1// SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
2/* Copyright (C) 2022 NVIDIA CORPORATION & AFFILIATES */
3
4#include <linux/bitfield.h>
5#include <linux/bitops.h>
6#include <linux/device.h>
7#include <linux/err.h>
8#include <linux/gpio/driver.h>
9#include <linux/interrupt.h>
10#include <linux/io.h>
11#include <linux/module.h>
12#include <linux/platform_device.h>
13#include <linux/spinlock.h>
14#include <linux/types.h>
15
16/*
17 * There are 2 YU GPIO blocks:
18 * gpio[0]: HOST_GPIO0->HOST_GPIO31
19 * gpio[1]: HOST_GPIO32->HOST_GPIO55
20 */
21#define MLXBF3_GPIO_MAX_PINS_PER_BLOCK 32
22#define MLXBF3_GPIO_MAX_PINS_BLOCK0    32
23#define MLXBF3_GPIO_MAX_PINS_BLOCK1    24
24
25/*
26 * fw_gpio[x] block registers and their offset
27 */
28#define MLXBF_GPIO_FW_OUTPUT_ENABLE_SET	  0x00
29#define MLXBF_GPIO_FW_DATA_OUT_SET        0x04
30
31#define MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR 0x00
32#define MLXBF_GPIO_FW_DATA_OUT_CLEAR      0x04
33
34#define MLXBF_GPIO_CAUSE_RISE_EN          0x00
35#define MLXBF_GPIO_CAUSE_FALL_EN          0x04
36#define MLXBF_GPIO_READ_DATA_IN           0x08
37
38#define MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0  0x00
39#define MLXBF_GPIO_CAUSE_OR_EVTEN0        0x14
40#define MLXBF_GPIO_CAUSE_OR_CLRCAUSE      0x18
41
42struct mlxbf3_gpio_context {
43	struct gpio_chip gc;
44
45	/* YU GPIO block address */
46	void __iomem *gpio_set_io;
47	void __iomem *gpio_clr_io;
48	void __iomem *gpio_io;
49
50	/* YU GPIO cause block address */
51	void __iomem *gpio_cause_io;
52};
53
54static void mlxbf3_gpio_irq_enable(struct irq_data *irqd)
55{
56	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
57	struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
58	irq_hw_number_t offset = irqd_to_hwirq(irqd);
59	unsigned long flags;
60	u32 val;
61
62	gpiochip_enable_irq(gc, offset);
63
64	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
65	writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
66
67	val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
68	val |= BIT(offset);
69	writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
70	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
71}
72
73static void mlxbf3_gpio_irq_disable(struct irq_data *irqd)
74{
75	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
76	struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
77	irq_hw_number_t offset = irqd_to_hwirq(irqd);
78	unsigned long flags;
79	u32 val;
80
81	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
82	val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
83	val &= ~BIT(offset);
84	writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
85	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
86
87	gpiochip_disable_irq(gc, offset);
88}
89
90static irqreturn_t mlxbf3_gpio_irq_handler(int irq, void *ptr)
91{
92	struct mlxbf3_gpio_context *gs = ptr;
93	struct gpio_chip *gc = &gs->gc;
94	unsigned long pending;
95	u32 level;
96
97	pending = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CAUSE_EVTEN0);
98	writel(pending, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
99
100	for_each_set_bit(level, &pending, gc->ngpio)
101		generic_handle_domain_irq(gc->irq.domain, level);
102
103	return IRQ_RETVAL(pending);
104}
105
106static int
107mlxbf3_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
108{
109	struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
110	struct mlxbf3_gpio_context *gs = gpiochip_get_data(gc);
111	irq_hw_number_t offset = irqd_to_hwirq(irqd);
112	unsigned long flags;
113	u32 val;
114
115	raw_spin_lock_irqsave(&gs->gc.bgpio_lock, flags);
116
117	switch (type & IRQ_TYPE_SENSE_MASK) {
118	case IRQ_TYPE_EDGE_BOTH:
119		val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
120		val |= BIT(offset);
121		writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
122		val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
123		val |= BIT(offset);
124		writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
125		break;
126	case IRQ_TYPE_EDGE_RISING:
127		val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
128		val |= BIT(offset);
129		writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_RISE_EN);
130		break;
131	case IRQ_TYPE_EDGE_FALLING:
132		val = readl(gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
133		val |= BIT(offset);
134		writel(val, gs->gpio_io + MLXBF_GPIO_CAUSE_FALL_EN);
135		break;
136	default:
137		raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
138		return -EINVAL;
139	}
140
141	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
142
143	irq_set_handler_locked(irqd, handle_edge_irq);
144
145	return 0;
146}
147
148/* This function needs to be defined for handle_edge_irq() */
149static void mlxbf3_gpio_irq_ack(struct irq_data *data)
150{
151}
152
153static const struct irq_chip gpio_mlxbf3_irqchip = {
154	.name = "MLNXBF33",
155	.irq_ack = mlxbf3_gpio_irq_ack,
156	.irq_set_type = mlxbf3_gpio_irq_set_type,
157	.irq_enable = mlxbf3_gpio_irq_enable,
158	.irq_disable = mlxbf3_gpio_irq_disable,
159	.flags = IRQCHIP_IMMUTABLE,
160	GPIOCHIP_IRQ_RESOURCE_HELPERS,
161};
162
163static int mlxbf3_gpio_add_pin_ranges(struct gpio_chip *chip)
164{
165	unsigned int id;
166
167	switch(chip->ngpio) {
168	case MLXBF3_GPIO_MAX_PINS_BLOCK0:
169		id = 0;
170		break;
171	case MLXBF3_GPIO_MAX_PINS_BLOCK1:
172		id = 1;
173		break;
174	default:
175		return -EINVAL;
176	}
177
178	return gpiochip_add_pin_range(chip, "MLNXBF34:00",
179			chip->base, id * MLXBF3_GPIO_MAX_PINS_PER_BLOCK,
180			chip->ngpio);
181}
182
183static int mlxbf3_gpio_probe(struct platform_device *pdev)
184{
185	struct device *dev = &pdev->dev;
186	struct mlxbf3_gpio_context *gs;
187	struct gpio_irq_chip *girq;
188	struct gpio_chip *gc;
189	int ret, irq;
190
191	gs = devm_kzalloc(dev, sizeof(*gs), GFP_KERNEL);
192	if (!gs)
193		return -ENOMEM;
194
195	gs->gpio_io = devm_platform_ioremap_resource(pdev, 0);
196	if (IS_ERR(gs->gpio_io))
197		return PTR_ERR(gs->gpio_io);
198
199	gs->gpio_cause_io = devm_platform_ioremap_resource(pdev, 1);
200	if (IS_ERR(gs->gpio_cause_io))
201		return PTR_ERR(gs->gpio_cause_io);
202
203	gs->gpio_set_io = devm_platform_ioremap_resource(pdev, 2);
204	if (IS_ERR(gs->gpio_set_io))
205		return PTR_ERR(gs->gpio_set_io);
206
207	gs->gpio_clr_io = devm_platform_ioremap_resource(pdev, 3);
208	if (IS_ERR(gs->gpio_clr_io))
209		return PTR_ERR(gs->gpio_clr_io);
210	gc = &gs->gc;
211
212	ret = bgpio_init(gc, dev, 4,
213			gs->gpio_io + MLXBF_GPIO_READ_DATA_IN,
214			gs->gpio_set_io + MLXBF_GPIO_FW_DATA_OUT_SET,
215			gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR,
216			gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET,
217			gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0);
218	if (ret)
219		return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__);
220
221	gc->request = gpiochip_generic_request;
222	gc->free = gpiochip_generic_free;
223	gc->owner = THIS_MODULE;
224	gc->add_pin_ranges = mlxbf3_gpio_add_pin_ranges;
225
226	irq = platform_get_irq(pdev, 0);
227	if (irq >= 0) {
228		girq = &gs->gc.irq;
229		gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip);
230		girq->default_type = IRQ_TYPE_NONE;
231		/* This will let us handle the parent IRQ in the driver */
232		girq->num_parents = 0;
233		girq->parents = NULL;
234		girq->parent_handler = NULL;
235		girq->handler = handle_bad_irq;
236
237		/*
238		 * Directly request the irq here instead of passing
239		 * a flow-handler because the irq is shared.
240		 */
241		ret = devm_request_irq(dev, irq, mlxbf3_gpio_irq_handler,
242				       IRQF_SHARED, dev_name(dev), gs);
243		if (ret)
244			return dev_err_probe(dev, ret, "failed to request IRQ");
245	}
246
247	platform_set_drvdata(pdev, gs);
248
249	ret = devm_gpiochip_add_data(dev, &gs->gc, gs);
250	if (ret)
251		dev_err_probe(dev, ret, "Failed adding memory mapped gpiochip\n");
252
253	return 0;
254}
255
256static const struct acpi_device_id mlxbf3_gpio_acpi_match[] = {
257	{ "MLNXBF33", 0 },
258	{}
259};
260MODULE_DEVICE_TABLE(acpi, mlxbf3_gpio_acpi_match);
261
262static struct platform_driver mlxbf3_gpio_driver = {
263	.driver = {
264		.name = "mlxbf3_gpio",
265		.acpi_match_table = mlxbf3_gpio_acpi_match,
266	},
267	.probe    = mlxbf3_gpio_probe,
268};
269module_platform_driver(mlxbf3_gpio_driver);
270
271MODULE_SOFTDEP("pre: pinctrl-mlxbf3");
272MODULE_DESCRIPTION("NVIDIA BlueField-3 GPIO Driver");
273MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
274MODULE_LICENSE("Dual BSD/GPL");
275