22 #include <linux/export.h>
24 #include <linux/list.h>
31 #include <linux/device.h>
34 #include <asm/exception.h>
65 static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
80 for (i = 0; i < 16; i++) {
89 static void resume_one_vic(
struct vic_device *vic)
111 static void vic_resume(
void)
115 for (
id = vic_id - 1;
id >= 0;
id--)
116 resume_one_vic(vic_devices +
id);
119 static void suspend_one_vic(
struct vic_device *vic)
137 static int vic_suspend(
void)
141 for (
id = 0;
id < vic_id;
id++)
142 suspend_one_vic(vic_devices +
id);
149 .resume = vic_resume,
159 static int __init vic_pm_init(
void)
171 static int vic_irqdomain_map(
struct irq_domain *
d,
unsigned int irq,
186 .map = vic_irqdomain_map,
204 static void __init vic_register(
void __iomem *base,
unsigned int irq,
205 u32 valid_sources,
u32 resume_sources,
211 printk(
KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
215 v = &vic_devices[vic_id];
222 &vic_irqdomain_ops, v);
225 static void vic_ack_irq(
struct irq_data *d)
227 void __iomem *base = irq_data_get_irq_chip_data(d);
228 unsigned int irq = d->
hwirq;
234 static void vic_mask_irq(
struct irq_data *d)
236 void __iomem *base = irq_data_get_irq_chip_data(d);
237 unsigned int irq = d->
hwirq;
241 static void vic_unmask_irq(
struct irq_data *d)
243 void __iomem *base = irq_data_get_irq_chip_data(d);
244 unsigned int irq = d->
hwirq;
248 #if defined(CONFIG_PM)
249 static struct vic_device *vic_from_irq(
unsigned int irq)
252 unsigned int base_irq = irq & ~31;
255 for (
id = 0;
id < vic_id;
id++, v++) {
256 if (v->
irq == base_irq)
266 unsigned int off = d->
hwirq;
283 #define vic_set_wake NULL
288 .irq_ack = vic_ack_irq,
289 .irq_mask = vic_mask_irq,
290 .irq_unmask = vic_unmask_irq,
308 for (i = 0; i < 19; i++) {
323 static void __init vic_init_st(
void __iomem *base,
unsigned int irq_start,
339 vic_clear_interrupts(base);
342 for (i = 0; i < 16; i++) {
350 vic_register(base, irq_start, vic_sources, 0, node);
354 u32 vic_sources,
u32 resume_sources,
362 for (i = 0; i < 4; i++) {
365 cellid |= (
readl(addr) & 0xff) << (8 * i);
367 vendor = (cellid >> 12) & 0xff;
369 base, cellid, vendor);
373 vic_init_st(base, irq_start, vic_sources, node);
386 vic_clear_interrupts(base);
390 vic_register(base, irq_start, vic_sources, resume_sources, node);
401 u32 vic_sources,
u32 resume_sources)
412 if (
WARN(parent,
"non-root VICs are not supported"))
463 for (i = 0, handled = 0; i < vic_id; ++
i)
464 handled |= handle_one_vic(&vic_devices[i], regs);