From eac8dbf74f30479b70b9a53f3b24285bd6229d09 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 3 Sep 2016 09:14:58 +0100 Subject: ARM: sa1111: ensure we only touch RAB bus type devices when removing When removing a SA1111 device, we try to remove all child devices. However, we must only remove our own RAB bus typed devices from the tree, there may be other devices present which should not be touched. This is necessary before we introduce gpiochip to SA1111 to avoid incorrectly trying to remove the gpiochip device, leading to an oops in __release_resource(). Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 2e076c492005..303c62861d84 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -815,6 +815,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { struct sa1111_dev *sadev = SA1111_DEV(dev); + if (dev->bus != &sa1111_bus_type) + return 0; device_del(&sadev->dev); release_resource(&sadev->res); put_device(&sadev->dev); -- cgit From 7d53c1f01210aa79838f1fe34b2a89f8e900d720 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2016 15:29:26 +0100 Subject: ARM: sa1111: use devm_kzalloc() Use devm_kzalloc() to allocate our driver data, so we can eliminate its kfree() from the device removal and error cleanup paths. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 303c62861d84..f2ce21c03646 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -696,7 +696,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) if (!pd) return -EINVAL; - sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); + sachip = devm_kzalloc(me, sizeof(struct sa1111), GFP_KERNEL); if (!sachip) return -ENOMEM; @@ -808,7 +808,6 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) err_clkput: clk_put(sachip->clk); err_free: - kfree(sachip); return ret; } @@ -847,7 +846,6 @@ static void __sa1111_remove(struct sa1111 *sachip) iounmap(sachip->base); clk_put(sachip->clk); - kfree(sachip); } struct sa1111_save_data { -- cgit From deee856a5c6293c50ad6589c9f8a1cca5ed08ae9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 30 Aug 2016 22:47:35 +0100 Subject: ARM: sa1111: use devm_clk_get() Convert sa1111 to use devm_clk_get() to get its clock resource, and strip out the clk_put() calls. This simplifies the error handling a little. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index f2ce21c03646..09a4f932c2ec 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -700,15 +700,13 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) if (!sachip) return -ENOMEM; - sachip->clk = clk_get(me, "SA1111_CLK"); - if (IS_ERR(sachip->clk)) { - ret = PTR_ERR(sachip->clk); - goto err_free; - } + sachip->clk = devm_clk_get(me, "SA1111_CLK"); + if (IS_ERR(sachip->clk)) + return PTR_ERR(sachip->clk); ret = clk_prepare(sachip->clk); if (ret) - goto err_clkput; + return ret; spin_lock_init(&sachip->lock); @@ -805,9 +803,6 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) iounmap(sachip->base); err_clk_unprep: clk_unprepare(sachip->clk); - err_clkput: - clk_put(sachip->clk); - err_free: return ret; } @@ -845,7 +840,6 @@ static void __sa1111_remove(struct sa1111 *sachip) } iounmap(sachip->base); - clk_put(sachip->clk); } struct sa1111_save_data { -- cgit From ccb7d854d65a09ffe4b6c8342b8d1c6bee6740bb Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2016 16:01:32 +0100 Subject: ARM: sa1111: move irq cleanup to separate function Move the SA1111 interrupt cleanup to a separate function, so it can be re-used in the probe error cleanup path. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 09a4f932c2ec..eaa818d921a9 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -509,6 +509,24 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) return 0; } +static void sa1111_remove_irq(struct sa1111 *sachip) +{ + void __iomem *irqbase = sachip->base + SA1111_INTC; + + /* disable all IRQs */ + sa1111_writel(0, irqbase + SA1111_INTEN0); + sa1111_writel(0, irqbase + SA1111_INTEN1); + sa1111_writel(0, irqbase + SA1111_WAKEEN0); + sa1111_writel(0, irqbase + SA1111_WAKEEN1); + + if (sachip->irq != NO_IRQ) { + irq_set_chained_handler_and_data(sachip->irq, NULL, NULL); + irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); + + release_mem_region(sachip->phys + SA1111_INTC, 512); + } +} + /* * Bring the SA1111 out of reset. This requires a set procedure: * 1. nRESET asserted (by hardware) @@ -819,26 +837,13 @@ static int sa1111_remove_one(struct device *dev, void *data) static void __sa1111_remove(struct sa1111 *sachip) { - void __iomem *irqbase = sachip->base + SA1111_INTC; - device_for_each_child(sachip->dev, NULL, sa1111_remove_one); - /* disable all IRQs */ - sa1111_writel(0, irqbase + SA1111_INTEN0); - sa1111_writel(0, irqbase + SA1111_INTEN1); - sa1111_writel(0, irqbase + SA1111_WAKEEN0); - sa1111_writel(0, irqbase + SA1111_WAKEEN1); + sa1111_remove_irq(sachip); clk_disable(sachip->clk); clk_unprepare(sachip->clk); - if (sachip->irq != NO_IRQ) { - irq_set_chained_handler_and_data(sachip->irq, NULL, NULL); - irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); - - release_mem_region(sachip->phys + SA1111_INTC, 512); - } - iounmap(sachip->base); } -- cgit From 17cf50116e10affaadfee9af2253c841f7ac0623 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 31 Aug 2016 08:49:45 +0100 Subject: ARM: sa1111: implement a gpio_chip for SA1111 GPIOs Add a gpio_chip instance for SA1111 GPIOs. This allows us to use gpiolib to lookup and manipulate SA1111 GPIOs. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index eaa818d921a9..16cc3b5122ad 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -15,6 +15,7 @@ * from machine specific code with proper arguments when required. */ #include +#include #include #include #include @@ -107,6 +108,7 @@ struct sa1111 { spinlock_t lock; void __iomem *base; struct sa1111_platform_data *pdata; + struct gpio_chip gc; #ifdef CONFIG_PM void *saved_state; #endif @@ -527,6 +529,163 @@ static void sa1111_remove_irq(struct sa1111 *sachip) } } +enum { + SA1111_GPIO_PXDDR = (SA1111_GPIO_PADDR - SA1111_GPIO_PADDR), + SA1111_GPIO_PXDRR = (SA1111_GPIO_PADRR - SA1111_GPIO_PADDR), + SA1111_GPIO_PXDWR = (SA1111_GPIO_PADWR - SA1111_GPIO_PADDR), + SA1111_GPIO_PXSDR = (SA1111_GPIO_PASDR - SA1111_GPIO_PADDR), + SA1111_GPIO_PXSSR = (SA1111_GPIO_PASSR - SA1111_GPIO_PADDR), +}; + +static struct sa1111 *gc_to_sa1111(struct gpio_chip *gc) +{ + return container_of(gc, struct sa1111, gc); +} + +static void __iomem *sa1111_gpio_map_reg(struct sa1111 *sachip, unsigned offset) +{ + void __iomem *reg = sachip->base + SA1111_GPIO; + + if (offset < 4) + return reg + SA1111_GPIO_PADDR; + if (offset < 10) + return reg + SA1111_GPIO_PBDDR; + if (offset < 18) + return reg + SA1111_GPIO_PCDDR; + return NULL; +} + +static u32 sa1111_gpio_map_bit(unsigned offset) +{ + if (offset < 4) + return BIT(offset); + if (offset < 10) + return BIT(offset - 4); + if (offset < 18) + return BIT(offset - 10); + return 0; +} + +static void sa1111_gpio_modify(void __iomem *reg, u32 mask, u32 set) +{ + u32 val; + + val = readl_relaxed(reg); + val &= ~mask; + val |= mask & set; + writel_relaxed(val, reg); +} + +static int sa1111_gpio_get_direction(struct gpio_chip *gc, unsigned offset) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + void __iomem *reg = sa1111_gpio_map_reg(sachip, offset); + u32 mask = sa1111_gpio_map_bit(offset); + + return !!(readl_relaxed(reg + SA1111_GPIO_PXDDR) & mask); +} + +static int sa1111_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + unsigned long flags; + void __iomem *reg = sa1111_gpio_map_reg(sachip, offset); + u32 mask = sa1111_gpio_map_bit(offset); + + spin_lock_irqsave(&sachip->lock, flags); + sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, mask); + sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, mask); + spin_unlock_irqrestore(&sachip->lock, flags); + + return 0; +} + +static int sa1111_gpio_direction_output(struct gpio_chip *gc, unsigned offset, + int value) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + unsigned long flags; + void __iomem *reg = sa1111_gpio_map_reg(sachip, offset); + u32 mask = sa1111_gpio_map_bit(offset); + + spin_lock_irqsave(&sachip->lock, flags); + sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0); + sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0); + sa1111_gpio_modify(reg + SA1111_GPIO_PXDDR, mask, 0); + sa1111_gpio_modify(reg + SA1111_GPIO_PXSDR, mask, 0); + spin_unlock_irqrestore(&sachip->lock, flags); + + return 0; +} + +static int sa1111_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + void __iomem *reg = sa1111_gpio_map_reg(sachip, offset); + u32 mask = sa1111_gpio_map_bit(offset); + + return !!(readl_relaxed(reg + SA1111_GPIO_PXDRR) & mask); +} + +static void sa1111_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + unsigned long flags; + void __iomem *reg = sa1111_gpio_map_reg(sachip, offset); + u32 mask = sa1111_gpio_map_bit(offset); + + spin_lock_irqsave(&sachip->lock, flags); + sa1111_gpio_modify(reg + SA1111_GPIO_PXDWR, mask, value ? mask : 0); + sa1111_gpio_modify(reg + SA1111_GPIO_PXSSR, mask, value ? mask : 0); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +static void sa1111_gpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, + unsigned long *bits) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + unsigned long flags; + void __iomem *reg = sachip->base + SA1111_GPIO; + u32 msk, val; + + msk = *mask; + val = *bits; + + spin_lock_irqsave(&sachip->lock, flags); + sa1111_gpio_modify(reg + SA1111_GPIO_PADWR, msk & 15, val); + sa1111_gpio_modify(reg + SA1111_GPIO_PASSR, msk & 15, val); + sa1111_gpio_modify(reg + SA1111_GPIO_PBDWR, (msk >> 4) & 255, val >> 4); + sa1111_gpio_modify(reg + SA1111_GPIO_PBSSR, (msk >> 4) & 255, val >> 4); + sa1111_gpio_modify(reg + SA1111_GPIO_PCDWR, (msk >> 12) & 255, val >> 12); + sa1111_gpio_modify(reg + SA1111_GPIO_PCSSR, (msk >> 12) & 255, val >> 12); + spin_unlock_irqrestore(&sachip->lock, flags); +} + +static int sa1111_gpio_to_irq(struct gpio_chip *gc, unsigned offset) +{ + struct sa1111 *sachip = gc_to_sa1111(gc); + + return sachip->irq_base + offset; +} + +static int sa1111_setup_gpios(struct sa1111 *sachip) +{ + sachip->gc.label = "sa1111"; + sachip->gc.parent = sachip->dev; + sachip->gc.owner = THIS_MODULE; + sachip->gc.get_direction = sa1111_gpio_get_direction; + sachip->gc.direction_input = sa1111_gpio_direction_input; + sachip->gc.direction_output = sa1111_gpio_direction_output; + sachip->gc.get = sa1111_gpio_get; + sachip->gc.set = sa1111_gpio_set; + sachip->gc.set_multiple = sa1111_gpio_set_multiple; + sachip->gc.to_irq = sa1111_gpio_to_irq; + sachip->gc.base = -1; + sachip->gc.ngpio = 18; + + return devm_gpiochip_add_data(sachip->dev, &sachip->gc, sachip); +} + /* * Bring the SA1111 out of reset. This requires a set procedure: * 1. nRESET asserted (by hardware) @@ -773,6 +932,11 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) goto err_clk; } + /* Setup the GPIOs - should really be done after the IRQ setup */ + ret = sa1111_setup_gpios(sachip); + if (ret) + goto err_irq; + #ifdef CONFIG_ARCH_SA1100 { unsigned int val; @@ -815,6 +979,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) return 0; + err_irq: + sa1111_remove_irq(sachip); err_clk: clk_disable(sachip->clk); err_unmap: -- cgit From 1629c9ab3679908d2e18ca306df1f07f48713f6b Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2016 18:43:28 +0100 Subject: ARM: sa1111: clean up duplication in IRQ chip implementation Clean up the duplication in the IRQ chip implementation - we can compute the register address from the interrupt number rather than duplicating the code for each register. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 189 ++++++++++++----------------------------------- 1 file changed, 48 insertions(+), 141 deletions(-) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 16cc3b5122ad..7f232ce50944 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -233,132 +233,44 @@ static void sa1111_irq_handler(struct irq_desc *desc) #define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base)) #define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32)) -static void sa1111_ack_irq(struct irq_data *d) -{ -} - -static void sa1111_mask_lowirq(struct irq_data *d) -{ - struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned long ie0; - - ie0 = sa1111_readl(mapbase + SA1111_INTEN0); - ie0 &= ~SA1111_IRQMASK_LO(d->irq); - writel(ie0, mapbase + SA1111_INTEN0); -} - -static void sa1111_unmask_lowirq(struct irq_data *d) +static u32 sa1111_irqmask(struct irq_data *d) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned long ie0; - - ie0 = sa1111_readl(mapbase + SA1111_INTEN0); - ie0 |= SA1111_IRQMASK_LO(d->irq); - sa1111_writel(ie0, mapbase + SA1111_INTEN0); -} -/* - * Attempt to re-trigger the interrupt. The SA1111 contains a register - * (INTSET) which claims to do this. However, in practice no amount of - * manipulation of INTEN and INTSET guarantees that the interrupt will - * be triggered. In fact, its very difficult, if not impossible to get - * INTSET to re-trigger the interrupt. - */ -static int sa1111_retrigger_lowirq(struct irq_data *d) -{ - struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_LO(d->irq); - unsigned long ip0; - int i; - - ip0 = sa1111_readl(mapbase + SA1111_INTPOL0); - for (i = 0; i < 8; i++) { - sa1111_writel(ip0 ^ mask, mapbase + SA1111_INTPOL0); - sa1111_writel(ip0, mapbase + SA1111_INTPOL0); - if (sa1111_readl(mapbase + SA1111_INTSTATCLR0) & mask) - break; - } - - if (i == 8) - pr_err("Danger Will Robinson: failed to re-trigger IRQ%d\n", - d->irq); - return i == 8 ? -1 : 0; + return BIT((d->irq - sachip->irq_base) & 31); } -static int sa1111_type_lowirq(struct irq_data *d, unsigned int flags) +static int sa1111_irqbank(struct irq_data *d) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_LO(d->irq); - unsigned long ip0; - - if (flags == IRQ_TYPE_PROBE) - return 0; - - if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0) - return -EINVAL; - - ip0 = sa1111_readl(mapbase + SA1111_INTPOL0); - if (flags & IRQ_TYPE_EDGE_RISING) - ip0 &= ~mask; - else - ip0 |= mask; - sa1111_writel(ip0, mapbase + SA1111_INTPOL0); - sa1111_writel(ip0, mapbase + SA1111_WAKEPOL0); - return 0; + return ((d->irq - sachip->irq_base) / 32) * 4; } -static int sa1111_wake_lowirq(struct irq_data *d, unsigned int on) +static void sa1111_ack_irq(struct irq_data *d) { - struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_LO(d->irq); - unsigned long we0; - - we0 = sa1111_readl(mapbase + SA1111_WAKEEN0); - if (on) - we0 |= mask; - else - we0 &= ~mask; - sa1111_writel(we0, mapbase + SA1111_WAKEEN0); - - return 0; } -static struct irq_chip sa1111_low_chip = { - .name = "SA1111-l", - .irq_ack = sa1111_ack_irq, - .irq_mask = sa1111_mask_lowirq, - .irq_unmask = sa1111_unmask_lowirq, - .irq_retrigger = sa1111_retrigger_lowirq, - .irq_set_type = sa1111_type_lowirq, - .irq_set_wake = sa1111_wake_lowirq, -}; - -static void sa1111_mask_highirq(struct irq_data *d) +static void sa1111_mask_irq(struct irq_data *d) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned long ie1; + void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d); + u32 ie; - ie1 = sa1111_readl(mapbase + SA1111_INTEN1); - ie1 &= ~SA1111_IRQMASK_HI(d->irq); - sa1111_writel(ie1, mapbase + SA1111_INTEN1); + ie = sa1111_readl(mapbase + SA1111_INTEN0); + ie &= ~sa1111_irqmask(d); + sa1111_writel(ie, mapbase + SA1111_INTEN0); } -static void sa1111_unmask_highirq(struct irq_data *d) +static void sa1111_unmask_irq(struct irq_data *d) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned long ie1; + void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d); + u32 ie; - ie1 = sa1111_readl(mapbase + SA1111_INTEN1); - ie1 |= SA1111_IRQMASK_HI(d->irq); - sa1111_writel(ie1, mapbase + SA1111_INTEN1); + ie = sa1111_readl(mapbase + SA1111_INTEN0); + ie |= sa1111_irqmask(d); + sa1111_writel(ie, mapbase + SA1111_INTEN0); } /* @@ -368,19 +280,18 @@ static void sa1111_unmask_highirq(struct irq_data *d) * be triggered. In fact, its very difficult, if not impossible to get * INTSET to re-trigger the interrupt. */ -static int sa1111_retrigger_highirq(struct irq_data *d) +static int sa1111_retrigger_irq(struct irq_data *d) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_HI(d->irq); - unsigned long ip1; + void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d); + u32 ip, mask = sa1111_irqmask(d); int i; - ip1 = sa1111_readl(mapbase + SA1111_INTPOL1); + ip = sa1111_readl(mapbase + SA1111_INTPOL0); for (i = 0; i < 8; i++) { - sa1111_writel(ip1 ^ mask, mapbase + SA1111_INTPOL1); - sa1111_writel(ip1, mapbase + SA1111_INTPOL1); - if (sa1111_readl(mapbase + SA1111_INTSTATCLR1) & mask) + sa1111_writel(ip ^ mask, mapbase + SA1111_INTPOL0); + sa1111_writel(ip, mapbase + SA1111_INTPOL0); + if (sa1111_readl(mapbase + SA1111_INTSTATCLR0) & mask) break; } @@ -390,12 +301,11 @@ static int sa1111_retrigger_highirq(struct irq_data *d) return i == 8 ? -1 : 0; } -static int sa1111_type_highirq(struct irq_data *d, unsigned int flags) +static int sa1111_type_irq(struct irq_data *d, unsigned int flags) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_HI(d->irq); - unsigned long ip1; + void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d); + u32 ip, mask = sa1111_irqmask(d); if (flags == IRQ_TYPE_PROBE) return 0; @@ -403,42 +313,41 @@ static int sa1111_type_highirq(struct irq_data *d, unsigned int flags) if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0) return -EINVAL; - ip1 = sa1111_readl(mapbase + SA1111_INTPOL1); + ip = sa1111_readl(mapbase + SA1111_INTPOL0); if (flags & IRQ_TYPE_EDGE_RISING) - ip1 &= ~mask; + ip &= ~mask; else - ip1 |= mask; - sa1111_writel(ip1, mapbase + SA1111_INTPOL1); - sa1111_writel(ip1, mapbase + SA1111_WAKEPOL1); + ip |= mask; + sa1111_writel(ip, mapbase + SA1111_INTPOL0); + sa1111_writel(ip, mapbase + SA1111_WAKEPOL0); return 0; } -static int sa1111_wake_highirq(struct irq_data *d, unsigned int on) +static int sa1111_wake_irq(struct irq_data *d, unsigned int on) { struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - void __iomem *mapbase = sachip->base + SA1111_INTC; - unsigned int mask = SA1111_IRQMASK_HI(d->irq); - unsigned long we1; + void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d); + u32 we, mask = sa1111_irqmask(d); - we1 = sa1111_readl(mapbase + SA1111_WAKEEN1); + we = sa1111_readl(mapbase + SA1111_WAKEEN0); if (on) - we1 |= mask; + we |= mask; else - we1 &= ~mask; - sa1111_writel(we1, mapbase + SA1111_WAKEEN1); + we &= ~mask; + sa1111_writel(we, mapbase + SA1111_WAKEEN0); return 0; } -static struct irq_chip sa1111_high_chip = { - .name = "SA1111-h", +static struct irq_chip sa1111_irq_chip = { + .name = "SA1111", .irq_ack = sa1111_ack_irq, - .irq_mask = sa1111_mask_highirq, - .irq_unmask = sa1111_unmask_highirq, - .irq_retrigger = sa1111_retrigger_highirq, - .irq_set_type = sa1111_type_highirq, - .irq_set_wake = sa1111_wake_highirq, + .irq_mask = sa1111_mask_irq, + .irq_unmask = sa1111_unmask_irq, + .irq_retrigger = sa1111_retrigger_irq, + .irq_set_type = sa1111_type_irq, + .irq_set_wake = sa1111_wake_irq, }; static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) @@ -484,16 +393,14 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) for (i = IRQ_GPAIN0; i <= SSPROR; i++) { irq = sachip->irq_base + i; - irq_set_chip_and_handler(irq, &sa1111_low_chip, - handle_edge_irq); + irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); } for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { irq = sachip->irq_base + i; - irq_set_chip_and_handler(irq, &sa1111_high_chip, - handle_edge_irq); + irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); } -- cgit From cf6e4ca3e53f734f8fcb253a686c1fdbb6a50e85 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2016 00:45:33 +0100 Subject: ARM: sa1111: add sa1111_get_irq() Add a helper function to get the irq number for a device. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 7f232ce50944..3c722a4143fe 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1357,6 +1357,14 @@ void sa1111_disable_device(struct sa1111_dev *sadev) } EXPORT_SYMBOL(sa1111_disable_device); +int sa1111_get_irq(struct sa1111_dev *sadev, unsigned num) +{ + if (num >= ARRAY_SIZE(sadev->irq)) + return -EINVAL; + return sadev->irq[num]; +} +EXPORT_SYMBOL_GPL(sa1111_get_irq); + /* * SA1111 "Register Access Bus." * -- cgit From b60752f2b20c167859943e001727f0d4da419b23 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2016 13:46:46 +0100 Subject: ARM: sa1111: provide to_sa1111_device() macro Provide a nicer to_sa1111_device macro to convert a struct device to a sa1111_dev. We will need this for drivers when converting them to dev_pm_ops, or removing shutdown methods. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'arch/arm/common') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 3c722a4143fe..4ecd5120fce7 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -691,7 +691,7 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, static void sa1111_dev_release(struct device *_dev) { - struct sa1111_dev *dev = SA1111_DEV(_dev); + struct sa1111_dev *dev = to_sa1111_device(_dev); kfree(dev); } @@ -899,7 +899,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_dev *sadev = to_sa1111_device(dev); if (dev->bus != &sa1111_bus_type) return 0; device_del(&sadev->dev); @@ -1373,7 +1373,7 @@ EXPORT_SYMBOL_GPL(sa1111_get_irq); */ static int sa1111_match(struct device *_dev, struct device_driver *_drv) { - struct sa1111_dev *dev = SA1111_DEV(_dev); + struct sa1111_dev *dev = to_sa1111_device(_dev); struct sa1111_driver *drv = SA1111_DRV(_drv); return !!(dev->devid & drv->devid); @@ -1381,7 +1381,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) static int sa1111_bus_suspend(struct device *dev, pm_message_t state) { - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_dev *sadev = to_sa1111_device(dev); struct sa1111_driver *drv = SA1111_DRV(dev->driver); int ret = 0; @@ -1392,7 +1392,7 @@ static int sa1111_bus_suspend(struct device *dev, pm_message_t state) static int sa1111_bus_resume(struct device *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_dev *sadev = to_sa1111_device(dev); struct sa1111_driver *drv = SA1111_DRV(dev->driver); int ret = 0; @@ -1406,12 +1406,12 @@ static void sa1111_bus_shutdown(struct device *dev) struct sa1111_driver *drv = SA1111_DRV(dev->driver); if (drv && drv->shutdown) - drv->shutdown(SA1111_DEV(dev)); + drv->shutdown(to_sa1111_device(dev)); } static int sa1111_bus_probe(struct device *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_dev *sadev = to_sa1111_device(dev); struct sa1111_driver *drv = SA1111_DRV(dev->driver); int ret = -ENODEV; @@ -1422,7 +1422,7 @@ static int sa1111_bus_probe(struct device *dev) static int sa1111_bus_remove(struct device *dev) { - struct sa1111_dev *sadev = SA1111_DEV(dev); + struct sa1111_dev *sadev = to_sa1111_device(dev); struct sa1111_driver *drv = SA1111_DRV(dev->driver); int ret = 0; @@ -1487,7 +1487,7 @@ static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) static int sa1111_notifier_call(struct notifier_block *n, unsigned long action, void *data) { - struct sa1111_dev *dev = SA1111_DEV(data); + struct sa1111_dev *dev = to_sa1111_device(data); switch (action) { case BUS_NOTIFY_ADD_DEVICE: -- cgit