Lines Matching +full:io +full:- +full:width
1 // SPDX-License-Identifier: GPL-2.0
14 #include <linux/io.h>
35 * SENSE is read-write 32-bit with 2-bits or 4-bits per IRQ (*)
36 * PRIO is read-write 32-bit with 4-bits per IRQ (**)
37 * SOURCE is read-only 32-bit or 8-bit with 1-bit per IRQ (***)
38 * MASK is write-only 32-bit or 8-bit with 1-bit per IRQ (***)
39 * CLEAR is write-only 32-bit or 8-bit with 1-bit per IRQ (***)
41 * (*) May be accessed by more than one driver instance - lock needed
42 * (**) Read-modify-write access by one driver instance - lock needed
43 * (***) Accessed by one driver instance only - no locking needed
50 int width; member
73 int irlm_bit; /* -1 if non-existent */
99 struct intc_irqpin_iomem *i = &p->iomem[reg]; in intc_irqpin_read()
101 return i->read(i->iomem); in intc_irqpin_read()
107 struct intc_irqpin_iomem *i = &p->iomem[reg]; in intc_irqpin_write()
109 i->write(i->iomem, data); in intc_irqpin_write()
115 return BIT((p->iomem[reg].width - 1) - hw_irq); in intc_irqpin_hwirq_mask()
128 int width, int value) in intc_irqpin_read_modify_write() argument
136 tmp &= ~(((1 << width) - 1) << shift); in intc_irqpin_read_modify_write()
146 /* The PRIO register is assumed to be 32-bit with fixed 4-bit fields. */ in intc_irqpin_mask_unmask_prio()
148 int shift = 32 - (irq + 1) * bitfield_width; in intc_irqpin_mask_unmask_prio()
152 do_mask ? 0 : (1 << bitfield_width) - 1); in intc_irqpin_mask_unmask_prio()
157 /* The SENSE register is assumed to be 32-bit. */ in intc_irqpin_set_sense()
158 int bitfield_width = p->sense_bitfield_width; in intc_irqpin_set_sense()
159 int shift = 32 - (irq + 1) * bitfield_width; in intc_irqpin_set_sense()
161 dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value); in intc_irqpin_set_sense()
164 return -EINVAL; in intc_irqpin_set_sense()
173 dev_dbg(&i->p->pdev->dev, "%s (%d:%d:%d)\n", in intc_irqpin_dbg()
174 str, i->requested_irq, i->hw_irq, i->domain_irq); in intc_irqpin_dbg()
182 intc_irqpin_dbg(&p->irq[hw_irq], "enable"); in intc_irqpin_irq_enable()
191 intc_irqpin_dbg(&p->irq[hw_irq], "disable"); in intc_irqpin_irq_disable()
200 intc_irqpin_dbg(&p->irq[hw_irq], "shared enable"); in intc_irqpin_shared_irq_enable()
203 p->shared_irq_mask &= ~BIT(hw_irq); in intc_irqpin_shared_irq_enable()
211 intc_irqpin_dbg(&p->irq[hw_irq], "shared disable"); in intc_irqpin_shared_irq_disable()
214 p->shared_irq_mask |= BIT(hw_irq); in intc_irqpin_shared_irq_disable()
220 int irq = p->irq[irqd_to_hwirq(d)].requested_irq; in intc_irqpin_irq_enable_force()
225 * assumes non-shared interrupt with 1:1 mapping in intc_irqpin_irq_enable_force()
228 irq_get_chip(irq)->irq_unmask(irq_get_irq_data(irq)); in intc_irqpin_irq_enable_force()
234 int irq = p->irq[irqd_to_hwirq(d)].requested_irq; in intc_irqpin_irq_disable_force()
237 * assumes non-shared interrupt with 1:1 mapping in intc_irqpin_irq_disable_force()
240 irq_get_chip(irq)->irq_mask(irq_get_irq_data(irq)); in intc_irqpin_irq_disable_force()
261 return -EINVAL; in intc_irqpin_irq_set_type()
272 irq_set_irq_wake(p->irq[hw_irq].requested_irq, on); in intc_irqpin_irq_set_wake()
274 atomic_inc(&p->wakeup_path); in intc_irqpin_irq_set_wake()
276 atomic_dec(&p->wakeup_path); in intc_irqpin_irq_set_wake()
284 struct intc_irqpin_priv *p = i->p; in intc_irqpin_irq_handler()
288 bit = intc_irqpin_hwirq_mask(p, INTC_IRQPIN_REG_SOURCE, i->hw_irq); in intc_irqpin_irq_handler()
293 generic_handle_irq(i->domain_irq); in intc_irqpin_irq_handler()
307 if (reg_source & BIT(7 - k)) { in intc_irqpin_shared_irq_handler()
308 if (BIT(k) & p->shared_irq_mask) in intc_irqpin_shared_irq_handler()
311 status |= intc_irqpin_irq_handler(irq, &p->irq[k]); in intc_irqpin_shared_irq_handler()
330 struct intc_irqpin_priv *p = h->host_data; in intc_irqpin_irq_domain_map()
332 p->irq[hw].domain_irq = virq; in intc_irqpin_irq_domain_map()
333 p->irq[hw].hw_irq = hw; in intc_irqpin_irq_domain_map()
335 intc_irqpin_dbg(&p->irq[hw], "map"); in intc_irqpin_irq_domain_map()
336 irq_set_chip_data(virq, h->host_data); in intc_irqpin_irq_domain_map()
339 irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); in intc_irqpin_irq_domain_map()
353 .irlm_bit = -1,
357 { .compatible = "renesas,intc-irqpin", },
358 { .compatible = "renesas,intc-irqpin-r8a7778",
360 { .compatible = "renesas,intc-irqpin-r8a7779",
362 { .compatible = "renesas,intc-irqpin-r8a7740",
364 { .compatible = "renesas,intc-irqpin-sh73a0",
373 struct device *dev = &pdev->dev; in intc_irqpin_probe()
376 struct resource *io[INTC_IRQPIN_REG_NR]; in intc_irqpin_probe() local
389 return -ENOMEM; in intc_irqpin_probe()
392 of_property_read_u32(dev->of_node, "sense-bitfield-width", in intc_irqpin_probe()
393 &p->sense_bitfield_width); in intc_irqpin_probe()
394 control_parent = of_property_read_bool(dev->of_node, "control-parent"); in intc_irqpin_probe()
395 if (!p->sense_bitfield_width) in intc_irqpin_probe()
396 p->sense_bitfield_width = 4; /* default to 4 bits */ in intc_irqpin_probe()
398 p->pdev = pdev; in intc_irqpin_probe()
407 memset(io, 0, sizeof(io)); in intc_irqpin_probe()
409 io[k] = platform_get_resource(pdev, IORESOURCE_MEM, k); in intc_irqpin_probe()
410 if (!io[k] && k < INTC_IRQPIN_REG_NR_MANDATORY) { in intc_irqpin_probe()
412 ret = -EINVAL; in intc_irqpin_probe()
420 if (ret == -ENXIO) in intc_irqpin_probe()
425 p->irq[k].p = p; in intc_irqpin_probe()
426 p->irq[k].requested_irq = ret; in intc_irqpin_probe()
432 ret = -EINVAL; in intc_irqpin_probe()
438 i = &p->iomem[k]; in intc_irqpin_probe()
441 if (!io[k]) in intc_irqpin_probe()
444 switch (resource_size(io[k])) { in intc_irqpin_probe()
446 i->width = 8; in intc_irqpin_probe()
447 i->read = intc_irqpin_read8; in intc_irqpin_probe()
448 i->write = intc_irqpin_write8; in intc_irqpin_probe()
451 i->width = 32; in intc_irqpin_probe()
452 i->read = intc_irqpin_read32; in intc_irqpin_probe()
453 i->write = intc_irqpin_write32; in intc_irqpin_probe()
457 ret = -EINVAL; in intc_irqpin_probe()
461 i->iomem = devm_ioremap(dev, io[k]->start, in intc_irqpin_probe()
462 resource_size(io[k])); in intc_irqpin_probe()
463 if (!i->iomem) { in intc_irqpin_probe()
465 ret = -ENXIO; in intc_irqpin_probe()
471 if (config && config->irlm_bit >= 0) { in intc_irqpin_probe()
472 if (io[INTC_IRQPIN_REG_IRLM]) in intc_irqpin_probe()
474 config->irlm_bit, 1, 1); in intc_irqpin_probe()
487 ref_irq = p->irq[0].requested_irq; in intc_irqpin_probe()
488 p->shared_irqs = 1; in intc_irqpin_probe()
490 if (ref_irq != p->irq[k].requested_irq) { in intc_irqpin_probe()
491 p->shared_irqs = 0; in intc_irqpin_probe()
500 } else if (!p->shared_irqs) { in intc_irqpin_probe()
508 irq_chip = &p->irq_chip; in intc_irqpin_probe()
509 irq_chip->name = "intc-irqpin"; in intc_irqpin_probe()
510 irq_chip->irq_mask = disable_fn; in intc_irqpin_probe()
511 irq_chip->irq_unmask = enable_fn; in intc_irqpin_probe()
512 irq_chip->irq_set_type = intc_irqpin_irq_set_type; in intc_irqpin_probe()
513 irq_chip->irq_set_wake = intc_irqpin_irq_set_wake; in intc_irqpin_probe()
514 irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; in intc_irqpin_probe()
516 p->irq_domain = irq_domain_add_simple(dev->of_node, nirqs, 0, in intc_irqpin_probe()
518 if (!p->irq_domain) { in intc_irqpin_probe()
519 ret = -ENXIO; in intc_irqpin_probe()
524 irq_domain_set_pm_device(p->irq_domain, dev); in intc_irqpin_probe()
526 if (p->shared_irqs) { in intc_irqpin_probe()
528 if (devm_request_irq(dev, p->irq[0].requested_irq, in intc_irqpin_probe()
532 ret = -ENOENT; in intc_irqpin_probe()
538 if (devm_request_irq(dev, p->irq[k].requested_irq, in intc_irqpin_probe()
540 &p->irq[k])) { in intc_irqpin_probe()
542 ret = -ENOENT; in intc_irqpin_probe()
557 irq_domain_remove(p->irq_domain); in intc_irqpin_probe()
568 irq_domain_remove(p->irq_domain); in intc_irqpin_remove()
569 pm_runtime_put(&pdev->dev); in intc_irqpin_remove()
570 pm_runtime_disable(&pdev->dev); in intc_irqpin_remove()
577 if (atomic_read(&p->wakeup_path)) in intc_irqpin_suspend()