From: Grant Likely Date: Wed, 6 Jul 2011 17:54:19 +0000 (-0600) Subject: gpio: Move mpc5200 gpio driver to drivers/gpio X-Git-Tag: firefly_0821_release~3680^2~5005^2~11 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=6eae1ace68ab775e9d47f1f8e40c811ac39f733f;p=firefly-linux-kernel-4.4.55.git gpio: Move mpc5200 gpio driver to drivers/gpio GPIO drivers are getting consolidated into drivers/gpio. While at it, change the driver name to mpc5200-gpio* to avoid collisions. Signed-off-by: Grant Likely --- diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig index 47ea1be1481b..90f4496017e4 100644 --- a/arch/powerpc/platforms/52xx/Kconfig +++ b/arch/powerpc/platforms/52xx/Kconfig @@ -55,14 +55,6 @@ config PPC_MPC5200_BUGFIX It is safe to say 'Y' here -config PPC_MPC5200_GPIO - bool "MPC5200 GPIO support" - depends on PPC_MPC52xx - select ARCH_REQUIRE_GPIOLIB - select GENERIC_GPIO - help - Enable gpiolib support for mpc5200 based boards - config PPC_MPC5200_LPBFIFO tristate "MPC5200 LocalPlus bus FIFO driver" depends on PPC_MPC52xx diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index 2bc8cd0c5cfc..4e62486791e9 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile @@ -14,5 +14,4 @@ ifeq ($(CONFIG_PPC_LITE5200),y) obj-$(CONFIG_PM) += lite5200_sleep.o lite5200_pm.o endif -obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o obj-$(CONFIG_PPC_MPC5200_LPBFIFO) += mpc52xx_lpbfifo.o diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c deleted file mode 100644 index 1757d1db4b51..000000000000 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * MPC52xx gpio driver - * - * Copyright (c) 2008 Sascha Hauer , Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static DEFINE_SPINLOCK(gpio_lock); - -struct mpc52xx_gpiochip { - struct of_mm_gpio_chip mmchip; - unsigned int shadow_dvo; - unsigned int shadow_gpioe; - unsigned int shadow_ddr; -}; - -/* - * GPIO LIB API implementation for wakeup GPIOs. - * - * There's a maximum of 8 wakeup GPIOs. Which of these are available - * for use depends on your board setup. - * - * 0 -> GPIO_WKUP_7 - * 1 -> GPIO_WKUP_6 - * 2 -> PSC6_1 - * 3 -> PSC6_0 - * 4 -> ETH_17 - * 5 -> PSC3_9 - * 6 -> PSC2_4 - * 7 -> PSC1_4 - * - */ -static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; - unsigned int ret; - - ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1; - - pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret); - - return ret; -} - -static inline void -__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; - - if (val) - chip->shadow_dvo |= 1 << (7 - gpio); - else - chip->shadow_dvo &= ~(1 << (7 - gpio)); - - out_8(®s->wkup_dvo, chip->shadow_dvo); -} - -static void -mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - __mpc52xx_wkup_gpio_set(gc, gpio, val); - - spin_unlock_irqrestore(&gpio_lock, flags); - - pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); -} - -static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - /* set the direction */ - chip->shadow_ddr &= ~(1 << (7 - gpio)); - out_8(®s->wkup_ddr, chip->shadow_ddr); - - /* and enable the pin */ - chip->shadow_gpioe |= 1 << (7 - gpio); - out_8(®s->wkup_gpioe, chip->shadow_gpioe); - - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -} - -static int -mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - __mpc52xx_wkup_gpio_set(gc, gpio, val); - - /* Then set direction */ - chip->shadow_ddr |= 1 << (7 - gpio); - out_8(®s->wkup_ddr, chip->shadow_ddr); - - /* Finally enable the pin */ - chip->shadow_gpioe |= 1 << (7 - gpio); - out_8(®s->wkup_gpioe, chip->shadow_gpioe); - - spin_unlock_irqrestore(&gpio_lock, flags); - - pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); - - return 0; -} - -static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) -{ - struct mpc52xx_gpiochip *chip; - struct mpc52xx_gpio_wkup __iomem *regs; - struct gpio_chip *gc; - int ret; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - gc = &chip->mmchip.gc; - - gc->ngpio = 8; - gc->direction_input = mpc52xx_wkup_gpio_dir_in; - gc->direction_output = mpc52xx_wkup_gpio_dir_out; - gc->get = mpc52xx_wkup_gpio_get; - gc->set = mpc52xx_wkup_gpio_set; - - ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); - if (ret) - return ret; - - regs = chip->mmchip.regs; - chip->shadow_gpioe = in_8(®s->wkup_gpioe); - chip->shadow_ddr = in_8(®s->wkup_ddr); - chip->shadow_dvo = in_8(®s->wkup_dvo); - - return 0; -} - -static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) -{ - return -EBUSY; -} - -static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { - { - .compatible = "fsl,mpc5200-gpio-wkup", - }, - {} -}; - -static struct platform_driver mpc52xx_wkup_gpiochip_driver = { - .driver = { - .name = "gpio_wkup", - .owner = THIS_MODULE, - .of_match_table = mpc52xx_wkup_gpiochip_match, - }, - .probe = mpc52xx_wkup_gpiochip_probe, - .remove = mpc52xx_gpiochip_remove, -}; - -/* - * GPIO LIB API implementation for simple GPIOs - * - * There's a maximum of 32 simple GPIOs. Which of these are available - * for use depends on your board setup. - * The numbering reflects the bit numbering in the port registers: - * - * 0..1 > reserved - * 2..3 > IRDA - * 4..7 > ETHR - * 8..11 > reserved - * 12..15 > USB - * 16..17 > reserved - * 18..23 > PSC3 - * 24..27 > PSC2 - * 28..31 > PSC1 - */ -static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; - unsigned int ret; - - ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1; - - return ret; -} - -static inline void -__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; - - if (val) - chip->shadow_dvo |= 1 << (31 - gpio); - else - chip->shadow_dvo &= ~(1 << (31 - gpio)); - out_be32(®s->simple_dvo, chip->shadow_dvo); -} - -static void -mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) -{ - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - __mpc52xx_simple_gpio_set(gc, gpio, val); - - spin_unlock_irqrestore(&gpio_lock, flags); - - pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); -} - -static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - /* set the direction */ - chip->shadow_ddr &= ~(1 << (31 - gpio)); - out_be32(®s->simple_ddr, chip->shadow_ddr); - - /* and enable the pin */ - chip->shadow_gpioe |= 1 << (31 - gpio); - out_be32(®s->simple_gpioe, chip->shadow_gpioe); - - spin_unlock_irqrestore(&gpio_lock, flags); - - return 0; -} - -static int -mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpiochip *chip = container_of(mm_gc, - struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - - /* First set initial value */ - __mpc52xx_simple_gpio_set(gc, gpio, val); - - /* Then set direction */ - chip->shadow_ddr |= 1 << (31 - gpio); - out_be32(®s->simple_ddr, chip->shadow_ddr); - - /* Finally enable the pin */ - chip->shadow_gpioe |= 1 << (31 - gpio); - out_be32(®s->simple_gpioe, chip->shadow_gpioe); - - spin_unlock_irqrestore(&gpio_lock, flags); - - pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); - - return 0; -} - -static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) -{ - struct mpc52xx_gpiochip *chip; - struct gpio_chip *gc; - struct mpc52xx_gpio __iomem *regs; - int ret; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - gc = &chip->mmchip.gc; - - gc->ngpio = 32; - gc->direction_input = mpc52xx_simple_gpio_dir_in; - gc->direction_output = mpc52xx_simple_gpio_dir_out; - gc->get = mpc52xx_simple_gpio_get; - gc->set = mpc52xx_simple_gpio_set; - - ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); - if (ret) - return ret; - - regs = chip->mmchip.regs; - chip->shadow_gpioe = in_be32(®s->simple_gpioe); - chip->shadow_ddr = in_be32(®s->simple_ddr); - chip->shadow_dvo = in_be32(®s->simple_dvo); - - return 0; -} - -static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { - { - .compatible = "fsl,mpc5200-gpio", - }, - {} -}; - -static struct platform_driver mpc52xx_simple_gpiochip_driver = { - .driver = { - .name = "gpio", - .owner = THIS_MODULE, - .of_match_table = mpc52xx_simple_gpiochip_match, - }, - .probe = mpc52xx_simple_gpiochip_probe, - .remove = mpc52xx_gpiochip_remove, -}; - -static int __init mpc52xx_gpio_init(void) -{ - if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver)) - printk(KERN_ERR "Unable to register wakeup GPIO driver\n"); - - if (platform_driver_register(&mpc52xx_simple_gpiochip_driver)) - printk(KERN_ERR "Unable to register simple GPIO driver\n"); - - return 0; -} - - -/* Make sure we get initialised before anyone else tries to use us */ -subsys_initcall(mpc52xx_gpio_init); - -/* No exit call at the moment as we cannot unregister of gpio chips */ - -MODULE_DESCRIPTION("Freescale MPC52xx gpio driver"); -MODULE_AUTHOR("Sascha Hauer , Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static DEFINE_SPINLOCK(gpio_lock); + +struct mpc52xx_gpiochip { + struct of_mm_gpio_chip mmchip; + unsigned int shadow_dvo; + unsigned int shadow_gpioe; + unsigned int shadow_ddr; +}; + +/* + * GPIO LIB API implementation for wakeup GPIOs. + * + * There's a maximum of 8 wakeup GPIOs. Which of these are available + * for use depends on your board setup. + * + * 0 -> GPIO_WKUP_7 + * 1 -> GPIO_WKUP_6 + * 2 -> PSC6_1 + * 3 -> PSC6_0 + * 4 -> ETH_17 + * 5 -> PSC3_9 + * 6 -> PSC2_4 + * 7 -> PSC1_4 + * + */ +static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + unsigned int ret; + + ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1; + + pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret); + + return ret; +} + +static inline void +__mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + + if (val) + chip->shadow_dvo |= 1 << (7 - gpio); + else + chip->shadow_dvo &= ~(1 << (7 - gpio)); + + out_8(®s->wkup_dvo, chip->shadow_dvo); +} + +static void +mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + __mpc52xx_wkup_gpio_set(gc, gpio, val); + + spin_unlock_irqrestore(&gpio_lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); +} + +static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + /* set the direction */ + chip->shadow_ddr &= ~(1 << (7 - gpio)); + out_8(®s->wkup_ddr, chip->shadow_ddr); + + /* and enable the pin */ + chip->shadow_gpioe |= 1 << (7 - gpio); + out_8(®s->wkup_gpioe, chip->shadow_gpioe); + + spin_unlock_irqrestore(&gpio_lock, flags); + + return 0; +} + +static int +mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + __mpc52xx_wkup_gpio_set(gc, gpio, val); + + /* Then set direction */ + chip->shadow_ddr |= 1 << (7 - gpio); + out_8(®s->wkup_ddr, chip->shadow_ddr); + + /* Finally enable the pin */ + chip->shadow_gpioe |= 1 << (7 - gpio); + out_8(®s->wkup_gpioe, chip->shadow_gpioe); + + spin_unlock_irqrestore(&gpio_lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int __devinit mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) +{ + struct mpc52xx_gpiochip *chip; + struct mpc52xx_gpio_wkup __iomem *regs; + struct gpio_chip *gc; + int ret; + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + gc = &chip->mmchip.gc; + + gc->ngpio = 8; + gc->direction_input = mpc52xx_wkup_gpio_dir_in; + gc->direction_output = mpc52xx_wkup_gpio_dir_out; + gc->get = mpc52xx_wkup_gpio_get; + gc->set = mpc52xx_wkup_gpio_set; + + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); + if (ret) + return ret; + + regs = chip->mmchip.regs; + chip->shadow_gpioe = in_8(®s->wkup_gpioe); + chip->shadow_ddr = in_8(®s->wkup_ddr); + chip->shadow_dvo = in_8(®s->wkup_dvo); + + return 0; +} + +static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) +{ + return -EBUSY; +} + +static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { + { .compatible = "fsl,mpc5200-gpio-wkup", }, + {} +}; + +static struct platform_driver mpc52xx_wkup_gpiochip_driver = { + .driver = { + .name = "mpc5200-gpio-wkup", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_wkup_gpiochip_match, + }, + .probe = mpc52xx_wkup_gpiochip_probe, + .remove = mpc52xx_gpiochip_remove, +}; + +/* + * GPIO LIB API implementation for simple GPIOs + * + * There's a maximum of 32 simple GPIOs. Which of these are available + * for use depends on your board setup. + * The numbering reflects the bit numbering in the port registers: + * + * 0..1 > reserved + * 2..3 > IRDA + * 4..7 > ETHR + * 8..11 > reserved + * 12..15 > USB + * 16..17 > reserved + * 18..23 > PSC3 + * 24..27 > PSC2 + * 28..31 > PSC1 + */ +static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + unsigned int ret; + + ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1; + + return ret; +} + +static inline void +__mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + + if (val) + chip->shadow_dvo |= 1 << (31 - gpio); + else + chip->shadow_dvo &= ~(1 << (31 - gpio)); + out_be32(®s->simple_dvo, chip->shadow_dvo); +} + +static void +mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + __mpc52xx_simple_gpio_set(gc, gpio, val); + + spin_unlock_irqrestore(&gpio_lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); +} + +static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + /* set the direction */ + chip->shadow_ddr &= ~(1 << (31 - gpio)); + out_be32(®s->simple_ddr, chip->shadow_ddr); + + /* and enable the pin */ + chip->shadow_gpioe |= 1 << (31 - gpio); + out_be32(®s->simple_gpioe, chip->shadow_gpioe); + + spin_unlock_irqrestore(&gpio_lock, flags); + + return 0; +} + +static int +mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct mpc52xx_gpiochip *chip = container_of(mm_gc, + struct mpc52xx_gpiochip, mmchip); + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + /* First set initial value */ + __mpc52xx_simple_gpio_set(gc, gpio, val); + + /* Then set direction */ + chip->shadow_ddr |= 1 << (31 - gpio); + out_be32(®s->simple_ddr, chip->shadow_ddr); + + /* Finally enable the pin */ + chip->shadow_gpioe |= 1 << (31 - gpio); + out_be32(®s->simple_gpioe, chip->shadow_gpioe); + + spin_unlock_irqrestore(&gpio_lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int __devinit mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) +{ + struct mpc52xx_gpiochip *chip; + struct gpio_chip *gc; + struct mpc52xx_gpio __iomem *regs; + int ret; + + chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + gc = &chip->mmchip.gc; + + gc->ngpio = 32; + gc->direction_input = mpc52xx_simple_gpio_dir_in; + gc->direction_output = mpc52xx_simple_gpio_dir_out; + gc->get = mpc52xx_simple_gpio_get; + gc->set = mpc52xx_simple_gpio_set; + + ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); + if (ret) + return ret; + + regs = chip->mmchip.regs; + chip->shadow_gpioe = in_be32(®s->simple_gpioe); + chip->shadow_ddr = in_be32(®s->simple_ddr); + chip->shadow_dvo = in_be32(®s->simple_dvo); + + return 0; +} + +static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { + { .compatible = "fsl,mpc5200-gpio", }, + {} +}; + +static struct platform_driver mpc52xx_simple_gpiochip_driver = { + .driver = { + .name = "mpc5200-gpio", + .owner = THIS_MODULE, + .of_match_table = mpc52xx_simple_gpiochip_match, + }, + .probe = mpc52xx_simple_gpiochip_probe, + .remove = mpc52xx_gpiochip_remove, +}; + +static int __init mpc52xx_gpio_init(void) +{ + if (platform_driver_register(&mpc52xx_wkup_gpiochip_driver)) + printk(KERN_ERR "Unable to register wakeup GPIO driver\n"); + + if (platform_driver_register(&mpc52xx_simple_gpiochip_driver)) + printk(KERN_ERR "Unable to register simple GPIO driver\n"); + + return 0; +} + + +/* Make sure we get initialised before anyone else tries to use us */ +subsys_initcall(mpc52xx_gpio_init); + +/* No exit call at the moment as we cannot unregister of gpio chips */ + +MODULE_DESCRIPTION("Freescale MPC52xx gpio driver"); +MODULE_AUTHOR("Sascha Hauer