1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2019 SiFive
6 #include <linux/bitops.h>
7 #include <linux/device.h>
8 #include <linux/errno.h>
9 #include <linux/gpio/driver.h>
10 #include <linux/init.h>
11 #include <linux/platform_device.h>
12 #include <linux/property.h>
13 #include <linux/slab.h>
14 #include <linux/spinlock.h>
15 #include <linux/regmap.h>
17 #define SIFIVE_GPIO_INPUT_VAL 0x00
18 #define SIFIVE_GPIO_INPUT_EN 0x04
19 #define SIFIVE_GPIO_OUTPUT_EN 0x08
20 #define SIFIVE_GPIO_OUTPUT_VAL 0x0C
21 #define SIFIVE_GPIO_RISE_IE 0x18
22 #define SIFIVE_GPIO_RISE_IP 0x1C
23 #define SIFIVE_GPIO_FALL_IE 0x20
24 #define SIFIVE_GPIO_FALL_IP 0x24
25 #define SIFIVE_GPIO_HIGH_IE 0x28
26 #define SIFIVE_GPIO_HIGH_IP 0x2C
27 #define SIFIVE_GPIO_LOW_IE 0x30
28 #define SIFIVE_GPIO_LOW_IP 0x34
29 #define SIFIVE_GPIO_OUTPUT_XOR 0x40
31 #define SIFIVE_GPIO_MAX 32
37 unsigned long irq_state
;
38 unsigned int trigger
[SIFIVE_GPIO_MAX
];
39 unsigned int irq_number
[SIFIVE_GPIO_MAX
];
42 static void sifive_gpio_set_ie(struct sifive_gpio
*chip
, unsigned int offset
)
47 raw_spin_lock_irqsave(&chip
->gc
.bgpio_lock
, flags
);
48 trigger
= (chip
->irq_state
& BIT(offset
)) ? chip
->trigger
[offset
] : 0;
49 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_RISE_IE
, BIT(offset
),
50 (trigger
& IRQ_TYPE_EDGE_RISING
) ? BIT(offset
) : 0);
51 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_FALL_IE
, BIT(offset
),
52 (trigger
& IRQ_TYPE_EDGE_FALLING
) ? BIT(offset
) : 0);
53 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_HIGH_IE
, BIT(offset
),
54 (trigger
& IRQ_TYPE_LEVEL_HIGH
) ? BIT(offset
) : 0);
55 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_LOW_IE
, BIT(offset
),
56 (trigger
& IRQ_TYPE_LEVEL_LOW
) ? BIT(offset
) : 0);
57 raw_spin_unlock_irqrestore(&chip
->gc
.bgpio_lock
, flags
);
60 static int sifive_gpio_irq_set_type(struct irq_data
*d
, unsigned int trigger
)
62 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
63 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
64 int offset
= irqd_to_hwirq(d
);
66 if (offset
< 0 || offset
>= gc
->ngpio
)
69 chip
->trigger
[offset
] = trigger
;
70 sifive_gpio_set_ie(chip
, offset
);
74 static void sifive_gpio_irq_enable(struct irq_data
*d
)
76 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
77 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
78 irq_hw_number_t hwirq
= irqd_to_hwirq(d
);
79 int offset
= hwirq
% SIFIVE_GPIO_MAX
;
80 u32 bit
= BIT(offset
);
83 gpiochip_enable_irq(gc
, hwirq
);
84 irq_chip_enable_parent(d
);
87 gc
->direction_input(gc
, offset
);
89 raw_spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
90 /* Clear any sticky pending interrupts */
91 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
92 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
93 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
94 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
95 raw_spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
97 /* Enable interrupts */
98 assign_bit(offset
, &chip
->irq_state
, 1);
99 sifive_gpio_set_ie(chip
, offset
);
102 static void sifive_gpio_irq_disable(struct irq_data
*d
)
104 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
105 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
106 irq_hw_number_t hwirq
= irqd_to_hwirq(d
);
107 int offset
= hwirq
% SIFIVE_GPIO_MAX
;
109 assign_bit(offset
, &chip
->irq_state
, 0);
110 sifive_gpio_set_ie(chip
, offset
);
111 irq_chip_disable_parent(d
);
112 gpiochip_disable_irq(gc
, hwirq
);
115 static void sifive_gpio_irq_eoi(struct irq_data
*d
)
117 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
118 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
119 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
120 u32 bit
= BIT(offset
);
123 raw_spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
124 /* Clear all pending interrupts */
125 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
126 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
127 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
128 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
129 raw_spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
131 irq_chip_eoi_parent(d
);
134 static int sifive_gpio_irq_set_affinity(struct irq_data
*data
,
135 const struct cpumask
*dest
,
138 if (data
->parent_data
)
139 return irq_chip_set_affinity_parent(data
, dest
, force
);
144 static const struct irq_chip sifive_gpio_irqchip
= {
145 .name
= "sifive-gpio",
146 .irq_set_type
= sifive_gpio_irq_set_type
,
147 .irq_mask
= irq_chip_mask_parent
,
148 .irq_unmask
= irq_chip_unmask_parent
,
149 .irq_enable
= sifive_gpio_irq_enable
,
150 .irq_disable
= sifive_gpio_irq_disable
,
151 .irq_eoi
= sifive_gpio_irq_eoi
,
152 .irq_set_affinity
= sifive_gpio_irq_set_affinity
,
153 .irq_set_wake
= irq_chip_set_wake_parent
,
154 .flags
= IRQCHIP_IMMUTABLE
,
155 GPIOCHIP_IRQ_RESOURCE_HELPERS
,
158 static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip
*gc
,
160 unsigned int child_type
,
161 unsigned int *parent
,
162 unsigned int *parent_type
)
164 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
165 struct irq_data
*d
= irq_get_irq_data(chip
->irq_number
[child
]);
167 *parent_type
= IRQ_TYPE_NONE
;
168 *parent
= irqd_to_hwirq(d
);
173 static const struct regmap_config sifive_gpio_regmap_config
= {
178 .disable_locking
= true,
181 static int sifive_gpio_probe(struct platform_device
*pdev
)
183 struct device
*dev
= &pdev
->dev
;
184 struct irq_domain
*parent
;
185 struct gpio_irq_chip
*girq
;
186 struct sifive_gpio
*chip
;
189 chip
= devm_kzalloc(dev
, sizeof(*chip
), GFP_KERNEL
);
193 chip
->base
= devm_platform_ioremap_resource(pdev
, 0);
194 if (IS_ERR(chip
->base
)) {
195 dev_err(dev
, "failed to allocate device memory\n");
196 return PTR_ERR(chip
->base
);
199 chip
->regs
= devm_regmap_init_mmio(dev
, chip
->base
,
200 &sifive_gpio_regmap_config
);
201 if (IS_ERR(chip
->regs
))
202 return PTR_ERR(chip
->regs
);
204 for (ngpio
= 0; ngpio
< SIFIVE_GPIO_MAX
; ngpio
++) {
205 ret
= platform_get_irq_optional(pdev
, ngpio
);
208 chip
->irq_number
[ngpio
] = ret
;
211 dev_err(dev
, "no IRQ found\n");
216 * The check above ensures at least one parent IRQ is valid.
217 * Assume all parent IRQs belong to the same domain.
219 parent
= irq_get_irq_data(chip
->irq_number
[0])->domain
;
221 ret
= bgpio_init(&chip
->gc
, dev
, 4,
222 chip
->base
+ SIFIVE_GPIO_INPUT_VAL
,
223 chip
->base
+ SIFIVE_GPIO_OUTPUT_VAL
,
225 chip
->base
+ SIFIVE_GPIO_OUTPUT_EN
,
226 chip
->base
+ SIFIVE_GPIO_INPUT_EN
,
227 BGPIOF_READ_OUTPUT_REG_SET
);
229 dev_err(dev
, "unable to init generic GPIO\n");
233 /* Disable all GPIO interrupts before enabling parent interrupts */
234 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IE
, 0);
235 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IE
, 0);
236 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IE
, 0);
237 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IE
, 0);
241 chip
->gc
.ngpio
= ngpio
;
242 chip
->gc
.label
= dev_name(dev
);
243 chip
->gc
.parent
= dev
;
244 chip
->gc
.owner
= THIS_MODULE
;
245 girq
= &chip
->gc
.irq
;
246 gpio_irq_chip_set_chip(girq
, &sifive_gpio_irqchip
);
247 girq
->fwnode
= dev_fwnode(dev
);
248 girq
->parent_domain
= parent
;
249 girq
->child_to_parent_hwirq
= sifive_gpio_child_to_parent_hwirq
;
250 girq
->handler
= handle_bad_irq
;
251 girq
->default_type
= IRQ_TYPE_NONE
;
253 return gpiochip_add_data(&chip
->gc
, chip
);
256 static const struct of_device_id sifive_gpio_match
[] = {
257 { .compatible
= "sifive,gpio0" },
258 { .compatible
= "sifive,fu540-c000-gpio" },
262 static struct platform_driver sifive_gpio_driver
= {
263 .probe
= sifive_gpio_probe
,
265 .name
= "sifive_gpio",
266 .of_match_table
= sifive_gpio_match
,
269 module_platform_driver(sifive_gpio_driver
)
271 MODULE_AUTHOR("Yash Shah <yash.shah@sifive.com>");
272 MODULE_DESCRIPTION("SiFive GPIO driver");
273 MODULE_LICENSE("GPL");