This patch is to add Altera System ID driver.
User can obtain the system ID and timestamp of the system by
reading the sysfs entry.
Usage:
cat /sys/bus/platform/devices/[addr].sysid/sysid/id
cat /sys/bus/platform/devices/[addr].sysid/sysid/timestamp
Signed-off-by: Ley Foon Tan <[email protected]>
---
.../devicetree/bindings/misc/altera_sysid.txt | 18 +++
drivers/misc/Kconfig | 6 +
drivers/misc/Makefile | 3 +-
drivers/misc/altera_sysid.c | 142 ++++++++++++++++++++
4 files changed, 168 insertions(+), 1 deletions(-)
create mode 100644 Documentation/devicetree/bindings/misc/altera_sysid.txt
create mode 100644 drivers/misc/altera_sysid.c
diff --git a/Documentation/devicetree/bindings/misc/altera_sysid.txt b/Documentation/devicetree/bindings/misc/altera_sysid.txt
new file mode 100644
index 0000000..463dc15
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/altera_sysid.txt
@@ -0,0 +1,18 @@
+Altera Sysid IP core driver
+
+Required properties:
+- compatible: altr,sysid-1.0
+
+Optional properties:
+- id: A unique 32-bit value that is based on the contents of the system.
+- timestamp: A unique 32-bit value that is based on the system generation time.
+
+Example:
+
+sysid_qsys: sysid@0x10000 {
+ compatible = "altr,sysid-1.0";
+ reg = < 0x10000 0x00000008 >;
+ id = < 1 >;
+ timestamp = < 1359538782 >;
+};
+
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e83fdfe..0e783af 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -510,6 +510,12 @@ config LATTICE_ECP3_CONFIG
If unsure, say N.
+config ALTERA_SYSID
+ tristate "Altera System ID"
+ help
+ This enables Altera System ID soft core driver.
+
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 35a1463..dc7142d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,7 +47,8 @@ obj-y += ti-st/
obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
-obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+obj-$(CONFIG_ALTERA_STAPL) += altera-stapl/
+obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
diff --git a/drivers/misc/altera_sysid.c b/drivers/misc/altera_sysid.c
new file mode 100644
index 0000000..7472a4b
--- /dev/null
+++ b/drivers/misc/altera_sysid.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Credit:
+ * Walter Goossens
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#define DRV_NAME "altera_sysid"
+
+struct altera_sysid {
+ void __iomem *regs;
+};
+
+/* System ID Registers*/
+#define SYSID_REG_ID (0x0)
+#define SYSID_REG_TIMESTAMP (0x4)
+
+static ssize_t altera_sysid_show_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct altera_sysid *sysid = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", readl(sysid->regs + SYSID_REG_ID));
+}
+
+static ssize_t altera_sysid_show_timestamp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned int reg;
+ struct tm timestamp;
+ struct altera_sysid *sysid = dev_get_drvdata(dev);
+
+ reg = readl(sysid->regs + SYSID_REG_TIMESTAMP);
+
+ time_to_tm(reg, 0, ×tamp);
+
+ return sprintf(buf, "%u (%u-%u-%u %u:%u:%u UTC)\n", reg,
+ (unsigned int)(timestamp.tm_year + 1900),
+ timestamp.tm_mon + 1, timestamp.tm_mday, timestamp.tm_hour,
+ timestamp.tm_min, timestamp.tm_sec);
+}
+
+static DEVICE_ATTR(id, S_IRUGO, altera_sysid_show_id, NULL);
+static DEVICE_ATTR(timestamp, S_IRUGO, altera_sysid_show_timestamp, NULL);
+
+static struct attribute *altera_sysid_attrs[] = {
+ &dev_attr_id.attr,
+ &dev_attr_timestamp.attr,
+ NULL,
+};
+
+struct attribute_group altera_sysid_attr_group = {
+ .name = "sysid",
+ .attrs = altera_sysid_attrs,
+};
+
+static int altera_sysid_probe(struct platform_device *pdev)
+{
+ struct altera_sysid *sysid;
+ struct resource *regs;
+
+ sysid = devm_kzalloc(&pdev->dev, sizeof(struct altera_sysid),
+ GFP_KERNEL);
+ if (!sysid)
+ return -ENOMEM;
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!regs)
+ return -ENXIO;
+
+ sysid->regs = devm_request_and_ioremap(&pdev->dev, regs);
+ if (!sysid->regs)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, sysid);
+
+ return sysfs_create_group(&pdev->dev.kobj, &altera_sysid_attr_group);
+}
+
+static int __exit altera_sysid_remove(struct platform_device *pdev)
+{
+ sysfs_remove_group(&pdev->dev.kobj, &altera_sysid_attr_group);
+
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static const struct of_device_id altera_sysid_match[] = {
+ { .compatible = "altr,sysid-1.0" },
+ { /* Sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, altera_sysid_match);
+
+static struct platform_driver altera_sysid_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = altera_sysid_match,
+ },
+ .remove = __exit_p(altera_sysid_remove),
+};
+
+static int __init altera_sysid_init(void)
+{
+ return platform_driver_probe(&altera_sysid_platform_driver,
+ altera_sysid_probe);
+}
+
+static void __exit altera_sysid_exit(void)
+{
+ platform_driver_unregister(&altera_sysid_platform_driver);
+}
+
+module_init(altera_sysid_init);
+module_exit(altera_sysid_exit);
+
+MODULE_AUTHOR("Ley Foon Tan");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Altera System ID driver");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.7.7.4
On Monday 04 March 2013, Ley Foon Tan wrote:
> This patch is to add Altera System ID driver.
> User can obtain the system ID and timestamp of the system by
> reading the sysfs entry.
>
> Usage:
> cat /sys/bus/platform/devices/[addr].sysid/sysid/id
> cat /sys/bus/platform/devices/[addr].sysid/sysid/timestamp
>
> Signed-off-by: Ley Foon Tan <[email protected]>
All sysfs files need documentation in Documentation/ABI/.
This driver looks like it should instead be using the infrastructure we
have for identifying an SoC in drivers/base/soc.c, which is currently
only used by the ARM u8500 platform but was introduced as a generic
interface for this a while ago.
Arnd
On Mon, Mar 04, 2013 at 03:32:19AM +0000, Arnd Bergmann wrote:
> On Monday 04 March 2013, Ley Foon Tan wrote:
> > This patch is to add Altera System ID driver.
> > User can obtain the system ID and timestamp of the system by
> > reading the sysfs entry.
> >
> > Usage:
> > cat /sys/bus/platform/devices/[addr].sysid/sysid/id
> > cat /sys/bus/platform/devices/[addr].sysid/sysid/timestamp
> >
> > Signed-off-by: Ley Foon Tan <[email protected]>
>
> All sysfs files need documentation in Documentation/ABI/.
>
> This driver looks like it should instead be using the infrastructure we
> have for identifying an SoC in drivers/base/soc.c, which is currently
> only used by the ARM u8500 platform but was introduced as a generic
> interface for this a while ago.
I agree, this shouldn't be a one-off sysfs file.
greg k-h
On Mon, 2013-03-04 at 11:44 +0800, Greg Kroah-Hartman wrote:
> On Mon, Mar 04, 2013 at 03:32:19AM +0000, Arnd Bergmann wrote:
> > On Monday 04 March 2013, Ley Foon Tan wrote:
> > > This patch is to add Altera System ID driver.
> > > User can obtain the system ID and timestamp of the system by
> > > reading the sysfs entry.
> > >
> > > Usage:
> > > cat /sys/bus/platform/devices/[addr].sysid/sysid/id
> > > cat /sys/bus/platform/devices/[addr].sysid/sysid/timestamp
> > >
> > > Signed-off-by: Ley Foon Tan <[email protected]>
> >
> > All sysfs files need documentation in Documentation/ABI/.
Okay, I will add document in this directory.
> >
> > This driver looks like it should instead be using the infrastructure we
> > have for identifying an SoC in drivers/base/soc.c, which is currently
> > only used by the ARM u8500 platform but was introduced as a generic
> > interface for this a while ago.
>
> I agree, this shouldn't be a one-off sysfs file.
>
> greg k-h
>
This IP core is not in the SoC. This core is in the FPGA and can be
accessed by the Nios II processor or accessed by SOCFPGA processor (ARM
based) via its interface to FPGA. Due to this, I think it shouldn't use
infrastructure in drivers/base/soc.c.
What do you think?
Thanks for the comments.
lftan
On Monday 04 March 2013, Ley Foon Tan wrote:
> This IP core is not in the SoC. This core is in the FPGA and can be
> accessed by the Nios II processor or accessed by SOCFPGA processor (ARM
> based) via its interface to FPGA. Due to this, I think it shouldn't use
> infrastructure in drivers/base/soc.c.
> What do you think?
The sysid component gives a version for the entire FPGA part and all
components inside it, right?
I think you should use the drivers/base/soc.c interface to describe the
SOCFPGA SoC components as well as the actual FPGA. You basically
end up having one device node that acts as the parent for the SoC
components, and a way to retrieve version information about it.
Depending on how it fits the actual hardware layout more closely,
you could have one node as the parent for all devices, or the
FPGA SoC node as a child of the main one, or two SoC nodes side by
side from the top-level.
Arnd
On Mon, 2013-03-04 at 12:55 +0000, Arnd Bergmann wrote:
> On Monday 04 March 2013, Ley Foon Tan wrote:
> > This IP core is not in the SoC. This core is in the FPGA and can be
> > accessed by the Nios II processor or accessed by SOCFPGA processor (ARM
> > based) via its interface to FPGA. Due to this, I think it shouldn't use
> > infrastructure in drivers/base/soc.c.
> > What do you think?
>
> The sysid component gives a version for the entire FPGA part and all
> components inside it, right?
>
> I think you should use the drivers/base/soc.c interface to describe the
> SOCFPGA SoC components as well as the actual FPGA. You basically
> end up having one device node that acts as the parent for the SoC
> components, and a way to retrieve version information about it.
>
> Depending on how it fits the actual hardware layout more closely,
> you could have one node as the parent for all devices, or the
> FPGA SoC node as a child of the main one, or two SoC nodes side by
> side from the top-level.
>
> Arnd
>
The sysid give the unique system ID and system generation timestamp of
the system.
CASE 1:
SOCFPGA SoC + Sysid component in FPGA
CASE 2
Nios II soft core CPU + Sysid (All in FPGA and no SoC is involved)
>From example use cases above, Case 2 doesn't involve SoC component.
To support both cases, do you think drivers/base/soc.c is still
suitable?
Thanks.
LFTan
On Tuesday 05 March 2013, Ley Foon Tan wrote:
> The sysid give the unique system ID and system generation timestamp of
> the system.
>
> CASE 1:
> SOCFPGA SoC + Sysid component in FPGA
>
> CASE 2
> Nios II soft core CPU + Sysid (All in FPGA and no SoC is involved)
>
> From example use cases above, Case 2 doesn't involve SoC component.
> To support both cases, do you think drivers/base/soc.c is still
> suitable?
Yes, I think so. I would consider the second case still a SoC, because
you have a single chip that contains the CPU and peripherals. From
the OS point of view, it does not matter that they are in an FPGA.
Arnd
On Tue, 2013-03-05 at 21:59 +0000, Arnd Bergmann wrote:
> On Tuesday 05 March 2013, Ley Foon Tan wrote:
> > The sysid give the unique system ID and system generation timestamp of
> > the system.
> >
> > CASE 1:
> > SOCFPGA SoC + Sysid component in FPGA
> >
> > CASE 2
> > Nios II soft core CPU + Sysid (All in FPGA and no SoC is involved)
> >
> > From example use cases above, Case 2 doesn't involve SoC component.
> > To support both cases, do you think drivers/base/soc.c is still
> > suitable?
>
> Yes, I think so. I would consider the second case still a SoC, because
> you have a single chip that contains the CPU and peripherals. From
> the OS point of view, it does not matter that they are in an FPGA.
>
> Arnd
Thanks for your input. I will go with your suggestion.
LFTan