1bc0ae0e7SAsmaa Mnebhi // SPDX-License-Identifier: GPL-2.0 2bc0ae0e7SAsmaa Mnebhi 3bc0ae0e7SAsmaa Mnebhi #include <linux/bitfield.h> 4bc0ae0e7SAsmaa Mnebhi #include <linux/bitops.h> 5bc0ae0e7SAsmaa Mnebhi #include <linux/device.h> 6bc0ae0e7SAsmaa Mnebhi #include <linux/gpio/driver.h> 7bc0ae0e7SAsmaa Mnebhi #include <linux/io.h> 8bc0ae0e7SAsmaa Mnebhi #include <linux/ioport.h> 9bc0ae0e7SAsmaa Mnebhi #include <linux/kernel.h> 10*603607e7SAndy Shevchenko #include <linux/mod_devicetable.h> 11bc0ae0e7SAsmaa Mnebhi #include <linux/module.h> 12bc0ae0e7SAsmaa Mnebhi #include <linux/platform_device.h> 13bc0ae0e7SAsmaa Mnebhi #include <linux/pm.h> 14bc0ae0e7SAsmaa Mnebhi #include <linux/resource.h> 15bc0ae0e7SAsmaa Mnebhi #include <linux/spinlock.h> 16bc0ae0e7SAsmaa Mnebhi #include <linux/types.h> 17bc0ae0e7SAsmaa Mnebhi 18bc0ae0e7SAsmaa Mnebhi /* 19bc0ae0e7SAsmaa Mnebhi * There are 3 YU GPIO blocks: 20bc0ae0e7SAsmaa Mnebhi * gpio[0]: HOST_GPIO0->HOST_GPIO31 21bc0ae0e7SAsmaa Mnebhi * gpio[1]: HOST_GPIO32->HOST_GPIO63 22bc0ae0e7SAsmaa Mnebhi * gpio[2]: HOST_GPIO64->HOST_GPIO69 23bc0ae0e7SAsmaa Mnebhi */ 24bc0ae0e7SAsmaa Mnebhi #define MLXBF2_GPIO_MAX_PINS_PER_BLOCK 32 25bc0ae0e7SAsmaa Mnebhi 26bc0ae0e7SAsmaa Mnebhi /* 27bc0ae0e7SAsmaa Mnebhi * arm_gpio_lock register: 28bc0ae0e7SAsmaa Mnebhi * bit[31] lock status: active if set 29bc0ae0e7SAsmaa Mnebhi * bit[15:0] set lock 30bc0ae0e7SAsmaa Mnebhi * The lock is enabled only if 0xd42f is written to this field 31bc0ae0e7SAsmaa Mnebhi */ 32bc0ae0e7SAsmaa Mnebhi #define YU_ARM_GPIO_LOCK_ADDR 0x2801088 33bc0ae0e7SAsmaa Mnebhi #define YU_ARM_GPIO_LOCK_SIZE 0x8 34bc0ae0e7SAsmaa Mnebhi #define YU_LOCK_ACTIVE_BIT(val) (val >> 31) 35bc0ae0e7SAsmaa Mnebhi #define YU_ARM_GPIO_LOCK_ACQUIRE 0xd42f 36bc0ae0e7SAsmaa Mnebhi #define YU_ARM_GPIO_LOCK_RELEASE 0x0 37bc0ae0e7SAsmaa Mnebhi 38bc0ae0e7SAsmaa Mnebhi /* 39bc0ae0e7SAsmaa Mnebhi * gpio[x] block registers and their offset 40bc0ae0e7SAsmaa Mnebhi */ 41bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_DATAIN 0x04 42bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_MODE1 0x08 43bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_MODE0 0x0c 44bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_DATASET 0x14 45bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_DATACLEAR 0x18 46bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_MODE1_CLEAR 0x50 47bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_MODE0_SET 0x54 48bc0ae0e7SAsmaa Mnebhi #define YU_GPIO_MODE0_CLEAR 0x58 49bc0ae0e7SAsmaa Mnebhi 50bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context_save_regs { 51bc0ae0e7SAsmaa Mnebhi u32 gpio_mode0; 52bc0ae0e7SAsmaa Mnebhi u32 gpio_mode1; 53bc0ae0e7SAsmaa Mnebhi }; 54bc0ae0e7SAsmaa Mnebhi 55bc0ae0e7SAsmaa Mnebhi /* BlueField-2 gpio block context structure. */ 56bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context { 57bc0ae0e7SAsmaa Mnebhi struct gpio_chip gc; 58bc0ae0e7SAsmaa Mnebhi 59bc0ae0e7SAsmaa Mnebhi /* YU GPIO blocks address */ 60bc0ae0e7SAsmaa Mnebhi void __iomem *gpio_io; 61bc0ae0e7SAsmaa Mnebhi 62bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context_save_regs *csave_regs; 63bc0ae0e7SAsmaa Mnebhi }; 64bc0ae0e7SAsmaa Mnebhi 65bc0ae0e7SAsmaa Mnebhi /* BlueField-2 gpio shared structure. */ 66bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_param { 67bc0ae0e7SAsmaa Mnebhi void __iomem *io; 68bc0ae0e7SAsmaa Mnebhi struct resource *res; 69bc0ae0e7SAsmaa Mnebhi struct mutex *lock; 70bc0ae0e7SAsmaa Mnebhi }; 71bc0ae0e7SAsmaa Mnebhi 72bc0ae0e7SAsmaa Mnebhi static struct resource yu_arm_gpio_lock_res = { 73bc0ae0e7SAsmaa Mnebhi .start = YU_ARM_GPIO_LOCK_ADDR, 74bc0ae0e7SAsmaa Mnebhi .end = YU_ARM_GPIO_LOCK_ADDR + YU_ARM_GPIO_LOCK_SIZE - 1, 75bc0ae0e7SAsmaa Mnebhi .name = "YU_ARM_GPIO_LOCK", 76bc0ae0e7SAsmaa Mnebhi }; 77bc0ae0e7SAsmaa Mnebhi 78bc0ae0e7SAsmaa Mnebhi static DEFINE_MUTEX(yu_arm_gpio_lock_mutex); 79bc0ae0e7SAsmaa Mnebhi 80bc0ae0e7SAsmaa Mnebhi static struct mlxbf2_gpio_param yu_arm_gpio_lock_param = { 81bc0ae0e7SAsmaa Mnebhi .res = &yu_arm_gpio_lock_res, 82bc0ae0e7SAsmaa Mnebhi .lock = &yu_arm_gpio_lock_mutex, 83bc0ae0e7SAsmaa Mnebhi }; 84bc0ae0e7SAsmaa Mnebhi 85bc0ae0e7SAsmaa Mnebhi /* Request memory region and map yu_arm_gpio_lock resource */ 86bc0ae0e7SAsmaa Mnebhi static int mlxbf2_gpio_get_lock_res(struct platform_device *pdev) 87bc0ae0e7SAsmaa Mnebhi { 88bc0ae0e7SAsmaa Mnebhi struct device *dev = &pdev->dev; 89bc0ae0e7SAsmaa Mnebhi struct resource *res; 90bc0ae0e7SAsmaa Mnebhi resource_size_t size; 91bc0ae0e7SAsmaa Mnebhi int ret = 0; 92bc0ae0e7SAsmaa Mnebhi 93bc0ae0e7SAsmaa Mnebhi mutex_lock(yu_arm_gpio_lock_param.lock); 94bc0ae0e7SAsmaa Mnebhi 95bc0ae0e7SAsmaa Mnebhi /* Check if the memory map already exists */ 96bc0ae0e7SAsmaa Mnebhi if (yu_arm_gpio_lock_param.io) 97bc0ae0e7SAsmaa Mnebhi goto exit; 98bc0ae0e7SAsmaa Mnebhi 99bc0ae0e7SAsmaa Mnebhi res = yu_arm_gpio_lock_param.res; 100bc0ae0e7SAsmaa Mnebhi size = resource_size(res); 101bc0ae0e7SAsmaa Mnebhi 102bc0ae0e7SAsmaa Mnebhi if (!devm_request_mem_region(dev, res->start, size, res->name)) { 103bc0ae0e7SAsmaa Mnebhi ret = -EFAULT; 104bc0ae0e7SAsmaa Mnebhi goto exit; 105bc0ae0e7SAsmaa Mnebhi } 106bc0ae0e7SAsmaa Mnebhi 107bc0ae0e7SAsmaa Mnebhi yu_arm_gpio_lock_param.io = devm_ioremap(dev, res->start, size); 10866d8ad67SWei Yongjun if (!yu_arm_gpio_lock_param.io) 10966d8ad67SWei Yongjun ret = -ENOMEM; 110bc0ae0e7SAsmaa Mnebhi 111bc0ae0e7SAsmaa Mnebhi exit: 112bc0ae0e7SAsmaa Mnebhi mutex_unlock(yu_arm_gpio_lock_param.lock); 113bc0ae0e7SAsmaa Mnebhi 114bc0ae0e7SAsmaa Mnebhi return ret; 115bc0ae0e7SAsmaa Mnebhi } 116bc0ae0e7SAsmaa Mnebhi 117bc0ae0e7SAsmaa Mnebhi /* 118bc0ae0e7SAsmaa Mnebhi * Acquire the YU arm_gpio_lock to be able to change the direction 119bc0ae0e7SAsmaa Mnebhi * mode. If the lock_active bit is already set, return an error. 120bc0ae0e7SAsmaa Mnebhi */ 121bc0ae0e7SAsmaa Mnebhi static int mlxbf2_gpio_lock_acquire(struct mlxbf2_gpio_context *gs) 122bc0ae0e7SAsmaa Mnebhi { 123bc0ae0e7SAsmaa Mnebhi u32 arm_gpio_lock_val; 124bc0ae0e7SAsmaa Mnebhi 125bc0ae0e7SAsmaa Mnebhi mutex_lock(yu_arm_gpio_lock_param.lock); 126e6862430SAxel Lin spin_lock(&gs->gc.bgpio_lock); 127bc0ae0e7SAsmaa Mnebhi 128bc0ae0e7SAsmaa Mnebhi arm_gpio_lock_val = readl(yu_arm_gpio_lock_param.io); 129bc0ae0e7SAsmaa Mnebhi 130bc0ae0e7SAsmaa Mnebhi /* 131bc0ae0e7SAsmaa Mnebhi * When lock active bit[31] is set, ModeX is write enabled 132bc0ae0e7SAsmaa Mnebhi */ 133bc0ae0e7SAsmaa Mnebhi if (YU_LOCK_ACTIVE_BIT(arm_gpio_lock_val)) { 134bc0ae0e7SAsmaa Mnebhi spin_unlock(&gs->gc.bgpio_lock); 135e6862430SAxel Lin mutex_unlock(yu_arm_gpio_lock_param.lock); 136bc0ae0e7SAsmaa Mnebhi return -EINVAL; 137bc0ae0e7SAsmaa Mnebhi } 138bc0ae0e7SAsmaa Mnebhi 139bc0ae0e7SAsmaa Mnebhi writel(YU_ARM_GPIO_LOCK_ACQUIRE, yu_arm_gpio_lock_param.io); 140bc0ae0e7SAsmaa Mnebhi 141bc0ae0e7SAsmaa Mnebhi return 0; 142bc0ae0e7SAsmaa Mnebhi } 143bc0ae0e7SAsmaa Mnebhi 144bc0ae0e7SAsmaa Mnebhi /* 145bc0ae0e7SAsmaa Mnebhi * Release the YU arm_gpio_lock after changing the direction mode. 146bc0ae0e7SAsmaa Mnebhi */ 147bc0ae0e7SAsmaa Mnebhi static void mlxbf2_gpio_lock_release(struct mlxbf2_gpio_context *gs) 148a7a9ad23SLee Jones __releases(&gs->gc.bgpio_lock) 149a7a9ad23SLee Jones __releases(yu_arm_gpio_lock_param.lock) 150bc0ae0e7SAsmaa Mnebhi { 151bc0ae0e7SAsmaa Mnebhi writel(YU_ARM_GPIO_LOCK_RELEASE, yu_arm_gpio_lock_param.io); 152bc0ae0e7SAsmaa Mnebhi spin_unlock(&gs->gc.bgpio_lock); 153e6862430SAxel Lin mutex_unlock(yu_arm_gpio_lock_param.lock); 154bc0ae0e7SAsmaa Mnebhi } 155bc0ae0e7SAsmaa Mnebhi 156bc0ae0e7SAsmaa Mnebhi /* 157bc0ae0e7SAsmaa Mnebhi * mode0 and mode1 are both locked by the gpio_lock field. 158bc0ae0e7SAsmaa Mnebhi * 159bc0ae0e7SAsmaa Mnebhi * Together, mode0 and mode1 define the gpio Mode dependeing also 160bc0ae0e7SAsmaa Mnebhi * on Reg_DataOut. 161bc0ae0e7SAsmaa Mnebhi * 162bc0ae0e7SAsmaa Mnebhi * {mode1,mode0}:{Reg_DataOut=0,Reg_DataOut=1}->{DataOut=0,DataOut=1} 163bc0ae0e7SAsmaa Mnebhi * 164bc0ae0e7SAsmaa Mnebhi * {0,0}:Reg_DataOut{0,1}->{Z,Z} Input PAD 165bc0ae0e7SAsmaa Mnebhi * {0,1}:Reg_DataOut{0,1}->{0,1} Full drive Output PAD 166bc0ae0e7SAsmaa Mnebhi * {1,0}:Reg_DataOut{0,1}->{0,Z} 0-set PAD to low, 1-float 167bc0ae0e7SAsmaa Mnebhi * {1,1}:Reg_DataOut{0,1}->{Z,1} 0-float, 1-set PAD to high 168bc0ae0e7SAsmaa Mnebhi */ 169bc0ae0e7SAsmaa Mnebhi 170bc0ae0e7SAsmaa Mnebhi /* 171bc0ae0e7SAsmaa Mnebhi * Set input direction: 172bc0ae0e7SAsmaa Mnebhi * {mode1,mode0} = {0,0} 173bc0ae0e7SAsmaa Mnebhi */ 174bc0ae0e7SAsmaa Mnebhi static int mlxbf2_gpio_direction_input(struct gpio_chip *chip, 175bc0ae0e7SAsmaa Mnebhi unsigned int offset) 176bc0ae0e7SAsmaa Mnebhi { 177bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context *gs = gpiochip_get_data(chip); 178bc0ae0e7SAsmaa Mnebhi int ret; 179bc0ae0e7SAsmaa Mnebhi 180bc0ae0e7SAsmaa Mnebhi /* 181bc0ae0e7SAsmaa Mnebhi * Although the arm_gpio_lock was set in the probe function, check again 182bc0ae0e7SAsmaa Mnebhi * if it is still enabled to be able to write to the ModeX registers. 183bc0ae0e7SAsmaa Mnebhi */ 184bc0ae0e7SAsmaa Mnebhi ret = mlxbf2_gpio_lock_acquire(gs); 185bc0ae0e7SAsmaa Mnebhi if (ret < 0) 186bc0ae0e7SAsmaa Mnebhi return ret; 187bc0ae0e7SAsmaa Mnebhi 188bc0ae0e7SAsmaa Mnebhi writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE0_CLEAR); 189bc0ae0e7SAsmaa Mnebhi writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE1_CLEAR); 190bc0ae0e7SAsmaa Mnebhi 191bc0ae0e7SAsmaa Mnebhi mlxbf2_gpio_lock_release(gs); 192bc0ae0e7SAsmaa Mnebhi 193bc0ae0e7SAsmaa Mnebhi return ret; 194bc0ae0e7SAsmaa Mnebhi } 195bc0ae0e7SAsmaa Mnebhi 196bc0ae0e7SAsmaa Mnebhi /* 197bc0ae0e7SAsmaa Mnebhi * Set output direction: 198bc0ae0e7SAsmaa Mnebhi * {mode1,mode0} = {0,1} 199bc0ae0e7SAsmaa Mnebhi */ 200bc0ae0e7SAsmaa Mnebhi static int mlxbf2_gpio_direction_output(struct gpio_chip *chip, 201bc0ae0e7SAsmaa Mnebhi unsigned int offset, 202bc0ae0e7SAsmaa Mnebhi int value) 203bc0ae0e7SAsmaa Mnebhi { 204bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context *gs = gpiochip_get_data(chip); 205bc0ae0e7SAsmaa Mnebhi int ret = 0; 206bc0ae0e7SAsmaa Mnebhi 207bc0ae0e7SAsmaa Mnebhi /* 208bc0ae0e7SAsmaa Mnebhi * Although the arm_gpio_lock was set in the probe function, 209bc0ae0e7SAsmaa Mnebhi * check again it is still enabled to be able to write to the 210bc0ae0e7SAsmaa Mnebhi * ModeX registers. 211bc0ae0e7SAsmaa Mnebhi */ 212bc0ae0e7SAsmaa Mnebhi ret = mlxbf2_gpio_lock_acquire(gs); 213bc0ae0e7SAsmaa Mnebhi if (ret < 0) 214bc0ae0e7SAsmaa Mnebhi return ret; 215bc0ae0e7SAsmaa Mnebhi 216bc0ae0e7SAsmaa Mnebhi writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE1_CLEAR); 217bc0ae0e7SAsmaa Mnebhi writel(BIT(offset), gs->gpio_io + YU_GPIO_MODE0_SET); 218bc0ae0e7SAsmaa Mnebhi 219bc0ae0e7SAsmaa Mnebhi mlxbf2_gpio_lock_release(gs); 220bc0ae0e7SAsmaa Mnebhi 221bc0ae0e7SAsmaa Mnebhi return ret; 222bc0ae0e7SAsmaa Mnebhi } 223bc0ae0e7SAsmaa Mnebhi 224bc0ae0e7SAsmaa Mnebhi /* BlueField-2 GPIO driver initialization routine. */ 225bc0ae0e7SAsmaa Mnebhi static int 226bc0ae0e7SAsmaa Mnebhi mlxbf2_gpio_probe(struct platform_device *pdev) 227bc0ae0e7SAsmaa Mnebhi { 228bc0ae0e7SAsmaa Mnebhi struct mlxbf2_gpio_context *gs; 229bc0ae0e7SAsmaa Mnebhi struct device *dev = &pdev->dev; 230bc0ae0e7SAsmaa Mnebhi struct gpio_chip *gc; 231bc0ae0e7SAsmaa Mnebhi struct resource *res; 232bc0ae0e7SAsmaa Mnebhi unsigned int npins; 233bc0ae0e7SAsmaa Mnebhi int ret; 234bc0ae0e7SAsmaa Mnebhi 235bc0ae0e7SAsmaa Mnebhi gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL); 236bc0ae0e7SAsmaa Mnebhi if (!gs) 237bc0ae0e7SAsmaa Mnebhi return -ENOMEM; 238bc0ae0e7SAsmaa Mnebhi 239bc0ae0e7SAsmaa Mnebhi /* YU GPIO block address */ 240bc0ae0e7SAsmaa Mnebhi res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 241bc0ae0e7SAsmaa Mnebhi if (!res) 242bc0ae0e7SAsmaa Mnebhi return -ENODEV; 243bc0ae0e7SAsmaa Mnebhi 244bc0ae0e7SAsmaa Mnebhi gs->gpio_io = devm_ioremap(dev, res->start, resource_size(res)); 245bc0ae0e7SAsmaa Mnebhi if (!gs->gpio_io) 246bc0ae0e7SAsmaa Mnebhi return -ENOMEM; 247bc0ae0e7SAsmaa Mnebhi 248bc0ae0e7SAsmaa Mnebhi ret = mlxbf2_gpio_get_lock_res(pdev); 249bc0ae0e7SAsmaa Mnebhi if (ret) { 250bc0ae0e7SAsmaa Mnebhi dev_err(dev, "Failed to get yu_arm_gpio_lock resource\n"); 251bc0ae0e7SAsmaa Mnebhi return ret; 252bc0ae0e7SAsmaa Mnebhi } 253bc0ae0e7SAsmaa Mnebhi 254bc0ae0e7SAsmaa Mnebhi if (device_property_read_u32(dev, "npins", &npins)) 255bc0ae0e7SAsmaa Mnebhi npins = MLXBF2_GPIO_MAX_PINS_PER_BLOCK; 256bc0ae0e7SAsmaa Mnebhi 257bc0ae0e7SAsmaa Mnebhi gc = &gs->gc; 258bc0ae0e7SAsmaa Mnebhi 259bc0ae0e7SAsmaa Mnebhi ret = bgpio_init(gc, dev, 4, 260bc0ae0e7SAsmaa Mnebhi gs->gpio_io + YU_GPIO_DATAIN, 261bc0ae0e7SAsmaa Mnebhi gs->gpio_io + YU_GPIO_DATASET, 262bc0ae0e7SAsmaa Mnebhi gs->gpio_io + YU_GPIO_DATACLEAR, 263bc0ae0e7SAsmaa Mnebhi NULL, 264bc0ae0e7SAsmaa Mnebhi NULL, 265bc0ae0e7SAsmaa Mnebhi 0); 266bc0ae0e7SAsmaa Mnebhi 267bc0ae0e7SAsmaa Mnebhi gc->direction_input = mlxbf2_gpio_direction_input; 268bc0ae0e7SAsmaa Mnebhi gc->direction_output = mlxbf2_gpio_direction_output; 269bc0ae0e7SAsmaa Mnebhi gc->ngpio = npins; 270bc0ae0e7SAsmaa Mnebhi gc->owner = THIS_MODULE; 271bc0ae0e7SAsmaa Mnebhi 272bc0ae0e7SAsmaa Mnebhi platform_set_drvdata(pdev, gs); 273bc0ae0e7SAsmaa Mnebhi 274bc0ae0e7SAsmaa Mnebhi ret = devm_gpiochip_add_data(dev, &gs->gc, gs); 275bc0ae0e7SAsmaa Mnebhi if (ret) { 276bc0ae0e7SAsmaa Mnebhi dev_err(dev, "Failed adding memory mapped gpiochip\n"); 277bc0ae0e7SAsmaa Mnebhi return ret; 278bc0ae0e7SAsmaa Mnebhi } 279bc0ae0e7SAsmaa Mnebhi 280bc0ae0e7SAsmaa Mnebhi return 0; 281bc0ae0e7SAsmaa Mnebhi } 282bc0ae0e7SAsmaa Mnebhi 283dabe57c3SAndy Shevchenko static int __maybe_unused mlxbf2_gpio_suspend(struct device *dev) 284bc0ae0e7SAsmaa Mnebhi { 285dabe57c3SAndy Shevchenko struct mlxbf2_gpio_context *gs = dev_get_drvdata(dev); 286bc0ae0e7SAsmaa Mnebhi 287bc0ae0e7SAsmaa Mnebhi gs->csave_regs->gpio_mode0 = readl(gs->gpio_io + 288bc0ae0e7SAsmaa Mnebhi YU_GPIO_MODE0); 289bc0ae0e7SAsmaa Mnebhi gs->csave_regs->gpio_mode1 = readl(gs->gpio_io + 290bc0ae0e7SAsmaa Mnebhi YU_GPIO_MODE1); 291bc0ae0e7SAsmaa Mnebhi 292bc0ae0e7SAsmaa Mnebhi return 0; 293bc0ae0e7SAsmaa Mnebhi } 294bc0ae0e7SAsmaa Mnebhi 295dabe57c3SAndy Shevchenko static int __maybe_unused mlxbf2_gpio_resume(struct device *dev) 296bc0ae0e7SAsmaa Mnebhi { 297dabe57c3SAndy Shevchenko struct mlxbf2_gpio_context *gs = dev_get_drvdata(dev); 298bc0ae0e7SAsmaa Mnebhi 299bc0ae0e7SAsmaa Mnebhi writel(gs->csave_regs->gpio_mode0, gs->gpio_io + 300bc0ae0e7SAsmaa Mnebhi YU_GPIO_MODE0); 301bc0ae0e7SAsmaa Mnebhi writel(gs->csave_regs->gpio_mode1, gs->gpio_io + 302bc0ae0e7SAsmaa Mnebhi YU_GPIO_MODE1); 303bc0ae0e7SAsmaa Mnebhi 304bc0ae0e7SAsmaa Mnebhi return 0; 305bc0ae0e7SAsmaa Mnebhi } 306dabe57c3SAndy Shevchenko static SIMPLE_DEV_PM_OPS(mlxbf2_pm_ops, mlxbf2_gpio_suspend, mlxbf2_gpio_resume); 307bc0ae0e7SAsmaa Mnebhi 3082f9bce5fSLee Jones static const struct acpi_device_id __maybe_unused mlxbf2_gpio_acpi_match[] = { 309bc0ae0e7SAsmaa Mnebhi { "MLNXBF22", 0 }, 310bc0ae0e7SAsmaa Mnebhi {}, 311bc0ae0e7SAsmaa Mnebhi }; 312bc0ae0e7SAsmaa Mnebhi MODULE_DEVICE_TABLE(acpi, mlxbf2_gpio_acpi_match); 313bc0ae0e7SAsmaa Mnebhi 314bc0ae0e7SAsmaa Mnebhi static struct platform_driver mlxbf2_gpio_driver = { 315bc0ae0e7SAsmaa Mnebhi .driver = { 316bc0ae0e7SAsmaa Mnebhi .name = "mlxbf2_gpio", 317*603607e7SAndy Shevchenko .acpi_match_table = mlxbf2_gpio_acpi_match, 318dabe57c3SAndy Shevchenko .pm = &mlxbf2_pm_ops, 319bc0ae0e7SAsmaa Mnebhi }, 320bc0ae0e7SAsmaa Mnebhi .probe = mlxbf2_gpio_probe, 321bc0ae0e7SAsmaa Mnebhi }; 322bc0ae0e7SAsmaa Mnebhi 323bc0ae0e7SAsmaa Mnebhi module_platform_driver(mlxbf2_gpio_driver); 324bc0ae0e7SAsmaa Mnebhi 325bc0ae0e7SAsmaa Mnebhi MODULE_DESCRIPTION("Mellanox BlueField-2 GPIO Driver"); 326bc0ae0e7SAsmaa Mnebhi MODULE_AUTHOR("Mellanox Technologies"); 327bc0ae0e7SAsmaa Mnebhi MODULE_LICENSE("GPL v2"); 328