ipr.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Interrupt handling for IPR-based IRQ.
  3. *
  4. * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
  5. * Copyright (C) 2000 Kazumoto Kojima
  6. * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
  7. * Copyright (C) 2006 Paul Mundt
  8. *
  9. * Supported system:
  10. * On-chip supporting modules (TMU, RTC, etc.).
  11. * On-chip supporting modules for SH7709/SH7709A/SH7729/SH7300.
  12. * Hitachi SolutionEngine external I/O:
  13. * MS7709SE01, MS7709ASE01, and MS7750SE01
  14. *
  15. * This file is subject to the terms and conditions of the GNU General Public
  16. * License. See the file "COPYING" in the main directory of this archive
  17. * for more details.
  18. */
  19. #include <linux/init.h>
  20. #include <linux/irq.h>
  21. #include <linux/module.h>
  22. #include <linux/io.h>
  23. #include <linux/interrupt.h>
  24. static void disable_ipr_irq(unsigned int irq)
  25. {
  26. struct ipr_data *p = get_irq_chip_data(irq);
  27. /* Set the priority in IPR to 0 */
  28. ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
  29. }
  30. static void enable_ipr_irq(unsigned int irq)
  31. {
  32. struct ipr_data *p = get_irq_chip_data(irq);
  33. /* Set priority in IPR back to original value */
  34. ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
  35. }
  36. static struct irq_chip ipr_irq_chip = {
  37. .name = "IPR",
  38. .mask = disable_ipr_irq,
  39. .unmask = enable_ipr_irq,
  40. .mask_ack = disable_ipr_irq,
  41. };
  42. unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak));
  43. unsigned int map_ipridx_to_addr(int idx)
  44. {
  45. return 0;
  46. }
  47. void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
  48. {
  49. int i;
  50. for (i = 0; i < nr_irqs; i++) {
  51. unsigned int irq = table[i].irq;
  52. if (!irq)
  53. irq = table[i].irq = i;
  54. /* could the IPR index be mapped, if not we ignore this */
  55. if (!table[i].addr) {
  56. table[i].addr = map_ipridx_to_addr(table[i].ipr_idx);
  57. if (!table[i].addr)
  58. continue;
  59. }
  60. disable_irq_nosync(irq);
  61. set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
  62. handle_level_irq, "level");
  63. set_irq_chip_data(irq, &table[i]);
  64. enable_ipr_irq(irq);
  65. }
  66. }
  67. EXPORT_SYMBOL(make_ipr_irq);
  68. #if !defined(CONFIG_CPU_HAS_PINT_IRQ)
  69. int ipr_irq_demux(int irq)
  70. {
  71. return irq;
  72. }
  73. #endif