diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 12:42:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-05 12:42:59 -0500 |
commit | d9b2c4d0b03c721808c0d259e43a27f1e80205bc (patch) | |
tree | f17a4166f62ee14faa1401a6cbd353a4ab8c77cb /drivers/mtd | |
parent | 27d16d08717faeaa8afd1b736a096dbaab90f08e (diff) | |
parent | 5fa9167a1bf5f5a4b7282f5e7ac56a4a5a1fa044 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (50 commits)
pcmcia: rework the irq_req_t typedef
pcmcia: remove deprecated handle_to_dev() macro
pcmcia: pcmcia_request_window() doesn't need a pointer to a pointer
pcmcia: remove unused "window_t" typedef
pcmcia: move some window-related code to pcmcia_ioctl.c
pcmcia: Change window_handle_t logic to unsigned long
pcmcia: Pass struct pcmcia_socket to pcmcia_get_mem_page()
pcmcia: Pass struct pcmcia_device to pcmcia_map_mem_page()
pcmcia: Pass struct pcmcia_device to pcmcia_release_window()
drivers/pcmcia: remove unnecessary kzalloc
pcmcia: correct handling for Zoomed Video registers in topic.h
pcmcia: fix printk formats
pcmcia: autoload module pcmcia
pcmcia/staging: update comedi drivers
PCMCIA: stop duplicating pci_irq in soc_pcmcia_socket
PCMCIA: ss: allow PCI IRQs > 255
PCMCIA: soc_common: remove 'dev' member from soc_pcmcia_socket
PCMCIA: soc_common: constify soc_pcmcia_socket ops member
PCMCIA: sa1111: remove duplicated initializers
PCMCIA: sa1111: wrap soc_pcmcia_socket to contain sa1111 specific data
...
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/maps/pcmciamtd.c | 197 |
1 files changed, 98 insertions, 99 deletions
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index d600c2deff73..689d6a79ffc0 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) | |||
118 | DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", | 118 | DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x", |
119 | dev->offset, mrq.CardOffset); | 119 | dev->offset, mrq.CardOffset); |
120 | mrq.Page = 0; | 120 | mrq.Page = 0; |
121 | ret = pcmcia_map_mem_page(win, &mrq); | 121 | ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq); |
122 | if (ret != 0) { | 122 | if (ret != 0) |
123 | cs_error(dev->p_dev, MapMemPage, ret); | ||
124 | return NULL; | 123 | return NULL; |
125 | } | ||
126 | dev->offset = mrq.CardOffset; | 124 | dev->offset = mrq.CardOffset; |
127 | } | 125 | } |
128 | return dev->win_base + (to & (dev->win_size-1)); | 126 | return dev->win_base + (to & (dev->win_size-1)); |
@@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on) | |||
327 | 325 | ||
328 | DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); | 326 | DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); |
329 | ret = pcmcia_modify_configuration(link, &mod); | 327 | ret = pcmcia_modify_configuration(link, &mod); |
330 | if (ret != 0) | ||
331 | cs_error(link, ModifyConfiguration, ret); | ||
332 | } | 328 | } |
333 | 329 | ||
334 | 330 | ||
@@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcmcia_device *link) | |||
348 | iounmap(dev->win_base); | 344 | iounmap(dev->win_base); |
349 | dev->win_base = NULL; | 345 | dev->win_base = NULL; |
350 | } | 346 | } |
351 | pcmcia_release_window(link->win); | 347 | pcmcia_release_window(link, link->win); |
352 | } | 348 | } |
353 | pcmcia_disable_device(link); | 349 | pcmcia_disable_device(link); |
354 | } | 350 | } |
355 | 351 | ||
356 | 352 | ||
357 | static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) | 353 | #ifdef CONFIG_MTD_DEBUG |
354 | static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev, | ||
355 | tuple_t *tuple, | ||
356 | void *priv_data) | ||
358 | { | 357 | { |
359 | int rc; | ||
360 | tuple_t tuple; | ||
361 | cisparse_t parse; | 358 | cisparse_t parse; |
362 | u_char buf[64]; | ||
363 | |||
364 | tuple.Attributes = 0; | ||
365 | tuple.TupleData = (cisdata_t *)buf; | ||
366 | tuple.TupleDataMax = sizeof(buf); | ||
367 | tuple.TupleOffset = 0; | ||
368 | tuple.DesiredTuple = RETURN_FIRST_TUPLE; | ||
369 | |||
370 | rc = pcmcia_get_first_tuple(link, &tuple); | ||
371 | while (rc == 0) { | ||
372 | rc = pcmcia_get_tuple_data(link, &tuple); | ||
373 | if (rc != 0) { | ||
374 | cs_error(link, GetTupleData, rc); | ||
375 | break; | ||
376 | } | ||
377 | rc = pcmcia_parse_tuple(&tuple, &parse); | ||
378 | if (rc != 0) { | ||
379 | cs_error(link, ParseTuple, rc); | ||
380 | break; | ||
381 | } | ||
382 | 359 | ||
383 | switch(tuple.TupleCode) { | 360 | if (!pcmcia_parse_tuple(tuple, &parse)) { |
384 | case CISTPL_FORMAT: { | 361 | cistpl_format_t *t = &parse.format; |
385 | cistpl_format_t *t = &parse.format; | 362 | (void)t; /* Shut up, gcc */ |
386 | (void)t; /* Shut up, gcc */ | 363 | DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", |
387 | DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", | 364 | t->type, t->edc, t->offset, t->length); |
388 | t->type, t->edc, t->offset, t->length); | 365 | } |
389 | break; | 366 | return -ENOSPC; |
367 | } | ||
390 | 368 | ||
391 | } | 369 | static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev, |
370 | tuple_t *tuple, | ||
371 | void *priv_data) | ||
372 | { | ||
373 | cisparse_t parse; | ||
374 | int i; | ||
392 | 375 | ||
393 | case CISTPL_DEVICE: { | 376 | if (!pcmcia_parse_tuple(tuple, &parse)) { |
394 | cistpl_device_t *t = &parse.device; | 377 | cistpl_jedec_t *t = &parse.jedec; |
395 | int i; | 378 | for (i = 0; i < t->nid; i++) |
396 | DEBUG(2, "Common memory:"); | 379 | DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info); |
397 | dev->pcmcia_map.size = t->dev[0].size; | 380 | } |
398 | for(i = 0; i < t->ndev; i++) { | 381 | return -ENOSPC; |
399 | DEBUG(2, "Region %d, type = %u", i, t->dev[i].type); | 382 | } |
400 | DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp); | 383 | #endif |
401 | DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed); | ||
402 | DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size); | ||
403 | } | ||
404 | break; | ||
405 | } | ||
406 | 384 | ||
407 | case CISTPL_VERS_1: { | 385 | static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev, |
408 | cistpl_vers_1_t *t = &parse.version_1; | 386 | tuple_t *tuple, |
409 | int i; | 387 | void *priv_data) |
410 | if(t->ns) { | 388 | { |
411 | dev->mtd_name[0] = '\0'; | 389 | struct pcmciamtd_dev *dev = priv_data; |
412 | for(i = 0; i < t->ns; i++) { | 390 | cisparse_t parse; |
413 | if(i) | 391 | cistpl_device_t *t = &parse.device; |
414 | strcat(dev->mtd_name, " "); | 392 | int i; |
415 | strcat(dev->mtd_name, t->str+t->ofs[i]); | ||
416 | } | ||
417 | } | ||
418 | DEBUG(2, "Found name: %s", dev->mtd_name); | ||
419 | break; | ||
420 | } | ||
421 | 393 | ||
422 | case CISTPL_JEDEC_C: { | 394 | if (pcmcia_parse_tuple(tuple, &parse)) |
423 | cistpl_jedec_t *t = &parse.jedec; | 395 | return -EINVAL; |
424 | int i; | 396 | |
425 | for(i = 0; i < t->nid; i++) { | 397 | DEBUG(2, "Common memory:"); |
426 | DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info); | 398 | dev->pcmcia_map.size = t->dev[0].size; |
427 | } | 399 | /* from here on: DEBUG only */ |
428 | break; | 400 | for (i = 0; i < t->ndev; i++) { |
429 | } | 401 | DEBUG(2, "Region %d, type = %u", i, t->dev[i].type); |
402 | DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp); | ||
403 | DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed); | ||
404 | DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size); | ||
405 | } | ||
406 | return 0; | ||
407 | } | ||
430 | 408 | ||
431 | case CISTPL_DEVICE_GEO: { | 409 | static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev, |
432 | cistpl_device_geo_t *t = &parse.device_geo; | 410 | tuple_t *tuple, |
433 | int i; | 411 | void *priv_data) |
434 | dev->pcmcia_map.bankwidth = t->geo[0].buswidth; | 412 | { |
435 | for(i = 0; i < t->ngeo; i++) { | 413 | struct pcmciamtd_dev *dev = priv_data; |
436 | DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth); | 414 | cisparse_t parse; |
437 | DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block); | 415 | cistpl_device_geo_t *t = &parse.device_geo; |
438 | DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block); | 416 | int i; |
439 | DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block); | ||
440 | DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition); | ||
441 | DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave); | ||
442 | } | ||
443 | break; | ||
444 | } | ||
445 | 417 | ||
446 | default: | 418 | if (pcmcia_parse_tuple(tuple, &parse)) |
447 | DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); | 419 | return -EINVAL; |
448 | } | 420 | |
421 | dev->pcmcia_map.bankwidth = t->geo[0].buswidth; | ||
422 | /* from here on: DEBUG only */ | ||
423 | for (i = 0; i < t->ngeo; i++) { | ||
424 | DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth); | ||
425 | DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block); | ||
426 | DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block); | ||
427 | DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block); | ||
428 | DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition); | ||
429 | DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave); | ||
430 | } | ||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | |||
435 | static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name) | ||
436 | { | ||
437 | int i; | ||
449 | 438 | ||
450 | rc = pcmcia_get_next_tuple(link, &tuple); | 439 | if (p_dev->prod_id[0]) { |
440 | dev->mtd_name[0] = '\0'; | ||
441 | for (i = 0; i < 4; i++) { | ||
442 | if (i) | ||
443 | strcat(dev->mtd_name, " "); | ||
444 | if (p_dev->prod_id[i]) | ||
445 | strcat(dev->mtd_name, p_dev->prod_id[i]); | ||
446 | } | ||
447 | DEBUG(2, "Found name: %s", dev->mtd_name); | ||
451 | } | 448 | } |
449 | |||
450 | #ifdef CONFIG_MTD_DEBUG | ||
451 | pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL); | ||
452 | pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL); | ||
453 | #endif | ||
454 | pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev); | ||
455 | pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev); | ||
456 | |||
452 | if(!dev->pcmcia_map.size) | 457 | if(!dev->pcmcia_map.size) |
453 | dev->pcmcia_map.size = MAX_PCMCIA_ADDR; | 458 | dev->pcmcia_map.size = MAX_PCMCIA_ADDR; |
454 | 459 | ||
@@ -481,16 +486,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, | |||
481 | * MTD device available to the system. | 486 | * MTD device available to the system. |
482 | */ | 487 | */ |
483 | 488 | ||
484 | #define CS_CHECK(fn, ret) \ | ||
485 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | ||
486 | |||
487 | static int pcmciamtd_config(struct pcmcia_device *link) | 489 | static int pcmciamtd_config(struct pcmcia_device *link) |
488 | { | 490 | { |
489 | struct pcmciamtd_dev *dev = link->priv; | 491 | struct pcmciamtd_dev *dev = link->priv; |
490 | struct mtd_info *mtd = NULL; | 492 | struct mtd_info *mtd = NULL; |
491 | cs_status_t status; | 493 | cs_status_t status; |
492 | win_req_t req; | 494 | win_req_t req; |
493 | int last_ret = 0, last_fn = 0; | ||
494 | int ret; | 495 | int ret; |
495 | int i; | 496 | int i; |
496 | static char *probes[] = { "jedec_probe", "cfi_probe" }; | 497 | static char *probes[] = { "jedec_probe", "cfi_probe" }; |
@@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) | |||
529 | int ret; | 530 | int ret; |
530 | DEBUG(2, "requesting window with size = %dKiB memspeed = %d", | 531 | DEBUG(2, "requesting window with size = %dKiB memspeed = %d", |
531 | req.Size >> 10, req.AccessSpeed); | 532 | req.Size >> 10, req.AccessSpeed); |
532 | ret = pcmcia_request_window(&link, &req, &link->win); | 533 | ret = pcmcia_request_window(link, &req, &link->win); |
533 | DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); | 534 | DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); |
534 | if(ret) { | 535 | if(ret) { |
535 | req.Size >>= 1; | 536 | req.Size >>= 1; |
@@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmcia_device *link) | |||
577 | DEBUG(2, "Setting Configuration"); | 578 | DEBUG(2, "Setting Configuration"); |
578 | ret = pcmcia_request_configuration(link, &link->conf); | 579 | ret = pcmcia_request_configuration(link, &link->conf); |
579 | if (ret != 0) { | 580 | if (ret != 0) { |
580 | cs_error(link, RequestConfiguration, ret); | ||
581 | if (dev->win_base) { | 581 | if (dev->win_base) { |
582 | iounmap(dev->win_base); | 582 | iounmap(dev->win_base); |
583 | dev->win_base = NULL; | 583 | dev->win_base = NULL; |
@@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmcia_device *link) | |||
652 | link->dev_node = &dev->node; | 652 | link->dev_node = &dev->node; |
653 | return 0; | 653 | return 0; |
654 | 654 | ||
655 | cs_failed: | 655 | failed: |
656 | cs_error(link, last_fn, last_ret); | ||
657 | err("CS Error, exiting"); | 656 | err("CS Error, exiting"); |
658 | pcmciamtd_release(link); | 657 | pcmciamtd_release(link); |
659 | return -ENODEV; | 658 | return -ENODEV; |