From a41677c6c5160f031038951fb94defeb93fe8160 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 1 Feb 2013 20:24:51 -0600 Subject: omap: mailbox: check iomem resource before dereferencing it Add a NULL check for iomem resource in mailbox probe functions. Signed-off-by: Fernando Guzman Lugo Signed-off-by: Suman Anna --- arch/arm/mach-omap2/mailbox.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 0b08026..9fe0bf2 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -382,6 +382,9 @@ static int omap2_mbox_probe(struct platform_device *pdev) } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -ENOENT; + mbox_base = ioremap(mem->start, resource_size(mem)); if (!mbox_base) return -ENOMEM; -- cgit v1.1 From f91ca05ff490421d348e27baa2363a49547dee57 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 7 Jun 2013 16:27:45 -0500 Subject: omap: mailbox: correct the argument type for irq ops The argument type used in the actual individual omap_mbox_ops for irqs should be omap_mbox_irq_t instead of omap_mbox_type_t. Signed-off-by: Suman Anna --- arch/arm/mach-omap2/mailbox.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 9fe0bf2..b01aae6 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -61,9 +61,6 @@ struct omap_mbox2_priv { unsigned long irqdisable; }; -static void omap2_mbox_enable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq); - static inline unsigned int mbox_read_reg(size_t ofs) { return __raw_readl(mbox_base + ofs); @@ -124,8 +121,7 @@ static int omap2_mbox_fifo_full(struct omap_mbox *mbox) } /* Mailbox IRQ handle functions */ -static void omap2_mbox_enable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) +static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) { struct omap_mbox2_priv *p = mbox->priv; u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; @@ -135,8 +131,7 @@ static void omap2_mbox_enable_irq(struct omap_mbox *mbox, mbox_write_reg(l, p->irqenable); } -static void omap2_mbox_disable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) +static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) { struct omap_mbox2_priv *p = mbox->priv; u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; @@ -147,8 +142,7 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, mbox_write_reg(bit, p->irqdisable); } -static void omap2_mbox_ack_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) +static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) { struct omap_mbox2_priv *p = mbox->priv; u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; @@ -159,8 +153,7 @@ static void omap2_mbox_ack_irq(struct omap_mbox *mbox, mbox_read_reg(p->irqstatus); } -static int omap2_mbox_is_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq) +static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) { struct omap_mbox2_priv *p = mbox->priv; u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; -- cgit v1.1 From b8a7cf8e2b15a3abac0a9e376b6b7ed4bbb6ee8e Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Mon, 28 Jan 2013 17:21:58 -0600 Subject: ARM: OMAP2+: mbox: remove dependencies with soc.h The OMAP mailbox platform driver code has been cleaned up to remove the dependencies with soc.h in preparation for moving the mailbox code to drivers folder. The code relied on cpu_is_xxx/soc_is_xxx macros previously to pick the the right set of mailbox devices and register with the mailbox driver. This data is now represented in a concise format and moved to the respective omap_hwmod data files and published to the driver through the platform data. Cc: Paul Walmsley Signed-off-by: Suman Anna --- arch/arm/mach-omap2/devices.c | 9 +- arch/arm/mach-omap2/mailbox.c | 254 +++++++++++------------------ arch/arm/mach-omap2/omap_hwmod_2420_data.c | 12 ++ arch/arm/mach-omap2/omap_hwmod_2430_data.c | 11 ++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 11 ++ 5 files changed, 135 insertions(+), 162 deletions(-) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 4269fc1..4c97a86 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -332,14 +333,20 @@ static inline void __init omap_init_mbox(void) { struct omap_hwmod *oh; struct platform_device *pdev; + struct omap_mbox_pdata *pdata; oh = omap_hwmod_lookup("mailbox"); if (!oh) { pr_err("%s: unable to find hwmod\n", __func__); return; } + if (!oh->dev_attr) { + pr_err("%s: hwmod doesn't have valid attrs\n", __func__); + return; + } - pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0); + pdata = (struct omap_mbox_pdata *)oh->dev_attr; + pdev = omap_device_build("omap-mailbox", -1, oh, pdata, sizeof(*pdata)); WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", __func__, PTR_ERR(pdev)); } diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index b01aae6..de21198 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -11,16 +11,16 @@ */ #include +#include #include #include #include #include #include +#include #include -#include "soc.h" - #define MAILBOX_REVISION 0x000 #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) @@ -59,6 +59,7 @@ struct omap_mbox2_priv { u32 notfull_bit; u32 ctx[OMAP4_MBOX_NR_REGS]; unsigned long irqdisable; + u32 intr_type; }; static inline unsigned int mbox_read_reg(size_t ofs) @@ -136,7 +137,11 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) struct omap_mbox2_priv *p = mbox->priv; u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - if (!cpu_is_omap44xx()) + /* + * Read and update the interrupt configuration register for pre-OMAP4. + * OMAP4 and later SoCs have a dedicated interrupt disabling register. + */ + if (!p->intr_type) bit = mbox_read_reg(p->irqdisable) & ~bit; mbox_write_reg(bit, p->irqdisable); @@ -168,7 +173,8 @@ static void omap2_mbox_save_ctx(struct omap_mbox *mbox) int i; struct omap_mbox2_priv *p = mbox->priv; int nr_regs; - if (cpu_is_omap44xx()) + + if (p->intr_type) nr_regs = OMAP4_MBOX_NR_REGS; else nr_regs = MBOX_NR_REGS; @@ -185,7 +191,8 @@ static void omap2_mbox_restore_ctx(struct omap_mbox *mbox) int i; struct omap_mbox2_priv *p = mbox->priv; int nr_regs; - if (cpu_is_omap44xx()) + + if (p->intr_type) nr_regs = OMAP4_MBOX_NR_REGS; else nr_regs = MBOX_NR_REGS; @@ -213,188 +220,113 @@ static struct omap_mbox_ops omap2_mbox_ops = { .restore_ctx = omap2_mbox_restore_ctx, }; -/* - * MAILBOX 0: ARM -> DSP, - * MAILBOX 1: ARM <- DSP. - * MAILBOX 2: ARM -> IVA, - * MAILBOX 3: ARM <- IVA. - */ - -/* FIXME: the following structs should be filled automatically by the user id */ - -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2) -/* DSP */ -static struct omap_mbox2_priv omap2_mbox_dsp_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE(0), - .fifo_stat = MAILBOX_FIFOSTATUS(0), - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE(1), - .msg_stat = MAILBOX_MSGSTATUS(1), - }, - .irqenable = MAILBOX_IRQENABLE(0), - .irqstatus = MAILBOX_IRQSTATUS(0), - .notfull_bit = MAILBOX_IRQ_NOTFULL(0), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), - .irqdisable = MAILBOX_IRQENABLE(0), -}; - -struct omap_mbox mbox_dsp_info = { - .name = "dsp", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_dsp_priv, -}; -#endif - -#if defined(CONFIG_ARCH_OMAP3) -struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL }; -#endif - -#if defined(CONFIG_SOC_OMAP2420) -/* IVA */ -static struct omap_mbox2_priv omap2_mbox_iva_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE(2), - .fifo_stat = MAILBOX_FIFOSTATUS(2), - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE(3), - .msg_stat = MAILBOX_MSGSTATUS(3), - }, - .irqenable = MAILBOX_IRQENABLE(3), - .irqstatus = MAILBOX_IRQSTATUS(3), - .notfull_bit = MAILBOX_IRQ_NOTFULL(2), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(3), - .irqdisable = MAILBOX_IRQENABLE(3), -}; - -static struct omap_mbox mbox_iva_info = { - .name = "iva", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_iva_priv, -}; -#endif - -#ifdef CONFIG_ARCH_OMAP2 -struct omap_mbox *omap2_mboxes[] = { - &mbox_dsp_info, -#ifdef CONFIG_SOC_OMAP2420 - &mbox_iva_info, -#endif - NULL -}; -#endif - -#if defined(CONFIG_ARCH_OMAP4) -/* OMAP4 */ -static struct omap_mbox2_priv omap2_mbox_1_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE(0), - .fifo_stat = MAILBOX_FIFOSTATUS(0), - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE(1), - .msg_stat = MAILBOX_MSGSTATUS(1), - }, - .irqenable = OMAP4_MAILBOX_IRQENABLE(0), - .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0), - .notfull_bit = MAILBOX_IRQ_NOTFULL(0), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), - .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0), -}; - -struct omap_mbox mbox_1_info = { - .name = "mailbox-1", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_1_priv, -}; - -static struct omap_mbox2_priv omap2_mbox_2_priv = { - .tx_fifo = { - .msg = MAILBOX_MESSAGE(3), - .fifo_stat = MAILBOX_FIFOSTATUS(3), - }, - .rx_fifo = { - .msg = MAILBOX_MESSAGE(2), - .msg_stat = MAILBOX_MSGSTATUS(2), - }, - .irqenable = OMAP4_MAILBOX_IRQENABLE(0), - .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0), - .notfull_bit = MAILBOX_IRQ_NOTFULL(3), - .newmsg_bit = MAILBOX_IRQ_NEWMSG(2), - .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0), -}; - -struct omap_mbox mbox_2_info = { - .name = "mailbox-2", - .ops = &omap2_mbox_ops, - .priv = &omap2_mbox_2_priv, -}; - -struct omap_mbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL }; -#endif - static int omap2_mbox_probe(struct platform_device *pdev) { struct resource *mem; int ret; - struct omap_mbox **list; - - if (false) - ; -#if defined(CONFIG_ARCH_OMAP3) - else if (cpu_is_omap34xx()) { - list = omap3_mboxes; + struct omap_mbox **list, *mbox, *mboxblk; + struct omap_mbox2_priv *priv, *privblk; + struct omap_mbox_pdata *pdata = pdev->dev.platform_data; + struct omap_mbox_dev_info *info; + int i; - list[0]->irq = platform_get_irq(pdev, 0); + if (!pdata || !pdata->info_cnt || !pdata->info) { + pr_err("%s: platform not supported\n", __func__); + return -ENODEV; } -#endif -#if defined(CONFIG_ARCH_OMAP2) - else if (cpu_is_omap2430()) { - list = omap2_mboxes; - list[0]->irq = platform_get_irq(pdev, 0); - } else if (cpu_is_omap2420()) { - list = omap2_mboxes; + /* allocate one extra for marking end of list */ + list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL); + if (!list) + return -ENOMEM; - list[0]->irq = platform_get_irq_byname(pdev, "dsp"); - list[1]->irq = platform_get_irq_byname(pdev, "iva"); + mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL); + if (!mboxblk) { + ret = -ENOMEM; + goto free_list; } -#endif -#if defined(CONFIG_ARCH_OMAP4) - else if (cpu_is_omap44xx()) { - list = omap4_mboxes; - list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0); + privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL); + if (!privblk) { + ret = -ENOMEM; + goto free_mboxblk; } -#endif - else { - pr_err("%s: platform not supported\n", __func__); - return -ENODEV; + + info = pdata->info; + for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { + priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); + priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); + priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); + priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); + priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); + priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); + if (pdata->intr_type) { + priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id); + priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id); + priv->irqdisable = + OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id); + } else { + priv->irqenable = MAILBOX_IRQENABLE(info->usr_id); + priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id); + priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id); + } + priv->intr_type = pdata->intr_type; + + mbox->priv = priv; + mbox->name = info->name; + mbox->ops = &omap2_mbox_ops; + mbox->irq = platform_get_irq(pdev, info->irq_id); + if (mbox->irq < 0) { + ret = mbox->irq; + goto free_privblk; + } + list[i] = mbox++; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) - return -ENOENT; + if (!mem) { + ret = -ENOENT; + goto free_privblk; + } mbox_base = ioremap(mem->start, resource_size(mem)); - if (!mbox_base) - return -ENOMEM; + if (!mbox_base) { + ret = -ENOMEM; + goto free_privblk; + } ret = omap_mbox_register(&pdev->dev, list); - if (ret) { - iounmap(mbox_base); - return ret; - } + if (ret) + goto unmap_mbox; + platform_set_drvdata(pdev, list); return 0; + +unmap_mbox: + iounmap(mbox_base); +free_privblk: + kfree(privblk); +free_mboxblk: + kfree(mboxblk); +free_list: + kfree(list); + return ret; } static int omap2_mbox_remove(struct platform_device *pdev) { + struct omap_mbox2_priv *privblk; + struct omap_mbox **list = platform_get_drvdata(pdev); + struct omap_mbox *mboxblk = list[0]; + + privblk = mboxblk->priv; omap_mbox_unregister(); iounmap(mbox_base); + kfree(privblk); + kfree(mboxblk); + kfree(list); + platform_set_drvdata(pdev, NULL); + return 0; } diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 5137cc8..dbcb928 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "omap_hwmod.h" @@ -166,6 +167,16 @@ static struct omap_hwmod omap2420_dma_system_hwmod = { }; /* mailbox */ +static struct omap_mbox_dev_info omap2420_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1, .irq_id = 0, .usr_id = 0 }, + { .name = "iva", .tx_id = 2, .rx_id = 3, .irq_id = 1, .usr_id = 3 }, +}; + +static struct omap_mbox_pdata omap2420_mailbox_attrs = { + .info_cnt = ARRAY_SIZE(omap2420_mailbox_info), + .info = omap2420_mailbox_info, +}; + static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = { { .name = "dsp", .irq = 26 + OMAP_INTC_START, }, { .name = "iva", .irq = 34 + OMAP_INTC_START, }, @@ -186,6 +197,7 @@ static struct omap_hwmod omap2420_mailbox_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, }, }, + .dev_attr = &omap2420_mailbox_attrs, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 4ce999e..df2f874 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "omap_hwmod.h" @@ -170,6 +171,15 @@ static struct omap_hwmod omap2430_dma_system_hwmod = { }; /* mailbox */ +static struct omap_mbox_dev_info omap2430_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, +}; + +static struct omap_mbox_pdata omap2430_mailbox_attrs = { + .info_cnt = ARRAY_SIZE(omap2430_mailbox_info), + .info = omap2430_mailbox_info, +}; + static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = { { .irq = 26 + OMAP_INTC_START, }, { .irq = -1 }, @@ -189,6 +199,7 @@ static struct omap_hwmod omap2430_mailbox_hwmod = { .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, }, }, + .dev_attr = &omap2430_mailbox_attrs, }; /* mcspi3 */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 31c7126..9ac5122 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "am35xx.h" @@ -1505,6 +1506,15 @@ static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = { .sysc = &omap3xxx_mailbox_sysc, }; +static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = { + { .name = "dsp", .tx_id = 0, .rx_id = 1 }, +}; + +static struct omap_mbox_pdata omap3xxx_mailbox_attrs = { + .info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info), + .info = omap3xxx_mailbox_info, +}; + static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = { { .irq = 26 + OMAP_INTC_START, }, { .irq = -1 }, @@ -1524,6 +1534,7 @@ static struct omap_hwmod omap3xxx_mailbox_hwmod = { .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT, }, }, + .dev_attr = &omap3xxx_mailbox_attrs, }; /* -- cgit v1.1 From fe32c1f6024e357f586b1d666237cab80a1215ce Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 7 May 2013 17:30:27 -0500 Subject: ARM: OMAP2+: add user and fifo info to mailbox platform data The different generations of OMAP2+ SoCs have almost the same mailbox IP, but the IP has configurable parameters for number of users (interrupts it can generate out towards processors) and number of fifos (the base unidirectional h/w communication channel). This data cannot be read from any registers, and so has been added to the platform data. This data together with the interrupt-type configuration can be used in properly figuring out the number of registers to save and restore in the OMAP mailbox driver code. Cc: Paul Walmsley Signed-off-by: Suman Anna --- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 2 ++ arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 ++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 ++ 3 files changed, 6 insertions(+) (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index dbcb928..d8b9d60 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -173,6 +173,8 @@ static struct omap_mbox_dev_info omap2420_mailbox_info[] = { }; static struct omap_mbox_pdata omap2420_mailbox_attrs = { + .num_users = 4, + .num_fifos = 6, .info_cnt = ARRAY_SIZE(omap2420_mailbox_info), .info = omap2420_mailbox_info, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index df2f874..5b90834 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -176,6 +176,8 @@ static struct omap_mbox_dev_info omap2430_mailbox_info[] = { }; static struct omap_mbox_pdata omap2430_mailbox_attrs = { + .num_users = 4, + .num_fifos = 6, .info_cnt = ARRAY_SIZE(omap2430_mailbox_info), .info = omap2430_mailbox_info, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 9ac5122..8e4cbc9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1511,6 +1511,8 @@ static struct omap_mbox_dev_info omap3xxx_mailbox_info[] = { }; static struct omap_mbox_pdata omap3xxx_mailbox_attrs = { + .num_users = 2, + .num_fifos = 2, .info_cnt = ARRAY_SIZE(omap3xxx_mailbox_info), .info = omap3xxx_mailbox_info, }; -- cgit v1.1 From c869c75c16b3d1ffcf64fb2fd63ba0c4a369071c Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Tue, 12 Mar 2013 17:55:29 -0500 Subject: mailbox/omap: move the OMAP mailbox framework to drivers The mailbox hardware (in OMAP) uses a queued mailbox interrupt mechanism that provides a communication channel between processors through a set of registers and their associated interrupt signals by sending and receiving messages. The OMAP mailbox framework/driver code is moved to be under drivers/mailbox, in preparation for adapting to a common mailbox driver framework. This allows the build for OMAP mailbox to be enabled (it was disabled during the multi-platform support). As part of the migration from plat and mach code: - Kconfig symbols have been renamed to build OMAP1 or OMAP2+ drivers. - mailbox.h under plat-omap/plat/include has been split into a public and private header files. The public header has only the API related functions and types. - The module name mailbox.ko from plat-omap is changed to omap-mailbox.ko - The module name mailbox_mach.ko from mach-omapX is changed as mailbox_omap1.ko for OMAP1 mailbox_omap2.ko for OMAP2+ Cc: Tony Lindgren [gregkh@linuxfoundation.org: ack for staging part] Acked-by: Greg Kroah-Hartman Signed-off-by: Omar Ramirez Luna Signed-off-by: Suman Anna --- arch/arm/mach-omap2/Makefile | 3 - arch/arm/mach-omap2/devices.c | 4 +- arch/arm/mach-omap2/mailbox.c | 358 ------------------------------------------ 3 files changed, 2 insertions(+), 363 deletions(-) delete mode 100644 arch/arm/mach-omap2/mailbox.c (limited to 'arch/arm/mach-omap2') diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 55a9d67..f2d19af 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -203,9 +203,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o obj-$(CONFIG_OMAP3_EMU) += emu.o obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o -obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o -mailbox_mach-objs := mailbox.o - iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o obj-y += $(iommu-m) $(iommu-y) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 4c97a86..73762ac 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -328,7 +328,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data return 0; } -#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) +#if defined(CONFIG_OMAP2PLUS_MBOX) || defined(CONFIG_OMAP2PLUS_MBOX_MODULE) static inline void __init omap_init_mbox(void) { struct omap_hwmod *oh; @@ -352,7 +352,7 @@ static inline void __init omap_init_mbox(void) } #else static inline void omap_init_mbox(void) { } -#endif /* CONFIG_OMAP_MBOX_FWK */ +#endif /* CONFIG_OMAP2PLUS_MBOX */ static inline void omap_init_sti(void) {} diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c deleted file mode 100644 index de21198..0000000 --- a/arch/arm/mach-omap2/mailbox.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Mailbox reservation modules for OMAP2/3 - * - * Copyright (C) 2006-2009 Nokia Corporation - * Written by: Hiroshi DOYU - * and Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAILBOX_REVISION 0x000 -#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) -#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) -#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m)) -#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u)) -#define MAILBOX_IRQENABLE(u) (0x104 + 8 * (u)) - -#define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 0x10 * (u)) -#define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u)) -#define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 0x10 * (u)) - -#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) -#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) - -#define MBOX_REG_SIZE 0x120 - -#define OMAP4_MBOX_REG_SIZE 0x130 - -#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32)) -#define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32)) - -static void __iomem *mbox_base; - -struct omap_mbox2_fifo { - unsigned long msg; - unsigned long fifo_stat; - unsigned long msg_stat; -}; - -struct omap_mbox2_priv { - struct omap_mbox2_fifo tx_fifo; - struct omap_mbox2_fifo rx_fifo; - unsigned long irqenable; - unsigned long irqstatus; - u32 newmsg_bit; - u32 notfull_bit; - u32 ctx[OMAP4_MBOX_NR_REGS]; - unsigned long irqdisable; - u32 intr_type; -}; - -static inline unsigned int mbox_read_reg(size_t ofs) -{ - return __raw_readl(mbox_base + ofs); -} - -static inline void mbox_write_reg(u32 val, size_t ofs) -{ - __raw_writel(val, mbox_base + ofs); -} - -/* Mailbox H/W preparations */ -static int omap2_mbox_startup(struct omap_mbox *mbox) -{ - u32 l; - - pm_runtime_enable(mbox->dev->parent); - pm_runtime_get_sync(mbox->dev->parent); - - l = mbox_read_reg(MAILBOX_REVISION); - pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); - - return 0; -} - -static void omap2_mbox_shutdown(struct omap_mbox *mbox) -{ - pm_runtime_put_sync(mbox->dev->parent); - pm_runtime_disable(mbox->dev->parent); -} - -/* Mailbox FIFO handle functions */ -static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; - return (mbox_msg_t) mbox_read_reg(fifo->msg); -} - -static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; - mbox_write_reg(msg, fifo->msg); -} - -static int omap2_mbox_fifo_empty(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; - return (mbox_read_reg(fifo->msg_stat) == 0); -} - -static int omap2_mbox_fifo_full(struct omap_mbox *mbox) -{ - struct omap_mbox2_fifo *fifo = - &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; - return mbox_read_reg(fifo->fifo_stat); -} - -/* Mailbox IRQ handle functions */ -static void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -{ - struct omap_mbox2_priv *p = mbox->priv; - u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - l = mbox_read_reg(p->irqenable); - l |= bit; - mbox_write_reg(l, p->irqenable); -} - -static void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -{ - struct omap_mbox2_priv *p = mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - /* - * Read and update the interrupt configuration register for pre-OMAP4. - * OMAP4 and later SoCs have a dedicated interrupt disabling register. - */ - if (!p->intr_type) - bit = mbox_read_reg(p->irqdisable) & ~bit; - - mbox_write_reg(bit, p->irqdisable); -} - -static void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -{ - struct omap_mbox2_priv *p = mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - - mbox_write_reg(bit, p->irqstatus); - - /* Flush posted write for irq status to avoid spurious interrupts */ - mbox_read_reg(p->irqstatus); -} - -static int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) -{ - struct omap_mbox2_priv *p = mbox->priv; - u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; - u32 enable = mbox_read_reg(p->irqenable); - u32 status = mbox_read_reg(p->irqstatus); - - return (int)(enable & status & bit); -} - -static void omap2_mbox_save_ctx(struct omap_mbox *mbox) -{ - int i; - struct omap_mbox2_priv *p = mbox->priv; - int nr_regs; - - if (p->intr_type) - nr_regs = OMAP4_MBOX_NR_REGS; - else - nr_regs = MBOX_NR_REGS; - for (i = 0; i < nr_regs; i++) { - p->ctx[i] = mbox_read_reg(i * sizeof(u32)); - - dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, - i, p->ctx[i]); - } -} - -static void omap2_mbox_restore_ctx(struct omap_mbox *mbox) -{ - int i; - struct omap_mbox2_priv *p = mbox->priv; - int nr_regs; - - if (p->intr_type) - nr_regs = OMAP4_MBOX_NR_REGS; - else - nr_regs = MBOX_NR_REGS; - for (i = 0; i < nr_regs; i++) { - mbox_write_reg(p->ctx[i], i * sizeof(u32)); - - dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__, - i, p->ctx[i]); - } -} - -static struct omap_mbox_ops omap2_mbox_ops = { - .type = OMAP_MBOX_TYPE2, - .startup = omap2_mbox_startup, - .shutdown = omap2_mbox_shutdown, - .fifo_read = omap2_mbox_fifo_read, - .fifo_write = omap2_mbox_fifo_write, - .fifo_empty = omap2_mbox_fifo_empty, - .fifo_full = omap2_mbox_fifo_full, - .enable_irq = omap2_mbox_enable_irq, - .disable_irq = omap2_mbox_disable_irq, - .ack_irq = omap2_mbox_ack_irq, - .is_irq = omap2_mbox_is_irq, - .save_ctx = omap2_mbox_save_ctx, - .restore_ctx = omap2_mbox_restore_ctx, -}; - -static int omap2_mbox_probe(struct platform_device *pdev) -{ - struct resource *mem; - int ret; - struct omap_mbox **list, *mbox, *mboxblk; - struct omap_mbox2_priv *priv, *privblk; - struct omap_mbox_pdata *pdata = pdev->dev.platform_data; - struct omap_mbox_dev_info *info; - int i; - - if (!pdata || !pdata->info_cnt || !pdata->info) { - pr_err("%s: platform not supported\n", __func__); - return -ENODEV; - } - - /* allocate one extra for marking end of list */ - list = kzalloc((pdata->info_cnt + 1) * sizeof(*list), GFP_KERNEL); - if (!list) - return -ENOMEM; - - mboxblk = mbox = kzalloc(pdata->info_cnt * sizeof(*mbox), GFP_KERNEL); - if (!mboxblk) { - ret = -ENOMEM; - goto free_list; - } - - privblk = priv = kzalloc(pdata->info_cnt * sizeof(*priv), GFP_KERNEL); - if (!privblk) { - ret = -ENOMEM; - goto free_mboxblk; - } - - info = pdata->info; - for (i = 0; i < pdata->info_cnt; i++, info++, priv++) { - priv->tx_fifo.msg = MAILBOX_MESSAGE(info->tx_id); - priv->tx_fifo.fifo_stat = MAILBOX_FIFOSTATUS(info->tx_id); - priv->rx_fifo.msg = MAILBOX_MESSAGE(info->rx_id); - priv->rx_fifo.msg_stat = MAILBOX_MSGSTATUS(info->rx_id); - priv->notfull_bit = MAILBOX_IRQ_NOTFULL(info->tx_id); - priv->newmsg_bit = MAILBOX_IRQ_NEWMSG(info->rx_id); - if (pdata->intr_type) { - priv->irqenable = OMAP4_MAILBOX_IRQENABLE(info->usr_id); - priv->irqstatus = OMAP4_MAILBOX_IRQSTATUS(info->usr_id); - priv->irqdisable = - OMAP4_MAILBOX_IRQENABLE_CLR(info->usr_id); - } else { - priv->irqenable = MAILBOX_IRQENABLE(info->usr_id); - priv->irqstatus = MAILBOX_IRQSTATUS(info->usr_id); - priv->irqdisable = MAILBOX_IRQENABLE(info->usr_id); - } - priv->intr_type = pdata->intr_type; - - mbox->priv = priv; - mbox->name = info->name; - mbox->ops = &omap2_mbox_ops; - mbox->irq = platform_get_irq(pdev, info->irq_id); - if (mbox->irq < 0) { - ret = mbox->irq; - goto free_privblk; - } - list[i] = mbox++; - } - - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem) { - ret = -ENOENT; - goto free_privblk; - } - - mbox_base = ioremap(mem->start, resource_size(mem)); - if (!mbox_base) { - ret = -ENOMEM; - goto free_privblk; - } - - ret = omap_mbox_register(&pdev->dev, list); - if (ret) - goto unmap_mbox; - platform_set_drvdata(pdev, list); - - return 0; - -unmap_mbox: - iounmap(mbox_base); -free_privblk: - kfree(privblk); -free_mboxblk: - kfree(mboxblk); -free_list: - kfree(list); - return ret; -} - -static int omap2_mbox_remove(struct platform_device *pdev) -{ - struct omap_mbox2_priv *privblk; - struct omap_mbox **list = platform_get_drvdata(pdev); - struct omap_mbox *mboxblk = list[0]; - - privblk = mboxblk->priv; - omap_mbox_unregister(); - iounmap(mbox_base); - kfree(privblk); - kfree(mboxblk); - kfree(list); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver omap2_mbox_driver = { - .probe = omap2_mbox_probe, - .remove = omap2_mbox_remove, - .driver = { - .name = "omap-mailbox", - }, -}; - -static int __init omap2_mbox_init(void) -{ - return platform_driver_register(&omap2_mbox_driver); -} - -static void __exit omap2_mbox_exit(void) -{ - platform_driver_unregister(&omap2_mbox_driver); -} - -module_init(omap2_mbox_init); -module_exit(omap2_mbox_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions"); -MODULE_AUTHOR("Hiroshi DOYU "); -MODULE_AUTHOR("Paul Mundt"); -MODULE_ALIAS("platform:omap2-mailbox"); -- cgit v1.1