diff options
| author | Kees Cook <kees+treewide@kernel.org> | 2026-09-02 15:31:14 -0700 |
|---|---|---|
| committer | Kees Cook <kees@kernel.org> | 2026-09-04 21:37:00 -0700 |
| commit | 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d (patch) | |
| tree | c65086f9bdcd48c6360fb7cb4598bca084da1f32 /drivers/gpio/gpio-mlxbf.c | |
| download | linux-stable-3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d.tar.gz linux-stable-3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d.zip | |
treewide: refresh kmalloc_obj() conversionsgrafted
This is another run of the Coccinelle script for converting kmalloc()
family of allocations to kmalloc_obj() via the existing rules in
scripts/coccinelle/api/kmalloc_objs.cocci
This catches both the set of kmalloc() uses added since the first
kmalloc_obj() conversions in v7.0 and adds a large group missed in the
first pass due to Coccinelle not interacting well with the cleanup.h
scoped_...() family of macros[1]. I worked around this with spatch's
"--macro-file" argument to a file with all the scoped_...() macros mapped
to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control
flow indicator I could find.
Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc,
riscv, and s390 with no new warnings.
Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1]
Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2]
Signed-off-by: Kees Cook <kees+treewide@kernel.org>
Diffstat (limited to 'drivers/gpio/gpio-mlxbf.c')
| -rw-r--r-- | drivers/gpio/gpio-mlxbf.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-mlxbf.c b/drivers/gpio/gpio-mlxbf.c new file mode 100644 index 000000000..a18fedbc4 --- /dev/null +++ b/drivers/gpio/gpio-mlxbf.c @@ -0,0 +1,157 @@ +// 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/gpio/generic.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_generic_chip chip; + + /* 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 gpio_generic_chip_config config; + 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->chip.gc; + + config = (struct gpio_generic_chip_config) { + .dev = dev, + .sz = 8, + .dat = gs->base + MLXBF_GPIO_PIN_STATE, + .dirout = gs->base + MLXBF_GPIO_PIN_DIR_O, + .dirin = gs->base + MLXBF_GPIO_PIN_DIR_I, + }; + + ret = gpio_generic_chip_init(&gs->chip, &config); + if (ret) + return -ENODEV; + + gc->owner = THIS_MODULE; + gc->ngpio = MLXBF_GPIO_NR; + + ret = devm_gpiochip_add_data(dev, &gs->chip.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 = platform_get_drvdata(pdev); + + writeq(gs->csave_regs.scratchpad, gs->base + MLXBF_GPIO_SCRATCHPAD); + writeq(gs->csave_regs.pad_control[0], + gs->base + MLXBF_GPIO_PAD_CONTROL_FIRST_WORD); + writeq(gs->csave_regs.pad_control[1], + gs->base + MLXBF_GPIO_PAD_CONTROL_1_FIRST_WORD); + writeq(gs->csave_regs.pad_control[2], + gs->base + MLXBF_GPIO_PAD_CONTROL_2_FIRST_WORD); + writeq(gs->csave_regs.pad_control[3], + gs->base + MLXBF_GPIO_PAD_CONTROL_3_FIRST_WORD); + writeq(gs->csave_regs.pin_dir_i, gs->base + MLXBF_GPIO_PIN_DIR_I); + writeq(gs->csave_regs.pin_dir_o, gs->base + MLXBF_GPIO_PIN_DIR_O); + + return 0; +} +#endif + +static const struct acpi_device_id __maybe_unused mlxbf_gpio_acpi_match[] = { + { "MLNXBF02", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, mlxbf_gpio_acpi_match); + +static struct platform_driver mlxbf_gpio_driver = { + .driver = { + .name = "mlxbf_gpio", + .acpi_match_table = ACPI_PTR(mlxbf_gpio_acpi_match), + }, + .probe = mlxbf_gpio_probe, +#ifdef CONFIG_PM + .suspend = mlxbf_gpio_suspend, + .resume = mlxbf_gpio_resume, +#endif +}; + +module_platform_driver(mlxbf_gpio_driver); + +MODULE_DESCRIPTION("Mellanox BlueField GPIO Driver"); +MODULE_AUTHOR("Mellanox Technologies"); +MODULE_LICENSE("GPL"); |
