Skip to contentSkip to conversation

Export SoC info through sysfs

RFC PATCH New Maxime Coquelin 10 participants 32 messages Mar 9, 2011 – Mar 11, 2011

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover Export SoC info through sysfs

Here is the first version of the proposal to export SoC related information to user-space through sysFS interface.

This serie is to continue what has been discussed on the "socinfo" thread created by Eduardo Valentin:
https://lkml.org/lkml/2010/5/11/364

The first patch introduces the common part, which provides an interface to the platform to register its name, and exports platform-defined IDs to user-space. The IDs strings can be provided in two ways: either with a pointer to the string, or by a callback returning the string.

The second patch is given as example for the ux500 architecture. It registers with the machine name "DB8500", and exports 3 informations (SoC unique ID, sili con revision and silicon process).

Here is the output for DB8500:
root at ME:/sys/devices/system/soc ls -l

-r--r--r--    1 root     root         4096 Jan 11 02:43 mach_name
-r--r--r--    1 root     root         4096 Jan 11 02:43 process
-r--r--r--    1 root     root         4096 Jan 11 02:43 revision
-r--r--r--    1 root     root         4096 Jan 11 02:43 soc_id

root at ME:/sys/devices/system/soc cat mach_name
DB8500
root at ME:/sys/devices/system/soc cat process
Standard
root at ME:/sys/devices/system/soc cat revision
2.0
root at ME:/sys/devices/system/soc cat soc_id
2ba07ce9e5835d6185321e9577462ef2ea2129cf

Any comments are welcome.

Note that I will be off from 13th to 21th of March.

Regards,
Maxime

-------------------------------------------------------------------------------

Maxime Coquelin (2):
Export SoC info through sysfs
ux500: Export U8500 SoC info through sysfs

 arch/arm/mach-ux500/id.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/base/Kconfig     |    4 ++
 drivers/base/Makefile    |    1 +
 drivers/base/soc.c       |   88 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h  |   33 ++++++++++++++++
 5 files changed, 222 insertions(+), 0 deletions(-)
 create mode 100644 drivers/base/soc.c
 create mode 100644 include/linux/sys_soc.h
#1 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/. Creation of a common "mach_name" entry to export machine name. Creation of platform-defined SoC information entries.

---
 drivers/base/Kconfig    |    4 ++
 drivers/base/Makefile   |    1 +
 drivers/base/soc.c      |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h |   33 +++++++++++++++++
 4 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 drivers/base/soc.c
 create mode 100644 include/linux/sys_soc.h
drivers/base/Kconfig +4 -0
index d57e8d0..4f2b56d 100644
@@ -168,4 +168,8 @@ config SYS_HYPERVISOR
 	bool
 	default n
 
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
 endmenu
drivers/base/Makefile +1 -0
index 5f51c3b..f3bcfb3 100644
@@ -18,6 +18,7 @@ ifeq ($(CONFIG_SYSFS),y)
 obj-$(CONFIG_MODULES)	+= module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
+obj-$(CONFIG_SYS_SOC) += soc.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
drivers/base/soc.c new file +88 -0

88 lines not on this page · raw message

include/linux/sys_soc.h new file +33 -0
new file mode 100644
index 0000000..b91a924
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Maxime Coquelin <[email protected]> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __SYS_SOC_H
+#define __SYS_SOC_H
+
+#include <linux/sysdev.h>
+
+/**
+ * struct sys_soc_info - SoC exports related informations
+ * @name: name of the export
+ * @info: pointer on the key to export
+ * @get_info: callback to retrieve key if info field is NULL
+ * @attr: export's sysdev class attribute
+ */
+struct sys_soc_info {
+	char *name;
+	char *info;
+	char *(*get_info)(struct sys_soc_info *);
+	struct sysdev_class_attribute attr;
+};
+
+/**
+ * void register_sys_soc(char *name, struct sys_soc_info *, int num)
+ * @name: name of the machine
+ * @info: pointer on the info table to export
+ * @num: number of info to export
+ */
+void register_sys_soc(char *name, struct sys_soc_info *info, int num);
+
+#endif /* __SYS_SOC_H */
Signature · 1 line
1.7.1
#2 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Hi Maxime,

Thanks for doing this, it looks very nice! A couple of nitpicks, but I've given it a quick spin on my platform and it provides us with all of the hooks to export all of the information we need.

Jamie

Quoted 54 lines · Maxime Coquelin

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/. Creation of a common "mach_name" entry to export machine name. Creation of platform-defined SoC information entries.

---
 drivers/base/Kconfig    |    4 ++
 drivers/base/Makefile   |    1 +
 drivers/base/soc.c      |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h |   33 +++++++++++++++++
 4 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 drivers/base/soc.c
 create mode 100644 include/linux/sys_soc.h
drivers/base/Kconfig +4 -0
index d57e8d0..4f2b56d 100644
@@ -168,4 +168,8 @@ config SYS_HYPERVISOR
 	bool
 	default n
 
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
 endmenu
drivers/base/Makefile +1 -0
index 5f51c3b..f3bcfb3 100644
@@ -18,6 +18,7 @@ ifeq ($(CONFIG_SYSFS),y)
 obj-$(CONFIG_MODULES)	+= module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
+obj-$(CONFIG_SYS_SOC) += soc.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
drivers/base/soc.c new file +7 -0
new file mode 100644
index 0000000..6fa538b
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Maxime Coquelin <[email protected]> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/sysdev.h>

drivers/base/soc.c line 17

Quoted 10 lines
drivers/base/soc.c new file +10 -0
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+static struct sysdev_class_attribute *soc_default_attrs[];
+
+struct sys_soc {
+	char *mach_name;

Can this be made const?

Quoted 19 lines
drivers/base/soc.c new file +19 -0
+	struct sysdev_class class;
+};
+
+struct sys_soc soc = {
+	.class = {
+		.name = "soc",
+		.attrs = soc_default_attrs,
+	},
+};
+
+static ssize_t show_mach_name(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", soc.mach_name);
+}
+static SYSDEV_CLASS_ATTR(mach_name, S_IRUGO, show_mach_name, NULL);
+
+static ssize_t show_info(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)

drivers/base/soc.c line 46

Quoted 10 lines
drivers/base/soc.c new file +10 -0
+{
+	struct sys_soc_info *si = container_of(attr,
+			struct sys_soc_info, attr);
+
+	if (si->info)
+		return sprintf(buf, "%s\n", si->info);
+	else if (si->get_info)
+		return sprintf(buf, "%s\n", si->get_info(si));
+	else
+		return sprintf(buf, "No data\n");

Isn't this a platform error if we don't have a way to get the required info? If in register_sys_soc_info() we check that one of si->info or si->get_info is non-NULL then we don't need this check. If we have something like:

static bool sys_soc_info_is_valid(struct sys_soc_info *info)

{
	if ((!info->info && !info->get_info) ||
	    info->info && info->get_info)
	    return false;

	return true;
}

then we can do this at registration. Is there a valid use case where someone could set the static info and the dynamic get_info callback?

drivers/base/soc.c line 58

Quoted 12 lines
drivers/base/soc.c new file +12 -0
+}
+
+void __init register_sys_soc_info(struct sys_soc_info *info, int nb_info)
+{
+	int i;
+
+	for (i = 0; i < nb_info; i++) {
+		info[i].attr.attr.name = info[i].name;
+		info[i].attr.attr.mode = S_IRUGO;
+		info[i].attr.show = show_info;
+
+		sysdev_class_create_file(&soc.class, &info[i].attr);
		if (sys_soc_info_is_valid(&info[i]))
			sysdev_class_create_file(...); ?

drivers/base/soc.c line 62

Quoted 4 lines
drivers/base/soc.c new file +4 -0
+	}
+}
+
+void __init register_sys_soc(char *name, struct sys_soc_info *info, int num)

