Commit 352bfbb3 authored by Krzysztof Kozlowski's avatar Krzysztof Kozlowski
Browse files

soc: samsung: exynos-chipid: convert to driver and merge exynos-asv



The Exynos Chip ID driver on Exynos SoCs has so far only informational
purpose - to expose the SoC device in sysfs.  No other drivers depend on
it so there is really no benefit of initializing it early.

The code would be the most flexible if converted to a regular driver.
However there is already another driver - Exynos ASV (Adaptive Supply
Voltage) - which binds to the device node of Chip ID.

The solution is to convert the Exynos Chip ID to a built in driver and
merge the Exynos ASV into it.

This has several benefits:
1. Although the Exynos ASV driver binds to a device node present in all
   Exynos DTS (generic compatible), it fails to probe except on the
   supported ones (only Exynos5422).  This means that the regular boot
   process has a planned/normal device probe failure.

   Merging the ASV into Chip ID will remove this probe failure because
   the final driver will always bind, just with disabled ASV features.

2. Allows to use dev_info() as the SoC bus is present (since
   core_initcall).

3. Could speed things up because of execution of Chip ID code in a SMP
   environment (after bringing up secondary CPUs, unlike early_initcall),
   This reduces the amount of work to be done early, when the kernel has
   to bring up critical devices.

5. Makes the Chip ID code defer-probe friendly,

Signed-off-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
Link: https://lore.kernel.org/r/20201207190517.262051-5-krzk@kernel.org


Reviewed-by: default avatarPankaj Dubey <pankaj.dubey@samsung.com>
parent 4561560d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ menuconfig ARCH_EXYNOS
	select ARM_GIC
	select EXYNOS_IRQ_COMBINER
	select COMMON_CLK_SAMSUNG
	select EXYNOS_ASV
	select EXYNOS_CHIPID
	select EXYNOS_THERMAL
	select EXYNOS_PMU
+5 −7
Original line number Diff line number Diff line
@@ -7,21 +7,19 @@ menuconfig SOC_SAMSUNG

if SOC_SAMSUNG

config EXYNOS_ASV
	bool "Exynos Adaptive Supply Voltage support" if COMPILE_TEST
	depends on (ARCH_EXYNOS && EXYNOS_CHIPID) || COMPILE_TEST
	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS

# There is no need to enable these drivers for ARMv8
config EXYNOS_ASV_ARM
	bool "Exynos ASV ARMv7-specific driver extensions" if COMPILE_TEST
	depends on EXYNOS_ASV
	depends on EXYNOS_CHIPID

config EXYNOS_CHIPID
	bool "Exynos Chipid controller driver" if COMPILE_TEST
	bool "Exynos ChipID controller and ASV driver" if COMPILE_TEST
	depends on ARCH_EXYNOS || COMPILE_TEST
	select EXYNOS_ASV_ARM if ARM && ARCH_EXYNOS
	select MFD_SYSCON
	select SOC_BUS
	help
	  Support for Samsung Exynos SoC ChipID and Adaptive Supply Voltage.

config EXYNOS_PMU
	bool "Exynos PMU controller driver" if COMPILE_TEST
+1 −2
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

obj-$(CONFIG_EXYNOS_ASV)	+= exynos-asv.o
obj-$(CONFIG_EXYNOS_ASV_ARM)	+= exynos5422-asv.o

obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o exynos-asv.o
obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o

obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
+11 −34
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@
/*
 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
 *	      http://www.samsung.com/
 * Copyright (c) 2020 Krzysztof Kozlowski <krzk@kernel.org>
 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
 * Author: Krzysztof Kozlowski <krzk@kernel.org>
 *
 * Samsung Exynos SoC Adaptive Supply Voltage support
 */
@@ -10,12 +12,7 @@
#include <linux/cpu.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
#include <linux/regmap.h>
#include <linux/soc/samsung/exynos-chipid.h>
@@ -111,7 +108,7 @@ static int exynos_asv_update_opps(struct exynos_asv *asv)
	return	0;
}

static int exynos_asv_probe(struct platform_device *pdev)
int exynos_asv_init(struct device *dev, struct regmap *regmap)
{
	int (*probe_func)(struct exynos_asv *asv);
	struct exynos_asv *asv;
@@ -119,21 +116,16 @@ static int exynos_asv_probe(struct platform_device *pdev)
	u32 product_id = 0;
	int ret, i;

	asv = devm_kzalloc(&pdev->dev, sizeof(*asv), GFP_KERNEL);
	asv = devm_kzalloc(dev, sizeof(*asv), GFP_KERNEL);
	if (!asv)
		return -ENOMEM;

	asv->chipid_regmap = device_node_to_regmap(pdev->dev.of_node);
	if (IS_ERR(asv->chipid_regmap)) {
		dev_err(&pdev->dev, "Could not find syscon regmap\n");
		return PTR_ERR(asv->chipid_regmap);
	}

	asv->chipid_regmap = regmap;
	asv->dev = dev;
	ret = regmap_read(asv->chipid_regmap, EXYNOS_CHIPID_REG_PRO_ID,
			  &product_id);
	if (ret < 0) {
		dev_err(&pdev->dev, "Cannot read revision from ChipID: %d\n",
			ret);
		dev_err(dev, "Cannot read revision from ChipID: %d\n", ret);
		return -ENODEV;
	}

@@ -142,7 +134,9 @@ static int exynos_asv_probe(struct platform_device *pdev)
		probe_func = exynos5422_asv_init;
		break;
	default:
		return -ENODEV;
		dev_dbg(dev, "No ASV support for this SoC\n");
		devm_kfree(dev, asv);
		return 0;
	}

	cpu_dev = get_cpu_device(0);
@@ -150,14 +144,11 @@ static int exynos_asv_probe(struct platform_device *pdev)
	if (ret < 0)
		return -EPROBE_DEFER;

	ret = of_property_read_u32(pdev->dev.of_node, "samsung,asv-bin",
	ret = of_property_read_u32(dev->of_node, "samsung,asv-bin",
				   &asv->of_bin);
	if (ret < 0)
		asv->of_bin = -EINVAL;

	asv->dev = &pdev->dev;
	dev_set_drvdata(&pdev->dev, asv);

	for (i = 0; i < ARRAY_SIZE(asv->subsys); i++)
		asv->subsys[i].asv = asv;

@@ -167,17 +158,3 @@ static int exynos_asv_probe(struct platform_device *pdev)

	return exynos_asv_update_opps(asv);
}

static const struct of_device_id exynos_asv_of_device_ids[] = {
	{ .compatible = "samsung,exynos4210-chipid" },
	{}
};

static struct platform_driver exynos_asv_driver = {
	.driver = {
		.name = "exynos-asv",
		.of_match_table = exynos_asv_of_device_ids,
	},
	.probe	= exynos_asv_probe,
};
module_platform_driver(exynos_asv_driver);
+2 −0
Original line number Diff line number Diff line
@@ -68,4 +68,6 @@ static inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *s
	return __asv_get_table_entry(&subsys->table, level, 0);
}

int exynos_asv_init(struct device *dev, struct regmap *regmap);

#endif /* __LINUX_SOC_EXYNOS_ASV_H */
Loading