Merge branch 'master' of git://git.denx.de/u-boot-atmel
[platform/kernel/u-boot.git] / arch / powerpc / cpu / ppc4xx / xilinx_irq.c
1 /*
2  * (C) Copyright 2008
3  * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@gmail.com
4  * This work has been supported by: QTechnology  http://qtec.com/
5  * Based on interrupts.c Wolfgang Denk-DENX Software Engineering-wd@denx.de
6  * SPDX-License-Identifier:     GPL-2.0+
7 */
8 #include <common.h>
9 #include <watchdog.h>
10 #include <command.h>
11 #include <asm/processor.h>
12 #include <asm/interrupt.h>
13 #include <asm/ppc4xx.h>
14 #include <ppc_asm.tmpl>
15 #include <commproc.h>
16 #include <asm/io.h>
17 #include <asm/xilinx_irq.h>
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 void pic_enable(void)
22 {
23         debug("Xilinx PIC at 0x%8x\n", intc);
24
25         /*
26          * Disable all external interrupts until they are
27          * explicitly requested.
28          */
29         out_be32((u32 *) IER, 0);
30
31         /* Acknowledge any pending interrupts just in case. */
32         out_be32((u32 *) IAR, 0xffffffff);
33
34         /* Turn on the Master Enable. */
35         out_be32((u32 *) MER, 0x3UL);
36
37         return;
38 }
39
40 int xilinx_pic_irq_get(void)
41 {
42         u32 irq;
43         irq = in_be32((u32 *) IVR);
44
45         /* If no interrupt is pending then all bits of the IVR are set to 1. As
46          * the IVR is as many bits wide as numbers of inputs are available.
47          * Therefore, if all bits of the IVR are set to one, its content will
48          * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS.
49          */
50         if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS)
51                 irq = -1;       /* report no pending interrupt. */
52
53         debug("get_irq: %d\n", irq);
54         return (irq);
55 }
56
57 void pic_irq_enable(unsigned int irq)
58 {
59         u32 mask = IRQ_MASK(irq);
60         debug("enable: %d\n", irq);
61         out_be32((u32 *) SIE, mask);
62 }
63
64 void pic_irq_disable(unsigned int irq)
65 {
66         u32 mask = IRQ_MASK(irq);
67         debug("disable: %d\n", irq);
68         out_be32((u32 *) CIE, mask);
69 }
70
71 void pic_irq_ack(unsigned int irq)
72 {
73         u32 mask = IRQ_MASK(irq);
74         debug("ack: %d\n", irq);
75         out_be32((u32 *) IAR, mask);
76 }
77
78 void external_interrupt(struct pt_regs *regs)
79 {
80         int irq;
81
82         irq = xilinx_pic_irq_get();
83         if (irq < 0)
84                 return;
85
86         interrupt_run_handler(irq);
87
88         return;
89 }