From patchwork Wed Aug 10 13:03:39 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 1053632 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7AD4Cfv006434 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 10 Aug 2011 13:04:34 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qr8S7-0007dF-DX; Wed, 10 Aug 2011 13:04:07 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Qr8S6-0002wX-UC; Wed, 10 Aug 2011 13:04:06 +0000 Received: from mail-wy0-f177.google.com ([74.125.82.177]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qr8S1-0002wD-K6 for linux-arm-kernel@lists.infradead.org; Wed, 10 Aug 2011 13:04:04 +0000 Received: by wyh11 with SMTP id 11so843620wyh.36 for ; Wed, 10 Aug 2011 06:03:57 -0700 (PDT) Received: by 10.227.10.201 with SMTP id q9mr2163169wbq.68.1312981437413; Wed, 10 Aug 2011 06:03:57 -0700 (PDT) Received: from localhost.localdomain (cpc2-aztw13-0-0-cust146.aztw.cable.virginmedia.com [77.99.12.147]) by mx.google.com with ESMTPS id et16sm741790wbb.19.2011.08.10.06.03.56 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 10 Aug 2011 06:03:56 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, arnd@arndb.de Subject: [PATCH 1/4] Framework for exporting System-on-Chip information via sysfs Date: Wed, 10 Aug 2011 14:03:39 +0100 Message-Id: <1312981422-13294-1-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 1.7.4.1 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110810_090401_929066_F6604795 X-CRM114-Status: GOOD ( 19.29 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.177 listed in list.dnswl.org] Cc: gregkh@suse.de, lee.jones@linaro.org, linus.walleij@stericsson.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Wed, 10 Aug 2011 13:04:34 +0000 (UTC) This patch introduces a new driver to drivers/base. The driver provides a means to export vital SoC data out to userspace via sysfs. Standard information applicable to all SoCs are exported to: /sys/devices/soc/[1|2|3|...]/[family|machine|revision|soc_id]. It is possible to create SoC specific items via the soc_parent, which is returned post-registration, although this should be discouraged. Signed-off-by: Lee Jones --- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/sys_soc.h | 41 ++++++++++++++++++ 4 files changed, 149 insertions(+), 0 deletions(-) create mode 100644 drivers/base/soc.c create mode 100644 include/linux/sys_soc.h diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index d57e8d0..372ef3a 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -168,4 +168,7 @@ config SYS_HYPERVISOR bool default n +config SYS_SOC + bool + endmenu diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 4c5701c..a0d246d 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -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 diff --git a/drivers/base/soc.c b/drivers/base/soc.c new file mode 100644 index 0000000..05944ef --- /dev/null +++ b/drivers/base/soc.c @@ -0,0 +1,104 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Lee Jones for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(register_lock); +static int soc_count = 0; + +static struct device soc_grandparent = { + .init_name = "soc", +}; + +static ssize_t soc_info_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct soc_device *soc_dev = dev->platform_data; + + if (!strncmp(attr->attr.name, "machine", 7)) + return sprintf(buf, "%s\n", soc_dev->machine); + if (!strncmp(attr->attr.name, "family", 6)) + return sprintf(buf, "%s\n", soc_dev->family); + if (!strncmp(attr->attr.name, "soc_id", 6)) + return sprintf(buf, "%s\n", soc_dev->soc_id); + if (!strncmp(attr->attr.name, "revision", 8)) + return sprintf(buf, "%s\n", soc_dev->revision); + + return sprintf(buf, "Unknown attribute name - %s\n", attr->attr.name); +} + +struct device_attribute soc_attrs[] = { + __ATTR(machine, S_IRUGO, soc_info_get, NULL), + __ATTR(family, S_IRUGO, soc_info_get, NULL), + __ATTR(soc_id, S_IRUGO, soc_info_get, NULL), + __ATTR(revision, S_IRUGO, soc_info_get, NULL), + __ATTR_NULL, +}; + +static void __exit soc_device_remove_files(struct device *soc) +{ + int i = 0; + + while (soc_attrs[i++].attr.name != NULL) + device_remove_file(soc, &soc_attrs[i]); +} + +static int __init soc_device_create_files(struct device *soc) +{ + int ret = 0; + int i = 0; + + while (soc_attrs[i].attr.name != NULL) { + ret = device_create_file(soc, &soc_attrs[i++]); + if (ret) + goto out; + } + return ret; + +out: + soc_device_remove_files(soc); + return ret; +} + +int __init soc_device_register(struct device *soc_parent, + struct soc_device *soc_dev) +{ + int ret; + + spin_lock_irq(®ister_lock); + + if (!soc_count) { + /* Register top-level SoC device '/sys/devices/soc' */ + ret = device_register(&soc_grandparent); + if (ret) + { + spin_unlock_irq(®ister_lock); + return ret; + } + } + + soc_count++; + soc_parent->parent = &soc_grandparent; + dev_set_name(soc_parent, "%i", soc_count); + soc_parent->platform_data = soc_dev; + + spin_unlock_irq(®ister_lock); + + ret = device_register(soc_parent); + if (ret) + return ret; + + soc_device_create_files(soc_parent); + + return ret; +} diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h new file mode 100644 index 0000000..3de6405 --- /dev/null +++ b/include/linux/sys_soc.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Lee Jones for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ +#ifndef __SYS_SOC_H +#define __SYS_SOC_H + +#include +#include +#include + +#define MAX_SOCS 8 +#define MACHINE 0 +#define FAMILY 1 +#define SOCID 2 +#define REVISION 3 + +struct soc_device { + struct device dev; + const char *machine; + const char *family; + const char *soc_id; + const char *revision; +}; + +/** + * soc_device_register - register SoC as a device + * @soc_parent: Parent node '/sys/devices/soc/X' + * @soc_dev: SoC device specific information + */ +int soc_device_register(struct device *soc_parent, + struct soc_device *soc_dev); + +/** + * soc_device_unregister - unregister SoC as a device + * @soc_parent: Parent node '/sys/devices/soc/X' + */ +void soc_device_unregister(struct device *soc_parent); + +#endif /* __SYS_SOC_H */