Commit 36ac0228 authored by Michael Walle's avatar Michael Walle Committed by Vignesh Raghavendra

mtd: spi-nor: add initial sysfs support

Add support to show the manufacturer, the partname and JEDEC identifier
as well as to dump the SFDP table. Not all flashes list their SFDP table
contents in their datasheet. So having that is useful. It might also be
helpful in bug reports from users.
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Acked-by: default avatarPratyush Yadav <p.yadav@ti.com>
parent 65b6d89d
What: /sys/bus/spi/devices/.../spi-nor/jedec_id
Date: April 2021
KernelVersion: 5.14
Contact: linux-mtd@lists.infradead.org
Description: (RO) The JEDEC ID of the SPI NOR flash as reported by the
flash device.
What: /sys/bus/spi/devices/.../spi-nor/manufacturer
Date: April 2021
KernelVersion: 5.14
Contact: linux-mtd@lists.infradead.org
Description: (RO) Manufacturer of the SPI NOR flash.
What: /sys/bus/spi/devices/.../spi-nor/partname
Date: April 2021
KernelVersion: 5.14
Contact: linux-mtd@lists.infradead.org
Description: (RO) Part name of the SPI NOR flash.
What: /sys/bus/spi/devices/.../spi-nor/sfdp
Date: April 2021
KernelVersion: 5.14
Contact: linux-mtd@lists.infradead.org
Description: (RO) This attribute is only present if the SPI NOR flash
device supports the "Read SFDP" command (5Ah).
If present, it contains the complete SFDP (serial flash
discoverable parameters) binary data of the flash.
# SPDX-License-Identifier: GPL-2.0
spi-nor-objs := core.o sfdp.o swp.o otp.o
spi-nor-objs := core.o sfdp.o swp.o otp.o sysfs.o
spi-nor-objs += atmel.o
spi-nor-objs += catalyst.o
spi-nor-objs += eon.o
......
......@@ -3459,6 +3459,7 @@ static struct spi_mem_driver spi_nor_driver = {
.driver = {
.name = "spi-nor",
.of_match_table = spi_nor_of_table,
.dev_groups = spi_nor_sysfs_groups,
},
.id_table = spi_nor_dev_ids,
},
......
......@@ -490,6 +490,8 @@ extern const struct spi_nor_manufacturer spi_nor_winbond;
extern const struct spi_nor_manufacturer spi_nor_xilinx;
extern const struct spi_nor_manufacturer spi_nor_xmc;
extern const struct attribute_group *spi_nor_sysfs_groups[];
void spi_nor_spimem_setup_op(const struct spi_nor *nor,
struct spi_mem_op *op,
const enum spi_nor_protocol proto);
......
// SPDX-License-Identifier: GPL-2.0
#include <linux/mtd/spi-nor.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
#include <linux/sysfs.h>
#include "core.h"
static ssize_t manufacturer_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
return sysfs_emit(buf, "%s\n", nor->manufacturer->name);
}
static DEVICE_ATTR_RO(manufacturer);
static ssize_t partname_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
return sysfs_emit(buf, "%s\n", nor->info->name);
}
static DEVICE_ATTR_RO(partname);
static ssize_t jedec_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
return sysfs_emit(buf, "%*phN\n", nor->info->id_len, nor->info->id);
}
static DEVICE_ATTR_RO(jedec_id);
static struct attribute *spi_nor_sysfs_entries[] = {
&dev_attr_manufacturer.attr,
&dev_attr_partname.attr,
&dev_attr_jedec_id.attr,
NULL
};
static ssize_t sfdp_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
{
struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
struct sfdp *sfdp = nor->sfdp;
size_t sfdp_size = sfdp->num_dwords * sizeof(*sfdp->dwords);
return memory_read_from_buffer(buf, count, &off, nor->sfdp->dwords,
sfdp_size);
}
static BIN_ATTR_RO(sfdp, 0);
static struct bin_attribute *spi_nor_sysfs_bin_entries[] = {
&bin_attr_sfdp,
NULL
};
static umode_t spi_nor_sysfs_is_bin_visible(struct kobject *kobj,
struct bin_attribute *attr, int n)
{
struct spi_device *spi = to_spi_device(kobj_to_dev(kobj));
struct spi_mem *spimem = spi_get_drvdata(spi);
struct spi_nor *nor = spi_mem_get_drvdata(spimem);
if (attr == &bin_attr_sfdp && nor->sfdp)
return 0444;
return 0;
}
static const struct attribute_group spi_nor_sysfs_group = {
.name = "spi-nor",
.is_bin_visible = spi_nor_sysfs_is_bin_visible,
.attrs = spi_nor_sysfs_entries,
.bin_attrs = spi_nor_sysfs_bin_entries,
};
const struct attribute_group *spi_nor_sysfs_groups[] = {
&spi_nor_sysfs_group,
NULL
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment