]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mailbox: mpfs: fix handling of the reg property
authorConor Dooley <conor.dooley@microchip.com>
Wed, 24 Aug 2022 07:08:11 +0000 (08:08 +0100)
committerJassi Brar <jaswinder.singh@linaro.org>
Thu, 6 Oct 2022 02:48:31 +0000 (21:48 -0500)
The "data" region of the PolarFire SoC's system controller mailbox is
not one continuous register space - the system controller's QSPI sits
between the control and data registers. Split the "data" reg into two
parts: "data" & "control". Optionally get the "data" register address
from the 3rd reg property in the devicetree & fall back to using the
old base + MAILBOX_REG_OFFSET that the current code uses.

Fixes: 83d7b1560810 ("mbox: add polarfire soc system controller mailbox")
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
drivers/mailbox/mailbox-mpfs.c

index 4e34854d12389825f4f926fa617914c70ecb534b..e432a8f0d14851d2b3b42c12da15628475a3726c 100644 (file)
@@ -62,6 +62,7 @@ struct mpfs_mbox {
        struct mbox_controller controller;
        struct device *dev;
        int irq;
+       void __iomem *ctrl_base;
        void __iomem *mbox_base;
        void __iomem *int_reg;
        struct mbox_chan chans[1];
@@ -73,7 +74,7 @@ static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
 {
        u32 status;
 
-       status = readl_relaxed(mbox->mbox_base + SERVICES_SR_OFFSET);
+       status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
 
        return status & SCB_STATUS_BUSY_MASK;
 }
@@ -99,14 +100,13 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
 
                for (index = 0; index < (msg->cmd_data_size / 4); index++)
                        writel_relaxed(word_buf[index],
-                                      mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
+                                      mbox->mbox_base + index * 0x4);
                if (extra_bits) {
                        u8 i;
                        u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
                        u8 *byte_buf = msg->cmd_data + byte_off;
 
-                       val = readl_relaxed(mbox->mbox_base +
-                                           MAILBOX_REG_OFFSET + index * 0x4);
+                       val = readl_relaxed(mbox->mbox_base + index * 0x4);
 
                        for (i = 0u; i < extra_bits; i++) {
                                val &= ~(0xffu << (i * 8u));
@@ -114,14 +114,14 @@ static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
                        }
 
                        writel_relaxed(val,
-                                      mbox->mbox_base + MAILBOX_REG_OFFSET + index * 0x4);
+                                      mbox->mbox_base + index * 0x4);
                }
        }
 
        opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
        tx_trigger = (opt_sel << SCB_CTRL_POS) & SCB_CTRL_MASK;
        tx_trigger |= SCB_CTRL_REQ_MASK | SCB_STATUS_NOTIFY_MASK;
-       writel_relaxed(tx_trigger, mbox->mbox_base + SERVICES_CR_OFFSET);
+       writel_relaxed(tx_trigger, mbox->ctrl_base + SERVICES_CR_OFFSET);
 
        return 0;
 }
@@ -141,7 +141,7 @@ static void mpfs_mbox_rx_data(struct mbox_chan *chan)
        if (!mpfs_mbox_busy(mbox)) {
                for (i = 0; i < num_words; i++) {
                        response->resp_msg[i] =
-                               readl_relaxed(mbox->mbox_base + MAILBOX_REG_OFFSET
+                               readl_relaxed(mbox->mbox_base
                                              + mbox->resp_offset + i * 0x4);
                }
        }
@@ -200,14 +200,18 @@ static int mpfs_mbox_probe(struct platform_device *pdev)
        if (!mbox)
                return -ENOMEM;
 
-       mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
-       if (IS_ERR(mbox->mbox_base))
-               return PTR_ERR(mbox->mbox_base);
+       mbox->ctrl_base = devm_platform_get_and_ioremap_resource(pdev, 0, &regs);
+       if (IS_ERR(mbox->ctrl_base))
+               return PTR_ERR(mbox->ctrl_base);
 
        mbox->int_reg = devm_platform_get_and_ioremap_resource(pdev, 1, &regs);
        if (IS_ERR(mbox->int_reg))
                return PTR_ERR(mbox->int_reg);
 
+       mbox->mbox_base = devm_platform_get_and_ioremap_resource(pdev, 2, &regs);
+       if (IS_ERR(mbox->mbox_base)) // account for the old dt-binding w/ 2 regs
+               mbox->mbox_base = mbox->ctrl_base + MAILBOX_REG_OFFSET;
+
        mbox->irq = platform_get_irq(pdev, 0);
        if (mbox->irq < 0)
                return mbox->irq;