[PATCH] ARM: OMAP2+: INTC: Acknowledge stuck active interrupts

2014-03-06 Thread Stefan Sørensen
When an interrupt has become active on the INTC it will stay active
until it is acked, even if masked or de-asserted. The
INTC_PENDING_IRQn registers are however updated and since these are
used by omap_intc_handle_irq to determine which interrupt to handle,
it will never see the active interrupt. This will result in a storm of
useless interrupts that is only stopped when another higher priority
interrupt is asserted.

Fix by sending the INTC an acknowledge if we find no interrupts to
handle.

Signed-off-by: Stefan Sørensen stefan.soren...@spectralink.com
---
 arch/arm/mach-omap2/irq.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index e022a86..6037a9a 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -222,6 +222,7 @@ void __init ti81xx_init_irq(void)
 static inline void omap_intc_handle_irq(void __iomem *base_addr, struct 
pt_regs *regs)
 {
u32 irqnr;
+   int handled_irq = 0;
 
do {
irqnr = readl_relaxed(base_addr + 0x98);
@@ -249,8 +250,15 @@ out:
if (irqnr) {
irqnr = irq_find_mapping(domain, irqnr);
handle_IRQ(irqnr, regs);
+   handled_irq = 1;
}
} while (irqnr);
+
+   /* If an irq is masked or deasserted while active, we will
+* keep ending up here with no irq handled. So remove it from
+* the INTC with an ack.*/
+   if (!handled_irq)
+   omap_ack_irq(NULL);
 }
 
 asmlinkage void __exception_irq_entry omap2_intc_handle_irq(struct pt_regs 
*regs)
-- 
1.8.5.3

--
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] ARM: OMAP2+: Use handle_fasteoi_irq for INTC interrupt handling

2014-02-24 Thread Stefan Sørensen
Currently INTC interrupts are handled using handle_level_irq which
will acknowledge the interrupt before running the handler. If a second
interrupt is then asserted and this interrupt is disabled while
running the first handler, the INTC will be brought into an
inconsistent state. In this state the INTC will interrupt the CPU but
the interrupt pending registers will show no pending interrupts
causing the CPU to take no action. This will repeat until another
higher priority interrupt triggers, hogging the CPU.

handle_fasteoi_irq does not acknowledge the interrupt before after
running the handler, so using this for handling INTC interrupts avoid
the above problem. This also brings the handling more in line with the
sequence described in the TRM.

Signed-off-by: Stefan Sørensen stefan.soren...@spectralink.com
---
 arch/arm/mach-omap2/irq.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index e022a86..9d09914 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -97,12 +97,6 @@ static void omap_ack_irq(struct irq_data *d)
intc_bank_write_reg(0x1, irq_banks[0], INTC_CONTROL);
 }
 
-static void omap_mask_ack_irq(struct irq_data *d)
-{
-   irq_gc_mask_disable_reg(d);
-   omap_ack_irq(d);
-}
-
 static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
 {
unsigned long tmp;
@@ -145,9 +139,9 @@ omap_alloc_gc(void __iomem *base, unsigned int irq_start, 
unsigned int num)
struct irq_chip_type *ct;
 
gc = irq_alloc_generic_chip(INTC, 1, irq_start, base,
-   handle_level_irq);
+   handle_fasteoi_irq);
ct = gc-chip_types;
-   ct-chip.irq_ack = omap_mask_ack_irq;
+   ct-chip.irq_eoi = omap_ack_irq;
ct-chip.irq_mask = irq_gc_mask_disable_reg;
ct-chip.irq_unmask = irq_gc_unmask_enable_reg;
ct-chip.flags |= IRQCHIP_SKIP_SET_WAKE;
-- 
1.8.5.3

--
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] mtd:elm: Use correct check on return value of pm_runtime_get_sync

2014-02-05 Thread Stefan Sørensen
The ELM driver incorrectly reagard any non-zero return value from
pm_runtime_get_sync as an error, but it may return 1 if the device
was already active. Fix to only error when return value is negative.

Signed-off-by: Stefan Sørensen stefan.soren...@spectralink.com
---
 drivers/mtd/devices/elm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
index d1dd6a3..e2c073c 100644
--- a/drivers/mtd/devices/elm.c
+++ b/drivers/mtd/devices/elm.c
@@ -380,7 +380,7 @@ static int elm_probe(struct platform_device *pdev)
}
 
pm_runtime_enable(pdev-dev);
-   if (pm_runtime_get_sync(pdev-dev)) {
+   if (pm_runtime_get_sync(pdev-dev)  0) {
ret = -EINVAL;
pm_runtime_disable(pdev-dev);
dev_err(pdev-dev, can't enable clock\n);
-- 
1.8.5.3

--
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