Andrew, This new patch set overwrites following patches: hwmon-lm70-convert-to-device-table-matching.patch hwmon-adxx-convert-to-device-table-matching.patch spi-merge-probe-and-probe_id-callbacks.patch spi-prefix-modalias-with-spi.patch of-remove-stmm25p40-alias.patch mtd-m25p80-convert-to-device-table-matching.patch spi-add-support-for-device-table-matching.patch Changes since v1: - Implemented Ben Dooks' idea of spi_get_device_id(), so we won't call spi_match_id() twice for drivers that don't need the id. - "spi: Merge probe and probe_id callbacks" patch no longer needed as we don't change probe()'s arguments; - Rename spi_device_id->data to driver_data, and turn it into kernel_ulong_t to match majority of subsystems. Most drivers don't need a pointer type anyway (e.g. m25p80 needs it, but lm70 and adcxx don't); - SPI_NAME_SIZE now defined to 32 (as it should be, using 20 for name size was a cut-n-paste typo from I2C defines). Thanks! -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
With this patch spi drivers can use standard spi_driver.id_table and
MODULE_DEVICE_TABLE() mechanisms to bind against the devices. Just
like we do with I2C drivers.
This is useful when a single driver supports several variants of
devices but it is not possible to detect them in run-time (like
non-JEDEC chips probing in drivers/mtd/devices/m25p80.c), and
when platform_data usage is overkill.
This patch also makes life a lot easier on OpenFirmware platforms,
since with OF we extensively use proper device IDs in modaliases.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/spi/spi.c | 23 +++++++++++++++++++++++
include/linux/mod_devicetable.h | 10 ++++++++++
include/linux/spi/spi.h | 10 ++++++++--
scripts/mod/file2alias.c | 13 +++++++++++++
4 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 70845cc..8518a6e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -59,9 +59,32 @@ static struct device_attribute spi_dev_attrs[] = {
* and the sysfs version makes coldplug work too.
*/
+static const struct spi_device_id *spi_match_id(const struct spi_device_id *id,
+ const struct spi_device *sdev)
+{
+ while (id->name[0]) {
+ if (!strcmp(sdev->modalias, id->name))
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
+const struct spi_device_id *spi_get_device_id(const struct spi_device *sdev)
+{
+ const struct spi_driver *sdrv = to_spi_driver(sdev->dev.driver);
+
+ return spi_match_id(sdrv->id_table, sdev);
+}
+EXPORT_SYMBOL_GPL(spi_get_device_id);
+
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
const struct spi_device *spi = to_spi_device(dev);
+ const struct spi_driver *sdrv = to_spi_driver(drv);
+
+ if (sdrv->id_table)
+ return !!spi_match_id(sdrv->id_table, spi);
return strcmp(spi->modalias, drv->name) == 0;
}
diff --git a/include/linux/mod_devicetable.h ...This patch converts the m25p80 driver so that now it uses .id_table
for device matching, making it properly detect devices on OpenFirmware
platforms (prior to this patch the driver misdetected non-JEDEC chips,
seeing all chips as "m25p80").
Also, now jedec_probe() only does jedec probing, nothing else. If it
is not able to detect a chip, NULL is returned and the driver fall
backs to the information specified by the platform (platform_data, or
exact ID).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/mtd/devices/m25p80.c | 146 +++++++++++++++++++++++-------------------
1 files changed, 80 insertions(+), 66 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 10ed195..0d74b38 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
@@ -462,8 +463,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
*/
struct flash_info {
- char *name;
-
/* JEDEC id zero means "no ID" (most older chips); otherwise it has
* a high byte of zero plus three data bytes: the manufacturer id,
* then a two byte device id.
@@ -481,74 +480,83 @@ struct flash_info {
#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
};
+#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
+ ((kernel_ulong_t)&(struct flash_info) { \
+ .jedec_id = (_jedec_id), \
+ .ext_id = (_ext_id), \
+ .sector_size = (_sector_size), \
+ .n_sectors = (_n_sectors), \
+ .flags = (_flags), \
+ })
/* NOTE: double check command sets and memory organization when you add
* more flash chips. This current list focusses on newer chips, which
* have been converging on command sets which including JEDEC ID.
*/
-static struct flash_info __devinitdata ...I suspect "detect" is a misnomer there. It only "detects" JEDEC chips. All others got explicit declarations ... so if there's misbehavior for other chips, it's because those declarations were poorly handled. Maybe I'd rather keep the warning, so there's a clue about what's really Anonymous inlined structures ... kind of ugly, but I can understand why you might not want to declare and name a At this point I wonder why you're not changing the probe sequence more. Get "id" and then "id" here. If it's for "m25p80" assume it's an old-style board init and do the current logic. Else just verify "info". There's a new error case of course: new-style but data->type Better: "if (info == NULL) ..." You've got all the pointers --
Hi David, Thanks for the review, and sorry for the delayed response. Currently the driver always tries JEDEC probing, and it wrongly "assumed" that all non-JEDEC chips are m25p80, because an entry for m25p80 chips had "0" in jedec id field, which isn't correct ID, but 0 is returned by We can't tell if the chip was actually found. M25Px0 chips can be JEDEC and non-JEDEC, e.g. Nymonyx manufacturing "M25P80" chips in two variants: "The RDID instruction is available only for parts made with Technology T9HX (0.11μm), ..." Most (but not all) non-JEDEC EEPROMs will return "0" for RDID opcode though (in that case warning is misleading). And for the chips that don't return 0, we shouldn't probe them with jedec at all. Yep, I was going to do it anyway, but for another reason: to support Yep, good ideas. Though, the code will vanish anyway. Patches on the way... --
Previosly the driver always tried JEDEC probing, assuming that non-JEDEC
chips will return '0'. But truly non-JEDEC chips (like CAT25) won't do
that, their behaviour on RDID command is undefined, so the driver should
not call jedec_probe() for these chips.
Also, be less strict on error conditions, don't fail to probe if JEDEC
found a chip that is different from what platform code told, instead
just print some warnings and use an information obtained via JEDEC. In
that case we should not trust partitions any longer, but they might be
still useful (i.e. they could protect some parts of the chip).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/mtd/devices/m25p80.c | 69 ++++++++++++++++++++++++-----------------
1 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 0d74b38..b75e319 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -581,6 +581,14 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
jedec = jedec << 8;
jedec |= id[2];
+ /*
+ * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
+ * which depend on technology process. Officially RDID command doesn't
+ * exist for non-JEDEC chips, but for compatibility they return ID 0.
+ */
+ if (jedec == 0)
+ return NULL;
+
ext_jedec = id[3] << 8 | id[4];
for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
@@ -602,7 +610,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
*/
static int __devinit m25p_probe(struct spi_device *spi)
{
- const struct spi_device_id *id;
+ const struct spi_device_id *id = spi_get_device_id(spi);
struct flash_platform_data *data;
struct m25p *flash;
struct flash_info *info;
@@ -615,41 +623,44 @@ static int __devinit m25p_probe(struct spi_device *spi)
*/
data = spi->dev.platform_data;
if (data && data->type) {
+ const struct spi_device_id ...On Wed, Aug 19, 2009 at 5:46 AM, Anton Vorontsov This patch caused a problem: even though the external flash doesn't exist, it will still pass the probe() and be registerred into kernel and given the partition table. You may refer to this bug report:
Thanks for the report.
There's little we can do about it. Platform code asked us
to register the device, and JEDEC probing of M25Pxx chips isn't
reliable (thanks to various vendors that make these JEDEC and
non-JEDEC variants), so the best thing we can do is to register
the chip anyway.
OTOH, if the board pulls MISO line up, then the following patch
should help.
If this won't work, we'll have to add some flag to the platform
data, i.e. to force JEDEC probing, and not trust platform data.
Not-yet-Signed-off-by: Anton Vorontsov <cbouatmailru@gmail.com>
---
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 81e49a9..a307929 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -16,6 +16,7 @@
*/
#include <linux/init.h>
+#include <linux/errno.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
@@ -723,7 +724,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
- return NULL;
+ return ERR_PTR(tmp);
}
jedec = id[0];
jedec = jedec << 8;
@@ -737,7 +738,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
* exist for non-JEDEC chips, but for compatibility they return ID 0.
*/
if (jedec == 0)
- return NULL;
+ return ERR_PTR(-EEXIST);
ext_jedec = id[3] << 8 | id[4];
@@ -749,7 +750,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
return &m25p_ids[tmp];
}
}
- return NULL;
+ return ERR_PTR(-ENODEV);
}
@@ -794,9 +795,11 @@ static int __devinit m25p_probe(struct spi_device *spi)
const struct spi_device_id *jid;
jid = jedec_probe(spi);
- if (!jid) {
+ if (IS_ERR(jid) && PTR_ERR(jid) == -EEXIST) {
dev_info(&spi->dev, "non-JEDEC variant of %s\n",
id->name);
+ } else if (IS_ERR(jid)) {
+ return ...Make sense with pullup to keep the value high while external device How about we add a non_jedec flag in platform_data, if the flag is 1, we let the detection pass even though the ID is 0? Otherwise, we need a --
Here i mean:
Index: drivers/mtd/devices/m25p80.c
===================================================================
--- drivers/mtd/devices/m25p80.c (revision 8927)
+++ drivers/mtd/devices/m25p80.c (revision 8929)
@@ -795,8 +795,13 @@
jid = jedec_probe(spi);
if (!jid) {
- dev_info(&spi->dev, "non-JEDEC variant of %s\n",
- id->name);
+ if (!data->non_jedec) {
+ dev_err(&spi->dev, "fail to detect%s\n",
+ id->name);
+ return -ENODEV;
+ } else
+ dev_info(&spi->dev, "non-JEDEC variant of %s\n",
+ id->name);
} else if (jid != id) {
/*
* JEDEC knows better, so overwrite platform ID. We
Index: include/linux/spi/flash.h
===================================================================
--- include/linux/spi/flash.h (revision 8927)
+++ include/linux/spi/flash.h (revision 8929)
@@ -25,6 +25,11 @@
char *type;
+ /*
+ * For non-JEDEC, id will be 0. In this case, we can't be sure
+ * whether the flash exists with runtime probing.
+ */
+ int non_jedec;
/* we'll likely add more ... use JEDEC IDs, etc */
--
On Mon, Jun 21, 2010 at 11:27:31AM +0800, Barry Song wrote: This will break at least OF-enabled platforms (e.g. PowerPC), they assume that the driver will success for non-JEDEC flashes. OF platforms don't pass platform data, and even if they did, device tree doesn't specify if the flash is JEDEC or non-JEDEC. Which is why I think that, by default, the driver should successfully register the flash even if JEDEC probe fails. So, instead of checking for "!non_jedec", I would recommend -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
Mike Frysinger suggested to use non_jedec since most devices are standard jedec devices. Only if non_jedec=1, we let the detection pass
Then please #ifdef it with CONFIG_OF. -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
I think the patch has nothing to do with platform. Here SPI Flash is a peripherals, doesn't depend on any platform. Adding a CONFIG_OF doesn't make sense very much. If you think most devices are non-JEDEC, we can change non_JEDEC to force_JEDEC as you said. But anyway, is that real that most devices are non_JEDEC? If not, I think we should change OF platform codes to --
With OF we don't place non-existent devices into the device
tree (or we mark them with status = "not-ok/disabled/absent"
You can't easily change OF. It's like "let's change ACPI tables
or BIOS in these PCs". Doable, but involves things like reflashing.
And we usually have to support old BIOSes as well.
OTOH, I see (git grep m25p arch/powerpc/boot/dts/) that in
mainline kernel only MPC8569 board has a correct m25p
node, and it is STMicro variant (it is JEDEC capable).
As we don't really have to support out of tree code, I'd
just go with this patch, assuming that we have to change
device tree for boards with non-JEDEC flashes. It's
effectively the same thing as platform data flag, except
that it works automatically for OF platforms.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 81e49a9..a610ca9 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -680,6 +680,16 @@ static const struct spi_device_id m25p_ids[] = {
{ "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) },
{ "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) },
+ { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) },
+ { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) },
+ { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) },
+ { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) },
+ { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) },
+ { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) },
+ { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) },
+ { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) },
+ { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) },
+
{ "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) },
{ "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) },
{ "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) },
@@ -795,8 +805,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
jid = jedec_probe(spi);
if (!jid) ...are you picking the m25p because its flash geometry matches whatever you're using, or because you have some weird variant of the m25p that has JEDEC commands removed ? -mike --
The latter. It's Numonyx M25Pxx flashes, see http://www.numonyx.com/Documents/Datasheets/M25P80.pdf The RDID instruction is available only for parts made with 110 nm Technology identified with Process letter '4'. -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
lovely. i guess this patch is the way to go to satisfy everyone's requirements. i'm also of the mindset that a mtd should not be created if the SPI flash isnt there simply because the resources say it might be. -mike --
The patch looks good to me. Only problem is NULL is also returned by
spi_write_then_read() fail:
static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
{
int tmp;
u8 code = OPCODE_RDID;
u8 id[5];
u32 jedec;
u16 ext_jedec;
struct flash_info *info;
/* JEDEC also defines an optional "extended device information"
* string for after vendor-specific data, after the three bytes
* we use here. Supporting some chips might require using it.
*/
tmp = spi_write_then_read(spi, &code, 1, id, 5);
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
return NULL;
}
...
}
--
On Tue, Jun 22, 2010 at 02:37:52PM +0800, Barry Song wrote: Agreed. Though, this is not a regression, and I guess desires its own patch. Here are two patches, one for 2.6.35 (minimal changes to fix the JEDEC problem), another for 2.6.36. --
spi_write_then_read() may return its own return codes (e.g. -EIO),
so let's propagate the value down to the probe().
Also, remove jedec == 0 check, it isn't needed as nowadays we use
dedicated SPI device IDs for non-JEDEC flashes.
Suggested-by: Barry Song <21cnbao@gmail.com>
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
This is for 2.6.36.
drivers/mtd/devices/m25p80.c | 18 ++++++------------
1 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index a610ca9..7bf5c45 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -16,6 +16,8 @@
*/
#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/errno.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/interrupt.h>
@@ -733,7 +735,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
dev_name(&spi->dev), tmp);
- return NULL;
+ return ERR_PTR(tmp);
}
jedec = id[0];
jedec = jedec << 8;
@@ -741,14 +743,6 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
jedec = jedec << 8;
jedec |= id[2];
- /*
- * Some chips (like Numonyx M25P80) have JEDEC and non-JEDEC variants,
- * which depend on technology process. Officially RDID command doesn't
- * exist for non-JEDEC chips, but for compatibility they return ID 0.
- */
- if (jedec == 0)
- return NULL;
-
ext_jedec = id[3] << 8 | id[4];
for (tmp = 0; tmp < ARRAY_SIZE(m25p_ids) - 1; tmp++) {
@@ -759,7 +753,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi)
return &m25p_ids[tmp];
}
}
- return NULL;
+ return ERR_PTR(-ENODEV);
}
@@ -804,8 +798,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
const struct spi_device_id *jid;
jid = jedec_probe(spi);
- if (!jid) {
- return ...Since commit 18c6182bae0acca220ed6611f741034d563cd19f ("Rework probing/JEDEC code"), m25p80 driver successfully registers chips even if JEDEC probing fails. This was needed to support non-JEDEC flashes. Though, it appears that some platforms (e.g. blackfin bf533 stamp[1]) used the old behavior to detect if there's any flash connected, so the driver have to fail on JEDEC probing errors. This patch restores the old behavior for JEDEC flashes, and adds "-nonjedec" SPI device IDs for M25Pxx flashes, so that the kernel still supports non-JEDEC flashes. [1] http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&am... Reported-by: Mingquan Pan Reported-by: Barry Song <21cnbao@gmail.com> Signed-off-by: Anton Vorontsov <avorontsov@mvista.com> --- This is for 2.6.35. drivers/mtd/devices/m25p80.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 81e49a9..a610ca9 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -680,6 +680,16 @@ static const struct spi_device_id m25p_ids[] = { { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, + { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, + { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, + { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, + { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, + { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, + { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, + { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, + { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, + { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, + { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, @@ -795,8 +805,7 @@ ...
Pushed both patches to my l2-mtd-2.6.git / dunno, added Mike's ack. -- Best Regards, Artem Bityutskiy (Артём Битюцкий) --
CAT25 chips (as manufactured by On Semiconductor, previously Catalyst
Semiconductor) are similar to the original M25Px0 chips, except:
- Address width can vary (1-2 bytes, in contrast to 3 bytes in M25P
chips). So, implement convenient m25p_addr2cmd() and m25p_cmdsz()
calls, and place address width information into flash_info struct;
- Page size can vary, therefore we shouldn't hardcode it, so get rid
of FLASH_PAGESIZE definition, and place the page size information
into flash_info struct;
- CAT25 EEPROMs don't need to be erased, so add NO_ERASE flag, and
propagate it to the mtd subsystem.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/mtd/devices/m25p80.c | 172 ++++++++++++++++++++++++------------------
1 files changed, 97 insertions(+), 75 deletions(-)
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index b75e319..8930266 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -29,9 +29,6 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
-
-#define FLASH_PAGESIZE 256
-
/* Flash opcodes. */
#define OPCODE_WREN 0x06 /* Write enable */
#define OPCODE_RDSR 0x05 /* Read status register */
@@ -56,7 +53,7 @@
/* Define max times to check status register before we give up. */
#define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */
-#define CMD_SIZE 4
+#define MAX_CMD_SIZE 4
#ifdef CONFIG_M25PXX_USE_FAST_READ
#define OPCODE_READ OPCODE_FAST_READ
@@ -73,8 +70,10 @@ struct m25p {
struct mutex lock;
struct mtd_info mtd;
unsigned partitioned:1;
+ u16 page_size;
+ u16 addr_width;
u8 erase_opcode;
- u8 command[CMD_SIZE + FAST_READ_DUMMY_BYTE];
+ u8 command[MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE];
};
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -184,6 +183,19 @@ static int erase_chip(struct m25p *flash)
return 0;
}
+static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, ...On Wed, 19 Aug 2009 01:46:28 +0400
This patch (still) doesn't know about the mx25l3205d, mx25l12805d and
mx25l12855e devices.
I randomly did this:
-> { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 256, 3, 0) },
-> { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 256, 3, 0) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 256, 3, 0) },
-> { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 256, 3, 0) },
--
Yes, support for these chips commited on Fri, 4 Sep 2009 08:40:27 Looks correct, thanks a lot. -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
On Mon, 3 Aug 2009 19:54:50 -0700 afaik there was no response to David's review comments, so this patch --
Hm? Response: http://lkml.org/lkml/2009/8/18/363 And the two patches I sent on top: http://lkml.org/lkml/2009/8/18/364 http://lkml.org/lkml/2009/8/18/366 -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
Got versions of those which apply to the mtd-2.6.git tree (which I'm about to ask Linus to pull)? -- dwmw2 --
On Tue, 22 Sep 2009 16:43:47 -0700 I'll send them in a sec. --
I'd love to, but they depend on a bunch of SPI patches that are still in -mm tree. As soon as SPI core changes hit Linus' tree, I think Andrew will send all m25p80 patches to you anyway. Thanks, -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
On Wed, 23 Sep 2009 03:55:34 +0400 Or David can ack them and I'll send 'em up. --
Yeah, you missed this patch: http://patchwork.kernel.org/patch/38179/ Thanks, -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
Beautiful - thanks - sorry to interrupt -- Michael Barkowski 905-482-4577 --
Hello Anton, Is m25p_probe now valid with dev.platform_data == NULL, for of platforms? Then shouldn't you have the following change as well, near the end of the function? - } else if (data->nr_parts) + } else if (data && data->nr_parts) dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", data->nr_parts, data->name); Or am I misunderstanding something? -- Michael Barkowski RuggedCom --
The alias isn't needed any longer since the m25p80 driver converted
to the module device table matching.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/of/base.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 69f85c0..ddf224d 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -447,7 +447,6 @@ struct of_modalias_table {
static struct of_modalias_table of_modalias_table[] = {
{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
{ "mmc-spi-slot", "mmc_spi" },
- { "stm,m25p40", "m25p80" },
};
/**
--
1.6.3.3
--
This patch makes the code a little bit nicer, and shorter.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/hwmon/adcxx.c | 101 ++++++++-----------------------------------------
1 files changed, 16 insertions(+), 85 deletions(-)
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c
index 242294d..5e9e095 100644
--- a/drivers/hwmon/adcxx.c
+++ b/drivers/hwmon/adcxx.c
@@ -43,6 +43,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#define DRVNAME "adcxx"
@@ -157,8 +158,9 @@ static struct sensor_device_attribute ad_input[] = {
/*----------------------------------------------------------------------*/
-static int __devinit adcxx_probe(struct spi_device *spi, int channels)
+static int __devinit adcxx_probe(struct spi_device *spi)
{
+ int channels = spi_get_device_id(spi)->driver_data;
struct adcxx *adc;
int status;
int i;
@@ -204,26 +206,6 @@ out_err:
return status;
}
-static int __devinit adcxx1s_probe(struct spi_device *spi)
-{
- return adcxx_probe(spi, 1);
-}
-
-static int __devinit adcxx2s_probe(struct spi_device *spi)
-{
- return adcxx_probe(spi, 2);
-}
-
-static int __devinit adcxx4s_probe(struct spi_device *spi)
-{
- return adcxx_probe(spi, 4);
-}
-
-static int __devinit adcxx8s_probe(struct spi_device *spi)
-{
- return adcxx_probe(spi, 8);
-}
-
static int __devexit adcxx_remove(struct spi_device *spi)
{
struct adcxx *adc = dev_get_drvdata(&spi->dev);
@@ -241,79 +223,33 @@ static int __devexit adcxx_remove(struct spi_device *spi)
return 0;
}
-static struct spi_driver adcxx1s_driver = {
- .driver = {
- .name = "adcxx1s",
- .owner = THIS_MODULE,
- },
- .probe = adcxx1s_probe,
- .remove = __devexit_p(adcxx_remove),
+static const struct spi_device_id adcxx_ids[] = {
+ { "adcxx1s", 1 },
+ { "adcxx2s", 2 },
+ { "adcxx4s", 4 },
+ { "adcxx8s", 8 },
+ { },
...This patch makes the code a little bit nicer, and shorter.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/hwmon/lm70.c | 55 +++++++++++++++++--------------------------------
1 files changed, 19 insertions(+), 36 deletions(-)
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index ae6204f..ab8a5d3 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -32,6 +32,7 @@
#include <linux/sysfs.h>
#include <linux/hwmon.h>
#include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
@@ -130,11 +131,20 @@ static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
/*----------------------------------------------------------------------*/
-static int __devinit common_probe(struct spi_device *spi, int chip)
+static int __devinit lm70_probe(struct spi_device *spi)
{
+ int chip = spi_get_device_id(spi)->driver_data;
struct lm70 *p_lm70;
int status;
+ /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+ if (spi->mode & (SPI_CPOL | SPI_CPHA))
+ return -EINVAL;
+
+ /* 3-wire link (shared SI/SO) for LM70 */
+ if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE))
+ return -EINVAL;
+
/* NOTE: we assume 8-bit words, and convert to 16 bits manually */
p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
@@ -170,24 +180,6 @@ out_dev_reg_failed:
return status;
}
-static int __devinit lm70_probe(struct spi_device *spi)
-{
- /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
- if ((spi->mode & (SPI_CPOL | SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
- return -EINVAL;
-
- return common_probe(spi, LM70_CHIP_LM70);
-}
-
-static int __devinit tmp121_probe(struct spi_device *spi)
-{
- /* signaling is SPI_MODE_0 with only MISO connected */
- if (spi->mode & (SPI_CPOL | SPI_CPHA))
- return -EINVAL;
-
- return common_probe(spi, LM70_CHIP_TMP121);
-}
-
static int __devexit lm70_remove(struct spi_device *spi)
{
struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ ...This makes it consistent with other buses (platform, i2c, vio, ...). I'm not sure why we use the prefixes, but there must be a reason. This was easy enough to do it, and I did it. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- drivers/gpio/max7301.c | 1 + drivers/gpio/mcp23s08.c | 1 + drivers/hwmon/lis3lv02d_spi.c | 2 +- drivers/hwmon/max1111.c | 1 + drivers/input/touchscreen/ad7877.c | 1 + drivers/input/touchscreen/ad7879.c | 1 + drivers/input/touchscreen/ads7846.c | 1 + drivers/leds/leds-dac124s085.c | 1 + drivers/mfd/ezx-pcap.c | 1 + drivers/misc/eeprom/at25.c | 2 +- drivers/mmc/host/mmc_spi.c | 1 + drivers/mtd/devices/mtd_dataflash.c | 1 + drivers/net/enc28j60.c | 1 + drivers/net/ks8851.c | 1 + drivers/net/wireless/libertas/if_spi.c | 1 + drivers/net/wireless/p54/p54spi.c | 1 + drivers/net/wireless/wl12xx/main.c | 1 + drivers/rtc/rtc-ds1305.c | 1 + drivers/rtc/rtc-ds1390.c | 1 + drivers/rtc/rtc-ds3234.c | 1 + drivers/rtc/rtc-m41t94.c | 1 + drivers/rtc/rtc-max6902.c | 1 + drivers/rtc/rtc-r9701.c | 1 + drivers/rtc/rtc-rs5c348.c | 1 + drivers/serial/max3100.c | 1 + drivers/spi/spi.c | 3 ++- drivers/spi/spidev.c | 1 + drivers/spi/tle62x0.c | 1 + drivers/staging/stlc45xx/stlc45xx.c | 1 + drivers/video/backlight/corgi_lcd.c | 1 + drivers/video/backlight/ltv350qv.c | 1 + drivers/video/backlight/tdo24m.c | 1 + drivers/video/backlight/tosa_lcd.c | 2 +- drivers/video/backlight/vgg2432a4.c | 3 +-- include/linux/mod_devicetable.h | 1 + scripts/mod/file2alias.c ...
Are you going to send v3 and address David's comments? Do you want some of these patches to go via the MTD tree or they better go as a series via some other tree? -- Best Regards, Artem Bityutskiy (Артём Битюцкий) --
No v3, but I'm going to address David's comments in a follow up Um.. The MTD patches depend on SPI subsystem changes... If David and Andrew are OK with SPI patches going through MTD tree, then I'm fine with it as well. Thanks, -- Anton Vorontsov email: cbouatmailru@gmail.com irc://irc.freenode.net/bd2 --
If you are not sure, then I suggest to make these go through something else (not MTD tree). -- Best Regards, Artem Bityutskiy (Артём Битюцкий) --
