Loading drivers/gpio/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -519,6 +519,7 @@ config GPIO_PCA953X config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" depends on GPIO_PCA953X=y select GPIOLIB_IRQCHIP help Say yes here to enable the pca953x to be used as an interrupt controller. It requires the driver to be built in the kernel. Loading drivers/gpio/gpio-pca953x.c +32 −61 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ #include <linux/init.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/i2c.h> #include <linux/platform_data/pca953x.h> #include <linux/slab.h> Loading Loading @@ -91,7 +89,6 @@ struct pca953x_chip { u8 irq_stat[MAX_BANK]; u8 irq_trig_raise[MAX_BANK]; u8 irq_trig_fall[MAX_BANK]; struct irq_domain *domain; #endif struct i2c_client *client; Loading @@ -100,6 +97,11 @@ struct pca953x_chip { int chip_type; }; static inline struct pca953x_chip *to_pca(struct gpio_chip *gc) { return container_of(gc, struct pca953x_chip, gpio_chip); } static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, int off) { Loading Loading @@ -202,12 +204,10 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ)); Loading @@ -233,12 +233,10 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); /* set output level */ if (val) Loading Loading @@ -285,12 +283,10 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u32 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); switch (chip->chip_type) { case PCA953X_TYPE: Loading @@ -315,12 +311,10 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); if (val) reg_val = chip->reg_output[off / BANK_SZ] Loading Loading @@ -367,38 +361,34 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) } #ifdef CONFIG_GPIO_PCA953X_IRQ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; chip = container_of(gc, struct pca953x_chip, gpio_chip); return irq_create_mapping(chip->domain, off); } static void pca953x_irq_mask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ)); } static void pca953x_irq_unmask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); } static void pca953x_irq_bus_lock(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); mutex_lock(&chip->irq_lock); } static void pca953x_irq_bus_sync_unlock(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); u8 new_irqs; int level, i; Loading @@ -420,7 +410,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); int bank_nb = d->hwirq / BANK_SZ; u8 mask = 1 << (d->hwirq % BANK_SZ); Loading Loading @@ -512,7 +503,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { level = __ffs(pending[i]); handle_nested_irq(irq_find_mapping(chip->domain, handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); nhandled++; Loading @@ -522,27 +513,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; } static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { irq_clear_status_flags(irq, IRQ_NOREQUEST); irq_set_chip_data(irq, d->host_data); irq_set_chip(irq, &pca953x_irq_chip); irq_set_nested_thread(irq, true); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else irq_set_noprobe(irq); #endif return 0; } static const struct irq_domain_ops pca953x_irq_simple_ops = { .map = pca953x_gpio_irq_map, .xlate = irq_domain_xlate_twocell, }; static int pca953x_irq_setup(struct pca953x_chip *chip, const struct i2c_device_id *id, int irq_base) Loading Loading @@ -574,14 +544,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->irq_stat[i] &= chip->reg_direction[i]; mutex_init(&chip->irq_lock); chip->domain = irq_domain_add_simple(client->dev.of_node, chip->gpio_chip.ngpio, irq_base, &pca953x_irq_simple_ops, chip); if (!chip->domain) return -ENODEV; ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, Loading @@ -595,7 +557,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return ret; } chip->gpio_chip.to_irq = pca953x_gpio_to_irq; ret = gpiochip_irqchip_add(&chip->gpio_chip, &pca953x_irq_chip, irq_base, handle_simple_irq, IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); return ret; } } return 0; Loading Loading @@ -759,11 +730,11 @@ static int pca953x_probe(struct i2c_client *client, if (ret) return ret; ret = pca953x_irq_setup(chip, id, irq_base); ret = gpiochip_add(&chip->gpio_chip); if (ret) return ret; ret = gpiochip_add(&chip->gpio_chip); ret = pca953x_irq_setup(chip, id, irq_base); if (ret) return ret; Loading Loading
drivers/gpio/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -519,6 +519,7 @@ config GPIO_PCA953X config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" depends on GPIO_PCA953X=y select GPIOLIB_IRQCHIP help Say yes here to enable the pca953x to be used as an interrupt controller. It requires the driver to be built in the kernel. Loading
drivers/gpio/gpio-pca953x.c +32 −61 Original line number Diff line number Diff line Loading @@ -15,8 +15,6 @@ #include <linux/init.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/i2c.h> #include <linux/platform_data/pca953x.h> #include <linux/slab.h> Loading Loading @@ -91,7 +89,6 @@ struct pca953x_chip { u8 irq_stat[MAX_BANK]; u8 irq_trig_raise[MAX_BANK]; u8 irq_trig_fall[MAX_BANK]; struct irq_domain *domain; #endif struct i2c_client *client; Loading @@ -100,6 +97,11 @@ struct pca953x_chip { int chip_type; }; static inline struct pca953x_chip *to_pca(struct gpio_chip *gc) { return container_of(gc, struct pca953x_chip, gpio_chip); } static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, int off) { Loading Loading @@ -202,12 +204,10 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ)); Loading @@ -233,12 +233,10 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); /* set output level */ if (val) Loading Loading @@ -285,12 +283,10 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u32 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); switch (chip->chip_type) { case PCA953X_TYPE: Loading @@ -315,12 +311,10 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; chip = container_of(gc, struct pca953x_chip, gpio_chip); mutex_lock(&chip->i2c_lock); if (val) reg_val = chip->reg_output[off / BANK_SZ] Loading Loading @@ -367,38 +361,34 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) } #ifdef CONFIG_GPIO_PCA953X_IRQ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; chip = container_of(gc, struct pca953x_chip, gpio_chip); return irq_create_mapping(chip->domain, off); } static void pca953x_irq_mask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ)); } static void pca953x_irq_unmask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); } static void pca953x_irq_bus_lock(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); mutex_lock(&chip->irq_lock); } static void pca953x_irq_bus_sync_unlock(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); u8 new_irqs; int level, i; Loading @@ -420,7 +410,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = to_pca(gc); int bank_nb = d->hwirq / BANK_SZ; u8 mask = 1 << (d->hwirq % BANK_SZ); Loading Loading @@ -512,7 +503,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { level = __ffs(pending[i]); handle_nested_irq(irq_find_mapping(chip->domain, handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); nhandled++; Loading @@ -522,27 +513,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; } static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { irq_clear_status_flags(irq, IRQ_NOREQUEST); irq_set_chip_data(irq, d->host_data); irq_set_chip(irq, &pca953x_irq_chip); irq_set_nested_thread(irq, true); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else irq_set_noprobe(irq); #endif return 0; } static const struct irq_domain_ops pca953x_irq_simple_ops = { .map = pca953x_gpio_irq_map, .xlate = irq_domain_xlate_twocell, }; static int pca953x_irq_setup(struct pca953x_chip *chip, const struct i2c_device_id *id, int irq_base) Loading Loading @@ -574,14 +544,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->irq_stat[i] &= chip->reg_direction[i]; mutex_init(&chip->irq_lock); chip->domain = irq_domain_add_simple(client->dev.of_node, chip->gpio_chip.ngpio, irq_base, &pca953x_irq_simple_ops, chip); if (!chip->domain) return -ENODEV; ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, Loading @@ -595,7 +557,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return ret; } chip->gpio_chip.to_irq = pca953x_gpio_to_irq; ret = gpiochip_irqchip_add(&chip->gpio_chip, &pca953x_irq_chip, irq_base, handle_simple_irq, IRQ_TYPE_NONE); if (ret) { dev_err(&client->dev, "could not connect irqchip to gpiochip\n"); return ret; } } return 0; Loading Loading @@ -759,11 +730,11 @@ static int pca953x_probe(struct i2c_client *client, if (ret) return ret; ret = pca953x_irq_setup(chip, id, irq_base); ret = gpiochip_add(&chip->gpio_chip); if (ret) return ret; ret = gpiochip_add(&chip->gpio_chip); ret = pca953x_irq_setup(chip, id, irq_base); if (ret) return ret; Loading