#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

Reply via email to