2014-04-25 09:10:44

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 0/5] devfreq: Support resource management functions and code clean

This patchset fix devfreq_remove_device() to remove duplicate function call
of _remove_devfreq() and add following functions for the resource management
of devfreq device and simpify the control of resource on exynos4_bus/exynos5_bus
driver.
- devm_devfreq_add_device
- devm_devfreq_remove_device
- devm_devfreq_register_opp_notifier
- devm_devfreq_unregister_opp_notifier

Chanwoo Choi (5):
devfreq: Fix devfreq_remove_device() to improve the sequence of resource free
devfreq: Add resource-managed function for devfreq device
devfreq: Add devm_devfreq_{register,unregister}_opp_notfier function
devfreq: exynos4: Use devm_devfreq_* function using device resource management
devfreq: exynos5: Use devm_devfreq_* function using device resource management

drivers/devfreq/devfreq.c | 125 ++++++++++++++++++++++++++++++++---
drivers/devfreq/exynos/exynos4_bus.c | 19 ++----
drivers/devfreq/exynos/exynos5_bus.c | 23 +++----
include/linux/devfreq.h | 35 +++++++++-
4 files changed, 161 insertions(+), 41 deletions(-)

--
1.8.0


2014-04-25 09:08:28

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 4/5] devfreq: exynos4: Use devm_devfreq_* function using device resource management

This patch uses devm_devfreq_add_device()/devm_devfreq_register_opp_notifier()
to control automatically the resource of devfreq.

Signed-off-by: Chanwoo Choi <[email protected]>
Cc: Kukjin Kim <[email protected]>
Cc: Bartlomiej Zolnierkiewicz <[email protected]>
Cc: Wei Yongjun <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/devfreq/exynos/exynos4_bus.c | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/devfreq/exynos/exynos4_bus.c b/drivers/devfreq/exynos/exynos4_bus.c
index d257f1f..bebb0a4 100644
--- a/drivers/devfreq/exynos/exynos4_bus.c
+++ b/drivers/devfreq/exynos/exynos4_bus.c
@@ -979,7 +979,7 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)

platform_set_drvdata(pdev, data);

- data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile,
+ data->devfreq = devm_devfreq_add_device(dev, &exynos4_devfreq_profile,
"simple_ondemand", NULL);
if (IS_ERR(data->devfreq))
return PTR_ERR(data->devfreq);
@@ -991,27 +991,20 @@ static int exynos4_busfreq_probe(struct platform_device *pdev)
busfreq_mon_reset(ppmu_data);

/* Register opp_notifier for Exynos4 busfreq */
- err = devfreq_register_opp_notifier(dev, data->devfreq);
+ err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
if (err < 0) {
dev_err(dev, "Failed to register opp notifier\n");
- goto err_notifier_opp;
+ return err;
}

/* Register pm_notifier for Exynos4 busfreq */
err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
- goto err_notifier_pm;
+ return err;
}

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)
@@ -1020,10 +1013,6 @@ static int exynos4_busfreq_remove(struct platform_device *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

2014-04-25 09:08:46

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 5/5] devfreq: exynos5: Use devm_devfreq_* function using device resource management

This patch uses devm_devfreq_add_device()/devm_devfreq_register_opp_notifier()
to control automatically the resource of devfreq.

Signed-off-by: Chanwoo Choi <[email protected]>
Cc: Kukjin Kim <[email protected]>
Cc: Sachin Kamat <[email protected]>
Cc: Bartlomiej Zolnierkiewicz <[email protected]>
Cc: Manish Badarkhe <[email protected]>
Cc: Abhilash Kesavan <[email protected]>
Cc: [email protected]
Cc: [email protected]
---
drivers/devfreq/exynos/exynos5_bus.c | 23 ++++++++---------------
1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c
index ab54a69..1f622f8 100644
--- a/drivers/devfreq/exynos/exynos5_bus.c
+++ b/drivers/devfreq/exynos/exynos5_bus.c
@@ -165,11 +165,6 @@ static int exynos5_int_get_dev_status(struct device *dev,
}
static void exynos5_int_exit(struct device *dev)
{
- struct platform_device *pdev = container_of(dev, struct platform_device,
- dev);
- struct busfreq_data_int *data = platform_get_drvdata(pdev);
-
- devfreq_unregister_opp_notifier(dev, data->devfreq);
}

static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
@@ -343,30 +338,29 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev)

busfreq_mon_reset(ppmu_data);

- data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
+ data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile,
"simple_ondemand", NULL);
-
if (IS_ERR(data->devfreq)) {
err = PTR_ERR(data->devfreq);
- goto err_devfreq_add;
+ return err;
}

