| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2011-2012 Avionic Design GmbH |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 6 | | - * published by the Free Software Foundation. |
|---|
| 7 | 4 | */ |
|---|
| 8 | 5 | |
|---|
| 9 | 6 | #include <linux/gpio/driver.h> |
|---|
| .. | .. |
|---|
| 241 | 238 | mutex_unlock(&adnp->i2c_lock); |
|---|
| 242 | 239 | } |
|---|
| 243 | 240 | |
|---|
| 244 | | -static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios) |
|---|
| 245 | | -{ |
|---|
| 246 | | - struct gpio_chip *chip = &adnp->gpio; |
|---|
| 247 | | - int err; |
|---|
| 248 | | - |
|---|
| 249 | | - adnp->reg_shift = get_count_order(num_gpios) - 3; |
|---|
| 250 | | - |
|---|
| 251 | | - chip->direction_input = adnp_gpio_direction_input; |
|---|
| 252 | | - chip->direction_output = adnp_gpio_direction_output; |
|---|
| 253 | | - chip->get = adnp_gpio_get; |
|---|
| 254 | | - chip->set = adnp_gpio_set; |
|---|
| 255 | | - chip->can_sleep = true; |
|---|
| 256 | | - |
|---|
| 257 | | - if (IS_ENABLED(CONFIG_DEBUG_FS)) |
|---|
| 258 | | - chip->dbg_show = adnp_gpio_dbg_show; |
|---|
| 259 | | - |
|---|
| 260 | | - chip->base = -1; |
|---|
| 261 | | - chip->ngpio = num_gpios; |
|---|
| 262 | | - chip->label = adnp->client->name; |
|---|
| 263 | | - chip->parent = &adnp->client->dev; |
|---|
| 264 | | - chip->of_node = chip->parent->of_node; |
|---|
| 265 | | - chip->owner = THIS_MODULE; |
|---|
| 266 | | - |
|---|
| 267 | | - err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp); |
|---|
| 268 | | - if (err) |
|---|
| 269 | | - return err; |
|---|
| 270 | | - |
|---|
| 271 | | - return 0; |
|---|
| 272 | | -} |
|---|
| 273 | | - |
|---|
| 274 | 241 | static irqreturn_t adnp_irq(int irq, void *data) |
|---|
| 275 | 242 | { |
|---|
| 276 | 243 | struct adnp *adnp = data; |
|---|
| .. | .. |
|---|
| 467 | 434 | return err; |
|---|
| 468 | 435 | } |
|---|
| 469 | 436 | |
|---|
| 470 | | - err = gpiochip_irqchip_add_nested(chip, |
|---|
| 471 | | - &adnp_irq_chip, |
|---|
| 472 | | - 0, |
|---|
| 473 | | - handle_simple_irq, |
|---|
| 474 | | - IRQ_TYPE_NONE); |
|---|
| 475 | | - if (err) { |
|---|
| 476 | | - dev_err(chip->parent, |
|---|
| 477 | | - "could not connect irqchip to gpiochip\n"); |
|---|
| 478 | | - return err; |
|---|
| 437 | + return 0; |
|---|
| 438 | +} |
|---|
| 439 | + |
|---|
| 440 | +static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios, |
|---|
| 441 | + bool is_irq_controller) |
|---|
| 442 | +{ |
|---|
| 443 | + struct gpio_chip *chip = &adnp->gpio; |
|---|
| 444 | + int err; |
|---|
| 445 | + |
|---|
| 446 | + adnp->reg_shift = get_count_order(num_gpios) - 3; |
|---|
| 447 | + |
|---|
| 448 | + chip->direction_input = adnp_gpio_direction_input; |
|---|
| 449 | + chip->direction_output = adnp_gpio_direction_output; |
|---|
| 450 | + chip->get = adnp_gpio_get; |
|---|
| 451 | + chip->set = adnp_gpio_set; |
|---|
| 452 | + chip->can_sleep = true; |
|---|
| 453 | + |
|---|
| 454 | + if (IS_ENABLED(CONFIG_DEBUG_FS)) |
|---|
| 455 | + chip->dbg_show = adnp_gpio_dbg_show; |
|---|
| 456 | + |
|---|
| 457 | + chip->base = -1; |
|---|
| 458 | + chip->ngpio = num_gpios; |
|---|
| 459 | + chip->label = adnp->client->name; |
|---|
| 460 | + chip->parent = &adnp->client->dev; |
|---|
| 461 | + chip->of_node = chip->parent->of_node; |
|---|
| 462 | + chip->owner = THIS_MODULE; |
|---|
| 463 | + |
|---|
| 464 | + if (is_irq_controller) { |
|---|
| 465 | + struct gpio_irq_chip *girq; |
|---|
| 466 | + |
|---|
| 467 | + err = adnp_irq_setup(adnp); |
|---|
| 468 | + if (err) |
|---|
| 469 | + return err; |
|---|
| 470 | + |
|---|
| 471 | + girq = &chip->irq; |
|---|
| 472 | + girq->chip = &adnp_irq_chip; |
|---|
| 473 | + /* This will let us handle the parent IRQ in the driver */ |
|---|
| 474 | + girq->parent_handler = NULL; |
|---|
| 475 | + girq->num_parents = 0; |
|---|
| 476 | + girq->parents = NULL; |
|---|
| 477 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 478 | + girq->handler = handle_simple_irq; |
|---|
| 479 | + girq->threaded = true; |
|---|
| 479 | 480 | } |
|---|
| 480 | 481 | |
|---|
| 481 | | - gpiochip_set_nested_irqchip(chip, &adnp_irq_chip, adnp->client->irq); |
|---|
| 482 | + err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp); |
|---|
| 483 | + if (err) |
|---|
| 484 | + return err; |
|---|
| 482 | 485 | |
|---|
| 483 | 486 | return 0; |
|---|
| 484 | 487 | } |
|---|
| .. | .. |
|---|
| 506 | 509 | mutex_init(&adnp->i2c_lock); |
|---|
| 507 | 510 | adnp->client = client; |
|---|
| 508 | 511 | |
|---|
| 509 | | - err = adnp_gpio_setup(adnp, num_gpios); |
|---|
| 512 | + err = adnp_gpio_setup(adnp, num_gpios, |
|---|
| 513 | + of_property_read_bool(np, "interrupt-controller")); |
|---|
| 510 | 514 | if (err) |
|---|
| 511 | 515 | return err; |
|---|
| 512 | | - |
|---|
| 513 | | - if (of_find_property(np, "interrupt-controller", NULL)) { |
|---|
| 514 | | - err = adnp_irq_setup(adnp); |
|---|
| 515 | | - if (err) |
|---|
| 516 | | - return err; |
|---|
| 517 | | - } |
|---|
| 518 | 516 | |
|---|
| 519 | 517 | i2c_set_clientdata(client, adnp); |
|---|
| 520 | 518 | |
|---|