summaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-ath79.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/gpio-ath79.c')
-rw-r--r--drivers/gpio/gpio-ath79.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c
index 6c6dcda1100c..f1a5ea9b3de2 100644
--- a/drivers/gpio/gpio-ath79.c
+++ b/drivers/gpio/gpio-ath79.c
@@ -222,14 +222,16 @@ MODULE_DEVICE_TABLE(of, ath79_gpio_of_match);
222static int ath79_gpio_probe(struct platform_device *pdev) 222static int ath79_gpio_probe(struct platform_device *pdev)
223{ 223{
224 struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 224 struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
225 struct device_node *np = pdev->dev.of_node; 225 struct device *dev = &pdev->dev;
226 struct device_node *np = dev->of_node;
226 struct ath79_gpio_ctrl *ctrl; 227 struct ath79_gpio_ctrl *ctrl;
228 struct gpio_irq_chip *girq;
227 struct resource *res; 229 struct resource *res;
228 u32 ath79_gpio_count; 230 u32 ath79_gpio_count;
229 bool oe_inverted; 231 bool oe_inverted;
230 int err; 232 int err;
231 233
232 ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); 234 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
233 if (!ctrl) 235 if (!ctrl)
234 return -ENOMEM; 236 return -ENOMEM;
235 platform_set_drvdata(pdev, ctrl); 237 platform_set_drvdata(pdev, ctrl);
@@ -237,7 +239,7 @@ static int ath79_gpio_probe(struct platform_device *pdev)
237 if (np) { 239 if (np) {
238 err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); 240 err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
239 if (err) { 241 if (err) {
240 dev_err(&pdev->dev, "ngpios property is not valid\n"); 242 dev_err(dev, "ngpios property is not valid\n");
241 return err; 243 return err;
242 } 244 }
243 oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio"); 245 oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
@@ -245,25 +247,24 @@ static int ath79_gpio_probe(struct platform_device *pdev)
245 ath79_gpio_count = pdata->ngpios; 247 ath79_gpio_count = pdata->ngpios;
246 oe_inverted = pdata->oe_inverted; 248 oe_inverted = pdata->oe_inverted;
247 } else { 249 } else {
248 dev_err(&pdev->dev, "No DT node or platform data found\n"); 250 dev_err(dev, "No DT node or platform data found\n");
249 return -EINVAL; 251 return -EINVAL;
250 } 252 }
251 253
252 if (ath79_gpio_count >= 32) { 254 if (ath79_gpio_count >= 32) {
253 dev_err(&pdev->dev, "ngpios must be less than 32\n"); 255 dev_err(dev, "ngpios must be less than 32\n");
254 return -EINVAL; 256 return -EINVAL;
255 } 257 }
256 258
257 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 259 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
258 if (!res) 260 if (!res)
259 return -EINVAL; 261 return -EINVAL;
260 ctrl->base = devm_ioremap_nocache( 262 ctrl->base = devm_ioremap_nocache(dev, res->start, resource_size(res));
261 &pdev->dev, res->start, resource_size(res));
262 if (!ctrl->base) 263 if (!ctrl->base)
263 return -ENOMEM; 264 return -ENOMEM;
264 265
265 raw_spin_lock_init(&ctrl->lock); 266 raw_spin_lock_init(&ctrl->lock);
266 err = bgpio_init(&ctrl->gc, &pdev->dev, 4, 267 err = bgpio_init(&ctrl->gc, dev, 4,
267 ctrl->base + AR71XX_GPIO_REG_IN, 268 ctrl->base + AR71XX_GPIO_REG_IN,
268 ctrl->base + AR71XX_GPIO_REG_SET, 269 ctrl->base + AR71XX_GPIO_REG_SET,
269 ctrl->base + AR71XX_GPIO_REG_CLEAR, 270 ctrl->base + AR71XX_GPIO_REG_CLEAR,
@@ -271,45 +272,33 @@ static int ath79_gpio_probe(struct platform_device *pdev)
271 oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL, 272 oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL,
272 0); 273 0);
273 if (err) { 274 if (err) {
274 dev_err(&pdev->dev, "bgpio_init failed\n"); 275 dev_err(dev, "bgpio_init failed\n");
275 return err; 276 return err;
276 } 277 }
277 /* Use base 0 to stay compatible with legacy platforms */ 278 /* Use base 0 to stay compatible with legacy platforms */
278 ctrl->gc.base = 0; 279 ctrl->gc.base = 0;
279 280
280 err = gpiochip_add_data(&ctrl->gc, ctrl); 281 /* Optional interrupt setup */
281 if (err) { 282 if (!np || of_property_read_bool(np, "interrupt-controller")) {
282 dev_err(&pdev->dev, 283 girq = &ctrl->gc.irq;
283 "cannot add AR71xx GPIO chip, error=%d", err); 284 girq->chip = &ath79_gpio_irqchip;
284 return err; 285 girq->parent_handler = ath79_gpio_irq_handler;
286 girq->num_parents = 1;
287 girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
288 GFP_KERNEL);
289 if (!girq->parents)
290 return -ENOMEM;
291 girq->parents[0] = platform_get_irq(pdev, 0);
292 girq->default_type = IRQ_TYPE_NONE;
293 girq->handler = handle_simple_irq;
285 } 294 }
286 295
287 if (np && !of_property_read_bool(np, "interrupt-controller")) 296 err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
288 return 0;
289
290 err = gpiochip_irqchip_add(&ctrl->gc, &ath79_gpio_irqchip, 0,
291 handle_simple_irq, IRQ_TYPE_NONE);
292 if (err) { 297 if (err) {
293 dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n"); 298 dev_err(dev,
294 goto gpiochip_remove; 299 "cannot add AR71xx GPIO chip, error=%d", err);
300 return err;
295 } 301 }
296
297 gpiochip_set_chained_irqchip(&ctrl->gc, &ath79_gpio_irqchip,
298 platform_get_irq(pdev, 0),
299 ath79_gpio_irq_handler);
300
301 return 0;
302
303gpiochip_remove:
304 gpiochip_remove(&ctrl->gc);
305 return err;
306}
307
308static int ath79_gpio_remove(struct platform_device *pdev)
309{
310 struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev);
311
312 gpiochip_remove(&ctrl->gc);
313 return 0; 302 return 0;
314} 303}
315 304
@@ -319,7 +308,6 @@ static struct platform_driver ath79_gpio_driver = {
319 .of_match_table = ath79_gpio_of_match, 308 .of_match_table = ath79_gpio_of_match,
320 }, 309 },
321 .probe = ath79_gpio_probe, 310 .probe = ath79_gpio_probe,
322 .remove = ath79_gpio_remove,
323}; 311};
324 312
325module_platform_driver(ath79_gpio_driver); 313module_platform_driver(ath79_gpio_driver);