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