summary refs log tree commit diff
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/devices.c9
-rw-r--r--arch/arm/mach-omap2/mailbox.c254
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c12
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c11
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c11
5 files changed, 135 insertions, 162 deletions
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 4269fc145698..4c97a86115e6 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -20,6 +20,7 @@
 #include <linux/pinctrl/machine.h>
 #include <linux/platform_data/omap4-keypad.h>
 #include <linux/platform_data/omap_ocp2scp.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <linux/usb/omap_control_usb.h>
 
 #include <asm/mach-types.h>
@@ -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 b01aae69010f..de21198d54ff 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -11,16 +11,16 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/platform_data/mailbox-omap.h>
 
 #include <plat/mailbox.h>
 
-#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 5137cc84b504..dbcb928eea50 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 <linux/i2c-omap.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #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 4ce999ee3ee9..df2f8742fe41 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 <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/omap-dma.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #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 31c7126eb3bb..9ac5122396d8 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 <linux/platform_data/asoc-ti-mcbsp.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 #include <linux/platform_data/iommu-omap.h>
+#include <linux/platform_data/mailbox-omap.h>
 #include <plat/dmtimer.h>
 
 #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,
 };
 
 /*