- devfreq_register_opp_notifier(dev, data->devfreq);
+ err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
+ if (err < 0) {
+ dev_err(dev, "Failed to register opp notifier\n");
+ return err;
+ }

err = register_pm_notifier(&data->pm_notifier);
if (err) {
dev_err(dev, "Failed to setup pm notifier\n");
- goto err_devfreq_add;
+ return err;
}

/* TODO: Add a new QOS class for int/mif bus */
pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);

return 0;
-
-err_devfreq_add:
- devfreq_remove_device(data->devfreq);
- return err;
}

static int exynos5_busfreq_int_remove(struct platform_device *pdev)
@@ -375,7 +369,6 @@ static int exynos5_busfreq_int_remove(struct platform_device *pdev)

pm_qos_remove_request(&data->int_req);
unregister_pm_notifier(&data->pm_notifier);
- devfreq_remove_device(data->devfreq);

return 0;
}
--
1.8.0

2014-04-25 09:09:35

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 2/5] devfreq: Add resource-managed function for devfreq device

This patch add resource-managed function for devfreq device as following
functions. The devm_devfreq_add_device() manages automatically the memory
of devfreq device using device resource management.
- devm_devfreq_add_device()
- devm_devfreq_remove_device()

Signed-off-by: Chanwoo Choi <[email protected]>
---
drivers/devfreq/devfreq.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/devfreq.h | 21 +++++++++++++++-
2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index e960eb0..0b80b60 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -659,6 +659,69 @@ int devfreq_remove_device(struct devfreq *devfreq)
}
EXPORT_SYMBOL(devfreq_remove_device);

+static int devm_devfreq_dev_match(struct device *dev, void *res, void *data)
+{
+ struct devfreq **r = res;
+ if (!r || !*r) {
+ WARN_ON(!r || !*r);
+ return 0;
+ }
+ return *r == data;
+}
+
+static void devm_devfreq_dev_release(struct device *dev, void *res)
+{
+ devfreq_remove_device(*(struct devfreq **)res);
+}
+
+/**
+ * devm_devfreq_add_device() - Resource-managed devfreq_add_device()
+ * @dev: the device to add devfreq feature.
+ * @profile: device-specific profile to run devfreq.
+ * @governor_name: name of the policy to choose frequency.
+ * @data: private data for the governor. The devfreq framework does not
+ * touch this value.
+ *
+ * This function manages automatically the memory of devfreq device using device
+ * resource management and simplify the free operation for memory of devfreq
+ * device.
+ */
+struct devfreq *devm_devfreq_add_device(struct device *dev,
+ struct devfreq_dev_profile *profile,
+ const char *governor_name,
+ void *data)
+{
+ struct devfreq **ptr, *devfreq;
+
+ ptr = devres_alloc(devm_devfreq_dev_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ devfreq = devfreq_add_device(dev, profile, governor_name, data);
+ if (IS_ERR(devfreq)) {
+ devres_free(ptr);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ *ptr = devfreq;
+ devres_add(dev, ptr);
+
+ return devfreq;
+}
+EXPORT_SYMBOL(devm_devfreq_add_device);
+
+/**
+ * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device()
+ * @dev: the device to add devfreq feature.
+ * @devfreq: the devfreq instance to be removed
+ */
+void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq)
+{
+ WARN_ON(devres_release(dev, devm_devfreq_dev_release,
+ devm_devfreq_dev_match, devfreq));
+}
+EXPORT_SYMBOL(devm_devfreq_remove_device);
+
/**
* devfreq_suspend_device() - Suspend devfreq of a device.
* @devfreq: the devfreq instance to be suspended
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 4dd8cca..45c29db 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -223,6 +223,12 @@ extern struct devfreq *devfreq_add_device(struct device *dev,
const char *governor_name,
void *data);
extern int devfreq_remove_device(struct devfreq *devfreq);
+extern struct devfreq *devm_devfreq_add_device(struct device *dev,
+ struct devfreq_dev_profile *profile,
+ const char *governor_name,
+ void *data);
+extern void devm_devfreq_remove_device(struct device *dev,
+ struct devfreq *devfreq);

/* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */
extern int devfreq_suspend_device(struct devfreq *devfreq);
@@ -262,7 +268,7 @@ static inline struct devfreq *devfreq_add_device(struct device *dev,
const char *governor_name,
void *data)
{
- return NULL;
+ return ERR_PTR(-ENOMEM);
}

static inline int devfreq_remove_device(struct devfreq *devfreq)
@@ -270,6 +276,19 @@ static inline int devfreq_remove_device(struct devfreq *devfreq)
return 0;
}

