diff options
-rw-r--r-- | arch/arm/mach-at91rm9200/devices.c | 12 | ||||
-rw-r--r-- | drivers/pcmcia/at91_cf.c | 51 |
2 files changed, 42 insertions, 21 deletions
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index 1781b8f342c4..bfe47bd6e50c 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c | |||
@@ -194,13 +194,23 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} | |||
194 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) | 194 | #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) |
195 | static struct at91_cf_data cf_data; | 195 | static struct at91_cf_data cf_data; |
196 | 196 | ||
197 | static struct resource at91_cf_resources[] = { | ||
198 | [0] = { | ||
199 | .start = AT91_CF_BASE, | ||
200 | /* ties up CS4, CS5, and CS6 */ | ||
201 | .end = AT91_CF_BASE + (0x30000000 - 1), | ||
202 | .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, | ||
203 | }, | ||
204 | }; | ||
205 | |||
197 | static struct platform_device at91rm9200_cf_device = { | 206 | static struct platform_device at91rm9200_cf_device = { |
198 | .name = "at91_cf", | 207 | .name = "at91_cf", |
199 | .id = -1, | 208 | .id = -1, |
200 | .dev = { | 209 | .dev = { |
201 | .platform_data = &cf_data, | 210 | .platform_data = &cf_data, |
202 | }, | 211 | }, |
203 | .num_resources = 0, | 212 | .resource = at91_cf_resources, |
213 | .num_resources = ARRAY_SIZE(at91_cf_resources), | ||
204 | }; | 214 | }; |
205 | 215 | ||
206 | void __init at91_add_device_cf(struct at91_cf_data *data) | 216 | void __init at91_add_device_cf(struct at91_cf_data *data) |
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 67cc5f7d0c90..a4d50940ebeb 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -28,8 +28,6 @@ | |||
28 | #include <asm/arch/gpio.h> | 28 | #include <asm/arch/gpio.h> |
29 | 29 | ||
30 | 30 | ||
31 | #define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */ | ||
32 | |||
33 | /* | 31 | /* |
34 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; | 32 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; |
35 | * some other bit in {A24,A22..A11} is nREG to flag memory access | 33 | * some other bit in {A24,A22..A11} is nREG to flag memory access |
@@ -76,7 +74,8 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r) | |||
76 | /* kick pccard as needed */ | 74 | /* kick pccard as needed */ |
77 | if (present != cf->present) { | 75 | if (present != cf->present) { |
78 | cf->present = present; | 76 | cf->present = present; |
79 | pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone"); | 77 | pr_debug("%s: card %s\n", driver_name, |
78 | present ? "present" : "gone"); | ||
80 | pcmcia_parse_events(&cf->socket, SS_DETECT); | 79 | pcmcia_parse_events(&cf->socket, SS_DETECT); |
81 | } | 80 | } |
82 | } | 81 | } |
@@ -93,7 +92,7 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
93 | 92 | ||
94 | cf = container_of(s, struct at91_cf_socket, socket); | 93 | cf = container_of(s, struct at91_cf_socket, socket); |
95 | 94 | ||
96 | /* NOTE: we assume 3VCARD, not XVCARD... */ | 95 | /* NOTE: CF is always 3VCARD */ |
97 | if (at91_cf_present(cf)) { | 96 | if (at91_cf_present(cf)) { |
98 | int rdy = cf->board->irq_pin; /* RDY/nIRQ */ | 97 | int rdy = cf->board->irq_pin; /* RDY/nIRQ */ |
99 | int vcc = cf->board->vcc_pin; | 98 | int vcc = cf->board->vcc_pin; |
@@ -109,7 +108,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) | |||
109 | return 0; | 108 | return 0; |
110 | } | 109 | } |
111 | 110 | ||
112 | static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | 111 | static int |
112 | at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) | ||
113 | { | 113 | { |
114 | struct at91_cf_socket *cf; | 114 | struct at91_cf_socket *cf; |
115 | 115 | ||
@@ -184,7 +184,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | /* pcmcia layer maps/unmaps mem regions */ | 186 | /* pcmcia layer maps/unmaps mem regions */ |
187 | static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) | 187 | static int |
188 | at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) | ||
188 | { | 189 | { |
189 | struct at91_cf_socket *cf; | 190 | struct at91_cf_socket *cf; |
190 | 191 | ||
@@ -218,12 +219,17 @@ static int __init at91_cf_probe(struct device *dev) | |||
218 | struct at91_cf_socket *cf; | 219 | struct at91_cf_socket *cf; |
219 | struct at91_cf_data *board = dev->platform_data; | 220 | struct at91_cf_data *board = dev->platform_data; |
220 | struct platform_device *pdev = to_platform_device(dev); | 221 | struct platform_device *pdev = to_platform_device(dev); |
222 | struct resource *io; | ||
221 | unsigned int csa; | 223 | unsigned int csa; |
222 | int status; | 224 | int status; |
223 | 225 | ||
224 | if (!board || !board->det_pin || !board->rst_pin) | 226 | if (!board || !board->det_pin || !board->rst_pin) |
225 | return -ENODEV; | 227 | return -ENODEV; |
226 | 228 | ||
229 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
230 | if (!io) | ||
231 | return -ENODEV; | ||
232 | |||
227 | cf = kcalloc(1, sizeof *cf, GFP_KERNEL); | 233 | cf = kcalloc(1, sizeof *cf, GFP_KERNEL); |
228 | if (!cf) | 234 | if (!cf) |
229 | return -ENOMEM; | 235 | return -ENOMEM; |
@@ -250,10 +256,14 @@ static int __init at91_cf_probe(struct device *dev) | |||
250 | * REVISIT: these timings are in terms of MCK cycles, so | 256 | * REVISIT: these timings are in terms of MCK cycles, so |
251 | * when MCK changes (cpufreq etc) so must these values... | 257 | * when MCK changes (cpufreq etc) so must these values... |
252 | */ | 258 | */ |
253 | at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN | 259 | at91_sys_write(AT91_SMC_CSR(4), |
254 | | AT91_SMC_NWS_(32) /* wait states */ | 260 | AT91_SMC_ACSS_STD |
255 | | AT91_SMC_RWSETUP_(6) /* setup time */ | 261 | | AT91_SMC_DBW_16 |
256 | | AT91_SMC_RWHOLD_(4) /* hold time */ | 262 | | AT91_SMC_BAT |
263 | | AT91_SMC_WSEN | ||
264 | | AT91_SMC_NWS_(32) /* wait states */ | ||
265 | | AT91_SMC_RWSETUP_(6) /* setup time */ | ||
266 | | AT91_SMC_RWHOLD_(4) /* hold time */ | ||
257 | ); | 267 | ); |
258 | 268 | ||
259 | /* must be a GPIO; ergo must trigger on both edges */ | 269 | /* must be a GPIO; ergo must trigger on both edges */ |
@@ -274,8 +284,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
274 | if (status < 0) | 284 | if (status < 0) |
275 | goto fail0a; | 285 | goto fail0a; |
276 | cf->socket.pci_irq = board->irq_pin; | 286 | cf->socket.pci_irq = board->irq_pin; |
277 | } | 287 | } else |
278 | else | ||
279 | cf->socket.pci_irq = NR_IRQS + 1; | 288 | cf->socket.pci_irq = NR_IRQS + 1; |
280 | 289 | ||
281 | /* pcmcia layer only remaps "real" memory not iospace */ | 290 | /* pcmcia layer only remaps "real" memory not iospace */ |
@@ -284,7 +293,8 @@ static int __init at91_cf_probe(struct device *dev) | |||
284 | goto fail1; | 293 | goto fail1; |
285 | 294 | ||
286 | /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ | 295 | /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ |
287 | if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name)) | 296 | if (!request_mem_region(io->start, io->end + 1 - io->start, |
297 | driver_name)) | ||
288 | goto fail1; | 298 | goto fail1; |
289 | 299 | ||
290 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, | 300 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, |
@@ -297,7 +307,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
297 | cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | 307 | cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP |
298 | | SS_CAP_MEM_ALIGN; | 308 | | SS_CAP_MEM_ALIGN; |
299 | cf->socket.map_size = SZ_2K; | 309 | cf->socket.map_size = SZ_2K; |
300 | cf->socket.io[0].NumPorts = SZ_2K; | 310 | cf->socket.io[0].res = io; |
301 | 311 | ||
302 | status = pcmcia_register_socket(&cf->socket); | 312 | status = pcmcia_register_socket(&cf->socket); |
303 | if (status < 0) | 313 | if (status < 0) |
@@ -307,7 +317,7 @@ static int __init at91_cf_probe(struct device *dev) | |||
307 | 317 | ||
308 | fail2: | 318 | fail2: |
309 | iounmap((void __iomem *) cf->socket.io_offset); | 319 | iounmap((void __iomem *) cf->socket.io_offset); |
310 | release_mem_region(AT91_CF_BASE, CF_SIZE); | 320 | release_mem_region(io->start, io->end + 1 - io->start); |
311 | fail1: | 321 | fail1: |
312 | if (board->irq_pin) | 322 | if (board->irq_pin) |
313 | free_irq(board->irq_pin, cf); | 323 | free_irq(board->irq_pin, cf); |
@@ -321,14 +331,15 @@ fail0: | |||
321 | 331 | ||
322 | static int __exit at91_cf_remove(struct device *dev) | 332 | static int __exit at91_cf_remove(struct device *dev) |
323 | { | 333 | { |
324 | struct at91_cf_socket *cf = dev_get_drvdata(dev); | 334 | struct at91_cf_socket *cf = dev_get_drvdata(dev); |
325 | unsigned int csa; | 335 | struct resource *io = cf->socket.io[0].res; |
336 | unsigned int csa; | ||
326 | 337 | ||
327 | pcmcia_unregister_socket(&cf->socket); | 338 | pcmcia_unregister_socket(&cf->socket); |
328 | free_irq(cf->board->irq_pin, cf); | 339 | free_irq(cf->board->irq_pin, cf); |
329 | free_irq(cf->board->det_pin, cf); | 340 | free_irq(cf->board->det_pin, cf); |
330 | iounmap((void __iomem *) cf->socket.io_offset); | 341 | iounmap((void __iomem *) cf->socket.io_offset); |
331 | release_mem_region(AT91_CF_BASE, CF_SIZE); | 342 | release_mem_region(io->start, io->end + 1 - io->start); |
332 | 343 | ||
333 | csa = at91_sys_read(AT91_EBI_CSA); | 344 | csa = at91_sys_read(AT91_EBI_CSA); |
334 | at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); | 345 | at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); |
@@ -342,8 +353,8 @@ static struct device_driver at91_cf_driver = { | |||
342 | .bus = &platform_bus_type, | 353 | .bus = &platform_bus_type, |
343 | .probe = at91_cf_probe, | 354 | .probe = at91_cf_probe, |
344 | .remove = __exit_p(at91_cf_remove), | 355 | .remove = __exit_p(at91_cf_remove), |
345 | .suspend = pcmcia_socket_dev_suspend, | 356 | .suspend = pcmcia_socket_dev_suspend, |
346 | .resume = pcmcia_socket_dev_resume, | 357 | .resume = pcmcia_socket_dev_resume, |
347 | }; | 358 | }; |
348 | 359 | ||
349 | /*--------------------------------------------------------------------------*/ | 360 | /*--------------------------------------------------------------------------*/ |