device.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * s6105 platform devices
  3. *
  4. * Copyright (c) 2009 emlix GmbH
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/gpio.h>
  8. #include <linux/init.h>
  9. #include <linux/irq.h>
  10. #include <linux/phy.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/serial.h>
  13. #include <linux/serial_8250.h>
  14. #include <variant/hardware.h>
  15. #include <variant/dmac.h>
  16. #include <platform/gpio.h>
  17. #define GPIO3_INTNUM 3
  18. #define UART_INTNUM 4
  19. #define GMAC_INTNUM 5
  20. static const signed char gpio3_irq_mappings[] = {
  21. S6_INTC_GPIO(3),
  22. -1
  23. };
  24. static const signed char uart_irq_mappings[] = {
  25. S6_INTC_UART(0),
  26. S6_INTC_UART(1),
  27. -1,
  28. };
  29. static const signed char gmac_irq_mappings[] = {
  30. S6_INTC_GMAC_STAT,
  31. S6_INTC_GMAC_ERR,
  32. S6_INTC_DMA_HOSTTERMCNT(0),
  33. S6_INTC_DMA_HOSTTERMCNT(1),
  34. -1
  35. };
  36. const signed char *platform_irq_mappings[NR_IRQS] = {
  37. [GPIO3_INTNUM] = gpio3_irq_mappings,
  38. [UART_INTNUM] = uart_irq_mappings,
  39. [GMAC_INTNUM] = gmac_irq_mappings,
  40. };
  41. static struct plat_serial8250_port serial_platform_data[] = {
  42. {
  43. .membase = (void *)S6_REG_UART + 0x0000,
  44. .mapbase = S6_REG_UART + 0x0000,
  45. .irq = UART_INTNUM,
  46. .uartclk = S6_SCLK,
  47. .regshift = 2,
  48. .iotype = SERIAL_IO_MEM,
  49. .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
  50. },
  51. {
  52. .membase = (void *)S6_REG_UART + 0x1000,
  53. .mapbase = S6_REG_UART + 0x1000,
  54. .irq = UART_INTNUM,
  55. .uartclk = S6_SCLK,
  56. .regshift = 2,
  57. .iotype = SERIAL_IO_MEM,
  58. .flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST,
  59. },
  60. { },
  61. };
  62. static struct resource s6_gmac_resource[] = {
  63. {
  64. .name = "mem",
  65. .start = (resource_size_t)S6_REG_GMAC,
  66. .end = (resource_size_t)S6_REG_GMAC + 0x10000 - 1,
  67. .flags = IORESOURCE_MEM,
  68. },
  69. {
  70. .name = "dma",
  71. .start = (resource_size_t)
  72. DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX),
  73. .end = (resource_size_t)
  74. DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1,
  75. .flags = IORESOURCE_DMA,
  76. },
  77. {
  78. .name = "dma",
  79. .start = (resource_size_t)
  80. DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX),
  81. .end = (resource_size_t)
  82. DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1,
  83. .flags = IORESOURCE_DMA,
  84. },
  85. {
  86. .name = "io",
  87. .start = (resource_size_t)S6_MEM_GMAC,
  88. .end = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1,
  89. .flags = IORESOURCE_IO,
  90. },
  91. {
  92. .name = "irq",
  93. .start = (resource_size_t)GMAC_INTNUM,
  94. .flags = IORESOURCE_IRQ,
  95. },
  96. {
  97. .name = "irq",
  98. .start = (resource_size_t)PHY_POLL,
  99. .flags = IORESOURCE_IRQ,
  100. },
  101. };
  102. static int __init prepare_phy_irq(int pin)
  103. {
  104. int irq;
  105. if (gpio_request(pin, "s6gmac_phy") < 0)
  106. goto fail;
  107. if (gpio_direction_input(pin) < 0)
  108. goto free;
  109. irq = gpio_to_irq(pin);
  110. if (irq < 0)
  111. goto free;
  112. if (irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0)
  113. goto free;
  114. return irq;
  115. free:
  116. gpio_free(pin);
  117. fail:
  118. return PHY_POLL;
  119. }
  120. static struct platform_device platform_devices[] = {
  121. {
  122. .name = "serial8250",
  123. .id = PLAT8250_DEV_PLATFORM,
  124. .dev = {
  125. .platform_data = serial_platform_data,
  126. },
  127. },
  128. {
  129. .name = "s6gmac",
  130. .id = 0,
  131. .resource = s6_gmac_resource,
  132. .num_resources = ARRAY_SIZE(s6_gmac_resource),
  133. },
  134. {
  135. I2C_BOARD_INFO("m41t62", S6I2C_ADDR_M41T62),
  136. },
  137. };
  138. static int __init device_init(void)
  139. {
  140. int i;
  141. s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ);
  142. for (i = 0; i < ARRAY_SIZE(platform_devices); i++)
  143. platform_device_register(&platform_devices[i]);
  144. return 0;
  145. }
  146. arch_initcall_sync(device_init);