platform.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/platform_device.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/memblock.h>
  5. #include <asm/virt.h>
  6. #include <asm/irq.h>
  7. #define VIRTIO_BUS_NB 128
  8. static struct platform_device * __init virt_virtio_init(unsigned int id)
  9. {
  10. const struct resource res[] = {
  11. DEFINE_RES_MEM(virt_bi_data.virtio.mmio + id * 0x200, 0x200),
  12. DEFINE_RES_IRQ(virt_bi_data.virtio.irq + id),
  13. };
  14. return platform_device_register_simple("virtio-mmio", id,
  15. res, ARRAY_SIZE(res));
  16. }
  17. static int __init virt_platform_init(void)
  18. {
  19. const struct resource goldfish_tty_res[] = {
  20. DEFINE_RES_MEM(virt_bi_data.tty.mmio, 1),
  21. DEFINE_RES_IRQ(virt_bi_data.tty.irq),
  22. };
  23. /* this is the second gf-rtc, the first one is used by the scheduler */
  24. const struct resource goldfish_rtc_res[] = {
  25. DEFINE_RES_MEM(virt_bi_data.rtc.mmio + 0x1000, 0x1000),
  26. DEFINE_RES_IRQ(virt_bi_data.rtc.irq + 1),
  27. };
  28. struct platform_device *pdev1, *pdev2;
  29. struct platform_device *pdevs[VIRTIO_BUS_NB];
  30. unsigned int i;
  31. int ret = 0;
  32. if (!MACH_IS_VIRT)
  33. return -ENODEV;
  34. /* We need this to have DMA'able memory provided to goldfish-tty */
  35. min_low_pfn = 0;
  36. pdev1 = platform_device_register_simple("goldfish_tty",
  37. PLATFORM_DEVID_NONE,
  38. goldfish_tty_res,
  39. ARRAY_SIZE(goldfish_tty_res));
  40. if (IS_ERR(pdev1))
  41. return PTR_ERR(pdev1);
  42. pdev2 = platform_device_register_simple("goldfish_rtc",
  43. PLATFORM_DEVID_NONE,
  44. goldfish_rtc_res,
  45. ARRAY_SIZE(goldfish_rtc_res));
  46. if (IS_ERR(pdev2)) {
  47. ret = PTR_ERR(pdev2);
  48. goto err_unregister_tty;
  49. }
  50. for (i = 0; i < VIRTIO_BUS_NB; i++) {
  51. pdevs[i] = virt_virtio_init(i);
  52. if (IS_ERR(pdevs[i])) {
  53. ret = PTR_ERR(pdevs[i]);
  54. goto err_unregister_rtc_virtio;
  55. }
  56. }
  57. return 0;
  58. err_unregister_rtc_virtio:
  59. while (i > 0)
  60. platform_device_unregister(pdevs[--i]);
  61. platform_device_unregister(pdev2);
  62. err_unregister_tty:
  63. platform_device_unregister(pdev1);
  64. return ret;
  65. }
  66. arch_initcall(virt_platform_init);