Lines Matching +full:edge +full:- +full:offset
1 // SPDX-License-Identifier: GPL-2.0-or-later
13 * See "Documentation/devicetree/bindings/gpio/gpio-grgpio.txt" for
45 /* Structure for an irq of the core - called an underlying irq */
56 s8 index; /* Index into struct grgpio_priv's uirqs, or -1 */
83 * obtains from this driver. An index value of -1 for a certain gpio
90 static void grgpio_set_imask(struct grgpio_priv *priv, unsigned int offset, in grgpio_set_imask() argument
93 struct gpio_chip *gc = &priv->gc; in grgpio_set_imask()
96 priv->imask |= BIT(offset); in grgpio_set_imask()
98 priv->imask &= ~BIT(offset); in grgpio_set_imask()
99 gc->write_reg(priv->regs + GRGPIO_IMASK, priv->imask); in grgpio_set_imask()
102 static int grgpio_to_irq(struct gpio_chip *gc, unsigned offset) in grgpio_to_irq() argument
106 if (offset >= gc->ngpio) in grgpio_to_irq()
107 return -ENXIO; in grgpio_to_irq()
109 if (priv->lirqs[offset].index < 0) in grgpio_to_irq()
110 return -ENXIO; in grgpio_to_irq()
112 return irq_create_mapping(priv->domain, offset); in grgpio_to_irq()
115 /* -------------------- IRQ chip functions -------------------- */
121 u32 mask = BIT(d->hwirq); in grgpio_irq_set_type()
125 u32 edge; in grgpio_irq_set_type() local
130 edge = 0; in grgpio_irq_set_type()
134 edge = 0; in grgpio_irq_set_type()
138 edge = mask; in grgpio_irq_set_type()
142 edge = mask; in grgpio_irq_set_type()
145 return -EINVAL; in grgpio_irq_set_type()
148 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_set_type()
150 ipol = priv->gc.read_reg(priv->regs + GRGPIO_IPOL) & ~mask; in grgpio_irq_set_type()
151 iedge = priv->gc.read_reg(priv->regs + GRGPIO_IEDGE) & ~mask; in grgpio_irq_set_type()
153 priv->gc.write_reg(priv->regs + GRGPIO_IPOL, ipol | pol); in grgpio_irq_set_type()
154 priv->gc.write_reg(priv->regs + GRGPIO_IEDGE, iedge | edge); in grgpio_irq_set_type()
156 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_set_type()
164 int offset = d->hwirq; in grgpio_irq_mask() local
167 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_mask()
169 grgpio_set_imask(priv, offset, 0); in grgpio_irq_mask()
171 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_mask()
177 int offset = d->hwirq; in grgpio_irq_unmask() local
180 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_unmask()
182 grgpio_set_imask(priv, offset, 1); in grgpio_irq_unmask()
184 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_unmask()
197 int ngpio = priv->gc.ngpio; in grgpio_irq_handler()
202 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_handler()
209 struct grgpio_lirq *lirq = &priv->lirqs[i]; in grgpio_irq_handler()
211 if (priv->imask & BIT(i) && lirq->index >= 0 && in grgpio_irq_handler()
212 priv->uirqs[lirq->index].uirq == irq) { in grgpio_irq_handler()
213 generic_handle_irq(lirq->irq); in grgpio_irq_handler()
218 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_handler()
221 dev_warn(priv->dev, "No gpio line matched irq %d\n", irq); in grgpio_irq_handler()
233 struct grgpio_priv *priv = d->host_data; in grgpio_irq_map()
237 int offset = hwirq; in grgpio_irq_map() local
241 return -EINVAL; in grgpio_irq_map()
243 lirq = &priv->lirqs[offset]; in grgpio_irq_map()
244 if (lirq->index < 0) in grgpio_irq_map()
245 return -EINVAL; in grgpio_irq_map()
247 dev_dbg(priv->dev, "Mapping irq %d for gpio line %d\n", in grgpio_irq_map()
248 irq, offset); in grgpio_irq_map()
250 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_map()
253 lirq->irq = irq; in grgpio_irq_map()
254 uirq = &priv->uirqs[lirq->index]; in grgpio_irq_map()
255 if (uirq->refcnt == 0) { in grgpio_irq_map()
256 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_map()
257 ret = request_irq(uirq->uirq, grgpio_irq_handler, 0, in grgpio_irq_map()
258 dev_name(priv->dev), priv); in grgpio_irq_map()
260 dev_err(priv->dev, in grgpio_irq_map()
262 uirq->uirq); in grgpio_irq_map()
265 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_map()
267 uirq->refcnt++; in grgpio_irq_map()
269 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_map()
282 struct grgpio_priv *priv = d->host_data; in grgpio_irq_unmap()
287 int ngpio = priv->gc.ngpio; in grgpio_irq_unmap()
293 raw_spin_lock_irqsave(&priv->gc.bgpio_lock, flags); in grgpio_irq_unmap()
296 index = -1; in grgpio_irq_unmap()
298 lirq = &priv->lirqs[i]; in grgpio_irq_unmap()
299 if (lirq->irq == irq) { in grgpio_irq_unmap()
301 lirq->irq = 0; in grgpio_irq_unmap()
302 index = lirq->index; in grgpio_irq_unmap()
309 uirq = &priv->uirqs[lirq->index]; in grgpio_irq_unmap()
310 uirq->refcnt--; in grgpio_irq_unmap()
311 if (uirq->refcnt == 0) { in grgpio_irq_unmap()
312 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_unmap()
313 free_irq(uirq->uirq, priv); in grgpio_irq_unmap()
318 raw_spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); in grgpio_irq_unmap()
326 /* ------------------------------------------------------------ */
330 struct device_node *np = ofdev->dev.of_node; in grgpio_probe()
340 priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); in grgpio_probe()
342 return -ENOMEM; in grgpio_probe()
348 gc = &priv->gc; in grgpio_probe()
349 err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA, in grgpio_probe()
353 dev_err(&ofdev->dev, "bgpio_init() failed\n"); in grgpio_probe()
357 priv->regs = regs; in grgpio_probe()
358 priv->imask = gc->read_reg(regs + GRGPIO_IMASK); in grgpio_probe()
359 priv->dev = &ofdev->dev; in grgpio_probe()
361 gc->owner = THIS_MODULE; in grgpio_probe()
362 gc->to_irq = grgpio_to_irq; in grgpio_probe()
363 gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np); in grgpio_probe()
364 gc->base = -1; in grgpio_probe()
368 gc->ngpio = GRGPIO_MAX_NGPIO; in grgpio_probe()
369 dev_dbg(&ofdev->dev, in grgpio_probe()
370 "No or invalid nbits property: assume %d\n", gc->ngpio); in grgpio_probe()
372 gc->ngpio = prop; in grgpio_probe()
381 if (size < gc->ngpio) { in grgpio_probe()
382 dev_err(&ofdev->dev, in grgpio_probe()
384 size, gc->ngpio); in grgpio_probe()
385 return -EINVAL; in grgpio_probe()
388 priv->domain = irq_domain_add_linear(np, gc->ngpio, in grgpio_probe()
391 if (!priv->domain) { in grgpio_probe()
392 dev_err(&ofdev->dev, "Could not add irq domain\n"); in grgpio_probe()
393 return -EINVAL; in grgpio_probe()
396 for (i = 0; i < gc->ngpio; i++) { in grgpio_probe()
400 lirq = &priv->lirqs[i]; in grgpio_probe()
401 lirq->index = irqmap[i]; in grgpio_probe()
403 if (lirq->index < 0) in grgpio_probe()
406 ret = platform_get_irq(ofdev, lirq->index); in grgpio_probe()
414 priv->uirqs[lirq->index].uirq = ret; in grgpio_probe()
422 dev_err(&ofdev->dev, "Could not add gpiochip\n"); in grgpio_probe()
423 if (priv->domain) in grgpio_probe()
424 irq_domain_remove(priv->domain); in grgpio_probe()
428 dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", in grgpio_probe()
429 priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off"); in grgpio_probe()
438 gpiochip_remove(&priv->gc); in grgpio_remove()
440 if (priv->domain) in grgpio_remove()
441 irq_domain_remove(priv->domain); in grgpio_remove()