Make name const? Also, should num be a size_t?

drivers/base/soc.c line 71

Quoted 9 lines
drivers/base/soc.c new file +9 -0
+{
+	int len;
+
+	len = strlen(name);
+	soc.mach_name = kzalloc(len + 1, GFP_KERNEL);
+	if (!soc.mach_name)
+		return;
+
+	sprintf(soc.mach_name, "%s", name);

soc.mach_name = kstrdup(name, GFP_KERNEL) instead of the allocate and sprintf?

Quoted 34 lines
drivers/base/soc.c new file +17 -0
+
+	if (sysdev_class_register(&soc.class)) {
+		kfree(soc.mach_name);
+		return;
+	}
+
+	register_sys_soc_info(info, num);
+}
+
+/*
+ * Common attributes for all platforms.
+ * Only machine name for now
+ */
+static struct sysdev_class_attribute *soc_default_attrs[] = {
+	&attr_mach_name,
+	NULL
+};
include/linux/sys_soc.h new file +11 -0
new file mode 100644
index 0000000..b91a924
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Maxime Coquelin <[email protected]> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+#ifndef __SYS_SOC_H
+#define __SYS_SOC_H
+
+#include <linux/sysdev.h>
+
+/**

include/linux/sys_soc.h line 21

Quoted 10 lines
include/linux/sys_soc.h new file +10 -0
+ * struct sys_soc_info - SoC exports related informations
+ * @name: name of the export
+ * @info: pointer on the key to export
+ * @get_info: callback to retrieve key if info field is NULL
+ * @attr: export's sysdev class attribute
+ */
+struct sys_soc_info {
+	char *name;
+	char *info;
+	char *(*get_info)(struct sys_soc_info *);

Could this return a const char* ?

include/linux/sys_soc.h line 26

Quoted 5 lines
include/linux/sys_soc.h new file +5 -0
+	struct sysdev_class_attribute attr;
+};
+
+/**
+ * void register_sys_soc(char *name, struct sys_soc_info *, int num)

I think this should be "register_sys_soc - register the soc information" for valid kerneldoc notation..

Quoted 15 lines
include/linux/sys_soc.h new file +7 -0
+ * @name: name of the machine
+ * @info: pointer on the info table to export
+ * @num: number of info to export
+ */
+void register_sys_soc(char *name, struct sys_soc_info *info, int num);
+
+#endif /* __SYS_SOC_H */
Signature · 7 lines
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
#3 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 7 lines · Jamie Iles

Hi Maxime,

Thanks for doing this, it looks very nice! A couple of nitpicks, but I've given it a quick spin on my platform and it provides us with all of the hooks to export all of the information we need.

Jamie

Hi Jamie,
Thanks for your review. Fine it works for you.

