| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007 David Brownell |
|---|
| 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 as published by |
|---|
| 8 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 9 | | - * (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 12 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 13 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 14 | | - * GNU General Public License for more details. |
|---|
| 15 | | - * |
|---|
| 16 | | - * You should have received a copy of the GNU General Public License |
|---|
| 17 | | - * along with this program; if not, write to the Free Software |
|---|
| 18 | | - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 19 | 6 | */ |
|---|
| 20 | 7 | |
|---|
| 21 | 8 | #include <linux/gpio/driver.h> |
|---|
| .. | .. |
|---|
| 89 | 76 | struct mutex lock; /* protect 'out' */ |
|---|
| 90 | 77 | unsigned out; /* software latch */ |
|---|
| 91 | 78 | unsigned status; /* current status */ |
|---|
| 92 | | - unsigned int irq_parent; |
|---|
| 93 | 79 | unsigned irq_enabled; /* enabled irqs */ |
|---|
| 94 | 80 | |
|---|
| 95 | 81 | int (*write)(struct i2c_client *client, unsigned data); |
|---|
| .. | .. |
|---|
| 211 | 197 | { |
|---|
| 212 | 198 | struct pcf857x *gpio = irq_data_get_irq_chip_data(data); |
|---|
| 213 | 199 | |
|---|
| 214 | | - int error = 0; |
|---|
| 215 | | - |
|---|
| 216 | | - if (gpio->irq_parent) { |
|---|
| 217 | | - error = irq_set_irq_wake(gpio->irq_parent, on); |
|---|
| 218 | | - if (error) { |
|---|
| 219 | | - dev_dbg(&gpio->client->dev, |
|---|
| 220 | | - "irq %u doesn't support irq_set_wake\n", |
|---|
| 221 | | - gpio->irq_parent); |
|---|
| 222 | | - gpio->irq_parent = 0; |
|---|
| 223 | | - } |
|---|
| 224 | | - } |
|---|
| 225 | | - return error; |
|---|
| 200 | + return irq_set_irq_wake(gpio->client->irq, on); |
|---|
| 226 | 201 | } |
|---|
| 227 | 202 | |
|---|
| 228 | 203 | static void pcf857x_irq_enable(struct irq_data *data) |
|---|
| .. | .. |
|---|
| 359 | 334 | gpio->out = ~n_latch; |
|---|
| 360 | 335 | gpio->status = gpio->read(gpio->client); |
|---|
| 361 | 336 | |
|---|
| 362 | | - status = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); |
|---|
| 363 | | - if (status < 0) |
|---|
| 364 | | - goto fail; |
|---|
| 365 | | - |
|---|
| 366 | 337 | /* Enable irqchip if we have an interrupt */ |
|---|
| 367 | 338 | if (client->irq) { |
|---|
| 368 | | - gpio->irqchip.name = "pcf857x", |
|---|
| 369 | | - gpio->irqchip.irq_enable = pcf857x_irq_enable, |
|---|
| 370 | | - gpio->irqchip.irq_disable = pcf857x_irq_disable, |
|---|
| 371 | | - gpio->irqchip.irq_ack = noop, |
|---|
| 372 | | - gpio->irqchip.irq_mask = noop, |
|---|
| 373 | | - gpio->irqchip.irq_unmask = noop, |
|---|
| 374 | | - gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake, |
|---|
| 375 | | - gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock, |
|---|
| 376 | | - gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock, |
|---|
| 377 | | - status = gpiochip_irqchip_add_nested(&gpio->chip, |
|---|
| 378 | | - &gpio->irqchip, |
|---|
| 379 | | - 0, handle_level_irq, |
|---|
| 380 | | - IRQ_TYPE_NONE); |
|---|
| 381 | | - if (status) { |
|---|
| 382 | | - dev_err(&client->dev, "cannot add irqchip\n"); |
|---|
| 383 | | - goto fail; |
|---|
| 384 | | - } |
|---|
| 339 | + struct gpio_irq_chip *girq; |
|---|
| 340 | + |
|---|
| 341 | + gpio->irqchip.name = "pcf857x"; |
|---|
| 342 | + gpio->irqchip.irq_enable = pcf857x_irq_enable; |
|---|
| 343 | + gpio->irqchip.irq_disable = pcf857x_irq_disable; |
|---|
| 344 | + gpio->irqchip.irq_ack = noop; |
|---|
| 345 | + gpio->irqchip.irq_mask = noop; |
|---|
| 346 | + gpio->irqchip.irq_unmask = noop; |
|---|
| 347 | + gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake; |
|---|
| 348 | + gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock; |
|---|
| 349 | + gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock; |
|---|
| 385 | 350 | |
|---|
| 386 | 351 | status = devm_request_threaded_irq(&client->dev, client->irq, |
|---|
| 387 | 352 | NULL, pcf857x_irq, IRQF_ONESHOT | |
|---|
| .. | .. |
|---|
| 390 | 355 | if (status) |
|---|
| 391 | 356 | goto fail; |
|---|
| 392 | 357 | |
|---|
| 393 | | - gpiochip_set_nested_irqchip(&gpio->chip, &gpio->irqchip, |
|---|
| 394 | | - client->irq); |
|---|
| 395 | | - gpio->irq_parent = client->irq; |
|---|
| 358 | + girq = &gpio->chip.irq; |
|---|
| 359 | + girq->chip = &gpio->irqchip; |
|---|
| 360 | + /* This will let us handle the parent IRQ in the driver */ |
|---|
| 361 | + girq->parent_handler = NULL; |
|---|
| 362 | + girq->num_parents = 0; |
|---|
| 363 | + girq->parents = NULL; |
|---|
| 364 | + girq->default_type = IRQ_TYPE_NONE; |
|---|
| 365 | + girq->handler = handle_level_irq; |
|---|
| 366 | + girq->threaded = true; |
|---|
| 396 | 367 | } |
|---|
| 397 | 368 | |
|---|
| 369 | + status = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); |
|---|
| 370 | + if (status < 0) |
|---|
| 371 | + goto fail; |
|---|
| 372 | + |
|---|
| 398 | 373 | /* Let platform code set up the GPIOs and their users. |
|---|
| 399 | 374 | * Now is the first time anyone could use them. |
|---|
| 400 | 375 | */ |
|---|