Skip to content

Commit

Permalink
drivers: misc: intel_sysid: Add sysid from arch to drivers
Browse files Browse the repository at this point in the history
Add new sysid driver. The Altera(Intel) Sysid component is generally part
of an FPGA design. The component can be hotplugged when the FPGA is
reconfigured. This driver support the component being hotplugged.
The sysid driver stores unique 32-bit id value which is similar to a
check-sum value; different components, different configuration options,
or both, can be configured to produce different id values. Timestamp field
is the unique 32-bit value that is based on the system generation time.

There are two basic ways to use the system ID core:
- Verify the system ID before downloading new software to a system. This
method can be used by software development tools, before downloading a
program to a target hardware system, if the program is compiled for
different hardware.

- Check system ID after reset. If a program is running on hardware other
than the expected Platform Designer system, the program may fail to
function altogether. If the program does not crash, it can behave
erroneously in subtle ways that are difficult to debug. To protect against
this case, a program can compare the expected system ID against the system
ID core, and report an error if they do not match.

Usage:
  cat /sys/bus/platform/devices/soc:base_fpga_region/
		soc:base_fpga_region:fpga_pr_region0/[addr.sysid]/sysid/id
  cat /sys/bus/platform/devices/soc:base_fpga_region/
		soc:base_fpga_region:fpga_pr_region0/[addr.sysid]/sysid/buildtime

Based on an initial contribution from Ley Foon Tan at Altera
Signed-off-by: Kah Jing Lee <kah.jing.lee@intel.com>
Reviewed-by: Zhou, Furong <furong.zhou@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
  • Loading branch information
kahjingl90 authored and intel-lab-lkp committed Jul 21, 2022
1 parent 8af028c commit 5e0d691
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/misc/Kconfig
Expand Up @@ -483,6 +483,15 @@ config OPEN_DICE

If unsure, say N.

config INTEL_SYSID
tristate "Intel System ID"
help
This enables the Intel System ID driver for a soft core.
Say Y here if you want to build a driver for Intel System ID.

To compile this driver as a module, choose M here: the
module will be called intel_sysid. If unsure, say N here.

source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions drivers/misc/Makefile
Expand Up @@ -40,6 +40,7 @@ obj-$(CONFIG_PCH_PHUB) += pch_phub.o
obj-y += ti-st/
obj-y += lis3lv02d/
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_INTEL_SYSID) += intel_sysid.o
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
Expand Down
114 changes: 114 additions & 0 deletions drivers/misc/intel_sysid.c
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022, Intel Corporation.
* Copyright (C) 2013-2015, Altera Corporation.
*
* Ley Foon Tan <lftan@altera.com>
* Kah Jing Lee <kah.jing.lee@intel.com>
*/

#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#define DRV_NAME "intel_sysid"

struct intel_sysid {
void __iomem *regs;
};

/* System ID Registers*/
#define SYSID_REG_ID 0x0
#define SYSID_REG_TIMESTAMP 0x4

static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct intel_sysid *sysid = dev_get_drvdata(dev);

return sprintf(buf, "%u\n", readl(sysid->regs + SYSID_REG_ID));
}

static void convert_readable_timestamp(struct tm *buildtime)
{
buildtime->tm_year += 1900;
buildtime->tm_mon += 1;
}

static ssize_t buildtime_show(struct device *dev, struct device_attribute *attr, char *buf)
{
unsigned int reg;
struct tm buildtime;
struct intel_sysid *sysid = dev_get_drvdata(dev);

reg = readl(sysid->regs + SYSID_REG_TIMESTAMP);
time64_to_tm(reg, 0, &buildtime);
convert_readable_timestamp(&buildtime);

return sprintf(buf, "%u (%u-%u-%u %u:%u:%u UTC)\n", reg,
(unsigned int)(buildtime.tm_year),
buildtime.tm_mon, buildtime.tm_mday, buildtime.tm_hour,
buildtime.tm_min, buildtime.tm_sec);
}

static DEVICE_ATTR_RO(id);
static DEVICE_ATTR_RO(buildtime);

static struct attribute *intel_sysid_attrs[] = {
&dev_attr_id.attr,
&dev_attr_buildtime.attr,
NULL
};

struct attribute_group intel_sysid_attr_group = {
.name = "sysid",
.attrs = intel_sysid_attrs,
};

static int intel_sysid_probe(struct platform_device *pdev)
{
struct intel_sysid *sysid;
struct resource *regs;

sysid = devm_kzalloc(&pdev->dev, sizeof(struct intel_sysid),
GFP_KERNEL);
if (!sysid)
return -ENOMEM;

regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs)
return -ENXIO;

sysid->regs = devm_ioremap_resource(&pdev->dev, regs);
if (IS_ERR(sysid->regs))
return PTR_ERR(sysid->regs);

platform_set_drvdata(pdev, sysid);

return devm_device_add_group(&pdev->dev, &intel_sysid_attr_group);
}

static const struct of_device_id intel_sysid_match[] = {
{ .compatible = "intel,socfpga-sysid-1.0" },
{ /* Sentinel */ }
};

MODULE_DEVICE_TABLE(of, intel_sysid_match);

static struct platform_driver intel_sysid_platform_driver = {
.driver = {
.name = DRV_NAME,
.of_match_table = of_match_ptr(intel_sysid_match),
},
.probe = intel_sysid_probe,
};

module_platform_driver(intel_sysid_platform_driver);

MODULE_AUTHOR("Kah Jing Lee <kah.jing.lee@intel.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Intel System ID driver");
MODULE_ALIAS("platform:" DRV_NAME);

0 comments on commit 5e0d691

Please sign in to comment.