Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fpga-irq.c
Go to the documentation of this file.
1 /*
2  * Support for Versatile FPGA-based IRQ controllers
3  */
4 #include <linux/irq.h>
5 #include <linux/io.h>
6 #include <linux/irqdomain.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/of_address.h>
10 
11 #include <asm/exception.h>
12 #include <asm/mach/irq.h>
13 #include <plat/fpga-irq.h>
14 
15 #define IRQ_STATUS 0x00
16 #define IRQ_RAW_STATUS 0x04
17 #define IRQ_ENABLE_SET 0x08
18 #define IRQ_ENABLE_CLEAR 0x0c
19 #define INT_SOFT_SET 0x10
20 #define INT_SOFT_CLEAR 0x14
21 #define FIQ_STATUS 0x20
22 #define FIQ_RAW_STATUS 0x24
23 #define FIQ_ENABLE 0x28
24 #define FIQ_ENABLE_SET 0x28
25 #define FIQ_ENABLE_CLEAR 0x2C
26 
35 struct fpga_irq_data {
36  void __iomem *base;
37  struct irq_chip chip;
39  struct irq_domain *domain;
41 };
42 
43 /* we cannot allocate memory when the controllers are initially registered */
44 static struct fpga_irq_data fpga_irq_devices[CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR];
45 static int fpga_irq_id;
46 
47 static void fpga_irq_mask(struct irq_data *d)
48 {
49  struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
50  u32 mask = 1 << d->hwirq;
51 
52  writel(mask, f->base + IRQ_ENABLE_CLEAR);
53 }
54 
55 static void fpga_irq_unmask(struct irq_data *d)
56 {
57  struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
58  u32 mask = 1 << d->hwirq;
59 
60  writel(mask, f->base + IRQ_ENABLE_SET);
61 }
62 
63 static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
64 {
65  struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
66  u32 status = readl(f->base + IRQ_STATUS);
67 
68  if (status == 0) {
69  do_bad_IRQ(irq, desc);
70  return;
71  }
72 
73  do {
74  irq = ffs(status) - 1;
75  status &= ~(1 << irq);
77  } while (status);
78 }
79 
80 /*
81  * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero
82  * if we've handled at least one interrupt. This does a single read of the
83  * status register and handles all interrupts in order from LSB first.
84  */
85 static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
86 {
87  int handled = 0;
88  int irq;
89  u32 status;
90 
91  while ((status = readl(f->base + IRQ_STATUS))) {
92  irq = ffs(status) - 1;
93  handle_IRQ(irq_find_mapping(f->domain, irq), regs);
94  handled = 1;
95  }
96 
97  return handled;
98 }
99 
100 /*
101  * Keep iterating over all registered FPGA IRQ controllers until there are
102  * no pending interrupts.
103  */
105 {
106  int i, handled;
107 
108  do {
109  for (i = 0, handled = 0; i < fpga_irq_id; ++i)
110  handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
111  } while (handled);
112 }
113 
114 static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
115  irq_hw_number_t hwirq)
116 {
117  struct fpga_irq_data *f = d->host_data;
118 
119  /* Skip invalid IRQs, only register handlers for the real ones */
120  if (!(f->valid & (1 << hwirq)))
121  return -ENOTSUPP;
122  irq_set_chip_data(irq, f);
123  irq_set_chip_and_handler(irq, &f->chip,
126  f->used_irqs++;
127  return 0;
128 }
129 
130 static struct irq_domain_ops fpga_irqdomain_ops = {
131  .map = fpga_irqdomain_map,
133 };
134 
135 static __init struct fpga_irq_data *
136 fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) {
137  struct fpga_irq_data *f;
138 
139  if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
140  printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
141  return NULL;
142  }
143  f = &fpga_irq_devices[fpga_irq_id];
144  f->base = base;
145  f->chip.name = name;
146  f->chip.irq_ack = fpga_irq_mask;
147  f->chip.irq_mask = fpga_irq_mask;
148  f->chip.irq_unmask = fpga_irq_unmask;
149  f->valid = valid;
150  fpga_irq_id++;
151 
152  return f;
153 }
154 
155 void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
156  int parent_irq, u32 valid, struct device_node *node)
157 {
158  struct fpga_irq_data *f;
159 
160  f = fpga_irq_prep_struct(base, name, valid);
161  if (!f)
162  return;
163 
164  if (parent_irq != -1) {
165  irq_set_handler_data(parent_irq, f);
166  irq_set_chained_handler(parent_irq, fpga_irq_handle);
167  }
168 
169  f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0,
170  &fpga_irqdomain_ops, f);
171  pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
172  fpga_irq_id, name, base, f->used_irqs);
173 }
174 
175 #ifdef CONFIG_OF
177  struct device_node *parent)
178 {
179  struct fpga_irq_data *f;
180  void __iomem *base;
181  u32 clear_mask;
182  u32 valid_mask;
183 
184  if (WARN_ON(!node))
185  return -ENODEV;
186 
187  base = of_iomap(node, 0);
188  WARN(!base, "unable to map fpga irq registers\n");
189 
190  if (of_property_read_u32(node, "clear-mask", &clear_mask))
191  clear_mask = 0;
192 
193  if (of_property_read_u32(node, "valid-mask", &valid_mask))
194  valid_mask = 0;
195 
196  f = fpga_irq_prep_struct(base, node->name, valid_mask);
197  if (!f)
198  return -ENOMEM;
199 
200  writel(clear_mask, base + IRQ_ENABLE_CLEAR);
201  writel(clear_mask, base + FIQ_ENABLE_CLEAR);
202 
203  f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f);
204  f->used_irqs = hweight32(valid_mask);
205 
206  pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
207  fpga_irq_id, node->name, base, f->used_irqs);
208  return 0;
209 }
210 #endif