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/of_irq.h>
10 #include <linux/gpio/driver.h>
11 #include <linux/init.h>
12 #include <linux/platform_device.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 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 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 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
79 u32 bit
= BIT(offset
);
82 irq_chip_enable_parent(d
);
85 gc
->direction_input(gc
, offset
);
87 spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
88 /* Clear any sticky pending interrupts */
89 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
90 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
91 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
92 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
93 spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
95 /* Enable interrupts */
96 assign_bit(offset
, &chip
->irq_state
, 1);
97 sifive_gpio_set_ie(chip
, offset
);
100 static void sifive_gpio_irq_disable(struct irq_data
*d
)
102 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
103 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
104 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
106 assign_bit(offset
, &chip
->irq_state
, 0);
107 sifive_gpio_set_ie(chip
, offset
);
108 irq_chip_disable_parent(d
);
111 static void sifive_gpio_irq_eoi(struct irq_data
*d
)
113 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
114 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
115 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
116 u32 bit
= BIT(offset
);
119 spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
120 /* Clear all pending interrupts */
121 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
122 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
123 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
124 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
125 spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
127 irq_chip_eoi_parent(d
);
130 static int sifive_gpio_irq_set_affinity(struct irq_data
*data
,
131 const struct cpumask
*dest
,
134 if (data
->parent_data
)
135 return irq_chip_set_affinity_parent(data
, dest
, force
);
140 static struct irq_chip sifive_gpio_irqchip
= {
141 .name
= "sifive-gpio",
142 .irq_set_type
= sifive_gpio_irq_set_type
,
143 .irq_mask
= irq_chip_mask_parent
,
144 .irq_unmask
= irq_chip_unmask_parent
,
145 .irq_enable
= sifive_gpio_irq_enable
,
146 .irq_disable
= sifive_gpio_irq_disable
,
147 .irq_eoi
= sifive_gpio_irq_eoi
,
148 .irq_set_affinity
= sifive_gpio_irq_set_affinity
,
151 static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip
*gc
,
153 unsigned int child_type
,
154 unsigned int *parent
,
155 unsigned int *parent_type
)
157 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
158 struct irq_data
*d
= irq_get_irq_data(chip
->irq_number
[child
]);
160 *parent_type
= IRQ_TYPE_NONE
;
161 *parent
= irqd_to_hwirq(d
);
166 static const struct regmap_config sifive_gpio_regmap_config
= {
171 .disable_locking
= true,
174 static int sifive_gpio_probe(struct platform_device
*pdev
)
176 struct device
*dev
= &pdev
->dev
;
177 struct device_node
*node
= pdev
->dev
.of_node
;
178 struct device_node
*irq_parent
;
179 struct irq_domain
*parent
;
180 struct gpio_irq_chip
*girq
;
181 struct sifive_gpio
*chip
;
184 chip
= devm_kzalloc(dev
, sizeof(*chip
), GFP_KERNEL
);
188 chip
->base
= devm_platform_ioremap_resource(pdev
, 0);
189 if (IS_ERR(chip
->base
)) {
190 dev_err(dev
, "failed to allocate device memory\n");
191 return PTR_ERR(chip
->base
);
194 chip
->regs
= devm_regmap_init_mmio(dev
, chip
->base
,
195 &sifive_gpio_regmap_config
);
196 if (IS_ERR(chip
->regs
))
197 return PTR_ERR(chip
->regs
);
199 ngpio
= of_irq_count(node
);
200 if (ngpio
> SIFIVE_GPIO_MAX
) {
201 dev_err(dev
, "Too many GPIO interrupts (max=%d)\n",
206 irq_parent
= of_irq_find_parent(node
);
208 dev_err(dev
, "no IRQ parent node\n");
211 parent
= irq_find_host(irq_parent
);
213 dev_err(dev
, "no IRQ parent domain\n");
217 for (i
= 0; i
< ngpio
; i
++)
218 chip
->irq_number
[i
] = platform_get_irq(pdev
, i
);
220 ret
= bgpio_init(&chip
->gc
, dev
, 4,
221 chip
->base
+ SIFIVE_GPIO_INPUT_VAL
,
222 chip
->base
+ SIFIVE_GPIO_OUTPUT_VAL
,
224 chip
->base
+ SIFIVE_GPIO_OUTPUT_EN
,
225 chip
->base
+ SIFIVE_GPIO_INPUT_EN
,
228 dev_err(dev
, "unable to init generic GPIO\n");
232 /* Disable all GPIO interrupts before enabling parent interrupts */
233 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IE
, 0);
234 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IE
, 0);
235 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IE
, 0);
236 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IE
, 0);
240 chip
->gc
.ngpio
= ngpio
;
241 chip
->gc
.label
= dev_name(dev
);
242 chip
->gc
.parent
= dev
;
243 chip
->gc
.owner
= THIS_MODULE
;
244 girq
= &chip
->gc
.irq
;
245 girq
->chip
= &sifive_gpio_irqchip
;
246 girq
->fwnode
= of_node_to_fwnode(node
);
247 girq
->parent_domain
= parent
;
248 girq
->child_to_parent_hwirq
= sifive_gpio_child_to_parent_hwirq
;
249 girq
->handler
= handle_bad_irq
;
250 girq
->default_type
= IRQ_TYPE_NONE
;
252 platform_set_drvdata(pdev
, chip
);
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
= of_match_ptr(sifive_gpio_match
),
269 builtin_platform_driver(sifive_gpio_driver
)