]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PM / devfreq: rk3399_dmc: Fix duplicated opp table on reload.
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>
Fri, 15 Jun 2018 15:12:17 +0000 (17:12 +0200)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Wed, 18 Jul 2018 04:58:39 +0000 (13:58 +0900)
The opp table is not removed when the driver is unloaded neither when
there is an error within probe, so if the driver is reloaded the opp
core shows the following warning:

  rk3399-dmc-freq dmc: _opp_add: duplicate OPPs detected. Existing: freq:
               200000000, volt: 900000, enabled: 1. New: freq: 200000000,
               volt: 900000, enabled: 1
  rk3399-dmc-freq dmc: _opp_add: duplicate OPPs detected. Existing: freq:
               400000000, volt: 900000, enabled: 1. New: freq: 400000000,
               volt: 900000, enabled: 1
  rk3399-dmc-freq dmc: _opp_add: duplicate OPPs detected. Existing: freq:
               666000000, volt: 900000, enabled: 1. New: freq: 666000000,
               volt: 900000, enabled: 1
  rk3399-dmc-freq dmc: _opp_add: duplicate OPPs detected. Existing: freq:
               800000000, volt: 900000, enabled: 1. New: freq: 800000000,
               volt: 900000, enabled: 1
  rk3399-dmc-freq dmc: _opp_add: duplicate OPPs detected. Existing: freq:
               928000000, volt: 900000, enabled: 1. New: freq: 928000000,
               volt: 900000, enabled: 1

This patch fixes the error path in the probe function and adds a .remove
function to properly cleanup the opp table on unloading.

Fixes: 5a893e31a636c (PM / devfreq: rockchip: add devfreq driver for rk3399 dmc)
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
drivers/devfreq/rk3399_dmc.c

index d5c03e5abe13dc58ed94c7437bde0d4549977fcf..e795ad2b3f6b86ef66194977f330428e240963d8 100644 (file)
@@ -375,8 +375,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
        data->rate = clk_get_rate(data->dmc_clk);
 
        opp = devfreq_recommended_opp(dev, &data->rate, 0);
-       if (IS_ERR(opp))
-               return PTR_ERR(opp);
+       if (IS_ERR(opp)) {
+               ret = PTR_ERR(opp);
+               goto err_free_opp;
+       }
 
        data->rate = dev_pm_opp_get_freq(opp);
        data->volt = dev_pm_opp_get_voltage(opp);
@@ -388,13 +390,33 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
                                           &rk3399_devfreq_dmc_profile,
                                           DEVFREQ_GOV_SIMPLE_ONDEMAND,
                                           &data->ondemand_data);
-       if (IS_ERR(data->devfreq))
-               return PTR_ERR(data->devfreq);
+       if (IS_ERR(data->devfreq)) {
+               ret = PTR_ERR(data->devfreq);
+               goto err_free_opp;
+       }
+
        devm_devfreq_register_opp_notifier(dev, data->devfreq);
 
        data->dev = dev;
        platform_set_drvdata(pdev, data);
 
+       return 0;
+
+err_free_opp:
+       dev_pm_opp_of_remove_table(&pdev->dev);
+       return ret;
+}
+
+static int rk3399_dmcfreq_remove(struct platform_device *pdev)
+{
+       struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
+
+       /*
+        * Before remove the opp table we need to unregister the opp notifier.
+        */
+       devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
+       dev_pm_opp_of_remove_table(dmcfreq->dev);
+
        return 0;
 }
 
@@ -406,6 +428,7 @@ MODULE_DEVICE_TABLE(of, rk3399dmc_devfreq_of_match);
 
 static struct platform_driver rk3399_dmcfreq_driver = {
        .probe  = rk3399_dmcfreq_probe,
+       .remove = rk3399_dmcfreq_remove,
        .driver = {
                .name   = "rk3399-dmc-freq",
                .pm     = &rk3399_dmcfreq_pm,