145051539SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 26eae1aceSGrant Likely /* 36eae1aceSGrant Likely * MPC52xx gpio driver 46eae1aceSGrant Likely * 56eae1aceSGrant Likely * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix 66eae1aceSGrant Likely */ 76eae1aceSGrant Likely 86eae1aceSGrant Likely #include <linux/of.h> 96eae1aceSGrant Likely #include <linux/kernel.h> 106eae1aceSGrant Likely #include <linux/slab.h> 11a99cc668SArnd Bergmann #include <linux/gpio/legacy-of-mm-gpiochip.h> 126eae1aceSGrant Likely #include <linux/io.h> 13e91d0f05SRob Herring #include <linux/platform_device.h> 14bb207ef1SPaul Gortmaker #include <linux/module.h> 156eae1aceSGrant Likely 166eae1aceSGrant Likely #include <asm/mpc52xx.h> 176eae1aceSGrant Likely #include <sysdev/fsl_soc.h> 186eae1aceSGrant Likely 196eae1aceSGrant Likely static DEFINE_SPINLOCK(gpio_lock); 206eae1aceSGrant Likely 216eae1aceSGrant Likely struct mpc52xx_gpiochip { 226eae1aceSGrant Likely struct of_mm_gpio_chip mmchip; 236eae1aceSGrant Likely unsigned int shadow_dvo; 246eae1aceSGrant Likely unsigned int shadow_gpioe; 256eae1aceSGrant Likely unsigned int shadow_ddr; 266eae1aceSGrant Likely }; 276eae1aceSGrant Likely 286eae1aceSGrant Likely /* 296eae1aceSGrant Likely * GPIO LIB API implementation for wakeup GPIOs. 306eae1aceSGrant Likely * 316eae1aceSGrant Likely * There's a maximum of 8 wakeup GPIOs. Which of these are available 326eae1aceSGrant Likely * for use depends on your board setup. 336eae1aceSGrant Likely * 346eae1aceSGrant Likely * 0 -> GPIO_WKUP_7 356eae1aceSGrant Likely * 1 -> GPIO_WKUP_6 366eae1aceSGrant Likely * 2 -> PSC6_1 376eae1aceSGrant Likely * 3 -> PSC6_0 386eae1aceSGrant Likely * 4 -> ETH_17 396eae1aceSGrant Likely * 5 -> PSC3_9 406eae1aceSGrant Likely * 6 -> PSC2_4 416eae1aceSGrant Likely * 7 -> PSC1_4 426eae1aceSGrant Likely * 436eae1aceSGrant Likely */ 446eae1aceSGrant Likely static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio) 456eae1aceSGrant Likely { 466eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 476eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 486eae1aceSGrant Likely unsigned int ret; 496eae1aceSGrant Likely 506eae1aceSGrant Likely ret = (in_8(®s->wkup_ival) >> (7 - gpio)) & 1; 516eae1aceSGrant Likely 526eae1aceSGrant Likely pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret); 536eae1aceSGrant Likely 546eae1aceSGrant Likely return ret; 556eae1aceSGrant Likely } 566eae1aceSGrant Likely 576eae1aceSGrant Likely static inline void 586eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 596eae1aceSGrant Likely { 606eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 61837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 626eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 636eae1aceSGrant Likely 646eae1aceSGrant Likely if (val) 656eae1aceSGrant Likely chip->shadow_dvo |= 1 << (7 - gpio); 666eae1aceSGrant Likely else 676eae1aceSGrant Likely chip->shadow_dvo &= ~(1 << (7 - gpio)); 686eae1aceSGrant Likely 696eae1aceSGrant Likely out_8(®s->wkup_dvo, chip->shadow_dvo); 706eae1aceSGrant Likely } 716eae1aceSGrant Likely 726eae1aceSGrant Likely static void 736eae1aceSGrant Likely mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 746eae1aceSGrant Likely { 756eae1aceSGrant Likely unsigned long flags; 766eae1aceSGrant Likely 776eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 786eae1aceSGrant Likely 796eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(gc, gpio, val); 806eae1aceSGrant Likely 816eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 826eae1aceSGrant Likely 836eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 846eae1aceSGrant Likely } 856eae1aceSGrant Likely 866eae1aceSGrant Likely static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 876eae1aceSGrant Likely { 886eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 89837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 906eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 916eae1aceSGrant Likely unsigned long flags; 926eae1aceSGrant Likely 936eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 946eae1aceSGrant Likely 956eae1aceSGrant Likely /* set the direction */ 966eae1aceSGrant Likely chip->shadow_ddr &= ~(1 << (7 - gpio)); 976eae1aceSGrant Likely out_8(®s->wkup_ddr, chip->shadow_ddr); 986eae1aceSGrant Likely 996eae1aceSGrant Likely /* and enable the pin */ 1006eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (7 - gpio); 1016eae1aceSGrant Likely out_8(®s->wkup_gpioe, chip->shadow_gpioe); 1026eae1aceSGrant Likely 1036eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 1046eae1aceSGrant Likely 1056eae1aceSGrant Likely return 0; 1066eae1aceSGrant Likely } 1076eae1aceSGrant Likely 1086eae1aceSGrant Likely static int 1096eae1aceSGrant Likely mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 1106eae1aceSGrant Likely { 1116eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 1126eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; 113837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 1146eae1aceSGrant Likely unsigned long flags; 1156eae1aceSGrant Likely 1166eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 1176eae1aceSGrant Likely 1186eae1aceSGrant Likely __mpc52xx_wkup_gpio_set(gc, gpio, val); 1196eae1aceSGrant Likely 1206eae1aceSGrant Likely /* Then set direction */ 1216eae1aceSGrant Likely chip->shadow_ddr |= 1 << (7 - gpio); 1226eae1aceSGrant Likely out_8(®s->wkup_ddr, chip->shadow_ddr); 1236eae1aceSGrant Likely 1246eae1aceSGrant Likely /* Finally enable the pin */ 1256eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (7 - gpio); 1266eae1aceSGrant Likely out_8(®s->wkup_gpioe, chip->shadow_gpioe); 1276eae1aceSGrant Likely 1286eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 1296eae1aceSGrant Likely 1306eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 1316eae1aceSGrant Likely 1326eae1aceSGrant Likely return 0; 1336eae1aceSGrant Likely } 1346eae1aceSGrant Likely 1353836309dSBill Pemberton static int mpc52xx_wkup_gpiochip_probe(struct platform_device *ofdev) 1366eae1aceSGrant Likely { 1376eae1aceSGrant Likely struct mpc52xx_gpiochip *chip; 1386eae1aceSGrant Likely struct mpc52xx_gpio_wkup __iomem *regs; 1396eae1aceSGrant Likely struct gpio_chip *gc; 1406eae1aceSGrant Likely int ret; 1416eae1aceSGrant Likely 142f91b2dbbSRicardo Ribalda Delgado chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL); 1436eae1aceSGrant Likely if (!chip) 1446eae1aceSGrant Likely return -ENOMEM; 1456eae1aceSGrant Likely 146f91b2dbbSRicardo Ribalda Delgado platform_set_drvdata(ofdev, chip); 147f91b2dbbSRicardo Ribalda Delgado 1486eae1aceSGrant Likely gc = &chip->mmchip.gc; 1496eae1aceSGrant Likely 1506eae1aceSGrant Likely gc->ngpio = 8; 1516eae1aceSGrant Likely gc->direction_input = mpc52xx_wkup_gpio_dir_in; 1526eae1aceSGrant Likely gc->direction_output = mpc52xx_wkup_gpio_dir_out; 1536eae1aceSGrant Likely gc->get = mpc52xx_wkup_gpio_get; 1546eae1aceSGrant Likely gc->set = mpc52xx_wkup_gpio_set; 1556eae1aceSGrant Likely 156837c2705SLinus Walleij ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip); 1576eae1aceSGrant Likely if (ret) 1586eae1aceSGrant Likely return ret; 1596eae1aceSGrant Likely 1606eae1aceSGrant Likely regs = chip->mmchip.regs; 1616eae1aceSGrant Likely chip->shadow_gpioe = in_8(®s->wkup_gpioe); 1626eae1aceSGrant Likely chip->shadow_ddr = in_8(®s->wkup_ddr); 1636eae1aceSGrant Likely chip->shadow_dvo = in_8(®s->wkup_dvo); 1646eae1aceSGrant Likely 1656eae1aceSGrant Likely return 0; 1666eae1aceSGrant Likely } 1676eae1aceSGrant Likely 168*0ede8698SUwe Kleine-König static void mpc52xx_gpiochip_remove(struct platform_device *ofdev) 1696eae1aceSGrant Likely { 170f91b2dbbSRicardo Ribalda Delgado struct mpc52xx_gpiochip *chip = platform_get_drvdata(ofdev); 171f91b2dbbSRicardo Ribalda Delgado 172f91b2dbbSRicardo Ribalda Delgado of_mm_gpiochip_remove(&chip->mmchip); 1736eae1aceSGrant Likely } 1746eae1aceSGrant Likely 1756eae1aceSGrant Likely static const struct of_device_id mpc52xx_wkup_gpiochip_match[] = { 1766eae1aceSGrant Likely { .compatible = "fsl,mpc5200-gpio-wkup", }, 1776eae1aceSGrant Likely {} 1786eae1aceSGrant Likely }; 1796eae1aceSGrant Likely 1806eae1aceSGrant Likely static struct platform_driver mpc52xx_wkup_gpiochip_driver = { 1816eae1aceSGrant Likely .driver = { 1826eae1aceSGrant Likely .name = "mpc5200-gpio-wkup", 1836eae1aceSGrant Likely .of_match_table = mpc52xx_wkup_gpiochip_match, 1846eae1aceSGrant Likely }, 1856eae1aceSGrant Likely .probe = mpc52xx_wkup_gpiochip_probe, 186*0ede8698SUwe Kleine-König .remove_new = mpc52xx_gpiochip_remove, 1876eae1aceSGrant Likely }; 1886eae1aceSGrant Likely 1896eae1aceSGrant Likely /* 1906eae1aceSGrant Likely * GPIO LIB API implementation for simple GPIOs 1916eae1aceSGrant Likely * 1926eae1aceSGrant Likely * There's a maximum of 32 simple GPIOs. Which of these are available 1936eae1aceSGrant Likely * for use depends on your board setup. 1946eae1aceSGrant Likely * The numbering reflects the bit numbering in the port registers: 1956eae1aceSGrant Likely * 1966eae1aceSGrant Likely * 0..1 > reserved 1976eae1aceSGrant Likely * 2..3 > IRDA 1986eae1aceSGrant Likely * 4..7 > ETHR 1996eae1aceSGrant Likely * 8..11 > reserved 2006eae1aceSGrant Likely * 12..15 > USB 2016eae1aceSGrant Likely * 16..17 > reserved 2026eae1aceSGrant Likely * 18..23 > PSC3 2036eae1aceSGrant Likely * 24..27 > PSC2 2046eae1aceSGrant Likely * 28..31 > PSC1 2056eae1aceSGrant Likely */ 2066eae1aceSGrant Likely static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio) 2076eae1aceSGrant Likely { 2086eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 2096eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2106eae1aceSGrant Likely unsigned int ret; 2116eae1aceSGrant Likely 2126eae1aceSGrant Likely ret = (in_be32(®s->simple_ival) >> (31 - gpio)) & 1; 2136eae1aceSGrant Likely 2146eae1aceSGrant Likely return ret; 2156eae1aceSGrant Likely } 2166eae1aceSGrant Likely 2176eae1aceSGrant Likely static inline void 2186eae1aceSGrant Likely __mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 2196eae1aceSGrant Likely { 2206eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 221837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 2226eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2236eae1aceSGrant Likely 2246eae1aceSGrant Likely if (val) 2256eae1aceSGrant Likely chip->shadow_dvo |= 1 << (31 - gpio); 2266eae1aceSGrant Likely else 2276eae1aceSGrant Likely chip->shadow_dvo &= ~(1 << (31 - gpio)); 2286eae1aceSGrant Likely out_be32(®s->simple_dvo, chip->shadow_dvo); 2296eae1aceSGrant Likely } 2306eae1aceSGrant Likely 2316eae1aceSGrant Likely static void 2326eae1aceSGrant Likely mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 2336eae1aceSGrant Likely { 2346eae1aceSGrant Likely unsigned long flags; 2356eae1aceSGrant Likely 2366eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2376eae1aceSGrant Likely 2386eae1aceSGrant Likely __mpc52xx_simple_gpio_set(gc, gpio, val); 2396eae1aceSGrant Likely 2406eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 2416eae1aceSGrant Likely 2426eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 2436eae1aceSGrant Likely } 2446eae1aceSGrant Likely 2456eae1aceSGrant Likely static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 2466eae1aceSGrant Likely { 2476eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 248837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 2496eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2506eae1aceSGrant Likely unsigned long flags; 2516eae1aceSGrant Likely 2526eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2536eae1aceSGrant Likely 2546eae1aceSGrant Likely /* set the direction */ 2556eae1aceSGrant Likely chip->shadow_ddr &= ~(1 << (31 - gpio)); 2566eae1aceSGrant Likely out_be32(®s->simple_ddr, chip->shadow_ddr); 2576eae1aceSGrant Likely 2586eae1aceSGrant Likely /* and enable the pin */ 2596eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (31 - gpio); 2606eae1aceSGrant Likely out_be32(®s->simple_gpioe, chip->shadow_gpioe); 2616eae1aceSGrant Likely 2626eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 2636eae1aceSGrant Likely 2646eae1aceSGrant Likely return 0; 2656eae1aceSGrant Likely } 2666eae1aceSGrant Likely 2676eae1aceSGrant Likely static int 2686eae1aceSGrant Likely mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 2696eae1aceSGrant Likely { 2706eae1aceSGrant Likely struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 271837c2705SLinus Walleij struct mpc52xx_gpiochip *chip = gpiochip_get_data(gc); 2726eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs = mm_gc->regs; 2736eae1aceSGrant Likely unsigned long flags; 2746eae1aceSGrant Likely 2756eae1aceSGrant Likely spin_lock_irqsave(&gpio_lock, flags); 2766eae1aceSGrant Likely 2776eae1aceSGrant Likely /* First set initial value */ 2786eae1aceSGrant Likely __mpc52xx_simple_gpio_set(gc, gpio, val); 2796eae1aceSGrant Likely 2806eae1aceSGrant Likely /* Then set direction */ 2816eae1aceSGrant Likely chip->shadow_ddr |= 1 << (31 - gpio); 2826eae1aceSGrant Likely out_be32(®s->simple_ddr, chip->shadow_ddr); 2836eae1aceSGrant Likely 2846eae1aceSGrant Likely /* Finally enable the pin */ 2856eae1aceSGrant Likely chip->shadow_gpioe |= 1 << (31 - gpio); 2866eae1aceSGrant Likely out_be32(®s->simple_gpioe, chip->shadow_gpioe); 2876eae1aceSGrant Likely 2886eae1aceSGrant Likely spin_unlock_irqrestore(&gpio_lock, flags); 2896eae1aceSGrant Likely 2906eae1aceSGrant Likely pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); 2916eae1aceSGrant Likely 2926eae1aceSGrant Likely return 0; 2936eae1aceSGrant Likely } 2946eae1aceSGrant Likely 2953836309dSBill Pemberton static int mpc52xx_simple_gpiochip_probe(struct platform_device *ofdev) 2966eae1aceSGrant Likely { 2976eae1aceSGrant Likely struct mpc52xx_gpiochip *chip; 2986eae1aceSGrant Likely struct gpio_chip *gc; 2996eae1aceSGrant Likely struct mpc52xx_gpio __iomem *regs; 3006eae1aceSGrant Likely int ret; 3016eae1aceSGrant Likely 302f91b2dbbSRicardo Ribalda Delgado chip = devm_kzalloc(&ofdev->dev, sizeof(*chip), GFP_KERNEL); 3036eae1aceSGrant Likely if (!chip) 3046eae1aceSGrant Likely return -ENOMEM; 3056eae1aceSGrant Likely 306f91b2dbbSRicardo Ribalda Delgado platform_set_drvdata(ofdev, chip); 307f91b2dbbSRicardo Ribalda Delgado 3086eae1aceSGrant Likely gc = &chip->mmchip.gc; 3096eae1aceSGrant Likely 3106eae1aceSGrant Likely gc->ngpio = 32; 3116eae1aceSGrant Likely gc->direction_input = mpc52xx_simple_gpio_dir_in; 3126eae1aceSGrant Likely gc->direction_output = mpc52xx_simple_gpio_dir_out; 3136eae1aceSGrant Likely gc->get = mpc52xx_simple_gpio_get; 3146eae1aceSGrant Likely gc->set = mpc52xx_simple_gpio_set; 3156eae1aceSGrant Likely 316837c2705SLinus Walleij ret = of_mm_gpiochip_add_data(ofdev->dev.of_node, &chip->mmchip, chip); 3176eae1aceSGrant Likely if (ret) 3186eae1aceSGrant Likely return ret; 3196eae1aceSGrant Likely 3206eae1aceSGrant Likely regs = chip->mmchip.regs; 3216eae1aceSGrant Likely chip->shadow_gpioe = in_be32(®s->simple_gpioe); 3226eae1aceSGrant Likely chip->shadow_ddr = in_be32(®s->simple_ddr); 3236eae1aceSGrant Likely chip->shadow_dvo = in_be32(®s->simple_dvo); 3246eae1aceSGrant Likely 3256eae1aceSGrant Likely return 0; 3266eae1aceSGrant Likely } 3276eae1aceSGrant Likely 3286eae1aceSGrant Likely static const struct of_device_id mpc52xx_simple_gpiochip_match[] = { 3296eae1aceSGrant Likely { .compatible = "fsl,mpc5200-gpio", }, 3306eae1aceSGrant Likely {} 3316eae1aceSGrant Likely }; 3326eae1aceSGrant Likely 3336eae1aceSGrant Likely static struct platform_driver mpc52xx_simple_gpiochip_driver = { 3346eae1aceSGrant Likely .driver = { 3356eae1aceSGrant Likely .name = "mpc5200-gpio", 3366eae1aceSGrant Likely .of_match_table = mpc52xx_simple_gpiochip_match, 3376eae1aceSGrant Likely }, 3386eae1aceSGrant Likely .probe = mpc52xx_simple_gpiochip_probe, 339*0ede8698SUwe Kleine-König .remove_new = mpc52xx_gpiochip_remove, 3406eae1aceSGrant Likely }; 3416eae1aceSGrant Likely 34220d7090fSThierry Reding static struct platform_driver * const drivers[] = { 34320d7090fSThierry Reding &mpc52xx_wkup_gpiochip_driver, 34420d7090fSThierry Reding &mpc52xx_simple_gpiochip_driver, 34520d7090fSThierry Reding }; 34620d7090fSThierry Reding 3476eae1aceSGrant Likely static int __init mpc52xx_gpio_init(void) 3486eae1aceSGrant Likely { 34920d7090fSThierry Reding return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); 3506eae1aceSGrant Likely } 3516eae1aceSGrant Likely 3526eae1aceSGrant Likely /* Make sure we get initialised before anyone else tries to use us */ 3536eae1aceSGrant Likely subsys_initcall(mpc52xx_gpio_init); 3546eae1aceSGrant Likely 355f91b2dbbSRicardo Ribalda Delgado static void __exit mpc52xx_gpio_exit(void) 356f91b2dbbSRicardo Ribalda Delgado { 35720d7090fSThierry Reding platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); 358f91b2dbbSRicardo Ribalda Delgado } 359f91b2dbbSRicardo Ribalda Delgado module_exit(mpc52xx_gpio_exit); 3606eae1aceSGrant Likely 3616eae1aceSGrant Likely MODULE_DESCRIPTION("Freescale MPC52xx gpio driver"); 3626eae1aceSGrant Likely MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); 3636eae1aceSGrant Likely MODULE_LICENSE("GPL v2"); 3646eae1aceSGrant Likely 365