Quoted 6 lines
drivers/base/soc.c new file +5 -0
+
+static struct sysdev_class_attribute *soc_default_attrs[];
+
+struct sys_soc {
+	char *mach_name;

Can this be made const?

Yes, you're right.

Quoted 12 lines

drivers/base/soc.c line 46

Quoted 7 lines
drivers/base/soc.c new file +7 -0
+
+	if (si->info)
+		return sprintf(buf, "%s\n", si->info);
+	else if (si->get_info)
+		return sprintf(buf, "%s\n", si->get_info(si));
+	else
+		return sprintf(buf, "No data\n");

Isn't this a platform error if we don't have a way to get the required info? If in register_sys_soc_info() we check that one of si->info or si->get_info is non-NULL then we don't need this check. If we have something like:

Quoted 8 lines

static bool sys_soc_info_is_valid(struct sys_soc_info *info)

{
	if ((!info->info&&  !info->get_info) ||
	    info->info&&  info->get_info)
	    return false;

	return true;
}

Yes it is a platform error, it should be tested at registration time.

Quoted 3 lines

then we can do this at registration. Is there a valid use case where someone could set the static info and the dynamic get_info callback?

At registration, no. But in the get_info callback, we can set the info field in order to call the callback once if the value will never change. However, I will remove this possibility as it is not clear.

Quoted 2 lines

Make name const? Also, should num be a size_t?

Fixed

Quoted 3 lines

soc.mach_name = kstrdup(name, GFP_KERNEL) instead of the allocate and sprintf?

Fixed.

Quoted 6 lines

include/linux/sys_soc.h line 21

Quoted 4 lines
include/linux/sys_soc.h new file +4 -0
+struct sys_soc_info {
+	char *name;
+	char *info;
+	char *(*get_info)(struct sys_soc_info *);

Could this return a const char* ?

Fixed.

Quoted 7 lines

include/linux/sys_soc.h line 26

Quoted 5 lines
include/linux/sys_soc.h new file +5 -0
+	struct sysdev_class_attribute attr;
+};
+
+/**
+ * void register_sys_soc(char *name, struct sys_soc_info *, int num)

I think this should be "register_sys_soc - register the soc information" for valid kerneldoc notation..

Fixed.

Regards,
Maxime

#4 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Maxime Coquelin

drivers/base/Kconfig config SYS_HYPERVISOR · line 175

Quoted 5 lines · Maxime Coquelin
drivers/base/Kconfig +4 -0
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
 endmenu

Would it not be better for this to depend on a symbol that systems can select when they add useful output? If there's nothing that generates information for it on a given platform there's no point in enabling it.

drivers/base/soc.c line 44

Quoted 10 lines
drivers/base/soc.c new file +10 -0
+static ssize_t show_info(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)
+{
+	struct sys_soc_info *si = container_of(attr,
+			struct sys_soc_info, attr);
+
+	if (si->info)
+		return sprintf(buf, "%s\n", si->info);
+	else if (si->get_info)
+		return sprintf(buf, "%s\n", si->get_info(si));

It seems like it'd be easier to pass the output buffer directly to get_info(), otherwise the get_info() implementation will have to figure out a buffer to return data from.

#5 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 11 lines · Mark Brown

drivers/base/Kconfig config SYS_HYPERVISOR · line 175

Quoted 5 lines · Maxime Coquelin
drivers/base/Kconfig +4 -0
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
  endmenu

Would it not be better for this to depend on a symbol that systems can select when they add useful output? If there's nothing that generates information for it on a given platform there's no point in enabling it.

It is deactivated by default when "default" parameter is not mentioned.

Quoted 5 lines
Quoted 5 lines
drivers/base/soc.c new file +5 -0
+static ssize_t show_info(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)
+{
+	struct sys_soc_info *si = container_of(attr,
+			struct sys_soc_info, attr);
Quoted 8 lines

drivers/base/soc.c line 44

Quoted 5 lines
drivers/base/soc.c new file +5 -0
+
+	if (si->info)
+		return sprintf(buf, "%s\n", si->info);
+	else if (si->get_info)
+		return sprintf(buf, "%s\n", si->get_info(si));

It seems like it'd be easier to pass the output buffer directly to get_info(), otherwise the get_info() implementation will have to figure out a buffer to return data from.

You're right, I will propose a path with passing the output buffer directly.

Regards,
Maxime

#6 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 7 lines · Maxime Coquelin
Quoted 3 lines · Mark Brown

Would it not be better for this to depend on a symbol that systems can select when they add useful output? If there's nothing that generates information for it on a given platform there's no point in enabling it.

It is deactivated by default when "default" parameter is not mentioned.

That's not the point - if the user sees the option and turns it on then there won't be anything they can actually do with it unless some other bit of software creates some data. No sense in offering them an option they can't actually use.

#7 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 10 lines · Mark Brown
Quoted 5 lines · Maxime Coquelin
Quoted 3 lines · Mark Brown

Would it not be better for this to depend on a symbol that systems can select when they add useful output? If there's nothing that generates information for it on a given platform there's no point in enabling it.

It is deactivated by default when "default" parameter is not mentioned.

That's not the point - if the user sees the option and turns it on then there won't be anything they can actually do with it unless some other bit of software creates some data. No sense in offering them an option they can't actually use.

I agree, I will remove the Kconfig option and let platform selects it.

#8 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Maxime Coquelin
Quoted 3 lines · On Wednesday 09 March 2011 17:59:20 Maxime Coquelin wrote:

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/.

Why under system?

As far as I can tell, the SOC already exists as a platform device under /sys/devices/platform, so just put the data in there.

There is no point in having the same physical device represented as multiple separate instances in sysfs.

Quoted 9 lines

Creation of a common "mach_name" entry to export machine name. Creation of platform-defined SoC information entries.

---
 drivers/base/Kconfig    |    4 ++
 drivers/base/Makefile   |    1 +
 drivers/base/soc.c      |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h |   33 +++++++++++++++++

This seems to be missing the documentation file. Every sysfs attribute you create must be documented.

drivers/base/Kconfig config SYS_HYPERVISOR · line 175

Quoted 11 lines
drivers/base/Kconfig +4 -0
@@ -168,4 +168,8 @@ config SYS_HYPERVISOR
 	bool
 	default n
 
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
 endmenu

CONFIG_EMBEDDED is gone, and did not mean what you intended.

Just make the information unconditionally available in the code that manages you SoC.

Quoted 8 lines
drivers/base/Kconfig +8 -0
+void __init register_sys_soc(char *name, struct sys_soc_info *info, int num)
+{
+	int len;
+
+	len = strlen(name);
+	soc.mach_name = kzalloc(len + 1, GFP_KERNEL);
+	if (!soc.mach_name)
+		return;

drivers/base/Kconfig

Quoted 10 lines
drivers/base/Kconfig +10 -0
+
+	sprintf(soc.mach_name, "%s", name);
+
+	if (sysdev_class_register(&soc.class)) {
+		kfree(soc.mach_name);
+		return;
+	}
+
+	register_sys_soc_info(info, num);
+}

You do way too much here when all you need is a platform device attribute.

Arnd

#9 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 8 lines · Arnd Bergmann
Quoted 3 lines · On Wednesday 09 March 2011 17:59:20 Maxime Coquelin wrote:

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/.

Why under system?

As far as I can tell, the SOC already exists as a platform device under /sys/devices/platform, so just put the data in there.

The aim of this patch is to provide a common interface for SoC vendors to export some pieces of information.
For now, only the machine name is common in this patch set, but some other attributes might be common (family name, silicon process...). Moving to /sys/devices/platform means it will be vendor-specific, so we loose the gain of having a common ABI. Right?

Quoted 6 lines

There is no point in having the same physical device represented as multiple separate instances in sysfs.

Quoted 3 lines

Creation of a common "mach_name" entry to export machine name. Creation of platform-defined SoC information entries.

Quoted 9 lines
Quoted 6 lines
---
  drivers/base/Kconfig    |    4 ++
  drivers/base/Makefile   |    1 +
  drivers/base/soc.c      |   88 +++++++++++++++++++++++++++++++++++++++++++++++
  include/linux/sys_soc.h |   33 +++++++++++++++++

This seems to be missing the documentation file. Every sysfs attribute you create must be documented.

Ok, I will fix it.

Quoted 13 lines

drivers/base/Kconfig config SYS_HYPERVISOR · line 175

Quoted 11 lines
drivers/base/Kconfig +4 -0
@@ -168,4 +168,8 @@ config SYS_HYPERVISOR
  	bool
  	default n
 
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED
+
  endmenu

CONFIG_EMBEDDED is gone, and did not mean what you intended.

Quoted 3 lines

Just make the information unconditionally available in the code that manages you SoC.

Ok.

Quoted 21 lines
Quoted 8 lines
drivers/base/Kconfig +8 -0
+void __init register_sys_soc(char *name, struct sys_soc_info *info, int num)
+{
+	int len;
+
+	len = strlen(name);
+	soc.mach_name = kzalloc(len + 1, GFP_KERNEL);
+	if (!soc.mach_name)
+		return;

drivers/base/Kconfig

Quoted 10 lines
drivers/base/Kconfig +10 -0
+
+	sprintf(soc.mach_name, "%s", name);
+
+	if (sysdev_class_register(&soc.class)) {
+		kfree(soc.mach_name);
+		return;
+	}
+
+	register_sys_soc_info(info, num);
+}

You do way too much here when all you need is a platform device attribute.

Quoted 1 line

Arnd

Thanks for your review,
Maxime

#10 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Arnd Bergmann

2011/3/9 Arnd Bergmann <[email protected]>:

Quoted 9 lines · On Wednesday 09 March 2011 17:59:20 Maxime Coquelin wrote:
Quoted 3 lines

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/.

Why under system?

As far as I can tell, the SOC already exists as a platform device under /sys/devices/platform,

This is from U8500:

/sys/devices/platform ls

ab8500-i2c.0   gpio.0         gpio.5         nmk-i2c.0      uevent
arm-pmu.0      gpio.1         gpio.6         nmk-i2c.1
cpufreq-u8500  gpio.2         gpio.7         nmk-i2c.2
dma40.0        gpio.3         gpio.8         nmk-i2c.3
gpio-keys.0    gpio.4         musb-ux500.0   reg-dummy

In our case the above are platform_device:s and also MFD cells, children of I2C devices (anything prefixed with ab8500-*) which have absolutely *nothing* to do with what is inside the SoC.

Further these SoC entries don't even have a device of *any* kind tied to them. It's just hooks reading binary right out of some extremely system-specific memory locations and producing matching strings.

"platform" means "platform bus" in this context, does it not? So your reasoning is that since on SoC:s there is one dominant bus called the platform bus that should also hold a reference to the SoC-specific stuff.

On the ARM Versatiles this isn't even true: there the dominant bus is the AMBA (PrimeCell) bus, and the U8500 uses a mixture of both. AMBA devices incidentally turn up as entries directly in /sys/devices:

/sys/devices ls

platform   sdi0       sdi4       system     uart1      virtual
rtc-pl031  sdi2       ssp0       uart0      uart2

The sdi, uart & rtc you see here are AMBA devices.

So platform is just the platform bus, not the, you know, *platform*. There are competing on-chip busses not just one.

So standardizing the location here, /sys/devices/system contain these more neutral things:

/sys/devices/system ls
clocksource cpu timekeeping timer

IMHO socinfo fits here, just as it is in the patch.

This might be a bit of bikeshed-color discussion but I happen to like this black color sooooo much...

Just my ?0.01
Linus Walleij

#11 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 4 lines · Linus Walleij

"platform" means "platform bus" in this context, does it not? So your reasoning is that since on SoC:s there is one dominant bus called the platform bus that should also hold a reference to the SoC-specific stuff.

Lots of stuff (like the MFD children of I2C devices) gets shoved on the platform bus on Linux - every time someone considers creating a new bus type for trivial devices the discussion ends up saying that the code will end up being pretty much identical to the platform bus as it's so straightforward so there's no point in cut'n'pasting the code.

Quoted 7 lines

So standardizing the location here, /sys/devices/system contain these more neutral things:

/sys/devices/system ls
clocksource cpu timekeeping timer

IMHO socinfo fits here, just as it is in the patch.

There's a general idea to kill of the system devices as the fact that they do special magic and don't have things like a struct device creates integration problems.

#12 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 7 lines · Mark Brown
Quoted 4 lines · Linus Walleij

"platform" means "platform bus" in this context, does it not? So your reasoning is that since on SoC:s there is one dominant bus called the platform bus that should also hold a reference to the SoC-specific stuff.

Quoted 5 lines

Lots of stuff (like the MFD children of I2C devices) gets shoved on the platform bus on Linux - every time someone considers creating a new bus type for trivial devices the discussion ends up saying that the code will end up being pretty much identical to the platform bus as it's so straightforward so there's no point in cut'n'pasting the code.

Note that there is a difference between using top-level platform devices (the ones that show up in /sys/devices/platform/) and platform devices that are children of others (all the others that are in /sys/bus/platform).

Creating a new bus_type for trivial things is rather pointless, so using a platform device is fine for MFD, since the child devices just show up in the hierarchy.

What some broken drivers do is to create platform devices ad hoc and just put them into /sys/platform/ directly although the devices clearly have a parent somewhere. These are bugs that should be fixed.

Arnd

#13 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 8 lines · Arnd Bergmann
Quoted 5 lines · Mark Brown

Lots of stuff (like the MFD children of I2C devices) gets shoved on the platform bus on Linux - every time someone considers creating a new bus type for trivial devices the discussion ends up saying that the code will end up being pretty much identical to the platform bus as it's so straightforward so there's no point in cut'n'pasting the code.

Quoted 4 lines

Note that there is a difference between using top-level platform devices (the ones that show up in /sys/devices/platform/) and platform devices that are children of others (all the others that are in /sys/bus/platform).

Sure.

Quoted 4 lines

What some broken drivers do is to create platform devices ad hoc and just put them into /sys/platform/ directly although the devices clearly have a parent somewhere. These are bugs that should be fixed.

Most of the devices doing that on ARMs tend to be devices where there's no bus that it's meaningful to expose to software - they'll typically be hanging off an AHB or APB bus which has either no real software control or control which is very heavily tied into the overall system control and so is better treated over the whole SoC rather than the bus.

#14 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 5 lines · Mark Brown

Most of the devices doing that on ARMs tend to be devices where there's no bus that it's meaningful to expose to software - they'll typically be hanging off an AHB or APB bus which has either no real software control or control which is very heavily tied into the overall system control and so is better treated over the whole SoC rather than the bus.

I can accept that it's reasonable to put all devices under /sys/devices/platform/ that are on the same top-level AHB or APB bus, although I also don't see a reason against making that bus a single device.

The one thing that really doesn't belong in /sys/devices/platform/ however are devices that are clearly children of some other device, e.g. a UART behind MFD behind I2C behind AHB.

Arnd

#15 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 3 lines · Arnd Bergmann

The one thing that really doesn't belong in /sys/devices/platform/ however are devices that are clearly children of some other device, e.g. a UART behind MFD behind I2C behind AHB.

Who ever thought about putting a UART behind I2C ? That's insane!

#16 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 6 lines · Russell King - ARM Linux
Quoted 3 lines · Arnd Bergmann

The one thing that really doesn't belong in /sys/devices/platform/ however are devices that are clearly children of some other device, e.g. a UART behind MFD behind I2C behind AHB.

Who ever thought about putting a UART behind I2C ? ?That's insane!

For immediate entertainment I can tell you we have such a thing in the AB3100 on the U300, at the other side of an I2C link.

That UART connects to a so-called "smart battery", since the AB3100 is our mixed-signal device it had the physical connections to the battery and thus that UART that can talk to the CPU inside the battery.

There aren't many bauds on this bus, I assure you... yet, batteries aren't very talkative anyway.

Yours,
Linus Walleij

#18 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Arnd Bergmann
Quoted 4 lines · Arnd Bergmann

I can accept that it's reasonable to put all devices under /sys/devices/platform/ that are on the same top-level AHB or APB bus, although I also don't see a reason against making that bus a single device.

You could, though the bus will just be a noop. Typically it's more than one bus but software basically can't tell.

Quoted 3 lines

The one thing that really doesn't belong in /sys/devices/platform/ however are devices that are clearly children of some other device, e.g. a UART behind MFD behind I2C behind AHB.

Right, and we seem to be fairly good at squashing such bugs when people notice them.

#19 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 9 lines · Mark Brown
Quoted 4 lines · Arnd Bergmann

I can accept that it's reasonable to put all devices under /sys/devices/platform/ that are on the same top-level AHB or APB bus, although I also don't see a reason against making that bus a single device.

You could, though the bus will just be a noop. Typically it's more than one bus but software basically can't tell.

Yes. The main reason for representing such a bus in sysfs would be to match the SOC's block diagram with the structure in the kernel.

The cost of an extra device is roughly zero, but structure generally helps. Another advantage is that you can associate attributes and names with the device, and simplify naming of the children without risking name space conflicts.

Arnd

#20 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 7 lines · Arnd Bergmann
Quoted 2 lines · Mark Brown

You could, though the bus will just be a noop. Typically it's more than one bus but software basically can't tell.

Yes. The main reason for representing such a bus in sysfs would be to match the SOC's block diagram with the structure in the kernel.

If you're doing that things like power domains tend to be a lot more interesting since you can do something meaningful with them in software. The non-visible buses aren't reliably documented anyway and the first procesor datasheet I just pulled up had a whole bunch of devices that span multiple buses anyway :)

#21 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 6 lines · Mark Brown
Quoted 4 lines · Arnd Bergmann
Quoted 2 lines · Mark Brown

You could, though the bus will just be a noop. Typically it's more than one bus but software basically can't tell.

Quoted 8 lines
Quoted 2 lines

Yes. The main reason for representing such a bus in sysfs would be to match the SOC's block diagram with the structure in the kernel.

If you're doing that things like power domains tend to be a lot more interesting since you can do something meaningful with them in software. The non-visible buses aren't reliably documented anyway and the first procesor datasheet I just pulled up had a whole bunch of devices that span multiple buses anyway :)

Yes, I'm aware that devices are not alwasy in a clear hierarchy and that you have bus addressing, device driver, clock, power and interrupt (and possibly more) trees that often don't match up.

My point is simply that we should still try to find a helpful tree representation in these cases, even if it's not perfect. Almost anything is better than having lots of unrelated devices in a flat directory.

Arnd

#22 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Linus Walleij
Quoted 14 lines · Linus Walleij
Quoted 3 lines

As far as I can tell, the SOC already exists as a platform device under /sys/devices/platform,

This is from U8500:

/sys/devices/platform ls

ab8500-i2c.0   gpio.0         gpio.5         nmk-i2c.0      uevent
arm-pmu.0      gpio.1         gpio.6         nmk-i2c.1
cpufreq-u8500  gpio.2         gpio.7         nmk-i2c.2
dma40.0        gpio.3         gpio.8         nmk-i2c.3
gpio-keys.0    gpio.4         musb-ux500.0   reg-dummy
Quoted 3 lines

In our case the above are platform_device:s and also MFD cells, children of I2C devices (anything prefixed with ab8500-*) which have absolutely nothing to do with what is inside the SoC.

Ok, I must correct myself:

There *should* *be* an SOC device that is the parent of all devices that are part of the SOC, instead of a bunch of random stuff getting placed directly under /sys/devices/platform.

Most of the stuff you have there really isn't a top-level platform device at all.

Quoted 3 lines

Further these SoC entries don't even have a device of any kind tied to them. It's just hooks reading binary right out of some extremely system-specific memory locations and producing matching strings.

On the SOC devices that I've dealt with, they are organized in some hierarchy of buses, and each bus has its own registers that identify it, and should therefore be represented in sysfs as a device with other child devices.

Making up a pseudo-device that does not refer to any hardware in particular is against the 'devices are only "devices"' rule in Documentation/sysfs-rules.txt.

If you really want that, it should be in /sys/kernel/, /sys/firmware/ or a new top-level directory in sysfs.

I think putting it in /sys/devices is good, but it has to be an attribute of an actual device, not an empty one that does not even have any child devices. If the device represents the soc, then every other device that is found in the soc should be a child of this one.

Quoted 4 lines

"platform" means "platform bus" in this context, does it not? So your reasoning is that since on SoC:s there is one dominant bus called the platform bus that should also hold a reference to the SoC-specific stuff.

No. Be careful not to confuse bus and bus_type here. Platform bus refers to the bus_type and it can hold any number of devices that are directly addressable but cannot be probed.

Quoted 10 lines

On the ARM Versatiles this isn't even true: there the dominant bus is the AMBA (PrimeCell) bus, and the U8500 uses a mixture of both. AMBA devices incidentally turn up as entries directly in /sys/devices:

/sys/devices ls

platform   sdi0       sdi4       system     uart1      virtual
rtc-pl031  sdi2       ssp0       uart0      uart2

The sdi, uart & rtc you see here are AMBA devices.

I would argue that these belong into a top-level AMBA bus device that holds all devices connected to one AMBA bus. It's a really bad idea to put random devices into a the global /sys/devices/ namespace, because of potential conflicts.

Quoted 2 lines

So platform is just the platform bus, not the, you know, *platform*. There are competing on-chip busses not just one.

Good point. Note that I did not mean to put the attributes directly under /sys/platform/, but under /sys/platform/foo/, where foo is the main bus that is used between the CPU core and all the SOC components.

This may of course not be easy. If you have an AMBA or PCI bus, you might want to have it represented as /sys/devices/pci0 and /sys/devices/amba0 instead of /sys/devices/platform/foo/amba0/.

Arnd

#23 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 9 lines · Arnd Bergmann
Quoted 2 lines · Linus Walleij

So platform is just the platform bus, not the, you know, *platform*. There are competing on-chip busses not just one.

Good point. Note that I did not mean to put the attributes directly under /sys/platform/, but under /sys/platform/foo/, where foo is the main bus that is used between the CPU core and all the SOC components.

Quoted 4 lines

This may of course not be easy. If you have an AMBA or PCI bus, you might want to have it represented as /sys/devices/pci0 and /sys/devices/amba0 instead of /sys/devices/platform/foo/amba0/.

Userspace app doing something needs the name and some unique number to be looked up. The first iteration of this patch (for the OMAPs) put it in /proc/socinfo with all the expected fuzz that this should go into sysfs as result.

So: where do we suggest Maxime actually put this then?

Quoted 3 lines

Making up a pseudo-device that does not refer to any hardware in particular is against the 'devices are only "devices"' rule in Documentation/sysfs-rules.txt.

Fine then I think we agree this can not realistically be under /sys/devices/* unless we first refactor all platforms that want to use this mechanism to have top-level-devices.

Quoted 8 lines

If you really want that, it should be in /sys/kernel/, /sys/firmware/ or a new top-level directory in sysfs.

I think putting it in /sys/devices is good, but it has to be an attribute of an actual device, not an empty one that does not even have any child devices. If the device represents the soc, then every other device that is found in the soc should be a child of this one.

IMO this is not good for socinfo, what is good for apps that want socinfo is to just attempt to open+read these file paths. Not to invoke libsysfs and start parsing the file tree to see if they can find some socinfo somewhere.

What about we just put it in
/sys/socinfo/* then, and we have a simple, easy-to-understand way for apps that want socinfo to read it out?

Everyone happy with this?

Yours,
Linus Walleij

#24 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 15 lines · Linus Walleij
Quoted 9 lines · Arnd Bergmann
Quoted 2 lines · Linus Walleij

So platform is just the platform bus, not the, you know, *platform*. There are competing on-chip busses not just one.

Good point. Note that I did not mean to put the attributes directly under /sys/platform/, but under /sys/platform/foo/, where foo is the main bus that is used between the CPU core and all the SOC components.

Quoted 4 lines

This may of course not be easy. If you have an AMBA or PCI bus, you might want to have it represented as /sys/devices/pci0 and /sys/devices/amba0 instead of /sys/devices/platform/foo/amba0/.

Quoted 6 lines

Userspace app doing something needs the name and some unique number to be looked up. The first iteration of this patch (for the OMAPs) put it in /proc/socinfo with all the expected fuzz that this should go into sysfs as result.

So: where do we suggest Maxime actually put this then?

I'm not sure we even need to define something really new. Ideally, it could just be properties of the devices in the device tree, but obviously we're not there yet and may not even want to go there for all platforms.

Quoted 7 lines
Quoted 3 lines

Making up a pseudo-device that does not refer to any hardware in particular is against the 'devices are only "devices"' rule in Documentation/sysfs-rules.txt.

Fine then I think we agree this can not realistically be under /sys/devices/* unless we first refactor all platforms that want to use this mechanism to have top-level-devices.

Not much refactoring required there, just register one (platform or top-level, I don't care) device named "soc", and make all platform devices of the soc have a .parent pointer to that device.

Then you can add attributes to the device.

Quoted 14 lines
Quoted 8 lines

If you really want that, it should be in /sys/kernel/, /sys/firmware/ or a new top-level directory in sysfs.

I think putting it in /sys/devices is good, but it has to be an attribute of an actual device, not an empty one that does not even have any child devices. If the device represents the soc, then every other device that is found in the soc should be a child of this one.

IMO this is not good for socinfo, what is good for apps that want socinfo is to just attempt to open+read these file paths. Not to invoke libsysfs and start parsing the file tree to see if they can find some socinfo somewhere.

Quoted 4 lines

What about we just put it in
/sys/socinfo/* then, and we have a simple, easy-to-understand way for apps that want socinfo to read it out?

Possible, but I'd be less happy with this. It's a bit of duplication of the information that is already present in both /sys/devices and /sys/firmware.

Arnd

#25 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 9 lines · Arnd Bergmann
Quoted 2 lines · Linus Walleij
Quoted 1 line · Arnd Bergmann

On Thursday 10 March 2011, Linus Walleij wrote:

Not much refactoring required there, just register one (platform or top-level, I don't care) device named "soc", and make all platform devices of the soc have a .parent pointer to that device.

Then you can add attributes to the device.

But since the name of the top-level device name is not subject to standardization, I suspect that an app not knowing which SoC it is running on will indeed need to parse through the entire sysfs/devices/* hierarchy to see if it can find some soc name.

No easy feat, indeed libsysfs can help you.
Equal to:

x=find /sys/devices | grep mach-name
cat x

Compare this to getting the *name* of the hardware you want to obtain the SoC-info for. Easy:

grep Hardware /proc/cpuinfo

What I'm trying to get at is that the user of this info isn't really interested in any device tree structure, it just becomes an obstacle s/he has to overcome to get this info out.

But there may be a compromise: if we create the socinfo in one place in the device tree (possibly the top node, or a dedicated device) then class it?

/sys/class/soc/soc0 -> ../../devices/platform/top-node

Then you find your entries easily by opening
/sys/class/soc/soc0/* ?

If the socinfo interface is singleton (and why should it not be) then:

/sys/class/soc -> ../devices/platfom/top-node

Or is this thing too trivial to have it's own class?

Yours,
Linus Walleij

#26 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

Quoted 5 lines · Linus Walleij

What I'm trying to get at is that the user of this info isn't really interested in any device tree structure, it just becomes an obstacle s/he has to overcome to get this info out.

Quoted 8 lines

But there may be a compromise: if we create the socinfo in one place in the device tree (possibly the top node, or a dedicated device) then class it?

/sys/class/soc/soc0 -> ../../devices/platform/top-node

Then you find your entries easily by opening
/sys/class/soc/soc0/* ?

That would be one way of finding all soc nodes, in case we want to have multiple ones. Similarly, it could be done based on

1. the name under /sys/devices/platform:

/sys/devices/platform/soc0
/sys/devices/platform/soc1
/sys/devices/platform/soc2

2. a new bus_type for soc devices, with bus_attributes:

/sys/bus/soc/devices/foo0 -> ../../../devices/platform/foo0 /sys/bus/soc/devices/bar0 -> ../../../devices/platform/bar0 /sys/bus/soc/devices/bar1 -> ../../../devices/platform/bar1

3. A new top-level device besides /sys/devices/platform (like PCI):

/sys/devices/soc0
/sys/devices/soc1
/sys/devices/soc2

Quoted 6 lines

If the socinfo interface is singleton (and why should it not be) then:

/sys/class/soc -> ../devices/platfom/top-node

Or is this thing too trivial to have it's own class?

In case of a singleton, I'd just use a fixed device as the parent:

/sys/devices/platform/soc/

or

/sys/devices/soc/

And pass that as the parent for all devices under it.

Arnd

#27 lore raw

RFC PATCH 1/2 Export SoC info through sysfs

In reply to Maxime Coquelin
Quoted 5 lines · Maxime Coquelin

Common base to export System-on-Chip related informations through sysfs.

Creation of a "soc" directory under /sys/devices/system/. Creation of a common "mach_name" entry to export machine name. Creation of platform-defined SoC information entries.

A few comments below. Echoing some of Jamie's and Mark's comments.

~Ryan

Quoted 16 lines
---
 drivers/base/Kconfig    |    4 ++
 drivers/base/Makefile   |    1 +
 drivers/base/soc.c      |   88 +++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h |   33 +++++++++++++++++
 4 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 drivers/base/soc.c
 create mode 100644 include/linux/sys_soc.h
drivers/base/Kconfig +0 -0
index d57e8d0..4f2b56d 100644

drivers/base/Kconfig config SYS_HYPERVISOR · line 173

Quoted 6 lines
drivers/base/Kconfig +3 -0
@@ -168,4 +168,8 @@ config SYS_HYPERVISOR
 	bool
 	default n
 
+config SYS_SOC
+	bool "Export SoC specific informations"
+	depends on EMBEDDED

This should ideally be automatically selected by platforms which provide SoC information.

Also, the word "informations" sounds odd to me. It can be replaced above with "information" and in some other places with "pieces of information" or similar.

Quoted 43 lines
drivers/base/Kconfig +1 -0
+
 endmenu
drivers/base/Makefile +1 -0
index 5f51c3b..f3bcfb3 100644
@@ -18,6 +18,7 @@ ifeq ($(CONFIG_SYSFS),y)
 obj-$(CONFIG_MODULES)	+= module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
+obj-$(CONFIG_SYS_SOC) += soc.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
drivers/base/soc.c new file +23 -0
new file mode 100644
index 0000000..6fa538b
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Maxime Coquelin <[email protected]> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include <linux/sysdev.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+
+static struct sysdev_class_attribute *soc_default_attrs[];
+
+struct sys_soc {
+	char *mach_name;
+	struct sysdev_class class;
+};
+
+struct sys_soc soc = {
+	.class = {
+		.name = "soc",

drivers/base/soc.c line 33

Quoted 10 lines
drivers/base/soc.c new file +10 -0
+		.attrs = soc_default_attrs,
+	},
+};
+
+static ssize_t show_mach_name(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", soc.mach_name);
+}
+static SYSDEV_CLASS_ATTR(mach_name, S_IRUGO, show_mach_name, NULL);

If you make mach_name work like the other SoC info attributes then it can be exported using the generic show_info function below. It also means that struct sys_soc is no longer necessary; you can just have the global sysdev_class.

drivers/base/soc.c line 46

Quoted 13 lines
drivers/base/soc.c new file +13 -0
+
+static ssize_t show_info(struct sysdev_class *class,
+				struct sysdev_class_attribute *attr, char *buf)
+{
+	struct sys_soc_info *si = container_of(attr,
+			struct sys_soc_info, attr);
+
+	if (si->info)
+		return sprintf(buf, "%s\n", si->info);
+	else if (si->get_info)
+		return sprintf(buf, "%s\n", si->get_info(si));
+	else
+		return sprintf(buf, "No data\n");

Agree with others that it should be a bug to have an item with no data. i.e. the registration should fail, probably with a WARN_ON. I also agree that buf should be passed directly into the get_info callback. How do we deal with overflow from dodgy callbacks? From memory we can safely write at least one page to a sysfs buffer?

drivers/base/soc.c line 50

Quoted 4 lines
drivers/base/soc.c new file +4 -0
+}
+
+void __init register_sys_soc_info(struct sys_soc_info *info, int nb_info)
+{

register_sys_soc_info can only be called once. That may be the intention, but it needs to be documented as such. Possibly a WARN_ON to catch it being called multiple times? I could see potential bugs in kernels which have multiple SoC/platforms built in.

This function should also be static, since calling it directly will result in the mach_name entry never being set.

drivers/base/soc.c line 56

Quoted 6 lines
drivers/base/soc.c new file +6 -0
+	int i;
+
+	for (i = 0; i < nb_info; i++) {
+		info[i].attr.attr.name = info[i].name;
+		info[i].attr.attr.mode = S_IRUGO;
+		info[i].attr.show = show_info;

This is double handling. Can't we do something like this:

struct sys_soc_info {
	char *info;
	char *(*get_info)(struct sys_soc_info *);
	struct sysdev_class_attribute attr;
};
#define SYS_SOC_ATTR_VALUE(name, value) {	\
	.attr.attr.name = name,			\
	.mode           = S_IRUGO,		\
	.info           = value,		\
}
#define SYS_SOC_ATTR_CALLBACK(name, callback) {	\
	.attr.attr.name = name,			\
	.mode           = S_IRUGO,		\
	.get_info       = callback,		\
}

Then the above code isn't necessary and the ux500 platform registration looks like this:

static struct sys_soc_info soc_info[] = {
	SYS_SOC_ATTR_CALLBACK("soc_id",   ux500_get_soc_id),
	SYS_SOC_ATTR_CALLBACK("revision", ux500_get_revision),
	SYS_SOC_ATTR_CALLBACK("process",  ux500_get_process),
};

Which is much more concise.

drivers/base/soc.c line 58

Quoted 2 lines
drivers/base/soc.c new file +2 -0
+
+		sysdev_class_create_file(&soc.class, &info[i].attr);

sysdev_class_create_file can fail, so we should propagate the error up.

drivers/base/soc.c line 71

Quoted 13 lines
drivers/base/soc.c new file +13 -0
+	}
+}
+
+void __init register_sys_soc(char *name, struct sys_soc_info *info, int num)
+{
+	int len;
+
+	len = strlen(name);
+	soc.mach_name = kzalloc(len + 1, GFP_KERNEL);
+	if (!soc.mach_name)
+		return;
+
+	sprintf(soc.mach_name, "%s", name);

Change name to mach_name (or family?) to make it clearer what it is for and make it const. Use kstrdup. This function should really return proper error codes rather than silently failing.

I also think mach_name should be added the same way as the other items since it should simplify the code a little.

drivers/base/soc.c line 76

Quoted 5 lines
drivers/base/soc.c new file +5 -0
+
+	if (sysdev_class_register(&soc.class)) {
+		kfree(soc.mach_name);
+		return;
+	}

Standard kernel coding practice is:

	err = sysdev_class_register(&soc.class);	
	if (err) {
		kfree(soc.mach_name);
		return err;
	}

drivers/base/soc.c line 88

Quoted 12 lines
drivers/base/soc.c new file +12 -0
+
+	register_sys_soc_info(info, num);
+}
+
+/*
+ * Common attributes for all platforms.
+ * Only machine name for now
+ */
+static struct sysdev_class_attribute *soc_default_attrs[] = {
+	&attr_mach_name,
+	NULL
+};

This becomes part of the ABI, so needs to be documented.

Quoted 11 lines
include/linux/sys_soc.h new file +5 -0
new file mode 100644
index 0000000..b91a924
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ * Author: Maxime Coquelin <[email protected]> for ST-Ericsson.
+ * License terms:  GNU General Public License (GPL), version 2
+ */

include/linux/sys_soc.h line 15

Quoted 10 lines
include/linux/sys_soc.h new file +10 -0
+#ifndef __SYS_SOC_H
+#define __SYS_SOC_H
+
+#include <linux/sysdev.h>
+
+/**
+ * struct sys_soc_info - SoC exports related informations
+ * @name: name of the export
+ * @info: pointer on the key to export
+ * @get_info: callback to retrieve key if info field is NULL

It should be noted here that one and only one of info and get_info must be set.

include/linux/sys_soc.h line 27

Quoted 12 lines
include/linux/sys_soc.h new file +12 -0
+ * @attr: export's sysdev class attribute
+ */
+struct sys_soc_info {
+	char *name;
+	char *info;
+	char *(*get_info)(struct sys_soc_info *);
+	struct sysdev_class_attribute attr;
+};
+
+/**
+ * void register_sys_soc(char *name, struct sys_soc_info *, int num)
+ * @name: name of the machine

This is not really descriptive enough. We need to be reasonably clear about what we mean by 'name'. Is it the mach name (i.e. the name of the mach-xxxx) directory, is it the family (i.e. omap3 and omap4 are both under omap), or is it something else?

include/linux/sys_soc.h line 30

Quoted 3 lines
include/linux/sys_soc.h new file +3 -0
+ * @info: pointer on the info table to export
+ * @num: number of info to export
+ */

Need to document here that register_sys_soc must only be called once.

include/linux/sys_soc.h line 33

Quoted 3 lines
include/linux/sys_soc.h new file +3 -0
+void register_sys_soc(char *name, struct sys_soc_info *info, int num);
+
+#endif /* __SYS_SOC_H */

~Ryan

Signature · 7 lines
Bluewater Systems Ltd - ARM Technology Solution Centre

Ryan Mallon         		5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com         	PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com	New Zealand
Phone: +64 3 3779127		Freecall: Australia 1800 148 751
Fax:   +64 3 3779135			  USA 1800 261 2934
#28 lore raw

RFC PATCH 2/2 ux500: Export U8500 SoC info through sysfs

In reply to Maxime Coquelin

ST-Ericsson's U8500 implementation.
Register sysfs SoC interface, and export SoC ID, process and silicon revision number.

---
 arch/arm/mach-ux500/id.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)
