Export SoC info through sysfs
Subsystems (5)
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_id2ba07ce9e5835d6185321e9577462ef2ea2129cf
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
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
@@ -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
@@ -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
@@ -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
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.Signed-off-by Maxime COQUELIN <[email protected]>--- 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.hdrivers/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 + endmenudrivers/base/Makefile +1
-0@@ -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) := -DDEBUGdrivers/base/soc.c new file +7
-0@@ -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@@ -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/
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 ofsi->infoorsi->get_infois 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_infocallback?
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
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Maxime Coquelindrivers/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.
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 + endmenuWould 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 theget_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
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.
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.
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Maxime CoquelinQuoted 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.Signed-off-by Maxime COQUELIN <[email protected]>--- 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
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
Signed-off-by Maxime COQUELIN<[email protected]>--- 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_EMBEDDEDis 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
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Arnd Bergmann2011/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
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/systemcontain these more neutral things:
/sys/devices/systemls
clocksource cpu timekeeping timerIMHO 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.
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
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.
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
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!
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
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Russell King - ARM LinuxQuoted 1 line · Russell King - ARM Linux
Who ever thought about putting a UART behind I2C ? That's insane!
Maxim MAX 3107
http://www.maxim-ic.com/datasheet/index.mvp/id/6463
The advantage is that you can have 8 of them on I2C and hundreds on SPI (which is insane ;-) )
Helmut
--
Scanned by MailScanner.
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Arnd BergmannQuoted 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.
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
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 :)
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
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Linus WalleijQuoted 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/platformlsab8500-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/deviceslsplatform sdi0 sdi4 system uart1 virtual rtc-pl031 sdi2 ssp0 uart0 uart2The 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
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/pci0and/sys/devices/amba0instead 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/devicesis 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
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/pci0and/sys/devices/amba0instead 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/socinfowith 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/devicesis 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
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
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-nodeThen 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-nodeOr 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
RFC PATCH 1/2 Export SoC info through sysfs
In reply to Maxime CoquelinQuoted 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
Signed-off-by Maxime COQUELIN <[email protected]>--- 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.hdrivers/base/Kconfig +0
-0
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+ endmenudrivers/base/Makefile +1
-0@@ -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) := -DDEBUGdrivers/base/soc.c new file +23
-0@@ -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@@ -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
RFC PATCH 2/2 ux500: Export U8500 SoC info through sysfs
In reply to Maxime CoquelinST-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
@@ -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
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
cover Export SoC info through sysfs
In reply to Maxime CoquelinHi,
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_idroot 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 catsoc_id2ba07ce9e5835d6185321e9577462ef2ea2129cfAny 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 sysfsarch/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
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.