xref: /linux/drivers/gpio/gpio-ixp4xx.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1813e7d36SLinus Walleij // SPDX-License-Identifier: GPL-2.0
2813e7d36SLinus Walleij //
3813e7d36SLinus Walleij // IXP4 GPIO driver
4813e7d36SLinus Walleij // Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
5813e7d36SLinus Walleij //
6813e7d36SLinus Walleij // based on previous work and know-how from:
7813e7d36SLinus Walleij // Deepak Saxena <dsaxena@plexity.net>
8813e7d36SLinus Walleij 
9*1e3d42f5SAndy Shevchenko #include <linux/bitops.h>
10813e7d36SLinus Walleij #include <linux/gpio/driver.h>
11813e7d36SLinus Walleij #include <linux/io.h>
12813e7d36SLinus Walleij #include <linux/irq.h>
13813e7d36SLinus Walleij #include <linux/irqdomain.h>
14813e7d36SLinus Walleij #include <linux/irqchip.h>
15e4bfb0ffSLinus Walleij #include <linux/of_irq.h>
16813e7d36SLinus Walleij #include <linux/platform_device.h>
17*1e3d42f5SAndy Shevchenko #include <linux/property.h>
18813e7d36SLinus Walleij 
19813e7d36SLinus Walleij #define IXP4XX_REG_GPOUT	0x00
20813e7d36SLinus Walleij #define IXP4XX_REG_GPOE		0x04
21813e7d36SLinus Walleij #define IXP4XX_REG_GPIN		0x08
22813e7d36SLinus Walleij #define IXP4XX_REG_GPIS		0x0C
23813e7d36SLinus Walleij #define IXP4XX_REG_GPIT1	0x10
24813e7d36SLinus Walleij #define IXP4XX_REG_GPIT2	0x14
25813e7d36SLinus Walleij #define IXP4XX_REG_GPCLK	0x18
26813e7d36SLinus Walleij #define IXP4XX_REG_GPDBSEL	0x1C
27813e7d36SLinus Walleij 
28813e7d36SLinus Walleij /*
29813e7d36SLinus Walleij  * The hardware uses 3 bits to indicate interrupt "style".
30813e7d36SLinus Walleij  * we clear and set these three bits accordingly. The lower 24
31813e7d36SLinus Walleij  * bits in two registers (GPIT1 and GPIT2) are used to set up
32813e7d36SLinus Walleij  * the style for 8 lines each for a total of 16 GPIO lines.
33813e7d36SLinus Walleij  */
34813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_ACTIVE_HIGH	0x0
35813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_ACTIVE_LOW	0x1
36813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_RISING_EDGE	0x2
37813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_FALLING_EDGE	0x3
38813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_TRANSITIONAL	0x4
39813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_MASK		GENMASK(2, 0)
40813e7d36SLinus Walleij #define IXP4XX_GPIO_STYLE_SIZE		3
41813e7d36SLinus Walleij 
429a9429b9SLinus Walleij /*
439a9429b9SLinus Walleij  * Clock output control register defines.
449a9429b9SLinus Walleij  */
459a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK0DC_SHIFT	0
469a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK0TC_SHIFT	4
479a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK0_MASK		GENMASK(7, 0)
489a9429b9SLinus Walleij #define IXP4XX_GPCLK_MUX14		BIT(8)
499a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK1DC_SHIFT	16
509a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK1TC_SHIFT	20
519a9429b9SLinus Walleij #define IXP4XX_GPCLK_CLK1_MASK		GENMASK(23, 16)
529a9429b9SLinus Walleij #define IXP4XX_GPCLK_MUX15		BIT(24)
539a9429b9SLinus Walleij 
54813e7d36SLinus Walleij /**
55813e7d36SLinus Walleij  * struct ixp4xx_gpio - IXP4 GPIO state container
56813e7d36SLinus Walleij  * @dev: containing device for this instance
57813e7d36SLinus Walleij  * @gc: gpiochip for this instance
58813e7d36SLinus Walleij  * @base: remapped I/O-memory base
59813e7d36SLinus Walleij  * @irq_edge: Each bit represents an IRQ: 1: edge-triggered,
60813e7d36SLinus Walleij  * 0: level triggered
61813e7d36SLinus Walleij  */
62813e7d36SLinus Walleij struct ixp4xx_gpio {
63813e7d36SLinus Walleij 	struct gpio_chip gc;
64*1e3d42f5SAndy Shevchenko 	struct device *dev;
65813e7d36SLinus Walleij 	void __iomem *base;
66813e7d36SLinus Walleij 	unsigned long long irq_edge;
67813e7d36SLinus Walleij };
68813e7d36SLinus Walleij 
ixp4xx_gpio_irq_ack(struct irq_data * d)69813e7d36SLinus Walleij static void ixp4xx_gpio_irq_ack(struct irq_data *d)
70813e7d36SLinus Walleij {
71aa7d618aSLinus Walleij 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
72aa7d618aSLinus Walleij 	struct ixp4xx_gpio *g = gpiochip_get_data(gc);
73813e7d36SLinus Walleij 
74813e7d36SLinus Walleij 	__raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS);
75813e7d36SLinus Walleij }
76813e7d36SLinus Walleij 
ixp4xx_gpio_mask_irq(struct irq_data * d)7794e9bc73SLinus Walleij static void ixp4xx_gpio_mask_irq(struct irq_data *d)
7894e9bc73SLinus Walleij {
7994e9bc73SLinus Walleij 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
8094e9bc73SLinus Walleij 
8194e9bc73SLinus Walleij 	irq_chip_mask_parent(d);
8294e9bc73SLinus Walleij 	gpiochip_disable_irq(gc, d->hwirq);
8394e9bc73SLinus Walleij }
8494e9bc73SLinus Walleij 
ixp4xx_gpio_irq_unmask(struct irq_data * d)85813e7d36SLinus Walleij static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
86813e7d36SLinus Walleij {
87aa7d618aSLinus Walleij 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
88aa7d618aSLinus Walleij 	struct ixp4xx_gpio *g = gpiochip_get_data(gc);
89813e7d36SLinus Walleij 
90813e7d36SLinus Walleij 	/* ACK when unmasking if not edge-triggered */
91813e7d36SLinus Walleij 	if (!(g->irq_edge & BIT(d->hwirq)))
92813e7d36SLinus Walleij 		ixp4xx_gpio_irq_ack(d);
93813e7d36SLinus Walleij 
9494e9bc73SLinus Walleij 	gpiochip_enable_irq(gc, d->hwirq);
95813e7d36SLinus Walleij 	irq_chip_unmask_parent(d);
96813e7d36SLinus Walleij }
97813e7d36SLinus Walleij 
ixp4xx_gpio_irq_set_type(struct irq_data * d,unsigned int type)98813e7d36SLinus Walleij static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
99813e7d36SLinus Walleij {
100aa7d618aSLinus Walleij 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
101aa7d618aSLinus Walleij 	struct ixp4xx_gpio *g = gpiochip_get_data(gc);
102813e7d36SLinus Walleij 	int line = d->hwirq;
103813e7d36SLinus Walleij 	unsigned long flags;
104813e7d36SLinus Walleij 	u32 int_style;
105813e7d36SLinus Walleij 	u32 int_reg;
106813e7d36SLinus Walleij 	u32 val;
107813e7d36SLinus Walleij 
108813e7d36SLinus Walleij 	switch (type) {
109813e7d36SLinus Walleij 	case IRQ_TYPE_EDGE_BOTH:
110813e7d36SLinus Walleij 		irq_set_handler_locked(d, handle_edge_irq);
111813e7d36SLinus Walleij 		int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
112813e7d36SLinus Walleij 		g->irq_edge |= BIT(d->hwirq);
113813e7d36SLinus Walleij 		break;
114813e7d36SLinus Walleij 	case IRQ_TYPE_EDGE_RISING:
115813e7d36SLinus Walleij 		irq_set_handler_locked(d, handle_edge_irq);
116813e7d36SLinus Walleij 		int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
117813e7d36SLinus Walleij 		g->irq_edge |= BIT(d->hwirq);
118813e7d36SLinus Walleij 		break;
119813e7d36SLinus Walleij 	case IRQ_TYPE_EDGE_FALLING:
120813e7d36SLinus Walleij 		irq_set_handler_locked(d, handle_edge_irq);
121813e7d36SLinus Walleij 		int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
122813e7d36SLinus Walleij 		g->irq_edge |= BIT(d->hwirq);
123813e7d36SLinus Walleij 		break;
124813e7d36SLinus Walleij 	case IRQ_TYPE_LEVEL_HIGH:
125813e7d36SLinus Walleij 		irq_set_handler_locked(d, handle_level_irq);
126813e7d36SLinus Walleij 		int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
127813e7d36SLinus Walleij 		g->irq_edge &= ~BIT(d->hwirq);
128813e7d36SLinus Walleij 		break;
129813e7d36SLinus Walleij 	case IRQ_TYPE_LEVEL_LOW:
130813e7d36SLinus Walleij 		irq_set_handler_locked(d, handle_level_irq);
131813e7d36SLinus Walleij 		int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
132813e7d36SLinus Walleij 		g->irq_edge &= ~BIT(d->hwirq);
133813e7d36SLinus Walleij 		break;
134813e7d36SLinus Walleij 	default:
135813e7d36SLinus Walleij 		return -EINVAL;
136813e7d36SLinus Walleij 	}
137813e7d36SLinus Walleij 
138813e7d36SLinus Walleij 	if (line >= 8) {
139813e7d36SLinus Walleij 		/* pins 8-15 */
140813e7d36SLinus Walleij 		line -= 8;
141813e7d36SLinus Walleij 		int_reg = IXP4XX_REG_GPIT2;
142813e7d36SLinus Walleij 	} else {
143813e7d36SLinus Walleij 		/* pins 0-7 */
144813e7d36SLinus Walleij 		int_reg = IXP4XX_REG_GPIT1;
145813e7d36SLinus Walleij 	}
146813e7d36SLinus Walleij 
1473c938cc5SSchspa Shi 	raw_spin_lock_irqsave(&g->gc.bgpio_lock, flags);
148813e7d36SLinus Walleij 
149813e7d36SLinus Walleij 	/* Clear the style for the appropriate pin */
150813e7d36SLinus Walleij 	val = __raw_readl(g->base + int_reg);
151813e7d36SLinus Walleij 	val &= ~(IXP4XX_GPIO_STYLE_MASK << (line * IXP4XX_GPIO_STYLE_SIZE));
152813e7d36SLinus Walleij 	__raw_writel(val, g->base + int_reg);
153813e7d36SLinus Walleij 
154813e7d36SLinus Walleij 	__raw_writel(BIT(line), g->base + IXP4XX_REG_GPIS);
155813e7d36SLinus Walleij 
156813e7d36SLinus Walleij 	/* Set the new style */
157813e7d36SLinus Walleij 	val = __raw_readl(g->base + int_reg);
158813e7d36SLinus Walleij 	val |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
159813e7d36SLinus Walleij 	__raw_writel(val, g->base + int_reg);
160813e7d36SLinus Walleij 
161813e7d36SLinus Walleij 	/* Force-configure this line as an input */
162813e7d36SLinus Walleij 	val = __raw_readl(g->base + IXP4XX_REG_GPOE);
163813e7d36SLinus Walleij 	val |= BIT(d->hwirq);
164813e7d36SLinus Walleij 	__raw_writel(val, g->base + IXP4XX_REG_GPOE);
165813e7d36SLinus Walleij 
1663c938cc5SSchspa Shi 	raw_spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
167813e7d36SLinus Walleij 
168813e7d36SLinus Walleij 	/* This parent only accept level high (asserted) */
169813e7d36SLinus Walleij 	return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
170813e7d36SLinus Walleij }
171813e7d36SLinus Walleij 
17294e9bc73SLinus Walleij static const struct irq_chip ixp4xx_gpio_irqchip = {
173813e7d36SLinus Walleij 	.name = "IXP4GPIO",
174813e7d36SLinus Walleij 	.irq_ack = ixp4xx_gpio_irq_ack,
17594e9bc73SLinus Walleij 	.irq_mask = ixp4xx_gpio_mask_irq,
176813e7d36SLinus Walleij 	.irq_unmask = ixp4xx_gpio_irq_unmask,
177813e7d36SLinus Walleij 	.irq_set_type = ixp4xx_gpio_irq_set_type,
17894e9bc73SLinus Walleij 	.flags = IRQCHIP_IMMUTABLE,
17994e9bc73SLinus Walleij 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
180813e7d36SLinus Walleij };
181813e7d36SLinus Walleij 
ixp4xx_gpio_child_to_parent_hwirq(struct gpio_chip * gc,unsigned int child,unsigned int child_type,unsigned int * parent,unsigned int * parent_type)182aa7d618aSLinus Walleij static int ixp4xx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
183aa7d618aSLinus Walleij 					     unsigned int child,
184aa7d618aSLinus Walleij 					     unsigned int child_type,
185aa7d618aSLinus Walleij 					     unsigned int *parent,
186aa7d618aSLinus Walleij 					     unsigned int *parent_type)
187813e7d36SLinus Walleij {
188aa7d618aSLinus Walleij 	/* All these interrupts are level high in the CPU */
189aa7d618aSLinus Walleij 	*parent_type = IRQ_TYPE_LEVEL_HIGH;
190813e7d36SLinus Walleij 
191aa7d618aSLinus Walleij 	/* GPIO lines 0..12 have dedicated IRQs */
192aa7d618aSLinus Walleij 	if (child == 0) {
193aa7d618aSLinus Walleij 		*parent = 6;
194aa7d618aSLinus Walleij 		return 0;
195813e7d36SLinus Walleij 	}
196aa7d618aSLinus Walleij 	if (child == 1) {
197aa7d618aSLinus Walleij 		*parent = 7;
198aa7d618aSLinus Walleij 		return 0;
199813e7d36SLinus Walleij 	}
200aa7d618aSLinus Walleij 	if (child >= 2 && child <= 12) {
201aa7d618aSLinus Walleij 		*parent = child + 17;
202813e7d36SLinus Walleij 		return 0;
203813e7d36SLinus Walleij 	}
204813e7d36SLinus Walleij 	return -EINVAL;
205813e7d36SLinus Walleij }
206813e7d36SLinus Walleij 
ixp4xx_gpio_probe(struct platform_device * pdev)207813e7d36SLinus Walleij static int ixp4xx_gpio_probe(struct platform_device *pdev)
208813e7d36SLinus Walleij {
209813e7d36SLinus Walleij 	unsigned long flags;
210813e7d36SLinus Walleij 	struct device *dev = &pdev->dev;
211e4bfb0ffSLinus Walleij 	struct device_node *np = dev->of_node;
212813e7d36SLinus Walleij 	struct irq_domain *parent;
213813e7d36SLinus Walleij 	struct ixp4xx_gpio *g;
214aa7d618aSLinus Walleij 	struct gpio_irq_chip *girq;
215c83227a5SLinus Walleij 	struct device_node *irq_parent;
2169a9429b9SLinus Walleij 	bool clk_14, clk_15;
2179a9429b9SLinus Walleij 	u32 val;
218813e7d36SLinus Walleij 	int ret;
219813e7d36SLinus Walleij 
220813e7d36SLinus Walleij 	g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);
221813e7d36SLinus Walleij 	if (!g)
222813e7d36SLinus Walleij 		return -ENOMEM;
223813e7d36SLinus Walleij 	g->dev = dev;
224813e7d36SLinus Walleij 
225f8d1af24SYang Li 	g->base = devm_platform_ioremap_resource(pdev, 0);
22661059b70SDing Xiang 	if (IS_ERR(g->base))
227813e7d36SLinus Walleij 		return PTR_ERR(g->base);
228813e7d36SLinus Walleij 
229aa7d618aSLinus Walleij 	irq_parent = of_irq_find_parent(np);
230aa7d618aSLinus Walleij 	if (!irq_parent) {
231aa7d618aSLinus Walleij 		dev_err(dev, "no IRQ parent node\n");
232aa7d618aSLinus Walleij 		return -ENODEV;
233aa7d618aSLinus Walleij 	}
234aa7d618aSLinus Walleij 	parent = irq_find_host(irq_parent);
235aa7d618aSLinus Walleij 	if (!parent) {
236aa7d618aSLinus Walleij 		dev_err(dev, "no IRQ parent domain\n");
237aa7d618aSLinus Walleij 		return -ENODEV;
238aa7d618aSLinus Walleij 	}
239aa7d618aSLinus Walleij 
240aa7d618aSLinus Walleij 	/*
2419a9429b9SLinus Walleij 	 * If either clock output is enabled explicitly in the device tree
2429a9429b9SLinus Walleij 	 * we take full control of the clock by masking off all bits for
2439a9429b9SLinus Walleij 	 * the clock control and selectively enabling them. Otherwise
2449a9429b9SLinus Walleij 	 * we leave the hardware default settings.
2459a9429b9SLinus Walleij 	 *
2469a9429b9SLinus Walleij 	 * Enable clock outputs with default timings of requested clock.
2479a9429b9SLinus Walleij 	 * If you need control over TC and DC, add these to the device
2489a9429b9SLinus Walleij 	 * tree bindings and use them here.
2499a9429b9SLinus Walleij 	 */
2509a9429b9SLinus Walleij 	clk_14 = of_property_read_bool(np, "intel,ixp4xx-gpio14-clkout");
2519a9429b9SLinus Walleij 	clk_15 = of_property_read_bool(np, "intel,ixp4xx-gpio15-clkout");
2529a9429b9SLinus Walleij 
2539a9429b9SLinus Walleij 	/*
254813e7d36SLinus Walleij 	 * Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on
255813e7d36SLinus Walleij 	 * specific machines.
256813e7d36SLinus Walleij 	 */
2574f3e79b3SLinus Walleij 	if (of_machine_is_compatible("dlink,dsm-g600-a") ||
2584f3e79b3SLinus Walleij 	    of_machine_is_compatible("iom,nas-100d"))
2599a9429b9SLinus Walleij 		val = 0;
2609a9429b9SLinus Walleij 	else {
2619a9429b9SLinus Walleij 		val = __raw_readl(g->base + IXP4XX_REG_GPCLK);
2629a9429b9SLinus Walleij 
2639a9429b9SLinus Walleij 		if (clk_14 || clk_15) {
2649a9429b9SLinus Walleij 			val &= ~(IXP4XX_GPCLK_MUX14 | IXP4XX_GPCLK_MUX15);
2659a9429b9SLinus Walleij 			val &= ~IXP4XX_GPCLK_CLK0_MASK;
2669a9429b9SLinus Walleij 			val &= ~IXP4XX_GPCLK_CLK1_MASK;
2679a9429b9SLinus Walleij 			if (clk_14) {
2689a9429b9SLinus Walleij 				/* IXP4XX_GPCLK_CLK0DC implicit low */
2699a9429b9SLinus Walleij 				val |= (1 << IXP4XX_GPCLK_CLK0TC_SHIFT);
2709a9429b9SLinus Walleij 				val |= IXP4XX_GPCLK_MUX14;
2719a9429b9SLinus Walleij 			}
2729a9429b9SLinus Walleij 
2739a9429b9SLinus Walleij 			if (clk_15) {
2749a9429b9SLinus Walleij 				/* IXP4XX_GPCLK_CLK1DC implicit low */
2759a9429b9SLinus Walleij 				val |= (1 << IXP4XX_GPCLK_CLK1TC_SHIFT);
2769a9429b9SLinus Walleij 				val |= IXP4XX_GPCLK_MUX15;
2779a9429b9SLinus Walleij 			}
2789a9429b9SLinus Walleij 		}
2799a9429b9SLinus Walleij 	}
2809a9429b9SLinus Walleij 
2819a9429b9SLinus Walleij 	__raw_writel(val, g->base + IXP4XX_REG_GPCLK);
282813e7d36SLinus Walleij 
283813e7d36SLinus Walleij 	/*
284813e7d36SLinus Walleij 	 * This is a very special big-endian ARM issue: when the IXP4xx is
285813e7d36SLinus Walleij 	 * run in big endian mode, all registers in the machine are switched
286813e7d36SLinus Walleij 	 * around to the CPU-native endianness. As you see mostly in the
287813e7d36SLinus Walleij 	 * driver we use __raw_readl()/__raw_writel() to access the registers
288813e7d36SLinus Walleij 	 * in the appropriate order. With the GPIO library we need to specify
289813e7d36SLinus Walleij 	 * byte order explicitly, so this flag needs to be set when compiling
290813e7d36SLinus Walleij 	 * for big endian.
291813e7d36SLinus Walleij 	 */
292813e7d36SLinus Walleij #if defined(CONFIG_CPU_BIG_ENDIAN)
293813e7d36SLinus Walleij 	flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
294813e7d36SLinus Walleij #else
295813e7d36SLinus Walleij 	flags = 0;
296813e7d36SLinus Walleij #endif
297813e7d36SLinus Walleij 
298813e7d36SLinus Walleij 	/* Populate and register gpio chip */
299813e7d36SLinus Walleij 	ret = bgpio_init(&g->gc, dev, 4,
300813e7d36SLinus Walleij 			 g->base + IXP4XX_REG_GPIN,
301813e7d36SLinus Walleij 			 g->base + IXP4XX_REG_GPOUT,
302813e7d36SLinus Walleij 			 NULL,
303813e7d36SLinus Walleij 			 NULL,
304813e7d36SLinus Walleij 			 g->base + IXP4XX_REG_GPOE,
305813e7d36SLinus Walleij 			 flags);
306813e7d36SLinus Walleij 	if (ret) {
307813e7d36SLinus Walleij 		dev_err(dev, "unable to init generic GPIO\n");
308813e7d36SLinus Walleij 		return ret;
309813e7d36SLinus Walleij 	}
310813e7d36SLinus Walleij 	g->gc.ngpio = 16;
311813e7d36SLinus Walleij 	g->gc.label = "IXP4XX_GPIO_CHIP";
312813e7d36SLinus Walleij 	/*
313813e7d36SLinus Walleij 	 * TODO: when we have migrated to device tree and all GPIOs
314813e7d36SLinus Walleij 	 * are fetched using phandles, set this to -1 to get rid of
315813e7d36SLinus Walleij 	 * the fixed gpiochip base.
316813e7d36SLinus Walleij 	 */
317813e7d36SLinus Walleij 	g->gc.base = 0;
318813e7d36SLinus Walleij 	g->gc.parent = &pdev->dev;
319813e7d36SLinus Walleij 	g->gc.owner = THIS_MODULE;
320813e7d36SLinus Walleij 
321aa7d618aSLinus Walleij 	girq = &g->gc.irq;
32294e9bc73SLinus Walleij 	gpio_irq_chip_set_chip(girq, &ixp4xx_gpio_irqchip);
323*1e3d42f5SAndy Shevchenko 	girq->fwnode = dev_fwnode(dev);
324aa7d618aSLinus Walleij 	girq->parent_domain = parent;
325aa7d618aSLinus Walleij 	girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq;
326aa7d618aSLinus Walleij 	girq->handler = handle_bad_irq;
327aa7d618aSLinus Walleij 	girq->default_type = IRQ_TYPE_NONE;
328aa7d618aSLinus Walleij 
329813e7d36SLinus Walleij 	ret = devm_gpiochip_add_data(dev, &g->gc, g);
330813e7d36SLinus Walleij 	if (ret) {
331813e7d36SLinus Walleij 		dev_err(dev, "failed to add SoC gpiochip\n");
332813e7d36SLinus Walleij 		return ret;
333813e7d36SLinus Walleij 	}
334813e7d36SLinus Walleij 
335813e7d36SLinus Walleij 	platform_set_drvdata(pdev, g);
336aa7d618aSLinus Walleij 	dev_info(dev, "IXP4 GPIO registered\n");
337813e7d36SLinus Walleij 
338813e7d36SLinus Walleij 	return 0;
339813e7d36SLinus Walleij }
340813e7d36SLinus Walleij 
341e4bfb0ffSLinus Walleij static const struct of_device_id ixp4xx_gpio_of_match[] = {
342e4bfb0ffSLinus Walleij 	{
343e4bfb0ffSLinus Walleij 		.compatible = "intel,ixp4xx-gpio",
344e4bfb0ffSLinus Walleij 	},
345e4bfb0ffSLinus Walleij 	{},
346e4bfb0ffSLinus Walleij };
347e4bfb0ffSLinus Walleij 
348e4bfb0ffSLinus Walleij 
349813e7d36SLinus Walleij static struct platform_driver ixp4xx_gpio_driver = {
350813e7d36SLinus Walleij 	.driver = {
351813e7d36SLinus Walleij 		.name		= "ixp4xx-gpio",
35207d93cbbSZhu Wang 		.of_match_table = ixp4xx_gpio_of_match,
353813e7d36SLinus Walleij 	},
354813e7d36SLinus Walleij 	.probe = ixp4xx_gpio_probe,
355813e7d36SLinus Walleij };
356813e7d36SLinus Walleij builtin_platform_driver(ixp4xx_gpio_driver);
357