diff options
Diffstat (limited to 'drivers/mtd/devices/m25p80.c')
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 81e49a9b017e..f90941a785e4 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -16,6 +16,8 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/err.h> | ||
20 | #include <linux/errno.h> | ||
19 | #include <linux/module.h> | 21 | #include <linux/module.h> |
20 | #include <linux/device.h> | 22 | #include <linux/device.h> |
21 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
@@ -639,8 +641,18 @@ static const struct spi_device_id m25p_ids[] = { | |||
639 | { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, | 641 | { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, |
640 | { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, | 642 | { "at26df321", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, |
641 | 643 | ||
644 | /* EON -- en25pxx */ | ||
645 | { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, | ||
646 | { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, | ||
647 | |||
648 | /* Intel/Numonyx -- xxxs33b */ | ||
649 | { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, | ||
650 | { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, | ||
651 | { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, | ||
652 | |||
642 | /* Macronix */ | 653 | /* Macronix */ |
643 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, | 654 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, |
655 | { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, | ||
644 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, | 656 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, |
645 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, | 657 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, |
646 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, | 658 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, |
@@ -680,6 +692,16 @@ static const struct spi_device_id m25p_ids[] = { | |||
680 | { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, | 692 | { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, |
681 | { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, | 693 | { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, |
682 | 694 | ||
695 | { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, | ||
696 | { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, | ||
697 | { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, | ||
698 | { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, | ||
699 | { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, | ||
700 | { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, | ||
701 | { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, | ||
702 | { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, | ||
703 | { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, | ||
704 | |||
683 | { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, | 705 | { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, |
684 | { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, | 706 | { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, |
685 | { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, | 707 | { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, |
@@ -694,6 +716,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
694 | { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, | 716 | { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, |
695 | { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, | 717 | { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, |
696 | { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, | 718 | { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, |
719 | { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, | ||
697 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, | 720 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, |
698 | 721 | ||
699 | /* Catalyst / On Semiconductor -- non-JEDEC */ | 722 | /* Catalyst / On Semiconductor -- non-JEDEC */ |
@@ -723,7 +746,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
723 | if (tmp < 0) { | 746 | if (tmp < 0) { |
724 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", | 747 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", |
725 | dev_name(&spi->dev), tmp); | 748 | dev_name(&spi->dev), tmp); |
726 | return NULL; | 749 | return ERR_PTR(tmp); |
727 | } | 750 | } |
728 | jedec = id[0]; | 751 | jedec = id[0]; |
729 | jedec = jedec << 8; | 752 | jedec = jedec << 8; |
@@ -731,14 +754,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
731 | jedec = jedec << 8; | 754 | jedec = jedec << 8; |
732 | jedec |= id[2]; | 755 | jedec |= id[2]; |
733 | 756 | ||
734 | /* | ||
735 | * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants, | ||
736 | * which depend on technology process. Officially RDID command doesn't | ||
737 | * exist for non-JEDEC chips, but for compatibility they return ID 0. | ||
738 | */ | ||
739 | if (jedec == 0) | ||
740 | return NULL; | ||
741 | |||
742 | ext_jedec = id[3] << 8 | id[4]; | 757 | ext_jedec = id[3] << 8 | id[4]; |
743 | 758 | ||
744 | for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { | 759 | for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) { |
@@ -749,7 +764,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
749 | return &m25p_ids[tmp]; | 764 | return &m25p_ids[tmp]; |
750 | } | 765 | } |
751 | } | 766 | } |
752 | return NULL; | 767 | return ERR_PTR(-ENODEV); |
753 | } | 768 | } |
754 | 769 | ||
755 | 770 | ||
@@ -794,9 +809,8 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
794 | const struct spi_device_id *jid; | 809 | const struct spi_device_id *jid; |
795 | 810 | ||
796 | jid = jedec_probe(spi); | 811 | jid = jedec_probe(spi); |
797 | if (!jid) { | 812 | if (IS_ERR(jid)) { |
798 | dev_info(&spi->dev, "non-JEDEC variant of %s\n", | 813 | return PTR_ERR(jid); |
799 | id->name); | ||
800 | } else if (jid != id) { | 814 | } else if (jid != id) { |
801 | /* | 815 | /* |
802 | * JEDEC knows better, so overwrite platform ID. We | 816 | * JEDEC knows better, so overwrite platform ID. We |
@@ -826,11 +840,12 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
826 | dev_set_drvdata(&spi->dev, flash); | 840 | dev_set_drvdata(&spi->dev, flash); |
827 | 841 | ||
828 | /* | 842 | /* |
829 | * Atmel and SST serial flash tend to power | 843 | * Atmel, SST and Intel/Numonyx serial flash tend to power |
830 | * up with the software protection bits set | 844 | * up with the software protection bits set |
831 | */ | 845 | */ |
832 | 846 | ||
833 | if (info->jedec_id >> 16 == 0x1f || | 847 | if (info->jedec_id >> 16 == 0x1f || |
848 | info->jedec_id >> 16 == 0x89 || | ||
834 | info->jedec_id >> 16 == 0xbf) { | 849 | info->jedec_id >> 16 == 0xbf) { |
835 | write_enable(flash); | 850 | write_enable(flash); |
836 | write_sr(flash, 0); | 851 | write_sr(flash, 0); |