+static inline struct devfreq *devm_devfreq_add_device(struct device *dev,
+ struct devfreq_dev_profile *profile,
+ const char *governor_name,
+ void *data)
+{
+ return ERR_PTR(-ENOMEM);
+}
+
+static inline void devm_devfreq_remove_device(struct device *dev,
+ struct devfreq *devfreq)
+{
+}
+
static inline int devfreq_suspend_device(struct devfreq *devfreq)
{
return 0;
--
1.8.0

2014-04-25 09:08:22

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 1/5] devfreq: Fix devfreq_remove_device() to improve the sequence of resource free

This patch modify devfreq_remove_device() to improve the sequence of resource
free. If executing existing devfreq_remove_device(), this function always
executes _remove_devfreq() twice. In result, second _remove_devfreq() always
return error value. So, This patch resolves complicated function sequence
as following:

[Flow sequence before modification]
devfreq_remove_device()
_remove_devfreq(devfreq, false)
kfree(devfreq); /* Free devfreq */
if (!skip ...) { /* skip is false */
device_unregister(&devfreq->dev)
put_device(&devfreq->dev);
...
dev->release()
devfreq_dev_release()
_remove_devfreq(devfreq, true) <- Recall to free devfreq
/*
* Always return error without freeing resource because
* already _remove_devfreq() frees the memory of devfreq.
*/
}

[Flow sequence after modification]
devfreq_remove_device
device_unregister(&devfreq->dev)
put_device(&devfreq->dev);
..
dev->release()
devfreq_dev_release()
_remove_devfreq()
kfree(devfreq); /* Free devfreq */

Signed-off-by: Chanwoo Choi <[email protected]>
---
drivers/devfreq/devfreq.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index d32c8b6..e960eb0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -437,7 +437,7 @@ update:
* @devfreq: the devfreq struct
* @skip: skip calling device_unregister().
*/
-static void _remove_devfreq(struct devfreq *devfreq, bool skip)
+static void _remove_devfreq(struct devfreq *devfreq)
{
mutex_lock(&devfreq_list_lock);
if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) {
@@ -462,11 +462,6 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip)
if (devfreq->profile->exit)
devfreq->profile->exit(devfreq->dev.parent);

- if (!skip && get_device(&devfreq->dev)) {
- device_unregister(&devfreq->dev);
- put_device(&devfreq->dev);
- }
-
mutex_destroy(&devfreq->lock);
kfree(devfreq);
}
@@ -476,14 +471,12 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip)
* @dev: the devfreq device
*
* This calls _remove_devfreq() if _remove_devfreq() is not called.
- * Note that devfreq_dev_release() could be called by _remove_devfreq() as
- * well as by others unregistering the device.
*/
static void devfreq_dev_release(struct device *dev)
{
struct devfreq *devfreq = to_devfreq(dev);

- _remove_devfreq(devfreq, true);
+ _remove_devfreq(devfreq);
}

static int devfreq_qos_sanity_check(struct device *dev,
@@ -659,7 +652,8 @@ int devfreq_remove_device(struct devfreq *devfreq)
if (!devfreq)
return -EINVAL;

- _remove_devfreq(devfreq, false);
+ device_unregister(&devfreq->dev);
+ put_device(&devfreq->dev);

return 0;
}
--
1.8.0

2014-04-25 09:11:57

by Chanwoo Choi

[permalink] [raw]
Subject: [PATCH 3/5] devfreq: Add devm_devfreq_{register,unregister}_opp_notfier function

This patch add resource-managed function for devfreq opp as following
functions. The devm_devfreq_register_opp_notifier() manages automatically
the registration of devfreq opp using device resource management.
- devm_devfreq_register_opp_notifier
- devm_devfreq_unregister_opp_notifier()

Signed-off-by: Chanwoo Choi <[email protected]>
---
drivers/devfreq/devfreq.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
include/linux/devfreq.h | 14 ++++++++++++++
2 files changed, 62 insertions(+)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0b80b60..3439406 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1293,6 +1293,54 @@ int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)
return ret;
}

