xref: /OK3568_Linux_fs/kernel/drivers/gpio/gpio-xgs-iproc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2017 Broadcom
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/gpio/driver.h>
7*4882a593Smuzhiyun #include <linux/init.h>
8*4882a593Smuzhiyun #include <linux/interrupt.h>
9*4882a593Smuzhiyun #include <linux/io.h>
10*4882a593Smuzhiyun #include <linux/irq.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/platform_device.h>
14*4882a593Smuzhiyun #include <linux/spinlock.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define IPROC_CCA_INT_F_GPIOINT		BIT(0)
17*4882a593Smuzhiyun #define IPROC_CCA_INT_STS		0x20
18*4882a593Smuzhiyun #define IPROC_CCA_INT_MASK		0x24
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define IPROC_GPIO_CCA_DIN		0x0
21*4882a593Smuzhiyun #define IPROC_GPIO_CCA_DOUT		0x4
22*4882a593Smuzhiyun #define IPROC_GPIO_CCA_OUT_EN		0x8
23*4882a593Smuzhiyun #define IPROC_GPIO_CCA_INT_LEVEL	0x10
24*4882a593Smuzhiyun #define IPROC_GPIO_CCA_INT_LEVEL_MASK	0x14
25*4882a593Smuzhiyun #define IPROC_GPIO_CCA_INT_EVENT	0x18
26*4882a593Smuzhiyun #define IPROC_GPIO_CCA_INT_EVENT_MASK	0x1C
27*4882a593Smuzhiyun #define IPROC_GPIO_CCA_INT_EDGE		0x24
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun struct iproc_gpio_chip {
30*4882a593Smuzhiyun 	struct irq_chip irqchip;
31*4882a593Smuzhiyun 	struct gpio_chip gc;
32*4882a593Smuzhiyun 	spinlock_t lock;
33*4882a593Smuzhiyun 	struct device *dev;
34*4882a593Smuzhiyun 	void __iomem *base;
35*4882a593Smuzhiyun 	void __iomem *intr;
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun static inline struct iproc_gpio_chip *
to_iproc_gpio(struct gpio_chip * gc)39*4882a593Smuzhiyun to_iproc_gpio(struct gpio_chip *gc)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	return container_of(gc, struct iproc_gpio_chip, gc);
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
iproc_gpio_irq_ack(struct irq_data * d)44*4882a593Smuzhiyun static void iproc_gpio_irq_ack(struct irq_data *d)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
47*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
48*4882a593Smuzhiyun 	int pin = d->hwirq;
49*4882a593Smuzhiyun 	unsigned long flags;
50*4882a593Smuzhiyun 	u32 irq = d->irq;
51*4882a593Smuzhiyun 	u32 irq_type, event_status = 0;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->lock, flags);
54*4882a593Smuzhiyun 	irq_type = irq_get_trigger_type(irq);
55*4882a593Smuzhiyun 	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
56*4882a593Smuzhiyun 		event_status |= BIT(pin);
57*4882a593Smuzhiyun 		writel_relaxed(event_status,
58*4882a593Smuzhiyun 			       chip->base + IPROC_GPIO_CCA_INT_EVENT);
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->lock, flags);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
iproc_gpio_irq_unmask(struct irq_data * d)63*4882a593Smuzhiyun static void iproc_gpio_irq_unmask(struct irq_data *d)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
66*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
67*4882a593Smuzhiyun 	int pin = d->hwirq;
68*4882a593Smuzhiyun 	unsigned long flags;
69*4882a593Smuzhiyun 	u32 irq = d->irq;
70*4882a593Smuzhiyun 	u32 int_mask, irq_type, event_mask;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->lock, flags);
73*4882a593Smuzhiyun 	irq_type = irq_get_trigger_type(irq);
74*4882a593Smuzhiyun 	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
75*4882a593Smuzhiyun 	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
78*4882a593Smuzhiyun 		event_mask |= 1 << pin;
79*4882a593Smuzhiyun 		writel_relaxed(event_mask,
80*4882a593Smuzhiyun 			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
81*4882a593Smuzhiyun 	} else {
82*4882a593Smuzhiyun 		int_mask |= 1 << pin;
83*4882a593Smuzhiyun 		writel_relaxed(int_mask,
84*4882a593Smuzhiyun 			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
85*4882a593Smuzhiyun 	}
86*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->lock, flags);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
iproc_gpio_irq_mask(struct irq_data * d)89*4882a593Smuzhiyun static void iproc_gpio_irq_mask(struct irq_data *d)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
92*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
93*4882a593Smuzhiyun 	int pin = d->hwirq;
94*4882a593Smuzhiyun 	unsigned long flags;
95*4882a593Smuzhiyun 	u32 irq = d->irq;
96*4882a593Smuzhiyun 	u32 irq_type, int_mask, event_mask;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->lock, flags);
99*4882a593Smuzhiyun 	irq_type = irq_get_trigger_type(irq);
100*4882a593Smuzhiyun 	event_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
101*4882a593Smuzhiyun 	int_mask = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	if (irq_type & IRQ_TYPE_EDGE_BOTH) {
104*4882a593Smuzhiyun 		event_mask &= ~BIT(pin);
105*4882a593Smuzhiyun 		writel_relaxed(event_mask,
106*4882a593Smuzhiyun 			       chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
107*4882a593Smuzhiyun 	} else {
108*4882a593Smuzhiyun 		int_mask &= ~BIT(pin);
109*4882a593Smuzhiyun 		writel_relaxed(int_mask,
110*4882a593Smuzhiyun 			       chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
111*4882a593Smuzhiyun 	}
112*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->lock, flags);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun 
iproc_gpio_irq_set_type(struct irq_data * d,u32 type)115*4882a593Smuzhiyun static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
118*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
119*4882a593Smuzhiyun 	int pin = d->hwirq;
120*4882a593Smuzhiyun 	unsigned long flags;
121*4882a593Smuzhiyun 	u32 irq = d->irq;
122*4882a593Smuzhiyun 	u32 event_pol, int_pol;
123*4882a593Smuzhiyun 	int ret = 0;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	spin_lock_irqsave(&chip->lock, flags);
126*4882a593Smuzhiyun 	switch (type & IRQ_TYPE_SENSE_MASK) {
127*4882a593Smuzhiyun 	case IRQ_TYPE_EDGE_RISING:
128*4882a593Smuzhiyun 		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
129*4882a593Smuzhiyun 		event_pol &= ~BIT(pin);
130*4882a593Smuzhiyun 		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
131*4882a593Smuzhiyun 		break;
132*4882a593Smuzhiyun 	case IRQ_TYPE_EDGE_FALLING:
133*4882a593Smuzhiyun 		event_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EDGE);
134*4882a593Smuzhiyun 		event_pol |= BIT(pin);
135*4882a593Smuzhiyun 		writel_relaxed(event_pol, chip->base + IPROC_GPIO_CCA_INT_EDGE);
136*4882a593Smuzhiyun 		break;
137*4882a593Smuzhiyun 	case IRQ_TYPE_LEVEL_HIGH:
138*4882a593Smuzhiyun 		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
139*4882a593Smuzhiyun 		int_pol &= ~BIT(pin);
140*4882a593Smuzhiyun 		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
141*4882a593Smuzhiyun 		break;
142*4882a593Smuzhiyun 	case IRQ_TYPE_LEVEL_LOW:
143*4882a593Smuzhiyun 		int_pol = readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
144*4882a593Smuzhiyun 		int_pol |= BIT(pin);
145*4882a593Smuzhiyun 		writel_relaxed(int_pol, chip->base + IPROC_GPIO_CCA_INT_LEVEL);
146*4882a593Smuzhiyun 		break;
147*4882a593Smuzhiyun 	default:
148*4882a593Smuzhiyun 		/* should not come here */
149*4882a593Smuzhiyun 		ret = -EINVAL;
150*4882a593Smuzhiyun 		goto out_unlock;
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	if (type & IRQ_TYPE_LEVEL_MASK)
154*4882a593Smuzhiyun 		irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq);
155*4882a593Smuzhiyun 	else if (type & IRQ_TYPE_EDGE_BOTH)
156*4882a593Smuzhiyun 		irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun out_unlock:
159*4882a593Smuzhiyun 	spin_unlock_irqrestore(&chip->lock, flags);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	return ret;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
iproc_gpio_irq_handler(int irq,void * data)164*4882a593Smuzhiyun static irqreturn_t iproc_gpio_irq_handler(int irq, void *data)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	struct gpio_chip *gc = (struct gpio_chip *)data;
167*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip = to_iproc_gpio(gc);
168*4882a593Smuzhiyun 	int bit;
169*4882a593Smuzhiyun 	unsigned long int_bits = 0;
170*4882a593Smuzhiyun 	u32 int_status;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* go through the entire GPIOs and handle all interrupts */
173*4882a593Smuzhiyun 	int_status = readl_relaxed(chip->intr + IPROC_CCA_INT_STS);
174*4882a593Smuzhiyun 	if (int_status & IPROC_CCA_INT_F_GPIOINT) {
175*4882a593Smuzhiyun 		u32 event, level;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 		/* Get level and edge interrupts */
178*4882a593Smuzhiyun 		event =
179*4882a593Smuzhiyun 		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT_MASK);
180*4882a593Smuzhiyun 		event &= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_EVENT);
181*4882a593Smuzhiyun 		level = readl_relaxed(chip->base + IPROC_GPIO_CCA_DIN);
182*4882a593Smuzhiyun 		level ^= readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL);
183*4882a593Smuzhiyun 		level &=
184*4882a593Smuzhiyun 		    readl_relaxed(chip->base + IPROC_GPIO_CCA_INT_LEVEL_MASK);
185*4882a593Smuzhiyun 		int_bits = level | event;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		for_each_set_bit(bit, &int_bits, gc->ngpio)
188*4882a593Smuzhiyun 			generic_handle_irq(irq_linear_revmap(gc->irq.domain, bit));
189*4882a593Smuzhiyun 	}
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	return int_bits ? IRQ_HANDLED : IRQ_NONE;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
iproc_gpio_probe(struct platform_device * pdev)194*4882a593Smuzhiyun static int iproc_gpio_probe(struct platform_device *pdev)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun 	struct device *dev = &pdev->dev;
197*4882a593Smuzhiyun 	struct device_node *dn = pdev->dev.of_node;
198*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip;
199*4882a593Smuzhiyun 	u32 num_gpios;
200*4882a593Smuzhiyun 	int irq, ret;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
203*4882a593Smuzhiyun 	if (!chip)
204*4882a593Smuzhiyun 		return -ENOMEM;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	chip->dev = dev;
207*4882a593Smuzhiyun 	platform_set_drvdata(pdev, chip);
208*4882a593Smuzhiyun 	spin_lock_init(&chip->lock);
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	chip->base = devm_platform_ioremap_resource(pdev, 0);
211*4882a593Smuzhiyun 	if (IS_ERR(chip->base))
212*4882a593Smuzhiyun 		return PTR_ERR(chip->base);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	ret = bgpio_init(&chip->gc, dev, 4,
215*4882a593Smuzhiyun 			 chip->base + IPROC_GPIO_CCA_DIN,
216*4882a593Smuzhiyun 			 chip->base + IPROC_GPIO_CCA_DOUT,
217*4882a593Smuzhiyun 			 NULL,
218*4882a593Smuzhiyun 			 chip->base + IPROC_GPIO_CCA_OUT_EN,
219*4882a593Smuzhiyun 			 NULL,
220*4882a593Smuzhiyun 			 0);
221*4882a593Smuzhiyun 	if (ret) {
222*4882a593Smuzhiyun 		dev_err(dev, "unable to init GPIO chip\n");
223*4882a593Smuzhiyun 		return ret;
224*4882a593Smuzhiyun 	}
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	chip->gc.label = dev_name(dev);
227*4882a593Smuzhiyun 	if (!of_property_read_u32(dn, "ngpios", &num_gpios))
228*4882a593Smuzhiyun 		chip->gc.ngpio = num_gpios;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	irq = platform_get_irq(pdev, 0);
231*4882a593Smuzhiyun 	if (irq > 0) {
232*4882a593Smuzhiyun 		struct gpio_irq_chip *girq;
233*4882a593Smuzhiyun 		struct irq_chip *irqc;
234*4882a593Smuzhiyun 		u32 val;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 		irqc = &chip->irqchip;
237*4882a593Smuzhiyun 		irqc->name = dev_name(dev);
238*4882a593Smuzhiyun 		irqc->irq_ack = iproc_gpio_irq_ack;
239*4882a593Smuzhiyun 		irqc->irq_mask = iproc_gpio_irq_mask;
240*4882a593Smuzhiyun 		irqc->irq_unmask = iproc_gpio_irq_unmask;
241*4882a593Smuzhiyun 		irqc->irq_set_type = iproc_gpio_irq_set_type;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 		chip->intr = devm_platform_ioremap_resource(pdev, 1);
244*4882a593Smuzhiyun 		if (IS_ERR(chip->intr))
245*4882a593Smuzhiyun 			return PTR_ERR(chip->intr);
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 		/* Enable GPIO interrupts for CCA GPIO */
248*4882a593Smuzhiyun 		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
249*4882a593Smuzhiyun 		val |= IPROC_CCA_INT_F_GPIOINT;
250*4882a593Smuzhiyun 		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 		/*
253*4882a593Smuzhiyun 		 * Directly request the irq here instead of passing
254*4882a593Smuzhiyun 		 * a flow-handler because the irq is shared.
255*4882a593Smuzhiyun 		 */
256*4882a593Smuzhiyun 		ret = devm_request_irq(dev, irq, iproc_gpio_irq_handler,
257*4882a593Smuzhiyun 				       IRQF_SHARED, chip->gc.label, &chip->gc);
258*4882a593Smuzhiyun 		if (ret) {
259*4882a593Smuzhiyun 			dev_err(dev, "Fail to request IRQ%d: %d\n", irq, ret);
260*4882a593Smuzhiyun 			return ret;
261*4882a593Smuzhiyun 		}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 		girq = &chip->gc.irq;
264*4882a593Smuzhiyun 		girq->chip = irqc;
265*4882a593Smuzhiyun 		/* This will let us handle the parent IRQ in the driver */
266*4882a593Smuzhiyun 		girq->parent_handler = NULL;
267*4882a593Smuzhiyun 		girq->num_parents = 0;
268*4882a593Smuzhiyun 		girq->parents = NULL;
269*4882a593Smuzhiyun 		girq->default_type = IRQ_TYPE_NONE;
270*4882a593Smuzhiyun 		girq->handler = handle_simple_irq;
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	ret = devm_gpiochip_add_data(dev, &chip->gc, chip);
274*4882a593Smuzhiyun 	if (ret) {
275*4882a593Smuzhiyun 		dev_err(dev, "unable to add GPIO chip\n");
276*4882a593Smuzhiyun 		return ret;
277*4882a593Smuzhiyun 	}
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
iproc_gpio_remove(struct platform_device * pdev)282*4882a593Smuzhiyun static int iproc_gpio_remove(struct platform_device *pdev)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	struct iproc_gpio_chip *chip;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	chip = platform_get_drvdata(pdev);
287*4882a593Smuzhiyun 	if (!chip)
288*4882a593Smuzhiyun 		return -ENODEV;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	if (chip->intr) {
291*4882a593Smuzhiyun 		u32 val;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 		val = readl_relaxed(chip->intr + IPROC_CCA_INT_MASK);
294*4882a593Smuzhiyun 		val &= ~IPROC_CCA_INT_F_GPIOINT;
295*4882a593Smuzhiyun 		writel_relaxed(val, chip->intr + IPROC_CCA_INT_MASK);
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	return 0;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun static const struct of_device_id bcm_iproc_gpio_of_match[] = {
302*4882a593Smuzhiyun 	{ .compatible = "brcm,iproc-gpio-cca" },
303*4882a593Smuzhiyun 	{}
304*4882a593Smuzhiyun };
305*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun static struct platform_driver bcm_iproc_gpio_driver = {
308*4882a593Smuzhiyun 	.driver = {
309*4882a593Smuzhiyun 		.name = "iproc-xgs-gpio",
310*4882a593Smuzhiyun 		.of_match_table = bcm_iproc_gpio_of_match,
311*4882a593Smuzhiyun 	},
312*4882a593Smuzhiyun 	.probe = iproc_gpio_probe,
313*4882a593Smuzhiyun 	.remove = iproc_gpio_remove,
314*4882a593Smuzhiyun };
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun module_platform_driver(bcm_iproc_gpio_driver);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun MODULE_DESCRIPTION("XGS IPROC GPIO driver");
319*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
320