summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2011-09-28 16:50:58 +0900
committerPaul Mundt <lethal@linux-sh.org>2011-10-28 15:03:52 +0900
commitad2a8e7ea4128af984a98537b1b9484722b6b4bb (patch)
treecf5030dda233a9182e78574356d1853652753aad
parentcf8e56bf5b60dba5ba11db83ca7f1df884e568e5 (diff)
downloadop-kernel-dev-ad2a8e7ea4128af984a98537b1b9484722b6b4bb.zip
op-kernel-dev-ad2a8e7ea4128af984a98537b1b9484722b6b4bb.tar.gz
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>
-rw-r--r--drivers/sh/pfc.c27
-rw-r--r--include/linux/sh_pfc.h11
2 files changed, 38 insertions, 0 deletions
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;
};
OpenPOWER on IntegriCloud