+static void devm_devfreq_opp_release(struct device *dev, void *res)
+{
+ devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res);
+}
+
+/**
+ * devm_ devfreq_register_opp_notifier()
+ * - Resource-managed devfreq_register_opp_notifier()
+ * @dev: The devfreq user device. (parent of devfreq)
+ * @devfreq: The devfreq object.
+ */
+int devm_devfreq_register_opp_notifier(struct device *dev,
+ struct devfreq *devfreq)
+{
+ struct devfreq **ptr;
+ int ret;
+
+ ptr = devres_alloc(devm_devfreq_opp_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return -ENOMEM;
+
+ ret = devfreq_register_opp_notifier(dev, devfreq);
+ if (ret) {
+ devres_free(ptr);
+ return ret;
+ }
+
+ *ptr = devfreq;
+ devres_add(dev, ptr);
+
+ return 0;
+}
+EXPORT_SYMBOL(devm_devfreq_register_opp_notifier);
+
+/**
+ * devm_devfreq_unregister_opp_notifier()
+ * - Resource-managed devfreq_unregister_opp_notifier()
+ * @dev: The devfreq user device. (parent of devfreq)
+ * @devfreq: The devfreq object.
+ */
+void devm_devfreq_unregister_opp_notifier(struct device *dev,
+ struct devfreq *devfreq)
+{
+ WARN_ON(devres_release(dev, devm_devfreq_opp_release,
+ devm_devfreq_dev_match, devfreq));
+}
+EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier);
+
MODULE_AUTHOR("MyungJoo Ham <[email protected]>");
MODULE_DESCRIPTION("devfreq class support");
MODULE_LICENSE("GPL");
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 45c29db..90f95a3 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -241,6 +241,10 @@ extern int devfreq_register_opp_notifier(struct device *dev,
struct devfreq *devfreq);
extern int devfreq_unregister_opp_notifier(struct device *dev,
struct devfreq *devfreq);
+extern int devm_devfreq_register_opp_notifier(struct device *dev,
+ struct devfreq *devfreq);
+extern void devm_devfreq_unregister_opp_notifier(struct device *dev,
+ struct devfreq *devfreq);

#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
/**
@@ -317,6 +321,16 @@ static inline int devfreq_unregister_opp_notifier(struct device *dev,
return -EINVAL;
}

+static inline int devm_devfreq_register_opp_notifier(struct device *dev,
+ struct devfreq *devfreq)
+{
+ return -EINVAL;
+}
+
+static inline void devm_devfreq_unregister_opp_notifier(struct device *dev,
+ struct devfreq *devfreq)
+{
+}
#endif /* CONFIG_PM_DEVFREQ */

#endif /* __LINUX_DEVFREQ_H__ */
--
1.8.0

2014-04-29 16:54:48

by Sachin Kamat

[permalink] [raw]
Subject: Re: [PATCH 5/5] devfreq: exynos5: Use devm_devfreq_* function using device resource management

Hi Chanwoo,

On 25 April 2014 14:38, Chanwoo Choi <[email protected]> wrote:
> This patch uses devm_devfreq_add_device()/devm_devfreq_register_opp_notifier()
> to control automatically the resource of devfreq.
>
> Signed-off-by: Chanwoo Choi <[email protected]>
> Cc: Kukjin Kim <[email protected]>
> Cc: Sachin Kamat <[email protected]>
> Cc: Bartlomiej Zolnierkiewicz <[email protected]>
> Cc: Manish Badarkhe <[email protected]>
> Cc: Abhilash Kesavan <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/devfreq/exynos/exynos5_bus.c | 23 ++++++++---------------
> 1 file changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c
> index ab54a69..1f622f8 100644
> --- a/drivers/devfreq/exynos/exynos5_bus.c
> +++ b/drivers/devfreq/exynos/exynos5_bus.c
> @@ -165,11 +165,6 @@ static int exynos5_int_get_dev_status(struct device *dev,
> }
> static void exynos5_int_exit(struct device *dev)
> {
> - struct platform_device *pdev = container_of(dev, struct platform_device,
> - dev);
> - struct busfreq_data_int *data = platform_get_drvdata(pdev);
> -
> - devfreq_unregister_opp_notifier(dev, data->devfreq);
> }

Do you need an empty function?

