Commit 06b49ea4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gpio-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO update from Linus Walleij:
 "This is the bulk of GPIO changes for the v3.17 development cycle, and
  this time we got a lot of action going on and it will continue:

   - The core GPIO library implementation has been split up in three
     different files:
     - gpiolib.c for the latest and greatest and shiny GPIO library code
       using GPIO descriptors only
     - gpiolib-legacy.c for the old integer number space API that we are
       phasing out gradually
     - gpiolib-sysfs.c for the sysfs interface that we are not entirely
       happy with, but has to live on for ABI compatibility

   - Add a flags argument to *gpiod_get* functions, with some
     backward-compatibility macros to ease transitions.  We should have
     had the flags there from the beginning it seems, now we need to
     clean up the mess.  There is a plan on how to move forward here
     devised by Alexandre Courbot and Mark Brown

   - Split off a special <linux/gpio/machine.h> header for the board
     gpio table registration, as per example from the regulator
     subsystem

   - Start to kill off the return value from gpiochip_remove() by
     removing the __must_check attribute and removing all checks inside
     the drivers/gpio directory.  The rationale is: well what were we
     supposed to do if there is an error code? Not much: print an error
     message.  And gpiolib already does that.  So make this function
     return void eventually

   - Some cleanups of hairy gpiolib code, make some functions not to be
     used outside the library private and make sure they are not
     exported, remove gpiod_lock/unlock_as_irq() as the existing
     function is for driver-internal use and fine as it is, delete
     gpio_ensure_requested() as it is not meaningful anymore

   - Support the GPIOF_ACTIVE_LOW flag from gpio_request_one() function
     calls, which is logical since this is already supported when
     referencing GPIOs from e.g. device trees

   - Switch STMPE, intel-mid, lynxpoint and ACPI (!) to use the gpiolib
     irqchip helpers cutting down on GPIO irqchip boilerplate a bit more

   - New driver for the Zynq GPIO block

   - The usual incremental improvements around a bunch of drivers

   - Janitorial syntactic and semantic cleanups by Jingoo Han, and
     Rickard Strandqvist especially"

* tag 'gpio-v3.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: (37 commits)
  MAINTAINERS: update GPIO include files
  gpio: add missing includes in machine.h
  gpio: add flags argument to gpiod_get*() functions
  MAINTAINERS: Update Samsung pin control entry
  gpio / ACPI: Move event handling registration to gpiolib irqchip helpers
  gpio: lynxpoint: Convert to use gpiolib irqchip
  gpio: split gpiod board registration into machine header
  gpio: remove gpio_ensure_requested()
  gpio: remove useless check in gpiolib_sysfs_init()
  gpiolib: Export gpiochip_request_own_desc and gpiochip_free_own_desc
  gpio: move gpio_ensure_requested() into legacy C file
  gpio: remove gpiod_lock/unlock_as_irq()
  gpio: make gpiochip_get_desc() gpiolib-private
  gpio: simplify gpiochip_export()
  gpio: remove export of private of_get_named_gpio_flags()
  gpio: Add support for GPIOF_ACTIVE_LOW to gpio_request_one functions
  gpio: zynq: Clear pending interrupt when enabling a IRQ
  gpio: drop retval check enforcing from gpiochip_remove()
  gpio: remove all usage of gpio_remove retval in driver/gpio
  devicetree: Add Zynq GPIO devicetree bindings documentation
  ...
