Lines Matching +full:child +full:- +full:interrupt +full:- +full:base

1 // SPDX-License-Identifier: GPL-2.0
6 // based on previous work and know-how from:
18 #include <linux/irqchip/irq-ixp4xx.h>
20 #include <asm/mach-types.h>
32 * The hardware uses 3 bits to indicate interrupt "style".
46 * struct ixp4xx_gpio - IXP4 GPIO state container
50 * @base: remapped I/O-memory base
51 * @irq_edge: Each bit represents an IRQ: 1: edge-triggered,
58 void __iomem *base; member
67 __raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS); in ixp4xx_gpio_irq_ack()
75 /* ACK when unmasking if not edge-triggered */ in ixp4xx_gpio_irq_unmask()
76 if (!(g->irq_edge & BIT(d->hwirq))) in ixp4xx_gpio_irq_unmask()
86 int line = d->hwirq; in ixp4xx_gpio_irq_set_type()
96 g->irq_edge |= BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
101 g->irq_edge |= BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
106 g->irq_edge |= BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
111 g->irq_edge &= ~BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
116 g->irq_edge &= ~BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
119 return -EINVAL; in ixp4xx_gpio_irq_set_type()
123 /* pins 8-15 */ in ixp4xx_gpio_irq_set_type()
124 line -= 8; in ixp4xx_gpio_irq_set_type()
127 /* pins 0-7 */ in ixp4xx_gpio_irq_set_type()
131 spin_lock_irqsave(&g->gc.bgpio_lock, flags); in ixp4xx_gpio_irq_set_type()
134 val = __raw_readl(g->base + int_reg); in ixp4xx_gpio_irq_set_type()
136 __raw_writel(val, g->base + int_reg); in ixp4xx_gpio_irq_set_type()
138 __raw_writel(BIT(line), g->base + IXP4XX_REG_GPIS); in ixp4xx_gpio_irq_set_type()
141 val = __raw_readl(g->base + int_reg); in ixp4xx_gpio_irq_set_type()
143 __raw_writel(val, g->base + int_reg); in ixp4xx_gpio_irq_set_type()
145 /* Force-configure this line as an input */ in ixp4xx_gpio_irq_set_type()
146 val = __raw_readl(g->base + IXP4XX_REG_GPOE); in ixp4xx_gpio_irq_set_type()
147 val |= BIT(d->hwirq); in ixp4xx_gpio_irq_set_type()
148 __raw_writel(val, g->base + IXP4XX_REG_GPOE); in ixp4xx_gpio_irq_set_type()
150 spin_unlock_irqrestore(&g->gc.bgpio_lock, flags); in ixp4xx_gpio_irq_set_type()
165 unsigned int child, in ixp4xx_gpio_child_to_parent_hwirq() argument
174 if (child == 0) { in ixp4xx_gpio_child_to_parent_hwirq()
178 if (child == 1) { in ixp4xx_gpio_child_to_parent_hwirq()
182 if (child >= 2 && child <= 12) { in ixp4xx_gpio_child_to_parent_hwirq()
183 *parent = child + 17; in ixp4xx_gpio_child_to_parent_hwirq()
186 return -EINVAL; in ixp4xx_gpio_child_to_parent_hwirq()
192 struct device *dev = &pdev->dev; in ixp4xx_gpio_probe()
193 struct device_node *np = dev->of_node; in ixp4xx_gpio_probe()
202 return -ENOMEM; in ixp4xx_gpio_probe()
203 g->dev = dev; in ixp4xx_gpio_probe()
206 g->base = devm_ioremap_resource(dev, res); in ixp4xx_gpio_probe()
207 if (IS_ERR(g->base)) in ixp4xx_gpio_probe()
208 return PTR_ERR(g->base); in ixp4xx_gpio_probe()
222 return -ENODEV; in ixp4xx_gpio_probe()
227 return -ENODEV; in ixp4xx_gpio_probe()
229 g->fwnode = of_node_to_fwnode(np); in ixp4xx_gpio_probe()
232 g->fwnode = irq_domain_alloc_fwnode(&res->start); in ixp4xx_gpio_probe()
233 if (!g->fwnode) { in ixp4xx_gpio_probe()
234 dev_err(dev, "no domain base\n"); in ixp4xx_gpio_probe()
235 return -ENODEV; in ixp4xx_gpio_probe()
244 __raw_writel(0x0, g->base + IXP4XX_REG_GPCLK); in ixp4xx_gpio_probe()
247 * This is a very special big-endian ARM issue: when the IXP4xx is in ixp4xx_gpio_probe()
249 * around to the CPU-native endianness. As you see mostly in the in ixp4xx_gpio_probe()
262 ret = bgpio_init(&g->gc, dev, 4, in ixp4xx_gpio_probe()
263 g->base + IXP4XX_REG_GPIN, in ixp4xx_gpio_probe()
264 g->base + IXP4XX_REG_GPOUT, in ixp4xx_gpio_probe()
267 g->base + IXP4XX_REG_GPOE, in ixp4xx_gpio_probe()
273 g->gc.ngpio = 16; in ixp4xx_gpio_probe()
274 g->gc.label = "IXP4XX_GPIO_CHIP"; in ixp4xx_gpio_probe()
277 * are fetched using phandles, set this to -1 to get rid of in ixp4xx_gpio_probe()
278 * the fixed gpiochip base. in ixp4xx_gpio_probe()
280 g->gc.base = 0; in ixp4xx_gpio_probe()
281 g->gc.parent = &pdev->dev; in ixp4xx_gpio_probe()
282 g->gc.owner = THIS_MODULE; in ixp4xx_gpio_probe()
284 girq = &g->gc.irq; in ixp4xx_gpio_probe()
285 girq->chip = &ixp4xx_gpio_irqchip; in ixp4xx_gpio_probe()
286 girq->fwnode = g->fwnode; in ixp4xx_gpio_probe()
287 girq->parent_domain = parent; in ixp4xx_gpio_probe()
288 girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq; in ixp4xx_gpio_probe()
289 girq->handler = handle_bad_irq; in ixp4xx_gpio_probe()
290 girq->default_type = IRQ_TYPE_NONE; in ixp4xx_gpio_probe()
292 ret = devm_gpiochip_add_data(dev, &g->gc, g); in ixp4xx_gpio_probe()
306 .compatible = "intel,ixp4xx-gpio",
314 .name = "ixp4xx-gpio",