arch/arm/mach-ux500/id.c +96 -0
index d35122e..0d41c77 100644
@@ -8,6 +8,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
 
 #include <asm/cputype.h>
 #include <asm/tlbflush.h>
@@ -105,3 +107,97 @@ void __init ux500_map_io(void)
 
 	ux500_print_soc_info(asicid);
 }
+
+
+#ifdef CONFIG_SYS_SOC
+#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0)
+#define U8500_BB_UID_LENGTH 5
+
+#define UX500_SOC_INFO_SZ 64
+
+static char soc_id[UX500_SOC_INFO_SZ];
+static char revision[UX500_SOC_INFO_SZ];
+static char process[UX500_SOC_INFO_SZ];
+
+static char *ux500_get_soc_id(struct sys_soc_info *si)
+{
+	void __iomem *uid_base = __io_address(U8500_BB_UID_BASE);
+	int i, sz = 0;
+
+	if (dbx500_partnumber() == 0x8500) {
+		for (i = 0; i < U8500_BB_UID_LENGTH; i++)
+			sz += snprintf(soc_id + sz, UX500_SOC_INFO_SZ - sz, "%08x",
+					readl(uid_base + i * sizeof(u32)));
+	}
+	else {
+		/* Don't know where it is located for U5500 */
+		sprintf(soc_id, "N/A");
+	}
+
+	/*
+	 * As this key will never change, no need to read it anymore.
+	 */
+	si->info = soc_id;
+	return soc_id;
+}
+
+static char *ux500_get_revision(struct sys_soc_info *si)
+{
+	unsigned int rev = dbx500_revision();
+
+	if (rev == 0x01)
+		sprintf(revision, "%s", "ED");
+	else if (rev >= 0xA0)
+		sprintf(revision, "%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf);
+	else
+		sprintf(revision, "%s", "Unknown");
+
+	/*
+	 * As this key will never change, no need to read it anymore.
+	 */
+	si->info = revision;
+	return revision;
+}
+
+static char *ux500_get_process(struct sys_soc_info *si)
+{
+	if (dbx500_id.process == 0x00)
+		sprintf(process, "Standard");
+	else
+		sprintf(process, "%02xnm", dbx500_id.process);
+
+	/*
+	 * As this key will never change, no need to read it anymore.
+	 */
+	si->info = process;
+	return process;
+}
+
+static struct sys_soc_info soc_info[] = {
+	[0] = {
+		.name = "soc_id",
+		.get_info = ux500_get_soc_id,
+	},
+	[1] = {
+		.name = "revision",
+		.get_info = ux500_get_revision,
+	},
+	[2] = {
+		.name = "process",
+		.get_info = ux500_get_process,
+	},
+};
+
+static int __init ux500_sys_soc_init(void)
+{
+	char part_number[8];
+
+	sprintf(part_number, "DB%4x", dbx500_partnumber());
+	register_sys_soc(part_number, soc_info, ARRAY_SIZE(soc_info));
+
+	return 0;
+}
+
+module_init(ux500_sys_soc_init);
+#endif
+
Signature · 1 line
1.7.1
#29 lore raw

RFC PATCH 2/2 ux500: Export U8500 SoC info through sysfs

Quoted 5 lines · On Wednesday 09 March 2011 17:59:21 Maxime Coquelin wrote:

ST-Ericsson's U8500 implementation.
Register sysfs SoC interface, and export SoC ID, process and silicon revision number.

arch/arm/mach-ux500/id.c +1 -0
+static char *ux500_get_soc_id(struct sys_soc_info *si)

arch/arm/mach-ux500/id.c void __init ux500_map_io(void) · line 163

Quoted 10 lines
arch/arm/mach-ux500/id.c +8 -0
+{
+	void __iomem *uid_base = __io_address(U8500_BB_UID_BASE);
 
+static char *ux500_get_revision(struct sys_soc_info *si)
+{
+	unsigned int rev = dbx500_revision();
 
+
+static char *ux500_get_process(struct sys_soc_info *si)
+{

These should all just be attributes of the platform device that represents your SoC.

Arnd

#30 lore raw

cover Export SoC info through sysfs

In reply to Maxime Coquelin

Hi,

Back after long silent :-)

Quoted 4 lines · ext Maxime Coquelin

Here is the first version of the proposal to export SoC related information to user-space through sysFS interface.

This serie is to continue what has been discussed on the "socinfo" thread created by Eduardo Valentin:
https://lkml.org/lkml/2010/5/11/364

Thanks for taking this further. Looks much more promising now :-).

Quoted 3 lines

The first patch introduces the common part, which provides an interface to the platform to register its name, and exports platform-defined IDs to user-space. The IDs strings can be provided in two ways: either with a pointer to the string, or by a callback returning the string.

Do you mind refreshing my memory why we need two ways of providing data to these attributes? I mean, I think if we provide the attribute value during registration time should be enough and simpler.

Unless you guys are talking about attributes with changes over the time, I don't really see the need for the callback there. At least from the original scope, I don't see any attributes which would be exported under soc info which would change over the time.

Or am I missing something?

Quoted 40 lines

The second patch is given as example for the ux500 architecture. It registers with the machine name "DB8500", and exports 3 informations (SoC unique ID, sili con revision and silicon process).

Here is the output for DB8500:
root at ME:/sys/devices/system/soc ls -l

(quoted diff) +0 -4
-r--r--r--    1 root     root         4096 Jan 11 02:43 mach_name
-r--r--r--    1 root     root         4096 Jan 11 02:43 process
-r--r--r--    1 root     root         4096 Jan 11 02:43 revision
-r--r--r--    1 root     root         4096 Jan 11 02:43 soc_id

root at ME:/sys/devices/system/soc cat mach_name
DB8500
root at ME:/sys/devices/system/soc cat process
Standard
root at ME:/sys/devices/system/soc cat revision
2.0
root at ME:/sys/devices/system/soc cat soc_id
2ba07ce9e5835d6185321e9577462ef2ea2129cf

Any comments are welcome.

Note that I will be off from 13th to 21th of March.

Regards,
Maxime

-------------------------------------------------------------------------------

Maxime Coquelin (2):
Export SoC info through sysfs
ux500: Export U8500 SoC info through sysfs

 arch/arm/mach-ux500/id.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/base/Kconfig     |    4 ++
 drivers/base/Makefile    |    1 +
 drivers/base/soc.c       |   88 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/sys_soc.h  |   33 ++++++++++++++++
 5 files changed, 222 insertions(+), 0 deletions(-)
 create mode 100644 drivers/base/soc.c
 create mode 100644 include/linux/sys_soc.h
Signature · 1 line
Eduardo Valentin
#31 lore raw

cover Export SoC info through sysfs

Hi Eduardo,

Quoted 7 lines · Eduardo Valentin
Quoted 3 lines

The first patch introduces the common part, which provides an interface to the platform to register its name, and exports platform-defined IDs to user-space. The IDs strings can be provided in two ways: either with a pointer to the string, or by a callback returning the string.

Do you mind refreshing my memory why we need two ways of providing data to these attributes? I mean, I think if we provide the attribute value during registration time should be enough and simpler.

Quoted 5 lines

Unless you guys are talking about attributes with changes over the time, I don't really see the need for the callback there. At least from the original scope, I don't see any attributes which would be exported under soc info which would change over the time.

Or am I missing something?

It would be simpler indeed. But I don't know what are other SoC vendors needs, does someone need to export a piece of information which may change at runtime? If we all agree that providing a string at registration is enough, I'll remove it.