Lines Matching +full:pl192 +full:- +full:vic
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * linux/arch/arm/common/vic.c
5 * Copyright (C) 1999 - 2003 ARM Limited
23 #include <linux/irqchip/arm-vic.h>
40 #define VIC_VECT_ADDR0 0x100 /* 0 to 15 (0..31 PL192) */
41 #define VIC_VECT_CNTL0 0x200 /* 0 to 15 (0..31 PL192) */
42 #define VIC_ITCR 0x300 /* VIC test control register */
49 * struct vic_device - VIC PM device
50 * @base: The register base for the VIC.
51 * @irq: The IRQ number for the base of the VIC.
59 * @domain: The IRQ domain for the VIC.
82 * vic_init2 - common initialisation code
83 * @base: Base of the VIC.
101 static void resume_one_vic(struct vic_device *vic) in resume_one_vic() argument
103 void __iomem *base = vic->base; in resume_one_vic()
105 printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base); in resume_one_vic()
107 /* re-initialise static settings */ in resume_one_vic()
110 writel(vic->int_select, base + VIC_INT_SELECT); in resume_one_vic()
111 writel(vic->protect, base + VIC_PROTECT); in resume_one_vic()
113 /* set the enabled ints and then clear the non-enabled */ in resume_one_vic()
114 writel(vic->int_enable, base + VIC_INT_ENABLE); in resume_one_vic()
115 writel(~vic->int_enable, base + VIC_INT_ENABLE_CLEAR); in resume_one_vic()
117 /* and the same for the soft-int register */ in resume_one_vic()
119 writel(vic->soft_int, base + VIC_INT_SOFT); in resume_one_vic()
120 writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR); in resume_one_vic()
127 for (id = vic_id - 1; id >= 0; id--) in vic_resume()
131 static void suspend_one_vic(struct vic_device *vic) in suspend_one_vic() argument
133 void __iomem *base = vic->base; in suspend_one_vic()
135 printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base); in suspend_one_vic()
137 vic->int_select = readl(base + VIC_INT_SELECT); in suspend_one_vic()
138 vic->int_enable = readl(base + VIC_INT_ENABLE); in suspend_one_vic()
139 vic->soft_int = readl(base + VIC_INT_SOFT); in suspend_one_vic()
140 vic->protect = readl(base + VIC_PROTECT); in suspend_one_vic()
145 writel(vic->resume_irqs, base + VIC_INT_ENABLE); in suspend_one_vic()
146 writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR); in suspend_one_vic()
165 * vic_pm_init - initcall to register VIC pm
169 * nature of the VIC's registration.
186 struct vic_device *v = d->host_data; in vic_irqdomain_map()
189 if (!(v->valid_sources & (1 << hwirq))) in vic_irqdomain_map()
190 return -EPERM; in vic_irqdomain_map()
192 irq_set_chip_data(irq, v->base); in vic_irqdomain_map()
198 * Handle each interrupt in a single VIC. Returns non-zero if we've
201 * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
203 static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) in handle_one_vic() argument
208 while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { in handle_one_vic()
209 irq = ffs(stat) - 1; in handle_one_vic()
210 generic_handle_domain_irq(vic->domain, irq); in handle_one_vic()
221 struct vic_device *vic = irq_desc_get_handler_data(desc); in vic_handle_irq_cascaded() local
225 while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { in vic_handle_irq_cascaded()
226 hwirq = ffs(stat) - 1; in vic_handle_irq_cascaded()
227 generic_handle_domain_irq(vic->domain, hwirq); in vic_handle_irq_cascaded()
234 * Keep iterating over all registered VIC's until there are no pending
253 * vic_register() - Register a VIC.
254 * @base: The base address of the VIC.
256 * @irq: The base IRQ for the VIC.
259 * @node: The device tree node associated with the VIC.
261 * Register the VIC with the system device tree so that it can be notified
263 * taken to re-instate the settings on resume.
265 * This also configures the IRQ domain for the VIC.
281 v->base = base; in vic_register()
282 v->valid_sources = valid_sources; in vic_register()
283 v->resume_sources = resume_sources; in vic_register()
292 v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, in vic_register()
297 irq_create_mapping(v->domain, i); in vic_register()
300 v->irq = irq; in vic_register()
302 v->irq = irq_find_mapping(v->domain, 0); in vic_register()
308 unsigned int irq = d->hwirq; in vic_ack_irq()
310 /* moreover, clear the soft-triggered, in case it was the reason */ in vic_ack_irq()
317 unsigned int irq = d->hwirq; in vic_mask_irq()
324 unsigned int irq = d->hwirq; in vic_unmask_irq()
336 if (v->irq == base_irq) in vic_from_irq()
345 struct vic_device *v = vic_from_irq(d->irq); in vic_set_wake()
346 unsigned int off = d->hwirq; in vic_set_wake()
350 return -EINVAL; in vic_set_wake()
352 if (!(bit & v->resume_sources)) in vic_set_wake()
353 return -EINVAL; in vic_set_wake()
356 v->resume_irqs |= bit; in vic_set_wake()
358 v->resume_irqs &= ~bit; in vic_set_wake()
367 .name = "VIC",
441 /* Identify which VIC cell this one is, by reading the ID */ in __vic_init()
448 printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n", in __vic_init()
456 printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n"); in __vic_init()
474 * vic_init() - initialise a vectored interrupt controller
497 return -EIO; in vic_of_init()
499 of_property_read_u32(node, "valid-mask", &interrupt_mask); in vic_of_init()
500 of_property_read_u32(node, "valid-wakeup-mask", &wakeup_mask); in vic_of_init()
512 IRQCHIP_DECLARE(arm_pl190_vic, "arm,pl190-vic", vic_of_init);
513 IRQCHIP_DECLARE(arm_pl192_vic, "arm,pl192-vic", vic_of_init);
514 IRQCHIP_DECLARE(arm_versatile_vic, "arm,versatile-vic", vic_of_init);