Re: [PATCH 01/32] arm/omap: use system_wq in mailbox
Tejun, On Tue, Jan 25, 2011 at 5:47 AM, Tejun Heo t...@kernel.org wrote: On Tue, Jan 04, 2011 at 06:24:21AM +0100, Tejun Heo wrote: Using dedicated workqueue or system_wq doesn't make any difference in terms of execution latency anymore. Sleeping work items no longer delay execution of other work items. If mailbox is very latency sensitive, it might make sense to create a HIGHPRI workqueue but that usually isn't necessary. Ping. Shall I apply the patch? I am sorry for the delay in acking your response. Your patch looks good to me. thank you, best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAP: device: make rt_va easily avaialable to drivers
On Wed, Dec 8, 2010 at 5:59 PM, Omar Ramirez Luna omar.rami...@ti.com wrote: Patch OMAP: hwmod/device: add omap_{device, hwmod}_get_mpu_rt_va[1], introduces omap_device_get_rt_va which is meant to be called by drivers to retrieve the _mpu_rt_va, however this function receives a pointer to an omap_device; since there is no practical way for a driver to get this parameter without fiddling with pdev and container_of macro, and omap_device code already does this, it is better for it to handle this case. Also moved header declaration to appear in the set of functions to be used by drivers, as per the comment there. [1] http://marc.info/?l=linux-omapm=127808467703366w=2 Signed-off-by: Omar Ramirez Luna omar.rami...@ti.com --- Acked-by: Hari Kanigeri h-kanige...@ti.com arch/arm/plat-omap/include/plat/omap_device.h | 3 +-- arch/arm/plat-omap/omap_device.c | 8 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 28e2d1a..1877c1a 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -80,6 +80,7 @@ struct omap_device { int omap_device_enable(struct platform_device *pdev); int omap_device_idle(struct platform_device *pdev); int omap_device_shutdown(struct platform_device *pdev); +void __iomem *omap_device_get_rt_va(struct platform_device *pdev); /* Core code interface */ @@ -101,8 +102,6 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, int omap_device_register(struct omap_device *od); int omap_early_device_register(struct omap_device *od); -void __iomem *omap_device_get_rt_va(struct omap_device *od); - /* OMAP PM interface */ int omap_device_align_pm_lat(struct platform_device *pdev, u32 new_wakeup_lat_limit); diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index abe933c..9d11195 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -681,7 +681,7 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) /** * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base - * @od: struct omap_device * + * @pdev: struct platform_device * * * Return the MPU's virtual address for the base of the hwmod, from * the ioremap() that the hwmod code does. Only valid if there is one @@ -690,8 +690,12 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) * otherwise, passes along the return value from * omap_hwmod_get_mpu_rt_va(). */ -void __iomem *omap_device_get_rt_va(struct omap_device *od) +void __iomem *omap_device_get_rt_va(struct platform_device *pdev) { + struct omap_device *od; + + od = _find_by_pdev(pdev); + if (od-hwmods_cnt != 1) return NULL; -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/7] usb: otg: Adding twl6030-usb transceiver driver for
Hema, On Tue, Dec 7, 2010 at 6:11 PM, Hema HK hem...@ti.com wrote: Adding the twl6030-usb transceiver support for OMAP4 musb driver. OMAP4 supports 2 types of transceiver interface. +} + +int omap4430_phy_set_clk(struct device *dev, int on) +{ + static int state; probably good to initialize to zero. + + if (on !state) { Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC v2 1/8] TILER-DMM: DMM-PAT driver for TI TILER
On Wed, Dec 1, 2010 at 11:16 PM, Varadarajan, Charulatha ch...@ti.com wrote: On Thu, Dec 2, 2010 at 07:57, Kanigeri, Hari h-kanige...@ti.com wrote: On Wed, Dec 1, 2010 at 8:10 PM, Kanigeri, Hari h-kanige...@ti.com wrote: On Wed, Dec 1, 2010 at 12:04 AM, Varadarajan, Charulatha ch...@ti.com wrote: David, + if (!oh) + goto error; + + data-base = oh-_mpu_rt_va; not required. Make use of platform_get APIs in probe to extract the base, dma and irq info using pdev. Not sure about using platform_get APIs. I think one has to use omap_hwmod_get_mpu_rt_va to get the address, which internally returns oh-_mpu_rt_va. small correction... omap_device_get_rt_va and not omap_hwmod_get_mpu_rt_va. To get the base address irq, you need not have to use omap_device_get_rt_va and pass it as pdata and then use it during probe. Instead in probe, you may do something like the following: If hwmod framework is already doing the ioremap on device address, then it is better to use it rather than duplicating the ioremap part again in probe function. From what I understand regarding omap_device_get_rt_va() function, it is added so that Driver's can avoid doing ioremap. check Santosh's comment on this API http://www.spinics.net/lists/arm-kernel/msg92260.html static int __devinit dev_probe (*pdev) { struct resource *res; void __iomem *base; u16 irq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (unlikely(!res)) { return -ENODEV; } base = ioremap(res-start, resource_size(res)); if (base) { return -ENOMEM; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (unlikely(!res)) { return -ENODEV; } irq = res-start; } -V Charulatha -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/4] OMAP: mailbox: fixes and enhancements
Here is the revised set taking into account comments received on previous patch set - Dropped the OMAP: mailbox: fix rx interrupt disable in omap4 patch. This patch will be sent along with mailbox hwmod changes. - Fixed the typo kifo to kfifo in OMAP: mailbox: send message in process context patch. References: http://marc.info/?l=linux-omapm=129069379825760w=2 http://marc.info/?l=linux-omapm=129060518315342w=2 The previous versions of this patch set can be found here === http://www.spinics.net/lists/linux-omap/msg40714.html http://www.spinics.net/lists/arm-kernel/msg104544.html http://www.spinics.net/lists/linux-omap/msg39988.html http://www.spinics.net/lists/linux-omap/msg39931.html http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37278.html Fernando Guzman Lugo (1): OMAP: mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (3): OMAP: mailbox: fix checkpatch warnings OMAP: mailbox: send message in process context OMAP: mailbox: add notification support for multiple readers arch/arm/plat-omap/include/plat/mailbox.h |8 +- arch/arm/plat-omap/mailbox.c | 130 + 2 files changed, 81 insertions(+), 57 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/4] OMAP: mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com The variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflicts. Now there is a full flag per mailbox queue. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |9 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..48e161c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,12 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + spin_lock_irq(mq-lock); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } + spin_unlock_irq(mq-lock); } } @@ -170,7 +175,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/4] OMAP: mailbox: fix checkpatch warnings
Fix the following checkpatch warnings observed in mailbox module. WARNING: please, no space for starting a line, excluding comments + fail_alloc_rxq:$ WARNING: please, no space for starting a line, excluding comments + fail_alloc_txq:$ WARNING: please, no space for starting a line, excluding comments + fail_request_irq:$ WARNING: line over 80 characters + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 48e161c..d9aa87c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -281,11 +281,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -396,7 +396,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 3/4] OMAP: mailbox: send message in process context
Schedule the Tasklet to send only when mailbox fifo is full and there are pending messages in kfifo, else send the message directly in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d9aa87c..cc58b44 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (kfifo_is_empty(mq-fifo) !__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 4/4] OMAP: mailbox: add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |7 +- arch/arm/plat-omap/mailbox.c | 103 - 2 files changed, 61 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..cc3921e 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -46,7 +46,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +57,15 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index cc58b44..459b319 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); spin_lock_irq(mq-lock); if (mq-full) { mq-full = false; @@ -249,41 +250,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; - } - mbox_configured++; - mutex_unlock(mbox_configured_lock); + if (unlikely(ret)) + goto fail_startup; + } else + goto fail_startup; } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq; + } + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret = -ENOMEM
[PATCH v4 0/5] OMAP: mailbox: fixes and enhancements
Thanks to Benoit and Felipe Balbi for their comments. Here is the revised set taking into account comments received. - Added more description for checkpatch warnings - Created revision field to check for mailbox IP version to use for rx interrupt disable functionality. - Cleaned up description in change full flag per mailbox patch. References: http://marc.info/?l=linux-omapm=129012283514652w=2 http://marc.info/?l=linux-omapm=129016767426046w=2 http://www.mail-archive.com/linux-omap@vger.kernel.org/msg38826.html The previous versions of this patch set can be found here === http://www.spinics.net/lists/arm-kernel/msg104544.html http://www.spinics.net/lists/linux-omap/msg39988.html http://www.spinics.net/lists/linux-omap/msg39931.html http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37278.html Fernando Guzman Lugo (1): OMAP: mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (4): OMAP: mailbox: fix rx interrupt disable in omap4 OMAP: mailbox: fix checkpatch warnings OMAP: mailbox: send message in process context OMAP: mailbox: add notification support for multiple readers arch/arm/mach-omap2/mailbox.c |7 ++- arch/arm/plat-omap/include/plat/mailbox.h | 12 ++- arch/arm/plat-omap/mailbox.c | 135 + 3 files changed, 96 insertions(+), 58 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] OMAP: mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com The variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflicts. Now there is a full flag per mailbox queue. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |9 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..48e161c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,12 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + spin_lock_irq(mq-lock); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } + spin_unlock_irq(mq-lock); } } @@ -170,7 +175,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/5] OMAP: mailbox: fix rx interrupt disable in omap4
disablign rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Defined rev field in mailbox structure to differentiate the mailbox versions. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |7 ++- arch/arm/plat-omap/include/plat/mailbox.h |4 arch/arm/plat-omap/mailbox.c |4 3 files changed, 14 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..c32058d 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,12 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + + if (mbox-rev == OMAP_MBOX_IP_VERSION_2) + l |= bit; + else + l = ~bit; + mbox_write_reg(l, p-irqdisable); } diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..1655c61 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -20,6 +20,9 @@ typedef int __bitwise omap_mbox_type_t; #define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1) #define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2) +#define OMAP_MBOX_IP_LEGACY0x1 +#define OMAP_MBOX_IP_VERSION_2 0x2 + struct omap_mbox_ops { omap_mbox_type_ttype; int (*startup)(struct omap_mbox *mbox); @@ -58,6 +61,7 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + int rev; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 48e161c..a1c6bd9 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -358,6 +358,10 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list) ret = PTR_ERR(mbox-dev); goto err_out; } + if (cpu_is_omap44xx()) + mbox-rev = OMAP_MBOX_IP_VERSION_2; + else + mbox-rev = OMAP_MBOX_IP_LEGACY; } return 0; -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/5] OMAP: mailbox: fix checkpatch warnings
Fix the following checkpatch warnings observed in mailbox module. WARNING: please, no space for starting a line, excluding comments + fail_alloc_rxq:$ WARNING: please, no space for starting a line, excluding comments + fail_alloc_txq:$ WARNING: please, no space for starting a line, excluding comments + fail_request_irq:$ WARNING: line over 80 characters + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index a1c6bd9..13698ab 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -281,11 +281,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -400,7 +400,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 4/5] OMAP: mailbox: send message in process context
Schedule the Tasklet to send only when mailbox fifo is full and there are pending messages in kifo, else send the message directly in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 13698ab..f4177df 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (kfifo_is_empty(mq-fifo) !__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 5/5] OMAP: mailbox: add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |7 +- arch/arm/plat-omap/mailbox.c | 104 - 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 1655c61..839c6c3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -49,7 +49,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -62,13 +61,15 @@ struct omap_mbox { struct device *dev; void*priv; int rev; + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index f4177df..05d1c9c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); spin_lock_irq(mq-lock); if (mq-full) { mq-full = false; @@ -249,41 +250,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; - } - mbox_configured++; - mutex_unlock(mbox_configured_lock); + if (unlikely(ret)) + goto fail_startup; + } else + goto fail_startup; } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq; + } + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret = -ENOMEM
[PATCH v3 3/5] OMAP: mailbox: fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..abfc495 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/5] OMAP: mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/5] OMAP: mailbox: fix rx interrupt disable in omap4
disabling rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..82b5ced 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,10 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + if (cpu_is_omap44xx()) + l |= bit; + else + l = ~bit; mbox_write_reg(l, p-irqdisable); } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/5] OMAP: mailbox: enhancements and fixes
Sending the patch set by seperating the clock related patch seperated out based on Paul Walmsey's comment. http://www.spinics.net/lists/arm-kernel/msg103692.html The clock patch will be sent out as a seperate patch. The previous versions of this patch set can be found here http://www.spinics.net/lists/linux-omap/msg39988.html http://www.spinics.net/lists/linux-omap/msg39931.html http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37278.html Fernando Guzman Lugo (1): OMAP: mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (4): OMAP: mailbox: fix rx interrupt disable in omap4 OMAP: mailbox: fix checkpatch warnings OMAP: mailbox: send message in process context OMAP: mailbox: add notification support for multiple readers arch/arm/mach-omap2/mailbox.c |5 +- arch/arm/plat-omap/include/plat/mailbox.h |8 +- arch/arm/plat-omap/mailbox.c | 127 + 3 files changed, 82 insertions(+), 58 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/5] OMAP: mailbox: send message in process context
Schedule the Tasklet to send only when mailbox fifo is full and there are pending messages in kifo, else send the message directly in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index abfc495..b14bc34 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (kfifo_is_empty(mq-fifo) !__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 5/5] OMAP: mailbox: add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |7 +- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..cc3921e 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -46,7 +46,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +57,15 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index b14bc34..b1f8f2c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -247,41 +248,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; - } - mbox_configured++; - mutex_unlock(mbox_configured_lock); + if (unlikely(ret)) + goto fail_startup; + } else + goto fail_startup; } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq; + } + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret
[PATCH] OMAP4: clocks: add dummy clock for mailbox
In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/clock44xx_data.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e10db7a..bdd9b85 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2687,6 +2687,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, uart3_ick,dummy_ck, CK_443X), CLK(NULL, uart4_ick,dummy_ck, CK_443X), CLK(omap_wdt, ick, dummy_ck, CK_443X), + CLK(NULL, mailboxes_ick,dummy_ck, CK_443X), }; int __init omap4xxx_clk_init(void) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] omap:clocks44x-add dummy clock for mailbox
In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/clock44xx_data.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e10db7a..421ae7f 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2687,6 +2687,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, uart3_ick,dummy_ck, CK_443X), CLK(NULL, uart4_ick,dummy_ck, CK_443X), CLK(omap_wdt, ick, dummy_ck, CK_443X), + CLK(NULL, mailboxes_ick,dummy_ck, CK_443X), }; int __init omap4xxx_clk_init(void) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] omap:mailbox: fix rx interrupt disable in omap4
disabling rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..82b5ced 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,10 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + if (cpu_is_omap44xx()) + l |= bit; + else + l = ~bit; mbox_write_reg(l, p-irqdisable); } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] omap:mailbox-fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..ed960c1 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] omap:mailbox-add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |7 +- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..cc3921e 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -46,7 +46,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +57,15 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index e353e26..53895c6 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -247,41 +248,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; - } - mbox_configured++; - mutex_unlock(mbox_configured_lock); + if (unlikely(ret)) + goto fail_startup; + } else + goto fail_startup; } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq; + } + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret
[PATCH 1/6] mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] omap:mailbox-send message in process context
Schedule the Tasklet to send only when mailbox fifo is full and there are pending messages in kifo, else send the message directly in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ed960c1..e353e26 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (kfifo_is_empty(mq-fifo) !__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] [v2] omap:mailbox-enhancements and fixes
Thanks to Rene Sapiens and Omar Ramirez for their inputs on initial patch set. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37278.html The patch set addresses the following review comments from Rene and Omar. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37626.html https://patchwork.kernel.org/patch/255091/ https://patchwork.kernel.org/patch/255081/ Following patches are changed because of above review comments: omap:mailbox-send message in process context omap:mailbox-add notification support for multiple readers Following patch is dropped from initial patch set omap:mailbox-resolve multiple receiver problem The patch set is tested on omap4 SDP board. Fernando Guzman Lugo (1): mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (5): omap:mailbox: fix rx interrupt disable in omap4 omap:mailbox-fix checkpatch warnings omap:mailbox-send message in process context omap:mailbox-add notification support for multiple readers omap:clocks44x-add dummy clock for mailbox arch/arm/mach-omap2/clock44xx_data.c |1 + arch/arm/mach-omap2/mailbox.c |5 +- arch/arm/plat-omap/include/plat/mailbox.h |8 +- arch/arm/plat-omap/mailbox.c | 127 + 4 files changed, 83 insertions(+), 58 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/6] OMAP: mailbox: fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..abfc495 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 6/6] OMAP4: clocks: add dummy clock for mailbox
In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/clock44xx_data.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e10db7a..bdd9b85 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2687,6 +2687,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, uart3_ick,dummy_ck, CK_443X), CLK(NULL, uart4_ick,dummy_ck, CK_443X), CLK(omap_wdt, ick, dummy_ck, CK_443X), + CLK(NULL, mailboxes_ick,dummy_ck, CK_443X), }; int __init omap4xxx_clk_init(void) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/6] OMAP: mailbox: add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |7 +- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 60 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..cc3921e 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -46,7 +46,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +57,15 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index b14bc34..b1f8f2c 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -247,41 +248,40 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; - } - mbox_configured++; - mutex_unlock(mbox_configured_lock); + if (unlikely(ret)) + goto fail_startup; + } else + goto fail_startup; } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq; + } + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret
[PATCH v2 4/6] OMAP: mailbox: send message in process context
Schedule the Tasklet to send only when mailbox fifo is full and there are pending messages in kifo, else send the message directly in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index abfc495..b14bc34 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (kfifo_is_empty(mq-fifo) !__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/6] OMAP: mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/6] [v2] OMAP: mailbox: enhancements and fixes
Benoit, Resending correcting the subject format based on Benoit's comment and fixing the over-indentation pointed out by Sergei. Pure nitpicking: That's a pretty fast update... but then it should be a v3 :-) Have to do it fast to keep your attention :). Since you are saying it is pure nitpicking I will leave it at v2 unless you insist. Why does the cover letter not use the same format? [PATCH 0/6] [v2] instead of [PATCH v2 0/6] Will take care of in this next revisions. Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/6] omap:clocks44x-add dummy clock for mailbox
Paul, On Wed, Nov 10, 2010 at 5:27 PM, Paul Walmsley p...@pwsan.com wrote: Hello Hari On Wed, 10 Nov 2010, Hari Kanigeri wrote: In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. If you split this off from the rest of your series, I'll queue it for .38. Thanks. I will send this patch separately. Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/7] omap:mailbox-add notification support for multiple readers
Omar, static void omap_mbox_fini(struct omap_mbox *mbox) { + if (!--mbox-use_count) { + tasklet_kill(mbox-txq-tasklet); + flush_work(mbox-rxq-work); + mbox_queue_free(mbox-txq); + mbox_queue_free(mbox-rxq); + } + + if (likely(mbox-ops-shutdown)) { + if (!--mbox_configured) { + free_irq(mbox-irq, mbox); Above hunks will create an imbalance of free_irq, as request_irq can be called per registered mailbox and free_irq is only done for the last caller releasing the mailbox handle. e.g.: mbox-1, mbox-N will request a shared irq on the same interrupt line, but only the last caller of omap_mbox_put will free its irq, leaving the other one there. This can be fixed if the free is moved to be executed within the following block: if (!--mbox-use_count) { ... free_irq(mbox-irq, mbox); } Good catch. I will make the changes in next revision. Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/7] omap:mailbox-resolve multiple receiver problem
Omar, OMAP4 shares one interrupt line for all the mailbox instances. The ISR is handling only the mailbox instance that was registered last. This shouldn't be needed, request_irq is being called with IRQF_SHARED flag and different device ids, so if a message arrives it fires an interrupt handler for each of the callers to request_irq and since the device id is actually a pointer to a mbox struct, the different users can be detected and signaled without looping through the mboxes list. Also using mboxes list, will try to check for all registered mailboxes during probe, which might not be the same as the actual users (the ones that have called omap_mbox_get) and then unnecesary check their irq statuses if an interrupt arrives. I think this patch can be dropped. Agree, I will drop the patch and send the rebased patches. Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/7] omap:mailbox-send message in process context
Rene, Thanks for your comment. @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); Please check if this scenario looks valid to you, as discussed and depicted with Fernando: Supposing that at this point the hw fifo is full and there are messages in the kfifo. if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } We reach this point. In this scenario, the DSP or other Core reads a message from the mbox hw fifo. The next happens: 1.- The not full interrupt is triggered to the MPU. 2.- The mbox's ISR schedules the tasklet to write the message. 3.- The ISR is left and returns to here (since we still have the bh lock the tasklet won't run). + if (!__mbox_poll_for_space(mbox)) {\ 4.- We check for mbox_fifo_full and we have space. so the message is written. + mbox_fifo_write(mbox, msg); At this point it looks that the FIFO order is lost. We write this message before the ones in the kfifo. Good point. I agree. A solution for this could be checking if there are messages in the kfifo before trying to write directly to the hw fifo, if so, just continue scheduling the tasklet. A change something like this ? - if (!__mbox_poll_for_space(mbox)) { + if (kfifo_is_empty() !__mbox_poll_for_space(mbox)) { mbox_fifo_write(mbox, msg); Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] omap:mailbox-fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..ed960c1 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] omap:mailbox-enhancements and fixes
Resending the patch set copying linux arm mailing list. please ignore the previous patchset. [http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37214.html] This patch set includes following mailbox enhancements and fixes. - Fix in RX interrupt disable mechanism for OMAP4 - Fix checkpatch warnings - Resolve multiple receiver problem in OMAP4 where there is only one interrupt line shared between Ducati and Tesla. - Protect the Mailbox's internal callback function pointer from being set directly by Users. Added option for multiple listeners on a mailbox instance. - Send Mailbox message in Process context to avoid the latency involved in scheduling Tasklet for every Mailbox message. Schedule Tasklet only when the mailbox fifo is full - There is no explicit mailbox configuration register to enable mailbox clocks. Define a dummy clock for mailbox to avoid addign cpu check for omap4 in mailbox driver. - The patch from Fernando was sent to LO, but looks like it didn't get merged, resending the patch after revising and rebasing. https://patchwork.kernel.org/patch/105650/ Fernando Guzman Lugo (1): mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (6): omap:mailbox: fix rx interrupt disable in omap4 omap:mailbox-fix checkpatch warnings omap:mailbox-send message in process context omap:mailbox-resolve multiple receiver problem omap:mailbox-add notification support for multiple readers omap:clocks44x-add dummy clock for mailbox arch/arm/mach-omap2/clock44xx_data.c |1 + arch/arm/mach-omap2/mailbox.c |5 +- arch/arm/plat-omap/include/plat/mailbox.h | 10 ++- arch/arm/plat-omap/mailbox.c | 148 + 4 files changed, 98 insertions(+), 66 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] omap:mailbox-send message in process context
Schedule the Tasklet to send only when mailbox fifo is full, else send the message in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ed960c1..a4170c7 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (!__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] omap:mailbox: fix rx interrupt disable in omap4
disabling rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..82b5ced 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,10 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + if (cpu_is_omap44xx()) + l |= bit; + else + l = ~bit; mbox_write_reg(l, p-irqdisable); } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] omap:mailbox-resolve multiple receiver problem
OMAP4 shares one interrupt line for all the mailbox instances. The ISR is handling only the mailbox instance that was registered last. So if both mailbox instances are running at the same time, the first mailbox that registered wouldn't get the mailbox message. The same issue is present in Transmit Interrupt case too. Only the last registered mailbox is handled. The fix is to iterate through the list of mailboxes that were registered checking for the mailbox TX and RX interrupt source. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com Signed-off-by: Subramaniam C.A subramaniam...@ti.com --- arch/arm/plat-omap/mailbox.c | 21 + 1 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index a4170c7..1727548 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -174,6 +174,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) struct omap_mbox_queue *mq = mbox-rxq; mbox_msg_t msg; int len; + bool msg_rx = false; while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { @@ -181,7 +182,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) mq-full = true; goto nomem; } - + msg_rx = true; msg = mbox_fifo_read(mbox); len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); @@ -192,21 +193,25 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) } /* no more messages in the fifo. clear IRQ source. */ - ack_mbox_irq(mbox, IRQ_RX); + if (msg_rx) + ack_mbox_irq(mbox, IRQ_RX); nomem: - queue_work(mboxd, mbox-rxq-work); + if (msg_rx) + queue_work(mboxd, mbox-rxq-work); } static irqreturn_t mbox_interrupt(int irq, void *p) { struct omap_mbox *mbox = p; - if (is_mbox_irq(mbox, IRQ_TX)) - __mbox_tx_interrupt(mbox); - - if (is_mbox_irq(mbox, IRQ_RX)) - __mbox_rx_interrupt(mbox); + for (i = 0; mboxes[i]; i++) { + struct omap_mbox *mbox = mboxes[i]; + if (is_mbox_irq(mbox, IRQ_TX)) + __mbox_tx_interrupt(mbox); + if (is_mbox_irq(mbox, IRQ_RX)) + __mbox_rx_interrupt(mbox); + } return IRQ_HANDLED; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] omap:mailbox-add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |9 ++- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..4c35654 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -8,6 +8,7 @@ #include linux/interrupt.h #include linux/device.h #include linux/kfifo.h +#include linux/notifier.h typedef u32 mbox_msg_t; struct omap_mbox; @@ -46,7 +47,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +58,16 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 1727548..35956f5 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -202,7 +203,7 @@ nomem: static irqreturn_t mbox_interrupt(int irq, void *p) { - struct omap_mbox *mbox = p; + int i; for (i = 0; mboxes[i]; i++) { struct omap_mbox *mbox = mboxes[i]; @@ -252,41 +253,39 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; + if (unlikely(ret)) + goto fail_startup; } - mbox_configured++; - mutex_unlock(mbox_configured_lock); } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq
[PATCH 2/7] omap:mailbox: fix rx interrupt disable in omap4
disabling rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..82b5ced 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,10 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + if (cpu_is_omap44xx()) + l |= bit; + else + l = ~bit; mbox_write_reg(l, p-irqdisable); } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] omap:clocks44x-add dummy clock for mailbox
In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/clock44xx_data.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e10db7a..421ae7f 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2687,6 +2687,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, uart3_ick,dummy_ck, CK_443X), CLK(NULL, uart4_ick,dummy_ck, CK_443X), CLK(omap_wdt, ick, dummy_ck, CK_443X), + CLK(NULL, mailboxes_ick,dummy_ck, CK_443X), }; int __init omap4xxx_clk_init(void) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] omap:mailbox-fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..ed960c1 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] omap:mailbox-enhancements and fixes
My apologies for spamming linux omap. Resending again with the patch set copying correct linux arm mailing list. please ignore the previous patchsets. [http://www.spinics.net/lists/linux-omap/msg38782.html] [http://www.mail-archive.com/linux-omap@vger.kernel.org/msg37214.html] This patch set includes following mailbox enhancements and fixes. - Fix in RX interrupt disable mechanism for OMAP4 - Fix checkpatch warnings - Resolve multiple receiver problem in OMAP4 where there is only one interrupt line shared between Ducati and Tesla. - Protect the Mailbox's internal callback function pointer from being set directly by Users. Added option for multiple listeners on a mailbox instance. - Send Mailbox message in Process context to avoid the latency involved in scheduling Tasklet for every Mailbox message. Schedule Tasklet only when the mailbox fifo is full - There is no explicit mailbox configuration register to enable mailbox clocks. Define a dummy clock for mailbox to avoid addign cpu check for omap4 in mailbox driver. - The patch from Fernando was sent to LO, but looks like it didn't get merged, resending the patch after revising and rebasing. https://patchwork.kernel.org/patch/105650/ Fernando Guzman Lugo (1): mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (6): omap:mailbox: fix rx interrupt disable in omap4 omap:mailbox-fix checkpatch warnings omap:mailbox-send message in process context omap:mailbox-resolve multiple receiver problem omap:mailbox-add notification support for multiple readers omap:clocks44x-add dummy clock for mailbox arch/arm/mach-omap2/clock44xx_data.c |1 + arch/arm/mach-omap2/mailbox.c |5 +- arch/arm/plat-omap/include/plat/mailbox.h | 10 ++- arch/arm/plat-omap/mailbox.c | 148 + 4 files changed, 98 insertions(+), 66 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] omap:mailbox-send message in process context
Schedule the Tasklet to send only when mailbox fifo is full, else send the message in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ed960c1..a4170c7 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (!__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] omap:mailbox-add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |9 ++- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..4c35654 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -8,6 +8,7 @@ #include linux/interrupt.h #include linux/device.h #include linux/kfifo.h +#include linux/notifier.h typedef u32 mbox_msg_t; struct omap_mbox; @@ -46,7 +47,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +58,16 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 1727548..35956f5 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -202,7 +203,7 @@ nomem: static irqreturn_t mbox_interrupt(int irq, void *p) { - struct omap_mbox *mbox = p; + int i; for (i = 0; mboxes[i]; i++) { struct omap_mbox *mbox = mboxes[i]; @@ -252,41 +253,39 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; + if (unlikely(ret)) + goto fail_startup; } - mbox_configured++; - mutex_unlock(mbox_configured_lock); } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq
[PATCH 5/7] omap:mailbox-resolve multiple receiver problem
OMAP4 shares one interrupt line for all the mailbox instances. The ISR is handling only the mailbox instance that was registered last. So if both mailbox instances are running at the same time, the first mailbox that registered wouldn't get the mailbox message. The same issue is present in Transmit Interrupt case too. Only the last registered mailbox is handled. The fix is to iterate through the list of mailboxes that were registered checking for the mailbox TX and RX interrupt source. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com Signed-off-by: Subramaniam C.A subramaniam...@ti.com --- arch/arm/plat-omap/mailbox.c | 21 + 1 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index a4170c7..1727548 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -174,6 +174,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) struct omap_mbox_queue *mq = mbox-rxq; mbox_msg_t msg; int len; + bool msg_rx = false; while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { @@ -181,7 +182,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) mq-full = true; goto nomem; } - + msg_rx = true; msg = mbox_fifo_read(mbox); len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); @@ -192,21 +193,25 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) } /* no more messages in the fifo. clear IRQ source. */ - ack_mbox_irq(mbox, IRQ_RX); + if (msg_rx) + ack_mbox_irq(mbox, IRQ_RX); nomem: - queue_work(mboxd, mbox-rxq-work); + if (msg_rx) + queue_work(mboxd, mbox-rxq-work); } static irqreturn_t mbox_interrupt(int irq, void *p) { struct omap_mbox *mbox = p; - if (is_mbox_irq(mbox, IRQ_TX)) - __mbox_tx_interrupt(mbox); - - if (is_mbox_irq(mbox, IRQ_RX)) - __mbox_rx_interrupt(mbox); + for (i = 0; mboxes[i]; i++) { + struct omap_mbox *mbox = mboxes[i]; + if (is_mbox_irq(mbox, IRQ_TX)) + __mbox_tx_interrupt(mbox); + if (is_mbox_irq(mbox, IRQ_RX)) + __mbox_rx_interrupt(mbox); + } return IRQ_HANDLED; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/7] omap:mailbox-send message in process context
Schedule the Tasklet to send only when mailbox fifo is full, else send the message in the Process context. This would avoid needless scheduling of Tasklet for every message transfer Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ed960c1..a4170c7 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -92,20 +92,25 @@ int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) struct omap_mbox_queue *mq = mbox-txq; int ret = 0, len; - spin_lock(mq-lock); + spin_lock_bh(mq-lock); if (kfifo_avail(mq-fifo) sizeof(msg)) { ret = -ENOMEM; goto out; } + if (!__mbox_poll_for_space(mbox)) { + mbox_fifo_write(mbox, msg); + goto out; + } + len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); tasklet_schedule(mbox-txq-tasklet); out: - spin_unlock(mq-lock); + spin_unlock_bh(mq-lock); return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/7] omap:mailbox-add notification support for multiple readers
In the current mailbox driver, the mailbox internal pointer for callback can be directly manipulated by the Users, so a second User can easily corrupt the first user's callback pointer. The initial effort to correct this issue can be referred here: https://patchwork.kernel.org/patch/107520/ Along with fixing the above stated issue, this patch adds the flexibility option to register notifications from multiple readers to the events received on a mailbox instance. The discussion regarding this can be referred here. http://www.mail-archive.com/linux-omap@vger.kernel.org/msg30671.html Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |9 ++- arch/arm/plat-omap/mailbox.c | 102 - 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 13f2ef3..4c35654 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -8,6 +8,7 @@ #include linux/interrupt.h #include linux/device.h #include linux/kfifo.h +#include linux/notifier.h typedef u32 mbox_msg_t; struct omap_mbox; @@ -46,7 +47,6 @@ struct omap_mbox_queue { struct kfifofifo; struct work_struct work; struct tasklet_struct tasklet; - int (*callback)(void *); struct omap_mbox*mbox; bool full; }; @@ -58,13 +58,16 @@ struct omap_mbox { struct omap_mbox_ops*ops; struct device *dev; void*priv; + + int use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox **); int omap_mbox_unregister(void); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 1727548..35956f5 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -28,6 +28,7 @@ #include linux/slab.h #include linux/kfifo.h #include linux/err.h +#include linux/notifier.h #include plat/mailbox.h @@ -150,8 +151,8 @@ static void mbox_rx_work(struct work_struct *work) len = kfifo_out(mq-fifo, (unsigned char *)msg, sizeof(msg)); WARN_ON(len != sizeof(msg)); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); if (mq-full) { mq-full = false; omap_mbox_enable_irq(mq-mbox, IRQ_RX); @@ -202,7 +203,7 @@ nomem: static irqreturn_t mbox_interrupt(int irq, void *p) { - struct omap_mbox *mbox = p; + int i; for (i = 0; mboxes[i]; i++) { struct omap_mbox *mbox = mboxes[i]; @@ -252,41 +253,39 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (mbox-ops-startup) { - mutex_lock(mbox_configured_lock); - if (!mbox_configured) + mutex_lock(mbox_configured_lock); + if (!mbox_configured++) { + if (likely(mbox-ops-startup)) { ret = mbox-ops-startup(mbox); - - if (ret) { - mutex_unlock(mbox_configured_lock); - return ret; + if (unlikely(ret)) + goto fail_startup; } - mbox_configured++; - mutex_unlock(mbox_configured_lock); } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (ret) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } - - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + if (!mbox-use_count++) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + pr_err(failed to register mailbox interrupt:%d\n, + ret); + goto fail_request_irq
[PATCH 1/7] mailbox: change full flag per mailbox queue instead of global
From: Fernando Guzman Lugo x0095...@ti.com As pointed by Ohad Ben-Cohen, the variable rq_full flag is a global variable, so if there are multiple mailbox users there will be conflics. Now there is a full flag per mailbox queue. Version 2: - Rebase to the latest. Version 3: - Remove spin_lock protection. When the full flag is true the interrupt for that mailbox is disabled. So there is no race condition if full flag is modified before calling omap_mbox_enable_irq. Reported-by: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Fernando Guzman Lugo x0095...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |1 + arch/arm/plat-omap/mailbox.c |7 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 9976565..13f2ef3 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -48,6 +48,7 @@ struct omap_mbox_queue { struct tasklet_struct tasklet; int (*callback)(void *); struct omap_mbox*mbox; + bool full; }; struct omap_mbox { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index d2fafb8..9ce3570 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,7 +33,6 @@ static struct workqueue_struct *mboxd; static struct omap_mbox **mboxes; -static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -148,6 +147,10 @@ static void mbox_rx_work(struct work_struct *work) if (mq-callback) mq-callback((void *)msg); + if (mq-full) { + mq-full = false; + omap_mbox_enable_irq(mq-mbox, IRQ_RX); + } } } @@ -170,7 +173,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); - rq_full = true; + mq-full = true; goto nomem; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] omap:mailbox-resolve multiple receiver problem
OMAP4 shares one interrupt line for all the mailbox instances. The ISR is handling only the mailbox instance that was registered last. So if both mailbox instances are running at the same time, the first mailbox that registered wouldn't get the mailbox message. The same issue is present in Transmit Interrupt case too. Only the last registered mailbox is handled. The fix is to iterate through the list of mailboxes that were registered checking for the mailbox TX and RX interrupt source. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com Signed-off-by: Subramaniam C.A subramaniam...@ti.com --- arch/arm/plat-omap/mailbox.c | 21 + 1 files changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index a4170c7..1727548 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -174,6 +174,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) struct omap_mbox_queue *mq = mbox-rxq; mbox_msg_t msg; int len; + bool msg_rx = false; while (!mbox_fifo_empty(mbox)) { if (unlikely(kfifo_avail(mq-fifo) sizeof(msg))) { @@ -181,7 +182,7 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) mq-full = true; goto nomem; } - + msg_rx = true; msg = mbox_fifo_read(mbox); len = kfifo_in(mq-fifo, (unsigned char *)msg, sizeof(msg)); @@ -192,21 +193,25 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) } /* no more messages in the fifo. clear IRQ source. */ - ack_mbox_irq(mbox, IRQ_RX); + if (msg_rx) + ack_mbox_irq(mbox, IRQ_RX); nomem: - queue_work(mboxd, mbox-rxq-work); + if (msg_rx) + queue_work(mboxd, mbox-rxq-work); } static irqreturn_t mbox_interrupt(int irq, void *p) { struct omap_mbox *mbox = p; - if (is_mbox_irq(mbox, IRQ_TX)) - __mbox_tx_interrupt(mbox); - - if (is_mbox_irq(mbox, IRQ_RX)) - __mbox_rx_interrupt(mbox); + for (i = 0; mboxes[i]; i++) { + struct omap_mbox *mbox = mboxes[i]; + if (is_mbox_irq(mbox, IRQ_TX)) + __mbox_tx_interrupt(mbox); + if (is_mbox_irq(mbox, IRQ_RX)) + __mbox_rx_interrupt(mbox); + } return IRQ_HANDLED; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] omap:mailbox: fix rx interrupt disable in omap4
disabling rx interrupt on omap4 is different than its pre-decessors. The bit in OMAP4_MAILBOX_IRQENABLE_CLR should be set to disable the interrupts instead of clearing the bit. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/mailbox.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index 42dbfa4..82b5ced 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -195,7 +195,10 @@ static void omap2_mbox_disable_irq(struct omap_mbox *mbox, struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox-priv; u32 l, bit = (irq == IRQ_TX) ? p-notfull_bit : p-newmsg_bit; l = mbox_read_reg(p-irqdisable); - l = ~bit; + if (cpu_is_omap44xx()) + l |= bit; + else + l = ~bit; mbox_write_reg(l, p-irqdisable); } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/7] omap:clocks44x-add dummy clock for mailbox
In omap4, there is no explicit configuration register to enable mailbox clocks. Defining dummy clock for mailbox clock module to keep the mailbox driver backward compatible with previous omaps. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/clock44xx_data.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index e10db7a..421ae7f 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -2687,6 +2687,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, uart3_ick,dummy_ck, CK_443X), CLK(NULL, uart4_ick,dummy_ck, CK_443X), CLK(omap_wdt, ick, dummy_ck, CK_443X), + CLK(NULL, mailboxes_ick,dummy_ck, CK_443X), }; int __init omap4xxx_clk_init(void) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/7] omap:mailbox-fix checkpatch warnings
Fix the checkpatch warnings observed in mailbox module Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/mailbox.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 9ce3570..ed960c1 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -279,11 +279,11 @@ static int omap_mbox_startup(struct omap_mbox *mbox) return 0; - fail_alloc_rxq: +fail_alloc_rxq: mbox_queue_free(mbox-txq); - fail_alloc_txq: +fail_alloc_txq: free_irq(mbox-irq, mbox); - fail_request_irq: +fail_request_irq: if (mbox-ops-shutdown) mbox-ops-shutdown(mbox); @@ -394,7 +394,8 @@ static int __init omap_mbox_init(void) /* kfifo size sanity check: alignment and minimal size */ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); - mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, + sizeof(mbox_msg_t)); return 0; } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/7] omap:mailbox-enhancments and fixes
This patch set includes following mailbox enhancments and fixes. - Fix in RX interrupt disable mechanism for OMAP4 - Fix checkpatch warnings - Resolve multiple receiver problem in OMAP4 where there is only one interrupt line shared between Ducati and Tesla. - Protect the Mailbox's internal callback function pointer from being set directly by Users. Added option for multiple listeners on a mailbox instance. - Send Mailbox message in Process context to avoid the latency involved in scheduling Tasklet for every Mailbox message. Schedule Tasklet only when the mailbox fifo is full - There is no explicit mailbox configuration register to enable mailbox clocks. Define a dummy clock for mailbox to avoid addign cpu check for omap4 in mailbox driver. - The patch from Fernando was sent to LO, but looks like it didn't get merged, resending the patch after revising and rebasing. Fernando Guzman Lugo (1): mailbox: change full flag per mailbox queue instead of global Hari Kanigeri (6): omap:mailbox: fix rx interrupt disable in omap4 omap:mailbox-fix checkpatch warnings omap:mailbox-send message in process context omap:mailbox-resolve multiple receiver problem omap:mailbox-add notification support for multiple readers omap:clocks44x-add dummy clock for mailbox arch/arm/mach-omap2/clock44xx_data.c |1 + arch/arm/mach-omap2/mailbox.c |5 +- arch/arm/plat-omap/include/plat/mailbox.h | 10 ++- arch/arm/plat-omap/mailbox.c | 148 + 4 files changed, 98 insertions(+), 66 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap:iommu-load cam register before flushing the entry
The flush_iotlb_page is not loading the cam register before flushing the cam entry. This causes wrong entry to be flushed out from the TLB, and if the entry happens to be a locked TLB entry it would lead to MMU faults. The fix is to load the cam register with the address to be flushed before flushing the TLB entry. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/iommu.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 2e603fe..c534280 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -315,6 +315,7 @@ void flush_iotlb_page(struct iommu *obj, u32 da) if ((start = da) (da start + bytes)) { dev_dbg(obj-dev, %s: %08x=%08x(%x)\n, __func__, start, da, bytes); + iotlb_load_cr(obj, cr); iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY); } } -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dspbridge and the omapl1x
Mugdha, On Thu, Aug 12, 2010 at 1:16 AM, Kamoolkar, Mugdha mug...@ti.com wrote: Ben, I'm still not sure about the iommu features required by dspbridge, I will need to look into this. But 2+3 sound like they could be provided by DSPLink itself. Would it be sane to put dspbridge on top of DSPLink? Just to sound it out, the DSP-side base image could be DSPBios + DSPLink (DSP-side) and the ARM-side would be made of dspbridge where the IPC is DSP Link 'compatible'. This could avoid a rewrite of the DSP-side of dspbridge maybe? Probably over-kill to get the features you want. iommu could not be adapted for OMAPL1xx since it abstracts the DSP MMU, which is non-existent on OMAPL1xx devices. Also, OMAPL1xx devices do not use mailbox interrupts. They have a different type of IPC interrupt, which is not mailbox. So a different kind of abstraction would be required to be able to use either mailbox or this different IPC interrupt. Thanks for providing information on OMAPL1xx devices. I wasn't aware of OMAP1 architecture. Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dspbridge and the omapl1x
On Thu, Aug 12, 2010 at 2:16 AM, Kamoolkar, Mugdha mug...@ti.com wrote: You are correct that dynamic linking and loading is a feature that is available in DSPBridge, and which is missing in DSPLink, which could work on OMAPL1xx if you ported DSPBridge to OMAPL1xx I imagined that the lack of MMU would be a blocker in porting dspbridge since it would be impossible to support scattered (in PAs) pages on the DSP-side. But Mugdha makes it sound like the port could be accomplished with DMM omitted. Also I believe that the new Contiguous Memory Allocation (CMA) framework was developed specifically for systems that need to allocate physically contiguous memory because they don't have an MMU. What would say to avoiding the IOMMU requirement and keeping DMM by using physically contiguous dynamically allocated memory regions like those provided by the new CMA [2]? Just curious as how CMA is different from Android's pmem. Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dspbridge and the omapl1x
Ben, Yes, dynamic memory management. With DSP Link on the OMAPL138 the memory allocated to the DSP must be specified as a 'hole' in Linux memory at boot-time [1[2][3]. It seems (perhaps this is wishful thinking) that dspbridge does not have this limitation. DSPBridge doesn't has this requirement. Also dynamic application loading. With DSP Link it is possible to run multiple linux processes concurrently communicating with DSP tasks but the image loaded and executed on the DSP side must contain the code for all of the tasks at load time [4]. It seems that dspbridge does not have this limitation. I am very interested in learning details about both dsplink and dspbridge; please reply with more details or corrections as you see fit. DSPBridge and DSPLink IPCs are for 2 different purposes. So before you make a switch to one of the IPC, I would recommend to you to make sure your requirements are met. To check the differences between DSPBridge and DSPLink, please check this email thread contributed by Richard W. http://linux.omap.com/pipermail/linux-omap-open-source/2007-May/009850.html. We are working on making some of core functionalities such as DMM, resource Management, reset Management of co-processors generic for any IPC to use. So if DSPLink is missing DMM functionality then it should be just the matter of DSPLink adapting to this. I am not aware of the official word from T.I to support dspbridge on OMAP1, but as the community you will have the support in case you want to go with dspbridge option. On a high level, this is what needs to be done to provide support for OMAP1. 1. Adapt to iommu. Add support if the support is not present for OMAP1. 2. Adapt to mailbox 3. Reset and Power management adaptation for OMAP1. Thank you, Best regards, Hari Best Regards, Ben Gardiner [1] http://processors.wiki.ti.com/index.php/Changing_DSPLink_Memory_Map [2] http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/29571.aspx [3] http://code.google.com/p/rowboat/wiki/DSP [4] http://processors.wiki.ti.com/index.php/Using_DSPLink_from_multiple_processes --- Nanometrics Inc. http://www.nanometrics.ca -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dspbridge and the omapl1x
Ben, On Wed, Aug 11, 2010 at 2:25 PM, Ben Gardiner bengardi...@nanometrics.ca wrote: Hello Hari, On Wed, Aug 11, 2010 at 12:55 PM, Hari Kanigeri hari.kanig...@gmail.com wrote: Ben, Yes, dynamic memory management. With DSP Link on the OMAPL138 the memory allocated to the DSP must be specified as a 'hole' in Linux memory at boot-time [1[2][3]. It seems (perhaps this is wishful thinking) that dspbridge does not have this limitation. DSPBridge doesn't has this requirement. Thank you for confirming. Also dynamic application loading. With DSP Link it is possible to run multiple linux processes concurrently communicating with DSP tasks but the image loaded and executed on the DSP side must contain the code for all of the tasks at load time [4]. It seems that dspbridge does not have this limitation. I am very interested in learning details about both dsplink and dspbridge; please reply with more details or corrections as you see fit. DSPBridge and DSPLink IPCs are for 2 different purposes. So before you make a switch to one of the IPC, I would recommend to you to make sure your requirements are met. To check the differences between DSPBridge and DSPLink, please check this email thread contributed by Richard W. http://linux.omap.com/pipermail/linux-omap-open-source/2007-May/009850.html. Good point. Thank you for making that clear to me. And for the link to the post, I'm regret that I missed that in my initial research. No problem. I'm starting to think that maybe a direct comparison between DSPLink and dspbridge is not a fair one. Yes, as you mentioned in your earlier email it's not Apples to Apples comparison. We are working on making some of core functionalities such as DMM, resource Management, reset Management of co-processors generic for any IPC to use. So if DSPLink is missing DMM functionality then it should be just the matter of DSPLink adapting to this. I don't get what you're trying to say here, sorry. Would DSPLink be one of the IPCs for which the 'core functionalities' could be adapted? May be let's re-visit this point when the RFC is send on my above mentioned features. Could you explain an example of how DMM being made generic for any IPC to use could be applied to DSPLink? Basically today the Dynamic memory management is handled by DSPBridge. So the userspace clients talk to DSPBridge, and DSPBridge in turn talks to IOMMU to map the user passed Buffers. DSPBridge is managing the virtual address space of DSP in this case. So basically where we are going is replacing DSPBridge's DMM module with a generic Kernel module that can handle the DMM for any given number of Co-Processors. OMAP3 has only Co-Processor, where as OMAP4 has 2 Co-Processors. The solution should be generic to handle any number of Devices. I will try to send an RFC of this implementation and I would love to get feedback from you. In case if you want to get some information on how the Dynamic memory mapping works, you can refer pages 12-15 of this presentation https://gforge.ti.com/gf/download/docmanfileversion/17/674/OMAP3430_Bridge_overview.pdf I am not aware of the official word from T.I to support dspbridge on OMAP1, but as the community you will have the support in case you want to go with dspbridge option. On a high level, this is what needs to be done to provide support for OMAP1. 1. Adapt to iommu. Add support if the support is not present for OMAP1. 2. Adapt to mailbox 3. Reset and Power management adaptation for OMAP1. Thanks for the roadmap. This doesn't sound too daunting, but that could be because I am ignorant of the details. :) I forgot to add item 4. Surprises :) I'm still not sure about the iommu features required by dspbridge, I will need to look into this. But 2+3 sound like they could be provided by DSPLink itself. Would it be sane to put dspbridge on top of DSPLink? Just to sound it out, the DSP-side base image could be DSPBios + DSPLink (DSP-side) and the ARM-side would be made of dspbridge where the IPC is DSP Link 'compatible'. This could avoid a rewrite of the DSP-side of dspbridge maybe? Probably over-kill to get the features you want. Thank youi, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dspbridge and the omapl1x
Ben, We are attracted to DSPBridge over DSPLink because it appears to have better dynamic resource management and it is headed for mainline (fingers crossed). Do you mean dynamic memory management ? Can you please elaborate on what feature you are referring to ? Thank you, Best regards, Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/7] save and restore etm state across core OFF modes
+config ENABLE_OFF_MODE_JTAG_ETM_DEBUG + bool Enable hardware emulation context save and restore + depends on ARCH_OMAP3 -- Shouldn't this be depends on OMAP3_EMU instead ? + default y -- As this is debug option, can you keep this n by default ? + help + This option enables JTAG ETM debugging across power states. + With out this option emulation features are reset across OFF + mode state changes. + Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 7/8] TILER-DMM: Main TILER driver implementation.
+s32 tiler_mmap_blk(struct tiler_block_t *blk, u32 offs, u32 size, + struct vm_area_struct *vma, u32 voffs) +{ + u32 v, p, len; + + /* don't allow mremap */ + vma-vm_flags |= VM_DONTEXPAND | VM_RESERVED; Should we add VM_LOCKED as well considering the page swapping ? -- VM_RESERVED serves this purpose right ? + + /* mapping must fit into vma */ + BUG_ON(vma-vm_start vma-vm_start + voffs || + vma-vm_start + voffs vma-vm_start + voffs + size || + vma-vm_start + voffs + size vma-vm_end); Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] omap:mailbox-provide multiple reader support
Phil, Thanks for looking at the patch. On Wed, Jul 21, 2010 at 4:45 AM, ext-phil.2.carm...@nokia.com wrote: Apologies - top posting and not quoting properly due to having to use MS's braindead OWA. It appears that most of the changes are simply indentation changes caused by the inclusion of a new inner block here: -- I don't know if we can say most of the changes are simply indentation changes. + if (atomic_inc_return(mbox-use_count) == 1) { rather than just using a goto to skip past the unneeded parts. (Hmmm, is it not simply an immediate return now?) The goto/return is both more idiomatic in linux, and I'm sure a simpler patch. -- Sure, I will make the change. Phil From: linux-omap-ow...@vger.kernel.org [linux-omap-ow...@vger.kernel.org] On Behalf Of ext Hari Kanigeri [h-kanige...@ti.com] Sent: 21 July 2010 01:41 To: Linux Omap; Tony Lindgren; Doyu Hiroshi (Nokia-MS/Helsinki) Cc: Ohad Ben-Cohen; Hari Kanigeri Subject: [PATCH 2/2] omap:mailbox-provide multiple reader support This patch provides mutiple readers support for a mailbox instance. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h | 6 ++- arch/arm/plat-omap/mailbox.c | 63 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 0486d64..c8e47d8 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -68,13 +68,15 @@ struct omap_mbox { void *priv; void (*err_notify)(void); + atomic_t use_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox *); int omap_mbox_unregister(struct omap_mbox *); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index baac315..f9f2af4 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work) if (unlikely(len != sizeof(msg))) pr_err(%s: kfifo_out anomaly detected\n, __func__); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); } } @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (unlikely(ret)) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } + if (atomic_inc_return(mbox-use_count) == 1) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + printk(KERN_ERR failed to register mailbox interrupt: + %d\n, ret); + goto fail_request_irq; + } - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_rxq; + mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_rxq; + } + mbox-rxq = mq; + mq-mbox = mbox; } - mbox-rxq = mq; - return 0; fail_alloc_rxq: @@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox) fail_alloc_txq: free_irq(mbox-irq, mbox); fail_request_irq: + atomic_dec(mbox-use_count); if (likely(mbox-ops-shutdown)) { if (atomic_dec_return(mbox_refcount) == 0
Re: [PATCH 2/2] omap:mailbox-provide multiple reader support
Fernando, Thanks for looking at the patch. On Tue, Jul 20, 2010 at 4:59 PM, Guzman Lugo, Fernando fernando.l...@ti.com wrote: Hi Hari, @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (unlikely(ret)) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } + if (atomic_inc_return(mbox-use_count) == 1) { What happen if a thread is preempted by other thread which also uses the same mailbox after doing the atomic_inc? The second thread also will call atomic_inc_return and in this case the value returned will be 2 and it will not initialize the mbox queues but it will return success status, in this point the second thread will think it could get the mailbox handle without any issue. However the first thread still can fail and not initialize correctly the mailbox leading second thread to not work properly or crash. I think all the initialization should be protected and not just the use_count. -- How about changing mboxes_lock from spinlock to mutex and protecting the initialization code ? I guess then the variables don't have to be atomic too. please share your thougts. Please let me know what you think. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] omap:mailbox-provide multiple readers support
This patch series provides the support for mutiple readers per mailbox instance. The first patch is mostly cleanup and the second patch consists of the changes to provide multiple readers support. Hari Kanigeri (2): omap:mailbox-make mailbox reference counter atomic omap:mailbox-provide multiple reader support arch/arm/plat-omap/include/plat/mailbox.h |6 ++- arch/arm/plat-omap/mailbox.c | 84 +++-- 2 files changed, 48 insertions(+), 42 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] omap:mailbox-provide multiple reader support
This patch provides mutiple readers support for a mailbox instance. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/mailbox.h |6 ++- arch/arm/plat-omap/mailbox.c | 63 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 0486d64..c8e47d8 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -68,13 +68,15 @@ struct omap_mbox { void*priv; void(*err_notify)(void); + atomic_tuse_count; + struct blocking_notifier_head notifier; }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); void omap_mbox_init_seq(struct omap_mbox *); -struct omap_mbox *omap_mbox_get(const char *); -void omap_mbox_put(struct omap_mbox *); +struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb); +void omap_mbox_put(struct omap_mbox *, struct notifier_block *nb); int omap_mbox_register(struct device *parent, struct omap_mbox *); int omap_mbox_unregister(struct omap_mbox *); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index baac315..f9f2af4 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -149,8 +149,8 @@ static void mbox_rx_work(struct work_struct *work) if (unlikely(len != sizeof(msg))) pr_err(%s: kfifo_out anomaly detected\n, __func__); - if (mq-callback) - mq-callback((void *)msg); + blocking_notifier_call_chain(mq-mbox-notifier, len, + (void *)msg); } } @@ -252,28 +252,30 @@ static int omap_mbox_startup(struct omap_mbox *mbox) } } - ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, - mbox-name, mbox); - if (unlikely(ret)) { - printk(KERN_ERR - failed to register mailbox interrupt:%d\n, ret); - goto fail_request_irq; - } + if (atomic_inc_return(mbox-use_count) == 1) { + ret = request_irq(mbox-irq, mbox_interrupt, IRQF_SHARED, + mbox-name, mbox); + if (unlikely(ret)) { + printk(KERN_ERR failed to register mailbox interrupt: + %d\n, ret); + goto fail_request_irq; + } - mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_txq; - } - mbox-txq = mq; + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_txq; + } + mbox-txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); - if (!mq) { - ret = -ENOMEM; - goto fail_alloc_rxq; + mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); + if (!mq) { + ret = -ENOMEM; + goto fail_alloc_rxq; + } + mbox-rxq = mq; + mq-mbox = mbox; } - mbox-rxq = mq; - return 0; fail_alloc_rxq: @@ -281,6 +283,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox) fail_alloc_txq: free_irq(mbox-irq, mbox); fail_request_irq: + atomic_dec(mbox-use_count); if (likely(mbox-ops-shutdown)) { if (atomic_dec_return(mbox_refcount) == 0) mbox-ops-shutdown(mbox); @@ -291,10 +294,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox) static void omap_mbox_fini(struct omap_mbox *mbox) { - mbox_queue_free(mbox-txq); - mbox_queue_free(mbox-rxq); - free_irq(mbox-irq, mbox); + if (atomic_dec_return(mbox-use_count) == 0) { + mbox_queue_free(mbox-txq); + mbox_queue_free(mbox-rxq); + free_irq(mbox-irq, mbox); + } if (likely(mbox-ops-shutdown)) { if (atomic_dec_return(mbox_refcount) == 0) @@ -314,7 +319,7 @@ static struct omap_mbox **find_mboxes(const char *name) return p; } -struct omap_mbox *omap_mbox_get(const char *name) +struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb) { struct omap_mbox *mbox; int ret; @@ -325,19 +330,21 @@ struct omap_mbox *omap_mbox_get(const char *name) spin_unlock(mboxes_lock); return ERR_PTR(-ENOENT); } - spin_unlock(mboxes_lock); ret = omap_mbox_startup(mbox); if (ret) return ERR_PTR
[PATCH 2/5] omap:hwspinlock-define HWSPINLOCK base address
From: Simon Que s...@ti.com Add HWSPINLCOK base address information in omap44xx.h Signed-off-by: Simon Que s...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/plat-omap/include/plat/omap44xx.h |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index 76832d3..8016508 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -49,5 +49,10 @@ #define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) #define OMAP44XX_HSUSB_OTG_BASE(L4_44XX_BASE + 0xAB000) +#define OMAP4_MMU1_BASE0x55082000 +#define OMAP4_MMU2_BASE0x4A066000 + +#define OMAP44XX_SPINLOCK_BASE (L4_44XX_BASE + 0xF6000) + #endif /* __ASM_ARCH_OMAP44XX_H */ -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/5] omap:hwmod-hwspinlock-enable
From: Simon Que s...@ti.com uncomment the hwmod part for hwspinlock Signed-off-by: Simon Que s...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 03bb3db..41dc77d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -4966,7 +4966,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { /* omap44xx_smartreflex_iva_hwmod, */ /* omap44xx_smartreflex_mpu_hwmod, */ /* spinlock class */ -/* omap44xx_spinlock_hwmod, */ + omap44xx_spinlock_hwmod, /* timer class */ omap44xx_timer1_hwmod, omap44xx_timer2_hwmod, -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/5] omap:hwspinlock-added hwspinlock driver
From: Simon Que s...@ti.com Created driver for OMAP hardware spinlock. This driver supports: - Reserved spinlocks for internal use - Dynamic allocation of unreserved locks - Lock, unlock, and trylock functions, with or without disabling irqs/preempt - Registered as a platform device driver The device initialization uses hwmod to configure the devices. One device will be created for each IP. It will pass spinlock register offset info to the driver. The device initialization file is: arch/arm/mach-omap2/hwspinlocks.c The driver takes in register offset info passed in device initialization. It uses hwmod to obtain the base address of the hardware spinlock module. Then it reads info from the registers. The function hwspinlock_probe() initializes the array of spinlock structures, each containing a spinlock register address calculated from the base address and lock offsets. The device driver file is: arch/arm/plat-omap/hwspinlock.c Here's an API summary: int hwspinlock_lock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will keep trying until it succeeds. This is a blocking function. int hwspinlock_trylock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will return BUSY. If it succeeds in locking, the function will return ACQUIRED. This is a non-blocking function. int hwspinlock_unlock(struct hwspinlock *); Unlock a hardware spinlock. struct hwspinlock *hwspinlock_request(void); Provides for dynamic allocation of a hardware spinlock. It returns the handle to the next available (unallocated) spinlock. If no more locks are available, it returns NULL. struct hwspinlock *hwspinlock_request_specific(unsigned int); Provides for static allocation of a specific hardware spinlock. This allows the system to use a specific spinlock, identified by an ID. If the ID is invalid or if the desired lock is already allocated, this will return NULL. Otherwise it returns a spinlock handle. int hwspinlock_free(struct hwspinlock *); Frees an allocated hardware spinlock (either reserved or unreserved). Signed-off-by: Simon Que s...@ti.com Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/hwspinlocks.c| 70 ++ arch/arm/plat-omap/hwspinlock.c | 335 ++ arch/arm/plat-omap/include/plat/hwspinlock.h | 29 +++ 3 files changed, 434 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/hwspinlocks.c create mode 100644 arch/arm/plat-omap/hwspinlock.c create mode 100644 arch/arm/plat-omap/include/plat/hwspinlock.h diff --git a/arch/arm/mach-omap2/hwspinlocks.c b/arch/arm/mach-omap2/hwspinlocks.c new file mode 100644 index 000..f0f05e1 --- /dev/null +++ b/arch/arm/mach-omap2/hwspinlocks.c @@ -0,0 +1,70 @@ +/* + * OMAP hardware spinlock device initialization + * + * Copyright (C) 2010 Texas Instruments. All rights reserved. + * + * Contact: Simon Que s...@ti.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include linux/module.h +#include linux/interrupt.h +#include linux/device.h +#include linux/delay.h +#include linux/io.h +#include linux/slab.h + +#include plat/hwspinlock.h +#include plat/omap_device.h +#include plat/omap_hwmod.h + +/* Spinlock register offsets */ +#define REVISION_OFFSET0x +#define SYSCONFIG_OFFSET 0x0010 +#define SYSSTATUS_OFFSET 0x0014 +#define LOCK_BASE_OFFSET 0x0800 +#define LOCK_OFFSET(i) (LOCK_BASE_OFFSET + 0x4 * (i)) + +/* Initialization function */ +int __init hwspinlocks_init(void) +{ + int retval = 0; + + struct hwspinlock_plat_info *pdata; + struct omap_hwmod *oh; + char *oh_name, *pdev_name; + + oh_name = spinlock; + oh = omap_hwmod_lookup(oh_name); + if (WARN_ON(oh == NULL)) + return -EINVAL; + + pdev_name = hwspinlock; + + /* Pass data to device initialization */ + pdata = kzalloc(sizeof(struct hwspinlock_plat_info), GFP_KERNEL); + if (WARN_ON(pdata == NULL)) + return -ENOMEM; + pdata-sysstatus_offset = SYSSTATUS_OFFSET; + pdata-lock_base_offset
[PATCH 0/5] omap:hwspinlock support-omap4
Resending the hwspinlock patch Simon Que sent few days ago by splitting the patch into logical pieces. The first 4 patches are based on Simon's patch. https://patchwork.kernel.org/patch/110672/ The 5th patch is a new patch to address race condition issue with I2C driver usage. Created driver for OMAP hardware spinlock. This driver supports: - Reserved spinlocks for internal use - Dynamic allocation of unreserved locks - Lock, unlock, and trylock functions, with or without disabling irqs/preempt - Registered as a platform device driver The device initialization uses hwmod to configure the devices. One device will be created for each IP. It will pass spinlock register offset info to the driver. The device initialization file is: arch/arm/mach-omap2/hwspinlocks.c The driver takes in register offset info passed in device initialization. It uses hwmod to obtain the base address of the hardware spinlock module. Then it reads info from the registers. The function hwspinlock_probe() initializes the array of spinlock structures, each containing a spinlock register address calculated from the base address and lock offsets. The device driver file is: arch/arm/plat-omap/hwspinlock.c Here's an API summary: int hwspinlock_lock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will keep trying until it succeeds. This is a blocking function. int hwspinlock_trylock(struct hwspinlock *); Attempt to lock a hardware spinlock. If it is busy, the function will return BUSY. If it succeeds in locking, the function will return ACQUIRED. This is a non-blocking function. int hwspinlock_unlock(struct hwspinlock *); Unlock a hardware spinlock. struct hwspinlock *hwspinlock_request(void); Provides for dynamic allocation of a hardware spinlock. It returns the handle to the next available (unallocated) spinlock. If no more locks are available, it returns NULL. struct hwspinlock *hwspinlock_request_specific(unsigned int); Provides for static allocation of a specific hardware spinlock. This allows the system to use a specific spinlock, identified by an ID. If the ID is invalid or if the desired lock is already allocated, this will return NULL. Otherwise it returns a spinlock handle. int hwspinlock_free(struct hwspinlock *); Frees an allocated hardware spinlock (either reserved or unreserved). Hari Kanigeri (1): omap:hwspinlocks-ensure the order of registration Simon Que (4): omap:hwmod-hwspinlock-enable omap:hwspinlock-define HWSPINLOCK base address omap:hwspinlock-added hwspinlock driver omap:hwspinlock-add build support arch/arm/mach-omap2/Makefile |2 + arch/arm/mach-omap2/hwspinlocks.c| 70 ++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c |2 +- arch/arm/plat-omap/Makefile |2 + arch/arm/plat-omap/hwspinlock.c | 334 ++ arch/arm/plat-omap/include/plat/hwspinlock.h | 29 +++ arch/arm/plat-omap/include/plat/omap44xx.h |5 + 7 files changed, 443 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/hwspinlocks.c create mode 100644 arch/arm/plat-omap/hwspinlock.c create mode 100644 arch/arm/plat-omap/include/plat/hwspinlock.h -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/5] omap:hwspinlocks-ensure the order of registration
Ensure that the hwspinlock driver is registered prior to I2C driver registration since I2C is dependent on hwspinlock. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/hwspinlocks.c |2 +- arch/arm/plat-omap/hwspinlock.c |3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/hwspinlocks.c b/arch/arm/mach-omap2/hwspinlocks.c index f0f05e1..a9f85b9 100644 --- a/arch/arm/mach-omap2/hwspinlocks.c +++ b/arch/arm/mach-omap2/hwspinlocks.c @@ -67,4 +67,4 @@ int __init hwspinlocks_init(void) return retval; } -module_init(hwspinlocks_init); +postcore_initcall(hwspinlocks_init); diff --git a/arch/arm/plat-omap/hwspinlock.c b/arch/arm/plat-omap/hwspinlock.c index 1883add..3742b04 100644 --- a/arch/arm/plat-omap/hwspinlock.c +++ b/arch/arm/plat-omap/hwspinlock.c @@ -309,6 +309,7 @@ static int __init hwspinlock_init(void) return retval; } +postcore_initcall(hwspinlock_init); /* Cleanup function */ static void __exit hwspinlock_exit(void) @@ -325,8 +326,6 @@ static void __exit hwspinlock_exit(void) if (hwspinlock_module-is_init) kfree(hwspinlocks); } - -module_init(hwspinlock_init); module_exit(hwspinlock_exit); MODULE_LICENSE(GPL v2); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/5] omap:hwspinlock-add build support
From: Simon Que s...@ti.com Patch to add suport to build hwspinlock modules Signed-off-by: Simon Que s...@ti.com --- arch/arm/mach-omap2/Makefile |2 ++ arch/arm/plat-omap/Makefile |2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 13825a2..d29ea57 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -177,3 +177,5 @@ smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o obj-y += $(smc91x-m) $(smc91x-y) obj-$(CONFIG_LEDS_PWM) += twl6030_pwm.o + +obj-$(CONFIG_ARCH_OMAP4) += hwspinlocks.o diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 87e5124..5d08f1c 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -38,3 +38,5 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y) obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o + +obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 3/3] mm: iommu: The Virtual Contiguous Memory Manager
He demonstrated the usage of his code in one of the emails he sent out initially. Did you go over that, and what (or how many) step would you use with the current code to do the same thing? -- So is this patch set adding layers and abstractions to help the User ? If the idea is to share some memory across multiple devices, I guess you can achieve the same by calling the map function provided by iommu module and sharing the mapped address to the 10's or 100's of devices to access the buffers. You would only need a dedicated virtual pool per IOMMU device to manage its virtual memory allocations. Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 3/3] mm: iommu: The Virtual Contiguous Memory Manager
The VCMM takes the long view. Its designed for a future in which the number of IOMMUs will go up and the ways in which these IOMMUs are composed will vary from system to system, and may vary at runtime. Already, there are ~20 different IOMMU map implementations in the kernel. Had the Linux kernel had the VCMM, many of those implementations could have leveraged the mapping and topology management of a VCMM, while focusing on a few key hardware specific functions (map this physical address, program the page table base register). -- Sounds good. Did you think of a way to handle the cases where one of the Device that is using the mapped address crashed ? How is the physical address unbacked in this case ? Hari -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3][v3] omap:iommu-enable TLB miss interrupt
The current iommu module doesn't provide the mechanism to get MMU fault on TLB miss when working with locked TLB entries and TWL disabled. To get the TLB miss interrupt, the TWL should be disabled. This patch set provides the option to enable/disable TWL and to enable TLB miss interrupt. Based on Hiroshi, the initial patch set was revised to add more flexibility to enable TWL and cleanup the part of the code that had layering violations. https://patchwork.kernel.org/patch/101336/ Hari Kanigeri (2): omap: iommu-update irq mask to be specific about twl and tlb omap: iommu-add functionality to get TLB miss interrupt Hiroshi DOYU (1): omap iommu: move iommu_disable at fault to the above layer arch/arm/mach-omap2/iommu2.c| 44 -- arch/arm/plat-omap/include/plat/iommu.h |2 + arch/arm/plat-omap/iommu.c | 19 + 3 files changed, 56 insertions(+), 9 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] omap: iommu-add functionality to get TLB miss interrupt
In order to enable TLB miss interrupt, the TWL should be disabled. This patch provides the functionality to get the MMU fault interrupt for a TLB miss in the cases where the users are working with the locked TLB entries and with TWL disabled. New interface is added to select twl and to enable TLB miss interrupt. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com Signed-off-by: Hiroshi Doyu hiroshi.d...@nokia.com --- arch/arm/mach-omap2/iommu2.c| 32 ++ arch/arm/plat-omap/include/plat/iommu.h |2 + arch/arm/plat-omap/iommu.c | 17 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index ebbdae2..edf7cd4 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -65,6 +65,26 @@ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0x :\ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xf000 : 0) + +static void __iommu_set_twl(struct iommu *obj, bool on) +{ + u32 l = iommu_read_reg(obj, MMU_CNTL); + + if (on) + iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); + else + iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); + + l = ~MMU_CNTL_MASK; + if (on) + l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); + else + l |= (MMU_CNTL_MMU_EN); + + iommu_write_reg(obj, l, MMU_CNTL); +} + + static int omap2_iommu_enable(struct iommu *obj) { u32 l, pa; @@ -100,13 +120,9 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); - iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); - l = iommu_read_reg(obj, MMU_CNTL); - l = ~MMU_CNTL_MASK; - l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); - iommu_write_reg(obj, l, MMU_CNTL); + __iommu_set_twl(obj, true); return 0; } @@ -122,6 +138,11 @@ static void omap2_iommu_disable(struct iommu *obj) dev_dbg(obj-dev, %s is shutting down\n, obj-name); } +static void omap2_iommu_set_twl(struct iommu *obj, bool on) +{ + __iommu_set_twl(obj, false); +} + static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) { int i; @@ -304,6 +325,7 @@ static const struct iommu_functions omap2_iommu_ops = { .enable = omap2_iommu_enable, .disable= omap2_iommu_disable, + .set_twl= omap2_iommu_set_twl, .fault_isr = omap2_iommu_fault_isr, .tlb_read_cr= omap2_tlb_read_cr, diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 0752af9..33c7d41 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); + void (*set_twl)(struct iommu *obj, bool on); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); +extern void iommu_set_twl(struct iommu *obj, bool on); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index b2b3937..aa064e1 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); +/** + * iommu_set_twl - enable/disable table walking logic + * @obj: target iommu + * @on:enable/disable + * + * Function used to enable/disable TWL. If one wants to work + * exclusively with locked TLB entries and receive notifications + * for TLB miss then call this function to disable TWL. + */ +void iommu_set_twl(struct iommu *obj, bool on) +{ + clk_enable(obj-clk); + arch_iommu-set_twl(obj, on); + clk_disable(obj-clk); +} +EXPORT_SYMBOL_GPL(iommu_set_twl); + #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2][v2] omap:iommu-enable TLB miss interrupt
The current iommu module doesn't provide the mechanism to get MMU fault on TLB miss when working with locked TLB entries and TWL disabled. To get the TLB miss interrupt, the TWL should be disabled. This patch set provides the option to enable/disable TWL and to enable TLB miss interrupt. Based on Hiroshi, the initial patch set was revised to add more flexibility to enable TWL. Hari Kanigeri (2): omap: iommu-update irq mask to be specific about twl and tlb omap: iommu-add functionality to get TLB miss interrupt arch/arm/mach-omap2/iommu2.c| 36 --- arch/arm/plat-omap/include/plat/iommu.h |2 + arch/arm/plat-omap/iommu.c | 17 ++ 3 files changed, 47 insertions(+), 8 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] omap: iommu-add functionality to get TLB miss interrupt
In order to enable TLB miss interrupt, the TWL should be disabled. This patch provides the functionality to get the MMU fault interrupt for a TLB miss in the cases where the users are working with the locked TLB entries and with TWL disabled. New interface is added to select twl and to enable TLB miss interrupt. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com Signed-off-by: Hiroshi Doyu hiroshi.d...@nokia.com --- arch/arm/mach-omap2/iommu2.c| 26 +- arch/arm/plat-omap/include/plat/iommu.h |2 ++ arch/arm/plat-omap/iommu.c | 17 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index ebbdae2..3cfe1c4 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -65,6 +65,25 @@ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0x :\ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xf000 : 0) + +static void omap2_iommu_set_twl(struct iommu *obj, bool on) +{ + u32 l = iommu_read_reg(obj, MMU_CNTL); + + if (on) + iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); + else + iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); + + l = ~MMU_CNTL_MASK; + if (on) + l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); + else + l |= (MMU_CNTL_MMU_EN); + + iommu_write_reg(obj, l, MMU_CNTL); +} + static int omap2_iommu_enable(struct iommu *obj) { u32 l, pa; @@ -100,13 +119,9 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); - iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); - l = iommu_read_reg(obj, MMU_CNTL); - l = ~MMU_CNTL_MASK; - l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN); - iommu_write_reg(obj, l, MMU_CNTL); + omap2_iommu_set_twl(obj, true); return 0; } @@ -304,6 +319,7 @@ static const struct iommu_functions omap2_iommu_ops = { .enable = omap2_iommu_enable, .disable= omap2_iommu_disable, + .set_twl= omap2_iommu_set_twl, .fault_isr = omap2_iommu_fault_isr, .tlb_read_cr= omap2_tlb_read_cr, diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 0752af9..33c7d41 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); + void (*set_twl)(struct iommu *obj, bool on); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); +extern void iommu_set_twl(struct iommu *obj, bool on); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index b2b3937..aa064e1 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); +/** + * iommu_set_twl - enable/disable table walking logic + * @obj: target iommu + * @on:enable/disable + * + * Function used to enable/disable TWL. If one wants to work + * exclusively with locked TLB entries and receive notifications + * for TLB miss then call this function to disable TWL. + */ +void iommu_set_twl(struct iommu *obj, bool on) +{ + clk_enable(obj-clk); + arch_iommu-set_twl(obj, on); + clk_disable(obj-clk); +} +EXPORT_SYMBOL_GPL(iommu_set_twl); + #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] omap: iommu-update irq mask to be specific about twl and tlb
Revise the IRQ mask definitions to handle the MMU faults related to TWL fault as well as TLB miss fault. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Hiroshi Doyu hiroshi.d...@nokia.com --- arch/arm/mach-omap2/iommu2.c | 12 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index e82da68..ebbdae2 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -44,9 +44,13 @@ #define MMU_IRQ_EMUMISS(1 2) #define MMU_IRQ_TRANSLATIONFAULT (1 1) #define MMU_IRQ_TLBMISS(1 0) -#define MMU_IRQ_MASK \ - (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \ -MMU_IRQ_TRANSLATIONFAULT) + +#define __MMU_IRQ_FAULT\ + (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT) +#define MMU_IRQ_MASK \ + (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS) +#define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT) +#define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS) /* MMU_CNTL */ #define MMU_CNTL_SHIFT 1 @@ -96,7 +100,7 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); - iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE); + iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); l = iommu_read_reg(obj, MMU_CNTL); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap:hwmod-remove prm header from prm-regbits-xxxx headers
The prm-regbits-.h header files are not dependent on prm.h header file. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c |1 + arch/arm/mach-omap2/prm-regbits-24xx.h |1 - arch/arm/mach-omap2/prm-regbits-34xx.h |1 - arch/arm/mach-omap2/prm-regbits-44xx.h |1 - 4 files changed, 1 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 667633c..88cc9ca 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -26,6 +26,7 @@ #include omap_hwmod_common_data.h #include cm.h +#include prm.h #include prm-regbits-44xx.h /* Base offset for all OMAP4 interrupts external to MPUSS */ diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h index 4002051..fd763b5 100644 --- a/arch/arm/mach-omap2/prm-regbits-24xx.h +++ b/arch/arm/mach-omap2/prm-regbits-24xx.h @@ -14,7 +14,6 @@ * published by the Free Software Foundation. */ -#include prm.h /* Bits shared between registers */ diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index 8f21bae..ef7fd5e 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -14,7 +14,6 @@ * published by the Free Software Foundation. */ -#include prm.h /* Shared register bits */ diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h index 597be4a..ef7af7e 100644 --- a/arch/arm/mach-omap2/prm-regbits-44xx.h +++ b/arch/arm/mach-omap2/prm-regbits-44xx.h @@ -22,7 +22,6 @@ #ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H #define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H -#include prm.h /* -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] omap: iommu-update irq mask to be specific about twl
Update the irq mask so that is is clear that the MMU interrupt is related to TWL fault. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/iommu2.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index e82da68..fcf4f4a 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -46,7 +46,13 @@ #define MMU_IRQ_TLBMISS(1 0) #define MMU_IRQ_MASK \ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \ -MMU_IRQ_TRANSLATIONFAULT) + MMU_IRQ_TRANSLATIONFAULT | MMU_IRQ_TLBMISS) +#define MMU_IRQ_TWL_MASK \ + (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \ + MMU_IRQ_TRANSLATIONFAULT) +#define MMU_IRQ_TLB_MISS_MASK \ + (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TLBMISS | MMU_IRQ_EMUMISS | \ + MMU_IRQ_TRANSLATIONFAULT) /* MMU_CNTL */ #define MMU_CNTL_SHIFT 1 @@ -96,7 +102,7 @@ static int omap2_iommu_enable(struct iommu *obj) l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE); iommu_write_reg(obj, l, MMU_SYSCONFIG); - iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE); + iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE); iommu_write_reg(obj, pa, MMU_TTB); l = iommu_read_reg(obj, MMU_CNTL); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] omap:iommu-enable TLB miss interrupt
The current iommu module doesn't provide the mechanism to get MMU fault on TLB miss when working with locked TLB entries and TWL disabled. To get the TLB miss interrupt, the TWL should be disabled. This patch set provides the mechanism to disable TWL and enable TLB miss interrupt. Hari Kanigeri (2): omap: iommu-update irq mask to be specific about twl omap: iommu-add functionality to get TLB miss interrupt arch/arm/mach-omap2/iommu2.c| 23 +-- arch/arm/plat-omap/include/plat/iommu.h |2 ++ arch/arm/plat-omap/iommu.c | 12 3 files changed, 35 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] omap: iommu-add functionality to get TLB miss interrupt
In order to enable TLB miss interrupt, the TWL should be disabled. This patch provides the functionality to get the MMU fault interrupt for a TLB miss in the cases where the users are working with the locked TLB entries and with TWL disabled. New interface is added to disable twl and enable TLB miss interrupt. Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Ramesh Gupta grgu...@ti.com --- arch/arm/mach-omap2/iommu2.c| 13 + arch/arm/plat-omap/include/plat/iommu.h |2 ++ arch/arm/plat-omap/iommu.c | 12 3 files changed, 27 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index fcf4f4a..2e78cea 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -124,6 +124,18 @@ static void omap2_iommu_disable(struct iommu *obj) dev_dbg(obj-dev, %s is shutting down\n, obj-name); } +static void omap2_iommu_disable_twl(struct iommu *obj) +{ + u32 l = iommu_read_reg(obj, MMU_CNTL); + + l = ~MMU_CNTL_MASK; + l |= (MMU_CNTL_MMU_EN); + iommu_write_reg(obj, l, MMU_CNTL); + + /* Enable TLB miss interrupt */ + iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE); +} + static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) { int i; @@ -306,6 +318,7 @@ static const struct iommu_functions omap2_iommu_ops = { .enable = omap2_iommu_enable, .disable= omap2_iommu_disable, + .disable_twl= omap2_iommu_disable_twl, .fault_isr = omap2_iommu_fault_isr, .tlb_read_cr= omap2_tlb_read_cr, diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 0752af9..52a3852 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); + void (*disable_twl)(struct iommu *obj); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); +extern void iommu_disable_twl(struct iommu *obj); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index b2b3937..d64a4d8 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -370,6 +370,18 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); +/** + * Call this function if working with locked TLB entries and + * TWL disabled + */ +extern void iommu_disable_twl(struct iommu *obj) +{ + clk_enable(obj-clk); + arch_iommu-disable_twl(obj); + clk_disable(obj-clk); +} +EXPORT_SYMBOL_GPL(iommu_disable_twl); + #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] omap: iommu- update ducati mmu irq define name
2.6.34-rc6 kernel has the Ducati mmu irq define name changed, which is resulting in compilation error. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/omap-iommu.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index eb9bee7..f5a1aad 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -59,7 +59,7 @@ static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; static struct iommu_device omap4_devices[] = { { .base = OMAP4_MMU1_BASE, - .irq = INT_44XX_DUCATI_MMU_IRQ, + .irq = OMAP44XX_IRQ_DUCATI_MMU, .pdata = { .name = ducati, .nr_tlb_entries = 32, -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4][v4]OMAP:IOMMU support for OMAP4 and TLB preservation support
Following are the revised patches addressing the comments from Tony, Felipe, and Hiroshi to address multi-omap support and make TLB locking mechanism generic. Hari Kanigeri (4): OMAP:iommu renamed omap3-iommu to omap-iommu OMAP:iommu support for OMAP4 OMAP:iommu - missing check for TLB valid entry OMAP:iommu- add TLB preservation support arch/arm/mach-omap2/Makefile |4 +- arch/arm/mach-omap2/iommu2.c |6 +- arch/arm/mach-omap2/omap-iommu.c | 157 arch/arm/mach-omap2/omap3-iommu.c | 105 --- arch/arm/plat-omap/include/plat/omap44xx.h |3 + arch/arm/plat-omap/iommu.c | 43 +--- 6 files changed, 191 insertions(+), 127 deletions(-) create mode 100644 arch/arm/mach-omap2/omap-iommu.c delete mode 100644 arch/arm/mach-omap2/omap3-iommu.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4][v4] OMAP:iommu support for OMAP4
This patch provides the iommu support for OMAP4 co-processors. Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/omap-iommu.c | 59 +-- arch/arm/plat-omap/include/plat/omap44xx.h |3 + 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 416a65d..eb9bee7 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -13,6 +13,7 @@ #include linux/platform_device.h #include plat/iommu.h +#include plat/irqs.h struct iommu_device { resource_size_t base; @@ -20,9 +21,11 @@ struct iommu_device { struct iommu_platform_data pdata; struct resource res[2]; }; +static struct iommu_device *devices; +static int num_iommu_devices; #ifdef CONFIG_ARCH_OMAP3 -static struct iommu_device devices[] = { +static struct iommu_device omap3_devices[] = { { .base = 0x480bd400, .irq = 24, @@ -44,11 +47,46 @@ static struct iommu_device devices[] = { }, #endif }; +#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices) +static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES]; +#else +#define omap3_devices NULL +#define NR_OMAP3_IOMMU_DEVICES 0 +#define omap3_iommu_pdev NULL #endif -#define NR_IOMMU_DEVICES ARRAY_SIZE(devices) +#ifdef CONFIG_ARCH_OMAP4 +static struct iommu_device omap4_devices[] = { + { + .base = OMAP4_MMU1_BASE, + .irq = INT_44XX_DUCATI_MMU_IRQ, + .pdata = { + .name = ducati, + .nr_tlb_entries = 32, + .clk_name = ducati_ick, + }, + }, +#if defined(CONFIG_MPU_TESLA_IOMMU) + { + .base = OMAP4_MMU2_BASE, + .irq = INT_44XX_DSP_MMU, + .pdata = { + .name = tesla, + .nr_tlb_entries = 32, + .clk_name = tesla_ick, + }, + }, +#endif +}; +#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices) +static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES]; +#else +#define omap4_devices NULL +#define NR_OMAP4_IOMMU_DEVICES 0 +#define omap4_iommu_pdev NULL +#endif -static struct platform_device *omap_iommu_pdev[NR_IOMMU_DEVICES]; +static struct platform_device **omap_iommu_pdev; static int __init omap_iommu_init(void) { @@ -58,7 +96,18 @@ static int __init omap_iommu_init(void) { .flags = IORESOURCE_IRQ }, }; - for (i = 0; i NR_IOMMU_DEVICES; i++) { + if (cpu_is_omap34xx()) { + devices = omap3_devices; + omap_iommu_pdev = omap3_iommu_pdev; + num_iommu_devices = NR_OMAP3_IOMMU_DEVICES; + } else if (cpu_is_omap44xx()) { + devices = omap4_devices; + omap_iommu_pdev = omap4_iommu_pdev; + num_iommu_devices = NR_OMAP4_IOMMU_DEVICES; + } else + return -ENODEV; + + for (i = 0; i num_iommu_devices; i++) { struct platform_device *pdev; const struct iommu_device *d = devices[i]; @@ -98,7 +147,7 @@ static void __exit omap_iommu_exit(void) { int i; - for (i = 0; i NR_IOMMU_DEVICES; i++) + for (i = 0; i num_iommu_devices; i++) platform_device_unregister(omap_iommu_pdev[i]); } module_exit(omap_iommu_exit); diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h index 9cb1e9d..1b5b786 100644 --- a/arch/arm/plat-omap/include/plat/omap44xx.h +++ b/arch/arm/plat-omap/include/plat/omap44xx.h @@ -47,5 +47,8 @@ #define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000) #define OMAP44XX_HSUSB_OTG_BASE(L4_44XX_BASE + 0xAB000) +#define OMAP4_MMU1_BASE0x55082000 +#define OMAP4_MMU2_BASE0x4A066000 + #endif /* __ASM_ARCH_OMAP44XX_H */ -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4][v4] OMAP:iommu renamed omap3-iommu to omap-iommu
This patch includes changes to omap3-iommu.c file to make it generic for all OMAPs. Renamed omap3-iommu.c to omap-iommu.c Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/Makefile |4 +-- .../arm/mach-omap2/{omap3-iommu.c = omap-iommu.c} | 23 +++ 2 files changed, 14 insertions(+), 13 deletions(-) rename arch/arm/mach-omap2/{omap3-iommu.c = omap-iommu.c} (79%) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index dac3e56..0f616cb 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -88,9 +88,7 @@ obj-$(CONFIG_ARCH_OMAP2) += remoteproc24xx.o obj-$(CONFIG_ARCH_OMAP3) += remoteproc3xxx.o obj-$(CONFIG_ARCH_OMAP4) += remoteproc44xx.o endif -iommu-y+= iommu2.o -iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o - +iommu-y+= iommu2.o omap-iommu.o obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y) i2c-omap-$(CONFIG_I2C_OMAP):= i2c.o diff --git a/arch/arm/mach-omap2/omap3-iommu.c b/arch/arm/mach-omap2/omap-iommu.c similarity index 79% rename from arch/arm/mach-omap2/omap3-iommu.c rename to arch/arm/mach-omap2/omap-iommu.c index fbbcb5c..416a65d 100644 --- a/arch/arm/mach-omap2/omap3-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -1,5 +1,5 @@ /* - * omap iommu: omap3 device registration + * omap iommu: omap device registration * * Copyright (C) 2008-2009 Nokia Corporation * @@ -21,6 +21,7 @@ struct iommu_device { struct resource res[2]; }; +#ifdef CONFIG_ARCH_OMAP3 static struct iommu_device devices[] = { { .base = 0x480bd400, @@ -43,11 +44,13 @@ static struct iommu_device devices[] = { }, #endif }; +#endif + #define NR_IOMMU_DEVICES ARRAY_SIZE(devices) -static struct platform_device *omap3_iommu_pdev[NR_IOMMU_DEVICES]; +static struct platform_device *omap_iommu_pdev[NR_IOMMU_DEVICES]; -static int __init omap3_iommu_init(void) +static int __init omap_iommu_init(void) { int i, err; struct resource res[] = { @@ -80,26 +83,26 @@ static int __init omap3_iommu_init(void) err = platform_device_add(pdev); if (err) goto err_out; - omap3_iommu_pdev[i] = pdev; + omap_iommu_pdev[i] = pdev; } return 0; err_out: while (i--) - platform_device_put(omap3_iommu_pdev[i]); + platform_device_put(omap_iommu_pdev[i]); return err; } -module_init(omap3_iommu_init); +module_init(omap_iommu_init); -static void __exit omap3_iommu_exit(void) +static void __exit omap_iommu_exit(void) { int i; for (i = 0; i NR_IOMMU_DEVICES; i++) - platform_device_unregister(omap3_iommu_pdev[i]); + platform_device_unregister(omap_iommu_pdev[i]); } -module_exit(omap3_iommu_exit); +module_exit(omap_iommu_exit); MODULE_AUTHOR(Hiroshi DOYU); -MODULE_DESCRIPTION(omap iommu: omap3 device registration); +MODULE_DESCRIPTION(omap iommu: omap device registration); MODULE_LICENSE(GPL v2); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4][v4] OMAP:iommu - missing check for TLB valid entry
Added the missing TLB valid entry setting for cam register Signed-off-by: Hari Kanigeri h-kanige...@ti.com --- arch/arm/mach-omap2/iommu2.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index 6f4b7cc..f01f985 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -183,7 +183,7 @@ static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e) if (!cr) return ERR_PTR(-ENOMEM); - cr-cam = (e-da MMU_CAM_VATAG_MASK) | e-prsvd | e-pgsz; + cr-cam = (e-da MMU_CAM_VATAG_MASK) | e-prsvd | e-pgsz | e-valid; cr-ram = e-pa | e-endian | e-elsz | e-mixed; return cr; -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4][v4] OMAP:iommu- add TLB preservation support
This patch adds TLB preservation support to IOMMU module Signed-off-by: Hari Kanigeri h-kanige...@ti.com Signed-off-by: Hiroshi Doyu hiroshi.d...@nokia.com --- arch/arm/mach-omap2/iommu2.c |4 ++- arch/arm/plat-omap/iommu.c | 43 + 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c index f01f985..5ce76e4 100644 --- a/arch/arm/mach-omap2/iommu2.c +++ b/arch/arm/mach-omap2/iommu2.c @@ -146,6 +146,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) printk(\n); iommu_write_reg(obj, stat, MMU_IRQSTATUS); + omap2_iommu_disable(obj); return stat; } @@ -211,7 +212,8 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf) char *p = buf; /* FIXME: Need more detail analysis of cam/ram */ - p += sprintf(p, %08x %08x\n, cr-cam, cr-ram); + p += sprintf(p, %08x %08x %01x\n, cr-cam, cr-ram, + (cr-cam MMU_CAM_P) ? 1 : 0); return p - buf; } diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 463d638..38658e3 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -171,15 +171,12 @@ static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l) l-base = MMU_LOCK_BASE(val); l-vict = MMU_LOCK_VICT(val); - BUG_ON(l-base != 0); /* Currently no preservation is used */ } static void iotlb_lock_set(struct iommu *obj, struct iotlb_lock *l) { u32 val; - BUG_ON(l-base != 0); /* Currently no preservation is used */ - val = (l-base MMU_LOCK_BASE_SHIFT); val |= (l-vict MMU_LOCK_VICT_SHIFT); @@ -230,22 +227,32 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) clk_enable(obj-clk); - for (i = 0; i obj-nr_tlb_entries; i++) { - struct cr_regs tmp; - - iotlb_lock_get(obj, l); - l.vict = i; - iotlb_lock_set(obj, l); - iotlb_read_cr(obj, tmp); - if (!iotlb_cr_valid(tmp)) - break; - } - - if (i == obj-nr_tlb_entries) { - dev_dbg(obj-dev, %s: full: no entry\n, __func__); + iotlb_lock_get(obj, l); + if (l.base == obj-nr_tlb_entries) { + dev_warn(obj-dev, %s: preserve entries full\n, __func__); err = -EBUSY; goto out; } + if (!e-prsvd) { + for (i = l.base; i obj-nr_tlb_entries; i++) { + struct cr_regs tmp; + + iotlb_lock_get(obj, l); + l.vict = i; + iotlb_lock_set(obj, l); + iotlb_read_cr(obj, tmp); + if (!iotlb_cr_valid(tmp)) + break; + } + if (i == obj-nr_tlb_entries) { + dev_dbg(obj-dev, %s: full: no entry\n, __func__); + err = -EBUSY; + goto out; + } + } else { + l.vict = l.base; + iotlb_lock_set(obj, l); + } cr = iotlb_alloc_cr(obj, e); if (IS_ERR(cr)) { @@ -256,9 +263,11 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e) iotlb_load_cr(obj, cr); kfree(cr); + if (e-prsvd) + l.base++; /* increment victim for next tlb load */ if (++l.vict == obj-nr_tlb_entries) - l.vict = 0; + l.vict = l.base; iotlb_lock_set(obj, l); out: clk_disable(obj-clk); -- 1.7.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html