Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: ath79: Add OF support to the GPIO driver

Replace the simple GPIO chip registration by a platform driver
and make ath79_gpio_init() just register the device.

Signed-off-by: Alban Bedel <albeu@free.fr>
Cc: linux-mips@linux-mips.org
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Alban Bedel and committed by
Ralf Baechle
2ddf3a79 d6743a49

+127 -22
+51
arch/mips/ath79/dev-common.c
··· 14 14 #include <linux/kernel.h> 15 15 #include <linux/init.h> 16 16 #include <linux/platform_device.h> 17 + #include <linux/platform_data/gpio-ath79.h> 17 18 #include <linux/serial_8250.h> 18 19 #include <linux/clk.h> 19 20 #include <linux/err.h> ··· 106 105 res.end = res.start + 0x8 - 1; 107 106 108 107 platform_device_register_simple("ath79-wdt", -1, &res, 1); 108 + } 109 + 110 + static struct ath79_gpio_platform_data ath79_gpio_pdata; 111 + 112 + static struct resource ath79_gpio_resources[] = { 113 + { 114 + .flags = IORESOURCE_MEM, 115 + .start = AR71XX_GPIO_BASE, 116 + .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1, 117 + }, 118 + { 119 + .start = ATH79_MISC_IRQ(2), 120 + .end = ATH79_MISC_IRQ(2), 121 + .flags = IORESOURCE_IRQ, 122 + }, 123 + }; 124 + 125 + static struct platform_device ath79_gpio_device = { 126 + .name = "ath79-gpio", 127 + .id = -1, 128 + .resource = ath79_gpio_resources, 129 + .num_resources = ARRAY_SIZE(ath79_gpio_resources), 130 + .dev = { 131 + .platform_data = &ath79_gpio_pdata 132 + }, 133 + }; 134 + 135 + void __init ath79_gpio_init(void) 136 + { 137 + if (soc_is_ar71xx()) { 138 + ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT; 139 + } else if (soc_is_ar7240()) { 140 + ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT; 141 + } else if (soc_is_ar7241() || soc_is_ar7242()) { 142 + ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT; 143 + } else if (soc_is_ar913x()) { 144 + ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT; 145 + } else if (soc_is_ar933x()) { 146 + ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT; 147 + } else if (soc_is_ar934x()) { 148 + ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT; 149 + ath79_gpio_pdata.oe_inverted = 1; 150 + } else if (soc_is_qca955x()) { 151 + ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; 152 + ath79_gpio_pdata.oe_inverted = 1; 153 + } else { 154 + BUG(); 155 + } 156 + 157 + platform_device_register(&ath79_gpio_device); 109 158 }
+57 -22
arch/mips/ath79/gpio.c
··· 20 20 #include <linux/io.h> 21 21 #include <linux/ioport.h> 22 22 #include <linux/gpio.h> 23 + #include <linux/platform_data/gpio-ath79.h> 24 + #include <linux/of_device.h> 23 25 24 26 #include <asm/mach-ath79/ar71xx_regs.h> 25 27 #include <asm/mach-ath79/ath79.h> 26 28 #include "common.h" 27 29 28 30 static void __iomem *ath79_gpio_base; 29 - static unsigned long ath79_gpio_count; 31 + static u32 ath79_gpio_count; 30 32 static DEFINE_SPINLOCK(ath79_gpio_lock); 31 33 32 34 static void __ath79_gpio_set_value(unsigned gpio, int value) ··· 180 178 ath79_gpio_function_setup(0, mask); 181 179 } 182 180 183 - void __init ath79_gpio_init(void) 181 + static const struct of_device_id ath79_gpio_of_match[] = { 182 + { .compatible = "qca,ar7100-gpio" }, 183 + { .compatible = "qca,ar9340-gpio" }, 184 + {}, 185 + }; 186 + 187 + static int ath79_gpio_probe(struct platform_device *pdev) 184 188 { 189 + struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data; 190 + struct device_node *np = pdev->dev.of_node; 191 + struct resource *res; 192 + bool oe_inverted; 185 193 int err; 186 194 187 - if (soc_is_ar71xx()) 188 - ath79_gpio_count = AR71XX_GPIO_COUNT; 189 - else if (soc_is_ar7240()) 190 - ath79_gpio_count = AR7240_GPIO_COUNT; 191 - else if (soc_is_ar7241() || soc_is_ar7242()) 192 - ath79_gpio_count = AR7241_GPIO_COUNT; 193 - else if (soc_is_ar913x()) 194 - ath79_gpio_count = AR913X_GPIO_COUNT; 195 - else if (soc_is_ar933x()) 196 - ath79_gpio_count = AR933X_GPIO_COUNT; 197 - else if (soc_is_ar934x()) 198 - ath79_gpio_count = AR934X_GPIO_COUNT; 199 - else if (soc_is_qca955x()) 200 - ath79_gpio_count = QCA955X_GPIO_COUNT; 201 - else 202 - BUG(); 195 + if (np) { 196 + err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); 197 + if (err) { 198 + dev_err(&pdev->dev, "ngpios property is not valid\n"); 199 + return err; 200 + } 201 + if (ath79_gpio_count >= 32) { 202 + dev_err(&pdev->dev, "ngpios must be less than 32\n"); 203 + return -EINVAL; 204 + } 205 + oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio"); 206 + } else if (pdata) { 207 + ath79_gpio_count = pdata->ngpios; 208 + oe_inverted = pdata->oe_inverted; 209 + } else { 210 + dev_err(&pdev->dev, "No DT node or platform data found\n"); 211 + return -EINVAL; 212 + } 203 213 204 - ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); 214 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 215 + ath79_gpio_base = devm_ioremap_nocache( 216 + &pdev->dev, res->start, resource_size(res)); 217 + if (!ath79_gpio_base) 218 + return -ENOMEM; 219 + 220 + ath79_gpio_chip.dev = &pdev->dev; 205 221 ath79_gpio_chip.ngpio = ath79_gpio_count; 206 - if (soc_is_ar934x() || soc_is_qca955x()) { 222 + if (oe_inverted) { 207 223 ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; 208 224 ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; 209 225 } 210 226 211 227 err = gpiochip_add(&ath79_gpio_chip); 212 - if (err) 213 - panic("cannot add AR71xx GPIO chip, error=%d", err); 228 + if (err) { 229 + dev_err(&pdev->dev, 230 + "cannot add AR71xx GPIO chip, error=%d", err); 231 + return err; 232 + } 233 + 234 + return 0; 214 235 } 236 + 237 + static struct platform_driver ath79_gpio_driver = { 238 + .driver = { 239 + .name = "ath79-gpio", 240 + .of_match_table = ath79_gpio_of_match, 241 + }, 242 + .probe = ath79_gpio_probe, 243 + }; 244 + 245 + module_platform_driver(ath79_gpio_driver); 215 246 216 247 int gpio_get_value(unsigned gpio) 217 248 {
+19
include/linux/platform_data/gpio-ath79.h
··· 1 + /* 2 + * Atheros AR7XXX/AR9XXX GPIO controller platform data 3 + * 4 + * Copyright (C) 2015 Alban Bedel <albeu@free.fr> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #ifndef __LINUX_PLATFORM_DATA_GPIO_ATH79_H 12 + #define __LINUX_PLATFORM_DATA_GPIO_ATH79_H 13 + 14 + struct ath79_gpio_platform_data { 15 + unsigned ngpios; 16 + bool oe_inverted; 17 + }; 18 + 19 + #endif