diff options
Diffstat (limited to 'drivers')
47 files changed, 756 insertions, 833 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0f91600c27ae..9370276fe7fe 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -26,12 +26,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 @@ -319,7 +319,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" @@ -329,20 +329,6 @@ config GPIO_MM_LANTIQ (EBU) found on Lantiq SoCs. The gpios are output only as they are created by attaching a 16bit latch to the bus. -config GPIO_MOCKUP - tristate "GPIO Testing Driver" - depends on GPIOLIB && SYSFS - select GPIO_SYSFS - select GPIOLIB_IRQCHIP - select IRQ_SIM - help - This enables GPIO Testing driver, which provides a way to test GPIO - subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS - must be selected for this test. - User could use it through the script in - tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in - it. - config GPIO_MPC5200 def_bool y depends on PPC_MPC52xx @@ -861,11 +847,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. @@ -892,17 +878,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" @@ -924,7 +910,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 @@ -1046,9 +1032,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" @@ -1084,7 +1070,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" @@ -1315,6 +1301,13 @@ config GPIO_MERRIFIELD help Say Y here to support Intel Merrifield GPIO. +config GPIO_MLXBF + tristate "Mellanox BlueField SoC GPIO" + depends on (MELLANOX_PLATFORM && ARM64 && ACPI) || (64BIT && COMPILE_TEST) + select GPIO_GENERIC + help + Say Y here if you want GPIO support on Mellanox BlueField SoC. + config GPIO_ML_IOH tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support" depends on X86 || COMPILE_TEST @@ -1435,10 +1428,22 @@ 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 +config GPIO_MOCKUP + tristate "GPIO Testing Driver" + depends on GPIOLIB + select IRQ_SIM + help + This enables GPIO Testing driver, which provides a way to test GPIO + subsystem through sysfs(or char device) and debugfs. GPIO_SYSFS + must be selected for this test. + User could use it through the script in + tools/testing/selftests/gpio/gpio-mockup.sh. Reference the usage in + it. + endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 54d55274b93a..db8d854f9aea 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o obj-$(CONFIG_GPIO_MERRIFIELD) += gpio-merrifield.o obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o +obj-$(CONFIG_GPIO_MLXBF) += gpio-mlxbf.o obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o obj-$(CONFIG_GPIO_MOCKUP) += gpio-mockup.o diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index fb7b620763a2..e81307f9754e 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c @@ -1,21 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver * * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/spi/spi.h> -#include <linux/gpio/driver.h> #include <linux/gpio/consumer.h> -#include <linux/slab.h> +#include <linux/gpio/driver.h> #include <linux/module.h> +#include <linux/mutex.h> +#include <linux/property.h> +#include <linux/slab.h> +#include <linux/spi/spi.h> #define GEN_74X164_NUMBER_GPIOS 8 @@ -116,10 +113,9 @@ static int gen_74x164_probe(struct spi_device *spi) if (ret < 0) return ret; - if (of_property_read_u32(spi->dev.of_node, "registers-number", - &nregs)) { - dev_err(&spi->dev, - "Missing registers-number property in the DT.\n"); + ret = device_property_read_u32(&spi->dev, "registers-number", &nregs); + if (ret) { + dev_err(&spi->dev, "Missing 'registers-number' property.\n"); return -EINVAL; } 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-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 217507002dbc..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); 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-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-mlxbf.c b/drivers/gpio/gpio-mlxbf.c new file mode 100644 index 000000000000..894aaf55fc96 --- /dev/null +++ b/drivers/gpio/gpio-mlxbf.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/acpi.h> +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/gpio/driver.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm.h> +#include <linux/resource.h> +#include <linux/types.h> + +/* Number of pins on BlueField */ +#define MLXBF_GPIO_NR 54 + +/* Pad Electrical Controls. */ +#define MLXBF_GPIO_PAD_CONTROL_FIRST_WORD 0x0700 +#define MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD 0x0708 +#define MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD 0x0710 +#define MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD 0x0718 + +#define MLXBF_GPIO_PIN_DIR_I 0x1040 +#define MLXBF_GPIO_PIN_DIR_O 0x1048 +#define MLXBF_GPIO_PIN_STATE 0x1000 +#define MLXBF_GPIO_SCRATCHPAD 0x20 + +#ifdef CONFIG_PM +struct mlxbf_gpio_context_save_regs { + u64 scratchpad; + u64 pad_control[MLXBF_GPIO_NR]; + u64 pin_dir_i; + u64 pin_dir_o; +}; +#endif + +/* Device state structure. */ +struct mlxbf_gpio_state { + struct gpio_chip gc; + + /* Memory Address */ + void __iomem *base; + +#ifdef CONFIG_PM + struct mlxbf_gpio_context_save_regs csave_regs; +#endif +}; + +static int mlxbf_gpio_probe(struct platform_device *pdev) +{ + struct mlxbf_gpio_state *gs; + struct device *dev = &pdev->dev; + struct gpio_chip *gc; + int ret; + + gs = devm_kzalloc(&pdev->dev, sizeof(*gs), GFP_KERNEL); + if (!gs) + return -ENOMEM; + + gs->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(gs->base)) + return PTR_ERR(gs->base); + + gc = &gs->gc; + ret = bgpio_init(gc, dev, 8, + gs->base + MLXBF_GPIO_PIN_STATE, + NULL, + NULL, + gs->base + MLXBF_GPIO_PIN_DIR_O, + gs->base + MLXBF_GPIO_PIN_DIR_I, + 0); + if (ret) + return -ENODEV; + + gc->owner = THIS_MODULE; + gc->ngpio = MLXBF_GPIO_NR; + + ret = devm_gpiochip_add_data(dev, &gs->gc, gs); + if (ret) { + dev_err(&pdev->dev, "Failed adding memory mapped gpiochip\n"); + return ret; + } + + platform_set_drvdata(pdev, gs); + dev_info(&pdev->dev, "registered Mellanox BlueField GPIO"); + return 0; +} + +#ifdef CONFIG_PM +static int mlxbf_gpio_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mlxbf_gpio_state *gs = platform_get_drvdata(pdev); + + gs->csave_regs.scratchpad = readq(gs->base + MLXBF_GPIO_SCRATCHPAD); + gs->csave_regs.pad_control[0] = + readq(gs->base + MLXBF_GPIO_PAD_CONTROL_FIRST_WORD); + gs->csave_regs.pad_control[1] = + readq(gs->base + MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD); + gs->csave_regs.pad_control[2] = + readq(gs->base + MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD); + gs->csave_regs.pad_control[3] = + readq(gs->base + MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD); + gs->csave_regs.pin_dir_i = readq(gs->base + MLXBF_GPIO_PIN_DIR_I); + gs->csave_regs.pin_dir_o = readq(gs->base + MLXBF_GPIO_PIN_DIR_O); + + return 0; +} + +static int mlxbf_gpio_resume(struct platform_device *pdev) +{ + struct mlxbf_gpio_state *gs = pla |