Hi,

minor nitpick inline

On 07/07/2015 14:58, Günther Kelleter wrote:
> Signed-off-by: Günther Kelleter <guenther.kelle...@devolo.de>
> ---
>  .../739-MIPS-ath79-add-gpio-irq-support.patch      | 225 
> +++++++++++++++++++++
>  1 file changed, 225 insertions(+)
>  create mode 100644 
> target/linux/ar71xx/patches-3.18/739-MIPS-ath79-add-gpio-irq-support.patch
> 
> diff --git 
> a/target/linux/ar71xx/patches-3.18/739-MIPS-ath79-add-gpio-irq-support.patch 
> b/target/linux/ar71xx/patches-3.18/739-MIPS-ath79-add-gpio-irq-support.patch
> new file mode 100644
> index 0000000..2b90df0
> --- /dev/null
> +++ 
> b/target/linux/ar71xx/patches-3.18/739-MIPS-ath79-add-gpio-irq-support.patch
> @@ -0,0 +1,225 @@
> +--- a/arch/mips/ath79/gpio.c
> ++++ b/arch/mips/ath79/gpio.c
> +@@ -20,9 +20,14 @@
> + #include <linux/io.h>
> + #include <linux/ioport.h>
> + #include <linux/gpio.h>
> ++#include <linux/irq.h>
> ++#include <linux/interrupt.h>
> ++
> ++#include <linux/of.h>
> + 
> + #include <asm/mach-ath79/ar71xx_regs.h>
> + #include <asm/mach-ath79/ath79.h>
> ++#include <asm/mach-ath79/irq.h>
> + #include "common.h"
> + 
> + void __iomem *ath79_gpio_base;
> +@@ -31,6 +36,13 @@ EXPORT_SYMBOL_GPL(ath79_gpio_base);
> + static unsigned long ath79_gpio_count;
> + static DEFINE_SPINLOCK(ath79_gpio_lock);
> + 
> ++/*
> ++ * gpio_both_edge is a bitmask of which gpio pins need to have
> ++ * the detect priority flipped from the interrupt handler to
> ++ * emulate IRQ_TYPE_EDGE_BOTH.
> ++ */
> ++static unsigned long gpio_both_edge = 0;
> ++
> + static void __ath79_gpio_set_value(unsigned gpio, int value)
> + {
> +     void __iomem *base = ath79_gpio_base;
> +@@ -209,6 +221,133 @@ void __init ath79_gpio_output_select(uns
> +     spin_unlock_irqrestore(&ath79_gpio_lock, flags);
> + }
> + 
> ++static int ath79_gpio_irq_type(struct irq_data *d, unsigned type)
> ++{
> ++    int offset = d->irq - ATH79_GPIO_IRQ_BASE;
> ++    void __iomem *base = ath79_gpio_base;
> ++    unsigned long flags;
> ++    unsigned long int_type;
> ++    unsigned long int_polarity;
> ++    unsigned long bit = (1 << offset);
> ++
> ++    spin_lock_irqsave(&ath79_gpio_lock, flags);
> ++
> ++    int_type = __raw_readl(base + AR71XX_GPIO_REG_INT_TYPE);
> ++    int_polarity = __raw_readl(base + AR71XX_GPIO_REG_INT_POLARITY);
> ++
> ++    gpio_both_edge &= ~bit;
> ++
> ++    switch (type) {
> ++    case IRQ_TYPE_EDGE_RISING:
> ++            int_type &= ~bit;
> ++            int_polarity |= bit;
> ++            break;
> ++
> ++    case IRQ_TYPE_EDGE_FALLING:
> ++            int_type &= ~bit;
> ++            int_polarity &= ~bit;
> ++            break;
> ++
> ++    case IRQ_TYPE_LEVEL_HIGH:
> ++            int_type |= bit;
> ++            int_polarity |= bit;
> ++            break;
> ++
> ++    case IRQ_TYPE_LEVEL_LOW:
> ++            int_type |= bit;
> ++            int_polarity &= ~bit;
> ++            break;
> ++
> ++    case IRQ_TYPE_EDGE_BOTH:
> ++            int_type |= bit;
> ++            /* set polarity based on current value */
> ++            if (gpio_get_value(offset)) {
> ++                    int_polarity &= ~bit;
> ++            } else {
> ++                    int_polarity |= bit;
> ++            }
> ++            /* flip this gpio in the interrupt handler */
> ++            gpio_both_edge |= bit;
> ++            break;
> ++
> ++    default:
> ++            spin_unlock_irqrestore(&ath79_gpio_lock, flags);
> ++            return -EINVAL;
> ++    }
> ++
> ++    __raw_writel(int_type, base + AR71XX_GPIO_REG_INT_TYPE);
> ++    __raw_writel(int_polarity, base + AR71XX_GPIO_REG_INT_POLARITY);
> ++
> ++    __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_MODE) | (1 << 
> offset),
> ++                 base + AR71XX_GPIO_REG_INT_MODE);
> ++
> ++    __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) & ~(1 << 
> offset),
> ++                 base + AR71XX_GPIO_REG_INT_ENABLE);
> ++
> ++    spin_unlock_irqrestore(&ath79_gpio_lock, flags);
> ++    return 0;
> ++}
> ++
> ++static void ath79_gpio_irq_enable(struct irq_data *d)
> ++{
> ++    int offset = d->irq - ATH79_GPIO_IRQ_BASE;
> ++    void __iomem *base = ath79_gpio_base;
> ++
> ++    __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) | (1 << 
> offset),
> ++                 base + AR71XX_GPIO_REG_INT_ENABLE);
> ++}
> ++
> ++static void ath79_gpio_irq_disable(struct irq_data *d)
> ++{
> ++    int offset = d->irq - ATH79_GPIO_IRQ_BASE;
> ++    void __iomem *base = ath79_gpio_base;
> ++
> ++    __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) & ~(1 << 
> offset),
> ++                 base + AR71XX_GPIO_REG_INT_ENABLE);
> ++}
> ++
> ++static struct irq_chip ath79_gpio_irqchip = {
> ++    .name = "GPIO",
> ++    .irq_enable = ath79_gpio_irq_enable,
> ++    .irq_disable = ath79_gpio_irq_disable,
> ++    .irq_set_type = ath79_gpio_irq_type,
> ++};
> ++
> ++static irqreturn_t ath79_gpio_irq(int irq, void *dev)
> ++{
> ++    void __iomem *base = ath79_gpio_base;
> ++    unsigned int stat = __raw_readl(base + AR71XX_GPIO_REG_INT_PENDING);
> ++
> ++    while (stat) {

make use of the for_each_set_bit() macro please


        John





> ++            int bit_num = __ffs(stat);
> ++            unsigned long bit = (1<<bit_num);
> ++
> ++            if (bit & gpio_both_edge) {
> ++                    __raw_writel(__raw_readl(base + 
> AR71XX_GPIO_REG_INT_POLARITY) ^ bit,
> ++                            base + AR71XX_GPIO_REG_INT_POLARITY);
> ++            }
> ++
> ++            generic_handle_irq(ATH79_GPIO_IRQ(bit_num));
> ++            stat &= ~bit;
> ++    }
> ++
> ++    return IRQ_HANDLED;
> ++}
> ++
> ++static int __init ath79_gpio_irq_init(struct gpio_chip *chip)
> ++{
> ++    int irq;
> ++    int irq_base = ATH79_GPIO_IRQ_BASE;
> ++
> ++    for (irq = irq_base; irq < irq_base + chip->ngpio; irq++) {
> ++            irq_set_chip_data(irq, chip);
> ++            irq_set_chip_and_handler(irq, &ath79_gpio_irqchip, 
> handle_simple_irq);
> ++            irq_set_noprobe(irq);
> ++    }
> ++
> ++    return 0;
> ++}
> ++
> + void __init ath79_gpio_init(void)
> + {
> +     int err;
> +@@ -245,6 +384,10 @@ void __init ath79_gpio_init(void)
> +     err = gpiochip_add(&ath79_gpio_chip);
> +     if (err)
> +             panic("cannot add AR71xx GPIO chip, error=%d", err);
> ++
> ++    ath79_gpio_irq_init(&ath79_gpio_chip);
> ++
> ++    request_irq(ATH79_MISC_IRQ(2), ath79_gpio_irq, 0, "ath79-gpio", NULL);
> + }
> + 
> + int gpio_get_value(unsigned gpio)
> +@@ -267,14 +410,22 @@ EXPORT_SYMBOL(gpio_set_value);
> + 
> + int gpio_to_irq(unsigned gpio)
> + {
> +-    /* FIXME */
> +-    return -EINVAL;
> ++    if (gpio > ath79_gpio_count) {
> ++            return -EINVAL;
> ++    }
> ++
> ++    return ATH79_GPIO_IRQ_BASE + gpio;
> + }
> + EXPORT_SYMBOL(gpio_to_irq);
> + 
> + int irq_to_gpio(unsigned irq)
> + {
> +-    /* FIXME */
> +-    return -EINVAL;
> ++    unsigned gpio = irq - ATH79_GPIO_IRQ_BASE;
> ++
> ++    if (gpio > ath79_gpio_count) {
> ++            return -EINVAL;
> ++    }
> ++
> ++    return gpio;
> + }
> + EXPORT_SYMBOL(irq_to_gpio);
> +--- a/arch/mips/include/asm/mach-ath79/irq.h
> ++++ b/arch/mips/include/asm/mach-ath79/irq.h
> +@@ -10,7 +10,7 @@
> + #define __ASM_MACH_ATH79_IRQ_H
> + 
> + #define MIPS_CPU_IRQ_BASE   0
> +-#define NR_IRQS                     51
> ++#define NR_IRQS                     83
> + 
> + #define ATH79_CPU_IRQ(_x)   (MIPS_CPU_IRQ_BASE + (_x))
> + 
> +@@ -30,6 +30,10 @@
> + #define ATH79_IP3_IRQ_COUNT     3
> + #define ATH79_IP3_IRQ(_x)       (ATH79_IP3_IRQ_BASE + (_x))
> + 
> ++#define ATH79_GPIO_IRQ_BASE (ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT)
> ++#define ATH79_GPIO_IRQ_COUNT        32
> ++#define ATH79_GPIO_IRQ(_x)  (ATH79_GPIO_IRQ_BASE + (_x))
> ++
> + #include_next <irq.h>
> + 
> + #endif /* __ASM_MACH_ATH79_IRQ_H */
> 
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to