Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: dataflash: Make use of "extened device information"

In anticipation of supporting chips that need it, extend the size of
struct flash_info's 'jedec_id' field to make room 2 byte of extended
device information as well as add code to fetch this data during
jedec_probe().

Cc: cphealy@gmail.com
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Brian Norris <computersforpeace@gmail.com>
Cc: Boris Brezillon <boris.brezillon@free-electrons.com>
Cc: Marek Vasut <marek.vasut@gmail.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Cc: linux-kernel@vger.kernel.org
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Tested-by: Chris Healy <cphealy@gmail.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Andrey Smirnov and committed by
Brian Norris
1da8869a a296a1bc

+57 -31
+57 -31
drivers/mtd/devices/mtd_dataflash.c
··· 84 84 85 85 #define CFI_MFR_ATMEL 0x1F 86 86 87 + #define DATAFLASH_SHIFT_EXTID 24 88 + #define DATAFLASH_SHIFT_ID 40 89 + 87 90 struct dataflash { 88 91 u8 command[4]; 89 92 char name[24]; ··· 690 687 /* JEDEC id has a high byte of zero plus three data bytes: 691 688 * the manufacturer id, then a two byte device id. 692 689 */ 693 - u32 jedec_id; 690 + u64 jedec_id; 694 691 695 692 /* The size listed here is what works with OP_ERASE_PAGE. */ 696 693 unsigned nr_pages; ··· 698 695 u16 pageoffset; 699 696 700 697 u16 flags; 698 + #define SUP_EXTID 0x0004 /* supports extended ID data */ 701 699 #define SUP_POW2PS 0x0002 /* supports 2^N byte pages */ 702 700 #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ 703 701 }; ··· 738 734 { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, 739 735 }; 740 736 741 - static struct flash_info *jedec_probe(struct spi_device *spi) 737 + static struct flash_info *jedec_lookup(struct spi_device *spi, 738 + u64 jedec, bool use_extid) 742 739 { 743 - int ret; 744 - u8 code = OP_READ_ID; 745 - u8 id[3]; 746 - u32 jedec; 747 740 struct flash_info *info; 748 741 int status; 749 - 750 - /* 751 - * JEDEC also defines an optional "extended device information" 752 - * string for after vendor-specific data, after the three bytes 753 - * we use here. Supporting some chips might require using it. 754 - * 755 - * If the vendor ID isn't Atmel's (0x1f), assume this call failed. 756 - * That's not an error; only rev C and newer chips handle it, and 757 - * only Atmel sells these chips. 758 - */ 759 - ret = spi_write_then_read(spi, &code, 1, id, 3); 760 - if (ret < 0) { 761 - dev_dbg(&spi->dev, "error %d reading JEDEC ID\n", ret); 762 - return ERR_PTR(ret); 763 - } 764 - 765 - if (id[0] != CFI_MFR_ATMEL) 766 - return NULL; 767 - 768 - jedec = id[0]; 769 - jedec = jedec << 8; 770 - jedec |= id[1]; 771 - jedec = jedec << 8; 772 - jedec |= id[2]; 773 742 774 743 for (info = dataflash_data; 775 744 info < dataflash_data + ARRAY_SIZE(dataflash_data); 776 745 info++) { 746 + if (use_extid && !(info->flags & SUP_EXTID)) 747 + continue; 748 + 777 749 if (info->jedec_id == jedec) { 778 750 dev_dbg(&spi->dev, "OTP, sector protect%s\n", 779 751 (info->flags & SUP_POW2PS) ? ··· 773 793 } 774 794 } 775 795 796 + return ERR_PTR(-ENODEV); 797 + } 798 + 799 + static struct flash_info *jedec_probe(struct spi_device *spi) 800 + { 801 + int ret; 802 + u8 code = OP_READ_ID; 803 + u64 jedec; 804 + u8 id[sizeof(jedec)] = {0}; 805 + const unsigned int id_size = 5; 806 + struct flash_info *info; 807 + 808 + /* 809 + * JEDEC also defines an optional "extended device information" 810 + * string for after vendor-specific data, after the three bytes 811 + * we use here. Supporting some chips might require using it. 812 + * 813 + * If the vendor ID isn't Atmel's (0x1f), assume this call failed. 814 + * That's not an error; only rev C and newer chips handle it, and 815 + * only Atmel sells these chips. 816 + */ 817 + ret = spi_write_then_read(spi, &code, 1, id, id_size); 818 + if (ret < 0) { 819 + dev_dbg(&spi->dev, "error %d reading JEDEC ID\n", ret); 820 + return ERR_PTR(ret); 821 + } 822 + 823 + if (id[0] != CFI_MFR_ATMEL) 824 + return NULL; 825 + 826 + jedec = be64_to_cpup((__be64 *)id); 827 + 828 + /* 829 + * First, try to match device using extended device 830 + * information 831 + */ 832 + info = jedec_lookup(spi, jedec >> DATAFLASH_SHIFT_EXTID, true); 833 + if (!IS_ERR(info)) 834 + return info; 835 + /* 836 + * If that fails, make another pass using regular ID 837 + * information 838 + */ 839 + info = jedec_lookup(spi, jedec >> DATAFLASH_SHIFT_ID, false); 840 + if (!IS_ERR(info)) 841 + return info; 776 842 /* 777 843 * Treat other chips as errors ... we won't know the right page 778 844 * size (it might be binary) even when we can tell which density 779 845 * class is involved (legacy chip id scheme). 780 846 */ 781 - dev_warn(&spi->dev, "JEDEC id %06x not handled\n", jedec); 847 + dev_warn(&spi->dev, "JEDEC id %016llx not handled\n", jedec); 782 848 return ERR_PTR(-ENODEV); 783 849 } 784 850