>
> static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
> @@ -343,30 +338,29 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev)
>
> busfreq_mon_reset(ppmu_data);
>
> - data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
> + data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile,
> "simple_ondemand", NULL);
> -
> if (IS_ERR(data->devfreq)) {
> err = PTR_ERR(data->devfreq);

No need of err. return PTR_ERR(data->devfreq);

> - goto err_devfreq_add;
> + return err;
> }
>
> - devfreq_register_opp_notifier(dev, data->devfreq);
> + err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
> + if (err < 0) {
> + dev_err(dev, "Failed to register opp notifier\n");
> + return err;
> + }
>
> err = register_pm_notifier(&data->pm_notifier);
> if (err) {
> dev_err(dev, "Failed to setup pm notifier\n");
> - goto err_devfreq_add;
> + return err;
> }
>
> /* TODO: Add a new QOS class for int/mif bus */
> pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
>
> return 0;
> -
> -err_devfreq_add:
> - devfreq_remove_device(data->devfreq);
> - return err;
> }
>
> static int exynos5_busfreq_int_remove(struct platform_device *pdev)
> @@ -375,7 +369,6 @@ static int exynos5_busfreq_int_remove(struct platform_device *pdev)
>
> pm_qos_remove_request(&data->int_req);
> unregister_pm_notifier(&data->pm_notifier);
> - devfreq_remove_device(data->devfreq);
>
> return 0;
> }
> --
> 1.8.0
>



--
With warm regards,
Sachin

2014-04-30 00:58:46

by Chanwoo Choi

[permalink] [raw]
Subject: Re: [PATCH 5/5] devfreq: exynos5: Use devm_devfreq_* function using device resource management

Hi Sachin,

On 04/30/2014 01:54 AM, Sachin Kamat wrote:
> Hi Chanwoo,
>
> On 25 April 2014 14:38, Chanwoo Choi <[email protected]> wrote:
>> This patch uses devm_devfreq_add_device()/devm_devfreq_register_opp_notifier()
>> to control automatically the resource of devfreq.
>>
>> Signed-off-by: Chanwoo Choi <[email protected]>
>> Cc: Kukjin Kim <[email protected]>
>> Cc: Sachin Kamat <[email protected]>
>> Cc: Bartlomiej Zolnierkiewicz <[email protected]>
>> Cc: Manish Badarkhe <[email protected]>
>> Cc: Abhilash Kesavan <[email protected]>
>> Cc: [email protected]
>> Cc: [email protected]
>> ---
>> drivers/devfreq/exynos/exynos5_bus.c | 23 ++++++++---------------
>> 1 file changed, 8 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c
>> index ab54a69..1f622f8 100644
>> --- a/drivers/devfreq/exynos/exynos5_bus.c
>> +++ b/drivers/devfreq/exynos/exynos5_bus.c
>> @@ -165,11 +165,6 @@ static int exynos5_int_get_dev_status(struct device *dev,
>> }
>> static void exynos5_int_exit(struct device *dev)
>> {
>> - struct platform_device *pdev = container_of(dev, struct platform_device,
>> - dev);
>> - struct busfreq_data_int *data = platform_get_drvdata(pdev);
>> -
>> - devfreq_unregister_opp_notifier(dev, data->devfreq);
>> }
>
> Do you need an empty function?

exynos5_init_exit() function would be removed because this function is not necessary.

>
>>
>> static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
>> @@ -343,30 +338,29 @@ static int exynos5_busfreq_int_probe(struct platform_device *pdev)
>>
>> busfreq_mon_reset(ppmu_data);
>>
>> - data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
>> + data->devfreq = devm_devfreq_add_device(dev, &exynos5_devfreq_int_profile,
>> "simple_ondemand", NULL);
>> -
>> if (IS_ERR(data->devfreq)) {
>> err = PTR_ERR(data->devfreq);
>
> No need of err. return PTR_ERR(data->devfreq);

OK, I'll fix it.

>
>> - goto err_devfreq_add;
>> + return err;
>> }
>>
>> - devfreq_register_opp_notifier(dev, data->devfreq);
>> + err = devm_devfreq_register_opp_notifier(dev, data->devfreq);
>> + if (err < 0) {
>> + dev_err(dev, "Failed to register opp notifier\n");
>> + return err;
>> + }
>>
>> err = register_pm_notifier(&data->pm_notifier);
>> if (err) {
>> dev_err(dev, "Failed to setup pm notifier\n");
>> - goto err_devfreq_add;
>> + return err;
>> }
>>
>> /* TODO: Add a new QOS class for int/mif bus */
>> pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
>>
>> return 0;
>> -
>> -err_devfreq_add:
>> - devfreq_remove_device(data->devfreq);
>> - return err;
>> }
>>
>> static int exynos5_busfreq_int_remove(struct platform_device *pdev)
>> @@ -375,7 +369,6 @@ static int exynos5_busfreq_int_remove(struct platform_device *pdev)
>>
>> pm_qos_remove_request(&data->int_req);
>> unregister_pm_notifier(&data->pm_notifier);
>> - devfreq_remove_device(data->devfreq);
>>
>> return 0;
>> }
>> --
>> 1.8.0
>>
>
>
>