irq.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. /*
  2. * s6000 irq crossbar
  3. *
  4. * Copyright (c) 2009 emlix GmbH
  5. * Authors: Johannes Weiner <jw@emlix.com>
  6. * Oskar Schirmer <os@emlix.com>
  7. */
  8. #include <linux/io.h>
  9. #include <asm/irq.h>
  10. #include <variant/hardware.h>
  11. /* S6_REG_INTC */
  12. #define INTC_STATUS 0x000
  13. #define INTC_RAW 0x010
  14. #define INTC_STATUS_AG 0x100
  15. #define INTC_CFG(n) (0x200 + 4 * (n))
  16. /*
  17. * The s6000 has a crossbar that multiplexes interrupt output lines
  18. * from the peripherals to input lines on the xtensa core.
  19. *
  20. * We leave the mapping decisions to the platform as it depends on the
  21. * actually connected peripherals which distribution makes sense.
  22. */
  23. extern const signed char *platform_irq_mappings[NR_IRQS];
  24. static unsigned long scp_to_intc_enable[] = {
  25. #define TO_INTC_ENABLE(n) (((n) << 1) + 1)
  26. TO_INTC_ENABLE(0),
  27. TO_INTC_ENABLE(1),
  28. TO_INTC_ENABLE(2),
  29. TO_INTC_ENABLE(3),
  30. TO_INTC_ENABLE(4),
  31. TO_INTC_ENABLE(5),
  32. TO_INTC_ENABLE(6),
  33. TO_INTC_ENABLE(7),
  34. TO_INTC_ENABLE(8),
  35. TO_INTC_ENABLE(9),
  36. TO_INTC_ENABLE(10),
  37. TO_INTC_ENABLE(11),
  38. TO_INTC_ENABLE(12),
  39. -1,
  40. -1,
  41. TO_INTC_ENABLE(13),
  42. -1,
  43. TO_INTC_ENABLE(14),
  44. -1,
  45. TO_INTC_ENABLE(15),
  46. #undef TO_INTC_ENABLE
  47. };
  48. static void irq_set(unsigned int irq, int enable)
  49. {
  50. unsigned long en;
  51. const signed char *m = platform_irq_mappings[irq];
  52. if (!m)
  53. return;
  54. en = enable ? scp_to_intc_enable[irq] : 0;
  55. while (*m >= 0) {
  56. writel(en, S6_REG_INTC + INTC_CFG(*m));
  57. m++;
  58. }
  59. }
  60. void variant_irq_enable(unsigned int irq)
  61. {
  62. irq_set(irq, 1);
  63. }
  64. void variant_irq_disable(unsigned int irq)
  65. {
  66. irq_set(irq, 0);
  67. }