linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver
@ 2014-03-14  9:30 Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 1/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe() Chanwoo Choi
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patchset support devicetree and use common ppmu driver instead of
individual code of exynos4_bus.c to remove duplicate code. Also this patchset
get the resources for busfreq from dt data by using DT helper function.
- PPMU register address
- PPMU clock
- Regulator for INT/MIF block

This patchset use SET_SYSTEM_SLEEP_PM_OPS macro intead of legacy method.
To remove power-leakage in suspend state, before entering suspend state,
disable ppmu clocks.

Changes from v2:
- Add detailed description to Documentation/devicetree/bindings/exynos4_bus.txt
  and change patch description of patch#8
- Change the sequence of patchset in patch #1 ~ #4
- Fix minor issue

Changes from v1:
- Add exynos4_bus.txt documentation for devicetree guide
- Fix probe failure if CONFIG_PM_OPP is disabled
- Fix typo and resource leak(regulator/clock/memory) when happening probe failure
- Add additionally comment for PPMU usage instead of previous PPC
- Split separate patch to remove ambiguous of patch

Chanwoo Choi (8):
  devfreq: exynos4: Fix bug of resource leak and code clean on probe()
  devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC
  devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data
  devfreq: exynos4: Add ppmu's clock control and code clean about regulator control
  devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro
  devfreq: exynos4: Fix power-leakage of clock on suspend state
  devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail
  Documentation: dt: devfreq: Add device tree binding of Exynos4
    busfreq

 .../devicetree/bindings/devfreq/exynos4_bus.txt    |  50 +++
 drivers/devfreq/Kconfig                            |   1 +
 drivers/devfreq/exynos/Makefile                    |   2 +-
 drivers/devfreq/exynos/exynos4_bus.c               | 415 ++++++++++++++-------
 4 files changed, 342 insertions(+), 126 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt

-- 
1.8.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCHv3 1/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe()
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 2/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC Chanwoo Choi
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch fix bug about resource leak when happening probe fail and code clean
to add debug message.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/exynos4_bus.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index e07b0c6..378e4bd 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -765,9 +765,6 @@ static int exynos4_bus_get_dev_status(struct device *dev,
 
 static void exynos4_bus_exit(struct device *dev)
 {
-	struct busfreq_data *data = dev_get_drvdata(dev);
-
-	devfreq_unregister_opp_notifier(dev, data->devfreq);
 }
 
 static struct devfreq_dev_profile exynos4_devfreq_profile = {
@@ -1048,8 +1045,11 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 		dev_err(dev, "Cannot determine the device id %d\n", data->type);
 		err = -EINVAL;
 	}
-	if (err)
+	if (err) {
+		dev_err(dev, "Cannot initialize busfreq table %d\n",
+			     data->type);
 		return err;
+	}
 
 	data->vdd_int = devm_regulator_get(dev, "vdd_int");
 	if (IS_ERR(data->vdd_int)) {
@@ -1086,23 +1086,39 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 	if (IS_ERR(data->devfreq))
 		return PTR_ERR(data->devfreq);
 
-	devfreq_register_opp_notifier(dev, data->devfreq);
+	/* Register opp_notifier for Exynos4 busfreq */
+	err = devfreq_register_opp_notifier(dev, data->devfreq);
+	if (err < 0) {
+		dev_err(dev, "Failed to register opp notifier\n");
+		goto err_notifier_opp;
+	}
 
+	/* Register pm_notifier for Exynos4 busfreq */
 	err = register_pm_notifier(&data->pm_notifier);
 	if (err) {
 		dev_err(dev, "Failed to setup pm notifier\n");
-		devfreq_remove_device(data->devfreq);
-		return err;
+		goto err_notifier_pm;
 	}
 
 	return 0;
+
+err_notifier_pm:
+	devfreq_unregister_opp_notifier(dev, data->devfreq);
+err_notifier_opp:
+	devfreq_remove_device(data->devfreq);
+
+	return err;
 }
 
 static int exynos4_busfreq_remove(struct platform_device *pdev)
 {
 	struct busfreq_data *data = platform_get_drvdata(pdev);
 
+	/* Unregister all of notifier chain */
 	unregister_pm_notifier(&data->pm_notifier);
+	devfreq_unregister_opp_notifier(data->dev, data->devfreq);
+
+	/* Remove devfreq instance */
 	devfreq_remove_device(data->devfreq);
 
 	return 0;
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 2/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 1/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe() Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 3/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data Chanwoo Choi
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch support DT(DeviceTree) method to probe exynos4_bus and get device
id of each Exynos4 SoC by using dt helper function.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/exynos4_bus.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index 378e4bd..2d2b44b 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -23,6 +23,7 @@
 #include <linux/devfreq.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/of.h>
 #include <linux/module.h>
 
 /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
@@ -1014,6 +1015,28 @@ unlock:
 	return NOTIFY_DONE;
 }
 
+static struct of_device_id exynos4_busfreq_id_match[] = {
+	{
+		.compatible = "samsung,exynos4210-busfreq",
+		.data = (void *)TYPE_BUSF_EXYNOS4210,
+	}, {
+		.compatible = "samsung,exynos4x12-busfreq",
+		.data = (void *)TYPE_BUSF_EXYNOS4x12,
+	},
+};
+
+static int exynos4_busfreq_get_driver_data(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+
+	match = of_match_node(exynos4_busfreq_id_match, dev->of_node);
+	if (!match)
+		return -ENODEV;
+
+	return (int) match->data;
+}
+
 static int exynos4_busfreq_probe(struct platform_device *pdev)
 {
 	struct busfreq_data *data;
@@ -1027,7 +1050,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	data->type = pdev->id_entry->driver_data;
+	data->type = exynos4_busfreq_get_driver_data(pdev);
 	data->dmc[0].hw_base = S5P_VA_DMC0;
 	data->dmc[1].hw_base = S5P_VA_DMC1;
 	data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
@@ -1151,6 +1174,7 @@ static struct platform_driver exynos4_busfreq_driver = {
 		.name	= "exynos4-busfreq",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos4_busfreq_pm,
+		.of_match_table = exynos4_busfreq_id_match,
 	},
 };
 
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 3/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 1/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe() Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 2/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 4/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control Chanwoo Choi
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch use common ppmu driver of exynos_ppmu.c driver instead of individual
function related to PPC because PPMU is integrated module with both PPC and
Bus event generator. When using PPMU to get bus performance read/write event,
exynos4_bus.c don't need to consider memory type.

And get ppmu address from dt data by using dt helper function (of_iomap).
And then this patch delete duplicate defined structure/enum.

For example,
busfreq@106A0000 {
	compatible = "samsung,exynos4x12-busfreq";
	reg = <0x106A0000 0x2000>, <0x106B0000 0x2000>;
	regs-name = "PPMU_DMC0", "PPMU_DMC1";
};

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/Makefile      |   2 +-
 drivers/devfreq/exynos/exynos4_bus.c | 234 +++++++++++++++++++----------------
 2 files changed, 129 insertions(+), 107 deletions(-)

diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile
index bfaaf5b..49bc917 100644
--- a/drivers/devfreq/exynos/Makefile
+++ b/drivers/devfreq/exynos/Makefile
@@ -1,3 +1,3 @@
 # Exynos DEVFREQ Drivers
-obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)	+= exynos_ppmu.o exynos4_bus.o
 obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)	+= exynos_ppmu.o exynos5_bus.o
diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index 2d2b44b..8ccbb31 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -24,17 +24,19 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/module.h>
 
+#include <mach/map.h>
+
+#include "exynos_ppmu.h"
+#include "exynos4_bus.h"
+
 /* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
 #ifdef CONFIG_EXYNOS_ASV
 extern unsigned int exynos_result_of_asv;
 #endif
 
-#include <mach/map.h>
-
-#include "exynos4_bus.h"
-
 #define MAX_SAFEVOLT	1200000 /* 1.2V */
 
 enum exynos4_busf_type {
@@ -45,22 +47,6 @@ enum exynos4_busf_type {
 /* Assume that the bus is saturated if the utilization is 40% */
 #define BUS_SATURATION_RATIO	40
 
-enum ppmu_counter {
-	PPMU_PMNCNT0 = 0,
-	PPMU_PMCCNT1,
-	PPMU_PMNCNT2,
-	PPMU_PMNCNT3,
-	PPMU_PMNCNT_MAX,
-};
-struct exynos4_ppmu {
-	void __iomem *hw_base;
-	unsigned int ccnt;
-	unsigned int event;
-	unsigned int count[PPMU_PMNCNT_MAX];
-	bool ccnt_overflow;
-	bool count_overflow[PPMU_PMNCNT_MAX];
-};
-
 enum busclk_level_idx {
 	LV_0 = 0,
 	LV_1,
@@ -69,6 +55,13 @@ enum busclk_level_idx {
 	LV_4,
 	_LV_END
 };
+
+enum exynos_ppmu_idx {
+	PPMU_DMC0,
+	PPMU_DMC1,
+	PPMU_END,
+};
+
 #define EX4210_LV_MAX	LV_2
 #define EX4x12_LV_MAX	LV_4
 #define EX4210_LV_NUM	(LV_2 + 1)
@@ -92,7 +85,7 @@ struct busfreq_data {
 	struct regulator *vdd_int;
 	struct regulator *vdd_mif; /* Exynos4412/4212 only */
 	struct busfreq_opp_info curr_oppinfo;
-	struct exynos4_ppmu dmc[2];
+	struct exynos_ppmu ppmu[PPMU_END];
 
 	struct notifier_block pm_notifier;
 	struct mutex lock;
@@ -102,12 +95,6 @@ struct busfreq_data {
 	unsigned int top_divtable[_LV_END];
 };
 
-struct bus_opp_table {
-	unsigned int idx;
-	unsigned long clk;
-	unsigned long volt;
-};
-
 /* 4210 controls clock of mif and voltage of int */
 static struct bus_opp_table exynos4210_busclk_table[] = {
 	{LV_0, 400000, 1150000},
@@ -525,27 +512,22 @@ static int exynos4x12_set_busclk(struct busfreq_data *data,
 	return 0;
 }
 
-
 static void busfreq_mon_reset(struct busfreq_data *data)
 {
 	unsigned int i;
 
-	for (i = 0; i < 2; i++) {
-		void __iomem *ppmu_base = data->dmc[i].hw_base;
+	for (i = 0; i < PPMU_END; i++) {
+		void __iomem *ppmu_base = data->ppmu[i].hw_base;
 
-		/* Reset PPMU */
-		__raw_writel(0x8000000f, ppmu_base + 0xf010);
-		__raw_writel(0x8000000f, ppmu_base + 0xf050);
-		__raw_writel(0x6, ppmu_base + 0xf000);
-		__raw_writel(0x0, ppmu_base + 0xf100);
+		/* Reset the performance and cycle counters */
+		exynos_ppmu_reset(ppmu_base);
 
-		/* Set PPMU Event */
-		data->dmc[i].event = 0x6;
-		__raw_writel(((data->dmc[i].event << 12) | 0x1),
-			     ppmu_base + 0xfc);
+		/* Setup count registers to monitor read/write transactions */
+		data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
+		exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
+					data->ppmu[i].event[PPMU_PMNCNT3]);
 
-		/* Start PPMU */
-		__raw_writel(0x1, ppmu_base + 0xf000);
+		exynos_ppmu_start(ppmu_base);
 	}
 }
 
@@ -553,23 +535,20 @@ static void exynos4_read_ppmu(struct busfreq_data *data)
 {
 	int i, j;
 
-	for (i = 0; i < 2; i++) {
-		void __iomem *ppmu_base = data->dmc[i].hw_base;
-		u32 overflow;
+	for (i = 0; i < PPMU_END; i++) {
+		void __iomem *ppmu_base = data->ppmu[i].hw_base;
 
-		/* Stop PPMU */
-		__raw_writel(0x0, ppmu_base + 0xf000);
+		exynos_ppmu_stop(ppmu_base);
 
 		/* Update local data from PPMU */
-		overflow = __raw_readl(ppmu_base + 0xf050);
-
-		data->dmc[i].ccnt = __raw_readl(ppmu_base + 0xf100);
-		data->dmc[i].ccnt_overflow = overflow & (1 << 31);
-
-		for (j = 0; j < PPMU_PMNCNT_MAX; j++) {
-			data->dmc[i].count[j] = __raw_readl(
-					ppmu_base + (0xf110 + (0x10 * j)));
-			data->dmc[i].count_overflow[j] = overflow & (1 << j);
+		data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
+
+		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+			if (data->ppmu[i].event[j] == 0)
+				data->ppmu[i].count[j] = 0;
+			else
+				data->ppmu[i].count[j] =
+					exynos_ppmu_read(ppmu_base, j);
 		}
 	}
 
@@ -699,66 +678,42 @@ out:
 	return err;
 }
 
-static int exynos4_get_busier_dmc(struct busfreq_data *data)
+static int exynos4_get_busier_ppmu(struct busfreq_data *data)
 {
-	u64 p0 = data->dmc[0].count[0];
-	u64 p1 = data->dmc[1].count[0];
-
-	p0 *= data->dmc[1].ccnt;
-	p1 *= data->dmc[0].ccnt;
-
-	if (data->dmc[1].ccnt == 0)
-		return 0;
+	int i, j;
+	int busy = 0;
+	unsigned int temp = 0;
+
+	for (i = 0; i < PPMU_END; i++) {
+		for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+			if (data->ppmu[i].count[j] > temp) {
+				temp = data->ppmu[i].count[j];
+				busy = i;
+			}
+		}
+	}
 
-	if (p0 > p1)
-		return 0;
-	return 1;
+	return busy;
 }
 
 static int exynos4_bus_get_dev_status(struct device *dev,
 				      struct devfreq_dev_status *stat)
 {
 	struct busfreq_data *data = dev_get_drvdata(dev);
-	int busier_dmc;
-	int cycles_x2 = 2; /* 2 x cycles */
-	void __iomem *addr;
-	u32 timing;
-	u32 memctrl;
+	int busier;
 
 	exynos4_read_ppmu(data);
-	busier_dmc = exynos4_get_busier_dmc(data);
+	busier = exynos4_get_busier_ppmu(data);
 	stat->current_frequency = data->curr_oppinfo.rate;
 
-	if (busier_dmc)
-		addr = S5P_VA_DMC1;
-	else
-		addr = S5P_VA_DMC0;
-
-	memctrl = __raw_readl(addr + 0x04); /* one of DDR2/3/LPDDR2 */
-	timing = __raw_readl(addr + 0x38); /* CL or WL/RL values */
-
-	switch ((memctrl >> 8) & 0xf) {
-	case 0x4: /* DDR2 */
-		cycles_x2 = ((timing >> 16) & 0xf) * 2;
-		break;
-	case 0x5: /* LPDDR2 */
-	case 0x6: /* DDR3 */
-		cycles_x2 = ((timing >> 8) & 0xf) + ((timing >> 0) & 0xf);
-		break;
-	default:
-		pr_err("%s: Unknown Memory Type(%d).\n", __func__,
-		       (memctrl >> 8) & 0xf);
-		return -EINVAL;
-	}
-
 	/* Number of cycles spent on memory access */
-	stat->busy_time = data->dmc[busier_dmc].count[0] / 2 * (cycles_x2 + 2);
+	stat->busy_time = data->ppmu[busier].count[PPMU_PMNCNT3];
 	stat->busy_time *= 100 / BUS_SATURATION_RATIO;
-	stat->total_time = data->dmc[busier_dmc].ccnt;
+	stat->total_time = data->ppmu[busier].ccnt;
 
 	/* If the counters have overflown, retry */
-	if (data->dmc[busier_dmc].ccnt_overflow ||
-	    data->dmc[busier_dmc].count_overflow[0])
+	if (data->ppmu[busier].ccnt_overflow ||
+	    data->ppmu[busier].count_overflow[0])
 		return -EAGAIN;
 
 	return 0;
@@ -766,6 +721,13 @@ static int exynos4_bus_get_dev_status(struct device *dev,
 
 static void exynos4_bus_exit(struct device *dev)
 {
+	struct busfreq_data *data = dev_get_drvdata(dev);
+	int i;
+
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->ppmu[i].hw_base)
+			iounmap(data->ppmu[i].hw_base);
+	}
 }
 
 static struct devfreq_dev_profile exynos4_devfreq_profile = {
@@ -1025,6 +987,39 @@ static struct of_device_id exynos4_busfreq_id_match[] = {
 	},
 };
 
+static int exynos4_busfreq_parse_dt(struct busfreq_data *data)
+{
+	struct device *dev = data->dev;
+	struct device_node *np = dev->of_node;
+	int i, ret;
+
+	if (!np) {
+		dev_err(dev, "Failed to find devicetree node\n");
+		return -EINVAL;
+	}
+
+	/* Maps the memory mapped IO to control PPMU register */
+	for (i = 0; i < PPMU_END; i++) {
+		data->ppmu[i].hw_base = of_iomap(np, i);
+		if (IS_ERR_OR_NULL(data->ppmu[i].hw_base)) {
+			dev_err(dev, "Failed to map memory region\n");
+			data->ppmu[i].hw_base = NULL;
+			ret = -EINVAL;
+			goto err_iomap;
+		}
+	}
+
+	return 0;
+
+err_iomap:
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->ppmu[i].hw_base)
+			iounmap(data->ppmu[i].hw_base);
+	}
+
+	return ret;
+}
+
 static int exynos4_busfreq_get_driver_data(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1042,7 +1037,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 	struct busfreq_data *data;
 	struct dev_pm_opp *opp;
 	struct device *dev = &pdev->dev;
-	int err = 0;
+	int i, err = 0;
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL);
 	if (data == NULL) {
@@ -1051,10 +1046,16 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 	}
 
 	data->type = exynos4_busfreq_get_driver_data(pdev);
-	data->dmc[0].hw_base = S5P_VA_DMC0;
-	data->dmc[1].hw_base = S5P_VA_DMC1;
 	data->pm_notifier.notifier_call = exynos4_busfreq_pm_notifier_event;
 	data->dev = dev;
+
+	/* Parse dt data to get register/regulator */
+	err = exynos4_busfreq_parse_dt(data);
+	if (err < 0) {
+		dev_err(dev, "Failed to parse dt for resource\n");
+		return err;
+	}
+
 	mutex_init(&data->lock);
 
 	switch (data->type) {
@@ -1102,12 +1103,20 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	busfreq_mon_reset(data);
-
+	/* Reigster Exynos4's devfreq instance with 'simple_ondemand' gov */
 	data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
 					   "simple_ondemand", NULL);
-	if (IS_ERR(data->devfreq))
-		return PTR_ERR(data->devfreq);
+	if (IS_ERR(data->devfreq)) {
+		dev_err(dev, "Failed to add devfreq device\n");
+		err = PTR_ERR(data->devfreq);
+		goto err_devfreq;
+	}
+
+	/*
+	 * Start PPMU(Performance Profiling Monitoring Unit) to check
+	 * utilization of each IP in the Exynos4 SoC.
+	 */
+	busfreq_mon_reset(data);
 
 	/* Register opp_notifier for Exynos4 busfreq */
 	err = devfreq_register_opp_notifier(dev, data->devfreq);
@@ -1128,9 +1137,22 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 err_notifier_pm:
 	devfreq_unregister_opp_notifier(dev, data->devfreq);
 err_notifier_opp:
+	/*
+	 * The devfreq_remove_device() would execute finally devfreq->profile
+	 * ->exit(). To avoid duplicate resource free operation, return directly
+	 * before executing resource free below 'err_devfreq' goto statement.
+	 */
 	devfreq_remove_device(data->devfreq);
 
 	return err;
+
+err_devfreq:
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->ppmu[i].hw_base)
+			iounmap(data->ppmu[i].hw_base);
+	}
+
+	return err;
 }
 
 static int exynos4_busfreq_remove(struct platform_device *pdev)
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 4/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
                   ` (2 preceding siblings ...)
  2014-03-14  9:30 ` [PATCHv3 3/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro Chanwoo Choi
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

There are not the clock controller of ppmudmc0/1. This patch control the clock
of ppmudmc0/1 which is used for monitoring memory bus utilization.

Also, this patch code clean about regulator control and free resource
when calling exit/remove function.

For example,
busfreq@106A0000 {
	compatible = "samsung,exynos4x12-busfreq";

	/* Clock for PPMUDMC0/1 */
	clocks = <&clock CLK_PPMUDMC0>, <&clock CLK_PPMUDMC1>;
	clock-names = "ppmudmc0", "ppmudmc1";

	/* Regulator for MIF/INT block */
	vdd_mif-supply = <&buck1_reg>;
	vdd_int-supply = <&buck3_reg>;
};

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/exynos4_bus.c | 104 ++++++++++++++++++++++++++++++-----
 1 file changed, 91 insertions(+), 13 deletions(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index 8ccbb31..60539e8 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -62,6 +62,11 @@ enum exynos_ppmu_idx {
 	PPMU_END,
 };
 
+static const char *exynos_ppmu_clk_name[] = {
+	[PPMU_DMC0]	= "ppmudmc0",
+	[PPMU_DMC1]	= "ppmudmc1",
+};
+
 #define EX4210_LV_MAX	LV_2
 #define EX4x12_LV_MAX	LV_4
 #define EX4210_LV_NUM	(LV_2 + 1)
@@ -86,6 +91,7 @@ struct busfreq_data {
 	struct regulator *vdd_mif; /* Exynos4412/4212 only */
 	struct busfreq_opp_info curr_oppinfo;
 	struct exynos_ppmu ppmu[PPMU_END];
+	struct clk *clk_ppmu[PPMU_END];
 
 	struct notifier_block pm_notifier;
 	struct mutex lock;
@@ -724,6 +730,19 @@ static void exynos4_bus_exit(struct device *dev)
 	struct busfreq_data *data = dev_get_drvdata(dev);
 	int i;
 
+	/*
+	 * Un-map memory map and disable regulator/clocks
+	 * to prevent power leakage.
+	 */
+	regulator_disable(data->vdd_int);
+	if (data->type == TYPE_BUSF_EXYNOS4x12)
+		regulator_disable(data->vdd_mif);
+
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->clk_ppmu[i])
+			clk_disable_unprepare(data->clk_ppmu[i]);
+	}
+
 	for (i = 0; i < PPMU_END; i++) {
 		if (data->ppmu[i].hw_base)
 			iounmap(data->ppmu[i].hw_base);
@@ -991,6 +1010,7 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data)
 {
 	struct device *dev = data->dev;
 	struct device_node *np = dev->of_node;
+	const char **clk_name = exynos_ppmu_clk_name;
 	int i, ret;
 
 	if (!np) {
@@ -1009,8 +1029,70 @@ static int exynos4_busfreq_parse_dt(struct busfreq_data *data)
 		}
 	}
 
+	/*
+	 * Get PPMU's clocks to control them. But, if PPMU's clocks
+	 * is default 'pass' state, this driver don't need control
+	 * PPMU's clock.
+	 */
+	for (i = 0; i < PPMU_END; i++) {
+		data->clk_ppmu[i] = devm_clk_get(dev, clk_name[i]);
+		if (IS_ERR_OR_NULL(data->clk_ppmu[i])) {
+			dev_warn(dev, "Cannot get %s clock\n", clk_name[i]);
+			data->clk_ppmu[i] = NULL;
+		}
+
+		ret = clk_prepare_enable(data->clk_ppmu[i]);
+		if (ret < 0) {
+			dev_warn(dev, "Cannot enable %s clock\n", clk_name[i]);
+			data->clk_ppmu[i] = NULL;
+			goto err_clocks;
+		}
+	}
+
+	/* Get regulator to control voltage of int block */
+	data->vdd_int = devm_regulator_get(dev, "vdd_int");
+	if (IS_ERR(data->vdd_int)) {
+		dev_err(dev, "Failed to get the regulator of vdd_int\n");
+		ret = PTR_ERR(data->vdd_int);
+		goto err_clocks;
+	}
+	ret = regulator_enable(data->vdd_int);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulator of vdd_int\n");
+		goto err_clocks;
+	}
+
+	switch (data->type) {
+	case TYPE_BUSF_EXYNOS4210:
+		break;
+	case TYPE_BUSF_EXYNOS4x12:
+		/* Get regulator to control voltage of mif blk if Exynos4x12 */
+		data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
+		if (IS_ERR(data->vdd_mif)) {
+			dev_err(dev, "Failed to get the regulator vdd_mif\n");
+			ret = PTR_ERR(data->vdd_mif);
+			goto err_regulator;
+		}
+		ret = regulator_enable(data->vdd_mif);
+		if (ret < 0) {
+			dev_err(dev, "Failed to enable regulator of vdd_mif\n");
+			goto err_regulator;
+		}
+		break;
+	default:
+		dev_err(dev, "Unknown device type : %d\n", data->type);
+		return -EINVAL;
+	};
+
 	return 0;
 
