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
32 #define SIFIVE_GPIO_IRQ_OFFSET 7
38 unsigned long irq_state
;
39 unsigned int trigger
[SIFIVE_GPIO_MAX
];
40 unsigned int irq_parent
[SIFIVE_GPIO_MAX
];
43 static void sifive_gpio_set_ie(struct sifive_gpio
*chip
, unsigned int offset
)
48 spin_lock_irqsave(&chip
->gc
.bgpio_lock
, flags
);
49 trigger
= (chip
->irq_state
& BIT(offset
)) ? chip
->trigger
[offset
] : 0;
50 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_RISE_IE
, BIT(offset
),
51 (trigger
& IRQ_TYPE_EDGE_RISING
) ? BIT(offset
) : 0);
52 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_FALL_IE
, BIT(offset
),
53 (trigger
& IRQ_TYPE_EDGE_FALLING
) ? BIT(offset
) : 0);
54 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_HIGH_IE
, BIT(offset
),
55 (trigger
& IRQ_TYPE_LEVEL_HIGH
) ? BIT(offset
) : 0);
56 regmap_update_bits(chip
->regs
, SIFIVE_GPIO_LOW_IE
, BIT(offset
),
57 (trigger
& IRQ_TYPE_LEVEL_LOW
) ? BIT(offset
) : 0);
58 spin_unlock_irqrestore(&chip
->gc
.bgpio_lock
, flags
);
61 static int sifive_gpio_irq_set_type(struct irq_data
*d
, unsigned int trigger
)
63 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
64 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
65 int offset
= irqd_to_hwirq(d
);
67 if (offset
< 0 || offset
>= gc
->ngpio
)
70 chip
->trigger
[offset
] = trigger
;
71 sifive_gpio_set_ie(chip
, offset
);
75 static void sifive_gpio_irq_enable(struct irq_data
*d
)
77 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
78 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
79 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
80 u32 bit
= BIT(offset
);
83 irq_chip_enable_parent(d
);
86 gc
->direction_input(gc
, offset
);
88 spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
89 /* Clear any sticky pending interrupts */
90 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
91 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
92 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
93 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
94 spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
96 /* Enable interrupts */
97 assign_bit(offset
, &chip
->irq_state
, 1);
98 sifive_gpio_set_ie(chip
, offset
);
101 static void sifive_gpio_irq_disable(struct irq_data
*d
)
103 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
104 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
105 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
107 assign_bit(offset
, &chip
->irq_state
, 0);
108 sifive_gpio_set_ie(chip
, offset
);
109 irq_chip_disable_parent(d
);
112 static void sifive_gpio_irq_eoi(struct irq_data
*d
)
114 struct gpio_chip
*gc
= irq_data_get_irq_chip_data(d
);
115 struct sifive_gpio
*chip
= gpiochip_get_data(gc
);
116 int offset
= irqd_to_hwirq(d
) % SIFIVE_GPIO_MAX
;
117 u32 bit
= BIT(offset
);
120 spin_lock_irqsave(&gc
->bgpio_lock
, flags
);
121 /* Clear all pending interrupts */
122 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IP
, bit
);
123 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IP
, bit
);
124 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IP
, bit
);
125 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IP
, bit
);
126 spin_unlock_irqrestore(&gc
->bgpio_lock
, flags
);
128 irq_chip_eoi_parent(d
);
131 static struct irq_chip sifive_gpio_irqchip
= {
132 .name
= "sifive-gpio",
133 .irq_set_type
= sifive_gpio_irq_set_type
,
134 .irq_mask
= irq_chip_mask_parent
,
135 .irq_unmask
= irq_chip_unmask_parent
,
136 .irq_enable
= sifive_gpio_irq_enable
,
137 .irq_disable
= sifive_gpio_irq_disable
,
138 .irq_eoi
= sifive_gpio_irq_eoi
,
141 static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip
*gc
,
143 unsigned int child_type
,
144 unsigned int *parent
,
145 unsigned int *parent_type
)
147 *parent_type
= IRQ_TYPE_NONE
;
148 *parent
= child
+ SIFIVE_GPIO_IRQ_OFFSET
;
152 static const struct regmap_config sifive_gpio_regmap_config
= {
157 .disable_locking
= true,
160 static int sifive_gpio_probe(struct platform_device
*pdev
)
162 struct device
*dev
= &pdev
->dev
;
163 struct device_node
*node
= pdev
->dev
.of_node
;
164 struct device_node
*irq_parent
;
165 struct irq_domain
*parent
;
166 struct gpio_irq_chip
*girq
;
167 struct sifive_gpio
*chip
;
170 chip
= devm_kzalloc(dev
, sizeof(*chip
), GFP_KERNEL
);
174 chip
->base
= devm_platform_ioremap_resource(pdev
, 0);
175 if (IS_ERR(chip
->base
)) {
176 dev_err(dev
, "failed to allocate device memory\n");
177 return PTR_ERR(chip
->base
);
180 chip
->regs
= devm_regmap_init_mmio(dev
, chip
->base
,
181 &sifive_gpio_regmap_config
);
182 if (IS_ERR(chip
->regs
))
183 return PTR_ERR(chip
->regs
);
185 ngpio
= of_irq_count(node
);
186 if (ngpio
>= SIFIVE_GPIO_MAX
) {
187 dev_err(dev
, "Too many GPIO interrupts (max=%d)\n",
192 irq_parent
= of_irq_find_parent(node
);
194 dev_err(dev
, "no IRQ parent node\n");
197 parent
= irq_find_host(irq_parent
);
199 dev_err(dev
, "no IRQ parent domain\n");
203 ret
= bgpio_init(&chip
->gc
, dev
, 4,
204 chip
->base
+ SIFIVE_GPIO_INPUT_VAL
,
205 chip
->base
+ SIFIVE_GPIO_OUTPUT_VAL
,
207 chip
->base
+ SIFIVE_GPIO_OUTPUT_EN
,
208 chip
->base
+ SIFIVE_GPIO_INPUT_EN
,
211 dev_err(dev
, "unable to init generic GPIO\n");
215 /* Disable all GPIO interrupts before enabling parent interrupts */
216 regmap_write(chip
->regs
, SIFIVE_GPIO_RISE_IE
, 0);
217 regmap_write(chip
->regs
, SIFIVE_GPIO_FALL_IE
, 0);
218 regmap_write(chip
->regs
, SIFIVE_GPIO_HIGH_IE
, 0);
219 regmap_write(chip
->regs
, SIFIVE_GPIO_LOW_IE
, 0);
223 chip
->gc
.ngpio
= ngpio
;
224 chip
->gc
.label
= dev_name(dev
);
225 chip
->gc
.parent
= dev
;
226 chip
->gc
.owner
= THIS_MODULE
;
227 girq
= &chip
->gc
.irq
;
228 girq
->chip
= &sifive_gpio_irqchip
;
229 girq
->fwnode
= of_node_to_fwnode(node
);
230 girq
->parent_domain
= parent
;
231 girq
->child_to_parent_hwirq
= sifive_gpio_child_to_parent_hwirq
;
232 girq
->handler
= handle_bad_irq
;
233 girq
->default_type
= IRQ_TYPE_NONE
;
235 platform_set_drvdata(pdev
, chip
);
236 return gpiochip_add_data(&chip
->gc
, chip
);
239 static const struct of_device_id sifive_gpio_match
[] = {
240 { .compatible
= "sifive,gpio0" },
241 { .compatible
= "sifive,fu540-c000-gpio" },
245 static struct platform_driver sifive_gpio_driver
= {
246 .probe
= sifive_gpio_probe
,
248 .name
= "sifive_gpio",
249 .of_match_table
= of_match_ptr(sifive_gpio_match
),
252 builtin_platform_driver(sifive_gpio_driver
)