diff options
Diffstat (limited to 'drivers/gpio/gpio-ath79.c')
-rw-r--r-- | drivers/gpio/gpio-ath79.c | 66 |
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); | |||
222 | static int ath79_gpio_probe(struct platform_device *pdev) | 222 | static 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 | |||
303 | gpiochip_remove: | ||
304 | gpiochip_remove(&ctrl->gc); | ||
305 | return err; | ||
306 | } | ||
307 | |||
308 | static 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 | ||
325 | module_platform_driver(ath79_gpio_driver); | 313 | module_platform_driver(ath79_gpio_driver); |