diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-08-18 23:29:52 +0200 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2017-08-18 23:29:52 +0200 |
commit | f2970be50a15013a910fb556e5b9c9131e8c1bee (patch) | |
tree | 9a976e09dac9368ac965e52c259f2fd6b03bce57 | |
parent | 9da95d8f5b37a3d6a5ef6142fa16a96cc004109d (diff) | |
parent | 27a0342ac162bf2ba30c288cfb7b72eabed38d8b (diff) |
Merge tag 'tegra-for-4.14-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers
Pull "soc/tegra: Changes for v4.14-rc1" from Thierry Reding:
Contains a fix for unbalanced reference counting of device tree nodes in
the PMC-based generic power domains code.
A second change moves the SoC device registration code from its old
location in arch/arm/mach-tegra to drivers/soc/tegra so that it can be
shared between 32-bit and 64-bit ARM Tegra SoCs.
* tag 'tegra-for-4.14-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
soc/tegra: Register SoC device
soc/tegra: Fix bad of_node_put() in powergate init
-rw-r--r-- | arch/arm/mach-tegra/tegra.c | 29 | ||||
-rw-r--r-- | drivers/soc/tegra/Kconfig | 5 | ||||
-rw-r--r-- | drivers/soc/tegra/fuse/fuse-tegra.c | 48 | ||||
-rw-r--r-- | drivers/soc/tegra/pmc.c | 4 | ||||
-rw-r--r-- | include/soc/tegra/fuse.h | 2 |
5 files changed, 55 insertions, 33 deletions
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index 649e9e8c7bcc..02e712d2ea30 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -84,35 +84,8 @@ static void __init tegra_dt_init_irq(void) static void __init tegra_dt_init(void) { - struct soc_device_attribute *soc_dev_attr; - struct soc_device *soc_dev; - struct device *parent = NULL; + struct device *parent = tegra_soc_device_register(); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); - if (!soc_dev_attr) - goto out; - - soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra"); - soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", - tegra_sku_info.revision); - soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id()); - - soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr->family); - kfree(soc_dev_attr->revision); - kfree(soc_dev_attr->soc_id); - kfree(soc_dev_attr); - goto out; - } - - parent = soc_device_to_device(soc_dev); - - /* - * Finished with the static registrations now; fill in the missing - * devices - */ -out: of_platform_default_populate(NULL, NULL, parent); } 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 diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index e233dd5dcab3..0453ff6839a7 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -918,10 +918,8 @@ static void tegra_powergate_init(struct tegra_pmc *pmc, if (!np) return; - for_each_child_of_node(np, child) { + for_each_child_of_node(np, child) tegra_powergate_add(pmc, child); - of_node_put(child); - } of_node_put(np); } diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index b4c9219e7f95..9b6ea0c72117 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h @@ -65,6 +65,8 @@ int tegra_fuse_readl(unsigned long offset, u32 *value); extern struct tegra_sku_info tegra_sku_info; +struct device *tegra_soc_device_register(void); + #endif /* __ASSEMBLY__ */ #endif /* __SOC_TEGRA_FUSE_H__ */ |