16eae1aceSGrant Likely /* 26eae1aceSGrant Likely * MPC52xx gpio driver 36eae1aceSGrant Likely * 46eae1aceSGrant Likely * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 56eae1aceSGrant Likely * 66eae1aceSGrant Likely * This program is free software; you can redistribute it and/or modify 76eae1aceSGrant Likely * it under the terms of the GNU General Public License version 2 86eae1aceSGrant Likely * as published by the Free Software Foundation. 96eae1aceSGrant Likely * 106eae1aceSGrant Likely * This program is distributed in the hope that it will be useful, 116eae1aceSGrant Likely * but WITHOUT ANY WARRANTY; without even the implied warranty of 126eae1aceSGrant Likely * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 136eae1aceSGrant Likely * GNU General Public License for more details. 146eae1aceSGrant Likely * 156eae1aceSGrant Likely * You should have received a copy of the GNU General Public License 166eae1aceSGrant Likely * along with this program; if not, write to the Free Software 176eae1aceSGrant Likely * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 186eae1aceSGrant Likely */ 196eae1aceSGrant Likely 206eae1aceSGrant Likely #include <linux/of.h> 216eae1aceSGrant Likely #include <linux/kernel.h> 226eae1aceSGrant Likely #include <linux/slab.h> 236eae1aceSGrant Likely #include <linux/of_gpio.h> 246eae1aceSGrant Likely #include <linux/io.h> 256eae1aceSGrant Likely #include <linux/of_platform.h> 26bb207ef1SPaul Gortmaker #include <linux/module.h> 276eae1aceSGrant Likely 286eae1aceSGrant Likely #include <asm/gpio.h> 296eae1aceSGrant Likely #include <asm/mpc52xx.h> 306eae1aceSGrant Likely #include <sysdev/fsl_soc.h> 316eae1aceSGrant Likely 326eae1aceSGrant Likely static DEFINE_SPINLOCK(gpio_lock); 336eae1aceSGrant Likely 346eae1aceSGrant Likely struct mpc52xx_gpiochip { 356eae1aceSGrant Likely struct of_mm_gpio_chip mmchip; 366eae1aceSGrant Likely unsigned int shadow_dvo; 376eae1aceSGrant Likely unsigned int shadow_gpioe; 386eae1aceSGrant Likely unsigned int shadow_ddr; 396eae1aceSGrant Likely }; 406eae1aceSGrant Likely 416eae1aceSGrant Likely /* 426eae1aceSGrant Likely * GPIO LIB API implementation for wakeup GPIOs. 436eae1aceSGrant Likely * 446eae1aceSGrant Likely * There's a maximum of 8 wakeup GPIOs. Which of these are available 456eae1aceSGrant Likely * for use depends on your board setup. 466eae1aceSGrant Likely * 476eae1aceSGrant Likely * 0 -> GPIO_WKUP_7 486eae1aceSGrant Likely * 1 -> GPIO_WKUP_6 496eae1aceSGrant Likely * 2 -> PSC6_1 506eae1aceSGrant Likely * 3 -> PSC6_0 516eae1aceSGrant Likely * 4 -> ETH_17 526eae1aceSGrant Likely * 5 -> PSC3_9 536eae1aceSGrant Likely * 6 -> PSC2_4 546eae1aceSGrant Likely * 7 -> PSC1_4 556eae1aceSGrant Likely * 566eae1aceSGrant Likely */ 576eae1aceSGrant Likely static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio) 586eae1aceSGrant Likely { 596eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 606eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 616eae1aceSGrant Likely unsigned int ret; 626eae1aceSGrant Likely 636eae1aceSGrant Likely ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1; 646eae1aceSGrant Likely 656eae1aceSGrant Likely pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret); 666eae1aceSGrant Likely 676eae1aceSGrant Likely return ret; 686eae1aceSGrant Likely } 696eae1aceSGrant Likely 706eae1aceSGrant Likely static inline void 716eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 726eae1aceSGrant Likely { 736eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 746eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 756eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 766eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 776eae1aceSGrant Likely 786eae1aceSGrant Likely if (val) 796eae1aceSGrant Likely chip->shadow_dvo |= 1 << (7 - gpio); 806eae1aceSGrant Likely else 816eae1aceSGrant Likely chip->shadow_dvo &= ~(1 << (7 - gpio)); 826eae1aceSGrant Likely 836eae1aceSGrant Likely out_8(®s->wkup_dvo, chip->shadow_dvo); 846eae1aceSGrant Likely } 856eae1aceSGrant Likely 866eae1aceSGrant Likely static void 876eae1aceSGrant Likely mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 886eae1aceSGrant Likely { 896eae1aceSGrant Likely unsigned long flags; 906eae1aceSGrant Likely 916eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 926eae1aceSGrant Likely 936eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(gc, gpio, val); 946eae1aceSGrant Likely 956eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 966eae1aceSGrant Likely 976eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 986eae1aceSGrant Likely } 996eae1aceSGrant Likely 1006eae1aceSGrant Likely static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 1016eae1aceSGrant Likely { 1026eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 1036eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 1046eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 1056eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 1066eae1aceSGrant Likely unsigned long flags; 1076eae1aceSGrant Likely 1086eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 1096eae1aceSGrant Likely 1106eae1aceSGrant Likely /* set the direction */ 1116eae1aceSGrant Likely chip->shadow_ddr &= ~(1 << (7 - gpio)); 1126eae1aceSGrant Likely out_8(®s->wkup_ddr, chip->shadow_ddr); 1136eae1aceSGrant Likely 1146eae1aceSGrant Likely /* and enable the pin */ 1156eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (7 - gpio); 1166eae1aceSGrant Likely out_8(®s->wkup_gpioe, chip->shadow_gpioe); 1176eae1aceSGrant Likely 1186eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 1196eae1aceSGrant Likely 1206eae1aceSGrant Likely return 0; 1216eae1aceSGrant Likely } 1226eae1aceSGrant Likely 1236eae1aceSGrant Likely static int 1246eae1aceSGrant Likely mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 1256eae1aceSGrant Likely { 1266eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 1276eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 1286eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 1296eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 1306eae1aceSGrant Likely unsigned long flags; 1316eae1aceSGrant Likely 1326eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 1336eae1aceSGrant Likely 1346eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(gc, gpio, val); 1356eae1aceSGrant Likely 1366eae1aceSGrant Likely /* Then set direction */ 1376eae1aceSGrant Likely chip->shadow_ddr |= 1 << (7 - gpio); 1386eae1aceSGrant Likely out_8(®s->wkup_ddr, chip->shadow_ddr); 1396eae1aceSGrant Likely 1406eae1aceSGrant Likely /* Finally enable the pin */ 1416eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (7 - gpio); 1426eae1aceSGrant Likely out_8(®s->wkup_gpioe, chip->shadow_gpioe); 1436eae1aceSGrant Likely 1446eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 1456eae1aceSGrant Likely 1466eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 1476eae1aceSGrant Likely 1486eae1aceSGrant Likely return 0; 1496eae1aceSGrant Likely } 1506eae1aceSGrant Likely 1513836309dSBill Pemberton static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) 1526eae1aceSGrant Likely { 1536eae1aceSGrant Likely struct mpc52xx_gpiochip *chip; 1546eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs; 1556eae1aceSGrant Likely struct gpio_chip *gc; 1566eae1aceSGrant Likely int ret; 1576eae1aceSGrant Likely 158f91b2dbbSRicardo Ribalda Delgado chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL); 1596eae1aceSGrant Likely if (!chip) 1606eae1aceSGrant Likely return -ENOMEM; 1616eae1aceSGrant Likely 162f91b2dbbSRicardo Ribalda Delgado platform_set_drvdata(ofdev, chip); 163f91b2dbbSRicardo Ribalda Delgado 1646eae1aceSGrant Likely gc = &chip->mmchip.gc; 1656eae1aceSGrant Likely 1666eae1aceSGrant Likely gc->ngpio = 8; 1676eae1aceSGrant Likely gc->direction_input = mpc52xx_wkup_gpio_dir_in; 1686eae1aceSGrant Likely gc->direction_output = mpc52xx_wkup_gpio_dir_out; 1696eae1aceSGrant Likely gc->get = mpc52xx_wkup_gpio_get; 1706eae1aceSGrant Likely gc->set = mpc52xx_wkup_gpio_set; 1716eae1aceSGrant Likely 1726eae1aceSGrant Likely ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); 1736eae1aceSGrant Likely if (ret) 1746eae1aceSGrant Likely return ret; 1756eae1aceSGrant Likely 1766eae1aceSGrant Likely regs = chip->mmchip.regs; 1776eae1aceSGrant Likely chip->shadow_gpioe = in_8(®s->wkup_gpioe); 1786eae1aceSGrant Likely chip->shadow_ddr = in_8(®s->wkup_ddr); 1796eae1aceSGrant Likely chip->shadow_dvo = in_8(®s->wkup_dvo); 1806eae1aceSGrant Likely 1816eae1aceSGrant Likely return 0; 1826eae1aceSGrant Likely } 1836eae1aceSGrant Likely 1846eae1aceSGrant Likely static int mpc52xx_gpiochip_remove(struct platform_device *ofdev) 1856eae1aceSGrant Likely { 186f91b2dbbSRicardo Ribalda Delgado struct mpc52xx_gpiochip *chip = platform_get_drvdata(ofdev); 187f91b2dbbSRicardo Ribalda Delgado 188f91b2dbbSRicardo Ribalda Delgado of_mm_gpiochip_remove(&chip->mmchip); 189f91b2dbbSRicardo Ribalda Delgado 190f91b2dbbSRicardo Ribalda Delgado return 0; 1916eae1aceSGrant Likely } 1926eae1aceSGrant Likely 1936eae1aceSGrant Likely static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { 1946eae1aceSGrant Likely { .compatible = "fsl,mpc5200-gpio-wkup", }, 1956eae1aceSGrant Likely {} 1966eae1aceSGrant Likely }; 1976eae1aceSGrant Likely 1986eae1aceSGrant Likely static struct platform_driver mpc52xx_wkup_gpiochip_driver = { 1996eae1aceSGrant Likely .driver = { 2006eae1aceSGrant Likely .name = "mpc5200-gpio-wkup", 2016eae1aceSGrant Likely .of_match_table = mpc52xx_wkup_gpiochip_match, 2026eae1aceSGrant Likely }, 2036eae1aceSGrant Likely .probe = mpc52xx_wkup_gpiochip_probe, 2046eae1aceSGrant Likely .remove = mpc52xx_gpiochip_remove, 2056eae1aceSGrant Likely }; 2066eae1aceSGrant Likely 2076eae1aceSGrant Likely /* 2086eae1aceSGrant Likely * GPIO LIB API implementation for simple GPIOs 2096eae1aceSGrant Likely * 2106eae1aceSGrant Likely * There's a maximum of 32 simple GPIOs. Which of these are available 2116eae1aceSGrant Likely * for use depends on your board setup. 2126eae1aceSGrant Likely * The numbering reflects the bit numbering in the port registers: 2136eae1aceSGrant Likely * 2146eae1aceSGrant Likely * 0..1 > reserved 2156eae1aceSGrant Likely * 2..3 > IRDA 2166eae1aceSGrant Likely * 4..7 > ETHR 2176eae1aceSGrant Likely * 8..11 > reserved 2186eae1aceSGrant Likely * 12..15 > USB 2196eae1aceSGrant Likely * 16..17 > reserved 2206eae1aceSGrant Likely * 18..23 > PSC3 2216eae1aceSGrant Likely * 24..27 > PSC2 2226eae1aceSGrant Likely * 28..31 > PSC1 2236eae1aceSGrant Likely */ 2246eae1aceSGrant Likely static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio) 2256eae1aceSGrant Likely { 2266eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 2276eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2286eae1aceSGrant Likely unsigned int ret; 2296eae1aceSGrant Likely 2306eae1aceSGrant Likely ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1; 2316eae1aceSGrant Likely 2326eae1aceSGrant Likely return ret; 2336eae1aceSGrant Likely } 2346eae1aceSGrant Likely 2356eae1aceSGrant Likely static inline void 2366eae1aceSGrant Likely __mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 2376eae1aceSGrant Likely { 2386eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 2396eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 2406eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 2416eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2426eae1aceSGrant Likely 2436eae1aceSGrant Likely if (val) 2446eae1aceSGrant Likely chip->shadow_dvo |= 1 << (31 - gpio); 2456eae1aceSGrant Likely else 2466eae1aceSGrant Likely chip->shadow_dvo &= ~(1 << (31 - gpio)); 2476eae1aceSGrant Likely out_be32(®s->simple_dvo, chip->shadow_dvo); 2486eae1aceSGrant Likely } 2496eae1aceSGrant Likely 2506eae1aceSGrant Likely static void 2516eae1aceSGrant Likely mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 2526eae1aceSGrant Likely { 2536eae1aceSGrant Likely unsigned long flags; 2546eae1aceSGrant Likely 2556eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2566eae1aceSGrant Likely 2576eae1aceSGrant Likely __mpc52xx_simple_gpio_set(gc, gpio, val); 2586eae1aceSGrant Likely 2596eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 2606eae1aceSGrant Likely 2616eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 2626eae1aceSGrant Likely } 2636eae1aceSGrant Likely 2646eae1aceSGrant Likely static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 2656eae1aceSGrant Likely { 2666eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 2676eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 2686eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 2696eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2706eae1aceSGrant Likely unsigned long flags; 2716eae1aceSGrant Likely 2726eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2736eae1aceSGrant Likely 2746eae1aceSGrant Likely /* set the direction */ 2756eae1aceSGrant Likely chip->shadow_ddr &= ~(1 << (31 - gpio)); 2766eae1aceSGrant Likely out_be32(®s->simple_ddr, chip->shadow_ddr); 2776eae1aceSGrant Likely 2786eae1aceSGrant Likely /* and enable the pin */ 2796eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (31 - gpio); 2806eae1aceSGrant Likely out_be32(®s->simple_gpioe, chip->shadow_gpioe); 2816eae1aceSGrant Likely 2826eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 2836eae1aceSGrant Likely 2846eae1aceSGrant Likely return 0; 2856eae1aceSGrant Likely } 2866eae1aceSGrant Likely 2876eae1aceSGrant Likely static int 2886eae1aceSGrant Likely mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 2896eae1aceSGrant Likely { 2906eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 2916eae1aceSGrant Likely struct mpc52xx_gpiochip *chip = container_of(mm_gc, 2926eae1aceSGrant Likely struct mpc52xx_gpiochip, mmchip); 2936eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2946eae1aceSGrant Likely unsigned long flags; 2956eae1aceSGrant Likely 2966eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2976eae1aceSGrant Likely 2986eae1aceSGrant Likely /* First set initial value */ 2996eae1aceSGrant Likely __mpc52xx_simple_gpio_set(gc, gpio, val); 3006eae1aceSGrant Likely 3016eae1aceSGrant Likely /* Then set direction */ 3026eae1aceSGrant Likely chip->shadow_ddr |= 1 << (31 - gpio); 3036eae1aceSGrant Likely out_be32(®s->simple_ddr, chip->shadow_ddr); 3046eae1aceSGrant Likely 3056eae1aceSGrant Likely /* Finally enable the pin */ 3066eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (31 - gpio); 3076eae1aceSGrant Likely out_be32(®s->simple_gpioe, chip->shadow_gpioe); 3086eae1aceSGrant Likely 3096eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 3106eae1aceSGrant Likely 3116eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 3126eae1aceSGrant Likely 3136eae1aceSGrant Likely return 0; 3146eae1aceSGrant Likely } 3156eae1aceSGrant Likely 3163836309dSBill Pemberton static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) 3176eae1aceSGrant Likely { 3186eae1aceSGrant Likely struct mpc52xx_gpiochip *chip; 3196eae1aceSGrant Likely struct gpio_chip *gc; 3206eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs; 3216eae1aceSGrant Likely int ret; 3226eae1aceSGrant Likely 323f91b2dbbSRicardo Ribalda Delgado chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL); 3246eae1aceSGrant Likely if (!chip) 3256eae1aceSGrant Likely return -ENOMEM; 3266eae1aceSGrant Likely 327f91b2dbbSRicardo Ribalda Delgado platform_set_drvdata(ofdev, chip); 328f91b2dbbSRicardo Ribalda Delgado 3296eae1aceSGrant Likely gc = &chip->mmchip.gc; 3306eae1aceSGrant Likely 3316eae1aceSGrant Likely gc->ngpio = 32; 3326eae1aceSGrant Likely gc->direction_input = mpc52xx_simple_gpio_dir_in; 3336eae1aceSGrant Likely gc->direction_output = mpc52xx_simple_gpio_dir_out; 3346eae1aceSGrant Likely gc->get = mpc52xx_simple_gpio_get; 3356eae1aceSGrant Likely gc->set = mpc52xx_simple_gpio_set; 3366eae1aceSGrant Likely 3376eae1aceSGrant Likely ret = of_mm_gpiochip_add(ofdev->dev.of_node, &chip->mmchip); 3386eae1aceSGrant Likely if (ret) 3396eae1aceSGrant Likely return ret; 3406eae1aceSGrant Likely 3416eae1aceSGrant Likely regs = chip->mmchip.regs; 3426eae1aceSGrant Likely chip->shadow_gpioe = in_be32(®s->simple_gpioe); 3436eae1aceSGrant Likely chip->shadow_ddr = in_be32(®s->simple_ddr); 3446eae1aceSGrant Likely chip->shadow_dvo = in_be32(®s->simple_dvo); 3456eae1aceSGrant Likely 3466eae1aceSGrant Likely return 0; 3476eae1aceSGrant Likely } 3486eae1aceSGrant Likely 3496eae1aceSGrant Likely static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { 3506eae1aceSGrant Likely { .compatible = "fsl,mpc5200-gpio", }, 3516eae1aceSGrant Likely {} 3526eae1aceSGrant Likely }; 3536eae1aceSGrant Likely 3546eae1aceSGrant Likely static struct platform_driver mpc52xx_simple_gpiochip_driver = { 3556eae1aceSGrant Likely .driver = { 3566eae1aceSGrant Likely .name = "mpc5200-gpio", 3576eae1aceSGrant Likely .of_match_table = mpc52xx_simple_gpiochip_match, 3586eae1aceSGrant Likely }, 3596eae1aceSGrant Likely .probe = mpc52xx_simple_gpiochip_probe, 3606eae1aceSGrant Likely .remove = mpc52xx_gpiochip_remove, 3616eae1aceSGrant Likely }; 3626eae1aceSGrant Likely 363*20d7090fSThierry Reding static struct platform_driver * const drivers[] = { 364*20d7090fSThierry Reding &mpc52xx_wkup_gpiochip_driver, 365*20d7090fSThierry Reding &mpc52xx_simple_gpiochip_driver, 366*20d7090fSThierry Reding }; 367*20d7090fSThierry Reding 3686eae1aceSGrant Likely static int __init mpc52xx_gpio_init(void) 3696eae1aceSGrant Likely { 370*20d7090fSThierry Reding return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 3716eae1aceSGrant Likely } 3726eae1aceSGrant Likely 3736eae1aceSGrant Likely /* Make sure we get initialised before anyone else tries to use us */ 3746eae1aceSGrant Likely subsys_initcall(mpc52xx_gpio_init); 3756eae1aceSGrant Likely 376f91b2dbbSRicardo Ribalda Delgado static void __exit mpc52xx_gpio_exit(void) 377f91b2dbbSRicardo Ribalda Delgado { 378*20d7090fSThierry Reding platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 379f91b2dbbSRicardo Ribalda Delgado } 380f91b2dbbSRicardo Ribalda Delgado module_exit(mpc52xx_gpio_exit); 3816eae1aceSGrant Likely 3826eae1aceSGrant Likely MODULE_DESCRIPTION("Freescale MPC52xx gpio driver"); 3836eae1aceSGrant Likely MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); 3846eae1aceSGrant Likely MODULE_LICENSE("GPL v2"); 3856eae1aceSGrant Likely 386