diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-13 11:19:07 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-13 11:19:07 -0800 |
commit | fb3b0673b7d5b477ed104949450cd511337ba3c6 (patch) | |
tree | 3057ae8aa7f1ccd23095860b56b45f6b57bd9ccb /drivers/mailbox | |
parent | 747c19eb7539b5e6bb15ed57a0a14ebf9f3adb8e (diff) | |
parent | 869b6ca39c08c5b10eeb29d4b3c4bc433bf8ba5e (diff) |
Merge tag 'mailbox-v5.17' of git://git.linaro.org/landing-teams/working/fujitsu/integration
Pull mailbox updates from Jassi Brar:
- qcom: misc updates to qcom-ipcc driver
- mpfs: change compatible string
- pcc:
- fix handling of subtypes
- avoid uninitialized variable
- mtk:
- add missing of_node_put
- enable control_by_sw
- silent probe-defer prints
- fix gce_num for mt8192
- zynq: add missing of_node_put
- imx: check for NULL instead of IS_ERR
- appple: switch to generic compatibles
- hi3660: convert comments to kernel-doc notation
* tag 'mailbox-v5.17' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
dt-bindings: mailbox: Add more protocol and client ID
mailbox: qcom-ipcc: Support interrupt wake up from suspend
mailbox: qcom-ipcc: Support more IPCC instance
mailbox: qcom-ipcc: Dynamic alloc for channel arrangement
mailbox: change mailbox-mpfs compatible string
mailbox: pcc: Handle all PCC subtypes correctly in pcc_mbox_irq
mailbox: pcc: Avoid using the uninitialized variable 'dev'
mailbox: mtk: add missing of_node_put before return
mailbox: zynq: add missing of_node_put before return
mailbox: imx: Fix an IS_ERR() vs NULL bug
mailbox: hi3660: convert struct comments to kernel-doc notation
mailbox: add control_by_sw for mt8195
mailbox: mtk-cmdq: Silent EPROBE_DEFER errors for clks
mailbox: fix gce_num of mt8192 driver data
mailbox: apple: Bind to generic compatibles
dt-bindings: mailbox: apple,mailbox: Add generic and t6000 compatibles
Diffstat (limited to 'drivers/mailbox')
-rw-r--r-- | drivers/mailbox/apple-mailbox.c | 4 | ||||
-rw-r--r-- | drivers/mailbox/hi3660-mailbox.c | 18 | ||||
-rw-r--r-- | drivers/mailbox/imx-mailbox.c | 4 | ||||
-rw-r--r-- | drivers/mailbox/mailbox-mpfs.c | 2 | ||||
-rw-r--r-- | drivers/mailbox/mtk-cmdq-mailbox.c | 15 | ||||
-rw-r--r-- | drivers/mailbox/pcc.c | 10 | ||||
-rw-r--r-- | drivers/mailbox/qcom-ipcc.c | 99 | ||||
-rw-r--r-- | drivers/mailbox/zynqmp-ipi-mailbox.c | 1 |
8 files changed, 105 insertions, 48 deletions
diff --git a/drivers/mailbox/apple-mailbox.c b/drivers/mailbox/apple-mailbox.c index 72942002a54a..496c4951ccb1 100644 --- a/drivers/mailbox/apple-mailbox.c +++ b/drivers/mailbox/apple-mailbox.c @@ -364,8 +364,8 @@ static const struct apple_mbox_hw apple_mbox_m3_hw = { }; static const struct of_device_id apple_mbox_of_match[] = { - { .compatible = "apple,t8103-asc-mailbox", .data = &apple_mbox_asc_hw }, - { .compatible = "apple,t8103-m3-mailbox", .data = &apple_mbox_m3_hw }, + { .compatible = "apple,asc-mailbox-v4", .data = &apple_mbox_asc_hw }, + { .compatible = "apple,m3-mailbox-v2", .data = &apple_mbox_m3_hw }, {} }; MODULE_DEVICE_TABLE(of, apple_mbox_of_match); diff --git a/drivers/mailbox/hi3660-mailbox.c b/drivers/mailbox/hi3660-mailbox.c index e41bd2f5ea46..ab24e731a782 100644 --- a/drivers/mailbox/hi3660-mailbox.c +++ b/drivers/mailbox/hi3660-mailbox.c @@ -44,14 +44,13 @@ #define MBOX_MSG_LEN 8 /** - * Hi3660 mailbox channel information + * struct hi3660_chan_info - Hi3660 mailbox channel information + * @dst_irq: Interrupt vector for remote processor + * @ack_irq: Interrupt vector for local processor * * A channel can be used for TX or RX, it can trigger remote * processor interrupt to notify remote processor and can receive - * interrupt if has incoming message. - * - * @dst_irq: Interrupt vector for remote processor - * @ack_irq: Interrupt vector for local processor + * interrupt if it has an incoming message. */ struct hi3660_chan_info { unsigned int dst_irq; @@ -59,16 +58,15 @@ struct hi3660_chan_info { }; /** - * Hi3660 mailbox controller data - * - * Mailbox controller includes 32 channels and can allocate - * channel for message transferring. - * + * struct hi3660_mbox - Hi3660 mailbox controller data * @dev: Device to which it is attached * @base: Base address of the register mapping region * @chan: Representation of channels in mailbox controller * @mchan: Representation of channel info * @controller: Representation of a communication channel controller + * + * Mailbox controller includes 32 channels and can allocate + * channel for message transferring. */ struct hi3660_mbox { struct device *dev; diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index ffe36a6bef9e..544de2db6453 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -563,8 +563,8 @@ static int imx_mu_probe(struct platform_device *pdev) size = sizeof(struct imx_sc_rpc_msg_max); priv->msg = devm_kzalloc(dev, size, GFP_KERNEL); - if (IS_ERR(priv->msg)) - return PTR_ERR(priv->msg); + if (!priv->msg) + return -ENOMEM; priv->clk = devm_clk_get(dev, NULL); if (IS_ERR(priv->clk)) { diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c index 0d6e2231a2c7..4e34854d1238 100644 --- a/drivers/mailbox/mailbox-mpfs.c +++ b/drivers/mailbox/mailbox-mpfs.c @@ -232,7 +232,7 @@ static int mpfs_mbox_probe(struct platform_device *pdev) } static const struct of_device_id mpfs_mbox_of_match[] = { - {.compatible = "microchip,polarfire-soc-mailbox", }, + {.compatible = "microchip,mpfs-mailbox", }, {}, }; MODULE_DEVICE_TABLE(of, mpfs_mbox_of_match); diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index a8845b162dbf..2578e5aaa935 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -573,8 +573,11 @@ static int cmdq_probe(struct platform_device *pdev) cmdq->clocks[alias_id].id = clk_names[alias_id]; cmdq->clocks[alias_id].clk = of_clk_get(node, 0); if (IS_ERR(cmdq->clocks[alias_id].clk)) { - dev_err(dev, "failed to get gce clk: %d\n", alias_id); - return PTR_ERR(cmdq->clocks[alias_id].clk); + of_node_put(node); + return dev_err_probe(dev, + PTR_ERR(cmdq->clocks[alias_id].clk), + "failed to get gce clk: %d\n", + alias_id); } } } @@ -582,8 +585,8 @@ static int cmdq_probe(struct platform_device *pdev) cmdq->clocks[alias_id].id = clk_name; cmdq->clocks[alias_id].clk = devm_clk_get(&pdev->dev, clk_name); if (IS_ERR(cmdq->clocks[alias_id].clk)) { - dev_err(dev, "failed to get gce clk\n"); - return PTR_ERR(cmdq->clocks[alias_id].clk); + return dev_err_probe(dev, PTR_ERR(cmdq->clocks[alias_id].clk), + "failed to get gce clk\n"); } } @@ -658,13 +661,13 @@ static const struct gce_plat gce_plat_v5 = { .thread_nr = 24, .shift = 3, .control_by_sw = true, - .gce_num = 2 + .gce_num = 1 }; static const struct gce_plat gce_plat_v6 = { .thread_nr = 24, .shift = 3, - .control_by_sw = false, + .control_by_sw = true, .gce_num = 2 }; diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 887a3704c12e..ed18936b8ce6 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -241,9 +241,11 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) if (ret) return IRQ_NONE; - val &= pchan->cmd_complete.status_mask; - if (!val) - return IRQ_NONE; + if (val) { /* Ensure GAS exists and value is non-zero */ + val &= pchan->cmd_complete.status_mask; + if (!val) + return IRQ_NONE; + } ret = pcc_chan_reg_read(&pchan->error, &val); if (ret) @@ -289,7 +291,7 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) pchan = chan_info + subspace_id; chan = pchan->chan.mchan; if (IS_ERR(chan) || chan->cl) { - dev_err(dev, "Channel not found for idx: %d\n", subspace_id); + pr_err("Channel not found for idx: %d\n", subspace_id); return ERR_PTR(-EBUSY); } dev = chan->mbox->dev; diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c index f1d4f4679b17..c5d963222014 100644 --- a/drivers/mailbox/qcom-ipcc.c +++ b/drivers/mailbox/qcom-ipcc.c @@ -13,8 +13,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> -#define IPCC_MBOX_MAX_CHAN 48 - /* IPCC Register offsets */ #define IPCC_REG_SEND_ID 0x0c #define IPCC_REG_RECV_ID 0x10 @@ -52,9 +50,10 @@ struct qcom_ipcc { struct device *dev; void __iomem *base; struct irq_domain *irq_domain; - struct mbox_chan chan[IPCC_MBOX_MAX_CHAN]; - struct qcom_ipcc_chan_info mchan[IPCC_MBOX_MAX_CHAN]; + struct mbox_chan *chans; + struct qcom_ipcc_chan_info *mchan; struct mbox_controller mbox; + int num_chans; int irq; }; @@ -166,25 +165,37 @@ static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, struct qcom_ipcc *ipcc = to_qcom_ipcc(mbox); struct qcom_ipcc_chan_info *mchan; struct mbox_chan *chan; - unsigned int i; + struct device *dev; + int chan_id; + + dev = ipcc->dev; if (ph->args_count != 2) return ERR_PTR(-EINVAL); - for (i = 0; i < IPCC_MBOX_MAX_CHAN; i++) { - chan = &ipcc->chan[i]; - if (!chan->con_priv) { - mchan = &ipcc->mchan[i]; - mchan->client_id = ph->args[0]; - mchan->signal_id = ph->args[1]; - chan->con_priv = mchan; - break; - } + for (chan_id = 0; chan_id < mbox->num_chans; chan_id++) { + chan = &ipcc->chans[chan_id]; + mchan = chan->con_priv; - chan = NULL; + if (!mchan) + break; + else if (mchan->client_id == ph->args[0] && + mchan->signal_id == ph->args[1]) + return ERR_PTR(-EBUSY); } - return chan ?: ERR_PTR(-EBUSY); + if (chan_id >= mbox->num_chans) + return ERR_PTR(-EBUSY); + + mchan = devm_kzalloc(dev, sizeof(*mchan), GFP_KERNEL); + if (!mchan) + return ERR_PTR(-ENOMEM); + + mchan->client_id = ph->args[0]; + mchan->signal_id = ph->args[1]; + chan->con_priv = mchan; + + return chan; } static const struct mbox_chan_ops ipcc_mbox_chan_ops = { @@ -192,15 +203,49 @@ static const struct mbox_chan_ops ipcc_mbox_chan_ops = { .shutdown = qcom_ipcc_mbox_shutdown, }; -static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc) +static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc, + struct device_node *controller_dn) { + struct of_phandle_args curr_ph; + struct device_node *client_dn; struct mbox_controller *mbox; struct device *dev = ipcc->dev; + int i, j, ret; + + /* + * Find out the number of clients interested in this mailbox + * and create channels accordingly. + */ + ipcc->num_chans = 0; + for_each_node_with_property(client_dn, "mboxes") { + if (!of_device_is_available(client_dn)) + continue; + i = of_count_phandle_with_args(client_dn, + "mboxes", "#mbox-cells"); + for (j = 0; j < i; j++) { + ret = of_parse_phandle_with_args(client_dn, "mboxes", + "#mbox-cells", j, &curr_ph); + of_node_put(curr_ph.np); + if (!ret && curr_ph.np == controller_dn) { + ipcc->num_chans++; + break; + } + } + } + + /* If no clients are found, skip registering as a mbox controller */ + if (!ipcc->num_chans) + return 0; + + ipcc->chans = devm_kcalloc(dev, ipcc->num_chans, + sizeof(struct mbox_chan), GFP_KERNEL); + if (!ipcc->chans) + return -ENOMEM; mbox = &ipcc->mbox; mbox->dev = dev; - mbox->num_chans = IPCC_MBOX_MAX_CHAN; - mbox->chans = ipcc->chan; + mbox->num_chans = ipcc->num_chans; + mbox->chans = ipcc->chans; mbox->ops = &ipcc_mbox_chan_ops; mbox->of_xlate = qcom_ipcc_mbox_xlate; mbox->txdone_irq = false; @@ -212,6 +257,8 @@ static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc) static int qcom_ipcc_probe(struct platform_device *pdev) { struct qcom_ipcc *ipcc; + static int id; + char *name; int ret; ipcc = devm_kzalloc(&pdev->dev, sizeof(*ipcc), GFP_KERNEL); @@ -228,27 +275,33 @@ static int qcom_ipcc_probe(struct platform_device *pdev) if (ipcc->irq < 0) return ipcc->irq; + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ipcc_%d", id++); + if (!name) + return -ENOMEM; + ipcc->irq_domain = irq_domain_add_tree(pdev->dev.of_node, &qcom_ipcc_irq_ops, ipcc); if (!ipcc->irq_domain) return -ENOMEM; - ret = qcom_ipcc_setup_mbox(ipcc); + ret = qcom_ipcc_setup_mbox(ipcc, pdev->dev.of_node); if (ret) goto err_mbox; ret = devm_request_irq(&pdev->dev, ipcc->irq, qcom_ipcc_irq_fn, - IRQF_TRIGGER_HIGH, "ipcc", ipcc); + IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND, name, ipcc); if (ret < 0) { dev_err(&pdev->dev, "Failed to register the irq: %d\n", ret); - goto err_mbox; + goto err_req_irq; } - enable_irq_wake(ipcc->irq); platform_set_drvdata(pdev, ipcc); return 0; +err_req_irq: + if (ipcc->num_chans) + mbox_controller_unregister(&ipcc->mbox); err_mbox: irq_domain_remove(ipcc->irq_domain); diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index f44079d62b1a..31a0fa914274 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -655,6 +655,7 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) mbox->pdata = pdata; ret = zynqmp_ipi_mbox_probe(mbox, nc); if (ret) { + of_node_put(nc); dev_err(dev, "failed to probe subdev.\n"); ret = -EINVAL; goto free_mbox_dev; |