Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 284803
b: refs/heads/master
c: 2de0dbc
h: refs/heads/master
i:
  284801: 141654a
  284799: f4d0467
v: v3
  • Loading branch information
Rob Herring committed Jan 5, 2012
1 parent eb8104f commit a09e9c4
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ab52475447641a6facf6ee5450bea24e477b811
refs/heads/master: 2de0dbc5f6830e7659083d1929f57cb88b16a3b6
44 changes: 8 additions & 36 deletions trunk/drivers/gpio/gpio-pl061.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
Expand Down Expand Up @@ -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);
}

Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit a09e9c4

Please sign in to comment.