* [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).