summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-at91/gpio.c
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-12-20 15:31:49 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-12-22 16:40:33 +0100
commiteb5eb6c147f9d4598b3d1e6546417d20c6905841 (patch)
tree8cdd5f4597c181252d6f00c6bc7ce7c464a7c08e /arch/arm/mach-at91/gpio.c
parent99bb1fbd6da2f3545c21f8148c679d52a543af18 (diff)
downloadbarebox-eb5eb6c147f9d4598b3d1e6546417d20c6905841.tar.gz
barebox-eb5eb6c147f9d4598b3d1e6546417d20c6905841.tar.xz
at91: gpio: switch to ops
imported from the kernel this allow to simplify the mux implemtation and will simplify the gpio support from bare_init or pbl Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-at91/gpio.c')
-rw-r--r--arch/arm/mach-at91/gpio.c388
1 files changed, 251 insertions, 137 deletions
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index acaf740cfc..5962b2a363 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -1,6 +1,6 @@
/*
- *
- * (c) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright (C) 2005 HP Labs
+ * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -29,144 +29,248 @@
#include <init.h>
#include <driver.h>
-#define AT91_PIO3 1
-#define MAX_GPIO_BANKS 5
+#define MAX_GPIO_BANKS 5
+#define MAX_NB_GPIO_PER_BANK 32
-static int gpio_banks;
-static int cpu_has_pio3;
+static int gpio_banks = 0;
/*
* Functionnality can change with newer chips
*/
-
struct at91_gpio_chip {
+ struct device_d *dev;
void __iomem *regbase; /* PIO bank virtual address */
+ struct at91_pinctrl_mux_ops *ops; /* ops */
};
static struct at91_gpio_chip gpio_chip[MAX_GPIO_BANKS];
-static inline void __iomem *pin_to_controller(unsigned pin)
+static inline unsigned pin_to_bank(unsigned pin)
+{
+ return pin / MAX_NB_GPIO_PER_BANK;
+}
+
+static inline unsigned pin_to_bank_offset(unsigned pin)
{
- pin /= 32;
+ return pin % MAX_NB_GPIO_PER_BANK;
+}
+
+static inline struct at91_gpio_chip *pin_to_controller(unsigned pin)
+{
+ pin /= MAX_NB_GPIO_PER_BANK;
if (likely(pin < gpio_banks))
- return gpio_chip[pin].regbase;
+ return &gpio_chip[pin];
return NULL;
}
static inline unsigned pin_to_mask(unsigned pin)
{
- return 1 << (pin % 32);
+ return 1 << pin_to_bank_offset(pin);
}
-/*
- * mux the pin to the "GPIO" peripheral role.
+/**
+ * struct at91_pinctrl_mux_ops - describes an At91 mux ops group
+ * on new IP with support for periph C and D the way to mux in
+ * periph A and B has changed
+ * So provide the right call back
+ * if not present means the IP does not support it
+ * @mux_A_periph: mux as periph A
+ * @mux_B_periph: mux as periph B
+ * @mux_C_periph: mux as periph C
+ * @mux_D_periph: mux as periph D
+ * @set_deglitch: enable/disable deglitch
+ * @set_debounce: enable/disable debounce
+ * @set_pulldown: enable/disable pulldown
+ * @disable_schmitt_trig: disable schmitt trigger
*/
-int at91_set_GPIO_periph(unsigned pin, int use_pullup)
-{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+struct at91_pinctrl_mux_ops {
+ void (*mux_A_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_B_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_C_periph)(void __iomem *pio, unsigned mask);
+ void (*mux_D_periph)(void __iomem *pio, unsigned mask);
+ void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on);
+ void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div);
+ void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on);
+ void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
+};
- if (!pio)
- return -EINVAL;
+static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
+{
__raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- __raw_writel(mask, pio + PIO_PER);
- return 0;
}
-EXPORT_SYMBOL(at91_set_GPIO_periph);
-/*
- * mux the pin to the "A" internal peripheral role.
- */
-int at91_set_A_periph(unsigned pin, int use_pullup)
+static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ __raw_writel(mask, pio + (on ? PIO_PUER : PIO_PUDR));
+}
- if (!pio)
- return -EINVAL;
+static void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on)
+{
+ __raw_writel(mask, pio + (on ? PIO_MDER : PIO_MDDR));
+}
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- if (cpu_has_pio3) {
- __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask,
- pio + PIO_ABCDSR1);
- __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
- pio + PIO_ABCDSR2);
- } else {
- __raw_writel(mask, pio + PIO_ASR);
- }
- __raw_writel(mask, pio + PIO_PDR);
- return 0;
+static void at91_mux_set_A_periph(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(mask, pio + PIO_ASR);
}
-EXPORT_SYMBOL(at91_set_A_periph);
-/*
- * mux the pin to the "B" internal peripheral role.
- */
-int at91_set_B_periph(unsigned pin, int use_pullup)
+static void at91_mux_set_B_periph(void __iomem *pio, unsigned mask)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ __raw_writel(mask, pio + PIO_BSR);
+}
- if (!pio)
- return -EINVAL;
+static void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask)
+{
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- if (cpu_has_pio3) {
- __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask,
- pio + PIO_ABCDSR1);
- __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
- pio + PIO_ABCDSR2);
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask,
+ pio + PIO_ABCDSR1);
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
+ pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask,
+ pio + PIO_ABCDSR1);
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR2) & ~mask,
+ pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1);
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
+ __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+}
+
+static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
+{
+ __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
+}
+
+static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on)
+{
+ if (is_on)
+ __raw_writel(mask, pio + PIO_IFSCDR);
+ at91_mux_set_deglitch(pio, mask, is_on);
+}
+
+static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
+ bool is_on, u32 div)
+{
+ if (is_on) {
+ __raw_writel(mask, pio + PIO_IFSCER);
+ __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
+ __raw_writel(mask, pio + PIO_IFER);
} else {
- __raw_writel(mask, pio + PIO_BSR);
+ __raw_writel(mask, pio + PIO_IFDR);
}
- __raw_writel(mask, pio + PIO_PDR);
- return 0;
}
-EXPORT_SYMBOL(at91_set_B_periph);
-/*
- * mux the pin to the "C" internal peripheral role.
- */
-int at91_set_C_periph(unsigned pin, int use_pullup)
+static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
+}
- if (!pio || !cpu_has_pio3)
- return -EINVAL;
+static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask)
+{
+ __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
+}
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- __raw_writel(__raw_readl(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1);
- __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
+static struct at91_pinctrl_mux_ops at91rm9200_ops = {
+ .mux_A_periph = at91_mux_set_A_periph,
+ .mux_B_periph = at91_mux_set_B_periph,
+ .set_deglitch = at91_mux_set_deglitch,
+};
+
+static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
+ .mux_A_periph = at91_mux_pio3_set_A_periph,
+ .mux_B_periph = at91_mux_pio3_set_B_periph,
+ .mux_C_periph = at91_mux_pio3_set_C_periph,
+ .mux_D_periph = at91_mux_pio3_set_D_periph,
+ .set_deglitch = at91_mux_pio3_set_deglitch,
+ .set_debounce = at91_mux_pio3_set_debounce,
+ .set_pulldown = at91_mux_pio3_set_pulldown,
+ .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig,
+};
+
+static void at91_mux_gpio_disable(void __iomem *pio, unsigned mask)
+{
__raw_writel(mask, pio + PIO_PDR);
- return 0;
}
-EXPORT_SYMBOL(at91_set_C_periph);
-/*
- * mux the pin to the "C" internal peripheral role.
- */
-int at91_set_D_periph(unsigned pin, int use_pullup)
+static void at91_mux_gpio_enable(void __iomem *pio, unsigned mask)
{
- void __iomem *pio = pin_to_controller(pin);
- unsigned mask = pin_to_mask(pin);
+ __raw_writel(mask, pio + PIO_PER);
+}
- if (!pio || !cpu_has_pio3)
+static void at91_mux_gpio_input(void __iomem *pio, unsigned mask, bool input)
+{
+ __raw_writel(mask, pio + (input ? PIO_ODR : PIO_OER));
+}
+
+int at91_mux_pin(unsigned pin, enum at91_mux mux, int use_pullup)
+{
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = pin_to_mask(pin);
+ int bank = pin_to_bank(pin);
+ struct device_d *dev = at91_gpio->dev;
+
+ if (!at91_gpio)
return -EINVAL;
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- __raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
- __raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
- __raw_writel(mask, pio + PIO_PDR);
+ pio = at91_gpio->regbase;
+ if (!pio)
+ return -EINVAL;
+
+ at91_mux_disable_interrupt(pio, mask);
+
+ pin %= MAX_NB_GPIO_PER_BANK;
+ if (mux) {
+ dev_dbg(dev, "pio%c%d configured as periph%c with pullup = %d\n",
+ bank + 'A', pin, mux - 1 + 'A', use_pullup);
+ } else {
+ dev_dbg(dev, "pio%c%d configured as gpio with pullup = %d\n",
+ bank + 'A', pin, use_pullup);
+ }
+
+ switch(mux) {
+ case AT91_MUX_GPIO:
+ at91_mux_gpio_enable(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_A:
+ at91_gpio->ops->mux_A_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_B:
+ at91_gpio->ops->mux_B_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_C:
+ if (!at91_gpio->ops->mux_C_periph)
+ return -EINVAL;
+ at91_gpio->ops->mux_C_periph(pio, mask);
+ break;
+ case AT91_MUX_PERIPH_D:
+ if (!at91_gpio->ops->mux_D_periph)
+ return -EINVAL;
+ at91_gpio->ops->mux_D_periph(pio, mask);
+ break;
+ }
+ if (mux)
+ at91_mux_gpio_disable(pio, mask);
+
+ if (use_pullup >= 0)
+ at91_mux_set_pullup(pio, mask, use_pullup);
+
return 0;
}
-EXPORT_SYMBOL(at91_set_D_periph);
+EXPORT_SYMBOL(at91_mux_pin);
/*
* mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
@@ -174,19 +278,22 @@ EXPORT_SYMBOL(at91_set_D_periph);
*/
int at91_set_gpio_input(unsigned pin, int use_pullup)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
+ int ret;
- if (!pio)
- return -EINVAL;
+ ret = at91_mux_pin(pin, AT91_MUX_GPIO, use_pullup);
+ if (ret)
+ return ret;
+
+ dev_dbg(at91_gpio->dev, "pio%c%d configured as input\n",
+ pin_to_bank(pin) + 'A', pin_to_bank_offset(pin));
+
+ at91_mux_gpio_input(pio, mask, true);
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
- __raw_writel(mask, pio + PIO_ODR);
- __raw_writel(mask, pio + PIO_PER);
return 0;
}
-EXPORT_SYMBOL(at91_set_gpio_input);
/*
* mux the pin to the gpio controller (instead of "A" or "B" peripheral),
@@ -194,17 +301,20 @@ EXPORT_SYMBOL(at91_set_gpio_input);
*/
int at91_set_gpio_output(unsigned pin, int value)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
+ int ret;
- if (!pio)
- return -EINVAL;
+ ret = at91_mux_pin(pin, AT91_MUX_GPIO, -1);
+ if (ret)
+ return ret;
- __raw_writel(mask, pio + PIO_IDR);
- __raw_writel(mask, pio + PIO_PUDR);
+ dev_dbg(at91_gpio->dev, "pio%c%d configured as output val = %d\n",
+ pin_to_bank(pin) + 'A', pin_to_bank_offset(pin), value);
+
+ at91_mux_gpio_input(pio, mask, false);
__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
- __raw_writel(mask, pio + PIO_OER);
- __raw_writel(mask, pio + PIO_PER);
return 0;
}
EXPORT_SYMBOL(at91_set_gpio_output);
@@ -214,15 +324,14 @@ EXPORT_SYMBOL(at91_set_gpio_output);
*/
int at91_set_deglitch(unsigned pin, int is_on)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
if (!pio)
return -EINVAL;
- if (cpu_has_pio3 && is_on)
- __raw_writel(mask, pio + PIO_IFSCDR);
- __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
+ at91_gpio->ops->set_deglitch(pio, mask, is_on);
return 0;
}
EXPORT_SYMBOL(at91_set_deglitch);
@@ -232,19 +341,14 @@ EXPORT_SYMBOL(at91_set_deglitch);
*/
int at91_set_debounce(unsigned pin, int is_on, int div)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
- if (!pio || !cpu_has_pio3)
+ if (!pio || !at91_gpio->ops->set_debounce)
return -EINVAL;
- if (is_on) {
- __raw_writel(mask, pio + PIO_IFSCER);
- __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
- __raw_writel(mask, pio + PIO_IFER);
- } else {
- __raw_writel(mask, pio + PIO_IFDR);
- }
+ at91_gpio->ops->set_debounce(pio, mask, is_on, div);
return 0;
}
EXPORT_SYMBOL(at91_set_debounce);
@@ -255,13 +359,14 @@ EXPORT_SYMBOL(at91_set_debounce);
*/
int at91_set_multi_drive(unsigned pin, int is_on)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
if (!pio)
return -EINVAL;
- __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR));
+ at91_mux_set_multidrive(pio, mask, is_on);
return 0;
}
EXPORT_SYMBOL(at91_set_multi_drive);
@@ -272,15 +377,16 @@ EXPORT_SYMBOL(at91_set_multi_drive);
*/
int at91_set_pulldown(unsigned pin, int is_on)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
- if (!pio || !cpu_has_pio3)
+ if (!pio || !at91_gpio->ops->set_pulldown)
return -EINVAL;
/* Disable pull-up anyway */
- __raw_writel(mask, pio + PIO_PUDR);
- __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
+ at91_mux_set_pullup(pio, mask, 0);
+ at91_gpio->ops->set_pulldown(pio, mask, is_on);
return 0;
}
EXPORT_SYMBOL(at91_set_pulldown);
@@ -290,13 +396,14 @@ EXPORT_SYMBOL(at91_set_pulldown);
*/
int at91_disable_schmitt_trig(unsigned pin)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
- if (!pio || !cpu_has_pio3)
+ if (!pio || !at91_gpio->ops->disable_schmitt_trig)
return -EINVAL;
- __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
+ at91_gpio->ops->disable_schmitt_trig(pio, mask);
return 0;
}
EXPORT_SYMBOL(at91_disable_schmitt_trig);
@@ -306,7 +413,8 @@ EXPORT_SYMBOL(at91_disable_schmitt_trig);
*/
int at91_set_gpio_value(unsigned pin, int value)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
if (!pio)
@@ -321,7 +429,8 @@ EXPORT_SYMBOL(at91_set_gpio_value);
*/
int at91_get_gpio_value(unsigned pin)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
u32 pdsr;
@@ -334,25 +443,27 @@ EXPORT_SYMBOL(at91_get_gpio_value);
int gpio_direction_input(unsigned pin)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
return -EINVAL;
- __raw_writel(mask, pio + PIO_ODR);
+ at91_mux_gpio_input(pio, mask, true);
return 0;
}
EXPORT_SYMBOL(gpio_direction_input);
int gpio_direction_output(unsigned pin, int value)
{
- void __iomem *pio = pin_to_controller(pin);
+ struct at91_gpio_chip *at91_gpio = pin_to_controller(pin);
+ void __iomem *pio = at91_gpio->regbase;
unsigned mask = pin_to_mask(pin);
if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
return -EINVAL;
__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
- __raw_writel(mask, pio + PIO_OER);
+ at91_mux_gpio_input(pio, mask, false);
return 0;
}
EXPORT_SYMBOL(gpio_direction_output);
@@ -361,13 +472,15 @@ EXPORT_SYMBOL(gpio_direction_output);
static int at91_gpio_probe(struct device_d *dev)
{
- struct at91_gpio_chip *at91_gpio = &gpio_chip[dev->id];
+ struct at91_gpio_chip *at91_gpio;
struct clk *clk;
int ret;
BUG_ON(dev->id > MAX_GPIO_BANKS);
- ret = dev_get_drvdata(dev, (unsigned long *)&cpu_has_pio3);
+ at91_gpio = &gpio_chip[dev->id];
+
+ ret = dev_get_drvdata(dev, (unsigned long *)&at91_gpio->ops);
if (ret) {
dev_err(dev, "dev_get_drvdata failed: %d\n", ret);
return ret;
@@ -387,6 +500,7 @@ static int at91_gpio_probe(struct device_d *dev)
return ret;
}
+ at91_gpio->dev = dev;
gpio_banks = max(gpio_banks, dev->id + 1);
at91_gpio->regbase = dev_request_mem_region(dev, 0);
@@ -396,10 +510,10 @@ static int at91_gpio_probe(struct device_d *dev)
static struct platform_device_id at91_gpio_ids[] = {
{
.name = "at91rm9200-gpio",
- .driver_data = (unsigned long)0,
+ .driver_data = (unsigned long)&at91rm9200_ops,
}, {
.name = "at91sam9x5-gpio",
- .driver_data = (unsigned long)AT91_PIO3,
+ .driver_data = (unsigned long)&at91sam9x5_ops,
}, {
/* sentinel */
},