0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/device.h>
0019 #include <linux/dma-mapping.h>
0020 #include <linux/err.h>
0021 #include <linux/interrupt.h>
0022 #include <linux/irq.h>
0023 #include <linux/kernel.h>
0024 #include <linux/mailbox_controller.h>
0025 #include <linux/module.h>
0026 #include <linux/of_address.h>
0027 #include <linux/of_irq.h>
0028 #include <linux/platform_device.h>
0029 #include <linux/spinlock.h>
0030
0031
0032 #define ARM_0_MAIL0 0x00
0033 #define ARM_0_MAIL1 0x20
0034
0035
0036
0037
0038
0039
0040
0041 #define MAIL0_RD (ARM_0_MAIL0 + 0x00)
0042 #define MAIL0_POL (ARM_0_MAIL0 + 0x10)
0043 #define MAIL0_STA (ARM_0_MAIL0 + 0x18)
0044 #define MAIL0_CNF (ARM_0_MAIL0 + 0x1C)
0045 #define MAIL1_WRT (ARM_0_MAIL1 + 0x00)
0046 #define MAIL1_STA (ARM_0_MAIL1 + 0x18)
0047
0048
0049 #define ARM_MS_FULL BIT(31)
0050 #define ARM_MS_EMPTY BIT(30)
0051
0052
0053 #define ARM_MC_IHAVEDATAIRQEN BIT(0)
0054
0055 struct bcm2835_mbox {
0056 void __iomem *regs;
0057 spinlock_t lock;
0058 struct mbox_controller controller;
0059 };
0060
0061 static struct bcm2835_mbox *bcm2835_link_mbox(struct mbox_chan *link)
0062 {
0063 return container_of(link->mbox, struct bcm2835_mbox, controller);
0064 }
0065
0066 static irqreturn_t bcm2835_mbox_irq(int irq, void *dev_id)
0067 {
0068 struct bcm2835_mbox *mbox = dev_id;
0069 struct device *dev = mbox->controller.dev;
0070 struct mbox_chan *link = &mbox->controller.chans[0];
0071
0072 while (!(readl(mbox->regs + MAIL0_STA) & ARM_MS_EMPTY)) {
0073 u32 msg = readl(mbox->regs + MAIL0_RD);
0074 dev_dbg(dev, "Reply 0x%08X\n", msg);
0075 mbox_chan_received_data(link, &msg);
0076 }
0077 return IRQ_HANDLED;
0078 }
0079
0080 static int bcm2835_send_data(struct mbox_chan *link, void *data)
0081 {
0082 struct bcm2835_mbox *mbox = bcm2835_link_mbox(link);
0083 u32 msg = *(u32 *)data;
0084
0085 spin_lock(&mbox->lock);
0086 writel(msg, mbox->regs + MAIL1_WRT);
0087 dev_dbg(mbox->controller.dev, "Request 0x%08X\n", msg);
0088 spin_unlock(&mbox->lock);
0089 return 0;
0090 }
0091
0092 static int bcm2835_startup(struct mbox_chan *link)
0093 {
0094 struct bcm2835_mbox *mbox = bcm2835_link_mbox(link);
0095
0096
0097 writel(ARM_MC_IHAVEDATAIRQEN, mbox->regs + MAIL0_CNF);
0098
0099 return 0;
0100 }
0101
0102 static void bcm2835_shutdown(struct mbox_chan *link)
0103 {
0104 struct bcm2835_mbox *mbox = bcm2835_link_mbox(link);
0105
0106 writel(0, mbox->regs + MAIL0_CNF);
0107 }
0108
0109 static bool bcm2835_last_tx_done(struct mbox_chan *link)
0110 {
0111 struct bcm2835_mbox *mbox = bcm2835_link_mbox(link);
0112 bool ret;
0113
0114 spin_lock(&mbox->lock);
0115 ret = !(readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL);
0116 spin_unlock(&mbox->lock);
0117 return ret;
0118 }
0119
0120 static const struct mbox_chan_ops bcm2835_mbox_chan_ops = {
0121 .send_data = bcm2835_send_data,
0122 .startup = bcm2835_startup,
0123 .shutdown = bcm2835_shutdown,
0124 .last_tx_done = bcm2835_last_tx_done
0125 };
0126
0127 static struct mbox_chan *bcm2835_mbox_index_xlate(struct mbox_controller *mbox,
0128 const struct of_phandle_args *sp)
0129 {
0130 if (sp->args_count != 0)
0131 return ERR_PTR(-EINVAL);
0132
0133 return &mbox->chans[0];
0134 }
0135
0136 static int bcm2835_mbox_probe(struct platform_device *pdev)
0137 {
0138 struct device *dev = &pdev->dev;
0139 int ret = 0;
0140 struct bcm2835_mbox *mbox;
0141
0142 mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
0143 if (mbox == NULL)
0144 return -ENOMEM;
0145 spin_lock_init(&mbox->lock);
0146
0147 ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0),
0148 bcm2835_mbox_irq, 0, dev_name(dev), mbox);
0149 if (ret) {
0150 dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
0151 ret);
0152 return -ENODEV;
0153 }
0154
0155 mbox->regs = devm_platform_ioremap_resource(pdev, 0);
0156 if (IS_ERR(mbox->regs)) {
0157 ret = PTR_ERR(mbox->regs);
0158 return ret;
0159 }
0160
0161 mbox->controller.txdone_poll = true;
0162 mbox->controller.txpoll_period = 5;
0163 mbox->controller.ops = &bcm2835_mbox_chan_ops;
0164 mbox->controller.of_xlate = &bcm2835_mbox_index_xlate;
0165 mbox->controller.dev = dev;
0166 mbox->controller.num_chans = 1;
0167 mbox->controller.chans = devm_kzalloc(dev,
0168 sizeof(*mbox->controller.chans), GFP_KERNEL);
0169 if (!mbox->controller.chans)
0170 return -ENOMEM;
0171
0172 ret = devm_mbox_controller_register(dev, &mbox->controller);
0173 if (ret)
0174 return ret;
0175
0176 platform_set_drvdata(pdev, mbox);
0177 dev_info(dev, "mailbox enabled\n");
0178
0179 return ret;
0180 }
0181
0182 static const struct of_device_id bcm2835_mbox_of_match[] = {
0183 { .compatible = "brcm,bcm2835-mbox", },
0184 {},
0185 };
0186 MODULE_DEVICE_TABLE(of, bcm2835_mbox_of_match);
0187
0188 static struct platform_driver bcm2835_mbox_driver = {
0189 .driver = {
0190 .name = "bcm2835-mbox",
0191 .of_match_table = bcm2835_mbox_of_match,
0192 },
0193 .probe = bcm2835_mbox_probe,
0194 };
0195 module_platform_driver(bcm2835_mbox_driver);
0196
0197 MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
0198 MODULE_DESCRIPTION("BCM2835 mailbox IPC driver");
0199 MODULE_LICENSE("GPL v2");