parents 664fb230 bdc6e95e
Xilinx Zynq GPIO controller Device Tree Bindings
-------------------------------------------
Required properties:
- #gpio-cells : Should be two
- First cell is the GPIO line number
- Second cell is used to specify optional
parameters (unused)
- compatible : Should be "xlnx,zynq-gpio-1.0"
- clocks : Clock specifier (see clock bindings for details)
- gpio-controller : Marks the device node as a GPIO controller.
- interrupts : Interrupt specifier (see interrupt bindings for
details)
- interrupt-parent : Must be core interrupt controller
- reg : Address and length of the register set for the device
Example:
gpio@e000a000 {
#gpio-cells = <2>;
compatible = "xlnx,zynq-gpio-1.0";
clocks = <&clkc 42>;
gpio-controller;
interrupt-parent = <&intc>;
interrupts = <0 20 4>;
reg = <0xe000a000 0x1000>;
};
......@@ -60,7 +60,7 @@ Platform Data
Finally, GPIOs can be bound to devices and functions using platform data. Board
files that desire to do so need to include the following header:
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
GPIOs are mapped by the means of tables of lookups, containing instances of the
gpiod_lookup structure. Two macros are defined to help declaring such mappings:
......
......@@ -29,13 +29,24 @@ gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
device that will use the GPIO and the function the requested GPIO is supposed to
fulfill:
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,
enum gpiod_flags flags)
If a function is implemented by using several GPIOs together (e.g. a simple LED
device that displays digits), an additional index argument can be specified:
struct gpio_desc *gpiod_get_index(struct device *dev,
const char *con_id, unsigned int idx)
const char *con_id, unsigned int idx,
enum gpiod_flags flags)
The flags parameter is used to optionally specify a direction and initial value
for the GPIO. Values can be:
* GPIOD_ASIS or 0 to not initialize the GPIO at all. The direction must be set
later with one of the dedicated functions.
* GPIOD_IN to initialize the GPIO as input.
* GPIOD_OUT_LOW to initialize the GPIO as output with a value of 0.
* GPIOD_OUT_HIGH to initialize the GPIO as output with a value of 1.
Both functions return either a valid GPIO descriptor, or an error code checkable
with IS_ERR() (they will never return a NULL pointer). -ENOENT will be returned
......@@ -46,11 +57,13 @@ errors and an absence of GPIO for optional GPIO parameters.
Device-managed variants of these functions are also defined:
struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id,
enum gpiod_flags flags)
struct gpio_desc *devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx)
unsigned int idx,
enum gpiod_flags flags)
A GPIO descriptor can be disposed of using the gpiod_put() function:
......@@ -67,8 +80,9 @@ Using GPIOs
Setting Direction
-----------------
The first thing a driver must do with a GPIO is setting its direction. This is
done by invoking one of the gpiod_direction_*() functions:
The first thing a driver must do with a GPIO is setting its direction. If no
direction-setting flags have been given to gpiod_get*(), this is done by
invoking one of the gpiod_direction_*() functions:
int gpiod_direction_input(struct gpio_desc *desc)
int gpiod_direction_output(struct gpio_desc *desc, int value)
......
......@@ -157,13 +157,34 @@ Locking IRQ usage
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
to mark the GPIO as being used as an IRQ:
int gpiod_lock_as_irq(struct gpio_desc *desc)
int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
is released:
void gpiod_unlock_as_irq(struct gpio_desc *desc)
void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
When implementing an irqchip inside a GPIO driver, these two functions should
typically be called in the .startup() and .shutdown() callbacks from the
irqchip.
Requesting self-owned GPIO pins
-------------------------------
Sometimes it is useful to allow a GPIO chip driver to request its own GPIO
descriptors through the gpiolib API. Using gpio_request() for this purpose
does not help since it pins the module to the kernel forever (it calls
try_module_get()). A GPIO driver can use the following functions instead
to request and free descriptors without being pinned to the kernel forever.
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
void gpiochip_free_own_desc(struct gpio_desc *desc)
Descriptors requested with gpiochip_request_own_desc() must be released with
gpiochip_free_own_desc().
These functions must be used with care since they do not affect module use
count. Do not use the functions to request gpio descriptors not owned by the
calling driver.
......@@ -4031,7 +4031,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git
S: Maintained
F: Documentation/gpio/
F: drivers/gpio/
F: include/linux/gpio*
F: include/linux/gpio/
F: include/linux/gpio.h
F: include/asm-generic/gpio.h
GRE DEMULTIPLEXER DRIVER
......@@ -7002,9 +7003,7 @@ M: Thomas Abraham <thomas.abraham@linaro.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
S: Maintained
F: drivers/pinctrl/pinctrl-exynos.*
F: drivers/pinctrl/pinctrl-s3c*
F: drivers/pinctrl/pinctrl-samsung.*
F: drivers/pinctrl/samsung/
PIN CONTROLLER - ST SPEAR
M: Viresh Kumar <viresh.linux@gmail.com>
......
......@@ -15,7 +15,7 @@
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
......
......@@ -17,7 +17,7 @@
*
*/
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/platform_device.h>
#include <linux/rfkill-gpio.h>
......
......@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
......
......@@ -340,6 +340,13 @@ config GPIO_XILINX
help
Say yes here to support the Xilinx FPGA GPIO device
config GPIO_ZYNQ
tristate "Xilinx Zynq GPIO support"
depends on ARCH_ZYNQ
select GPIOLIB_IRQCHIP
help
Say yes here to support Xilinx Zynq GPIO controller.
config GPIO_XTENSA
bool "Xtensa GPIO32 support"
depends on XTENSA
......@@ -423,7 +430,7 @@ config GPIO_GE_FPGA
config GPIO_LYNXPOINT
tristate "Intel Lynxpoint GPIO support"
depends on ACPI && X86
select IRQ_DOMAIN
select GPIOLIB_IRQCHIP
help
driver for GPIO functionality on Intel Lynxpoint PCH chipset
Requires ACPI device enumeration code to set up a platform device.
......@@ -586,6 +593,7 @@ config GPIO_SX150X
config GPIO_STMPE
bool "STMPE GPIOs"
depends on MFD_STMPE
select GPIOLIB_IRQCHIP
help
This enables support for the GPIOs found on the STMPE I/O
Expanders.
......
......@@ -4,7 +4,9 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
obj-$(CONFIG_GPIO_DEVRES) += devres.o
obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_GPIOLIB) += gpiolib-legacy.o
obj-$(CONFIG_OF_GPIO) += gpiolib-of.o
obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o
obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o
# Device drivers. Generally keep list sorted alphabetically
......@@ -102,3 +104,4 @@ obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
obj-$(CONFIG_GPIO_XTENSA) += gpio-xtensa.o
obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o
obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o
......@@ -39,47 +39,53 @@ static int devm_gpiod_match(struct device *dev, void *res, void *data)
* devm_gpiod_get - Resource-managed gpiod_get()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @flags: optional GPIO initialization flags
*
* Managed gpiod_get(). GPIO descriptors returned from this function are
* automatically disposed on driver detach. See gpiod_get() for detailed
* information about behavior and return values.
*/
struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
const char *con_id)
struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
{
return devm_gpiod_get_index(dev, con_id, 0);
return devm_gpiod_get_index(dev, con_id, 0, flags);
}
EXPORT_SYMBOL(devm_gpiod_get);
EXPORT_SYMBOL(__devm_gpiod_get);
/**
* devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @flags: optional GPIO initialization flags
*
* Managed gpiod_get_optional(). GPIO descriptors returned from this function
* are automatically disposed on driver detach. See gpiod_get_optional() for
* detailed information about behavior and return values.
*/
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id)
struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags)
{
return devm_gpiod_get_index_optional(dev, con_id, 0);
return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
}
EXPORT_SYMBOL(devm_gpiod_get_optional);
EXPORT_SYMBOL(__devm_gpiod_get_optional);
/**
* devm_gpiod_get_index - Resource-managed gpiod_get_index()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @idx: index of the GPIO to obtain in the consumer
* @flags: optional GPIO initialization flags
*
* Managed gpiod_get_index(). GPIO descriptors returned from this function are
* automatically disposed on driver detach. See gpiod_get_index() for detailed
* information about behavior and return values.
*/
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx)
unsigned int idx,
enum gpiod_flags flags)
{
struct gpio_desc **dr;
struct gpio_desc *desc;
......@@ -89,7 +95,7 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
if (!dr)
return ERR_PTR(-ENOMEM);
desc = gpiod_get_index(dev, con_id, idx);
desc = gpiod_get_index(dev, con_id, idx, flags);
if (IS_ERR(desc)) {
devres_free(dr);
return desc;
......@@ -100,26 +106,28 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
return desc;
}
EXPORT_SYMBOL(devm_gpiod_get_index);
EXPORT_SYMBOL(__devm_gpiod_get_index);
/**
* devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @index: index of the GPIO to obtain in the consumer
* @flags: optional GPIO initialization flags
*
* Managed gpiod_get_index_optional(). GPIO descriptors returned from this
* function are automatically disposed on driver detach. See
* gpiod_get_index_optional() for detailed information about behavior and
* return values.
*/
struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
struct gpio_desc *__must_check __devm_gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index)
unsigned int index,
enum gpiod_flags flags)
{
struct gpio_desc *desc;
desc = devm_gpiod_get_index(dev, con_id, index);
desc = devm_gpiod_get_index(dev, con_id, index, flags);
if (IS_ERR(desc)) {
if (PTR_ERR(desc) == -ENOENT)
return NULL;
......@@ -127,7 +135,7 @@ struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
return desc;
}
EXPORT_SYMBOL(devm_gpiod_get_index_optional);
EXPORT_SYMBOL(__devm_gpiod_get_index_optional);
/**
* devm_gpiod_put - Resource-managed gpiod_put()
......
......@@ -167,13 +167,11 @@ static int gen_74x164_probe(struct spi_device *spi)
static int gen_74x164_remove(struct spi_device *spi)
{
struct gen_74x164_chip *chip = spi_get_drvdata(spi);
int ret;
ret = gpiochip_remove(&chip->gpio_chip);
if (!ret)
mutex_destroy(&chip->lock);
gpiochip_remove(&chip->gpio_chip);
mutex_destroy(&chip->lock);
return ret;
return 0;
}
static const struct of_device_id gen_74x164_dt_ids[] = {
......
......@@ -585,15 +585,8 @@ static int adnp_i2c_remove(struct i2c_client *client)
{
struct adnp *adnp = i2c_get_clientdata(client);
struct device_node *np = client->dev.of_node;
int err;
err = gpiochip_remove(&adnp->gpio);
if (err < 0) {
dev_err(&client->dev, "%s failed: %d\n", "gpiochip_remove()",
err);
return err;
}
gpiochip_remove(&adnp->gpio);
if (of_find_property(np, "interrupt-controller", NULL))
adnp_irq_teardown(adnp);
......
......@@ -167,15 +167,9 @@ static int adp5520_gpio_probe(struct platform_device *pdev)
static int adp5520_gpio_remove(struct platform_device *pdev)
{
struct adp5520_gpio *dev;
int ret;
dev = platform_get_drvdata(pdev);
ret = gpiochip_remove(&dev->gpio_chip);
if (ret) {
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", ret);
return ret;
}
gpiochip_remove(&dev->gpio_chip);
return 0;
}
......
......@@ -470,11 +470,7 @@ static int adp5588_gpio_remove(struct i2c_client *client)
if (dev->irq_base)
free_irq(dev->client->irq, dev);
ret = gpiochip_remove(&dev->gpio_chip);
if (ret) {
dev_err(&client->dev, "gpiochip_remove failed %d\n", ret);
return ret;
}
gpiochip_remove(&dev->gpio_chip);
kfree(dev);
return 0;
......
......@@ -232,8 +232,7 @@ static int __init amd_gpio_init(void)
static void __exit amd_gpio_exit(void)
{
int err = gpiochip_remove(&gp.chip);
WARN_ON(err);
gpiochip_remove(&gp.chip);
ioport_unmap(gp.pm);
release_region(gp.pmbase + PMBASE_OFFSET, PMBASE_SIZE);
}
......
......@@ -149,7 +149,8 @@ static int arizona_gpio_remove(struct platform_device *pdev)
{
struct arizona_gpio *arizona_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&arizona_gpio->gpio_chip);
gpiochip_remove(&arizona_gpio->gpio_chip);
return 0;
}
static struct platform_driver arizona_gpio_driver = {
......
......@@ -358,14 +358,8 @@ static int cs5535_gpio_probe(struct platform_device *pdev)
static int cs5535_gpio_remove(struct platform_device *pdev)
{
struct resource *r;
int err;
err = gpiochip_remove(&cs5535_gpio_chip.chip);
if (err) {
/* uhh? */
dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
return err;
}
gpiochip_remove(&cs5535_gpio_chip.chip);
r = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(r->start, resource_size(r));
......
......@@ -237,7 +237,8 @@ static int da9052_gpio_remove(struct platform_device *pdev)
{
struct da9052_gpio *gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&gpio->gp);
gpiochip_remove(&gpio->gp);
return 0;
}
static struct platform_driver da9052_gpio_driver = {
......
......@@ -174,7 +174,8 @@ static int da9055_gpio_remove(struct platform_device *pdev)
{
struct da9055_gpio *gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&gpio->gp);
gpiochip_remove(&gpio->gp);
return 0;
}
static struct platform_driver da9055_gpio_driver = {
......
......@@ -359,7 +359,7 @@ static void dwapb_gpio_unregister(struct dwapb_gpio *gpio)
for (m = 0; m < gpio->nr_ports; ++m)
if (gpio->ports[m].is_registered)
WARN_ON(gpiochip_remove(&gpio->ports[m].bgc.gc));
gpiochip_remove(&gpio->ports[m].bgc.gc);
}
static int dwapb_gpio_probe(struct platform_device *pdev)
......
......@@ -409,11 +409,8 @@ static int em_gio_probe(struct platform_device *pdev)
static int em_gio_remove(struct platform_device *pdev)
{
struct em_gio_priv *p = platform_get_drvdata(pdev);
int ret;
ret = gpiochip_remove(&p->gpio_chip);
if (ret)
return ret;
gpiochip_remove(&p->gpio_chip);
irq_domain_remove(p->irq_domain);
return 0;
......
......@@ -317,13 +317,7 @@ static int f7188x_gpio_probe(struct platform_device *pdev)
err_gpiochip:
for (i = i - 1; i >= 0; i--) {
struct f7188x_gpio_bank *bank = &data->bank[i];
int tmp;
tmp = gpiochip_remove(&bank->chip);
if (tmp < 0)
dev_err(&pdev->dev,
"Failed to remove gpiochip %d: %d\n",
i, tmp);
gpiochip_remove(&bank->chip);
}
return err;
......@@ -331,20 +325,12 @@ static int f7188x_gpio_probe(struct platform_device *pdev)
static int f7188x_gpio_remove(struct platform_device *pdev)
{
int err;
int i;
struct f7188x_gpio_data *data = platform_get_drvdata(pdev);
for (i = 0; i < data->nr_bank; i++) {
struct f7188x_gpio_bank *bank = &data->bank[i];
err = gpiochip_remove(&bank->chip);
if (err) {
dev_err(&pdev->dev,
"Failed to remove GPIO gpiochip %d: %d\n",
i, err);
return err;
}
gpiochip_remove(&bank->chip);
}
return 0;
......
......@@ -398,7 +398,8 @@ static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin)
int bgpio_remove(struct bgpio_chip *bgc)
{
return gpiochip_remove(&bgc->gc);
gpiochip_remove(&bgc->gc);
return 0;
}
EXPORT_SYMBOL_GPL(bgpio_remove);
......
......@@ -468,9 +468,7 @@ static int grgpio_remove(struct platform_device *ofdev)
}
}
ret = gpiochip_remove(&priv->bgc.gc);
if (ret)
goto out;
gpiochip_remove(&priv->bgc.gc);
if (priv->domain)
irq_domain_remove(priv->domain);
......
......@@ -514,14 +514,7 @@ static int ichx_gpio_probe(struct platform_device *pdev)
static int ichx_gpio_remove(struct platform_device *pdev)
{
int err;
err = gpiochip_remove(&ichx_priv.chip);
if (err) {
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", err);
return err;
}
gpiochip_remove(&ichx_priv.chip);
ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
if (ichx_priv.pm_base)
......
......@@ -28,12 +28,10 @@
#include <linux/stddef.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/gpio/driver.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/irqdomain.h>
#define INTEL_MID_IRQ_TYPE_EDGE (1 << 0)
#define INTEL_MID_IRQ_TYPE_LEVEL (1 << 1)
......@@ -78,10 +76,12 @@ struct intel_mid_gpio {
void __iomem *reg_base;
spinlock_t lock;
struct pci_dev *pdev;
struct irq_domain *domain;
};
#define to_intel_gpio_priv(chip) container_of(chip, struct intel_mid_gpio, chip)
static inline struct intel_mid_gpio *to_intel_gpio_priv(struct gpio_chip *gc)
{
return container_of(gc, struct intel_mid_gpio, chip);
}
static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
enum GPIO_REG reg_type)
......@@ -182,15 +182,10 @@ static int intel_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static int intel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct intel_mid_gpio *priv = to_intel_gpio_priv(chip);
return irq_create_mapping(priv->domain, offset);
}
static int intel_mid_irq_type(struct irq_data *d, unsigned type)
{
struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct intel_mid_gpio *priv = to_intel_gpio_priv(gc);
u32 gpio = irqd_to_hwirq(d);
unsigned long flags;
u32 value;
......@@ -231,33 +226,11 @@ static void intel_mid_irq_mask(struct irq_data *d)
{
}
static int intel_mid_irq_reqres(struct irq_data *d)
{
struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&priv->chip, irqd_to_hwirq(d))) {
dev_err(priv->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
return -EINVAL;
}
return 0;
}
static void intel_mid_irq_relres(struct irq_data *d)
{
struct intel_mid_gpio *priv = irq_data_get_irq_chip_data(d);
gpio_unlock_as_irq(&priv->chip, irqd_to_hwirq(d));
}
static struct irq_chip intel_mid_irqchip = {
.name = "INTEL_MID-GPIO",
.irq_mask = intel_mid_irq_mask,
.irq_unmask = intel_mid_irq_unmask,
.irq_set_type = intel_mid_irq_type,
.irq_request_resources = intel_mid_irq_reqres,
.irq_release_resources = intel_mid_irq_relres,
};
static const struct intel_mid_gpio_ddata gpio_lincroft = {
......@@ -330,8 +303,9 @@ MODULE_DEVICE_TABLE(pci, intel_gpio_ids);
static void intel_mid_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct intel_mid_gpio *priv = to_intel_gpio_priv(gc);
struct irq_data *data = irq_desc_get_irq_data(desc);
struct intel_mid_gpio *priv = irq_data_get_irq_handler_data(data);
struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, gpio, mask;
unsigned long pending;
......@@ -345,7 +319,7 @@ static void intel_mid_irq_handler(unsigned irq, struct irq_desc *desc)
mask = BIT(gpio);
/* Clear before handling so we can't lose an edge */
writel(mask, gedr);
generic_handle_irq(irq_find_mapping(priv->domain,
generic_handle_irq(irq_find_mapping(gc->irqdomain,
base + gpio));
}
}
......@@ -371,23 +345,6 @@ static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv)
}
}
static int intel_gpio_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
struct intel_mid_gpio *priv = d->host_data;
irq_set_chip_and_handler(irq, &intel_mid_irqchip, handle_simple_irq);
irq_set_chip_data(irq, priv);
irq_set_irq_type(irq, IRQ_TYPE_NONE);
return 0;
}
static const struct irq_domain_ops intel_gpio_irq_ops = {
.map = intel_gpio_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int intel_gpio_runtime_idle(struct device *dev)
{
int err = pm_schedule_suspend(dev, 500);
......@@ -441,7 +398,6 @@ static int intel_gpio_probe(struct pci_dev *pdev,
priv->chip.direction_output = intel_gpio_direction_output;
priv->chip.get = intel_gpio_get;
priv->chip.set = intel_gpio_set;
priv->chip.to_irq = intel_gpio_to_irq;
priv->chip.base = gpio_base;
priv->chip.ngpio = ddata->ngpio;
priv->chip.can_sleep = false;
......@@ -449,11 +405,6 @@ static int intel_gpio_probe(struct pci_dev *pdev,
spin_lock_init(&priv->lock);
priv->domain = irq_domain_add_simple(pdev->dev.of_node, ddata->ngpio,
irq_base, &intel_gpio_irq_ops, priv);
if (!priv->domain)
return -ENOMEM;
pci_set_drvdata(pdev, priv);
retval = gpiochip_add(&priv->chip);
if (retval) {
......@@ -461,10 +412,23 @@ static int intel_gpio_probe(struct pci_dev *pdev,
return retval;
}
retval = gpiochip_irqchip_add(&priv->chip,
&intel_mid_irqchip,
irq_base,
handle_simple_irq,
IRQ_TYPE_NONE);
if (retval) {
dev_err(&pdev->dev,
"could not connect irqchip to gpiochip\n");
return retval;
}
intel_mid_irq_init_hw(priv);
irq_set_handler_data(pdev->irq, priv);
irq_set_chained_handler(pdev->irq, intel_mid_irq_handler);
gpiochip_set_chained_irqchip(&priv->chip,
&intel_mid_irqchip,
pdev->irq,
intel_mid_irq_handler);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_allow(&pdev->dev);
......
......@@ -217,11 +217,7 @@ static int __init it8761e_gpio_init(void)
static void __exit it8761e_gpio_exit(void)
{
if (gpio_ba) {
int ret = gpiochip_remove(&it8761e_gpio_chip);
WARN(ret, "%s(): gpiochip_remove() failed, ret=%d\n",
__func__, ret);
gpiochip_remove(&it8761e_gpio_chip);
release_region(gpio_ba, GPIO_IOSIZE);
gpio_ba = 0;
}
......
......@@ -194,14 +194,8 @@ static int ttl_probe(struct platform_device *pdev)
static int ttl_remove(struct platform_device *pdev)
{
struct ttl_module *mod = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
int ret;
ret = gpiochip_remove(&mod->gpio);
if (ret) {
dev_err(dev, "unable to remove GPIO chip\n");
return ret;
}
gpiochip_remove(&mod->gpio);
return 0;
}
......
......@@ -199,7 +199,8 @@ static int kempld_gpio_remove(struct platform_device *pdev)
{
struct kempld_gpio_data *gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&gpio->chip);
gpiochip_remove(&gpio->chip);
return 0;
}
static struct platform_driver kempld_gpio_driver = {
......
......@@ -216,7 +216,8 @@ static int lp3943_gpio_remove(struct platform_device *pdev)
{
struct lp3943_gpio *lp3943_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&lp3943_gpio->chip);
gpiochip_remove(&lp3943_gpio->chip);
return 0;
}
static const struct of_device_id lp3943_gpio_of_match[] = {
......
......@@ -560,7 +560,7 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev)
}
#ifdef CONFIG_OF
static struct of_device_id lpc32xx_gpio_of_match[] = {
static const struct of_device_id lpc32xx_gpio_of_match[] = {
{ .compatible = "nxp,lpc3220-gpio", },
{ },
};
......
......@@ -25,9 +25,7 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
......@@ -62,7 +60,6 @@
struct lp_gpio {
struct gpio_chip chip;
struct irq_domain *domain;
struct platform_device *pdev;
spinlock_t lock;
unsigned long reg_base;
......@@ -151,7 +148,8 @@ static void lp_gpio_free(struct gpio_chip *chip, unsigned offset)
static int lp_irq_type(struct irq_data *d, unsigned type)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
u32 hwirq = irqd_to_hwirq(d);
unsigned long flags;
u32 value;
......@@ -236,16 +234,11 @@ static int lp_gpio_direction_output(struct gpio_chip *chip,
return 0;
}
static int lp_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct lp_gpio *lg = container_of(chip, struct lp_gpio, chip);
return irq_create_mapping(lg->domain, offset);
}
static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
{
struct irq_data *data = irq_desc_get_irq_data(desc);
struct lp_gpio *lg = irq_data_get_irq_handler_data(data);
struct gpio_chip *gc = irq_desc_get_handler_data(desc);
struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
struct irq_chip *chip = irq_data_get_irq_chip(data);
u32 base, pin, mask;
unsigned long reg, ena, pending;
......@@ -262,7 +255,7 @@ static void lp_gpio_irq_handler(unsigned hwirq, struct irq_desc *desc)
mask = BIT(pin);
/* Clear before handling so we don't lose an edge */
outl(mask, reg);
irq = irq_find_mapping(lg->domain, base + pin);
irq = irq_find_mapping(lg->chip.irqdomain, base + pin);
generic_handle_irq(irq);
}
}
......@@ -279,7 +272,8 @@ static void lp_irq_mask(struct irq_data *d)
static void lp_irq_enable(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
u32 hwirq = irqd_to_hwirq(d);
unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
unsigned long flags;
......@@ -291,7 +285,8 @@ static void lp_irq_enable(struct irq_data *d)
static void lp_irq_disable(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct lp_gpio *lg = container_of(gc, struct lp_gpio, chip);
u32 hwirq = irqd_to_hwirq(d);
unsigned long reg = lp_gpio_reg(&lg->chip, hwirq, LP_INT_ENABLE);
unsigned long flags;
......@@ -301,26 +296,6 @@ static void lp_irq_disable(struct irq_data *d)
spin_unlock_irqrestore(&lg->lock, flags);
}
static int lp_irq_reqres(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
if (gpio_lock_as_irq(&lg->chip, irqd_to_hwirq(d))) {
dev_err(lg->chip.dev,
"unable to lock HW IRQ %lu for IRQ\n",
irqd_to_hwirq(d));
return -EINVAL;
}
return 0;
}
static void lp_irq_relres(struct irq_data *d)
{
struct lp_gpio *lg = irq_data_get_irq_chip_data(d);
gpio_unlock_as_irq(&lg->chip, irqd_to_hwirq(d));
}
static struct irq_chip lp_irqchip = {
.name = "LP-GPIO",
.irq_mask = lp_irq_mask,
......@@ -328,8 +303,6 @@ static struct irq_chip lp_irqchip = {
.irq_enable = lp_irq_enable,
.irq_disable = lp_irq_disable,
.irq_set_type = lp_irq_type,
.irq_request_resources = lp_irq_reqres,
.irq_release_resources = lp_irq_relres,
.flags = IRQCHIP_SKIP_SET_WAKE,
};
......@@ -348,22 +321,6 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg)
}
}
static int lp_gpio_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
struct lp_gpio *lg = d->host_data;
irq_set_chip_and_handler(irq, &lp_irqchip, handle_simple_irq);
irq_set_chip_data(irq, lg);
irq_set_irq_type(irq, IRQ_TYPE_NONE);
return 0;
}
static const struct irq_domain_ops lp_gpio_irq_ops = {
.map = lp_gpio_irq_map,
};
static int lp_gpio_probe(struct platform_device *pdev)
{
struct lp_gpio *lg;
......@@ -371,7 +328,6 @@ static int lp_gpio_probe(struct platform_device *pdev)
struct resource *io_rc, *irq_rc;
struct device *dev = &pdev->dev;
unsigned long reg_len;
unsigned hwirq;
int ret = -ENODEV;
lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL);
......@@ -414,27 +370,28 @@ static int lp_gpio_probe(struct platform_device *pdev)
gc->can_sleep = false;
gc->dev = dev;
ret = gpiochip_add(gc);
if (ret) {
dev_err(dev, "failed adding lp-gpio chip\n");
return ret;
}
/* set up interrupts */
if (irq_rc && irq_rc->start) {
hwirq = irq_rc->start;
gc->to_irq = lp_gpio_to_irq;
lg->domain = irq_domain_add_linear(NULL, LP_NUM_GPIO,
&lp_gpio_irq_ops, lg);
if (!lg->domain)
return -ENXIO;
lp_gpio_irq_init_hw(lg);
ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0,
handle_simple_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(dev, "failed to add irqchip\n");
gpiochip_remove(gc);
return ret;
}
irq_set_handler_data(hwirq, lg);
irq_set_chained_handler(hwirq, lp_gpio_irq_handler);
gpiochip_set_chained_irqchip(gc, &lp_irqchip,
(unsigned)irq_rc->start,
lp_gpio_irq_handler);
}
ret = gpiochip_add(gc);
if (ret) {
dev_err(dev, "failed adding lp-gpio chip\n");
return ret;
}
pm_runtime_enable(dev);
return 0;
......@@ -465,11 +422,8 @@ MODULE_DEVICE_TABLE(acpi, lynxpoint_gpio_acpi_match);
static int lp_gpio_remove(struct platform_device *pdev)
{
struct lp_gpio *lg = platform_get_drvdata(pdev);
int err;
pm_runtime_disable(&pdev->dev);
err = gpiochip_remove(&lg->chip);
if (err)
dev_warn(&pdev->dev, "failed to remove gpio_chip.\n");
gpiochip_remove(&lg->chip);
return 0;
}
......
......@@ -228,21 +228,16 @@ EXPORT_SYMBOL_GPL(__max730x_probe);
int __max730x_remove(struct device *dev)
{
struct max7301 *ts = dev_get_drvdata(dev);
int ret;
if (ts == NULL)
return -ENODEV;
/* Power down the chip and disable IRQ output */
ts->write(dev, 0x04, 0x00);
ret = gpiochip_remove(&ts->chip);
if (!ret)
mutex_destroy(&ts->lock);
else
dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
return ret;
gpiochip_remove(&ts->chip);
mutex_destroy(&ts->lock);
kfree(ts);
return 0;
}
EXPORT_SYMBOL_GPL(__max730x_remove);
......
......@@ -676,12 +676,7 @@ static int max732x_remove(struct i2c_client *client)
}
}
ret = gpiochip_remove(&chip->gpio_chip);
if (ret) {
dev_err(&client->dev, "%s failed, %d\n",
"gpiochip_remove()", ret);
return ret;
}
gpiochip_remove(&chip->gpio_chip);
max732x_irq_teardown(chip);
......
......@@ -149,20 +149,15 @@ static int mc33880_probe(struct spi_device *spi)
static int mc33880_remove(struct spi_device *spi)
{
struct mc33880 *mc;
int ret;
mc = spi_get_drvdata(spi);
if (mc == NULL)
return -ENODEV;
ret = gpiochip_remove(&mc->chip);
if (!ret)
mutex_destroy(&mc->lock);
else
dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
ret);
gpiochip_remove(&mc->chip);
mutex_destroy(&mc->lock);
return ret;
return 0;
}
static struct spi_driver mc33880_driver = {
......
......@@ -118,7 +118,8 @@ static int mc9s08dz60_remove(struct i2c_client *client)
mc9s = i2c_get_clientdata(client);
return gpiochip_remove(&mc9s->chip);
gpiochip_remove(&mc9s->chip);
return 0;
}
static const struct i2c_device_id mc9s08dz60_id[] = {
......
......@@ -812,16 +812,14 @@ static int mcp230xx_probe(struct i2c_client *client,
static int mcp230xx_remove(struct i2c_client *client)
{
struct mcp23s08 *mcp = i2c_get_clientdata(client);
int status;
if (client->irq && mcp->irq_controller)
mcp23s08_irq_teardown(mcp);
status = gpiochip_remove(&mcp->chip);
if (status == 0)
kfree(mcp);
gpiochip_remove(&mcp->chip);
kfree(mcp);
return status;
return 0;
}
static const struct i2c_device_id mcp230xx_id[] = {
......@@ -960,13 +958,10 @@ static int mcp23s08_probe(struct spi_device *spi)
fail:
for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
int tmp;
if (!data->mcp[addr])
continue;
tmp = gpiochip_remove(&data->mcp[addr]->chip);
if (tmp < 0)
dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
gpiochip_remove(&data->mcp[addr]->chip);
}
kfree(data);
return status;
......@@ -976,23 +971,16 @@ static int mcp23s08_remove(struct spi_device *spi)
{
struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
unsigned addr;
int status = 0;
for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
int tmp;
if (!data->mcp[addr])
continue;
tmp = gpiochip_remove(&data->mcp[addr]->chip);
if (tmp < 0) {
dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
status = tmp;
}
gpiochip_remove(&data->mcp[addr]->chip);
}
if (status == 0)
kfree(data);
return status;
kfree(data);
return 0;
}
static const struct spi_device_id mcp23s08_ids[] = {
......
......@@ -497,8 +497,7 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
err_gpiochip_add:
while (--i >= 0) {
chip--;
if (gpiochip_remove(&chip->gpio))
dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i);
gpiochip_remove(&chip->gpio);
}
kfree(chip_save);
......@@ -519,7 +518,6 @@ static int ioh_gpio_probe(struct pci_dev *pdev,
static void ioh_gpio_remove(struct pci_dev *pdev)
{
int err;
int i;
struct ioh_gpio *chip = pci_get_drvdata(pdev);
void *chip_save;
......@@ -530,9 +528,7 @@ static void ioh_gpio_remove(struct pci_dev *pdev)
for (i = 0; i < 8; i++, chip++) {
irq_free_descs(chip->irq_base, num_ports[i]);
err = gpiochip_remove(&chip->gpio);
if (err)
dev_err(&pdev->dev, "Failed gpiochip_remove\n");
gpiochip_remove(&chip->gpio);
}
chip = chip_save;
......
......@@ -438,10 +438,7 @@ MODULE_DEVICE_TABLE(of, msm_gpio_of_match);
static int msm_gpio_remove(struct platform_device *dev)
{
int ret = gpiochip_remove(&msm_gpio.gpio_chip);
if (ret < 0)
return ret;
gpiochip_remove(&msm_gpio.gpio_chip);
irq_set_handler(msm_gpio.summary_irq, NULL);
......
......@@ -485,7 +485,7 @@ static int mxc_gpio_probe(struct platform_device *pdev)
out_irqdesc_free:
irq_free_descs(irq_base, 32);
out_gpiochip_remove:
WARN_ON(gpiochip_remove(&port->bgc.gc) < 0);
gpiochip_remove(&port->bgc.gc);
out_bgpio_remove:
bgpio_remove(&port->bgc);
out_bgio:
......
......@@ -129,7 +129,8 @@ static int octeon_gpio_probe(struct platform_device *pdev)
static int octeon_gpio_remove(struct platform_device *pdev)
{
struct gpio_chip *chip = pdev->dev.platform_data;
return gpiochip_remove(chip);
gpiochip_remove(chip);
return 0;
}
static struct of_device_id octeon_gpio_match[] = {
......
This diff is collapsed.
......@@ -210,7 +210,8 @@ static int palmas_gpio_remove(struct platform_device *pdev)
{
struct palmas_gpio *palmas_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&palmas_gpio->gpio_chip);
gpiochip_remove(&palmas_gpio->gpio_chip);
return 0;
}
static struct platform_driver palmas_gpio_driver = {
......
......@@ -765,12 +765,7 @@ static int pca953x_remove(struct i2c_client *client)
}
}
ret = gpiochip_remove(&chip->gpio_chip);
if (ret) {
dev_err(&client->dev, "%s failed, %d\n",
"gpiochip_remove()", ret);
return ret;
}
gpiochip_remove(&chip->gpio_chip);
return 0;
}
......
......@@ -444,9 +444,7 @@ static int pcf857x_remove(struct i2c_client *client)
if (client->irq)
pcf857x_irq_domain_cleanup(gpio);
status = gpiochip_remove(&gpio->chip);
if (status)
dev_err(&client->dev, "%s --> %d\n", "remove", status);
gpiochip_remove(&gpio->chip);
return status;
}
......
......@@ -426,9 +426,7 @@ static int pch_gpio_probe(struct pci_dev *pdev,
err_request_irq:
irq_free_descs(irq_base, gpio_pins[chip->ioh]);
if (gpiochip_remove(&chip->gpio))
dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
gpiochip_remove(&chip->gpio);
err_gpiochip_add:
pci_iounmap(pdev, chip->base);
......@@ -447,7 +445,6 @@ static int pch_gpio_probe(struct pci_dev *pdev,
static void pch_gpio_remove(struct pci_dev *pdev)
{
int err;
struct pch_gpio *chip = pci_get_drvdata(pdev);
if (chip->irq_base != -1) {
......@@ -456,10 +453,7 @@ static void pch_gpio_remove(struct pci_dev *pdev)
irq_free_descs(chip->irq_base, gpio_pins[chip->ioh]);
}
err = gpiochip_remove(&chip->gpio);
if (err)
dev_err(&pdev->dev, "Failed gpiochip_remove\n");
gpiochip_remove(&chip->gpio);
pci_iounmap(pdev, chip->base);
pci_release_regions(pdev);
pci_disable_device(pdev);
......
......@@ -498,7 +498,7 @@ static int pxa_gpio_nums(struct platform_device *pdev)
}
#ifdef CONFIG_OF
static struct of_device_id pxa_gpio_dt_ids[] = {
static const struct of_device_id pxa_gpio_dt_ids[] = {
{ .compatible = "intel,pxa25x-gpio", .data = &pxa25x_id, },
{ .compatible = "intel,pxa26x-gpio", .data = &pxa26x_id, },
{ .compatible = "intel,pxa27x-gpio", .data = &pxa27x_id, },
......@@ -649,6 +649,11 @@ static int pxa_gpio_probe(struct platform_device *pdev)
handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
} else {
if (irq0 > 0)
irq_set_chained_handler(irq0, pxa_gpio_demux_handler);
if (irq1 > 0)
irq_set_chained_handler(irq1, pxa_gpio_demux_handler);
}
irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler);
......
......@@ -148,7 +148,8 @@ static int rc5t583_gpio_remove(struct platform_device *pdev)
{
struct rc5t583_gpio *rc5t583_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&rc5t583_gpio->gpio_chip);
gpiochip_remove(&rc5t583_gpio->gpio_chip);
return 0;
}
static struct platform_driver rc5t583_gpio_driver = {
......
......@@ -240,9 +240,9 @@ static int gpio_rcar_get(struct gpio_chip *chip, unsigned offset)
/* testing on r8a7790 shows that INDT does not show correct pin state
* when configured as output, so use OUTDT in case of output pins */
if (gpio_rcar_read(gpio_to_priv(chip), INOUTSEL) & bit)
return (int)(gpio_rcar_read(gpio_to_priv(chip), OUTDT) & bit);
return !!(gpio_rcar_read(gpio_to_priv(chip), OUTDT) & bit);
else
return (int)(gpio_rcar_read(gpio_to_priv(chip), INDT) & bit);
return !!(gpio_rcar_read(gpio_to_priv(chip), INDT) & bit);
}
static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value)
......@@ -472,11 +472,8 @@ static int gpio_rcar_probe(struct platform_device *pdev)
static int gpio_rcar_remove(struct platform_device *pdev)
{
struct gpio_rcar_priv *p = platform_get_drvdata(pdev);
int ret;
ret = gpiochip_remove(&p->gpio_chip);
if (ret)
return ret;
gpiochip_remove(&p->gpio_chip);
irq_domain_remove(p->irq_domain);
pm_runtime_put(&pdev->dev);
......
......@@ -199,14 +199,11 @@ static int rdc321x_gpio_probe(struct platform_device *pdev)
static int rdc321x_gpio_remove(struct platform_device *pdev)
{
int ret;
struct rdc321x_gpio *rdc321x_gpio_dev = platform_get_drvdata(pdev);
ret = gpiochip_remove(&rdc321x_gpio_dev->chip);
if (ret)
dev_err(&pdev->dev, "failed to unregister chip\n");
gpiochip_remove(&rdc321x_gpio_dev->chip);
return ret;
return 0;
}
static struct platform_driver rdc321x_gpio_driver = {
......
......@@ -290,8 +290,7 @@ static int sch_gpio_probe(struct platform_device *pdev)
return 0;
err_sch_gpio_resume:
if (gpiochip_remove(&sch_gpio_core))
dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
gpiochip_remove(&sch_gpio_core);
err_sch_gpio_core:
release_region(res->start, resource_size(res));
......@@ -304,23 +303,14 @@ static int sch_gpio_remove(struct platform_device *pdev)
{
struct resource *res;
if (gpio_ba) {
int err;
err = gpiochip_remove(&sch_gpio_core);
if (err)
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", err);
err = gpiochip_remove(&sch_gpio_resume);
if (err)
dev_err(&pdev->dev, "%s failed, %d\n",
"gpiochip_remove()", err);
gpiochip_remove(&sch_gpio_core);
gpiochip_remove(&sch_gpio_resume);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, resource_size(res));
gpio_ba = 0;
return err;
}
return 0;
......
......@@ -291,14 +291,12 @@ static int sch311x_gpio_remove(struct platform_device *pdev)
{
struct sch311x_pdev_data *pdata = pdev->dev.platform_data;
struct sch311x_gpio_priv *priv = platform_get_drvdata(pdev);
int err, i;
int i;
release_region(pdata->runtime_reg + GP1, 6);
for (i = 0; i < ARRAY_SIZE(priv->blocks); i++) {
err = gpiochip_remove(&priv->blocks[i].chip);
if (err)
return err;
gpiochip_remove(&priv->blocks[i].chip);
dev_info(&pdev->dev,
"SMSC SCH311x GPIO block %d unregistered.\n", i);
}
......
......@@ -265,9 +265,7 @@ static void sdv_gpio_remove(struct pci_dev *pdev)
free_irq(pdev->irq, sd);
irq_free_descs(sd->irq_base, SDV_NUM_PUB_GPIOS);
if (gpiochip_remove(&sd->bgpio.gc))
dev_err(&pdev->dev, "gpiochip_remove() failed.\n");
gpiochip_remove(&sd->bgpio.gc);
pci_release_region(pdev, GPIO_BAR);
iounmap(sd->gpio_pub_base);
pci_disable_device(pdev);
......
......@@ -10,8 +10,6 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/mfd/stmpe.h>
......@@ -31,9 +29,7 @@ struct stmpe_gpio {
struct stmpe *stmpe;
struct device *dev;
struct mutex irq_lock;
struct irq_domain *domain;
unsigned norequest_mask;
/* Caches of interrupt control registers for bus_lock */
u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS];
......@@ -101,13 +97,6 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip,
return stmpe_set_bits(stmpe, reg, mask, 0);
}
static int stmpe_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip);
return irq_create_mapping(stmpe_gpio->domain, offset);
}
static int stmpe_gpio_request(struct gpio_chip *chip, unsigned offset)
{
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(chip);
......@@ -126,14 +115,14 @@ static struct gpio_chip template_chip = {
.get = stmpe_gpio_get,
.direction_output = stmpe_gpio_direction_output,
.set = stmpe_gpio_set,
.to_irq = stmpe_gpio_to_irq,
.request = stmpe_gpio_request,
.can_sleep = true,
};
static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
......@@ -160,14 +149,16 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
static void stmpe_gpio_irq_lock(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc);
mutex_lock(&stmpe_gpio->irq_lock);
}
static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc);
struct stmpe *stmpe = stmpe_gpio->stmpe;
int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8);
static const u8 regmap[] = {
......@@ -200,7 +191,8 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
static void stmpe_gpio_irq_mask(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
......@@ -210,7 +202,8 @@ static void stmpe_gpio_irq_mask(struct irq_data *d)
static void stmpe_gpio_irq_unmask(struct irq_data *d)
{
struct stmpe_gpio *stmpe_gpio = irq_data_get_irq_chip_data(d);
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct stmpe_gpio *stmpe_gpio = to_stmpe_gpio(gc);
int offset = d->hwirq;
int regoffset = offset / 8;
int mask = 1 << (offset % 8);
......@@ -253,7 +246,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
while (stat) {
int bit = __ffs(stat);
int line = bank * 8 + bit;
int child_irq = irq_find_mapping(stmpe_gpio->domain,
int child_irq = irq_find_mapping(stmpe_gpio->chip.irqdomain,
line);
handle_nested_irq(child_irq);
......@@ -271,56 +264,6 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
return IRQ_HANDLED;
}
static int stmpe_gpio_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
struct stmpe_gpio *stmpe_gpio = d->host_data;
if (!stmpe_gpio)
return -EINVAL;
irq_set_chip_data(irq, stmpe_gpio);
irq_set_chip_and_handler(irq, &stmpe_gpio_irq_chip,
handle_simple_irq);
irq_set_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
return 0;
}
static void stmpe_gpio_irq_unmap(struct irq_domain *d, unsigned int irq)
{
#ifdef CONFIG_ARM
set_irq_flags(irq, 0);
#endif
irq_set_chip_and_handler(irq, NULL, NULL);
irq_set_chip_data(irq, NULL);
}
static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = {
.unmap = stmpe_gpio_irq_unmap,
.map = stmpe_gpio_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio,
struct device_node *np)
{
stmpe_gpio->domain = irq_domain_add_simple(np,
stmpe_gpio->chip.ngpio, 0,
&stmpe_gpio_irq_simple_ops, stmpe_gpio);
if (!stmpe_gpio->domain) {
dev_err(stmpe_gpio->dev, "failed to create irqdomain\n");
return -ENOSYS;
}
return 0;
}
static int stmpe_gpio_probe(struct platform_device *pdev)
{
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
......@@ -358,30 +301,37 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
if (irq < 0)
dev_info(&pdev->dev,
"device configured in no-irq mode; "
"device configured in no-irq mode: "
"irqs are not available\n");
ret = stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
if (ret)
goto out_free;
if (irq >= 0) {
ret = stmpe_gpio_irq_init(stmpe_gpio, np);
if (ret)
goto out_disable;
ret = request_threaded_irq(irq, NULL, stmpe_gpio_irq,
IRQF_ONESHOT, "stmpe-gpio", stmpe_gpio);
if (irq > 0) {
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
stmpe_gpio_irq, IRQF_ONESHOT,
"stmpe-gpio", stmpe_gpio);
if (ret) {
dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
goto out_disable;
}
ret = gpiochip_irqchip_add(&stmpe_gpio->chip,
&stmpe_gpio_irq_chip,
0,
handle_simple_irq,
IRQ_TYPE_NONE);
if (ret) {
dev_err(&pdev->dev,
"could not connect irqchip to gpiochip\n");
return ret;
}
}
ret = gpiochip_add(&stmpe_gpio->chip);
if (ret) {
dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret);
goto out_freeirq;
goto out_disable;
}
if (pdata && pdata->setup)
......@@ -391,9 +341,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
return 0;
out_freeirq:
if (irq >= 0)
free_irq(irq, stmpe_gpio);
out_disable:
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
out_free:
......@@ -406,24 +353,14 @@ static int stmpe_gpio_remove(struct platform_device *pdev)
struct stmpe_gpio *stmpe_gpio = platform_get_drvdata(pdev);
struct stmpe *stmpe = stmpe_gpio->stmpe;
struct stmpe_gpio_platform_data *pdata = stmpe->pdata->gpio;
int irq = platform_get_irq(pdev, 0);
int ret;
if (pdata && pdata->remove)
pdata->remove(stmpe, stmpe_gpio->chip.base);
ret = gpiochip_remove(&stmpe_gpio->chip);
if (ret < 0) {
dev_err(stmpe_gpio->dev,
"unable to remove gpiochip: %d\n", ret);
return ret;
}
gpiochip_remove(&stmpe_gpio->chip);
stmpe_disable(stmpe, STMPE_BLOCK_GPIO);
if (irq >= 0)
free_irq(irq, stmpe_gpio);
kfree(stmpe_gpio);
return 0;
......
......@@ -615,19 +615,16 @@ static int sx150x_probe(struct i2c_client *client,
return 0;
probe_fail_post_gpiochip_add:
WARN_ON(gpiochip_remove(&chip->gpio_chip) < 0);
gpiochip_remove(&chip->gpio_chip);
return rc;
}
static int sx150x_remove(struct i2c_client *client)
{
struct sx150x_chip *chip;
int rc;
chip = i2c_get_clientdata(client);
rc = gpiochip_remove(&chip->gpio_chip);
if (rc < 0)
return rc;
gpiochip_remove(&chip->gpio_chip);
if (chip->irq_summary >= 0)
sx150x_remove_irq_chip(chip);
......
......@@ -172,7 +172,8 @@ static int syscon_gpio_remove(struct platform_device *pdev)
{
struct syscon_gpio_priv *priv = platform_get_drvdata(pdev);
return gpiochip_remove(&priv->chip);
gpiochip_remove(&priv->chip);
return 0;
}
static struct platform_driver syscon_gpio_driver = {
......
......@@ -291,7 +291,6 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
static int __exit tb10x_gpio_remove(struct platform_device *pdev)
{
struct tb10x_gpio *tb10x_gpio = platform_get_drvdata(pdev);
int ret;
if (tb10x_gpio->gc.to_irq) {
irq_remove_generic_chip(tb10x_gpio->domain->gc->gc[0],
......@@ -300,9 +299,7 @@ static int __exit tb10x_gpio_remove(struct platform_device *pdev)
irq_domain_remove(tb10x_gpio->domain);
free_irq(tb10x_gpio->irq, tb10x_gpio);
}
ret = gpiochip_remove(&tb10x_gpio->gc);
if (ret)
return ret;
gpiochip_remove(&tb10x_gpio->gc);
return 0;
}
......
......@@ -313,17 +313,11 @@ static int tc3589x_gpio_remove(struct platform_device *pdev)
struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev);
struct tc3589x *tc3589x = tc3589x_gpio->tc3589x;
struct tc3589x_gpio_platform_data *pdata = tc3589x->pdata->gpio;
int ret;
if (pdata && pdata->remove)
pdata->remove(tc3589x, tc3589x_gpio->chip.base);
ret = gpiochip_remove(&tc3589x_gpio->chip);
if (ret < 0) {
dev_err(tc3589x_gpio->dev,
"unable to remove gpiochip: %d\n", ret);
return ret;
}
gpiochip_remove(&tc3589x_gpio->chip);
return 0;
}
......
......@@ -307,7 +307,6 @@ static int timbgpio_probe(struct platform_device *pdev)
static int timbgpio_remove(struct platform_device *pdev)
{
int err;
struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct timbgpio *tgpio = platform_get_drvdata(pdev);
int irq = platform_get_irq(pdev, 0);
......@@ -323,9 +322,7 @@ static int timbgpio_remove(struct platform_device *pdev)
irq_set_handler_data(irq, NULL);
}
err = gpiochip_remove(&tgpio->gpio);
if (err)
printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n");
gpiochip_remove(&tgpio->gpio);
return 0;
}
......
......@@ -137,7 +137,8 @@ static int tps6586x_gpio_remove(struct platform_device *pdev)
{
struct tps6586x_gpio *tps6586x_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&tps6586x_gpio->gpio_chip);
gpiochip_remove(&tps6586x_gpio->gpio_chip);
return 0;
}
static struct platform_driver tps6586x_gpio_driver = {
......
......@@ -190,7 +190,8 @@ static int tps65910_gpio_remove(struct platform_device *pdev)
{
struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&tps65910_gpio->gpio_chip);
gpiochip_remove(&tps65910_gpio->gpio_chip);
return 0;
}
static struct platform_driver tps65910_gpio_driver = {
......
......@@ -117,7 +117,8 @@ static int tps65912_gpio_remove(struct platform_device *pdev)
{
struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&tps65912_gpio->gpio_chip);
gpiochip_remove(&tps65912_gpio->gpio_chip);
return 0;
}
static struct platform_driver tps65912_gpio_driver = {
......
......@@ -427,8 +427,7 @@ static int ts5500_dio_probe(struct platform_device *pdev)
return 0;
cleanup:
if (gpiochip_remove(&priv->gpio_chip))
dev_err(dev, "failed to remove gpio chip\n");
gpiochip_remove(&priv->gpio_chip);
return ret;
}
......@@ -437,7 +436,8 @@ static int ts5500_dio_remove(struct platform_device *pdev)
struct ts5500_priv *priv = platform_get_drvdata(pdev);
ts5500_disable_irq(priv);
return gpiochip_remove(&priv->gpio_chip);
gpiochip_remove(&priv->gpio_chip);
return 0;
}
static struct platform_device_id ts5500_dio_ids[] = {
......
......@@ -554,7 +554,7 @@ static int gpio_twl4030_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
if (pdata && pdata->setup) {
if (pdata->setup) {
int status;
status = pdata->setup(&pdev->dev, priv->gpio_chip.base,
......@@ -583,9 +583,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
}
}
status = gpiochip_remove(&priv->gpio_chip);
if (status < 0)
return status;
gpiochip_remove(&priv->gpio_chip);
if (is_module())
return 0;
......
......@@ -111,7 +111,8 @@ static int gpo_twl6040_probe(struct platform_device *pdev)
static int gpo_twl6040_remove(struct platform_device *pdev)
{
return gpiochip_remove(&twl6040gpo_chip);
gpiochip_remove(&twl6040gpo_chip);
return 0;
}
/* Note: this hardware lives inside an I2C-based multi-function device. */
......
......@@ -70,7 +70,7 @@ static int ucb1400_gpio_probe(struct platform_device *dev)
if (err)
goto err;
if (ucb && ucb->gpio_setup)
if (ucb->gpio_setup)
err = ucb->gpio_setup(&dev->dev, ucb->gc.ngpio);
err:
......@@ -89,7 +89,7 @@ static int ucb1400_gpio_remove(struct platform_device *dev)
return err;
}
err = gpiochip_remove(&ucb->gc);
gpiochip_remove(&ucb->gc);
return err;
}
......
......@@ -446,8 +446,7 @@ static int vprbrd_gpio_probe(struct platform_device *pdev)
return ret;
err_gpiob:
if (gpiochip_remove(&vb_gpio->gpioa))
dev_err(&pdev->dev, "%s gpiochip_remove failed\n", __func__);
gpiochip_remove(&vb_gpio->gpioa);
err_gpioa:
return ret;
......@@ -456,13 +455,10 @@ static int vprbrd_gpio_probe(struct platform_device *pdev)
static int vprbrd_gpio_remove(struct platform_device *pdev)
{
struct vprbrd_gpio *vb_gpio = platform_get_drvdata(pdev);
int ret;
ret = gpiochip_remove(&vb_gpio->gpiob);
if (ret == 0)
ret = gpiochip_remove(&vb_gpio->gpioa);
gpiochip_remove(&vb_gpio->gpiob);
return ret;
return 0;
}
static struct platform_driver vprbrd_gpio_driver = {
......
......@@ -515,7 +515,7 @@ static int giu_probe(struct platform_device *pdev)
struct resource *res;
unsigned int trigger, i, pin;
struct irq_chip *chip;
int irq, retval;
int irq, ret;
switch (pdev->id) {
case GPIO_50PINS_PULLUPDOWN:
......@@ -544,7 +544,11 @@ static int giu_probe(struct platform_device *pdev)
vr41xx_gpio_chip.dev = &pdev->dev;
retval = gpiochip_add(&vr41xx_gpio_chip);
ret = gpiochip_add(&vr41xx_gpio_chip);
if (!ret) {
iounmap(giu_base);
return -ENODEV;
}
giu_write(GIUINTENL, 0);
giu_write(GIUINTENH, 0);
......
......@@ -288,8 +288,7 @@ static int vx855gpio_remove(struct platform_device *pdev)
struct vx855_gpio *vg = platform_get_drvdata(pdev);
struct resource *res;
if (gpiochip_remove(&vg->gpio))
dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
gpiochip_remove(&vg->gpio);
if (vg->gpi_reserved) {
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
......
......@@ -279,7 +279,8 @@ static int wm831x_gpio_remove(struct platform_device *pdev)
{
struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&wm831x_gpio->gpio_chip);
gpiochip_remove(&wm831x_gpio->gpio_chip);
return 0;
}
static struct platform_driver wm831x_gpio_driver = {
......
......@@ -145,7 +145,8 @@ static int wm8350_gpio_remove(struct platform_device *pdev)
{
struct wm8350_gpio_data *wm8350_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&wm8350_gpio->gpio_chip);
gpiochip_remove(&wm8350_gpio->gpio_chip);
return 0;
}
static struct platform_driver wm8350_gpio_driver = {
......
......@@ -285,7 +285,8 @@ static int wm8994_gpio_remove(struct platform_device *pdev)
{
struct wm8994_gpio *wm8994_gpio = platform_get_drvdata(pdev);
return gpiochip_remove(&wm8994_gpio->gpio_chip);
gpiochip_remove(&wm8994_gpio->gpio_chip);
return 0;
}
static struct platform_driver wm8994_gpio_driver = {
......
This diff is collapsed.
......@@ -157,7 +157,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
gpiod_direction_input(desc);
ret = gpiod_lock_as_irq(desc);
ret = gpio_lock_as_irq(chip, pin);
if (ret) {
dev_err(chip->dev, "Failed to lock GPIO as interrupt\n");
goto fail_free_desc;
......@@ -212,7 +212,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
fail_free_event:
kfree(event);
fail_unlock_irq:
gpiod_unlock_as_irq(desc);
gpio_unlock_as_irq(chip, pin);
fail_free_desc:
gpiochip_free_own_desc(desc);
......@@ -221,7 +221,7 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
/**
* acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events
* @acpi_gpio: ACPI GPIO chip
* @chip: GPIO chip
*
* ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are
* handled by ACPI event methods which need to be called from the GPIO
......@@ -229,11 +229,21 @@ static acpi_status acpi_gpiochip_request_interrupt(struct acpi_resource *ares,
* gpio pins have acpi event methods and assigns interrupt handlers that calls
* the acpi event methods for those pins.
*/
static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
void acpi_gpiochip_request_interrupts(struct gpio_chip *chip)
{
struct gpio_chip *chip = acpi_gpio->chip;
struct acpi_gpio_chip *acpi_gpio;
acpi_handle handle;
acpi_status status;
if (!chip->dev || !chip->to_irq)
return;
if (!chip->to_irq)
handle = ACPI_HANDLE(chip->dev);
if (!handle)
return;
status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
if (ACPI_FAILURE(status))
return;
INIT_LIST_HEAD(&acpi_gpio->events);
......@@ -243,17 +253,27 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
/**
* acpi_gpiochip_free_interrupts() - Free GPIO ACPI event interrupts.
* @acpi_gpio: ACPI GPIO chip
* @chip: GPIO chip
*
* Free interrupts associated with GPIO ACPI event method for the given
* GPIO chip.
*/
static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
void acpi_gpiochip_free_interrupts(struct gpio_chip *chip)
{
struct acpi_gpio_chip *acpi_gpio;
struct acpi_gpio_event *event, *ep;
struct gpio_chip *chip = acpi_gpio->chip;
acpi_handle handle;
acpi_status status;
if (!chip->dev || !chip->to_irq)
return;
if (!chip->to_irq)
handle = ACPI_HANDLE(chip->dev);
if (!handle)
return;
status = acpi_get_data(handle, acpi_gpio_chip_dh, (void **)&acpi_gpio);
if (ACPI_FAILURE(status))
return;
list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
......@@ -263,7 +283,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
desc = gpiochip_get_desc(chip, event->pin);
if (WARN_ON(IS_ERR(desc)))
continue;
gpiod_unlock_as_irq(desc);
gpio_unlock_as_irq(chip, event->pin);
gpiochip_free_own_desc(desc);
list_del(&event->node);
kfree(event);
......@@ -525,7 +545,6 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
return;
}
acpi_gpiochip_request_interrupts(acpi_gpio);
acpi_gpiochip_request_regions(acpi_gpio);
}
......@@ -549,7 +568,6 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
}
acpi_gpiochip_free_regions(acpi_gpio);
acpi_gpiochip_free_interrupts(acpi_gpio);
acpi_detach_data(handle, acpi_gpio_chip_dh);
kfree(acpi_gpio);
......
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include "gpiolib.h"
void gpio_free(unsigned gpio)
{
gpiod_free(gpio_to_desc(gpio));
}
EXPORT_SYMBOL_GPL(gpio_free);
/**
* gpio_request_one - request a single GPIO with initial configuration
* @gpio: the GPIO number
* @flags: GPIO configuration as specified by GPIOF_*
* @label: a literal description string of this GPIO
*/
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
{
struct gpio_desc *desc;
int err;
desc = gpio_to_desc(gpio);
err = gpiod_request(desc, label);
if (err)
return err;
if (flags & GPIOF_OPEN_DRAIN)
set_bit(FLAG_OPEN_DRAIN, &desc->flags);
if (flags & GPIOF_OPEN_SOURCE)
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
if (flags & GPIOF_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
if (flags & GPIOF_DIR_IN)
err = gpiod_direction_input(desc);
else
err = gpiod_direction_output_raw(desc,
(flags & GPIOF_INIT_HIGH) ? 1 : 0);
if (err)
goto free_gpio;
if (flags & GPIOF_EXPORT) {
err = gpiod_export(desc, flags & GPIOF_EXPORT_CHANGEABLE);
if (err)
goto free_gpio;
}
return 0;
free_gpio:
gpiod_free(desc);
return err;
}
EXPORT_SYMBOL_GPL(gpio_request_one);
int gpio_request(unsigned gpio, const char *label)
{
return gpiod_request(gpio_to_desc(gpio), label);
}
EXPORT_SYMBOL_GPL(gpio_request);
/**
* gpio_request_array - request multiple GPIOs in a single call
* @array: array of the 'struct gpio'
* @num: how many GPIOs in the array
*/
int gpio_request_array(const struct gpio *array, size_t num)
{
int i, err;
for (i = 0; i < num; i++, array++) {
err = gpio_request_one(array->gpio, array->flags, array->label);
if (err)
goto err_free;
}
return 0;
err_free:
while (i--)
gpio_free((--array)->gpio);
return err;
}
EXPORT_SYMBOL_GPL(gpio_request_array);
/**
* gpio_free_array - release multiple GPIOs in a single call
* @array: array of the 'struct gpio'
* @num: how many GPIOs in the array
*/
void gpio_free_array(const struct gpio *array, size_t num)
{
while (num--)
gpio_free((array++)->gpio);
}
EXPORT_SYMBOL_GPL(gpio_free_array);
......@@ -23,7 +23,7 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
struct gpio_desc;
#include "gpiolib.h"
/* Private data structure for of_gpiochip_find_and_xlate */
struct gg_data {
......@@ -82,19 +82,19 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
&gg_data.gpiospec);
if (ret) {
pr_debug("%s: can't parse gpios property of node '%s[%d]'\n",
__func__, np->full_name, index);
pr_debug("%s: can't parse '%s' property of node '%s[%d]'\n",
__func__, propname, np->full_name, index);
return ERR_PTR(ret);
}
gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);
of_node_put(gg_data.gpiospec.np);
pr_debug("%s exited with status %d\n", __func__,
pr_debug("%s: parsed '%s' property of node '%s[%d]' - status (%d)\n",
__func__, propname, np->full_name, index,
PTR_ERR_OR_ZERO(gg_data.out_gpio));
return gg_data.out_gpio;
}
EXPORT_SYMBOL(of_get_named_gpiod_flags);
int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
int index, enum of_gpio_flags *flags)
......
This diff is collapsed.
This diff is collapsed.
......@@ -31,12 +31,21 @@ struct acpi_gpio_info {
void acpi_gpiochip_add(struct gpio_chip *chip);
void acpi_gpiochip_remove(struct gpio_chip *chip);
void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
struct gpio_desc *acpi_get_gpiod_by_index(struct device *dev, int index,
struct acpi_gpio_info *info);
#else
static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
static inline void
acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
static inline void
acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
static inline struct gpio_desc *
acpi_get_gpiod_by_index(struct device *dev, int index,
struct acpi_gpio_info *info)
......@@ -45,10 +54,100 @@ acpi_get_gpiod_by_index(struct device *dev, int index,
}
#endif
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
void gpiochip_free_own_desc(struct gpio_desc *desc);
struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
const char *list_name, int index, enum of_gpio_flags *flags);
struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip, u16 hwnum);
extern struct spinlock gpio_lock;
extern struct list_head gpio_chips;
struct gpio_desc {
struct gpio_chip *chip;
unsigned long flags;
/* flag symbols are bit numbers */
#define FLAG_REQUESTED 0
#define FLAG_IS_OUT 1
#define FLAG_EXPORT 2 /* protected by sysfs_lock */
#define FLAG_SYSFS 3 /* exported via /sys/class/gpio/control */
#define FLAG_TRIG_FALL 4 /* trigger on falling edge */
#define FLAG_TRIG_RISE 5 /* trigger on rising edge */
#define FLAG_ACTIVE_LOW 6 /* value has active low */
#define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */
#define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */
#define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */
#define ID_SHIFT 16 /* add new flags before this one */
#define GPIO_FLAGS_MASK ((1 << ID_SHIFT) - 1)
#define GPIO_TRIGGER_MASK (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
const char *label;
};
int gpiod_request(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc);
/*
* Return the GPIO number of the passed descriptor relative to its chip
*/
static int __maybe_unused gpio_chip_hwgpio(const struct gpio_desc *desc)
{
return desc - &desc->chip->desc[0];
}
/* With descriptor prefix */
#define gpiod_emerg(desc, fmt, ...) \
pr_emerg("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
##__VA_ARGS__)
#define gpiod_crit(desc, fmt, ...) \
pr_crit("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
##__VA_ARGS__)
#define gpiod_err(desc, fmt, ...) \
pr_err("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
##__VA_ARGS__)
#define gpiod_warn(desc, fmt, ...) \
pr_warn("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
##__VA_ARGS__)
#define gpiod_info(desc, fmt, ...) \
pr_info("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?", \
##__VA_ARGS__)
#define gpiod_dbg(desc, fmt, ...) \
pr_debug("gpio-%d (%s): " fmt, desc_to_gpio(desc), desc->label ? : "?",\
##__VA_ARGS__)
/* With chip prefix */
#define chip_emerg(chip, fmt, ...) \
pr_emerg("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#define chip_crit(chip, fmt, ...) \
pr_crit("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#define chip_err(chip, fmt, ...) \
pr_err("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#define chip_warn(chip, fmt, ...) \
pr_warn("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#define chip_info(chip, fmt, ...) \
pr_info("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#define chip_dbg(chip, fmt, ...) \
pr_debug("GPIO chip %s: " fmt, chip->label, ##__VA_ARGS__)
#ifdef CONFIG_GPIO_SYSFS
int gpiochip_export(struct gpio_chip *chip);
void gpiochip_unexport(struct gpio_chip *chip);
#else
static inline int gpiochip_export(struct gpio_chip *chip)
{
return 0;
}
static inline void gpiochip_unexport(struct gpio_chip *chip)
{
}
#endif /* CONFIG_GPIO_SYSFS */
#endif /* GPIOLIB_H */
......@@ -110,9 +110,6 @@ static inline int __gpio_to_irq(unsigned gpio)
return gpiod_to_irq(gpio_to_desc(gpio));
}
extern int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset);
extern void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset);
extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
extern int gpio_request_array(const struct gpio *array, size_t num);
extern void gpio_free_array(const struct gpio *array, size_t num);
......
......@@ -18,30 +18,79 @@ struct gpio_desc;
#ifdef CONFIG_GPIOLIB
#define GPIOD_FLAGS_BIT_DIR_SET BIT(0)
#define GPIOD_FLAGS_BIT_DIR_OUT BIT(1)
#define GPIOD_FLAGS_BIT_DIR_VAL BIT(2)
/**
* Optional flags that can be passed to one of gpiod_* to configure direction
* and output value. These values cannot be OR'd.
*/
enum gpiod_flags {
GPIOD_ASIS = 0,
GPIOD_IN = GPIOD_FLAGS_BIT_DIR_SET,
GPIOD_OUT_LOW = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT,
GPIOD_OUT_HIGH = GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
GPIOD_FLAGS_BIT_DIR_VAL,
};
/* Acquire and dispose GPIOs */
struct gpio_desc *__must_check gpiod_get(struct device *dev,
const char *con_id);
struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
struct gpio_desc *__must_check __gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
#define __gpiod_get(dev, con_id, flags, ...) __gpiod_get(dev, con_id, flags)
#define gpiod_get(varargs...) __gpiod_get(varargs, 0)
struct gpio_desc *__must_check __gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx);
struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
const char *con_id);
struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev,
unsigned int idx,
enum gpiod_flags flags);
#define __gpiod_get_index(dev, con_id, index, flags, ...) \
__gpiod_get_index(dev, con_id, index, flags)
#define gpiod_get_index(varargs...) __gpiod_get_index(varargs, 0)
struct gpio_desc *__must_check __gpiod_get_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
#define __gpiod_get_optional(dev, con_id, flags, ...) \
__gpiod_get_optional(dev, con_id, flags)
#define gpiod_get_optional(varargs...) __gpiod_get_optional(varargs, 0)
struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
const char *con_id,
unsigned int index);
unsigned int index,
enum gpiod_flags flags);
#define __gpiod_get_index_optional(dev, con_id, index, flags, ...) \
__gpiod_get_index_optional(dev, con_id, index, flags)
#define gpiod_get_index_optional(varargs...) \
__gpiod_get_index_optional(varargs, 0)
void gpiod_put(struct gpio_desc *desc);
struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
const char *con_id);
struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
#define __devm_gpiod_get(dev, con_id, flags, ...) \
__devm_gpiod_get(dev, con_id, flags)
#define devm_gpiod_get(varargs...) __devm_gpiod_get(varargs, 0)
struct gpio_desc *__must_check __devm_gpiod_get_index(struct device *dev,
const char *con_id,
unsigned int idx);
struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
const char *con_id);
unsigned int idx,
enum gpiod_flags flags);
#define __devm_gpiod_get_index(dev, con_id, index, flags, ...) \
__devm_gpiod_get_index(dev, con_id, index, flags)
#define devm_gpiod_get_index(varargs...) __devm_gpiod_get_index(varargs, 0)
struct gpio_desc *__must_check __devm_gpiod_get_optional(struct device *dev,
const char *con_id,
enum gpiod_flags flags);
#define __devm_gpiod_get_optional(dev, con_id, flags, ...) \
__devm_gpiod_get_optional(dev, con_id, flags)
#define devm_gpiod_get_optional(varargs...) \
__devm_gpiod_get_optional(varargs, 0)
struct gpio_desc *__must_check
devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index);
__devm_gpiod_get_index_optional(struct device *dev, const char *con_id,
unsigned int index, enum gpiod_flags flags);
#define __devm_gpiod_get_index_optional(dev, con_id, index, flags, ...) \
__devm_gpiod_get_index_optional(dev, con_id, index, flags)
#define devm_gpiod_get_index_optional(varargs...) \
__devm_gpiod_get_index_optional(varargs, 0)
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc);
......
......@@ -141,73 +141,16 @@ extern const char *gpiochip_is_requested(struct gpio_chip *chip,
/* add/remove chips */
extern int gpiochip_add(struct gpio_chip *chip);
extern int __must_check gpiochip_remove(struct gpio_chip *chip);
extern int gpiochip_remove(struct gpio_chip *chip);
extern struct gpio_chip *gpiochip_find(void *data,
int (*match)(struct gpio_chip *chip, void *data));
/* lock/unlock as IRQ */
int gpiod_lock_as_irq(struct gpio_desc *desc);
void gpiod_unlock_as_irq(struct gpio_desc *desc);
int gpio_lock_as_irq(struct gpio_chip *chip, unsigned int offset);
void gpio_unlock_as_irq(struct gpio_chip *chip, unsigned int offset);
struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
u16 hwnum);
enum gpio_lookup_flags {
GPIO_ACTIVE_HIGH = (0 << 0),
GPIO_ACTIVE_LOW = (1 << 0),
GPIO_OPEN_DRAIN = (1 << 1),
GPIO_OPEN_SOURCE = (1 << 2),
};
/**
* struct gpiod_lookup - lookup table
* @chip_label: name of the chip the GPIO belongs to
* @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO
* @con_id: name of the GPIO from the device's point of view
* @idx: index of the GPIO in case several GPIOs share the same name
* @flags: mask of GPIO_* values
*
* gpiod_lookup is a lookup table for associating GPIOs to specific devices and
* functions using platform data.
*/
struct gpiod_lookup {
const char *chip_label;
u16 chip_hwnum;
const char *con_id;
unsigned int idx;
enum gpio_lookup_flags flags;
};
struct gpiod_lookup_table {
struct list_head list;
const char *dev_id;
struct gpiod_lookup table[];
};
/*
* Simple definition of a single GPIO under a con_id
*/
#define GPIO_LOOKUP(_chip_label, _chip_hwnum, _con_id, _flags) \
GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _con_id, 0, _flags)
/*
* Use this macro if you need to have several GPIOs under the same con_id.
* Each GPIO needs to use a different index and can be accessed using
* gpiod_get_index()
*/
#define GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _con_id, _idx, _flags) \
{ \
.chip_label = _chip_label, \
.chip_hwnum = _chip_hwnum, \
.con_id = _con_id, \
.idx = _idx, \
.flags = _flags, \
}
void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
#ifdef CONFIG_GPIOLIB_IRQCHIP
void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
......@@ -223,6 +166,9 @@ int gpiochip_irqchip_add(struct gpio_chip *gpiochip,
#endif /* CONFIG_GPIO_IRQCHIP */
int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
void gpiochip_free_own_desc(struct gpio_desc *desc);
#else /* CONFIG_GPIOLIB */
static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
......
#ifndef __LINUX_GPIO_MACHINE_H
#define __LINUX_GPIO_MACHINE_H
#include <linux/types.h>
#include <linux/list.h>
enum gpio_lookup_flags {
GPIO_ACTIVE_HIGH = (0 << 0),
GPIO_ACTIVE_LOW = (1 << 0),
GPIO_OPEN_DRAIN = (1 << 1),
GPIO_OPEN_SOURCE = (1 << 2),
};
/**
* struct gpiod_lookup - lookup table
* @chip_label: name of the chip the GPIO belongs to
* @chip_hwnum: hardware number (i.e. relative to the chip) of the GPIO
* @con_id: name of the GPIO from the device's point of view
* @idx: index of the GPIO in case several GPIOs share the same name
* @flags: mask of GPIO_* values
*
* gpiod_lookup is a lookup table for associating GPIOs to specific devices and
* functions using platform data.
*/
struct gpiod_lookup {
const char *chip_label;
u16 chip_hwnum;
const char *con_id;
unsigned int idx;
enum gpio_lookup_flags flags;
};
struct gpiod_lookup_table {
struct list_head list;
const char *dev_id;
struct gpiod_lookup table[];
};
/*
* Simple definition of a single GPIO under a con_id
*/
#define GPIO_LOOKUP(_chip_label, _chip_hwnum, _con_id, _flags) \
GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _con_id, 0, _flags)
/*
* Use this macro if you need to have several GPIOs under the same con_id.
* Each GPIO needs to use a different index and can be accessed using
* gpiod_get_index()
*/
#define GPIO_LOOKUP_IDX(_chip_label, _chip_hwnum, _con_id, _idx, _flags) \
{ \
.chip_label = _chip_label, \
.chip_hwnum = _chip_hwnum, \
.con_id = _con_id, \
.idx = _idx, \
.flags = _flags, \
}
void gpiod_add_lookup_table(struct gpiod_lookup_table *table);
#endif /* __LINUX_GPIO_MACHINE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment