summary refs log tree commit diff
path: root/drivers/soc
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-08-17 16:42:17 +0200
committerThierry Reding <treding@nvidia.com>2017-08-17 16:43:13 +0200
commit27a0342ac162bf2ba30c288cfb7b72eabed38d8b (patch)
tree48f4e7d789054b3dd4235bd89ccb76aad84d398e /drivers/soc
parent0c106e57dea709395b5b5eb004987b7ddad251ad (diff)
downloadlinux-27a0342ac162bf2ba30c288cfb7b72eabed38d8b.tar.gz
soc/tegra: Register SoC device
Move this code from arch/arm/mach-tegra and make it common among 32-bit
and 64-bit Tegra SoCs. This is slightly complicated by the fact that on
32-bit Tegra, the SoC device is used as the parent for all devices that
are instantiated from device tree.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/tegra/Kconfig5
-rw-r--r--drivers/soc/tegra/fuse/fuse-tegra.c48
2 files changed, 51 insertions, 2 deletions
diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig
index 1beb7c347344..e9e277178c94 100644
--- a/drivers/soc/tegra/Kconfig
+++ b/drivers/soc/tegra/Kconfig
@@ -107,6 +107,11 @@ config ARCH_TEGRA_186_SOC
 endif
 endif
 
+config SOC_TEGRA_FUSE
+	def_bool y
+	depends on ARCH_TEGRA
+	select SOC_BUS
+
 config SOC_TEGRA_FLOWCTRL
 	bool
 
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index 7413f60fa855..e4f78de8f95f 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -19,10 +19,12 @@
 #include <linux/device.h>
 #include <linux/kobject.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
 
 #include <soc/tegra/common.h>
 #include <soc/tegra/fuse.h>
@@ -210,6 +212,31 @@ static void tegra_enable_fuse_clk(void __iomem *base)
 	writel(reg, base + 0x14);
 }
 
+struct device * __init tegra_soc_device_register(void)
+{
+	struct soc_device_attribute *attr;
+	struct soc_device *dev;
+
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return NULL;
+
+	attr->family = kasprintf(GFP_KERNEL, "Tegra");
+	attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
+	attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
+
+	dev = soc_device_register(attr);
+	if (IS_ERR(dev)) {
+		kfree(attr->soc_id);
+		kfree(attr->revision);
+		kfree(attr->family);
+		kfree(attr);
+		return ERR_CAST(dev);
+	}
+
+	return soc_device_to_device(dev);
+}
+
 static int __init tegra_init_fuse(void)
 {
 	const struct of_device_id *match;
@@ -311,6 +338,23 @@ static int __init tegra_init_fuse(void)
 	pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
 		 tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
 
+
 	return 0;
 }
 early_initcall(tegra_init_fuse);
+
+#ifdef CONFIG_ARM64
+static int __init tegra_init_soc(void)
+{
+	struct device *soc;
+
+	soc = tegra_soc_device_register();
+	if (IS_ERR(soc)) {
+		pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc));
+		return PTR_ERR(soc);
+	}
+
+	return 0;
+}
+device_initcall(tegra_init_soc)
+#endif