Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: (GPL-2.0)
2/*
3 * Microchip PolarFire SoC (MPFS) GPIO controller driver
4 *
5 * Copyright (c) 2018-2024 Microchip Technology Inc. and its subsidiaries
6 */
7
8#include <linux/clk.h>
9#include <linux/device.h>
10#include <linux/errno.h>
11#include <linux/gpio/driver.h>
12#include <linux/interrupt.h>
13#include <linux/mod_devicetable.h>
14#include <linux/of_irq.h>
15#include <linux/platform_device.h>
16#include <linux/property.h>
17#include <linux/regmap.h>
18#include <linux/spinlock.h>
19
20#define MPFS_GPIO_CTRL(i) (0x4 * (i))
21#define MPFS_MAX_NUM_GPIO 32
22#define MPFS_GPIO_EN_INT BIT(3)
23#define MPFS_GPIO_EN_OUT_BUF BIT(2)
24#define MPFS_GPIO_EN_IN BIT(1)
25#define MPFS_GPIO_EN_OUT BIT(0)
26#define MPFS_GPIO_DIR_MASK GENMASK(2, 0)
27
28#define MPFS_GPIO_TYPE_INT_EDGE_BOTH 0x80
29#define MPFS_GPIO_TYPE_INT_EDGE_NEG 0x60
30#define MPFS_GPIO_TYPE_INT_EDGE_POS 0x40
31#define MPFS_GPIO_TYPE_INT_LEVEL_LOW 0x20
32#define MPFS_GPIO_TYPE_INT_LEVEL_HIGH 0x00
33#define MPFS_GPIO_TYPE_INT_MASK GENMASK(7, 5)
34#define MPFS_IRQ_REG 0x80
35
36#define MPFS_INP_REG 0x84
37#define COREGPIO_INP_REG 0x90
38#define MPFS_OUTP_REG 0x88
39#define COREGPIO_OUTP_REG 0xA0
40
41struct mpfs_gpio_reg_offsets {
42 u8 inp;
43 u8 outp;
44};
45
46struct mpfs_gpio_chip {
47 struct regmap *regs;
48 const struct mpfs_gpio_reg_offsets *offsets;
49 struct gpio_chip gc;
50};
51
52static const struct regmap_config mpfs_gpio_regmap_config = {
53 .reg_bits = 32,
54 .reg_stride = 4,
55 .val_bits = 32,
56 .use_raw_spinlock = true,
57};
58
59static int mpfs_gpio_direction_input(struct gpio_chip *gc, unsigned int gpio_index)
60{
61 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
62
63 regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
64 MPFS_GPIO_DIR_MASK, MPFS_GPIO_EN_IN);
65
66 return 0;
67}
68
69static int mpfs_gpio_direction_output(struct gpio_chip *gc, unsigned int gpio_index, int value)
70{
71 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
72
73 regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
74 MPFS_GPIO_DIR_MASK, MPFS_GPIO_EN_OUT | MPFS_GPIO_EN_OUT_BUF);
75 regmap_update_bits(mpfs_gpio->regs, mpfs_gpio->offsets->outp, BIT(gpio_index),
76 value << gpio_index);
77
78 return 0;
79}
80
81static int mpfs_gpio_get_direction(struct gpio_chip *gc,
82 unsigned int gpio_index)
83{
84 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
85 unsigned int gpio_cfg;
86
87 regmap_read(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index), &gpio_cfg);
88 if (gpio_cfg & MPFS_GPIO_EN_IN)
89 return GPIO_LINE_DIRECTION_IN;
90
91 return GPIO_LINE_DIRECTION_OUT;
92}
93
94static int mpfs_gpio_get(struct gpio_chip *gc, unsigned int gpio_index)
95{
96 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
97
98 if (mpfs_gpio_get_direction(gc, gpio_index) == GPIO_LINE_DIRECTION_OUT)
99 return regmap_test_bits(mpfs_gpio->regs, mpfs_gpio->offsets->outp, BIT(gpio_index));
100 else
101 return regmap_test_bits(mpfs_gpio->regs, mpfs_gpio->offsets->inp, BIT(gpio_index));
102}
103
104static int mpfs_gpio_set(struct gpio_chip *gc, unsigned int gpio_index, int value)
105{
106 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
107 int ret;
108
109 mpfs_gpio_get(gc, gpio_index);
110
111 ret = regmap_update_bits(mpfs_gpio->regs, mpfs_gpio->offsets->outp,
112 BIT(gpio_index), value << gpio_index);
113
114 mpfs_gpio_get(gc, gpio_index);
115
116 return ret;
117}
118
119static int mpfs_gpio_irq_set_type(struct irq_data *data, unsigned int type)
120{
121 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
122 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
123 int gpio_index = irqd_to_hwirq(data) % 32;
124 u32 interrupt_type;
125
126 switch (type) {
127 case IRQ_TYPE_EDGE_BOTH:
128 interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_BOTH;
129 break;
130 case IRQ_TYPE_EDGE_FALLING:
131 interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_NEG;
132 break;
133 case IRQ_TYPE_EDGE_RISING:
134 interrupt_type = MPFS_GPIO_TYPE_INT_EDGE_POS;
135 break;
136 case IRQ_TYPE_LEVEL_HIGH:
137 interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_HIGH;
138 break;
139 case IRQ_TYPE_LEVEL_LOW:
140 interrupt_type = MPFS_GPIO_TYPE_INT_LEVEL_LOW;
141 break;
142 }
143
144 regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
145 MPFS_GPIO_TYPE_INT_MASK, interrupt_type);
146
147 return 0;
148}
149
150static void mpfs_gpio_irq_unmask(struct irq_data *data)
151{
152 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
153 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
154 int gpio_index = irqd_to_hwirq(data) % 32;
155
156 gpiochip_enable_irq(gc, gpio_index);
157 mpfs_gpio_direction_input(gc, gpio_index);
158 regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
159 MPFS_GPIO_EN_INT, MPFS_GPIO_EN_INT);
160}
161
162static void mpfs_gpio_irq_mask(struct irq_data *data)
163{
164 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);
165 struct mpfs_gpio_chip *mpfs_gpio = gpiochip_get_data(gc);
166 int gpio_index = irqd_to_hwirq(data) % 32;
167
168 regmap_update_bits(mpfs_gpio->regs, MPFS_GPIO_CTRL(gpio_index),
169 MPFS_GPIO_EN_INT, 0);
170 gpiochip_disable_irq(gc, gpio_index);
171}
172
173static const struct irq_chip mpfs_gpio_irqchip = {
174 .name = "MPFS GPIO",
175 .irq_set_type = mpfs_gpio_irq_set_type,
176 .irq_mask = mpfs_gpio_irq_mask,
177 .irq_unmask = mpfs_gpio_irq_unmask,
178 .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
179 GPIOCHIP_IRQ_RESOURCE_HELPERS,
180};
181
182static void mpfs_gpio_irq_handler(struct irq_desc *desc)
183{
184 struct irq_chip *irqchip = irq_desc_get_chip(desc);
185 struct mpfs_gpio_chip *mpfs_gpio = irq_desc_get_handler_data(desc);
186 unsigned long status;
187 u32 val;
188 int i;
189
190 chained_irq_enter(irqchip, desc);
191
192 regmap_read(mpfs_gpio->regs, MPFS_IRQ_REG, &val);
193 status = val;
194 for_each_set_bit(i, &status, MPFS_MAX_NUM_GPIO) {
195 regmap_write(mpfs_gpio->regs, MPFS_IRQ_REG, BIT(i));
196 generic_handle_domain_irq(mpfs_gpio->gc.irq.domain, i);
197 }
198
199 chained_irq_exit(irqchip, desc);
200}
201
202static int mpfs_gpio_probe(struct platform_device *pdev)
203{
204 struct device *dev = &pdev->dev;
205 struct device_node *node = dev->of_node;
206 struct mpfs_gpio_chip *mpfs_gpio;
207 struct gpio_irq_chip *girq;
208 struct clk *clk;
209 void __iomem *base;
210 int ngpios, nirqs, ret;
211
212 mpfs_gpio = devm_kzalloc(dev, sizeof(*mpfs_gpio), GFP_KERNEL);
213 if (!mpfs_gpio)
214 return -ENOMEM;
215
216 mpfs_gpio->offsets = device_get_match_data(&pdev->dev);
217
218 base = devm_platform_ioremap_resource(pdev, 0);
219 if (IS_ERR(base))
220 return dev_err_probe(dev, PTR_ERR(base), "failed to ioremap memory resource\n");
221
222 mpfs_gpio->regs = devm_regmap_init_mmio(dev, base, &mpfs_gpio_regmap_config);
223 if (IS_ERR(mpfs_gpio->regs))
224 return dev_err_probe(dev, PTR_ERR(mpfs_gpio->regs),
225 "failed to initialise regmap\n");
226
227 clk = devm_clk_get_enabled(dev, NULL);
228 if (IS_ERR(clk))
229 return dev_err_probe(dev, PTR_ERR(clk), "failed to get and enable clock\n");
230
231 ngpios = MPFS_MAX_NUM_GPIO;
232 device_property_read_u32(dev, "ngpios", &ngpios);
233 if (ngpios > MPFS_MAX_NUM_GPIO)
234 ngpios = MPFS_MAX_NUM_GPIO;
235
236 mpfs_gpio->gc.direction_input = mpfs_gpio_direction_input;
237 mpfs_gpio->gc.direction_output = mpfs_gpio_direction_output;
238 mpfs_gpio->gc.get_direction = mpfs_gpio_get_direction;
239 mpfs_gpio->gc.get = mpfs_gpio_get;
240 mpfs_gpio->gc.set = mpfs_gpio_set;
241 mpfs_gpio->gc.base = -1;
242 mpfs_gpio->gc.ngpio = ngpios;
243 mpfs_gpio->gc.label = dev_name(dev);
244 mpfs_gpio->gc.parent = dev;
245 mpfs_gpio->gc.owner = THIS_MODULE;
246
247 nirqs = of_irq_count(node);
248 if (nirqs > MPFS_MAX_NUM_GPIO)
249 return -ENXIO;
250
251 if (nirqs) {
252 girq = &mpfs_gpio->gc.irq;
253
254 gpio_irq_chip_set_chip(girq, &mpfs_gpio_irqchip);
255
256 girq->num_parents = nirqs;
257 girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
258 sizeof(*girq->parents), GFP_KERNEL);
259 if (!girq->parents)
260 return -ENOMEM;
261
262 for (int i = 0; i < nirqs; i++) {
263 ret = platform_get_irq(pdev, i);
264 if (ret < 0)
265 return ret;
266
267 girq->parents[i] = ret;
268 girq->parent_handler_data = mpfs_gpio;
269 girq->parent_handler = mpfs_gpio_irq_handler;
270 }
271
272 girq->handler = handle_level_irq;
273 girq->default_type = IRQ_TYPE_NONE;
274 }
275
276 return devm_gpiochip_add_data(dev, &mpfs_gpio->gc, mpfs_gpio);
277}
278
279static const struct mpfs_gpio_reg_offsets mpfs_reg_offsets = {
280 .inp = MPFS_INP_REG,
281 .outp = MPFS_OUTP_REG,
282};
283
284static const struct mpfs_gpio_reg_offsets coregpio_reg_offsets = {
285 .inp = COREGPIO_INP_REG,
286 .outp = COREGPIO_OUTP_REG,
287};
288
289static const struct of_device_id mpfs_gpio_of_ids[] = {
290 {
291 .compatible = "microchip,mpfs-gpio",
292 .data = &mpfs_reg_offsets,
293 }, {
294 .compatible = "microchip,coregpio-rtl-v3",
295 .data = &coregpio_reg_offsets,
296 },
297 { /* end of list */ }
298};
299
300static struct platform_driver mpfs_gpio_driver = {
301 .probe = mpfs_gpio_probe,
302 .driver = {
303 .name = "microchip,mpfs-gpio",
304 .of_match_table = mpfs_gpio_of_ids,
305 },
306};
307builtin_platform_driver(mpfs_gpio_driver);