#21613: brcm63xx: external IRQs broken
------------------------+---------------------------------------
Reporter: dgcbueu@… | Owner: developers
Type: defect | Status: new
Priority: high | Milestone: Designated Driver (Trunk)
Component: kernel | Version: Trunk
Resolution: | Keywords:
------------------------+---------------------------------------
Comment (by Likharevdmitriy@…):
I fixed it like this:
{{{
--- ./irq-bcm6345-ext.c 2016-03-03 02:41:57.312097733 +0500
+++ ./irq-bcm6345-ext-patched.c 2016-03-03 02:23:10.538692292 +0500
@@ -16,6 +16,7 @@
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <bcm63xx_io.h>
#include "irqchip.h"
@@ -71,9 +72,9 @@ static void bcm6345_ext_intc_irq_ack(str
u32 reg;
raw_spin_lock(&priv->lock);
- reg = __raw_readl(priv->reg);
- reg |= hwirq << (EXTIRQ_CFG_CLEAR * priv->shift);
- __raw_writel(reg, priv->reg);
+ reg = bcm_readl(priv->reg);
+ reg |= 1 << (hwirq + EXTIRQ_CFG_CLEAR * priv->shift);
+ bcm_writel(reg, priv->reg);
raw_spin_unlock(&priv->lock);
}
@@ -84,9 +85,9 @@ static void bcm6345_ext_intc_irq_mask(st
u32 reg;
raw_spin_lock(&priv->lock);
- reg = __raw_readl(priv->reg);
- reg &= ~(hwirq << (EXTIRQ_CFG_MASK * priv->shift));
- __raw_writel(reg, priv->reg);
+ reg = bcm_readl(priv->reg);
+ reg &= ~(1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift));
+ bcm_writel(reg, priv->reg);
raw_spin_unlock(&priv->lock);
}
@@ -97,9 +98,9 @@ static void bcm6345_ext_intc_irq_unmask(
u32 reg;
raw_spin_lock(&priv->lock);
- reg = __raw_readl(priv->reg);
- reg |= hwirq << (EXTIRQ_CFG_MASK * priv->shift);
- __raw_writel(reg, priv->reg);
+ reg = bcm_readl(priv->reg);
+ reg |= 1 << (hwirq + EXTIRQ_CFG_MASK * priv->shift);
+ bcm_writel(reg, priv->reg);
raw_spin_unlock(&priv->lock);
}
@@ -143,22 +144,22 @@ static int bcm6345_ext_intc_set_type(str
}
raw_spin_lock(&priv->lock);
- reg = __raw_readl(priv->reg);
+ reg = bcm_readl(priv->reg);
if (levelsense)
- reg |= hwirq << (EXTIRQ_CFG_LEVELSENSE * priv->shift);
+ reg |= 1 << (hwirq + EXTIRQ_CFG_LEVELSENSE * priv->shift);
else
- reg &= ~(hwirq << (EXTIRQ_CFG_LEVELSENSE * priv->shift));
+ reg &= ~(1 << (hwirq + EXTIRQ_CFG_LEVELSENSE *
priv->shift));
if (sense)
- reg |= hwirq << (EXTIRQ_CFG_SENSE * priv->shift);
+ reg |= 1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift);
else
- reg &= ~(hwirq << (EXTIRQ_CFG_SENSE * priv->shift));
+ reg &= ~(1 << (hwirq + EXTIRQ_CFG_SENSE * priv->shift));
if (bothedge)
- reg |= hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift);
+ reg |= 1 << (hwirq + EXTIRQ_CFG_BOTHEDGE * priv->shift);
else
- reg &= ~(hwirq << (EXTIRQ_CFG_BOTHEDGE * priv->shift));
+ reg &= ~(1 << (hwirq + EXTIRQ_CFG_BOTHEDGE *
priv->shift));
- __raw_writel(reg, priv->reg);
+ bcm_writel(reg, priv->reg);
raw_spin_unlock(&priv->lock);
irqd_set_trigger_type(data, flow_type);
@@ -208,6 +209,7 @@ static int __init __bcm6345_ext_intc_ini
data->reg = reg;
+ data->shift = shift;
data->chip.name = "bcm6345-ext-intc";
data->chip.irq_ack = bcm6345_ext_intc_irq_ack;
data->chip.irq_mask = bcm6345_ext_intc_irq_mask;
}}}
tested on bcm6328
--
Ticket URL: <https://dev.openwrt.org/ticket/21613#comment:2>
OpenWrt <http://openwrt.org>
Opensource Wireless Router Technology
_______________________________________________
openwrt-tickets mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-tickets