irq.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * interrupt controller support for CSR SiRFprimaII
  3. *
  4. * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
  5. *
  6. * Licensed under GPLv2 or later.
  7. */
  8. #include <linux/init.h>
  9. #include <linux/io.h>
  10. #include <linux/irq.h>
  11. #include <mach/hardware.h>
  12. #include <asm/mach/irq.h>
  13. #include <linux/of.h>
  14. #include <linux/of_address.h>
  15. #define SIRFSOC_INT_RISC_MASK0 0x0018
  16. #define SIRFSOC_INT_RISC_MASK1 0x001C
  17. #define SIRFSOC_INT_RISC_LEVEL0 0x0020
  18. #define SIRFSOC_INT_RISC_LEVEL1 0x0024
  19. void __iomem *sirfsoc_intc_base;
  20. static __init void
  21. sirfsoc_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
  22. {
  23. struct irq_chip_generic *gc;
  24. struct irq_chip_type *ct;
  25. gc = irq_alloc_generic_chip("SIRFINTC", 1, irq_start, base, handle_level_irq);
  26. ct = gc->chip_types;
  27. ct->chip.irq_mask = irq_gc_mask_clr_bit;
  28. ct->chip.irq_unmask = irq_gc_mask_set_bit;
  29. ct->regs.mask = SIRFSOC_INT_RISC_MASK0;
  30. irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, IRQ_NOREQUEST, 0);
  31. }
  32. static __init void sirfsoc_irq_init(void)
  33. {
  34. sirfsoc_alloc_gc(sirfsoc_intc_base, 0, 32);
  35. sirfsoc_alloc_gc(sirfsoc_intc_base + 4, 32, SIRFSOC_INTENAL_IRQ_END - 32);
  36. writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL0);
  37. writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_LEVEL1);
  38. writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK0);
  39. writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1);
  40. }
  41. static struct of_device_id intc_ids[] = {
  42. { .compatible = "sirf,prima2-intc" },
  43. };
  44. void __init sirfsoc_of_irq_init(void)
  45. {
  46. struct device_node *np;
  47. np = of_find_matching_node(NULL, intc_ids);
  48. if (!np)
  49. panic("unable to find compatible intc node in dtb\n");
  50. sirfsoc_intc_base = of_iomap(np, 0);
  51. if (!sirfsoc_intc_base)
  52. panic("unable to map intc cpu registers\n");
  53. of_node_put(np);
  54. sirfsoc_irq_init();
  55. }