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 | /*--------------------------------------------------------------------------*/ |
