diff options
Diffstat (limited to 'drivers/mtd/devices/mtd_dataflash.c')
| -rw-r--r-- | drivers/mtd/devices/mtd_dataflash.c | 91 |
1 files changed, 42 insertions, 49 deletions
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 13749d458a31..d75c7af18a63 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #include <linux/mutex.h> | 17 | #include <linux/mutex.h> |
| 18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
| 19 | #include <linux/math64.h> | 19 | #include <linux/math64.h> |
| 20 | #include <linux/of.h> | ||
| 21 | #include <linux/of_device.h> | ||
| 20 | 22 | ||
| 21 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 22 | #include <linux/spi/flash.h> | 24 | #include <linux/spi/flash.h> |
| @@ -24,7 +26,6 @@ | |||
| 24 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
| 25 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
| 26 | 28 | ||
| 27 | |||
| 28 | /* | 29 | /* |
| 29 | * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in | 30 | * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in |
| 30 | * each chip, which may be used for double buffered I/O; but this driver | 31 | * each chip, which may be used for double buffered I/O; but this driver |
| @@ -98,6 +99,16 @@ struct dataflash { | |||
| 98 | struct mtd_info mtd; | 99 | struct mtd_info mtd; |
| 99 | }; | 100 | }; |
| 100 | 101 | ||
| 102 | #ifdef CONFIG_OF | ||
| 103 | static const struct of_device_id dataflash_dt_ids[] = { | ||
| 104 | { .compatible = "atmel,at45", }, | ||
| 105 | { .compatible = "atmel,dataflash", }, | ||
| 106 | { /* sentinel */ } | ||
| 107 | }; | ||
| 108 | #else | ||
| 109 | #define dataflash_dt_ids NULL | ||
| 110 | #endif | ||
| 111 | |||
| 101 | /* ......................................................................... */ | 112 | /* ......................................................................... */ |
| 102 | 113 | ||
| 103 | /* | 114 | /* |
| @@ -122,7 +133,7 @@ static int dataflash_waitready(struct spi_device *spi) | |||
| 122 | for (;;) { | 133 | for (;;) { |
| 123 | status = dataflash_status(spi); | 134 | status = dataflash_status(spi); |
| 124 | if (status < 0) { | 135 | if (status < 0) { |
| 125 | DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n", | 136 | pr_debug("%s: status %d?\n", |
| 126 | dev_name(&spi->dev), status); | 137 | dev_name(&spi->dev), status); |
| 127 | status = 0; | 138 | status = 0; |
| 128 | } | 139 | } |
| @@ -149,7 +160,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 149 | uint8_t *command; | 160 | uint8_t *command; |
| 150 | uint32_t rem; | 161 | uint32_t rem; |
| 151 | 162 | ||
| 152 | DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%llx len 0x%llx\n", | 163 | pr_debug("%s: erase addr=0x%llx len 0x%llx\n", |
| 153 | dev_name(&spi->dev), (long long)instr->addr, | 164 | dev_name(&spi->dev), (long long)instr->addr, |
| 154 | (long long)instr->len); | 165 | (long long)instr->len); |
| 155 | 166 | ||
| @@ -187,7 +198,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 187 | command[2] = (uint8_t)(pageaddr >> 8); | 198 | command[2] = (uint8_t)(pageaddr >> 8); |
| 188 | command[3] = 0; | 199 | command[3] = 0; |
| 189 | 200 | ||
| 190 | DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n", | 201 | pr_debug("ERASE %s: (%x) %x %x %x [%i]\n", |
| 191 | do_block ? "block" : "page", | 202 | do_block ? "block" : "page", |
| 192 | command[0], command[1], command[2], command[3], | 203 | command[0], command[1], command[2], command[3], |
| 193 | pageaddr); | 204 | pageaddr); |
| @@ -238,8 +249,8 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 238 | uint8_t *command; | 249 | uint8_t *command; |
| 239 | int status; | 250 | int status; |
| 240 | 251 | ||
| 241 | DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n", | 252 | pr_debug("%s: read 0x%x..0x%x\n", dev_name(&priv->spi->dev), |
| 242 | dev_name(&priv->spi->dev), (unsigned)from, (unsigned)(from + len)); | 253 | (unsigned)from, (unsigned)(from + len)); |
| 243 | 254 | ||
| 244 | *retlen = 0; | 255 | *retlen = 0; |
| 245 | 256 | ||
| @@ -255,7 +266,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 255 | 266 | ||
| 256 | command = priv->command; | 267 | command = priv->command; |
| 257 | 268 | ||
| 258 | DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n", | 269 | pr_debug("READ: (%x) %x %x %x\n", |
| 259 | command[0], command[1], command[2], command[3]); | 270 | command[0], command[1], command[2], command[3]); |
| 260 | 271 | ||
| 261 | spi_message_init(&msg); | 272 | spi_message_init(&msg); |
| @@ -287,7 +298,7 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 287 | *retlen = msg.actual_length - 8; | 298 | *retlen = msg.actual_length - 8; |
| 288 | status = 0; | 299 | status = 0; |
| 289 | } else | 300 | } else |
| 290 | DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n", | 301 | pr_debug("%s: read %x..%x --> %d\n", |
| 291 | dev_name(&priv->spi->dev), | 302 | dev_name(&priv->spi->dev), |
| 292 | (unsigned)from, (unsigned)(from + len), | 303 | (unsigned)from, (unsigned)(from + len), |
| 293 | status); | 304 | status); |
| @@ -314,7 +325,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 314 | int status = -EINVAL; | 325 | int status = -EINVAL; |
| 315 | uint8_t *command; | 326 | uint8_t *command; |
| 316 | 327 | ||
| 317 | DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n", | 328 | pr_debug("%s: write 0x%x..0x%x\n", |
| 318 | dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); | 329 | dev_name(&spi->dev), (unsigned)to, (unsigned)(to + len)); |
| 319 | 330 | ||
| 320 | *retlen = 0; | 331 | *retlen = 0; |
| @@ -340,7 +351,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 340 | 351 | ||
| 341 | mutex_lock(&priv->lock); | 352 | mutex_lock(&priv->lock); |
| 342 | while (remaining > 0) { | 353 | while (remaining > 0) { |
| 343 | DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n", | 354 | pr_debug("write @ %i:%i len=%i\n", |
| 344 | pageaddr, offset, writelen); | 355 | pageaddr, offset, writelen); |
| 345 | 356 | ||
| 346 | /* REVISIT: | 357 | /* REVISIT: |
| @@ -368,12 +379,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 368 | command[2] = (addr & 0x0000FF00) >> 8; | 379 | command[2] = (addr & 0x0000FF00) >> 8; |
| 369 | command[3] = 0; | 380 | command[3] = 0; |
| 370 | 381 | ||
| 371 | DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n", | 382 | pr_debug("TRANSFER: (%x) %x %x %x\n", |
| 372 | command[0], command[1], command[2], command[3]); | 383 | command[0], command[1], command[2], command[3]); |
| 373 | 384 | ||
| 374 | status = spi_sync(spi, &msg); | 385 | status = spi_sync(spi, &msg); |
| 375 | if (status < 0) | 386 | if (status < 0) |
| 376 | DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n", | 387 | pr_debug("%s: xfer %u -> %d\n", |
| 377 | dev_name(&spi->dev), addr, status); | 388 | dev_name(&spi->dev), addr, status); |
| 378 | 389 | ||
| 379 | (void) dataflash_waitready(priv->spi); | 390 | (void) dataflash_waitready(priv->spi); |
| @@ -386,7 +397,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 386 | command[2] = (addr & 0x0000FF00) >> 8; | 397 | command[2] = (addr & 0x0000FF00) >> 8; |
| 387 | command[3] = (addr & 0x000000FF); | 398 | command[3] = (addr & 0x000000FF); |
| 388 | 399 | ||
| 389 | DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n", | 400 | pr_debug("PROGRAM: (%x) %x %x %x\n", |
| 390 | command[0], command[1], command[2], command[3]); | 401 | command[0], command[1], command[2], command[3]); |
| 391 | 402 | ||
| 392 | x[1].tx_buf = writebuf; | 403 | x[1].tx_buf = writebuf; |
| @@ -395,7 +406,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 395 | status = spi_sync(spi, &msg); | 406 | status = spi_sync(spi, &msg); |
| 396 | spi_transfer_del(x + 1); | 407 | spi_transfer_del(x + 1); |
| 397 | if (status < 0) | 408 | if (status < 0) |
| 398 | DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n", | 409 | pr_debug("%s: pgm %u/%u -> %d\n", |
| 399 | dev_name(&spi->dev), addr, writelen, status); | 410 | dev_name(&spi->dev), addr, writelen, status); |
| 400 | 411 | ||
| 401 | (void) dataflash_waitready(priv->spi); | 412 | (void) dataflash_waitready(priv->spi); |
| @@ -410,12 +421,12 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 410 | command[2] = (addr & 0x0000FF00) >> 8; | 421 | command[2] = (addr & 0x0000FF00) >> 8; |
| 411 | command[3] = 0; | 422 | command[3] = 0; |
| 412 | 423 | ||
| 413 | DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n", | 424 | pr_debug("COMPARE: (%x) %x %x %x\n", |
| 414 | command[0], command[1], command[2], command[3]); | 425 | command[0], command[1], command[2], command[3]); |
| 415 | 426 | ||
| 416 | status = spi_sync(spi, &msg); | 427 | status = spi_sync(spi, &msg); |
| 417 | if (status < 0) | 428 | if (status < 0) |
| 418 | DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n", | 429 | pr_debug("%s: compare %u -> %d\n", |
| 419 | dev_name(&spi->dev), addr, status); | 430 | dev_name(&spi->dev), addr, status); |
| 420 | 431 | ||
| 421 | status = dataflash_waitready(priv->spi); | 432 | status = dataflash_waitready(priv->spi); |
| @@ -634,11 +645,10 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
| 634 | { | 645 | { |
| 635 | struct dataflash *priv; | 646 | struct dataflash *priv; |
| 636 | struct mtd_info *device; | 647 | struct mtd_info *device; |
| 648 | struct mtd_part_parser_data ppdata; | ||
| 637 | struct flash_platform_data *pdata = spi->dev.platform_data; | 649 | struct flash_platform_data *pdata = spi->dev.platform_data; |
| 638 | char *otp_tag = ""; | 650 | char *otp_tag = ""; |
| 639 | int err = 0; | 651 | int err = 0; |
| 640 | struct mtd_partition *parts; | ||
| 641 | int nr_parts = 0; | ||
| 642 | 652 | ||
| 643 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | 653 | priv = kzalloc(sizeof *priv, GFP_KERNEL); |
| 644 | if (!priv) | 654 | if (!priv) |
| @@ -677,28 +687,11 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
| 677 | pagesize, otp_tag); | 687 | pagesize, otp_tag); |
| 678 | dev_set_drvdata(&spi->dev, priv); | 688 | dev_set_drvdata(&spi->dev, priv); |
| 679 | 689 | ||
| 680 | if (mtd_has_cmdlinepart()) { | 690 | ppdata.of_node = spi->dev.of_node; |
| 681 | static const char *part_probes[] = { "cmdlinepart", NULL, }; | 691 | err = mtd_device_parse_register(device, NULL, &ppdata, |
| 682 | 692 | pdata ? pdata->parts : NULL, | |
| 683 | nr_parts = parse_mtd_partitions(device, part_probes, &parts, | 693 | pdata ? pdata->nr_parts : 0); |
| 684 | 0); | ||
| 685 | } | ||
| 686 | 694 | ||
| 687 | if (nr_parts <= 0 && pdata && pdata->parts) { | ||
| 688 | parts = pdata->parts; | ||
| 689 | nr_parts = pdata->nr_parts; | ||
| 690 | } | ||
| 691 | |||
| 692 | if (nr_parts > 0) { | ||
| 693 | priv->partitioned = 1; | ||
| 694 | err = mtd_device_register(device, parts, nr_parts); | ||
| 695 | goto out; | ||
| 696 | } | ||
| 697 | |||
| 698 | if (mtd_device_register(device, NULL, 0) == 1) | ||
| 699 | err = -ENODEV; | ||
| 700 | |||
| 701 | out: | ||
| 702 | if (!err) | 695 | if (!err) |
| 703 | return 0; | 696 | return 0; |
| 704 | 697 | ||
| @@ -787,7 +780,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
| 787 | */ | 780 | */ |
| 788 | tmp = spi_write_then_read(spi, &code, 1, id, 3); | 781 | tmp = spi_write_then_read(spi, &code, 1, id, 3); |
| 789 | if (tmp < 0) { | 782 | if (tmp < 0) { |
| 790 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", | 783 | pr_debug("%s: error %d reading JEDEC ID\n", |
| 791 | dev_name(&spi->dev), tmp); | 784 | dev_name(&spi->dev), tmp); |
| 792 | return ERR_PTR(tmp); | 785 | return ERR_PTR(tmp); |
| 793 | } | 786 | } |
| @@ -804,7 +797,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
| 804 | tmp < ARRAY_SIZE(dataflash_data); | 797 | tmp < ARRAY_SIZE(dataflash_data); |
| 805 | tmp++, info++) { | 798 | tmp++, info++) { |
| 806 | if (info->jedec_id == jedec) { | 799 | if (info->jedec_id == jedec) { |
| 807 | DEBUG(MTD_DEBUG_LEVEL1, "%s: OTP, sector protect%s\n", | 800 | pr_debug("%s: OTP, sector protect%s\n", |
| 808 | dev_name(&spi->dev), | 801 | dev_name(&spi->dev), |
| 809 | (info->flags & SUP_POW2PS) | 802 | (info->flags & SUP_POW2PS) |
| 810 | ? ", binary pagesize" : "" | 803 | ? ", binary pagesize" : "" |
| @@ -812,8 +805,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
| 812 | if (info->flags & SUP_POW2PS) { | 805 | if (info->flags & SUP_POW2PS) { |
| 813 | status = dataflash_status(spi); | 806 | status = dataflash_status(spi); |
| 814 | if (status < 0) { | 807 | if (status < 0) { |
| 815 | DEBUG(MTD_DEBUG_LEVEL1, | 808 | pr_debug("%s: status error %d\n", |
| 816 | "%s: status error %d\n", | ||
| 817 | dev_name(&spi->dev), status); | 809 | dev_name(&spi->dev), status); |
| 818 | return ERR_PTR(status); | 810 | return ERR_PTR(status); |
| 819 | } | 811 | } |
| @@ -878,7 +870,7 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
| 878 | */ | 870 | */ |
| 879 | status = dataflash_status(spi); | 871 | status = dataflash_status(spi); |
| 880 | if (status <= 0 || status == 0xff) { | 872 | if (status <= 0 || status == 0xff) { |
| 881 | DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n", | 873 | pr_debug("%s: status error %d\n", |
| 882 | dev_name(&spi->dev), status); | 874 | dev_name(&spi->dev), status); |
| 883 | if (status == 0 || status == 0xff) | 875 | if (status == 0 || status == 0xff) |
| 884 | status = -ENODEV; | 876 | status = -ENODEV; |
| @@ -914,14 +906,14 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
| 914 | break; | 906 | break; |
| 915 | /* obsolete AT45DB1282 not (yet?) supported */ | 907 | /* obsolete AT45DB1282 not (yet?) supported */ |
| 916 | default: | 908 | default: |
| 917 | DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n", | 909 | pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev), |
| 918 | dev_name(&spi->dev), status & 0x3c); | 910 | status & 0x3c); |
| 919 | status = -ENODEV; | 911 | status = -ENODEV; |
| 920 | } | 912 | } |
| 921 | 913 | ||
| 922 | if (status < 0) | 914 | if (status < 0) |
| 923 | DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n", | 915 | pr_debug("%s: add_dataflash --> %d\n", dev_name(&spi->dev), |
| 924 | dev_name(&spi->dev), status); | 916 | status); |
| 925 | 917 | ||
| 926 | return status; | 918 | return status; |
| 927 | } | 919 | } |
| @@ -931,7 +923,7 @@ static int __devexit dataflash_remove(struct spi_device *spi) | |||
| 931 | struct dataflash *flash = dev_get_drvdata(&spi->dev); | 923 | struct dataflash *flash = dev_get_drvdata(&spi->dev); |
| 932 | int status; | 924 | int status; |
| 933 | 925 | ||
| 934 | DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev)); | 926 | pr_debug("%s: remove\n", dev_name(&spi->dev)); |
| 935 | 927 | ||
| 936 | status = mtd_device_unregister(&flash->mtd); | 928 | status = mtd_device_unregister(&flash->mtd); |
| 937 | if (status == 0) { | 929 | if (status == 0) { |
| @@ -946,6 +938,7 @@ static struct spi_driver dataflash_driver = { | |||
| 946 | .name = "mtd_dataflash", | 938 | .name = "mtd_dataflash", |
| 947 | .bus = &spi_bus_type, | 939 | .bus = &spi_bus_type, |
| 948 | .owner = THIS_MODULE, | 940 | .owner = THIS_MODULE, |
| 941 | .of_match_table = dataflash_dt_ids, | ||
| 949 | }, | 942 | }, |
| 950 | 943 | ||
| 951 | .probe = dataflash_probe, | 944 | .probe = dataflash_probe, |
