* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.