|
@@ -12,7 +12,6 @@
|
|
|
#include <linux/spinlock.h>
|
|
|
#include <linux/errno.h>
|
|
|
#include <linux/module.h>
|
|
|
-#include <linux/list.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/ioport.h>
|
|
|
#include <linux/irq.h>
|
|
@@ -37,13 +36,6 @@
|
|
|
#define PL061_GPIO_NR 8
|
|
|
|
|
|
struct pl061_gpio {
|
|
|
- /* We use a list of pl061_gpio structs for each trigger IRQ in the main
|
|
|
- * interrupts controller of the system. We need this to support systems
|
|
|
- * in which more that one PL061s are connected to the same IRQ. The ISR
|
|
|
- * interates through this list to find the source of the interrupt.
|
|
|
- */
|
|
|
- struct list_head list;
|
|
|
-
|
|
|
/* Each of the two spinlocks protects a different set of hardware
|
|
|
* regiters and data structurs. This decouples the code of the IRQ from
|
|
|
* the GPIO code. This also makes the case of a GPIO routine call from
|
|
@@ -172,26 +164,20 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
|
|
|
|
|
|
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
|
|
|
{
|
|
|
- struct list_head *chip_list = irq_get_handler_data(irq);
|
|
|
- struct list_head *ptr;
|
|
|
- struct pl061_gpio *chip;
|
|
|
+ unsigned long pending;
|
|
|
+ int offset;
|
|
|
+ struct pl061_gpio *chip = irq_desc_get_handler_data(desc);
|
|
|
struct irq_chip *irqchip = irq_desc_get_chip(desc);
|
|
|
|
|
|
chained_irq_enter(irqchip, desc);
|
|
|
- list_for_each(ptr, chip_list) {
|
|
|
- unsigned long pending;
|
|
|
- int offset;
|
|
|
-
|
|
|
- chip = list_entry(ptr, struct pl061_gpio, list);
|
|
|
- pending = readb(chip->base + GPIOMIS);
|
|
|
- writeb(pending, chip->base + GPIOIC);
|
|
|
-
|
|
|
- if (pending == 0)
|
|
|
- continue;
|
|
|
|
|
|
+ pending = readb(chip->base + GPIOMIS);
|
|
|
+ writeb(pending, chip->base + GPIOIC);
|
|
|
+ if (pending) {
|
|
|
for_each_set_bit(offset, &pending, PL061_GPIO_NR)
|
|
|
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
|
|
|
}
|
|
|
+
|
|
|
chained_irq_exit(irqchip, desc);
|
|
|
}
|
|
|
|
|
@@ -218,9 +204,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
|
|
|
{
|
|
|
struct pl061_platform_data *pdata;
|
|
|
struct pl061_gpio *chip;
|
|
|
- struct list_head *chip_list;
|
|
|
int ret, irq, i;
|
|
|
- static DECLARE_BITMAP(init_irq, NR_IRQS);
|
|
|
|
|
|
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
|
|
if (chip == NULL)
|
|
@@ -251,7 +235,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
|
|
|
}
|
|
|
|
|
|
spin_lock_init(&chip->lock);
|
|
|
- INIT_LIST_HEAD(&chip->list);
|
|
|
|
|
|
chip->gc.direction_input = pl061_direction_input;
|
|
|
chip->gc.direction_output = pl061_direction_output;
|
|
@@ -283,18 +266,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
|
|
|
goto iounmap;
|
|
|
}
|
|
|
irq_set_chained_handler(irq, pl061_irq_handler);
|
|
|
- if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */
|
|
|
- chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL);
|
|
|
- if (chip_list == NULL) {
|
|
|
- clear_bit(irq, init_irq);
|
|
|
- ret = -ENOMEM;
|
|
|
- goto iounmap;
|
|
|
- }
|
|
|
- INIT_LIST_HEAD(chip_list);
|
|
|
- irq_set_handler_data(irq, chip_list);
|
|
|
- } else
|
|
|
- chip_list = irq_get_handler_data(irq);
|
|
|
- list_add(&chip->list, chip_list);
|
|
|
+ irq_set_handler_data(irq, chip);
|
|
|
|
|
|
for (i = 0; i < PL061_GPIO_NR; i++) {
|
|
|
if (pdata) {
|