aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2008-07-30 15:35:05 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-08-01 16:47:47 -0400
commit34a82443b79dcda4304b229d555586296da40c16 (patch)
treee375cf274b6c2eb1f41c81db3a864facfb7cce46 /drivers
parent623fa579e61f250c1913c70257ef3a753820bb68 (diff)
[MTD] dataflash OTP support
Now that we can tell when we have one of the newer DataFlash chips, optionally expose the 128 bytes of OTP memory they provide. Tested on at45db642 revision B and D chips. Switch mtdchar over to a generic HAVE_MTD_OTP flag instead of adding another #ifdef for each type of chip whose driver has OTP support. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Bryan Wu <cooloney@kernel.org> Cc: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/Kconfig5
-rw-r--r--drivers/mtd/chips/Kconfig1
-rw-r--r--drivers/mtd/devices/Kconfig11
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c206
-rw-r--r--drivers/mtd/mtdchar.c4
-rw-r--r--drivers/mtd/onenand/Kconfig1
6 files changed, 219 insertions, 9 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 14f11f8b9e5f..a90d50c2c3e5 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -172,6 +172,11 @@ config MTD_CHAR
172 memory chips, and also use ioctl() to obtain information about 172 memory chips, and also use ioctl() to obtain information about
173 the device, or to erase parts of it. 173 the device, or to erase parts of it.
174 174
175config HAVE_MTD_OTP
176 bool
177 help
178 Enable access to OTP regions using MTD_CHAR.
179
175config MTD_BLKDEVS 180config MTD_BLKDEVS
176 tristate "Common interface to block layer for MTD 'translation layers'" 181 tristate "Common interface to block layer for MTD 'translation layers'"
177 depends on BLOCK 182 depends on BLOCK
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 479d32b57a1e..4c35e5d77f95 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -154,6 +154,7 @@ config MTD_CFI_I8
154config MTD_OTP 154config MTD_OTP
155 bool "Protection Registers aka one-time programmable (OTP) bits" 155 bool "Protection Registers aka one-time programmable (OTP) bits"
156 depends on MTD_CFI_ADV_OPTIONS 156 depends on MTD_CFI_ADV_OPTIONS
157 select HAVE_MTD_OTP
157 default n 158 default n
158 help 159 help
159 This enables support for reading, writing and locking so called 160 This enables support for reading, writing and locking so called
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 9c613f06623c..88f4df047464 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -59,6 +59,17 @@ config MTD_DATAFLASH
59 Sometimes DataFlash chips are packaged inside MMC-format 59 Sometimes DataFlash chips are packaged inside MMC-format
60 cards; at this writing, the MMC stack won't handle those. 60 cards; at this writing, the MMC stack won't handle those.
61 61
62config MTD_DATAFLASH_OTP
63 bool "DataFlash OTP support (Security Register)"
64 depends on MTD_DATAFLASH
65 select HAVE_MTD_OTP
66 help
67 Newer DataFlash chips (revisions C and D) support 128 bytes of
68 one-time-programmable (OTP) data. The first half may be written
69 (once) with up to 64 bytes of data, such as a serial number or
70 other key product data. The second half is programmed with a
71 unique-to-each-chip bit pattern at the factory.
72
62config MTD_M25P80 73config MTD_M25P80
63 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" 74 tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
64 depends on SPI_MASTER && EXPERIMENTAL 75 depends on SPI_MASTER && EXPERIMENTAL
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 8bd0dea6885f..17c9b20dca87 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -80,7 +80,8 @@
80 */ 80 */
81#define OP_READ_ID 0x9F 81#define OP_READ_ID 0x9F
82#define OP_READ_SECURITY 0x77 82#define OP_READ_SECURITY 0x77
83#define OP_WRITE_SECURITY 0x9A /* OTP bits */ 83#define OP_WRITE_SECURITY_REVC 0x9A
84#define OP_WRITE_SECURITY 0x9B /* revision D */
84 85
85 86
86struct dataflash { 87struct dataflash {
@@ -451,16 +452,192 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
451 452
452/* ......................................................................... */ 453/* ......................................................................... */
453 454
455#ifdef CONFIG_MTD_DATAFLASH_OTP
456
457static int dataflash_get_otp_info(struct mtd_info *mtd,
458 struct otp_info *info, size_t len)
459{
460 /* Report both blocks as identical: bytes 0..64, locked.
461 * Unless the user block changed from all-ones, we can't
462 * tell whether it's still writable; so we assume it isn't.
463 */
464 info->start = 0;
465 info->length = 64;
466 info->locked = 1;
467 return sizeof(*info);
468}
469
470static ssize_t otp_read(struct spi_device *spi, unsigned base,
471 uint8_t *buf, loff_t off, size_t len)
472{
473 struct spi_message m;
474 size_t l;
475 uint8_t *scratch;
476 struct spi_transfer t;
477 int status;
478
479 if (off > 64)
480 return -EINVAL;
481
482 if ((off + len) > 64)
483 len = 64 - off;
484 if (len == 0)
485 return len;
486
487 spi_message_init(&m);
488
489 l = 4 + base + off + len;
490 scratch = kzalloc(l, GFP_KERNEL);
491 if (!scratch)
492 return -ENOMEM;
493
494 /* OUT: OP_READ_SECURITY, 3 don't-care bytes, zeroes
495 * IN: ignore 4 bytes, data bytes 0..N (max 127)
496 */
497 scratch[0] = OP_READ_SECURITY;
498
499 memset(&t, 0, sizeof t);
500 t.tx_buf = scratch;
501 t.rx_buf = scratch;
502 t.len = l;
503 spi_message_add_tail(&t, &m);
504
505 dataflash_waitready(spi);
506
507 status = spi_sync(spi, &m);
508 if (status >= 0) {
509 memcpy(buf, scratch + 4 + base + off, len);
510 status = len;
511 }
512
513 kfree(scratch);
514 return status;
515}
516
517static int dataflash_read_fact_otp(struct mtd_info *mtd,
518 loff_t from, size_t len, size_t *retlen, u_char *buf)
519{
520 struct dataflash *priv = (struct dataflash *)mtd->priv;
521 int status;
522
523 /* 64 bytes, from 0..63 ... start at 64 on-chip */
524 mutex_lock(&priv->lock);
525 status = otp_read(priv->spi, 64, buf, from, len);
526 mutex_unlock(&priv->lock);
527
528 if (status < 0)
529 return status;
530 *retlen = status;
531 return 0;
532}
533
534static int dataflash_read_user_otp(struct mtd_info *mtd,
535 loff_t from, size_t len, size_t *retlen, u_char *buf)
536{
537 struct dataflash *priv = (struct dataflash *)mtd->priv;
538 int status;
539
540 /* 64 bytes, from 0..63 ... start at 0 on-chip */
541 mutex_lock(&priv->lock);
542 status = otp_read(priv->spi, 0, buf, from, len);
543 mutex_unlock(&priv->lock);
544
545 if (status < 0)
546 return status;
547 *retlen = status;
548 return 0;
549}
550
551static int dataflash_write_user_otp(struct mtd_info *mtd,
552 loff_t from, size_t len, size_t *retlen, u_char *buf)
553{
554 struct spi_message m;
555 const size_t l = 4 + 64;
556 uint8_t *scratch;
557 struct spi_transfer t;
558 struct dataflash *priv = (struct dataflash *)mtd->priv;
559 int status;
560
561 if (len > 64)
562 return -EINVAL;
563
564 /* Strictly speaking, we *could* truncate the write ... but
565 * let's not do that for the only write that's ever possible.
566 */
567 if ((from + len) > 64)
568 return -EINVAL;
569
570 /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
571 * IN: ignore all
572 */
573 scratch = kzalloc(l, GFP_KERNEL);
574 if (!scratch)
575 return -ENOMEM;
576 scratch[0] = OP_WRITE_SECURITY;
577 memcpy(scratch + 4 + from, buf, len);
578
579 spi_message_init(&m);
580
581 memset(&t, 0, sizeof t);
582 t.tx_buf = scratch;
583 t.len = l;
584 spi_message_add_tail(&t, &m);
585
586 /* Write the OTP bits, if they've not yet been written.
587 * This modifies SRAM buffer1.
588 */
589 mutex_lock(&priv->lock);
590 dataflash_waitready(priv->spi);
591 status = spi_sync(priv->spi, &m);
592 mutex_unlock(&priv->lock);
593
594 kfree(scratch);
595
596 if (status >= 0) {
597 status = 0;
598 *retlen = len;
599 }
600 return status;
601}
602
603static char *otp_setup(struct mtd_info *device, char revision)
604{
605 device->get_fact_prot_info = dataflash_get_otp_info;
606 device->read_fact_prot_reg = dataflash_read_fact_otp;
607 device->get_user_prot_info = dataflash_get_otp_info;
608 device->read_user_prot_reg = dataflash_read_user_otp;
609
610 /* rev c parts (at45db321c and at45db1281 only!) use a
611 * different write procedure; not (yet?) implemented.
612 */
613 if (revision > 'c')
614 device->write_user_prot_reg = dataflash_write_user_otp;
615
616 return ", OTP";
617}
618
619#else
620
621static char *otp_setup(struct mtd_info *device)
622{
623 return " (OTP)";
624}
625
626#endif
627
628/* ......................................................................... */
629
454/* 630/*
455 * Register DataFlash device with MTD subsystem. 631 * Register DataFlash device with MTD subsystem.
456 */ 632 */
457static int __devinit 633static int __devinit
458add_dataflash(struct spi_device *spi, char *name, 634add_dataflash_otp(struct spi_device *spi, char *name,
459 int nr_pages, int pagesize, int pageoffset) 635 int nr_pages, int pagesize, int pageoffset, char revision)
460{ 636{
461 struct dataflash *priv; 637 struct dataflash *priv;
462 struct mtd_info *device; 638 struct mtd_info *device;
463 struct flash_platform_data *pdata = spi->dev.platform_data; 639 struct flash_platform_data *pdata = spi->dev.platform_data;
640 char *otp_tag = "";
464 641
465 priv = kzalloc(sizeof *priv, GFP_KERNEL); 642 priv = kzalloc(sizeof *priv, GFP_KERNEL);
466 if (!priv) 643 if (!priv)
@@ -489,8 +666,12 @@ add_dataflash(struct spi_device *spi, char *name,
489 device->write = dataflash_write; 666 device->write = dataflash_write;
490 device->priv = priv; 667 device->priv = priv;
491 668
492 dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes\n", 669 if (revision >= 'c')
493 name, DIV_ROUND_UP(device->size, 1024), pagesize); 670 otp_tag = otp_setup(device, revision);
671
672 dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n",
673 name, DIV_ROUND_UP(device->size, 1024),
674 pagesize, otp_tag);
494 dev_set_drvdata(&spi->dev, priv); 675 dev_set_drvdata(&spi->dev, priv);
495 676
496 if (mtd_has_partitions()) { 677 if (mtd_has_partitions()) {
@@ -519,6 +700,14 @@ add_dataflash(struct spi_device *spi, char *name,
519 return add_mtd_device(device) == 1 ? -ENODEV : 0; 700 return add_mtd_device(device) == 1 ? -ENODEV : 0;
520} 701}
521 702
703static inline int __devinit
704add_dataflash(struct spi_device *spi, char *name,
705 int nr_pages, int pagesize, int pageoffset)
706{
707 return add_dataflash_otp(spi, name, nr_pages, pagesize,
708 pageoffset, 0);
709}
710
522struct flash_info { 711struct flash_info {
523 char *name; 712 char *name;
524 713
@@ -664,13 +853,16 @@ static int __devinit dataflash_probe(struct spi_device *spi)
664 * Try to detect dataflash by JEDEC ID. 853 * Try to detect dataflash by JEDEC ID.
665 * If it succeeds we know we have either a C or D part. 854 * If it succeeds we know we have either a C or D part.
666 * D will support power of 2 pagesize option. 855 * D will support power of 2 pagesize option.
856 * Both support the security register, though with different
857 * write procedures.
667 */ 858 */
668 info = jedec_probe(spi); 859 info = jedec_probe(spi);
669 if (IS_ERR(info)) 860 if (IS_ERR(info))
670 return PTR_ERR(info); 861 return PTR_ERR(info);
671 if (info != NULL) 862 if (info != NULL)
672 return add_dataflash(spi, info->name, info->nr_pages, 863 return add_dataflash_otp(spi, info->name, info->nr_pages,
673 info->pagesize, info->pageoffset); 864 info->pagesize, info->pageoffset,
865 (info->flags & SUP_POW2PS) ? 'd' : 'c');
674 866
675 /* 867 /*
676 * Older chips support only legacy commands, identifing 868 * Older chips support only legacy commands, identifing
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index d2f331876e4c..13cc67ad272a 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -350,7 +350,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
350 wake_up((wait_queue_head_t *)instr->priv); 350 wake_up((wait_queue_head_t *)instr->priv);
351} 351}
352 352
353#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) 353#ifdef CONFIG_HAVE_MTD_OTP
354static int otp_select_filemode(struct mtd_file_info *mfi, int mode) 354static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
355{ 355{
356 struct mtd_info *mtd = mfi->mtd; 356 struct mtd_info *mtd = mfi->mtd;
@@ -663,7 +663,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
663 break; 663 break;
664 } 664 }
665 665
666#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) 666#ifdef CONFIG_HAVE_MTD_OTP
667 case OTPSELECT: 667 case OTPSELECT:
668 { 668 {
669 int mode; 669 int mode;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index cb41cbca64f7..b94a61b670d1 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -29,6 +29,7 @@ config MTD_ONENAND_GENERIC
29 29
30config MTD_ONENAND_OTP 30config MTD_ONENAND_OTP
31 bool "OneNAND OTP Support" 31 bool "OneNAND OTP Support"
32 select HAVE_MTD_OTP
32 help 33 help
33 One Block of the NAND Flash Array memory is reserved as 34 One Block of the NAND Flash Array memory is reserved as
34 a One-Time Programmable Block memory area. 35 a One-Time Programmable Block memory area.