| From 8baa9a6e15ed242d3900b8c0caff14f85a0d3f8a Mon Sep 17 00:00:00 2001 |
| From: Magnus Damm <damm@opensource.se> |
| Date: Wed, 28 Sep 2011 16:50:58 +0900 |
| Subject: sh: pfc: Add GPIO IRQ support |
| |
| Add GPIO IRQ support to the shared PFC code in drivers/sh/pfc.c |
| |
| The enums pointed out by a certain GPIO will be matched against |
| a table for IRQ to enum mappings. |
| |
| Only the shared PFC code is updated by this patch. SoC specific |
| changes are also needed to allow platforms to make use of this |
| feature. |
| |
| Signed-off-by: Magnus Damm <damm@opensource.se> |
| Signed-off-by: Paul Mundt <lethal@linux-sh.org> |
| (cherry picked from commit ad2a8e7ea4128af984a98537b1b9484722b6b4bb) |
| |
| Signed-off-by: Simon Horman <horms@verge.net.au> |
| --- |
| drivers/sh/pfc.c | 27 +++++++++++++++++++++++++++ |
| include/linux/sh_pfc.h | 11 +++++++++++ |
| 2 files changed, 38 insertions(+) |
| |
| diff --git a/drivers/sh/pfc.c b/drivers/sh/pfc.c |
| index de5e3d6..e67fe17 100644 |
| --- a/drivers/sh/pfc.c |
| +++ b/drivers/sh/pfc.c |
| @@ -577,6 +577,32 @@ static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| sh_gpio_set_value(chip_to_pinmux(chip), offset, value); |
| } |
| |
| +static int sh_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
| +{ |
| + struct pinmux_info *gpioc = chip_to_pinmux(chip); |
| + pinmux_enum_t enum_id; |
| + pinmux_enum_t *enum_ids; |
| + int i, k, pos; |
| + |
| + pos = 0; |
| + enum_id = 0; |
| + while (1) { |
| + pos = get_gpio_enum_id(gpioc, offset, pos, &enum_id); |
| + if (pos <= 0 || !enum_id) |
| + break; |
| + |
| + for (i = 0; i < gpioc->gpio_irq_size; i++) { |
| + enum_ids = gpioc->gpio_irq[i].enum_ids; |
| + for (k = 0; enum_ids[k]; k++) { |
| + if (enum_ids[k] == enum_id) |
| + return gpioc->gpio_irq[i].irq; |
| + } |
| + } |
| + } |
| + |
| + return -ENOSYS; |
| +} |
| + |
| int register_pinmux(struct pinmux_info *pip) |
| { |
| struct gpio_chip *chip = &pip->chip; |
| @@ -592,6 +618,7 @@ int register_pinmux(struct pinmux_info *pip) |
| chip->get = sh_gpio_get; |
| chip->direction_output = sh_gpio_direction_output; |
| chip->set = sh_gpio_set; |
| + chip->to_irq = sh_gpio_to_irq; |
| |
| WARN_ON(pip->first_gpio != 0); /* needs testing */ |
| |
| diff --git a/include/linux/sh_pfc.h b/include/linux/sh_pfc.h |
| index 12f3519..bc8c920 100644 |
| --- a/include/linux/sh_pfc.h |
| +++ b/include/linux/sh_pfc.h |
| @@ -61,6 +61,14 @@ struct pinmux_data_reg { |
| .reg = r, .reg_width = r_width, \ |
| .enum_ids = (pinmux_enum_t [r_width]) \ |
| |
| +struct pinmux_irq { |
| + int irq; |
| + pinmux_enum_t *enum_ids; |
| +}; |
| + |
| +#define PINMUX_IRQ(irq_nr, ids...) \ |
| + { .irq = irq_nr, .enum_ids = (pinmux_enum_t []) { ids, 0 } } \ |
| + |
| struct pinmux_range { |
| pinmux_enum_t begin; |
| pinmux_enum_t end; |
| @@ -87,6 +95,9 @@ struct pinmux_info { |
| pinmux_enum_t *gpio_data; |
| unsigned int gpio_data_size; |
| |
| + struct pinmux_irq *gpio_irq; |
| + unsigned int gpio_irq_size; |
| + |
| struct gpio_chip chip; |
| }; |
| |
| -- |
| 1.7.10 |
| |