Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mailbox-v5.3' of git://git.linaro.org/landing-teams/working/fujitsu/integration

Pull mailbox updates from Jassi Brar:

- stm32: race fix by adding a spinlock

- mhu: trim included headers

- omap: add support for K3 SoCs

- imx: Irq disable fix

- bcm: tidy up extracting driver data

- tegra: make resume 'noirq'

- api: fix error handling

* tag 'mailbox-v5.3' of git://git.linaro.org/landing-teams/working/fujitsu/integration:
mailbox: handle failed named mailbox channel request
mailbox: tegra: avoid resume NULL mailboxes
mailbox: tegra: hsp: add noirq resume
mailbox: bcm-flexrm-mailbox: using dev_get_drvdata directly
mailbox: imx: Clear GIEn bit at shutdown
mailbox: omap: Add support for TI K3 SoCs
dt-bindings: mailbox: omap: Update bindings for TI K3 SoCs
mailbox: arm_mhu: reorder header inclusion and drop unneeded ones
mailbox: stm32_ipcc: add spinlock to fix channels concurrent access

+135 -59
+50 -9
Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
··· 1 - OMAP2+ Mailbox Driver 1 + OMAP2+ and K3 Mailbox 2 2 ===================== 3 3 4 4 The OMAP mailbox hardware facilitates communication between different processors ··· 7 7 communication is achieved through a set of registers for message storage and 8 8 interrupt configuration registers. 9 9 10 - Each mailbox IP block has a certain number of h/w fifo queues and output 10 + Each mailbox IP block/cluster has a certain number of h/w fifo queues and output 11 11 interrupt lines. An output interrupt line is routed to an interrupt controller 12 12 within a processor subsystem, and there can be more than one line going to a 13 13 specific processor's interrupt controller. The interrupt line connections are ··· 23 23 instance. DRA7xx has multiple instances with different number of h/w fifo queues 24 24 and interrupt lines between different instances. The interrupt lines can also be 25 25 routed to different processor sub-systems on DRA7xx as they are routed through 26 - the Crossbar, a kind of interrupt router/multiplexer. 26 + the Crossbar, a kind of interrupt router/multiplexer. The K3 AM65x and J721E 27 + SoCs has each of these instances form a cluster and combine multiple clusters 28 + into a single IP block present within the Main NavSS. The interrupt lines from 29 + all these clusters are multiplexed and routed to different processor subsystems 30 + over a limited number of common interrupt output lines of an Interrupt Router. 27 31 28 32 Mailbox Device Node: 29 33 ==================== 30 - A Mailbox device node is used to represent a Mailbox IP instance within a SoC. 31 - The sub-mailboxes are represented as child nodes of this parent node. 34 + A Mailbox device node is used to represent a Mailbox IP instance/cluster within 35 + a SoC. The sub-mailboxes are represented as child nodes of this parent node. 32 36 33 37 Required properties: 34 38 -------------------- ··· 41 37 "ti,omap3-mailbox" for OMAP3430, OMAP3630 SoCs 42 38 "ti,omap4-mailbox" for OMAP44xx, OMAP54xx, AM33xx, 43 39 AM43xx and DRA7xx SoCs 40 + "ti,am654-mailbox" for K3 AM65x and J721E SoCs 44 41 - reg: Contains the mailbox register address range (base 45 42 address and length) 46 43 - interrupts: Contains the interrupt information for the mailbox 47 44 device. The format is dependent on which interrupt 48 - controller the OMAP device uses 49 - - ti,hwmods: Name of the hwmod associated with the mailbox 45 + controller the Mailbox device uses 50 46 - #mbox-cells: Common mailbox binding property to identify the number 51 47 of cells required for the mailbox specifier. Should be 52 48 1 53 49 - ti,mbox-num-users: Number of targets (processor devices) that the mailbox 54 50 device can interrupt 55 51 - ti,mbox-num-fifos: Number of h/w fifo queues within the mailbox IP block 52 + 53 + SoC-specific Required properties: 54 + --------------------------------- 55 + The following are mandatory properties for the OMAP architecture based SoCs 56 + only: 57 + - ti,hwmods: Name of the hwmod associated with the mailbox. This 58 + should be defined in the mailbox node only if the node 59 + is not defined as a child node of a corresponding sysc 60 + interconnect node. 61 + 62 + The following are mandatory properties for the K3 AM65x and J721E SoCs only: 63 + - interrupt-parent: Should contain a phandle to the TI-SCI interrupt 64 + controller node that is used to dynamically program 65 + the interrupt routes between the IP and the main GIC 66 + controllers. See the following binding for additional 67 + details, 68 + Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt 56 69 57 70 Child Nodes: 58 71 ============ ··· 119 98 Example: 120 99 -------- 121 100 122 - /* OMAP4 */ 101 + 1. /* OMAP4 */ 123 102 mailbox: mailbox@4a0f4000 { 124 103 compatible = "ti,omap4-mailbox"; 125 104 reg = <0x4a0f4000 0x200>; ··· 144 123 ... 145 124 }; 146 125 147 - /* AM33xx */ 126 + 2. /* AM33xx */ 148 127 mailbox: mailbox@480c8000 { 149 128 compatible = "ti,omap4-mailbox"; 150 129 reg = <0x480C8000 0x200>; ··· 156 135 mbox_wkupm3: wkup_m3 { 157 136 ti,mbox-tx = <0 0 0>; 158 137 ti,mbox-rx = <0 0 3>; 138 + }; 139 + }; 140 + 141 + 3. /* AM65x */ 142 + &cbass_main { 143 + cbass_main_navss: interconnect0 { 144 + mailbox0_cluster0: mailbox@31f80000 { 145 + compatible = "ti,am654-mailbox"; 146 + reg = <0x00 0x31f80000 0x00 0x200>; 147 + #mbox-cells = <1>; 148 + ti,mbox-num-users = <4>; 149 + ti,mbox-num-fifos = <16>; 150 + interrupt-parent = <&intr_main_navss>; 151 + interrupts = <164 0>; 152 + 153 + mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 { 154 + ti,mbox-tx = <1 0 0>; 155 + ti,mbox-rx = <0 0 0>; 156 + }; 157 + }; 159 158 }; 160 159 };
+1 -1
drivers/mailbox/Kconfig
··· 54 54 55 55 config OMAP2PLUS_MBOX 56 56 tristate "OMAP2+ Mailbox framework support" 57 - depends on ARCH_OMAP2PLUS 57 + depends on ARCH_OMAP2PLUS || ARCH_K3 58 58 help 59 59 Mailbox implementation for OMAP family chips with hardware for 60 60 interprocessor communication involving DSP, IVA1.0 and IVA2 in
+5 -8
drivers/mailbox/arm_mhu.c
··· 5 5 * Author: Jassi Brar <jaswinder.singh@linaro.org> 6 6 */ 7 7 8 - #include <linux/interrupt.h> 9 - #include <linux/spinlock.h> 10 - #include <linux/mutex.h> 11 - #include <linux/delay.h> 12 - #include <linux/slab.h> 13 - #include <linux/err.h> 14 - #include <linux/io.h> 15 - #include <linux/module.h> 16 8 #include <linux/amba/bus.h> 9 + #include <linux/device.h> 10 + #include <linux/err.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/io.h> 17 13 #include <linux/mailbox_controller.h> 14 + #include <linux/module.h> 18 15 19 16 #define INTR_STAT_OFS 0x0 20 17 #define INTR_SET_OFS 0x8
+2 -4
drivers/mailbox/bcm-flexrm-mailbox.c
··· 1163 1163 1164 1164 static int flexrm_debugfs_conf_show(struct seq_file *file, void *offset) 1165 1165 { 1166 - struct platform_device *pdev = to_platform_device(file->private); 1167 - struct flexrm_mbox *mbox = platform_get_drvdata(pdev); 1166 + struct flexrm_mbox *mbox = dev_get_drvdata(file->private); 1168 1167 1169 1168 /* Write config in file */ 1170 1169 flexrm_write_config_in_seqfile(mbox, file); ··· 1173 1174 1174 1175 static int flexrm_debugfs_stats_show(struct seq_file *file, void *offset) 1175 1176 { 1176 - struct platform_device *pdev = to_platform_device(file->private); 1177 - struct flexrm_mbox *mbox = platform_get_drvdata(pdev); 1177 + struct flexrm_mbox *mbox = dev_get_drvdata(file->private); 1178 1178 1179 1179 /* Write stats in file */ 1180 1180 flexrm_write_stats_in_seqfile(mbox, file);
+2 -2
drivers/mailbox/imx-mailbox.c
··· 217 217 if (cp->type == IMX_MU_TYPE_TXDB) 218 218 tasklet_kill(&cp->txdb_tasklet); 219 219 220 - imx_mu_xcr_rmw(priv, 0, 221 - IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx)); 220 + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx) | 221 + IMX_MU_xCR_RIEn(cp->idx) | IMX_MU_xCR_GIEn(cp->idx)); 222 222 223 223 free_irq(priv->irq, chan); 224 224 }
+4 -2
drivers/mailbox/mailbox.c
··· 418 418 419 419 of_property_for_each_string(np, "mbox-names", prop, mbox_name) { 420 420 if (!strncmp(name, mbox_name, strlen(name))) 421 - break; 421 + return mbox_request_channel(cl, index); 422 422 index++; 423 423 } 424 424 425 - return mbox_request_channel(cl, index); 425 + dev_err(cl->dev, "%s() could not locate channel named \"%s\"\n", 426 + __func__, name); 427 + return ERR_PTR(-EINVAL); 426 428 } 427 429 EXPORT_SYMBOL_GPL(mbox_request_channel_byname); 428 430
+26 -17
drivers/mailbox/omap-mailbox.c
··· 3 3 * OMAP mailbox driver 4 4 * 5 5 * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved. 6 - * Copyright (C) 2013-2016 Texas Instruments Incorporated - http://www.ti.com 6 + * Copyright (C) 2013-2019 Texas Instruments Incorporated - http://www.ti.com 7 7 * 8 8 * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> 9 9 * Suman Anna <s-anna@ti.com> ··· 141 141 } 142 142 143 143 /* Mailbox FIFO handle functions */ 144 - static mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) 144 + static u32 mbox_fifo_read(struct omap_mbox *mbox) 145 145 { 146 146 struct omap_mbox_fifo *fifo = &mbox->rx_fifo; 147 147 148 - return (mbox_msg_t)mbox_read_reg(mbox->parent, fifo->msg); 148 + return mbox_read_reg(mbox->parent, fifo->msg); 149 149 } 150 150 151 - static void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) 151 + static void mbox_fifo_write(struct omap_mbox *mbox, u32 msg) 152 152 { 153 153 struct omap_mbox_fifo *fifo = &mbox->tx_fifo; 154 154 ··· 256 256 { 257 257 struct omap_mbox_queue *mq = 258 258 container_of(work, struct omap_mbox_queue, work); 259 - mbox_msg_t msg; 259 + mbox_msg_t data; 260 + u32 msg; 260 261 int len; 261 262 262 263 while (kfifo_len(&mq->fifo) >= sizeof(msg)) { 263 264 len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); 264 265 WARN_ON(len != sizeof(msg)); 266 + data = msg; 265 267 266 - mbox_chan_received_data(mq->mbox->chan, (void *)msg); 268 + mbox_chan_received_data(mq->mbox->chan, (void *)data); 267 269 spin_lock_irq(&mq->lock); 268 270 if (mq->full) { 269 271 mq->full = false; ··· 288 286 static void __mbox_rx_interrupt(struct omap_mbox *mbox) 289 287 { 290 288 struct omap_mbox_queue *mq = mbox->rxq; 291 - mbox_msg_t msg; 289 + u32 msg; 292 290 int len; 293 291 294 292 while (!mbox_fifo_empty(mbox)) { ··· 542 540 mutex_unlock(&mdev->cfg_lock); 543 541 } 544 542 545 - static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, void *data) 543 + static int omap_mbox_chan_send_noirq(struct omap_mbox *mbox, u32 msg) 546 544 { 547 545 int ret = -EBUSY; 548 546 549 547 if (!mbox_fifo_full(mbox)) { 550 548 _omap_mbox_enable_irq(mbox, IRQ_RX); 551 - mbox_fifo_write(mbox, (mbox_msg_t)data); 549 + mbox_fifo_write(mbox, msg); 552 550 ret = 0; 553 551 _omap_mbox_disable_irq(mbox, IRQ_RX); 554 552 ··· 560 558 return ret; 561 559 } 562 560 563 - static int omap_mbox_chan_send(struct omap_mbox *mbox, void *data) 561 + static int omap_mbox_chan_send(struct omap_mbox *mbox, u32 msg) 564 562 { 565 563 int ret = -EBUSY; 566 564 567 565 if (!mbox_fifo_full(mbox)) { 568 - mbox_fifo_write(mbox, (mbox_msg_t)data); 566 + mbox_fifo_write(mbox, msg); 569 567 ret = 0; 570 568 } 571 569 ··· 578 576 { 579 577 struct omap_mbox *mbox = mbox_chan_to_omap_mbox(chan); 580 578 int ret; 579 + u32 msg = omap_mbox_message(data); 581 580 582 581 if (!mbox) 583 582 return -EINVAL; 584 583 585 584 if (mbox->send_no_irq) 586 - ret = omap_mbox_chan_send_noirq(mbox, data); 585 + ret = omap_mbox_chan_send_noirq(mbox, msg); 587 586 else 588 - ret = omap_mbox_chan_send(mbox, data); 587 + ret = omap_mbox_chan_send(mbox, msg); 589 588 590 589 return ret; 591 590 } ··· 657 654 }, 658 655 { 659 656 .compatible = "ti,omap4-mailbox", 657 + .data = &omap4_data, 658 + }, 659 + { 660 + .compatible = "ti,am654-mailbox", 660 661 .data = &omap4_data, 661 662 }, 662 663 { ··· 837 830 mdev->intr_type = intr_type; 838 831 mdev->mboxes = list; 839 832 840 - /* OMAP does not have a Tx-Done IRQ, but rather a Tx-Ready IRQ */ 833 + /* 834 + * OMAP/K3 Mailbox IP does not have a Tx-Done IRQ, but rather a Tx-Ready 835 + * IRQ and is needed to run the Tx state machine 836 + */ 841 837 mdev->controller.txdone_irq = true; 842 838 mdev->controller.dev = mdev->dev; 843 839 mdev->controller.ops = &omap_mbox_chan_ops; ··· 909 899 return err; 910 900 911 901 /* kfifo size sanity check: alignment and minimal size */ 912 - mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); 913 - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, 914 - sizeof(mbox_msg_t)); 902 + mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(u32)); 903 + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(u32)); 915 904 916 905 err = platform_driver_register(&omap_mbox_driver); 917 906 if (err)
+27 -10
drivers/mailbox/stm32-ipcc.c
··· 50 50 void __iomem *reg_base; 51 51 void __iomem *reg_proc; 52 52 struct clk *clk; 53 + spinlock_t lock; /* protect access to IPCC registers */ 53 54 int irqs[IPCC_IRQ_NUM]; 54 55 int wkp; 55 56 u32 proc_id; ··· 59 58 u32 xmr; 60 59 }; 61 60 62 - static inline void stm32_ipcc_set_bits(void __iomem *reg, u32 mask) 61 + static inline void stm32_ipcc_set_bits(spinlock_t *lock, void __iomem *reg, 62 + u32 mask) 63 63 { 64 + unsigned long flags; 65 + 66 + spin_lock_irqsave(lock, flags); 64 67 writel_relaxed(readl_relaxed(reg) | mask, reg); 68 + spin_unlock_irqrestore(lock, flags); 65 69 } 66 70 67 - static inline void stm32_ipcc_clr_bits(void __iomem *reg, u32 mask) 71 + static inline void stm32_ipcc_clr_bits(spinlock_t *lock, void __iomem *reg, 72 + u32 mask) 68 73 { 74 + unsigned long flags; 75 + 76 + spin_lock_irqsave(lock, flags); 69 77 writel_relaxed(readl_relaxed(reg) & ~mask, reg); 78 + spin_unlock_irqrestore(lock, flags); 70 79 } 71 80 72 81 static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data) ··· 103 92 104 93 mbox_chan_received_data(&ipcc->controller.chans[chan], NULL); 105 94 106 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, 95 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, 107 96 RX_BIT_CHAN(chan)); 108 97 109 98 ret = IRQ_HANDLED; ··· 132 121 dev_dbg(dev, "%s: chan:%d tx\n", __func__, chan); 133 122 134 123 /* mask 'tx channel free' interrupt */ 135 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, 124 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, 136 125 TX_BIT_CHAN(chan)); 137 126 138 127 mbox_chan_txdone(&ipcc->controller.chans[chan], 0); ··· 152 141 dev_dbg(ipcc->controller.dev, "%s: chan:%d\n", __func__, chan); 153 142 154 143 /* set channel n occupied */ 155 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XSCR, TX_BIT_CHAN(chan)); 144 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR, 145 + TX_BIT_CHAN(chan)); 156 146 157 147 /* unmask 'tx channel free' interrupt */ 158 - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, TX_BIT_CHAN(chan)); 148 + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, 149 + TX_BIT_CHAN(chan)); 159 150 160 151 return 0; 161 152 } ··· 176 163 } 177 164 178 165 /* unmask 'rx channel occupied' interrupt */ 179 - stm32_ipcc_clr_bits(ipcc->reg_proc + IPCC_XMR, RX_BIT_CHAN(chan)); 166 + stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, 167 + RX_BIT_CHAN(chan)); 180 168 181 169 return 0; 182 170 } ··· 189 175 controller); 190 176 191 177 /* mask rx/tx interrupt */ 192 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, 178 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, 193 179 RX_BIT_CHAN(chan) | TX_BIT_CHAN(chan)); 194 180 195 181 clk_disable_unprepare(ipcc->clk); ··· 221 207 ipcc = devm_kzalloc(dev, sizeof(*ipcc), GFP_KERNEL); 222 208 if (!ipcc) 223 209 return -ENOMEM; 210 + 211 + spin_lock_init(&ipcc->lock); 224 212 225 213 /* proc_id */ 226 214 if (of_property_read_u32(np, "st,proc-id", &ipcc->proc_id)) { ··· 275 259 } 276 260 277 261 /* mask and enable rx/tx irq */ 278 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XMR, 262 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR, 279 263 RX_BIT_MASK | TX_BIT_MASK); 280 - stm32_ipcc_set_bits(ipcc->reg_proc + IPCC_XCR, XCR_RXOIE | XCR_TXOIE); 264 + stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XCR, 265 + XCR_RXOIE | XCR_TXOIE); 281 266 282 267 /* wakeup */ 283 268 if (of_property_read_bool(np, "wakeup-source")) {
+15 -5
drivers/mailbox/tegra-hsp.c
··· 775 775 { 776 776 struct tegra_hsp *hsp = dev_get_drvdata(dev); 777 777 unsigned int i; 778 + struct tegra_hsp_doorbell *db; 778 779 779 - for (i = 0; i < hsp->num_sm; i++) { 780 - struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i]; 780 + list_for_each_entry(db, &hsp->doorbells, list) { 781 + if (db && db->channel.chan) 782 + tegra_hsp_doorbell_startup(db->channel.chan); 783 + } 781 784 782 - if (mb->channel.chan->cl) 783 - tegra_hsp_mailbox_startup(mb->channel.chan); 785 + if (hsp->mailboxes) { 786 + for (i = 0; i < hsp->num_sm; i++) { 787 + struct tegra_hsp_mailbox *mb = &hsp->mailboxes[i]; 788 + 789 + if (mb->channel.chan->cl) 790 + tegra_hsp_mailbox_startup(mb->channel.chan); 791 + } 784 792 } 785 793 786 794 return 0; 787 795 } 788 796 789 - static SIMPLE_DEV_PM_OPS(tegra_hsp_pm_ops, NULL, tegra_hsp_resume); 797 + static const struct dev_pm_ops tegra_hsp_pm_ops = { 798 + .resume_noirq = tegra_hsp_resume, 799 + }; 790 800 791 801 static const struct tegra_hsp_db_map tegra186_hsp_db_map[] = { 792 802 { "ccplex", TEGRA_HSP_DB_MASTER_CCPLEX, HSP_DB_CCPLEX, },
+3 -1
include/linux/omap-mailbox.h
··· 6 6 #ifndef OMAP_MAILBOX_H 7 7 #define OMAP_MAILBOX_H 8 8 9 - typedef u32 mbox_msg_t; 9 + typedef uintptr_t mbox_msg_t; 10 + 11 + #define omap_mbox_message(data) (u32)(mbox_msg_t)(data) 10 12 11 13 typedef int __bitwise omap_mbox_irq_t; 12 14 #define IRQ_TX ((__force omap_mbox_irq_t) 1)