2 * arch/powerpc/sysdev/ipic.c
4 * IPIC routines implementations.
6 * Copyright 2005 Freescale Semiconductor, Inc.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/errno.h>
16 #include <linux/reboot.h>
17 #include <linux/slab.h>
18 #include <linux/stddef.h>
19 #include <linux/sched.h>
20 #include <linux/signal.h>
21 #include <linux/sysdev.h>
22 #include <linux/device.h>
23 #include <linux/bootmem.h>
24 #include <linux/spinlock.h>
32 static struct ipic
* primary_ipic
;
33 static DEFINE_SPINLOCK(ipic_lock
);
35 static struct ipic_info ipic_info
[] = {
40 .force
= IPIC_SIFCR_H
,
48 .force
= IPIC_SIFCR_H
,
56 .force
= IPIC_SIFCR_H
,
64 .force
= IPIC_SIFCR_H
,
72 .force
= IPIC_SIFCR_H
,
80 .force
= IPIC_SIFCR_H
,
103 .prio
= IPIC_SMPRR_A
,
111 .prio
= IPIC_SMPRR_B
,
119 .prio
= IPIC_SMPRR_B
,
127 .prio
= IPIC_SMPRR_B
,
135 .prio
= IPIC_SMPRR_B
,
141 .pend
= IPIC_SIPNR_H
,
142 .mask
= IPIC_SIMSR_H
,
143 .prio
= IPIC_SIPRR_A
,
144 .force
= IPIC_SIFCR_H
,
149 .pend
= IPIC_SIPNR_H
,
150 .mask
= IPIC_SIMSR_H
,
151 .prio
= IPIC_SIPRR_A
,
152 .force
= IPIC_SIFCR_H
,
157 .pend
= IPIC_SIPNR_H
,
158 .mask
= IPIC_SIMSR_H
,
159 .prio
= IPIC_SIPRR_A
,
160 .force
= IPIC_SIFCR_H
,
165 .pend
= IPIC_SIPNR_H
,
166 .mask
= IPIC_SIMSR_H
,
167 .prio
= IPIC_SIPRR_A
,
168 .force
= IPIC_SIFCR_H
,
173 .pend
= IPIC_SIPNR_H
,
174 .mask
= IPIC_SIMSR_H
,
175 .prio
= IPIC_SIPRR_A
,
176 .force
= IPIC_SIFCR_H
,
181 .pend
= IPIC_SIPNR_H
,
182 .mask
= IPIC_SIMSR_H
,
183 .prio
= IPIC_SIPRR_A
,
184 .force
= IPIC_SIFCR_H
,
189 .pend
= IPIC_SIPNR_H
,
190 .mask
= IPIC_SIMSR_H
,
191 .prio
= IPIC_SIPRR_A
,
192 .force
= IPIC_SIFCR_H
,
197 .pend
= IPIC_SIPNR_H
,
198 .mask
= IPIC_SIMSR_H
,
199 .prio
= IPIC_SIPRR_A
,
200 .force
= IPIC_SIFCR_H
,
207 .prio
= IPIC_SMPRR_A
,
213 .pend
= IPIC_SIPNR_L
,
214 .mask
= IPIC_SIMSR_L
,
215 .prio
= IPIC_SMPRR_A
,
216 .force
= IPIC_SIFCR_L
,
221 .pend
= IPIC_SIPNR_L
,
222 .mask
= IPIC_SIMSR_L
,
223 .prio
= IPIC_SMPRR_A
,
224 .force
= IPIC_SIFCR_L
,
229 .pend
= IPIC_SIPNR_L
,
230 .mask
= IPIC_SIMSR_L
,
231 .prio
= IPIC_SMPRR_A
,
232 .force
= IPIC_SIFCR_L
,
237 .pend
= IPIC_SIPNR_L
,
238 .mask
= IPIC_SIMSR_L
,
239 .prio
= IPIC_SMPRR_A
,
240 .force
= IPIC_SIFCR_L
,
245 .pend
= IPIC_SIPNR_L
,
246 .mask
= IPIC_SIMSR_L
,
247 .prio
= IPIC_SMPRR_B
,
248 .force
= IPIC_SIFCR_L
,
253 .pend
= IPIC_SIPNR_L
,
254 .mask
= IPIC_SIMSR_L
,
255 .prio
= IPIC_SMPRR_B
,
256 .force
= IPIC_SIFCR_L
,
261 .pend
= IPIC_SIPNR_L
,
262 .mask
= IPIC_SIMSR_L
,
263 .prio
= IPIC_SMPRR_B
,
264 .force
= IPIC_SIFCR_L
,
269 .pend
= IPIC_SIPNR_L
,
270 .mask
= IPIC_SIMSR_L
,
271 .prio
= IPIC_SMPRR_B
,
272 .force
= IPIC_SIFCR_L
,
277 .pend
= IPIC_SIPNR_L
,
278 .mask
= IPIC_SIMSR_L
,
280 .force
= IPIC_SIFCR_L
,
284 .pend
= IPIC_SIPNR_L
,
285 .mask
= IPIC_SIMSR_L
,
287 .force
= IPIC_SIFCR_L
,
291 .pend
= IPIC_SIPNR_L
,
292 .mask
= IPIC_SIMSR_L
,
294 .force
= IPIC_SIFCR_L
,
298 .pend
= IPIC_SIPNR_L
,
299 .mask
= IPIC_SIMSR_L
,
301 .force
= IPIC_SIFCR_L
,
305 .pend
= IPIC_SIPNR_L
,
306 .mask
= IPIC_SIMSR_L
,
308 .force
= IPIC_SIFCR_L
,
312 .pend
= IPIC_SIPNR_L
,
313 .mask
= IPIC_SIMSR_L
,
315 .force
= IPIC_SIFCR_L
,
319 .pend
= IPIC_SIPNR_L
,
320 .mask
= IPIC_SIMSR_L
,
322 .force
= IPIC_SIFCR_L
,
326 .pend
= IPIC_SIPNR_L
,
327 .mask
= IPIC_SIMSR_L
,
329 .force
= IPIC_SIFCR_L
,
333 .pend
= IPIC_SIPNR_L
,
334 .mask
= IPIC_SIMSR_L
,
336 .force
= IPIC_SIFCR_L
,
340 .pend
= IPIC_SIPNR_L
,
341 .mask
= IPIC_SIMSR_L
,
343 .force
= IPIC_SIFCR_L
,
347 .pend
= IPIC_SIPNR_L
,
348 .mask
= IPIC_SIMSR_L
,
350 .force
= IPIC_SIFCR_L
,
354 .pend
= IPIC_SIPNR_L
,
355 .mask
= IPIC_SIMSR_L
,
357 .force
= IPIC_SIFCR_L
,
361 .pend
= IPIC_SIPNR_L
,
362 .mask
= IPIC_SIMSR_L
,
364 .force
= IPIC_SIFCR_L
,
369 static inline u32
ipic_read(volatile u32 __iomem
*base
, unsigned int reg
)
371 return in_be32(base
+ (reg
>> 2));
374 static inline void ipic_write(volatile u32 __iomem
*base
, unsigned int reg
, u32 value
)
376 out_be32(base
+ (reg
>> 2), value
);
379 static inline struct ipic
* ipic_from_irq(unsigned int virq
)
384 #define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq)
386 static void ipic_unmask_irq(unsigned int virq
)
388 struct ipic
*ipic
= ipic_from_irq(virq
);
389 unsigned int src
= ipic_irq_to_hw(virq
);
393 spin_lock_irqsave(&ipic_lock
, flags
);
395 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].mask
);
396 temp
|= (1 << (31 - ipic_info
[src
].bit
));
397 ipic_write(ipic
->regs
, ipic_info
[src
].mask
, temp
);
399 spin_unlock_irqrestore(&ipic_lock
, flags
);
402 static void ipic_mask_irq(unsigned int virq
)
404 struct ipic
*ipic
= ipic_from_irq(virq
);
405 unsigned int src
= ipic_irq_to_hw(virq
);
409 spin_lock_irqsave(&ipic_lock
, flags
);
411 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].mask
);
412 temp
&= ~(1 << (31 - ipic_info
[src
].bit
));
413 ipic_write(ipic
->regs
, ipic_info
[src
].mask
, temp
);
415 spin_unlock_irqrestore(&ipic_lock
, flags
);
418 static void ipic_ack_irq(unsigned int virq
)
420 struct ipic
*ipic
= ipic_from_irq(virq
);
421 unsigned int src
= ipic_irq_to_hw(virq
);
425 spin_lock_irqsave(&ipic_lock
, flags
);
427 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].pend
);
428 temp
|= (1 << (31 - ipic_info
[src
].bit
));
429 ipic_write(ipic
->regs
, ipic_info
[src
].pend
, temp
);
431 spin_unlock_irqrestore(&ipic_lock
, flags
);
434 static void ipic_mask_irq_and_ack(unsigned int virq
)
436 struct ipic
*ipic
= ipic_from_irq(virq
);
437 unsigned int src
= ipic_irq_to_hw(virq
);
441 spin_lock_irqsave(&ipic_lock
, flags
);
443 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].mask
);
444 temp
&= ~(1 << (31 - ipic_info
[src
].bit
));
445 ipic_write(ipic
->regs
, ipic_info
[src
].mask
, temp
);
447 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].pend
);
448 temp
|= (1 << (31 - ipic_info
[src
].bit
));
449 ipic_write(ipic
->regs
, ipic_info
[src
].pend
, temp
);
451 spin_unlock_irqrestore(&ipic_lock
, flags
);
454 static int ipic_set_irq_type(unsigned int virq
, unsigned int flow_type
)
456 struct ipic
*ipic
= ipic_from_irq(virq
);
457 unsigned int src
= ipic_irq_to_hw(virq
);
458 struct irq_desc
*desc
= get_irq_desc(virq
);
459 unsigned int vold
, vnew
, edibit
;
461 if (flow_type
== IRQ_TYPE_NONE
)
462 flow_type
= IRQ_TYPE_LEVEL_LOW
;
464 /* ipic supports only low assertion and high-to-low change senses
466 if (!(flow_type
& (IRQ_TYPE_LEVEL_LOW
| IRQ_TYPE_EDGE_FALLING
))) {
467 printk(KERN_ERR
"ipic: sense type 0x%x not supported\n",
472 desc
->status
&= ~(IRQ_TYPE_SENSE_MASK
| IRQ_LEVEL
);
473 desc
->status
|= flow_type
& IRQ_TYPE_SENSE_MASK
;
474 if (flow_type
& IRQ_TYPE_LEVEL_LOW
) {
475 desc
->status
|= IRQ_LEVEL
;
476 desc
->handle_irq
= handle_level_irq
;
478 desc
->handle_irq
= handle_edge_irq
;
481 /* only EXT IRQ senses are programmable on ipic
482 * internal IRQ senses are LEVEL_LOW
484 if (src
== IPIC_IRQ_EXT0
)
487 if (src
>= IPIC_IRQ_EXT1
&& src
<= IPIC_IRQ_EXT7
)
488 edibit
= (14 - (src
- IPIC_IRQ_EXT1
));
490 return (flow_type
& IRQ_TYPE_LEVEL_LOW
) ? 0 : -EINVAL
;
492 vold
= ipic_read(ipic
->regs
, IPIC_SECNR
);
493 if ((flow_type
& IRQ_TYPE_SENSE_MASK
) == IRQ_TYPE_EDGE_FALLING
) {
494 vnew
= vold
| (1 << edibit
);
496 vnew
= vold
& ~(1 << edibit
);
499 ipic_write(ipic
->regs
, IPIC_SECNR
, vnew
);
503 static struct irq_chip ipic_irq_chip
= {
504 .typename
= " IPIC ",
505 .unmask
= ipic_unmask_irq
,
506 .mask
= ipic_mask_irq
,
507 .mask_ack
= ipic_mask_irq_and_ack
,
509 .set_type
= ipic_set_irq_type
,
512 static int ipic_host_match(struct irq_host
*h
, struct device_node
*node
)
514 /* Exact match, unless ipic node is NULL */
515 return h
->of_node
== NULL
|| h
->of_node
== node
;
518 static int ipic_host_map(struct irq_host
*h
, unsigned int virq
,
521 struct ipic
*ipic
= h
->host_data
;
522 struct irq_chip
*chip
;
525 chip
= &ipic
->hc_irq
;
527 set_irq_chip_data(virq
, ipic
);
528 set_irq_chip_and_handler(virq
, chip
, handle_level_irq
);
530 /* Set default irq type */
531 set_irq_type(virq
, IRQ_TYPE_NONE
);
536 static int ipic_host_xlate(struct irq_host
*h
, struct device_node
*ct
,
537 u32
*intspec
, unsigned int intsize
,
538 irq_hw_number_t
*out_hwirq
, unsigned int *out_flags
)
541 /* interrupt sense values coming from the device tree equal either
542 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
544 *out_hwirq
= intspec
[0];
546 *out_flags
= intspec
[1];
548 *out_flags
= IRQ_TYPE_NONE
;
552 static struct irq_host_ops ipic_host_ops
= {
553 .match
= ipic_host_match
,
554 .map
= ipic_host_map
,
555 .xlate
= ipic_host_xlate
,
558 struct ipic
* __init
ipic_init(struct device_node
*node
, unsigned int flags
)
564 ipic
= alloc_bootmem(sizeof(struct ipic
));
568 memset(ipic
, 0, sizeof(struct ipic
));
570 ipic
->irqhost
= irq_alloc_host(of_node_get(node
), IRQ_HOST_MAP_LINEAR
,
573 if (ipic
->irqhost
== NULL
) {
578 ret
= of_address_to_resource(node
, 0, &res
);
584 ipic
->regs
= ioremap(res
.start
, res
.end
- res
.start
+ 1);
586 ipic
->irqhost
->host_data
= ipic
;
587 ipic
->hc_irq
= ipic_irq_chip
;
590 ipic_write(ipic
->regs
, IPIC_SICNR
, 0x0);
592 /* default priority scheme is grouped. If spread mode is required
593 * configure SICFR accordingly */
594 if (flags
& IPIC_SPREADMODE_GRP_A
)
596 if (flags
& IPIC_SPREADMODE_GRP_D
)
598 if (flags
& IPIC_SPREADMODE_MIX_A
)
600 if (flags
& IPIC_SPREADMODE_MIX_B
)
603 ipic_write(ipic
->regs
, IPIC_SICNR
, temp
);
605 /* handle MCP route */
607 if (flags
& IPIC_DISABLE_MCP_OUT
)
609 ipic_write(ipic
->regs
, IPIC_SERCR
, temp
);
611 /* handle routing of IRQ0 to MCP */
612 temp
= ipic_read(ipic
->regs
, IPIC_SEMSR
);
614 if (flags
& IPIC_IRQ0_MCP
)
617 temp
&= ~SEMSR_SIRQ0
;
619 ipic_write(ipic
->regs
, IPIC_SEMSR
, temp
);
622 irq_set_default_host(primary_ipic
->irqhost
);
624 printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS
,
630 int ipic_set_priority(unsigned int virq
, unsigned int priority
)
632 struct ipic
*ipic
= ipic_from_irq(virq
);
633 unsigned int src
= ipic_irq_to_hw(virq
);
640 if (ipic_info
[src
].prio
== 0)
643 temp
= ipic_read(ipic
->regs
, ipic_info
[src
].prio
);
646 temp
&= ~(0x7 << (20 + (3 - priority
) * 3));
647 temp
|= ipic_info
[src
].prio_mask
<< (20 + (3 - priority
) * 3);
649 temp
&= ~(0x7 << (4 + (7 - priority
) * 3));
650 temp
|= ipic_info
[src
].prio_mask
<< (4 + (7 - priority
) * 3);
653 ipic_write(ipic
->regs
, ipic_info
[src
].prio
, temp
);
658 void ipic_set_highest_priority(unsigned int virq
)
660 struct ipic
*ipic
= ipic_from_irq(virq
);
661 unsigned int src
= ipic_irq_to_hw(virq
);
664 temp
= ipic_read(ipic
->regs
, IPIC_SICFR
);
666 /* clear and set HPI */
668 temp
|= (src
& 0x7f) << 24;
670 ipic_write(ipic
->regs
, IPIC_SICFR
, temp
);
673 void ipic_set_default_priority(void)
675 ipic_write(primary_ipic
->regs
, IPIC_SIPRR_A
, IPIC_SIPRR_A_DEFAULT
);
676 ipic_write(primary_ipic
->regs
, IPIC_SIPRR_D
, IPIC_SIPRR_D_DEFAULT
);
677 ipic_write(primary_ipic
->regs
, IPIC_SMPRR_A
, IPIC_SMPRR_A_DEFAULT
);
678 ipic_write(primary_ipic
->regs
, IPIC_SMPRR_B
, IPIC_SMPRR_B_DEFAULT
);
681 void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq
)
683 struct ipic
*ipic
= primary_ipic
;
686 temp
= ipic_read(ipic
->regs
, IPIC_SERMR
);
687 temp
|= (1 << (31 - mcp_irq
));
688 ipic_write(ipic
->regs
, IPIC_SERMR
, temp
);
691 void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq
)
693 struct ipic
*ipic
= primary_ipic
;
696 temp
= ipic_read(ipic
->regs
, IPIC_SERMR
);
697 temp
&= (1 << (31 - mcp_irq
));
698 ipic_write(ipic
->regs
, IPIC_SERMR
, temp
);
701 u32
ipic_get_mcp_status(void)
703 return ipic_read(primary_ipic
->regs
, IPIC_SERMR
);
706 void ipic_clear_mcp_status(u32 mask
)
708 ipic_write(primary_ipic
->regs
, IPIC_SERMR
, mask
);
711 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
712 unsigned int ipic_get_irq(void)
716 BUG_ON(primary_ipic
== NULL
);
718 #define IPIC_SIVCR_VECTOR_MASK 0x7f
719 irq
= ipic_read(primary_ipic
->regs
, IPIC_SIVCR
) & IPIC_SIVCR_VECTOR_MASK
;
721 if (irq
== 0) /* 0 --> no irq is pending */
724 return irq_linear_revmap(primary_ipic
->irqhost
, irq
);
727 static struct sysdev_class ipic_sysclass
= {
728 set_kset_name("ipic"),
731 static struct sys_device device_ipic
= {
733 .cls
= &ipic_sysclass
,
736 static int __init
init_ipic_sysfs(void)
740 if (!primary_ipic
->regs
)
742 printk(KERN_DEBUG
"Registering ipic with sysfs...\n");
744 rc
= sysdev_class_register(&ipic_sysclass
);
746 printk(KERN_ERR
"Failed registering ipic sys class\n");
749 rc
= sysdev_register(&device_ipic
);
751 printk(KERN_ERR
"Failed registering ipic sys device\n");
757 subsys_initcall(init_ipic_sysfs
);