mpic_msi.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; version 2 of the
  7. * License.
  8. *
  9. */
  10. #include <linux/irq.h>
  11. #include <linux/bitmap.h>
  12. #include <linux/msi.h>
  13. #include <asm/mpic.h>
  14. #include <asm/prom.h>
  15. #include <asm/hw_irq.h>
  16. #include <asm/ppc-pci.h>
  17. #include <asm/msi_bitmap.h>
  18. #include <sysdev/mpic.h>
  19. void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
  20. {
  21. /* The mpic calls this even when there is no allocator setup */
  22. if (!mpic->msi_bitmap.bitmap)
  23. return;
  24. msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
  25. }
  26. #ifdef CONFIG_MPIC_U3_HT_IRQS
  27. static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
  28. {
  29. irq_hw_number_t hwirq;
  30. struct irq_host_ops *ops = mpic->irqhost->ops;
  31. struct device_node *np;
  32. int flags, index, i;
  33. struct of_irq oirq;
  34. pr_debug("mpic: found U3, guessing msi allocator setup\n");
  35. /* Reserve source numbers we know are reserved in the HW */
  36. for (i = 0; i < 8; i++)
  37. msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  38. for (i = 42; i < 46; i++)
  39. msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  40. for (i = 100; i < 105; i++)
  41. msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, i);
  42. np = NULL;
  43. while ((np = of_find_all_nodes(np))) {
  44. pr_debug("mpic: mapping hwirqs for %s\n", np->full_name);
  45. index = 0;
  46. while (of_irq_map_one(np, index++, &oirq) == 0) {
  47. ops->xlate(mpic->irqhost, NULL, oirq.specifier,
  48. oirq.size, &hwirq, &flags);
  49. msi_bitmap_reserve_hwirq(&mpic->msi_bitmap, hwirq);
  50. }
  51. }
  52. return 0;
  53. }
  54. #else
  55. static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
  56. {
  57. return -1;
  58. }
  59. #endif
  60. int mpic_msi_init_allocator(struct mpic *mpic)
  61. {
  62. int rc;
  63. rc = msi_bitmap_alloc(&mpic->msi_bitmap, mpic->irq_count,
  64. mpic->irqhost->of_node);
  65. if (rc)
  66. return rc;
  67. rc = msi_bitmap_reserve_dt_hwirqs(&mpic->msi_bitmap);
  68. if (rc > 0) {
  69. if (mpic->flags & MPIC_U3_HT_IRQS)
  70. rc = mpic_msi_reserve_u3_hwirqs(mpic);
  71. if (rc) {
  72. msi_bitmap_free(&mpic->msi_bitmap);
  73. return rc;
  74. }
  75. }
  76. return 0;
  77. }