diff options
Diffstat (limited to 'drivers/gpio')
42 files changed, 431 insertions, 494 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c7a174edeaa3..50020cacf1b4 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -27,12 +27,12 @@ config GPIOLIB_FASTPATH_LIMIT range 32 512 default 512 help - This adjusts the point at which certain APIs will switch from - using a stack allocated buffer to a dynamically allocated buffer. + This adjusts the point at which certain APIs will switch from + using a stack allocated buffer to a dynamically allocated buffer. - You shouldn't need to change this unless you really need to - optimize either stack space or performance. Change this carefully - since setting an incorrect value could cause stack corruption. + You shouldn't need to change this unless you really need to + optimize either stack space or performance. Change this carefully + since setting an incorrect value could cause stack corruption. config OF_GPIO def_bool y @@ -320,7 +320,7 @@ config GPIO_MENZ127 depends on MCB select GPIO_GENERIC help - Say yes here to support the MEN 16Z127 GPIO Controller + Say yes here to support the MEN 16Z127 GPIO Controller config GPIO_MM_LANTIQ bool "Lantiq Memory mapped GPIOs" @@ -848,11 +848,11 @@ config GPIO_MAX732X Input and Output (designed by 'P'). The combinations are listed below: - 8 bits: max7319 (8I), max7320 (8O), max7321 (8P), - max7322 (4I4O), max7323 (4P4O) + 8 bits: max7319 (8I), max7320 (8O), max7321 (8P), + max7322 (4I4O), max7323 (4P4O) - 16 bits: max7324 (8I8O), max7325 (8P8O), - max7326 (4I12O), max7327 (4P12O) + 16 bits: max7324 (8I8O), max7325 (8P8O), + max7326 (4I12O), max7327 (4P12O) Board setup code must specify the model to use, and the start number for these GPIOs. @@ -879,17 +879,17 @@ config GPIO_PCA953X SMBus I/O expanders, made mostly by NXP or TI. Compatible models include: - 4 bits: pca9536, pca9537 + 4 bits: pca9536, pca9537 - 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554, - pca9556, pca9557, pca9574, tca6408, tca9554, xra1202 + 8 bits: max7310, max7315, pca6107, pca9534, pca9538, pca9554, + pca9556, pca9557, pca9574, tca6408, tca9554, xra1202 - 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575, - tca6416 + 16 bits: max7312, max7313, pca9535, pca9539, pca9555, pca9575, + tca6416 - 24 bits: tca6424 + 24 bits: tca6424 - 40 bits: pca9505, pca9698 + 40 bits: pca9505, pca9698 config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" @@ -911,7 +911,7 @@ config GPIO_PCF857X 8 bits: pcf8574, pcf8574a, pca8574, pca8574a, pca9670, pca9672, pca9674, pca9674a, - max7328, max7329 + max7328, max7329 16 bits: pcf8575, pcf8575c, pca8575, pca9671, pca9673, pca9675 @@ -1033,9 +1033,9 @@ config HTC_EGPIO bool "HTC EGPIO support" depends on GPIOLIB && ARM help - This driver supports the CPLD egpio chip present on - several HTC phones. It provides basic support for input - pins, output pins, and irqs. + This driver supports the CPLD egpio chip present on + several HTC phones. It provides basic support for input + pins, output pins, and irqs. config GPIO_JANZ_TTL tristate "Janz VMOD-TTL Digital IO Module" @@ -1071,7 +1071,7 @@ config GPIO_LP873X on LP873X PMICs. This driver can also be built as a module. If so, the module will be - called gpio-lp873x. + called gpio-lp873x. config GPIO_LP87565 tristate "TI LP87565 GPIO" @@ -1429,9 +1429,9 @@ config GPIO_VIPERBOARD Say yes here to access the GPIO signals of Nano River Technologies Viperboard. There are two GPIO chips on the board: gpioa and gpiob. - See viperboard API specification and Nano - River Tech's viperboard.h for detailed meaning - of the module parameters. + See viperboard API specification and Nano + River Tech's viperboard.h for detailed meaning + of the module parameters. endmenu diff --git a/drivers/gpio/gpio-74xx-mmio.c b/drivers/gpio/gpio-74xx-mmio.c index 49616ec815ee..04247075091d 100644 --- a/drivers/gpio/gpio-74xx-mmio.c +++ b/drivers/gpio/gpio-74xx-mmio.c @@ -106,7 +106,6 @@ static int mmio_74xx_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) static int mmio_74xx_gpio_probe(struct platform_device *pdev) { struct mmio_74xx_gpio_priv *priv; - struct resource *res; void __iomem *dat; int err; @@ -116,8 +115,7 @@ static int mmio_74xx_gpio_probe(struct platform_device *pdev) priv->flags = (uintptr_t)of_device_get_match_data(&pdev->dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dat = devm_ioremap_resource(&pdev->dev, res); + dat = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dat)) return PTR_ERR(dat); diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 91b90c0cea73..12acdac85820 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -132,8 +132,10 @@ static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset) if (err < 0) goto out; - if (err & BIT(pos)) - err = -EACCES; + if (value & BIT(pos)) { + err = -EPERM; + goto out; + } err = 0; diff --git a/drivers/gpio/gpio-amdpt.c b/drivers/gpio/gpio-amdpt.c index 9b78dc837603..1ffd7c2d1285 100644 --- a/drivers/gpio/gpio-amdpt.c +++ b/drivers/gpio/gpio-amdpt.c @@ -78,7 +78,6 @@ static int pt_gpio_probe(struct platform_device *pdev) struct acpi_device *acpi_dev; acpi_handle handle = ACPI_HANDLE(dev); struct pt_gpio_chip *pt_gpio; - struct resource *res_mem; int ret = 0; if (acpi_bus_get_device(handle, &acpi_dev)) { @@ -90,12 +89,7 @@ static int pt_gpio_probe(struct platform_device *pdev) if (!pt_gpio) return -ENOMEM; - res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res_mem) { - dev_err(&pdev->dev, "Failed to get MMIO resource for PT GPIO.\n"); - return -EINVAL; - } - pt_gpio->reg_base = devm_ioremap_resource(dev, res_mem); + pt_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pt_gpio->reg_base)) { dev_err(&pdev->dev, "Failed to map MMIO resource for PT GPIO.\n"); return PTR_ERR(pt_gpio->reg_base); diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index 854bce4fb9e7..0f1b55c7c361 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -1156,15 +1156,13 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) { const struct of_device_id *gpio_id; struct aspeed_gpio *gpio; - struct resource *res; int rc, i, banks; gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gpio->base = devm_ioremap_resource(&pdev->dev, res); + gpio->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(gpio->base)) return PTR_ERR(gpio->base); @@ -1224,6 +1222,8 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) gpio->offset_timer = devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL); + if (!gpio->offset_timer) + return -ENOMEM; return aspeed_gpio_setup_irqs(gpio, pdev); } diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index c5536a509b59..9fa6d3a967d2 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -568,7 +568,6 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct of_device_id *match; - struct resource *res; struct bcm_kona_gpio_bank *bank; struct bcm_kona_gpio *kona_gpio; struct gpio_chip *chip; @@ -618,8 +617,7 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev) return -ENXIO; } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - kona_gpio->reg_base = devm_ioremap_resource(dev, res); + kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(kona_gpio->reg_base)) { ret = -ENXIO; goto err_irq_domain; diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c index aec8d5df9f30..712ae212b0b4 100644 --- a/drivers/gpio/gpio-cadence.c +++ b/drivers/gpio/gpio-cadence.c @@ -148,7 +148,6 @@ static struct irq_chip cdns_gpio_irqchip = { static int cdns_gpio_probe(struct platform_device *pdev) { struct cdns_gpio_chip *cgpio; - struct resource *res; int ret, irq; u32 dir_prev; u32 num_gpios = 32; @@ -157,8 +156,7 @@ static int cdns_gpio_probe(struct platform_device *pdev) if (!cgpio) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - cgpio->regs = devm_ioremap_resource(&pdev->dev, res); + cgpio->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(cgpio->regs)) return PTR_ERR(cgpio->regs); diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index 52fd63f02134..0fbbb0edc0ba 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -19,7 +19,6 @@ static int clps711x_gpio_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; void __iomem *dat, *dir; struct gpio_chip *gc; - struct resource *res; int err, id; if (!np) @@ -33,13 +32,11 @@ static int clps711x_gpio_probe(struct platform_device *pdev) if (!gc) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dat = devm_ioremap_resource(&pdev->dev, res); + dat = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(dat)) return PTR_ERR(dat); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - dir = devm_ioremap_resource(&pdev->dev, res); + dir = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(dir)) return PTR_ERR(dir); diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 84ae04402f70..d3eda65fd6d3 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -655,7 +655,6 @@ MODULE_DEVICE_TABLE(acpi, dwapb_acpi_match); static int dwapb_gpio_probe(struct platform_device *pdev) { unsigned int i; - struct resource *res; struct dwapb_gpio *gpio; int err; struct device *dev = &pdev->dev; @@ -688,8 +687,7 @@ static int dwapb_gpio_probe(struct platform_device *pdev) if (!gpio->ports) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gpio->regs = devm_ioremap_resource(&pdev->dev, res); + gpio->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(gpio->regs)) return PTR_ERR(gpio->regs); diff --git a/drivers/gpio/gpio-exar.c b/drivers/gpio/gpio-exar.c index 0ecd2369c2ca..a09d2f9ebacc 100644 --- a/drivers/gpio/gpio-exar.c +++ b/drivers/gpio/gpio-exar.c @@ -148,6 +148,8 @@ static int gpio_exar_probe(struct platform_device *pdev) mutex_init(&exar_gpio->lock); index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); + if (index < 0) + goto err_destroy; sprintf(exar_gpio->name, "exar_gpio%d", index); exar_gpio->gpio_chip.label = exar_gpio->name; diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c index 45fe125823a8..8ff8ce2970d9 100644 --- a/drivers/gpio/gpio-ftgpio010.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -225,7 +225,6 @@ static int ftgpio_gpio_set_config(struct gpio_chip *gc, unsigned int offset, static int ftgpio_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; struct ftgpio_gpio *g; int irq; int ret; @@ -236,8 +235,7 @@ static int ftgpio_gpio_probe(struct platform_device *pdev) g->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - g->base = devm_ioremap_resource(dev, res); + g->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(g->base)) return PTR_ERR(g->base); diff --git a/drivers/gpio/gpio-hlwd.c b/drivers/gpio/gpio-hlwd.c index a7b17897356e..e5fa00f8145f 100644 --- a/drivers/gpio/gpio-hlwd.c +++ b/drivers/gpio/gpio-hlwd.c @@ -208,7 +208,6 @@ static int hlwd_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) static int hlwd_gpio_probe(struct platform_device *pdev) { struct hlwd_gpio *hlwd; - struct resource *regs_resource; u32 ngpios; int res; @@ -216,8 +215,7 @@ static int hlwd_gpio_probe(struct platform_device *pdev) if (!hlwd) return -ENOMEM; - regs_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hlwd->regs = devm_ioremap_resource(&pdev->dev, regs_resource); + hlwd->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hlwd->regs)) return PTR_ERR(hlwd->regs); diff --git a/drivers/gpio/gpio-iop.c b/drivers/gpio/gpio-iop.c index 8d62db447ec1..11b77d868c89 100644 --- a/drivers/gpio/gpio-iop.c +++ b/drivers/gpio/gpio-iop.c @@ -21,7 +21,6 @@ static int iop3xx_gpio_probe(struct platform_device *pdev) { - struct resource *res; struct gpio_chip *gc; void __iomem *base; int err; @@ -30,8 +29,7 @@ static int iop3xx_gpio_probe(struct platform_device *pdev) if (!gc) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 6b9bf8b7bf16..b97a91166497 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -147,7 +147,6 @@ static int ttl_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct ttl_module *mod; struct gpio_chip *gpio; - struct resource *res; int ret; pdata = dev_get_platdata(&pdev->dev); @@ -164,8 +163,7 @@ static int ttl_probe(struct platform_device *pdev) spin_lock_init(&mod->lock); /* get access to the MODULbus registers for this module */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mod->regs = devm_ioremap_resource(dev, res); + mod->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mod->regs)) return PTR_ERR(mod->regs); diff --git a/drivers/gpio/gpio-loongson1.c b/drivers/gpio/gpio-loongson1.c index fca84ccac35c..1b1ee94eeab4 100644 --- a/drivers/gpio/gpio-loongson1.c +++ b/drivers/gpio/gpio-loongson1.c @@ -47,15 +47,13 @@ static int ls1x_gpio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct gpio_chip *gc; - struct resource *res; int ret; gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); if (!gc) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gpio_reg_base = devm_ioremap_resource(dev, res); + gpio_reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(gpio_reg_base)) return PTR_ERR(gpio_reg_base); diff --git a/drivers/gpio/gpio-lpc18xx.c b/drivers/gpio/gpio-lpc18xx.c index d441dbaed7a3..d711ae06747e 100644 --- a/drivers/gpio/gpio-lpc18xx.c +++ b/drivers/gpio/gpio-lpc18xx.c @@ -340,10 +340,7 @@ static int lpc18xx_gpio_probe(struct platform_device *pdev) index = of_property_match_string(dev->of_node, "reg-names", "gpio"); if (index < 0) { /* To support backward compatibility take the first resource */ - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gc->base = devm_ioremap_resource(dev, res); + gc->base = devm_platform_ioremap_resource(pdev, 0); } else { struct resource res; diff --git a/drivers/gpio/gpio-mb86s7x.c b/drivers/gpio/gpio-mb86s7x.c index 3134c0d2bfe4..9308081e0a4a 100644 --- a/drivers/gpio/gpio-mb86s7x.c +++ b/drivers/gpio/gpio-mb86s7x.c @@ -146,7 +146,6 @@ static void mb86s70_gpio_set(struct gpio_chip *gc, unsigned gpio, int value) static int mb86s70_gpio_probe(struct platform_device *pdev) { struct mb86s70_gpio_chip *gchip; - struct resource *res; int ret; gchip = devm_kzalloc(&pdev->dev, sizeof(*gchip), GFP_KERNEL); @@ -155,8 +154,7 @@ static int mb86s70_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gchip); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gchip->base = devm_ioremap_resource(&pdev->dev, res); + gchip->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(gchip->base)) return PTR_ERR(gchip->base); diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index 50bdc29591c0..6f904c874678 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -134,17 +134,6 @@ static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) unsigned long pinmask = bgpio_line2mask(gc, gpio); bool dir = !!(gc->bgpio_dir & pinmask); - /* - * If the direction is OUT we read the value from the SET - * register, and if the direction is IN we read the value - * from the DAT register. - * - * If the direction bits are inverted, naturally this gets - * inverted too. - */ - if (gc->bgpio_dir_inverted) - dir = !dir; - if (dir) return !!(gc->read_reg(gc->reg_set) & pinmask); else @@ -164,14 +153,8 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, /* Make sure we first clear any bits that are zero when we read the register */ *bits &= ~*mask; - /* Exploit the fact that we know which directions are set */ - if (gc->bgpio_dir_inverted) { - set_mask = *mask & ~gc->bgpio_dir; - get_mask = *mask & gc->bgpio_dir; - } else { - set_mask = *mask & gc->bgpio_dir; - get_mask = *mask & ~gc->bgpio_dir; - } + set_mask = *mask & gc->bgpio_dir; + get_mask = *mask & ~gc->bgpio_dir; if (set_mask) *bits |= gc->read_reg(gc->reg_set) & set_mask; @@ -372,11 +355,12 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) spin_lock_irqsave(&gc->bgpio_lock, flags); - if (gc->bgpio_dir_inverted) - gc->bgpio_dir |= bgpio_line2mask(gc, gpio); - else - gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); - gc->write_reg(gc->reg_dir, gc->bgpio_dir); + gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); + + if (gc->reg_dir_in) + gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir); + if (gc->reg_dir_out) + gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); spin_unlock_irqrestore(&gc->bgpio_lock, flags); @@ -385,11 +369,16 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) { - /* Return 0 if output, 1 of input */ - if (gc->bgpio_dir_inverted) - return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); - else - return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); + /* Return 0 if output, 1 if input */ + if (gc->bgpio_dir_unreadable) + return !(gc->bgpio_dir & bgpio_line2mask(gc, gpio)); + if (gc->reg_dir_out) + return !(gc->read_reg(gc->reg_dir_out) & bgpio_line2mask(gc, gpio)); + if (gc->reg_dir_in) + return !!(gc->read_reg(gc->reg_dir_in) & bgpio_line2mask(gc, gpio)); + + /* This should not happen */ + return 1; } static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) @@ -400,11 +389,12 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) spin_lock_irqsave(&gc->bgpio_lock, flags); - if (gc->bgpio_dir_inverted) - gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); - else - gc->bgpio_dir |= bgpio_line2mask(gc, gpio); - gc->write_reg(gc->reg_dir, gc->bgpio_dir); + gc->bgpio_dir |= bgpio_line2mask(gc, gpio); + + if (gc->reg_dir_in) + gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir); + if (gc->reg_dir_out) + gc->write_reg(gc->reg_dir_out, gc->bgpio_dir); spin_unlock_irqrestore(&gc->bgpio_lock, flags); @@ -537,19 +527,12 @@ static int bgpio_setup_direction(struct gpio_chip *gc, void __iomem *dirin, unsigned long flags) { - if (dirout && dirin) { - return -EINVAL; - } else if (dirout) { - gc->reg_dir = dirout; - gc->direction_output = bgpio_dir_out; - gc->direction_input = bgpio_dir_in; - gc->get_direction = bgpio_get_dir; - } else if (dirin) { - gc->reg_dir = dirin; + if (dirout || dirin) { + gc->reg_dir_out = dirout; + gc->reg_dir_in = dirin; gc->direction_output = bgpio_dir_out; gc->direction_input = bgpio_dir_in; gc->get_direction = bgpio_get_dir; - gc->bgpio_dir_inverted = true; } else { if (flags & BGPIOF_NO_OUTPUT) gc->direction_output = bgpio_dir_out_err; @@ -588,11 +571,11 @@ static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin) * @dirout: MMIO address for the register to set the line as OUTPUT. It is assumed * that setting a line to 1 in this register will turn that line into an * output line. Conversely, setting the line to 0 will turn that line into - * an input. Either this or @dirin can be defined, but never both. + * an input. * @dirin: MMIO address for the register to set this line as INPUT. It is assumed * that setting a line to 1 in this register will turn that line into an * input line. Conversely, setting the line to 0 will turn that line into - * an output. Either this or @dirout can be defined, but never both. + * an output. * @flags: Different flags that will affect the behaviour of the device, such as * endianness etc. */ @@ -634,8 +617,28 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, if (gc->set == bgpio_set_set && !(flags & BGPIOF_UNREADABLE_REG_SET)) gc->bgpio_data = gc->read_reg(gc->reg_set); - if (gc->reg_dir && !(flags & BGPIOF_UNREADABLE_REG_DIR)) - gc->bgpio_dir = gc->read_reg(gc->reg_dir); + + if (flags & BGPIOF_UNREADABLE_REG_DIR) + gc->bgpio_dir_unreadable = true; + + /* + * Inspect hardware to find initial direction setting. + */ + if ((gc->reg_dir_out || gc->reg_dir_in) && + !(flags & BGPIOF_UNREADABLE_REG_DIR)) { + if (gc->reg_dir_out) + gc->bgpio_dir = gc->read_reg(gc->reg_dir_out); + else if (gc->reg_dir_in) + gc->bgpio_dir = ~gc->read_reg(gc->reg_dir_in); + /* + * If we have two direction registers, synchronise + * input setting to output setting, the library + * can not handle a line being input and output at + * the same time. + */ + if (gc->reg_dir_out && gc->reg_dir_in) + gc->write_reg(gc->reg_dir_in, ~gc->bgpio_dir); + } return ret; } diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 154d959e8993..b6a4efce7c92 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -204,8 +204,8 @@ static ssize_t gpio_mockup_debugfs_read(struct file *file, struct gpio_mockup_chip *chip; struct seq_file *sfile; struct gpio_chip *gc; + int val, cnt; char buf[3]; - int val, rv; if (*ppos != 0) return 0; @@ -216,13 +216,9 @@ static ssize_t gpio_mockup_debugfs_read(struct file *file, gc = &chip->gc; val = gpio_mockup_get(gc, priv->offset); - snprintf(buf, sizeof(buf), "%d\n", val); + cnt = snprintf(buf, sizeof(buf), "%d\n", val); - rv = copy_to_user(usr_buf, buf, sizeof(buf)); - if (rv) - return rv; - - return sizeof(buf) - 1; + return simple_read_from_buffer(usr_buf, size, ppos, buf, cnt); } static ssize_t gpio_mockup_debugfs_write(struct file *file, diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c index 74401e0adb29..79654fb2e50f 100644 --- a/drivers/gpio/gpio-mt7621.c +++ b/ |