018-modular-init-smc91x.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. Index: linux-2.6.21.7/drivers/net/Kconfig
  2. ===================================================================
  3. --- linux-2.6.21.7.orig/drivers/net/Kconfig
  4. +++ linux-2.6.21.7/drivers/net/Kconfig
  5. @@ -959,6 +959,12 @@ config SMC91X
  6. module, say M here and read <file:Documentation/modules.txt> as well
  7. as <file:Documentation/networking/net-modules.txt>.
  8. +config SMC91X_GUMSTIX
  9. + tristate
  10. + default m if SMC91X=m
  11. + default y if SMC91X=y
  12. + depends on SMC91X && ARCH_GUMSTIX
  13. +
  14. config SMC9194
  15. tristate "SMC 9194 support"
  16. depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
  17. Index: linux-2.6.21.7/drivers/net/Makefile
  18. ===================================================================
  19. --- linux-2.6.21.7.orig/drivers/net/Makefile
  20. +++ linux-2.6.21.7/drivers/net/Makefile
  21. @@ -201,6 +201,7 @@ obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
  22. obj-$(CONFIG_MACB) += macb.o
  23. +obj-$(CONFIG_SMC91X_GUMSTIX) += gumstix-smc91x.o
  24. obj-$(CONFIG_ARM) += arm/
  25. obj-$(CONFIG_DEV_APPLETALK) += appletalk/
  26. obj-$(CONFIG_TR) += tokenring/
  27. Index: linux-2.6.21.7/drivers/net/smc91x.c
  28. ===================================================================
  29. --- linux-2.6.21.7.orig/drivers/net/smc91x.c
  30. +++ linux-2.6.21.7/drivers/net/smc91x.c
  31. @@ -2373,6 +2373,10 @@ static struct platform_driver smc_driver
  32. },
  33. };
  34. +#ifdef CONFIG_ARCH_GUMSTIX
  35. +extern void gumstix_smc91x_load(void);
  36. +#endif
  37. +
  38. static int __init smc_init(void)
  39. {
  40. #ifdef MODULE
  41. @@ -2384,6 +2388,10 @@ static int __init smc_init(void)
  42. #endif
  43. #endif
  44. +#ifdef CONFIG_ARCH_GUMSTIX
  45. + gumstix_smc91x_load();
  46. +#endif
  47. +
  48. return platform_driver_register(&smc_driver);
  49. }
  50. Index: linux-2.6.21.7/drivers/net/gumstix-smc91x.c
  51. ===================================================================
  52. --- /dev/null
  53. +++ linux-2.6.21.7/drivers/net/gumstix-smc91x.c
  54. @@ -0,0 +1,143 @@
  55. +/*
  56. + * Gumstix SMC91C111 chip intialization driver
  57. + *
  58. + * Author: Craig Hughes
  59. + * Created: December 9, 2004
  60. + * Copyright: (C) 2004 Craig Hughes
  61. + *
  62. + * This program is free software; you can redistribute it and/or modify
  63. + * it under the terms of the GNU General Public License as published by
  64. + * the Free Software Foundation; either version 2 of the License, or
  65. + * (at your option) any later version.
  66. + *
  67. + */
  68. +
  69. +#include <linux/module.h>
  70. +#include <linux/ioport.h>
  71. +#include <linux/device.h>
  72. +#include <linux/platform_device.h>
  73. +#include <linux/delay.h>
  74. +
  75. +#include <asm/hardware.h>
  76. +#include <asm/arch/pxa-regs.h>
  77. +#include <asm/delay.h>
  78. +
  79. +#include <asm/arch/gumstix.h>
  80. +
  81. +#define SMC_DEBUG 0
  82. +#include <asm/io.h>
  83. +#include "smc91x.h"
  84. +
  85. +static struct resource gumstix_smc91x0_resources[] = {
  86. + [0] = {
  87. + .name = "smc91x-regs",
  88. + .start = PXA_CS1_PHYS + 0x00000300,
  89. + .end = PXA_CS1_PHYS + 0x000fffff,
  90. + .flags = IORESOURCE_MEM,
  91. + },
  92. + [1] = {
  93. + .start = GUMSTIX_ETH0_IRQ,
  94. + .end = GUMSTIX_ETH0_IRQ,
  95. + .flags = IORESOURCE_IRQ,
  96. + },
  97. +};
  98. +
  99. +static struct resource gumstix_smc91x1_resources[] = {
  100. + [0] = {
  101. + .name = "smc91x-regs",
  102. + .start = PXA_CS2_PHYS + 0x00000300,
  103. + .end = PXA_CS2_PHYS + 0x000fffff,
  104. + .flags = IORESOURCE_MEM,
  105. + },
  106. + [1] = {
  107. + .start = GUMSTIX_ETH1_IRQ,
  108. + .end = GUMSTIX_ETH1_IRQ,
  109. + .flags = IORESOURCE_IRQ,
  110. + },
  111. +};
  112. +
  113. +static struct platform_device gumstix_smc91x0_device = {
  114. + .name = "smc91x",
  115. + .id = 0,
  116. + .num_resources = ARRAY_SIZE(gumstix_smc91x0_resources),
  117. + .resource = gumstix_smc91x0_resources,
  118. +};
  119. +
  120. +static struct platform_device gumstix_smc91x1_device = {
  121. + .name = "smc91x",
  122. + .id = 1,
  123. + .num_resources = ARRAY_SIZE(gumstix_smc91x1_resources),
  124. + .resource = gumstix_smc91x1_resources,
  125. +};
  126. +
  127. +static struct platform_device *smc91x_devices[] = {
  128. + &gumstix_smc91x0_device,
  129. + &gumstix_smc91x1_device,
  130. +};
  131. +
  132. +/* First we're going to test if there's a 2nd SMC91C111, and if not, then we'll free up those resources and the GPIO lines
  133. + * that it would otherwise use. We have no choice but to probe by doing:
  134. + * Set nCS2 to CS2 mode
  135. + * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset)
  136. + * Read from the memory space to check for the sentinel sequence identifying a likely SMC91C111 device
  137. + */
  138. +int __init gumstix_smc91x_init(void)
  139. +{
  140. + unsigned int val, num_devices=ARRAY_SIZE(smc91x_devices);
  141. + void *ioaddr;
  142. +
  143. + /* Set up nPWE */
  144. + pxa_gpio_mode(GPIO49_nPWE_MD);
  145. +
  146. + pxa_gpio_mode(GPIO78_nCS_2_MD);
  147. + // If either if statement fails, then we'll drop out and turn_off_eth1,
  148. + // if both succeed, then we'll skip that and just proceed with 2 cards
  149. + if(request_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT, "smc91x probe"))
  150. + {
  151. + ioaddr = ioremap(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT);
  152. + val = ioread16(ioaddr + BANK_SELECT);
  153. + iounmap(ioaddr);
  154. + release_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT);
  155. + if ((val & 0xFF00) == 0x3300) {
  156. + goto proceed;
  157. + }
  158. + }
  159. +
  160. +turn_off_eth1:
  161. + // This is apparently not an SMC91C111
  162. + // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode
  163. + num_devices--;
  164. + smc91x_devices[1] = NULL;
  165. + pxa_gpio_mode(78 | GPIO_IN);
  166. +
  167. +proceed:
  168. + pxa_gpio_mode(GPIO15_nCS_1_MD);
  169. +
  170. + if(smc91x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
  171. + pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
  172. + if(smc91x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
  173. + GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
  174. + udelay(1); // Hold RESET for at least 100ns
  175. + if(smc91x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
  176. + GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
  177. + msleep(50);
  178. +
  179. + return platform_add_devices(smc91x_devices, num_devices);
  180. +}
  181. +
  182. +void __exit gumstix_smc91x_exit(void)
  183. +{
  184. + if(smc91x_devices[1] != NULL) platform_device_unregister(&gumstix_smc91x1_device);
  185. + platform_device_unregister(&gumstix_smc91x0_device);
  186. +}
  187. +
  188. +void gumstix_smc91x_load(void) {}
  189. +EXPORT_SYMBOL(gumstix_smc91x_load);
  190. +
  191. +module_init(gumstix_smc91x_init);
  192. +module_exit(gumstix_smc91x_exit);
  193. +
  194. +MODULE_LICENSE("GPL");
  195. +MODULE_AUTHOR("Craig Hughes <[email protected]>");
  196. +MODULE_DESCRIPTION("Gumstix board SMC91C111 chip initialization driver");
  197. +MODULE_VERSION("1:0.1");