Linux Audio

Check our new training course

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