diff options
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 7 | ||||
-rw-r--r-- | drivers/gpio/gpio-104-dio-48e.c | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-104-idio-16.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-altera.c | 9 | ||||
-rw-r--r-- | drivers/gpio/gpio-elkhartlake.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-gpio-mm.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-graniterapids.c | 52 | ||||
-rw-r--r-- | drivers/gpio/gpio-i8255.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-idio-16.c | 5 | ||||
-rw-r--r-- | drivers/gpio/gpio-ljca.c | 4 | ||||
-rw-r--r-- | drivers/gpio/gpio-loongson-64bit.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-menz127.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-merrifield.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-mpc8xxx.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-pca953x.c | 3 | ||||
-rw-r--r-- | drivers/gpio/gpio-pci-idio-16.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-regmap.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-sim.c | 48 | ||||
-rw-r--r-- | drivers/gpio/gpio-tangier.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-tps65219.c | 12 | ||||
-rw-r--r-- | drivers/gpio/gpio-tqmx86.c | 206 | ||||
-rw-r--r-- | drivers/gpio/gpio-twl6040.c | 6 | ||||
-rw-r--r-- | drivers/gpio/gpio-virtuser.c | 91 | ||||
-rw-r--r-- | drivers/gpio/gpio-xilinx.c | 32 | ||||
-rw-r--r-- | drivers/gpio/gpiolib-swnode.c | 2 |
25 files changed, 326 insertions, 180 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 56fee58e281e..add5ad29a673 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -482,8 +482,9 @@ config GPIO_MT7621 Say yes here to support the Mediatek MT7621 SoC GPIO device. config GPIO_MVEBU - def_bool y + bool "Marvell Orion and EBU GPIO support" if COMPILE_TEST depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST + default PLAT_ORION || ARCH_MVEBU select GENERIC_IRQ_CHIP select REGMAP_MMIO @@ -528,9 +529,9 @@ config GPIO_OCTEON family of SOCs. config GPIO_OMAP - tristate "TI OMAP GPIO support" if ARCH_OMAP2PLUS || COMPILE_TEST + tristate "TI OMAP GPIO support" + depends on ARCH_OMAP || COMPILE_TEST default y if ARCH_OMAP - depends on ARM select GENERIC_IRQ_CHIP select GPIOLIB_IRQCHIP help diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 4df9becaf349..cf5a50102d49 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -22,7 +22,7 @@ #include "gpio-i8255.h" -MODULE_IMPORT_NS(I8255); +MODULE_IMPORT_NS("I8255"); #define DIO48E_EXTENT 16 #define MAX_NUM_DIO48E max_num_isa_dev(DIO48E_EXTENT) @@ -339,4 +339,4 @@ module_isa_driver_with_irq(dio48e_driver, num_dio48e, num_irq); MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(I8254); +MODULE_IMPORT_NS("I8254"); diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index f03ccd0f534c..ffe7e1cb6b23 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -126,4 +126,4 @@ module_isa_driver_with_irq(idio_16_driver, num_idio_16, num_irq); MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); MODULE_DESCRIPTION("ACCES 104-IDIO-16 GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_IDIO_16); +MODULE_IMPORT_NS("GPIO_IDIO_16"); diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index 73e660c5e38a..17ab039c7413 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -32,14 +32,12 @@ * will be blocked until the current one completes. * @interrupt_trigger : specifies the hardware configured IRQ trigger type * (rising, falling, both, high) -* @mapped_irq : kernel mapped irq number. */ struct altera_gpio_chip { struct gpio_chip gc; void __iomem *regs; raw_spinlock_t gpio_lock; int interrupt_trigger; - int mapped_irq; }; static void altera_gpio_irq_unmask(struct irq_data *d) @@ -235,6 +233,7 @@ static int altera_gpio_probe(struct platform_device *pdev) int reg, ret; struct altera_gpio_chip *altera_gc; struct gpio_irq_chip *girq; + int mapped_irq; altera_gc = devm_kzalloc(&pdev->dev, sizeof(*altera_gc), GFP_KERNEL); if (!altera_gc) @@ -271,8 +270,8 @@ static int altera_gpio_probe(struct platform_device *pdev) if (IS_ERR(altera_gc->regs)) return dev_err_probe(dev, PTR_ERR(altera_gc->regs), "failed to ioremap memory resource\n"); - altera_gc->mapped_irq = platform_get_irq_optional(pdev, 0); - if (altera_gc->mapped_irq < 0) + mapped_irq = platform_get_irq_optional(pdev, 0); + if (mapped_irq < 0) goto skip_irq; if (device_property_read_u32(dev, "altr,interrupt-type", ®)) { @@ -296,7 +295,7 @@ static int altera_gpio_probe(struct platform_device *pdev) return -ENOMEM; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_bad_irq; - girq->parents[0] = altera_gc->mapped_irq; + girq->parents[0] = mapped_irq; skip_irq: ret = devm_gpiochip_add_data(dev, &altera_gc->gc, altera_gc); diff --git a/drivers/gpio/gpio-elkhartlake.c b/drivers/gpio/gpio-elkhartlake.c index 887c0fe99d39..95de52d2cc63 100644 --- a/drivers/gpio/gpio-elkhartlake.c +++ b/drivers/gpio/gpio-elkhartlake.c @@ -75,4 +75,4 @@ MODULE_AUTHOR("Pandith N <pandith.n@intel.com>"); MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>"); MODULE_DESCRIPTION("Intel Elkhart Lake PSE GPIO driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(GPIO_TANGIER); +MODULE_IMPORT_NS("GPIO_TANGIER"); diff --git a/drivers/gpio/gpio-gpio-mm.c b/drivers/gpio/gpio-gpio-mm.c index 43d823a56e59..fb7c510bf2fa 100644 --- a/drivers/gpio/gpio-gpio-mm.c +++ b/drivers/gpio/gpio-gpio-mm.c @@ -18,7 +18,7 @@ #include "gpio-i8255.h" -MODULE_IMPORT_NS(I8255); +MODULE_IMPORT_NS("I8255"); #define GPIOMM_EXTENT 8 #define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT) diff --git a/drivers/gpio/gpio-graniterapids.c b/drivers/gpio/gpio-graniterapids.c index f2e911a3d2ca..ad6a045fd3d2 100644 --- a/drivers/gpio/gpio-graniterapids.c +++ b/drivers/gpio/gpio-graniterapids.c @@ -32,12 +32,14 @@ #define GNR_PINS_PER_REG 32 #define GNR_NUM_REGS DIV_ROUND_UP(GNR_NUM_PINS, GNR_PINS_PER_REG) -#define GNR_CFG_BAR 0x00 +#define GNR_CFG_PADBAR 0x00 #define GNR_CFG_LOCK_OFFSET 0x04 -#define GNR_GPI_STATUS_OFFSET 0x20 +#define GNR_GPI_STATUS_OFFSET 0x14 #define GNR_GPI_ENABLE_OFFSET 0x24 -#define GNR_CFG_DW_RX_MASK GENMASK(25, 22) +#define GNR_CFG_DW_HOSTSW_MODE BIT(27) +#define GNR_CFG_DW_RX_MASK GENMASK(23, 22) +#define GNR_CFG_DW_INTSEL_MASK GENMASK(21, 14) #define GNR_CFG_DW_RX_DISABLE FIELD_PREP(GNR_CFG_DW_RX_MASK, 2) #define GNR_CFG_DW_RX_EDGE FIELD_PREP(GNR_CFG_DW_RX_MASK, 1) #define GNR_CFG_DW_RX_LEVEL FIELD_PREP(GNR_CFG_DW_RX_MASK, 0) @@ -50,6 +52,7 @@ * struct gnr_gpio - Intel Granite Rapids-D vGPIO driver state * @gc: GPIO controller interface * @reg_base: base address of the GPIO registers + * @pad_base: base address of the vGPIO pad configuration registers * @ro_bitmap: bitmap of read-only pins * @lock: guard the registers * @pad_backup: backup of the register state for suspend @@ -57,6 +60,7 @@ struct gnr_gpio { struct gpio_chip gc; void __iomem *reg_base; + void __iomem *pad_base; DECLARE_BITMAP(ro_bitmap, GNR_NUM_PINS); raw_spinlock_t lock; u32 pad_backup[]; @@ -65,7 +69,7 @@ struct gnr_gpio { static void __iomem *gnr_gpio_get_padcfg_addr(const struct gnr_gpio *priv, unsigned int gpio) { - return priv->reg_base + gpio * sizeof(u32); + return priv->pad_base + gpio * sizeof(u32); } static int gnr_gpio_configure_line(struct gpio_chip *gc, unsigned int gpio, @@ -88,6 +92,20 @@ static int gnr_gpio_configure_line(struct gpio_chip *gc, unsigned int gpio, return 0; } +static int gnr_gpio_request(struct gpio_chip *gc, unsigned int gpio) +{ + struct gnr_gpio *priv = gpiochip_get_data(gc); + u32 dw; + + dw = readl(gnr_gpio_get_padcfg_addr(priv, gpio)); + if (!(dw & GNR_CFG_DW_HOSTSW_MODE)) { + dev_warn(gc->parent, "GPIO %u is not owned by host", gpio); + return -EBUSY; + } + + return 0; +} + static int gnr_gpio_get(struct gpio_chip *gc, unsigned int gpio) { const struct gnr_gpio *priv = gpiochip_get_data(gc); @@ -139,6 +157,7 @@ static int gnr_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio, in static const struct gpio_chip gnr_gpio_chip = { .owner = THIS_MODULE, + .request = gnr_gpio_request, .get = gnr_gpio_get, .set = gnr_gpio_set, .get_direction = gnr_gpio_get_direction, @@ -166,7 +185,7 @@ static void gnr_gpio_irq_ack(struct irq_data *d) guard(raw_spinlock_irqsave)(&priv->lock); reg = readl(addr); - reg &= ~BIT(bit_idx); + reg |= BIT(bit_idx); writel(reg, addr); } @@ -209,10 +228,18 @@ static void gnr_gpio_irq_unmask(struct irq_data *d) static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - irq_hw_number_t pin = irqd_to_hwirq(d); - u32 mask = GNR_CFG_DW_RX_MASK; + struct gnr_gpio *priv = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + u32 reg; u32 set; + /* Allow interrupts only if Interrupt Select field is non-zero */ + reg = readl(gnr_gpio_get_padcfg_addr(priv, hwirq)); + if (!(reg & GNR_CFG_DW_INTSEL_MASK)) { + dev_dbg(gc->parent, "GPIO %lu cannot be used as IRQ", hwirq); + return -EPERM; + } + /* Falling edge and level low triggers not supported by the GPIO controller */ switch (type) { case IRQ_TYPE_NONE: @@ -230,10 +257,11 @@ static int gnr_gpio_irq_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - return gnr_gpio_configure_line(gc, pin, mask, set); + return gnr_gpio_configure_line(gc, hwirq, GNR_CFG_DW_RX_MASK, set); } static const struct irq_chip gnr_gpio_irq_chip = { + .name = "gpio-graniterapids", .irq_ack = gnr_gpio_irq_ack, .irq_mask = gnr_gpio_irq_mask, .irq_unmask = gnr_gpio_irq_unmask, @@ -291,6 +319,7 @@ static int gnr_gpio_probe(struct platform_device *pdev) struct gnr_gpio *priv; void __iomem *regs; int irq, ret; + u32 offset; priv = devm_kzalloc(dev, struct_size(priv, pad_backup, num_backup_pins), GFP_KERNEL); if (!priv) @@ -302,6 +331,10 @@ static int gnr_gpio_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); + priv->reg_base = regs; + offset = readl(priv->reg_base + GNR_CFG_PADBAR); + priv->pad_base = priv->reg_base + offset; + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -311,8 +344,6 @@ static int gnr_gpio_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "failed to request interrupt\n"); - priv->reg_base = regs + readl(regs + GNR_CFG_BAR); - gnr_gpio_init_pin_ro_bits(dev, priv->reg_base + GNR_CFG_LOCK_OFFSET, priv->ro_bitmap); @@ -324,7 +355,6 @@ static int gnr_gpio_probe(struct platform_device *pdev) girq = &priv->gc.irq; gpio_irq_chip_set_chip(girq, &gnr_gpio_irq_chip); - girq->chip->name = dev_name(dev); girq->parent_handler = NULL; girq->num_parents = 0; girq->parents = NULL; diff --git a/drivers/gpio/gpio-i8255.c b/drivers/gpio/gpio-i8255.c index 64ab80fc4a1e..953018bfa2b1 100644 --- a/drivers/gpio/gpio-i8255.c +++ b/drivers/gpio/gpio-i8255.c @@ -134,7 +134,7 @@ int devm_i8255_regmap_register(struct device *const dev, return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config)); } -EXPORT_SYMBOL_NS_GPL(devm_i8255_regmap_register, I8255); +EXPORT_SYMBOL_NS_GPL(devm_i8255_regmap_register, "I8255"); MODULE_AUTHOR("William Breathitt Gray"); MODULE_DESCRIPTION("Intel 8255 Programmable Peripheral Interface"); diff --git a/drivers/gpio/gpio-idio-16.c b/drivers/gpio/gpio-idio-16.c index 53b1eb876a12..0103be977c66 100644 --- a/drivers/gpio/gpio-idio-16.c +++ b/drivers/gpio/gpio-idio-16.c @@ -3,6 +3,9 @@ * GPIO library for the ACCES IDIO-16 family * Copyright (C) 2022 William Breathitt Gray */ + +#define DEFAULT_SYMBOL_NAMESPACE "GPIO_IDIO_16" + #include <linux/bits.h> #include <linux/device.h> #include <linux/err.h> @@ -14,8 +17,6 @@ #include "gpio-idio-16.h" -#define DEFAULT_SYMBOL_NAMESPACE GPIO_IDIO_16 - #define IDIO_16_DAT_BASE 0x0 #define IDIO_16_OUT_BASE IDIO_16_DAT_BASE #define IDIO_16_IN_BASE (IDIO_16_DAT_BASE + 1) diff --git a/drivers/gpio/gpio-ljca.c b/drivers/gpio/gpio-ljca.c index d67b912d884d..817ecb12d550 100644 --- a/drivers/gpio/gpio-ljca.c +++ b/drivers/gpio/gpio-ljca.c @@ -82,9 +82,9 @@ static int ljca_gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, int ret; mutex_lock(&ljca_gpio->trans_lock); + packet->num = 1; packet->item[0].index = gpio_id; packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id]; - packet->num = 1; ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet, struct_size(packet, item, packet->num), NULL, 0); @@ -492,4 +492,4 @@ MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>"); MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>"); MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver"); MODULE_LICENSE("GPL"); -MODULE_IMPORT_NS(LJCA); +MODULE_IMPORT_NS("LJCA"); diff --git a/drivers/gpio/gpio-loongson-64bit.c b/drivers/gpio/gpio-loongson-64bit.c index 6749d4dd6d64..7f4d78fd800e 100644 --- a/drivers/gpio/gpio-loongson-64bit.c +++ b/drivers/gpio/gpio-loongson-64bit.c @@ -237,9 +237,9 @@ static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data1 = { static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data2 = { .label = "ls2k2000_gpio", .mode = BIT_CTRL_MODE, - .conf_offset = 0x84, - .in_offset = 0x88, - .out_offset = 0x80, + .conf_offset = 0x4, + .in_offset = 0x8, + .out_offset = 0x0, }; static const struct loongson_gpio_chip_data loongson_gpio_ls3a5000_data = { diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c index 3ccd2cb35b9c..ebe5da4933bc 100644 --- a/drivers/gpio/gpio-menz127.c +++ b/drivers/gpio/gpio-menz127.c @@ -201,4 +201,4 @@ MODULE_AUTHOR("Andreas Werner <andreas.werner@men.de>"); MODULE_DESCRIPTION("MEN 16z127 GPIO Controller"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("mcb:16z127"); -MODULE_IMPORT_NS(MCB); +MODULE_IMPORT_NS("MCB"); diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index cd20604f26de..4335a5d8e4f6 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -142,4 +142,4 @@ module_pci_driver(mrfld_gpio_driver); MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); MODULE_DESCRIPTION("Intel Merrifield SoC GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_TANGIER); +MODULE_IMPORT_NS("GPIO_TANGIER"); diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 24417c3247b0..0cd4c36ae8aa 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -285,6 +285,7 @@ static const struct mpc8xxx_gpio_devtype mpc8xxx_gpio_devtype_default = { }; static const struct of_device_id mpc8xxx_gpio_ids[] = { + { .compatible = "fsl,mpc8314-gpio", }, { .compatible = "fsl,mpc8349-gpio", }, { .compatible = "fsl,mpc8572-gpio", .data = &mpc8572_gpio_devtype, }, { .compatible = "fsl,mpc8610-gpio", }, diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 272febc3230e..be4c9981ebc4 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -1088,7 +1088,8 @@ static int pca953x_probe(struct i2c_client *client) */ reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(reset_gpio)) - return PTR_ERR(reset_gpio); + return dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to get reset gpio\n"); } chip->client = client; diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 64f332c80550..476cea1b5ed7 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c @@ -112,4 +112,4 @@ module_pci_driver(idio_16_driver); MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>"); MODULE_DESCRIPTION("ACCES PCI-IDIO-16 GPIO driver"); MODULE_LICENSE("GPL v2"); -MODULE_IMPORT_NS(GPIO_IDIO_16); +MODULE_IMPORT_NS("GPIO_IDIO_16"); diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 71684dee2ca5..05f8781b5204 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -262,6 +262,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config chip->label = config->label ?: dev_name(config->parent); chip->can_sleep = regmap_might_sleep(config->regmap); + chip->request = gpiochip_generic_request; + chip->free = gpiochip_generic_free; chip->get = gpio_regmap_get; if (gpio->reg_set_base && gpio->reg_clr_base) chip->set = gpio_regmap_set_with_clear; diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index f387dad81f29..686ae3d11ba3 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -1027,6 +1027,30 @@ static void gpio_sim_device_deactivate(struct gpio_sim_device *dev) dev->pdev = NULL; } +static void +gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock) +{ + struct configfs_subsystem *subsys = dev->group.cg_subsys; + struct gpio_sim_bank *bank; + struct gpio_sim_line *line; + + /* + * The device only needs to depend on leaf line entries. This is + * sufficient to lock up all the configfs entries that the + * instantiated, alive device depends on. + */ + list_for_each_entry(bank, &dev->bank_list, siblings) { + list_for_each_entry(line, &bank->line_list, siblings) { + if (lock) + WARN_ON(configfs_depend_item_unlocked( + subsys, &line->group.cg_item)); + else + configfs_undepend_item_unlocked( + &line->group.cg_item); + } + } +} + static ssize_t gpio_sim_device_config_live_store(struct config_item *item, const char *page, size_t count) @@ -1039,14 +1063,24 @@ gpio_sim_device_config_live_store(struct config_item *item, if (ret) return ret; - guard(mutex)(&dev->lock); + if (live) + gpio_sim_device_lockup_configfs(dev, true); - if (live == gpio_sim_device_is_live(dev)) - ret = -EPERM; - else if (live) - ret = gpio_sim_device_activate(dev); - else - gpio_sim_device_deactivate(dev); + scoped_guard(mutex, &dev->lock) { + if (live == gpio_sim_device_is_live(dev)) + ret = -EPERM; + else if (live) + ret = gpio_sim_device_activate(dev); + else + gpio_sim_device_deactivate(dev); + } + + /* + * Undepend is required only if device disablement (live == 0) + * succeeds or if device enablement (live == 1) fails. + */ + if (live == !!ret) + gpio_sim_device_lockup_configfs(dev, false); return ret ?: count; } diff --git a/drivers/gpio/gpio-tangier.c b/drivers/gpio/gpio-tangier.c index 4b29abafecf6..a415e6d36173 100644 --- a/drivers/gpio/gpio-tangier.c +++ b/drivers/gpio/gpio-tangier.c @@ -459,7 +459,7 @@ int devm_tng_gpio_probe(struct device *dev, struct tng_gpio *gpio) return 0; } -EXPORT_SYMBOL_NS_GPL(devm_tng_gpio_probe, GPIO_TANGIER); +EXPORT_SYMBOL_NS_GPL(devm_tng_gpio_probe, "GPIO_TANGIER"); static int tng_gpio_suspend(struct device *dev) { diff --git a/drivers/gpio/gpio-tps65219.c b/drivers/gpio/gpio-tps65219.c index cd1f17041f8c..526640c39a11 100644 --- a/drivers/gpio/gpio-tps65219.c +++ b/drivers/gpio/gpio-tps65219.c @@ -15,8 +15,6 @@ #define TPS65219_GPIO0_DIR_MASK BIT(3) #define TPS65219_GPIO0_OFFSET 2 #define TPS65219_GPIO0_IDX 0 -#define TPS65219_GPIO_DIR_IN 1 -#define TPS65219_GPIO_DIR_OUT 0 struct tps65219_gpio { struct gpio_chip gpio_chip; @@ -61,7 +59,7 @@ static int tps65219_gpio_get(struct gpio_chip *gc, unsigned int offset) * status bit. */ - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT) + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT) return -ENOTSUPP; return ret; @@ -124,10 +122,10 @@ static int tps65219_gpio_direction_input(struct gpio_chip *gc, unsigned int offs return -ENOTSUPP; } - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_IN) + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_IN) return 0; - return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_IN); + return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_IN); } static int tps65219_gpio_direction_output(struct gpio_chip *gc, unsigned int offset, int value) @@ -136,10 +134,10 @@ static int tps65219_gpio_direction_output(struct gpio_chip *gc, unsigned int off if (offset != TPS65219_GPIO0_IDX) return 0; - if (tps65219_gpio_get_direction(gc, offset) == TPS65219_GPIO_DIR_OUT) + if (tps65219_gpio_get_direction(gc, offset) == GPIO_LINE_DIRECTION_OUT) return 0; - return tps65219_gpio_change_direction(gc, offset, TPS65219_GPIO_DIR_OUT); + return tps65219_gpio_change_direction(gc, offset, GPIO_LINE_DIRECTION_OUT); } static const struct gpio_chip tps65219_template_chip = { diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c index 5e26eb3adabb..18f523a15b3c 100644 --- a/drivers/gpio/gpio-tqmx86.c +++ b/drivers/gpio/gpio-tqmx86.c @@ -29,18 +29,22 @@ #define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ #define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ -#define TQMX86_GPII_NONE 0 -#define TQMX86_GPII_FALLING BIT(0) -#define TQMX86_GPII_RISING BIT(1) -/* Stored in irq_type as a trigger type, but not actually valid as a register - * value, so the name doesn't use "GPII" +/* + * NONE, FALLING and RISING use the same bit patterns that can be programmed to + * the GPII register (after passing them to the TQMX86_GPII_ macros to shift + * them to the right position) */ -#define TQMX86_INT_BOTH (BIT(0) | BIT(1)) -#define TQMX86_GPII_MASK (BIT(0) | BIT(1)) -#define TQMX86_GPII_BITS 2 +#define TQMX86_INT_TRIG_NONE 0 +#define TQMX86_INT_TRIG_FALLING BIT(0) +#define TQMX86_INT_TRIG_RISING BIT(1) +#define TQMX86_INT_TRIG_BOTH (BIT(0) | BIT(1)) +#define TQMX86_INT_TRIG_MASK (BIT(0) | BIT(1)) /* Stored in irq_type with GPII bits */ #define TQMX86_INT_UNMASKED BIT(2) +#define TQMX86_GPIIC_CONFIG(i, v) ((v) << (2 * (i))) +#define TQMX86_GPIIC_MASK(i) TQMX86_GPIIC_CONFIG(i, TQMX86_INT_TRIG_MASK) + struct tqmx86_gpio_data { struct gpio_chip chip; void __iomem *io_base; @@ -48,7 +52,7 @@ struct tqmx86_gpio_data { /* Lock must be held for accessing output and irq_type fields */ raw_spinlock_t spinlock; DECLARE_BITMAP(output, TQMX86_NGPIO); - u8 irq_type[TQMX86_NGPI]; + u8 irq_type[TQMX86_NGPIO]; }; static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg) @@ -62,6 +66,18 @@ static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val, iowrite8(val, gd->io_base + reg); } +static void tqmx86_gpio_clrsetbits(struct tqmx86_gpio_data *gpio, + u8 clr, u8 set, unsigned int reg) + __must_hold(&gpio->spinlock) +{ + u8 val = tqmx86_gpio_read(gpio, reg); + + val &= ~clr; + val |= set; + + tqmx86_gpio_write(gpio, val, reg); +} + static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); @@ -69,127 +85,137 @@ static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset)); } +static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset, + int value) + __must_hold(&gpio->spinlock) +{ + __assign_bit(offset, gpio->output, value); + tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); +} + static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); - unsigned long flags; - raw_spin_lock_irqsave(&gpio->spinlock, flags); - __assign_bit(offset, gpio->output, value); - tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + guard(raw_spinlock_irqsave)(&gpio->spinlock); + + _tqmx86_gpio_set(gpio, offset, value); } static int tqmx86_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - /* Direction cannot be changed. Validate is an input. */ - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) - return 0; - else - return -EINVAL; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + + guard(raw_spinlock_irqsave)(&gpio->spinlock); + + tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD); + + return 0; } static int tqmx86_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - /* Direction cannot be changed, validate is an output */ - if (BIT(offset) & TQMX86_DIR_INPUT_MASK) - return -EINVAL; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + + guard(raw_spinlock_irqsave)(&gpio->spinlock); + + _tqmx86_gpio_set(gpio, offset, value); + tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD); - tqmx86_gpio_set(chip, offset, value); return 0; } static int tqmx86_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - if (TQMX86_DIR_INPUT_MASK & BIT(offset)) - return GPIO_LINE_DIRECTION_IN; + struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); + u8 val; + + val = tqmx86_gpio_read(gpio, TQMX86_GPIODD); + + if (val & BIT(offset)) + return GPIO_LINE_DIRECTION_OUT; - return GPIO_LINE_DIRECTION_OUT; + return GPIO_LINE_DIRECTION_IN; } -static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset) +static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq) __must_hold(&gpio->spinlock) { - u8 type = TQMX86_GPII_NONE, gpiic; + u8 type = TQMX86_INT_TRIG_NONE; + int gpiic_irq = hwirq - TQMX86_NGPO; - if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) { - type = gpio->irq_type[offset] & TQMX86_GPII_MASK; + if (gpio->irq_type[hwirq] & TQMX86_INT_UNMASKED) { + type = gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK; - if (type == TQMX86_INT_BOTH) - type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO) - ? TQMX86_GPII_FALLING - : TQMX86_GPII_RISING; + if (type == TQMX86_INT_TRIG_BOTH) + type = tqmx86_gpio_get(&gpio->chip, hwirq) + ? TQMX86_INT_TRIG_FALLING + : TQMX86_INT_TRIG_RISING; } - gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC); - gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS)); - gpiic |= type << (offset * TQMX86_GPII_BITS); - tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC); + tqmx86_gpio_clrsetbits(gpio, + TQMX86_GPIIC_MASK(gpiic_irq), + TQMX86_GPIIC_CONFIG(gpiic_irq, type), + TQMX86_GPIIC); } static void tqmx86_gpio_irq_mask(struct irq_data *data) { - unsigned int offset = (data->hwirq - TQMX86_NGPO); struct tqmx86_gpio_data *gpio = gpiochip_get_data( irq_data_get_irq_chip_data(data)); - unsigned long flags; - raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED; - tqmx86_gpio_irq_config(gpio, offset); - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { + gpio->irq_type[data->hwirq] &= ~TQMX86_INT_UNMASKED; + tqmx86_gpio_irq_config(gpio, data->hwirq); + } gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data)); } static void tqmx86_gpio_irq_unmask(struct irq_data *data) { - unsigned int offset = (data->hwirq - TQMX86_NGPO); struct tqmx86_gpio_data *gpio = gpiochip_get_data( irq_data_get_irq_chip_data(data)); - unsigned long flags; gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data)); - raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpio->irq_type[offset] |= TQMX86_INT_UNMASKED; - tqmx86_gpio_irq_config(gpio, offset); - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + guard(raw_spinlock_irqsave)(&gpio->spinlock); + + gpio->irq_type[data->hwirq] |= TQMX86_INT_UNMASKED; + tqmx86_gpio_irq_config(gpio, data->hwirq); } static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type) { struct tqmx86_gpio_data *gpio = gpiochip_get_data( irq_data_get_irq_chip_data(data)); - unsigned int offset = (data->hwirq - TQMX86_NGPO); unsigned int edge_type = type & IRQF_TRIGGER_MASK; - unsigned long flags; u8 new_type; switch (edge_type) { case IRQ_TYPE_EDGE_RISING: - new_type = TQMX86_GPII_RISING; + new_type = TQMX86_INT_TRIG_RISING; break; case IRQ_TYPE_EDGE_FALLING: - new_type = TQMX86_GPII_FALLING; + new_type = TQMX86_INT_TRIG_FALLING; break; case IRQ_TYPE_EDGE_BOTH: - new_type = TQMX86_INT_BOTH; + new_type = TQMX86_INT_TRIG_BOTH; break; default: return -EINVAL; /* not supported */ } - raw_spin_lock_irqsave(&gpio->spinlock, flags); - gpio->irq_type[offset] &= ~TQMX86_GPII_MASK; - gpio->irq_type[offset] |= new_type; - tqmx86_gpio_irq_config(gpio, offset); - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); + guard(raw_spinlock_irqsave)(&gpio->spinlock); + + gpio->irq_type[data->hwirq] &= ~TQMX86_INT_TRIG_MASK; + gpio->irq_type[data->hwirq] |= new_type; + tqmx86_gpio_irq_config(gpio, data->hwirq); return 0; } @@ -199,8 +225,8 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc) struct gpio_chip *chip = irq_desc_get_handler_data(desc); struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); struct irq_chip *irq_chip = irq_desc_get_chip(desc); - unsigned long irq_bits, flags; - int i; + unsigned long irq_bits; + int i, hwirq; u8 irq_status; chained_irq_enter(irq_chip, desc); @@ -210,32 +236,38 @@ static void tqmx86_gpio_irq_handler(struct irq_desc *desc) irq_bits = irq_status; - raw_spin_lock_irqsave(&gpio->spinlock, flags); - for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { - /* - * Edge-both triggers are implemented by flipping the edge - * trigger after each interrupt, as the controller only supports - * either rising or falling edge triggers, but not both. - * - * Internally, the TQMx86 GPIO controller has separate status - * registers for rising and falling edge interrupts. GPIIC - * configures which bits from which register are visible in the - * interrupt status register GPIIS and defines what triggers the - * parent IRQ line. Writing to GPIIS always clears both rising - * and falling interrupt flags internally, regardless of the - * currently configured trigger. - * - * In consequence, we can cleanly implement the edge-both - * trigger in software by first clearing the interrupt and then - * setting the new trigger based on the current GPIO input in - * tqmx86_gpio_irq_config() - even if an edge arrives between - * reading the input and setting the trigger, we will have a new - * interrupt pending. - */ - if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH) - tqmx86_gpio_irq_config(gpio, i); + scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { + for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { + hwirq = i + TQMX86_NGPO; + + /* + * Edge-both triggers are implemented by flipping the + * edge trigger after each interrupt, as the controller + * only supports either rising or falling edge triggers, + * but not both. + * + * Internally, the TQMx86 GPIO controller has separate + * status registers for rising and falling edge + * interrupts. GPIIC configures which bits from which + * register are visible in the interrupt status register + * GPIIS and defines what triggers the parent IRQ line. + * Writing to GPIIS always clears both rising and + * falling interrupt flags internally, regardless of the + * currently configured trigger. + * + * In consequence, we can cleanly implement the + * edge-both trigger in software by first clearing the + * interrupt and then setting the new trigger based on + * the current GPIO input in tqmx86_gpio_irq_config() - + * even if an edge arrives between reading the input and + * setting the trigger, we will have a new interrupt + * pending. + */ + if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) == + TQMX86_INT_TRIG_BOTH) + tqmx86_gpio_irq_config(gpio, hwirq); + } } - raw_spin_unlock_irqrestore(&gpio->spinlock, flags); for_each_set_bit(i, &irq_bits, TQMX86_NGPI) generic_handle_domain_irq(gpio->chip.irq.domain, diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c index 6c3fbf382dba..b9171bf66168 100644 --- a/drivers/gpio/gpio-twl6040.c +++ b/drivers/gpio/gpio-twl6040.c @@ -22,7 +22,7 @@ static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset) { - struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); + struct twl6040 *twl6040 = gpiochip_get_data(chip); int ret = 0; ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL); @@ -46,7 +46,7 @@ static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset, static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value) { - struct twl6040 *twl6040 = dev_get_drvdata(chip->parent->parent); + struct twl6040 *twl6040 = gpiochip_get_data(chip); int ret; u8 gpoctl; @@ -91,7 +91,7 @@ static int gpo_twl6040_probe(struct platform_device *pdev) twl6040gpo_chip.parent = &pdev->dev; - ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, NULL); + ret = devm_gpiochip_add_data(&pdev->dev, &twl6040gpo_chip, twl6040); if (ret < 0) { dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); twl6040gpo_chip.ngpio = 0; diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c index 91b6352c957c..e89f299f2140 100644 --- a/drivers/gpio/gpio-virtuser.c +++ b/drivers/gpio/gpio-virtuser.c @@ -1410,7 +1410,7 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) size_t num_entries = gpio_virtuser_get_lookup_count(dev); struct gpio_virtuser_lookup_entry *entry; struct gpio_virtuser_lookup *lookup; - unsigned int i = 0; + unsigned int i = 0, idx; lockdep_assert_held(&dev->lock); @@ -1424,12 +1424,12 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) return -ENOMEM; list_for_each_entry(lookup, &dev->lookup_list, siblings) { + idx = 0; list_for_each_entry(entry, &lookup->entry_list, siblings) { - table->table[i] = + table->table[i++] = GPIO_LOOKUP_IDX(entry->key, entry->offset < 0 ? U16_MAX : entry->offset, - lookup->con_id, i, entry->flags); - i++; + lookup->con_id, idx++, entry->flags); } } @@ -1439,6 +1439,15 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) return 0; } +static void +gpio_virtuser_remove_lookup_table(struct gpio_virtuser_device *dev) +{ + gpiod_remove_lookup_table(dev->lookup_table); + kfree(dev->lookup_table->dev_id); + kfree(dev->lookup_table); + dev->lookup_table = NULL; +} + static struct fwnode_handle * gpio_virtuser_make_device_swnode(struct gpio_virtuser_device *dev) { @@ -1487,10 +1496,8 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev) pdevinfo.fwnode = swnode; ret = gpio_virtuser_make_lookup_table(dev); - if (ret) { - fwnode_remove_software_node(swnode); - return ret; - } + if (ret) + goto err_remove_swnode; reinit_completion(&dev->probe_completion); dev->driver_bound = false; @@ -1498,23 +1505,31 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev) pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); - fwnode_remove_software_node(swnode); - return PTR_ERR(pdev); + goto err_remove_lookup_table; } wait_for_completion(&dev->probe_completion); bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier); if (!dev->driver_bound) { - platform_device_unregister(pdev); - fwnode_remove_software_node(swnode); - return -ENXIO; + ret = -ENXIO; + goto err_unregister_pdev; } dev->pdev = pdev; return 0; + +err_unregister_pdev: + platform_device_unregister(pdev); +err_remove_lookup_table: + gpio_virtuser_remove_lookup_table(dev); +err_remove_swnode: + fwnode_remove_software_node(swnode); + + return ret; } static void @@ -1526,10 +1541,33 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev) swnode = dev_fwnode(&dev->pdev->dev); platform_device_unregister(dev->pdev); + gpio_virtuser_remove_lookup_table(dev); fwnode_remove_software_node(swnode); dev->pdev = NULL; - gpiod_remove_lookup_table(dev->lookup_table); - kfree(dev->lookup_table); +} + +static void +gpio_virtuser_device_lockup_configfs(struct gpio_virtuser_device *dev, bool lock) +{ + struct configfs_subsystem *subsys = dev->group.cg_subsys; + struct gpio_virtuser_lookup_entry *entry; + struct gpio_virtuser_lookup *lookup; + + /* + * The device only needs to depend on leaf lookup entries. This is + * sufficient to lock up all the configfs entries that the + * instantiated, alive device depends on. + */ + list_for_each_entry(lookup, &dev->lookup_list, siblings) { + list_for_each_entry(entry, &lookup->entry_list, siblings) { + if (lock) + WARN_ON(configfs_depend_item_unlocked( + subsys, &entry->group.cg_item)); + else + configfs_undepend_item_unlocked( + &entry->group.cg_item); + } + } } static ssize_t @@ -1544,15 +1582,24 @@ gpio_virtuser_device_config_live_store(struct config_item *item, if (ret) return ret; - guard(mutex)(&dev->lock); + if (live) + gpio_virtuser_device_lockup_configfs(dev, true); - if (live == gpio_virtuser_device_is_live(dev)) - return -EPERM; + scoped_guard(mutex, &dev->lock) { + if (live == gpio_virtuser_device_is_live(dev)) + ret = -EPERM; + else if (live) + ret = gpio_virtuser_device_activate(dev); + else + gpio_virtuser_device_deactivate(dev); + } - if (live) - ret = gpio_virtuser_device_activate(dev); - else - gpio_virtuser_device_deactivate(dev); + /* + * Undepend is required only if device disablement (live == 0) + * succeeds or if device enablement (live == 1) fails. + */ + if (live == !!ret) + gpio_virtuser_device_lockup_configfs(dev, false); return ret ?: count; } diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index c6a8f2c82680..792d94c49077 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -65,7 +65,7 @@ struct xgpio_instance { DECLARE_BITMAP(state, 64); DECLARE_BITMAP(last_irq_read, 64); DECLARE_BITMAP(dir, 64); - spinlock_t gpio_lock; /* For serializing operations */ + raw_spinlock_t gpio_lock; /* For serializing operations */ int irq; DECLARE_BITMAP(enable, 64); DECLARE_BITMAP(rising_edge, 64); @@ -179,14 +179,14 @@ static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) struct xgpio_instance *chip = gpiochip_get_data(gc); int bit = xgpio_to_bit(chip, gpio); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); /* Write to GPIO signal and set its direction to output */ __assign_bit(bit, chip->state, val); xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); } /** @@ -210,7 +210,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64); bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); bitmap_replace(state, chip->state, hw_bits, hw_mask, 64); @@ -218,7 +218,7 @@ static void xgpio_set_multiple(struct gpio_chip *gc, unsigned long *mask, bitmap_copy(chip->state, state, 64); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); } /** @@ -236,13 +236,13 @@ static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) struct xgpio_instance *chip = gpiochip_get_data(gc); int bit = xgpio_to_bit(chip, gpio); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); /* Set the GPIO bit in shadow register and set direction as input */ __set_bit(bit, chip->dir); xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); return 0; } @@ -265,7 +265,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) struct xgpio_instance *chip = gpiochip_get_data(gc); int bit = xgpio_to_bit(chip, gpio); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); /* Write state of GPIO signal */ __assign_bit(bit, chip->state, val); @@ -275,7 +275,7 @@ static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) __clear_bit(bit, chip->dir); xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir); - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); return 0; } @@ -398,7 +398,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) int bit = xgpio_to_bit(chip, irq_offset); u32 mask = BIT(bit / 32), temp; - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); __clear_bit(bit, chip->enable); @@ -408,7 +408,7 @@ static void xgpio_irq_mask(struct irq_data *irq_data) temp &= ~mask; xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp); } - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); gpiochip_disable_irq(&chip->gc, irq_offset); } @@ -428,7 +428,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) gpiochip_enable_irq(&chip->gc, irq_offset); - spin_lock_irqsave(&chip->gpio_lock, flags); + raw_spin_lock_irqsave(&chip->gpio_lock, flags); __set_bit(bit, chip->enable); @@ -447,7 +447,7 @@ static void xgpio_irq_unmask(struct irq_data *irq_data) xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val); } - spin_unlock_irqrestore(&chip->gpio_lock, flags); + raw_spin_unlock_irqrestore(&chip->gpio_lock, flags); } /** @@ -512,7 +512,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) chained_irq_enter(irqchip, desc); - spin_lock(&chip->gpio_lock); + raw_spin_lock(&chip->gpio_lock); xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all); @@ -529,7 +529,7 @@ static void xgpio_irqhandler(struct irq_desc *desc) bitmap_copy(chip->last_irq_read, all, 64); bitmap_or(all, rising, falling, 64); - spin_unlock(&chip->gpio_lock); + raw_spin_unlock(&chip->gpio_lock); dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling); @@ -620,7 +620,7 @@ static int xgpio_probe(struct platform_device *pdev) bitmap_set(chip->hw_map, 0, width[0]); bitmap_set(chip->hw_map, 32, width[1]); - spin_lock_init(&chip->gpio_lock); + raw_spin_lock_init(&chip->gpio_lock); chip->gc.base = -1; chip->gc.ngpio = bitmap_weight(chip->hw_map, 64); diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c index 51d2475c05c5..f21dbc28cf2c 100644 --- a/drivers/gpio/gpiolib-swnode.c +++ b/drivers/gpio/gpiolib-swnode.c @@ -141,7 +141,7 @@ int swnode_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) const struct software_node swnode_gpio_undefined = { .name = GPIOLIB_SWNODE_UNDEFINED_NAME, }; -EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, GPIO_SWNODE); +EXPORT_SYMBOL_NS_GPL(swnode_gpio_undefined, "GPIO_SWNODE"); static int __init swnode_gpio_init(void) { |