diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-12-20 15:31:48 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-22 16:40:33 +0100 |
commit | 99bb1fbd6da2f3545c21f8148c679d52a543af18 (patch) | |
tree | 1f44d8c18635235b1248fcd65fed779bf92999a4 /arch/arm/mach-at91/gpio.c | |
parent | 521f3a53b32839078259addeb26c280c0a76e64c (diff) | |
download | barebox-99bb1fbd6da2f3545c21f8148c679d52a543af18.tar.gz barebox-99bb1fbd6da2f3545c21f8148c679d52a543af18.tar.xz |
at91: gpio: switch to device driver
this is the first step to prepare the switch to the gpiolib
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.c | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index cd0136fc13..acaf740cfc 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -19,28 +19,37 @@ #include <common.h> #include <linux/clk.h> +#include <linux/err.h> #include <errno.h> #include <io.h> #include <mach/gpio.h> #include <mach/io.h> #include <mach/cpu.h> #include <gpio.h> +#include <init.h> +#include <driver.h> + +#define AT91_PIO3 1 +#define MAX_GPIO_BANKS 5 static int gpio_banks; static int cpu_has_pio3; -static struct at91_gpio_bank *gpio; /* * Functionnality can change with newer chips */ +struct at91_gpio_chip { + void __iomem *regbase; /* PIO bank virtual address */ +}; +static struct at91_gpio_chip gpio_chip[MAX_GPIO_BANKS]; static inline void __iomem *pin_to_controller(unsigned pin) { pin /= 32; if (likely(pin < gpio_banks)) - return gpio[pin].regbase; + return gpio_chip[pin].regbase; return NULL; } @@ -350,19 +359,60 @@ EXPORT_SYMBOL(gpio_direction_output); /*--------------------------------------------------------------------------*/ -int at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) +static int at91_gpio_probe(struct device_d *dev) { - unsigned i; + struct at91_gpio_chip *at91_gpio = &gpio_chip[dev->id]; + struct clk *clk; + int ret; + + BUG_ON(dev->id > MAX_GPIO_BANKS); + + ret = dev_get_drvdata(dev, (unsigned long *)&cpu_has_pio3); + if (ret) { + dev_err(dev, "dev_get_drvdata failed: %d\n", ret); + return ret; + } - gpio = data; - gpio_banks = nr_banks; + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } - for (i = 0; i < nr_banks; i++, data++) { - /* enable PIO controller's clock */ - clk_enable(data->clock); + ret = clk_enable(clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(clk); + return ret; } - cpu_has_pio3 = cpu_is_at91sam9x5() || cpu_is_at91sam9n12(); + gpio_banks = max(gpio_banks, dev->id + 1); + at91_gpio->regbase = dev_request_mem_region(dev, 0); return 0; } + +static struct platform_device_id at91_gpio_ids[] = { + { + .name = "at91rm9200-gpio", + .driver_data = (unsigned long)0, + }, { + .name = "at91sam9x5-gpio", + .driver_data = (unsigned long)AT91_PIO3, + }, { + /* sentinel */ + }, +}; + +static struct driver_d at91_gpio_driver = { + .name = "at91-gpio", + .probe = at91_gpio_probe, + .id_table = at91_gpio_ids, +}; + +static int at91_gpio_init(void) +{ + return platform_driver_register(&at91_gpio_driver); +} +postcore_initcall(at91_gpio_init); |