aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/langwell_gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/langwell_gpio.c')
-rw-r--r--drivers/gpio/langwell_gpio.c43
1 files changed, 20 insertions, 23 deletions
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
index 54d70a47afc1..560ab648cf18 100644
--- a/drivers/gpio/langwell_gpio.c
+++ b/drivers/gpio/langwell_gpio.c
@@ -187,31 +187,28 @@ MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
187 187
188static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) 188static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
189{ 189{
190 struct lnw_gpio *lnw = get_irq_data(irq); 190 struct irq_data *data = irq_desc_get_irq_data(desc);
191 u32 base, gpio; 191 struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data);
192 struct irq_chip *chip = irq_data_get_irq_chip(data);
193 u32 base, gpio, mask;
194 unsigned long pending;
192 void __iomem *gedr; 195 void __iomem *gedr;
193 u32 gedr_v;
194 196
195 /* check GPIO controller to check which pin triggered the interrupt */ 197 /* check GPIO controller to check which pin triggered the interrupt */
196 for (base = 0; base < lnw->chip.ngpio; base += 32) { 198 for (base = 0; base < lnw->chip.ngpio; base += 32) {
197 gedr = gpio_reg(&lnw->chip, base, GEDR); 199 gedr = gpio_reg(&lnw->chip, base, GEDR);
198 gedr_v = readl(gedr); 200 pending = readl(gedr);
199 if (!gedr_v) 201 while (pending) {
200 continue; 202 gpio = __ffs(pending) - 1;
201 for (gpio = base; gpio < base + 32; gpio++) 203 mask = BIT(gpio);
202 if (gedr_v & BIT(gpio % 32)) { 204 pending &= ~mask;
203 pr_debug("pin %d triggered\n", gpio); 205 /* Clear before handling so we can't lose an edge */
204 generic_handle_irq(lnw->irq_base + gpio); 206 writel(mask, gedr);
205 } 207 generic_handle_irq(lnw->irq_base + base + gpio);
206 /* clear the edge detect status bit */ 208 }
207 writel(gedr_v, gedr);
208 } 209 }
209 210
210 if (desc->chip->irq_eoi) 211 chip->irq_eoi(data);
211 desc->chip->irq_eoi(irq_get_irq_data(irq));
212 else
213 dev_warn(lnw->chip.dev, "missing EOI handler for irq %d\n", irq);
214
215} 212}
216 213
217static int __devinit lnw_gpio_probe(struct pci_dev *pdev, 214static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
@@ -279,12 +276,12 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
279 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval); 276 dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
280 goto err5; 277 goto err5;
281 } 278 }
282 set_irq_data(pdev->irq, lnw); 279 irq_set_handler_data(pdev->irq, lnw);
283 set_irq_chained_handler(pdev->irq, lnw_irq_handler); 280 irq_set_chained_handler(pdev->irq, lnw_irq_handler);
284 for (i = 0; i < lnw->chip.ngpio; i++) { 281 for (i = 0; i < lnw->chip.ngpio; i++) {
285 set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip, 282 irq_set_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
286 handle_simple_irq, "demux"); 283 handle_simple_irq, "demux");
287 set_irq_chip_data(i + lnw->irq_base, lnw); 284 irq_set_chip_data(i + lnw->irq_base, lnw);
288 } 285 }
289 286
290 spin_lock_init(&lnw->lock); 287 spin_lock_init(&lnw->lock);