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); |
