1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/mtd/spi-nor.h>
4 #include <linux/spi/spi.h>
5 #include <linux/spi/spi-mem.h>
6 #include <linux/sysfs.h>
10 static ssize_t
manufacturer_show(struct device
*dev
,
11 struct device_attribute
*attr
, char *buf
)
13 struct spi_device
*spi
= to_spi_device(dev
);
14 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
15 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
17 return sysfs_emit(buf
, "%s\n", nor
->manufacturer
->name
);
19 static DEVICE_ATTR_RO(manufacturer
);
21 static ssize_t
partname_show(struct device
*dev
,
22 struct device_attribute
*attr
, char *buf
)
24 struct spi_device
*spi
= to_spi_device(dev
);
25 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
26 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
28 return sysfs_emit(buf
, "%s\n", nor
->info
->name
);
30 static DEVICE_ATTR_RO(partname
);
32 static ssize_t
jedec_id_show(struct device
*dev
,
33 struct device_attribute
*attr
, char *buf
)
35 struct spi_device
*spi
= to_spi_device(dev
);
36 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
37 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
38 const u8
*id
= nor
->info
->id
? nor
->info
->id
->bytes
: nor
->id
;
39 u8 id_len
= nor
->info
->id
? nor
->info
->id
->len
: SPI_NOR_MAX_ID_LEN
;
41 return sysfs_emit(buf
, "%*phN\n", id_len
, id
);
43 static DEVICE_ATTR_RO(jedec_id
);
45 static struct attribute
*spi_nor_sysfs_entries
[] = {
46 &dev_attr_manufacturer
.attr
,
47 &dev_attr_partname
.attr
,
48 &dev_attr_jedec_id
.attr
,
52 static ssize_t
sfdp_read(struct file
*filp
, struct kobject
*kobj
,
53 struct bin_attribute
*bin_attr
, char *buf
,
54 loff_t off
, size_t count
)
56 struct spi_device
*spi
= to_spi_device(kobj_to_dev(kobj
));
57 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
58 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
59 struct sfdp
*sfdp
= nor
->sfdp
;
60 size_t sfdp_size
= sfdp
->num_dwords
* sizeof(*sfdp
->dwords
);
62 return memory_read_from_buffer(buf
, count
, &off
, nor
->sfdp
->dwords
,
65 static BIN_ATTR_RO(sfdp
, 0);
67 static struct bin_attribute
*spi_nor_sysfs_bin_entries
[] = {
72 static umode_t
spi_nor_sysfs_is_visible(struct kobject
*kobj
,
73 struct attribute
*attr
, int n
)
75 struct spi_device
*spi
= to_spi_device(kobj_to_dev(kobj
));
76 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
77 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
79 if (attr
== &dev_attr_manufacturer
.attr
&& !nor
->manufacturer
)
81 if (attr
== &dev_attr_partname
.attr
&& !nor
->info
->name
)
83 if (attr
== &dev_attr_jedec_id
.attr
&& !nor
->info
->id
&& !nor
->id
)
89 static umode_t
spi_nor_sysfs_is_bin_visible(struct kobject
*kobj
,
90 const struct bin_attribute
*attr
, int n
)
92 struct spi_device
*spi
= to_spi_device(kobj_to_dev(kobj
));
93 struct spi_mem
*spimem
= spi_get_drvdata(spi
);
94 struct spi_nor
*nor
= spi_mem_get_drvdata(spimem
);
96 if (attr
== &bin_attr_sfdp
&& nor
->sfdp
)
102 static const struct attribute_group spi_nor_sysfs_group
= {
104 .is_visible
= spi_nor_sysfs_is_visible
,
105 .is_bin_visible
= spi_nor_sysfs_is_bin_visible
,
106 .attrs
= spi_nor_sysfs_entries
,
107 .bin_attrs
= spi_nor_sysfs_bin_entries
,
110 const struct attribute_group
*spi_nor_sysfs_groups
[] = {
111 &spi_nor_sysfs_group
,