xref: /linux/drivers/gpio/gpio-mlxbf2.c (revision 603607e70e3626e6ceb3ddec86e2a060c6cd6191)
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