~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/platforms/8xx/pic.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/kernel.h>
  2 #include <linux/stddef.h>
  3 #include <linux/sched.h>
  4 #include <linux/signal.h>
  5 #include <linux/irq.h>
  6 #include <linux/dma-mapping.h>
  7 #include <linux/of_address.h>
  8 #include <linux/of_irq.h>
  9 #include <asm/irq.h>
 10 #include <asm/io.h>
 11 #include <asm/8xx_immap.h>
 12 
 13 #include "pic.h"
 14 
 15 
 16 #define PIC_VEC_SPURRIOUS      15
 17 
 18 static struct irq_domain *mpc8xx_pic_host;
 19 static unsigned long mpc8xx_cached_irq_mask;
 20 static sysconf8xx_t __iomem *siu_reg;
 21 
 22 static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d)
 23 {
 24         return 0x80000000 >> irqd_to_hwirq(d);
 25 }
 26 
 27 static void mpc8xx_unmask_irq(struct irq_data *d)
 28 {
 29         mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
 30         out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 31 }
 32 
 33 static void mpc8xx_mask_irq(struct irq_data *d)
 34 {
 35         mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d);
 36         out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 37 }
 38 
 39 static void mpc8xx_ack(struct irq_data *d)
 40 {
 41         out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d));
 42 }
 43 
 44 static void mpc8xx_end_irq(struct irq_data *d)
 45 {
 46         mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d);
 47         out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask);
 48 }
 49 
 50 static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
 51 {
 52         /* only external IRQ senses are programmable */
 53         if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) {
 54                 unsigned int siel = in_be32(&siu_reg->sc_siel);
 55                 siel |= mpc8xx_irqd_to_bit(d);
 56                 out_be32(&siu_reg->sc_siel, siel);
 57                 irq_set_handler_locked(d, handle_edge_irq);
 58         }
 59         return 0;
 60 }
 61 
 62 static struct irq_chip mpc8xx_pic = {
 63         .name = "8XX SIU",
 64         .irq_unmask = mpc8xx_unmask_irq,
 65         .irq_mask = mpc8xx_mask_irq,
 66         .irq_ack = mpc8xx_ack,
 67         .irq_eoi = mpc8xx_end_irq,
 68         .irq_set_type = mpc8xx_set_irq_type,
 69 };
 70 
 71 unsigned int mpc8xx_get_irq(void)
 72 {
 73         int irq;
 74 
 75         /* For MPC8xx, read the SIVEC register and shift the bits down
 76          * to get the irq number.
 77          */
 78         irq = in_be32(&siu_reg->sc_sivec) >> 26;
 79 
 80         if (irq == PIC_VEC_SPURRIOUS)
 81                 return 0;
 82 
 83         return irq_linear_revmap(mpc8xx_pic_host, irq);
 84 
 85 }
 86 
 87 static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq,
 88                           irq_hw_number_t hw)
 89 {
 90         pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
 91 
 92         /* Set default irq handle */
 93         irq_set_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq);
 94         return 0;
 95 }
 96 
 97 
 98 static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
 99                             const u32 *intspec, unsigned int intsize,
100                             irq_hw_number_t *out_hwirq, unsigned int *out_flags)
101 {
102         static unsigned char map_pic_senses[4] = {
103                 IRQ_TYPE_EDGE_RISING,
104                 IRQ_TYPE_LEVEL_LOW,
105                 IRQ_TYPE_LEVEL_HIGH,
106                 IRQ_TYPE_EDGE_FALLING,
107         };
108 
109         if (intspec[0] > 0x1f)
110                 return 0;
111 
112         *out_hwirq = intspec[0];
113         if (intsize > 1 && intspec[1] < 4)
114                 *out_flags = map_pic_senses[intspec[1]];
115         else
116                 *out_flags = IRQ_TYPE_NONE;
117 
118         return 0;
119 }
120 
121 
122 static const struct irq_domain_ops mpc8xx_pic_host_ops = {
123         .map = mpc8xx_pic_host_map,
124         .xlate = mpc8xx_pic_host_xlate,
125 };
126 
127 void __init mpc8xx_pic_init(void)
128 {
129         struct resource res;
130         struct device_node *np;
131         int ret;
132 
133         np = of_find_compatible_node(NULL, NULL, "fsl,pq1-pic");
134         if (np == NULL)
135                 np = of_find_node_by_type(NULL, "mpc8xx-pic");
136         if (np == NULL) {
137                 printk(KERN_ERR "Could not find fsl,pq1-pic node\n");
138                 return;
139         }
140 
141         ret = of_address_to_resource(np, 0, &res);
142         if (ret)
143                 goto out;
144 
145         siu_reg = ioremap(res.start, resource_size(&res));
146         if (!siu_reg)
147                 goto out;
148 
149         mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
150         if (!mpc8xx_pic_host)
151                 printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
152 
153 out:
154         of_node_put(np);
155 }
156 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php