Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
prm_common.c
Go to the documentation of this file.
1 /*
2  * OMAP2+ common Power & Reset Management (PRM) IP block functions
3  *
4  * Copyright (C) 2011 Texas Instruments, Inc.
5  * Tero Kristo <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  *
12  * For historical purposes, the API used to configure the PRM
13  * interrupt handler refers to it as the "PRCM interrupt." The
14  * underlying registers are located in the PRM on OMAP3/4.
15  *
16  * XXX This code should eventually be moved to a PRM driver.
17  */
18 
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/io.h>
23 #include <linux/irq.h>
24 #include <linux/interrupt.h>
25 #include <linux/slab.h>
26 
27 #include <plat/common.h>
28 #include <plat/prcm.h>
29 
30 #include "prm2xxx_3xxx.h"
31 #include "prm44xx.h"
32 
33 /*
34  * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs
35  * XXX this is technically not needed, since
36  * omap_prcm_register_chain_handler() could allocate this based on the
37  * actual amount of memory needed for the SoC
38  */
39 #define OMAP_PRCM_MAX_NR_PENDING_REG 2
40 
41 /*
42  * prcm_irq_chips: an array of all of the "generic IRQ chips" in use
43  * by the PRCM interrupt handler code. There will be one 'chip' per
44  * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have
45  * one "chip" and OMAP4 will have two.)
46  */
47 static struct irq_chip_generic **prcm_irq_chips;
48 
49 /*
50  * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code
51  * is currently running on. Defined and passed by initialization code
52  * that calls omap_prcm_register_chain_handler().
53  */
54 static struct omap_prcm_irq_setup *prcm_irq_setup;
55 
56 /* Private functions */
57 
58 /*
59  * Move priority events from events to priority_events array
60  */
61 static void omap_prcm_events_filter_priority(unsigned long *events,
62  unsigned long *priority_events)
63 {
64  int i;
65 
66  for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
67  priority_events[i] =
68  events[i] & prcm_irq_setup->priority_mask[i];
69  events[i] ^= priority_events[i];
70  }
71 }
72 
73 /*
74  * PRCM Interrupt Handler
75  *
76  * This is a common handler for the OMAP PRCM interrupts. Pending
77  * interrupts are detected by a call to prcm_pending_events and
78  * dispatched accordingly. Clearing of the wakeup events should be
79  * done by the SoC specific individual handlers.
80  */
81 static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc)
82 {
83  unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
84  unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
85  struct irq_chip *chip = irq_desc_get_chip(desc);
86  unsigned int virtirq;
87  int nr_irq = prcm_irq_setup->nr_regs * 32;
88 
89  /*
90  * If we are suspended, mask all interrupts from PRCM level,
91  * this does not ack them, and they will be pending until we
92  * re-enable the interrupts, at which point the
93  * omap_prcm_irq_handler will be executed again. The
94  * _save_and_clear_irqen() function must ensure that the PRM
95  * write to disable all IRQs has reached the PRM before
96  * returning, or spurious PRCM interrupts may occur during
97  * suspend.
98  */
99  if (prcm_irq_setup->suspended) {
100  prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
101  prcm_irq_setup->suspend_save_flag = true;
102  }
103 
104  /*
105  * Loop until all pending irqs are handled, since
106  * generic_handle_irq() can cause new irqs to come
107  */
108  while (!prcm_irq_setup->suspended) {
109  prcm_irq_setup->read_pending_irqs(pending);
110 
111  /* No bit set, then all IRQs are handled */
112  if (find_first_bit(pending, nr_irq) >= nr_irq)
113  break;
114 
115  omap_prcm_events_filter_priority(pending, priority_pending);
116 
117  /*
118  * Loop on all currently pending irqs so that new irqs
119  * cannot starve previously pending irqs
120  */
121 
122  /* Serve priority events first */
123  for_each_set_bit(virtirq, priority_pending, nr_irq)
124  generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
125 
126  /* Serve normal events next */
127  for_each_set_bit(virtirq, pending, nr_irq)
128  generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
129  }
130  if (chip->irq_ack)
131  chip->irq_ack(&desc->irq_data);
132  if (chip->irq_eoi)
133  chip->irq_eoi(&desc->irq_data);
134  chip->irq_unmask(&desc->irq_data);
135 
136  prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */
137 }
138 
139 /* Public functions */
140 
150 {
151  int i;
152 
153  if (!prcm_irq_setup || !name)
154  return -ENOENT;
155 
156  for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
157  if (!strcmp(prcm_irq_setup->irqs[i].name, name))
158  return prcm_irq_setup->base_irq +
159  prcm_irq_setup->irqs[i].offset;
160 
161  return -ENOENT;
162 }
163 
171 {
172  int i;
173 
174  if (!prcm_irq_setup) {
175  pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
176  return;
177  }
178 
179  if (prcm_irq_chips) {
180  for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
181  if (prcm_irq_chips[i])
182  irq_remove_generic_chip(prcm_irq_chips[i],
183  0xffffffff, 0, 0);
184  prcm_irq_chips[i] = NULL;
185  }
186  kfree(prcm_irq_chips);
187  prcm_irq_chips = NULL;
188  }
189 
190  kfree(prcm_irq_setup->saved_mask);
191  prcm_irq_setup->saved_mask = NULL;
192 
193  kfree(prcm_irq_setup->priority_mask);
194  prcm_irq_setup->priority_mask = NULL;
195 
196  irq_set_chained_handler(prcm_irq_setup->irq, NULL);
197 
198  if (prcm_irq_setup->base_irq > 0)
199  irq_free_descs(prcm_irq_setup->base_irq,
200  prcm_irq_setup->nr_regs * 32);
201  prcm_irq_setup->base_irq = 0;
202 }
203 
205 {
206  prcm_irq_setup->suspended = true;
207 }
208 
210 {
211  prcm_irq_setup->suspended = false;
212 
213  /* If we have not saved the masks, do not attempt to restore */
214  if (!prcm_irq_setup->suspend_save_flag)
215  return;
216 
217  prcm_irq_setup->suspend_save_flag = false;
218 
219  /*
220  * Re-enable all masked PRCM irq sources, this causes the PRCM
221  * interrupt to fire immediately if the events were masked
222  * previously in the chain handler
223  */
224  prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
225 }
226 
238 {
239  int nr_regs;
241  int offset, i;
242  struct irq_chip_generic *gc;
243  struct irq_chip_type *ct;
244 
245  if (!irq_setup)
246  return -EINVAL;
247 
248  nr_regs = irq_setup->nr_regs;
249 
250  if (prcm_irq_setup) {
251  pr_err("PRCM: already initialized; won't reinitialize\n");
252  return -EINVAL;
253  }
254 
255  if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
256  pr_err("PRCM: nr_regs too large\n");
257  return -EINVAL;
258  }
259 
260  prcm_irq_setup = irq_setup;
261 
262  prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL);
263  prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL);
264  prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs,
265  GFP_KERNEL);
266 
267  if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
268  !prcm_irq_setup->priority_mask) {
269  pr_err("PRCM: kzalloc failed\n");
270  goto err;
271  }
272 
273  memset(mask, 0, sizeof(mask));
274 
275  for (i = 0; i < irq_setup->nr_irqs; i++) {
276  offset = irq_setup->irqs[i].offset;
277  mask[offset >> 5] |= 1 << (offset & 0x1f);
278  if (irq_setup->irqs[i].priority)
279  irq_setup->priority_mask[offset >> 5] |=
280  1 << (offset & 0x1f);
281  }
282 
283  irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
284 
285  irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
286  0);
287 
288  if (irq_setup->base_irq < 0) {
289  pr_err("PRCM: failed to allocate irq descs: %d\n",
290  irq_setup->base_irq);
291  goto err;
292  }
293 
294  for (i = 0; i < irq_setup->nr_regs; i++) {
295  gc = irq_alloc_generic_chip("PRCM", 1,
296  irq_setup->base_irq + i * 32, prm_base,
298 
299  if (!gc) {
300  pr_err("PRCM: failed to allocate generic chip\n");
301  goto err;
302  }
303  ct = gc->chip_types;
304  ct->chip.irq_ack = irq_gc_ack_set_bit;
305  ct->chip.irq_mask = irq_gc_mask_clr_bit;
306  ct->chip.irq_unmask = irq_gc_mask_set_bit;
307 
308  ct->regs.ack = irq_setup->ack + i * 4;
309  ct->regs.mask = irq_setup->mask + i * 4;
310 
311  irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
312  prcm_irq_chips[i] = gc;
313  }
314 
315  return 0;
316 
317 err:
319  return -ENOMEM;
320 }
321 
322 /*
323  * Stubbed functions so that common files continue to build when
324  * custom builds are used
325  * XXX These are temporary and should be removed at the earliest possible
326  * opportunity
327  */
329 {
330  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
331  return 0;
332 }
333 
335 {
336  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
337 }
338 
340  s16 module, s16 idx)
341 {
342  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
343  return 0;
344 }
345 
347 {
348  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
349  return 0;
350 }
351 
353 {
354  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
355  return 0;
356 }
357 
359 {
360  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
361  return 0;
362 }
363 
365 {
366  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
367  return 0;
368 }
369 
371 {
372  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
373  return 0;
374 }
375 
376 int __weak omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
377  u8 st_shift)
378 {
379  WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
380  return 0;
381 }
382