+err_regulator:
+	regulator_disable(data->vdd_int);
+err_clocks:
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->clk_ppmu[i])
+			clk_disable_unprepare(data->clk_ppmu[i]);
+	}
 err_iomap:
 	for (i = 0; i < PPMU_END; i++) {
 		if (data->ppmu[i].hw_base)
@@ -1075,19 +1157,6 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	data->vdd_int = devm_regulator_get(dev, "vdd_int");
-	if (IS_ERR(data->vdd_int)) {
-		dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
-		return PTR_ERR(data->vdd_int);
-	}
-	if (data->type == TYPE_BUSF_EXYNOS4x12) {
-		data->vdd_mif = devm_regulator_get(dev, "vdd_mif");
-		if (IS_ERR(data->vdd_mif)) {
-			dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n");
-			return PTR_ERR(data->vdd_mif);
-		}
-	}
-
 	rcu_read_lock();
 	opp = dev_pm_opp_find_freq_floor(dev,
 					 &exynos4_devfreq_profile.initial_freq);
@@ -1147,6 +1216,15 @@ err_notifier_opp:
 	return err;
 
 err_devfreq:
+	regulator_disable(data->vdd_int);
+	if (data->type == TYPE_BUSF_EXYNOS4x12)
+		regulator_disable(data->vdd_mif);
+
+	for (i = 0; i < PPMU_END; i++) {
+		if (data->clk_ppmu[i])
+			clk_disable_unprepare(data->clk_ppmu[i]);
+	}
+
 	for (i = 0; i < PPMU_END; i++) {
 		if (data->ppmu[i].hw_base)
 			iounmap(data->ppmu[i].hw_base);
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
                   ` (3 preceding siblings ...)
  2014-03-14  9:30 ` [PATCHv3 4/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-17  0:17   ` Jingoo Han
  2014-03-14  9:30 ` [PATCHv3 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state Chanwoo Choi
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch use SET_SYSTEM_SLEEP_PM_OPS macro instead of legacy method.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/exynos4_bus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index 60539e8..e5d2c5a 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -1247,6 +1247,7 @@ static int exynos4_busfreq_remove(struct platform_device *pdev)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int exynos4_busfreq_resume(struct device *dev)
 {
 	struct busfreq_data *data = dev_get_drvdata(dev);
@@ -1254,9 +1255,10 @@ static int exynos4_busfreq_resume(struct device *dev)
 	busfreq_mon_reset(data);
 	return 0;
 }
+#endif
 
 static const struct dev_pm_ops exynos4_busfreq_pm = {
-	.resume	= exynos4_busfreq_resume,
+	SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume)
 };
 
 static const struct platform_device_id exynos4_busfreq_id[] = {
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
                   ` (4 preceding siblings ...)
  2014-03-14  9:30 ` [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 8/8] Documentation: dt: devfreq: Add device tree binding of Exynos4 busfreq Chanwoo Choi
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch disable ppmu clocks before entering suspend state to remove
power-leakage and enable ppmu clocks on resume function.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/exynos/exynos4_bus.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index e5d2c5a..65e097a 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -1251,14 +1251,37 @@ static int exynos4_busfreq_remove(struct platform_device *pdev)
 static int exynos4_busfreq_resume(struct device *dev)
 {
 	struct busfreq_data *data = dev_get_drvdata(dev);
+	int i;
+
+	/* Enable clock after wake-up from suspend state */
+	for (i = 0; i < PPMU_END; i++)
+		clk_prepare_enable(data->clk_ppmu[i]);
+
+	/* Reset PPMU to check utilization again */
 
 	busfreq_mon_reset(data);
+
 	return 0;
 }
+
+static int exynos4_busfreq_suspend(struct device *dev)
+{
+	struct busfreq_data *data = dev_get_drvdata(dev);
+	int i;
+
+	/*
+	 * Disable clock before entering suspend state
+	 * to reduce leakage power on suspend state.
+	 */
+	for (i = 0; i < PPMU_END; i++)
+		clk_disable_unprepare(data->clk_ppmu[i]);
+
+	return 0;
+};
 #endif
 
 static const struct dev_pm_ops exynos4_busfreq_pm = {
-	SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume)
+	SET_SYSTEM_SLEEP_PM_OPS(exynos4_busfreq_suspend, exynos4_busfreq_resume)
 };
 
 static const struct platform_device_id exynos4_busfreq_id[] = {
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
                   ` (5 preceding siblings ...)
  2014-03-14  9:30 ` [PATCHv3 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  2014-03-14  9:30 ` [PATCHv3 8/8] Documentation: dt: devfreq: Add device tree binding of Exynos4 busfreq Chanwoo Choi
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch add CONFIG_PM_OPP dependecy to exynos4_bus driver
to fix probe fail as following log:

[    3.721389] exynos4-busfreq busfreq.3: Fail to add opp entries.
[    3.721697] exynos4-busfreq: probe of busfreq.3 failed with error -22

If CONFIG_PM_OPP is disabled, dev_pm_opp_find_freq_floor() in xxx_probe()
will always return -EINVAL error.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 drivers/devfreq/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 7d2f435..b2de2a1 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -70,6 +70,7 @@ config ARM_EXYNOS4_BUS_DEVFREQ
 	depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
 	select ARCH_HAS_OPP
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select PM_OPP
 	help
 	  This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int)
 	  and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int).
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCHv3 8/8] Documentation: dt: devfreq: Add device tree binding of Exynos4 busfreq
  2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
                   ` (6 preceding siblings ...)
  2014-03-14  9:30 ` [PATCHv3 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail Chanwoo Choi
@ 2014-03-14  9:30 ` Chanwoo Choi
  7 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-14  9:30 UTC (permalink / raw)
  To: myungjoo.ham, kyungmin.park
  Cc: rafael.j.wysocki, nm, b.zolnierkie, pawel.moll, mark.rutland,
	swarren, ijc+devicetree, linux-pm, linux-kernel,
	linux-samsung-soc, devicetree, linux-doc, Chanwoo Choi

This patch introduce device tree binding for the Exynos4's busfreq driver.
The Exynos4's busfreq driver support DVFS(Dynamic Voltage Frequency Scaling)
of Exynos4 memory bus to optimize power-consumption on runtime state.
Exynos4's busfreq driver need the utilization of memory bus. So, busfreq driver
use PPMU_DMC0/PPMU_DMC1 IP among various PPMU(Performance Profiling Monitoring
Units) which provide the data of read/write counters on memory bus. This driver
adjust the frequency/voltage of memory bus according to PPMU_DMC0/PPMU_DMC1
counters.

Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
---
 .../devicetree/bindings/devfreq/exynos4_bus.txt    | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/devfreq/exynos4_bus.txt

diff --git a/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt
new file mode 100644
index 0000000..bd397ed
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/exynos4_bus.txt
@@ -0,0 +1,50 @@
+
+Exynos4 Memory Bus frequency driver
+-----------------------------------
+
+Exynos4 SoC need Busfreq (Memory Bus frequency) driver to support DVFS (Dynamic
+Voltage Frequency Scaling) of Exynos4 SoC's memory bus. This driver controls
+dynamically the frequency/voltage of memory bus to optimize power-consumption
+of memory bus. When checking the utilization of memory bus, Exynos4's busfreq
+driver uses PPMU_DMC0/PPMU_DMC1 (Performance Profiling Monitoring Units)
+which provide the data of read/write counters on memory bus.
+
+Required properties:
+- compatible	: should contain Exynos4 SoC type as following:
+		  - "samsung,exynos4210-busfreq" for Exynos4210
+		  - "samsung,exynos4x12-busfreq" for Exynos4x12
+- reg		: physical address of PPMU_DMC0/PPMU_DMC1 register and length
+		  for memory mapping
+- clocks	: phandles to clock-controller and clock number of PPMU_DMC0
+		  /PPMU_DMC1
+- clock-names	: clock names for PPMU_DMC0/PPMU_DMC1
+		  - "ppmudmc0" for PPMU_DMC0
+		  - "ppmudmc1" for PPMU_DMC1
+- vdd_int-supply: regulator for interface block of Exynos4 SoC
+
+Optional properties:
+- vdd_mif-supply: regulator for DMC block if using Exynos4x12 SoC
+
+Example:
+For Exynos4210 busfreq,
+
+	busfreq@106A0000 {
+		compatible = "samsung,exynos4210-busfreq";
+		reg = <0x106A0000 0x2000>, <0x106B0000 0x2000>;
+		clocks = <&clock CLK_PPMUDMC0>, <&clock CLK_PPMUDMC1>;
+		clock-names = "ppmudmc0", "ppmudmc1";
+
+		vdd_int-supply = <&buck3_reg>;
+	};
+
+For Exynos4x12 busfreq,
+
+	busfreq@106A0000 {
+		compatible = "samsung,exynos4x12-busfreq";
+		reg = <0x106A0000 0x2000>, <0x106B0000 0x2000>;
+		clocks = <&clock CLK_PPMUDMC0>, <&clock CLK_PPMUDMC1>;
+		clock-names = "ppmudmc0", "ppmudmc1";
+
+		vdd_int-supply = <&buck3_reg>;
+		vdd_mif-suppy = <&buck1_reg>;
+	};
-- 
1.8.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro
  2014-03-14  9:30 ` [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro Chanwoo Choi
@ 2014-03-17  0:17   ` Jingoo Han
  2014-03-17  1:34     ` Chanwoo Choi
  0 siblings, 1 reply; 11+ messages in thread
From: Jingoo Han @ 2014-03-17  0:17 UTC (permalink / raw)
  To: 'Chanwoo Choi'
  Cc: myungjoo.ham, kyungmin.park, rafael.j.wysocki, nm, b.zolnierkie,
	pawel.moll, mark.rutland, swarren, ijc+devicetree, linux-pm,
	linux-kernel, linux-samsung-soc, devicetree, linux-doc,
	'Jingoo Han'

On Friday, March 14, 2014 6:30 PM, Chanwoo Choi wrote:
> 
> This patch use SET_SYSTEM_SLEEP_PM_OPS macro instead of legacy method.
> 
> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
> ---
>  drivers/devfreq/exynos/exynos4_bus.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
> index 60539e8..e5d2c5a 100644
> --- a/drivers/devfreq/exynos/exynos4_bus.c
> +++ b/drivers/devfreq/exynos/exynos4_bus.c
> @@ -1247,6 +1247,7 @@ static int exynos4_busfreq_remove(struct platform_device *pdev)
>  	return 0;
>  }
> 
> +#ifdef CONFIG_PM_SLEEP
>  static int exynos4_busfreq_resume(struct device *dev)
>  {
>  	struct busfreq_data *data = dev_get_drvdata(dev);
> @@ -1254,9 +1255,10 @@ static int exynos4_busfreq_resume(struct device *dev)
>  	busfreq_mon_reset(data);
>  	return 0;
>  }
> +#endif
> 
>  static const struct dev_pm_ops exynos4_busfreq_pm = {
> -	.resume	= exynos4_busfreq_resume,
> +	SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume)

Hi Chanwoo Choi,

How about using SIMPLE_DEV_PM_OPS instead of SET_SYSTEM_SLEEP_PM_OPS?
SIMPLE_DEV_PM_OPS is simpler as below.

static SIMPLE_DEV_PM_OPS(exynos4_busfreq_pm, NULL, exynos4_busfreq_resume);

However, if runtime pm functions will be added later,
SIMPLE_DEV_PM_OPS is not necessary.

Best regards,
Jingoo Han

>  };
> 
>  static const struct platform_device_id exynos4_busfreq_id[] = {
> --
> 1.8.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro
  2014-03-17  0:17   ` Jingoo Han
@ 2014-03-17  1:34     ` Chanwoo Choi
  0 siblings, 0 replies; 11+ messages in thread
From: Chanwoo Choi @ 2014-03-17  1:34 UTC (permalink / raw)
  To: Jingoo Han
  Cc: myungjoo.ham, kyungmin.park, rafael.j.wysocki, nm, b.zolnierkie,
	pawel.moll, mark.rutland, swarren, ijc+devicetree, linux-pm,
	linux-kernel, linux-samsung-soc, devicetree, linux-doc

Hi Jingoo,

On 03/17/2014 09:17 AM, Jingoo Han wrote:
> On Friday, March 14, 2014 6:30 PM, Chanwoo Choi wrote:
>>
>> This patch use SET_SYSTEM_SLEEP_PM_OPS macro instead of legacy method.
>>
>> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
>> ---
>>  drivers/devfreq/exynos/exynos4_bus.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
>> index 60539e8..e5d2c5a 100644
>> --- a/drivers/devfreq/exynos/exynos4_bus.c
>> +++ b/drivers/devfreq/exynos/exynos4_bus.c
>> @@ -1247,6 +1247,7 @@ static int exynos4_busfreq_remove(struct platform_device *pdev)
>>  	return 0;
>>  }
>>
>> +#ifdef CONFIG_PM_SLEEP
>>  static int exynos4_busfreq_resume(struct device *dev)
>>  {
>>  	struct busfreq_data *data = dev_get_drvdata(dev);
>> @@ -1254,9 +1255,10 @@ static int exynos4_busfreq_resume(struct device *dev)
>>  	busfreq_mon_reset(data);
>>  	return 0;
>>  }
>> +#endif
>>
>>  static const struct dev_pm_ops exynos4_busfreq_pm = {
>> -	.resume	= exynos4_busfreq_resume,
>> +	SET_SYSTEM_SLEEP_PM_OPS(NULL, exynos4_busfreq_resume)
> 
> Hi Chanwoo Choi,
> 
> How about using SIMPLE_DEV_PM_OPS instead of SET_SYSTEM_SLEEP_PM_OPS?
> SIMPLE_DEV_PM_OPS is simpler as below.
> 
> static SIMPLE_DEV_PM_OPS(exynos4_busfreq_pm, NULL, exynos4_busfreq_resume);
> 
> However, if runtime pm functions will be added later,
> SIMPLE_DEV_PM_OPS is not necessary.
> 

OK, I'll use SIMPLE_DEV_PM_OPS on next patchset.

Best Regards,
Chanwoo Choi



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-03-17  1:34 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-14  9:30 [PATCHv3 0/8] devfreq: exynos4: Support dt and use common ppmu driver Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 1/8] devfreq: exynos4: Fix bug of resource leak and code clean on probe() Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 2/8] devfreq: exynos4: Support devicetree to get device id of Exynos4 SoC Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 3/8] devfreq: exynos4: Use common ppmu driver and get ppmu address from dt data Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 4/8] devfreq: exynos4: Add ppmu's clock control and code clean about regulator control Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 5/8] devfreq: exynos4: Use SET_SYSTEM_SLEEP_PM_OPS macro Chanwoo Choi
2014-03-17  0:17   ` Jingoo Han
2014-03-17  1:34     ` Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 6/8] devfreq: exynos4: Fix power-leakage of clock on suspend state Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 7/8] devfreq: exynos4: Add CONFIG_PM_OPP dependency to fix probe fail Chanwoo Choi
2014-03-14  9:30 ` [PATCHv3 8/8] Documentation: dt: devfreq: Add device tree binding of Exynos4 busfreq Chanwoo Choi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).