| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Atheros AR71XX/AR724X/AR913X GPIO API support |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
|---|
| 6 | 7 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
|---|
| 7 | 8 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 10 | | - * under the terms of the GNU General Public License version 2 as published |
|---|
| 11 | | - * by the Free Software Foundation. |
|---|
| 12 | 9 | */ |
|---|
| 13 | 10 | |
|---|
| 14 | 11 | #include <linux/gpio/driver.h> |
|---|
| .. | .. |
|---|
| 132 | 129 | |
|---|
| 133 | 130 | case IRQ_TYPE_LEVEL_HIGH: |
|---|
| 134 | 131 | polarity |= mask; |
|---|
| 135 | | - /* fall through */ |
|---|
| 132 | + fallthrough; |
|---|
| 136 | 133 | case IRQ_TYPE_LEVEL_LOW: |
|---|
| 137 | 134 | type |= mask; |
|---|
| 138 | 135 | break; |
|---|
| .. | .. |
|---|
| 225 | 222 | static int ath79_gpio_probe(struct platform_device *pdev) |
|---|
| 226 | 223 | { |
|---|
| 227 | 224 | struct ath79_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); |
|---|
| 228 | | - struct device_node *np = pdev->dev.of_node; |
|---|
| 225 | + struct device *dev = &pdev->dev; |
|---|
| 226 | + struct device_node *np = dev->of_node; |
|---|
| 229 | 227 | struct ath79_gpio_ctrl *ctrl; |
|---|
| 230 | | - struct resource *res; |
|---|
| 228 | + struct gpio_irq_chip *girq; |
|---|
| 231 | 229 | u32 ath79_gpio_count; |
|---|
| 232 | 230 | bool oe_inverted; |
|---|
| 233 | 231 | int err; |
|---|
| 234 | 232 | |
|---|
| 235 | | - ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL); |
|---|
| 233 | + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); |
|---|
| 236 | 234 | if (!ctrl) |
|---|
| 237 | 235 | return -ENOMEM; |
|---|
| 238 | 236 | platform_set_drvdata(pdev, ctrl); |
|---|
| .. | .. |
|---|
| 240 | 238 | if (np) { |
|---|
| 241 | 239 | err = of_property_read_u32(np, "ngpios", &ath79_gpio_count); |
|---|
| 242 | 240 | if (err) { |
|---|
| 243 | | - dev_err(&pdev->dev, "ngpios property is not valid\n"); |
|---|
| 241 | + dev_err(dev, "ngpios property is not valid\n"); |
|---|
| 244 | 242 | return err; |
|---|
| 245 | 243 | } |
|---|
| 246 | 244 | oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio"); |
|---|
| .. | .. |
|---|
| 248 | 246 | ath79_gpio_count = pdata->ngpios; |
|---|
| 249 | 247 | oe_inverted = pdata->oe_inverted; |
|---|
| 250 | 248 | } else { |
|---|
| 251 | | - dev_err(&pdev->dev, "No DT node or platform data found\n"); |
|---|
| 249 | + dev_err(dev, "No DT node or platform data found\n"); |
|---|
| 252 | 250 | return -EINVAL; |
|---|
| 253 | 251 | } |
|---|
| 254 | 252 | |
|---|
| 255 | 253 | if (ath79_gpio_count >= 32) { |
|---|
| 256 | | - dev_err(&pdev->dev, "ngpios must be less than 32\n"); |
|---|
| 254 | + dev_err(dev, "ngpios must be less than 32\n"); |
|---|
| 257 | 255 | return -EINVAL; |
|---|
| 258 | 256 | } |
|---|
| 259 | 257 | |
|---|
| 260 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 261 | | - if (!res) |
|---|
| 262 | | - return -EINVAL; |
|---|
| 263 | | - ctrl->base = devm_ioremap_nocache( |
|---|
| 264 | | - &pdev->dev, res->start, resource_size(res)); |
|---|
| 265 | | - if (!ctrl->base) |
|---|
| 266 | | - return -ENOMEM; |
|---|
| 258 | + ctrl->base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 259 | + if (IS_ERR(ctrl->base)) |
|---|
| 260 | + return PTR_ERR(ctrl->base); |
|---|
| 267 | 261 | |
|---|
| 268 | 262 | raw_spin_lock_init(&ctrl->lock); |
|---|
| 269 | | - err = bgpio_init(&ctrl->gc, &pdev->dev, 4, |
|---|
| 263 | + err = bgpio_init(&ctrl->gc, dev, 4, |
|---|
| 270 | 264 | ctrl->base + AR71XX_GPIO_REG_IN, |
|---|
| 271 | 265 | ctrl->base + AR71XX_GPIO_REG_SET, |
|---|
| 272 | 266 | ctrl->base + AR71XX_GPIO_REG_CLEAR, |
|---|
| .. | .. |
|---|
| 274 | 268 | oe_inverted ? ctrl->base + AR71XX_GPIO_REG_OE : NULL, |
|---|
| 275 | 269 | 0); |
|---|
| 276 | 270 | if (err) { |
|---|
| 277 | | - dev_err(&pdev->dev, "bgpio_init failed\n"); |
|---|
| 271 | + dev_err(dev, "bgpio_init failed\n"); |
|---|
| 278 | 272 | return err; |
|---|
| 279 | 273 | } |
|---|
| 280 | 274 | /* Use base 0 to stay compatible with legacy platforms */ |
|---|
| 281 | 275 | ctrl->gc.base = 0; |
|---|
| 282 | 276 | |
|---|
| 283 | | - err = gpiochip_add_data(&ctrl->gc, ctrl); |
|---|
| 277 | + /* Optional interrupt setup */ |
|---|
| 278 | + if (!np || of_property_read_bool(np, "interrupt-controller")) { |
|---|
| 279 | + girq = &ctrl->gc.irq; |
|---|
| 280 | + girq->chip = &ath79_gpio_irqchip; |
|---|
| 281 | + girq->parent_handler = ath79_gpio_irq_handler; |
|---|
| 282 | + girq->num_parents = 1; |
|---|
| 283 | + girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), |
|---|
| 284 | + GFP_KERNEL); |
|---|
| 285 | + if (!girq->parents) |
|---|
| 286 | + return -ENOMEM; |
|---|
| 287 | + girq->parents[0] = platform_get_irq(pdev, 0); |
|---|
| 288 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 289 | + girq->handler = handle_simple_irq; |
|---|
| 290 | + } |
|---|
| 291 | + |
|---|
| 292 | + err = devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); |
|---|
| 284 | 293 | if (err) { |
|---|
| 285 | | - dev_err(&pdev->dev, |
|---|
| 294 | + dev_err(dev, |
|---|
| 286 | 295 | "cannot add AR71xx GPIO chip, error=%d", err); |
|---|
| 287 | 296 | return err; |
|---|
| 288 | 297 | } |
|---|
| 289 | | - |
|---|
| 290 | | - if (np && !of_property_read_bool(np, "interrupt-controller")) |
|---|
| 291 | | - return 0; |
|---|
| 292 | | - |
|---|
| 293 | | - err = gpiochip_irqchip_add(&ctrl->gc, &ath79_gpio_irqchip, 0, |
|---|
| 294 | | - handle_simple_irq, IRQ_TYPE_NONE); |
|---|
| 295 | | - if (err) { |
|---|
| 296 | | - dev_err(&pdev->dev, "failed to add gpiochip_irqchip\n"); |
|---|
| 297 | | - goto gpiochip_remove; |
|---|
| 298 | | - } |
|---|
| 299 | | - |
|---|
| 300 | | - gpiochip_set_chained_irqchip(&ctrl->gc, &ath79_gpio_irqchip, |
|---|
| 301 | | - platform_get_irq(pdev, 0), |
|---|
| 302 | | - ath79_gpio_irq_handler); |
|---|
| 303 | | - |
|---|
| 304 | | - return 0; |
|---|
| 305 | | - |
|---|
| 306 | | -gpiochip_remove: |
|---|
| 307 | | - gpiochip_remove(&ctrl->gc); |
|---|
| 308 | | - return err; |
|---|
| 309 | | -} |
|---|
| 310 | | - |
|---|
| 311 | | -static int ath79_gpio_remove(struct platform_device *pdev) |
|---|
| 312 | | -{ |
|---|
| 313 | | - struct ath79_gpio_ctrl *ctrl = platform_get_drvdata(pdev); |
|---|
| 314 | | - |
|---|
| 315 | | - gpiochip_remove(&ctrl->gc); |
|---|
| 316 | 298 | return 0; |
|---|
| 317 | 299 | } |
|---|
| 318 | 300 | |
|---|
| .. | .. |
|---|
| 322 | 304 | .of_match_table = ath79_gpio_of_match, |
|---|
| 323 | 305 | }, |
|---|
| 324 | 306 | .probe = ath79_gpio_probe, |
|---|
| 325 | | - .remove = ath79_gpio_remove, |
|---|
| 326 | 307 | }; |
|---|
| 327 | 308 | |
|---|
| 328 | 309 | module_platform_driver(ath79_gpio_driver); |
|---|