/* serialize access to hardware register and enabled below */
struct mutex lock;
struct completion conversion_done;
+ struct device *dev;
void __iomem *regs;
struct clk *clk_sense;
struct clk *clk_bus;
writel(SFCTEMP_RSTN, sfctemp->regs);
}
-static int sfctemp_enable(struct sfctemp *sfctemp)
+static int sfctemp_clk_enable(struct sfctemp *sfctemp)
{
int ret = 0;
- mutex_lock(&sfctemp->lock);
- if (sfctemp->enabled)
- goto done;
-
ret = clk_prepare_enable(sfctemp->clk_bus);
if (ret)
goto err;
if (ret)
goto err_disable_sense;
- sfctemp_power_up(sfctemp);
- sfctemp->enabled = true;
-done:
- mutex_unlock(&sfctemp->lock);
return ret;
-
err_disable_sense:
clk_disable_unprepare(sfctemp->clk_sense);
err_assert_bus:
return ret;
}
+static int sfctemp_clk_disable(struct sfctemp *sfctemp)
+{
+ reset_control_assert(sfctemp->rst_sense);
+ clk_disable_unprepare(sfctemp->clk_sense);
+ reset_control_assert(sfctemp->rst_bus);
+ clk_disable_unprepare(sfctemp->clk_bus);
+ return 0;
+}
+
+static int sfctemp_enable(struct sfctemp *sfctemp)
+{
+ int ret = 0;
+
+ mutex_lock(&sfctemp->lock);
+ if (sfctemp->enabled || IS_ENABLED(CONFIG_PM))
+ goto done;
+
+ ret = sfctemp_clk_enable(sfctemp);
+ sfctemp_power_up(sfctemp);
+done:
+ sfctemp->enabled = true;
+ mutex_unlock(&sfctemp->lock);
+ return ret;
+}
+
static int sfctemp_disable(struct sfctemp *sfctemp)
{
mutex_lock(&sfctemp->lock);
- if (!sfctemp->enabled)
+ if (!sfctemp->enabled || IS_ENABLED(CONFIG_PM))
goto done;
sfctemp_power_down(sfctemp);
- reset_control_assert(sfctemp->rst_sense);
- clk_disable_unprepare(sfctemp->clk_sense);
- reset_control_assert(sfctemp->rst_bus);
- clk_disable_unprepare(sfctemp->clk_bus);
- sfctemp->enabled = false;
+ sfctemp_clk_disable(sfctemp);
done:
+ sfctemp->enabled = false;
mutex_unlock(&sfctemp->lock);
return 0;
}
goto out;
}
+ pm_runtime_get_sync(sfctemp->dev);
sfctemp_run_single(sfctemp);
ret = wait_for_completion_interruptible_timeout(&sfctemp->conversion_done,
* SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000;
ret = 0;
+ pm_runtime_put(sfctemp->dev);
out:
mutex_unlock(&sfctemp->lock);
return ret;
u32 attr, int channel, long *val)
{
struct sfctemp *sfctemp = dev_get_drvdata(dev);
- int ret;
-
- ret = pm_runtime_get_sync(dev);
switch (type) {
case hwmon_temp:
switch (attr) {
case hwmon_temp_enable:
*val = sfctemp->enabled;
- pm_runtime_put(dev);
return 0;
case hwmon_temp_input:
- ret = sfctemp_convert(sfctemp, val);
- pm_runtime_put(dev);
- return ret;
+ return sfctemp_convert(sfctemp, val);
}
- pm_runtime_put(dev);
return -EINVAL;
default:
- pm_runtime_put(dev);
return -EINVAL;
}
}
if (!sfctemp)
return -ENOMEM;
+ sfctemp->dev = dev;
+ sfctemp->enabled = false;
dev_set_drvdata(dev, sfctemp);
mutex_init(&sfctemp->lock);
init_completion(&sfctemp->conversion_done);
return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus),
"error getting busreset\n");
- ret = reset_control_assert(sfctemp->rst_sense);
- if (ret)
- return dev_err_probe(dev, ret, "error asserting sense reset\n");
-
- ret = reset_control_assert(sfctemp->rst_bus);
- if (ret)
- return dev_err_probe(dev, ret, "error asserting bus reset\n");
-
ret = platform_get_irq(pdev, 0);
if (ret < 0)
return ret;
hwmon_dev = devm_hwmon_device_register_with_info(dev, pdev->name, sfctemp,
&sfctemp_chip_info, NULL);
-
- pm_runtime_enable(hwmon_dev);
pm_runtime_enable(dev);
- sfctemp_disable(sfctemp);
-
return PTR_ERR_OR_ZERO(hwmon_dev);
}
#ifdef CONFIG_PM
-
static int starfive_temp_suspend(struct device *dev)
{
struct sfctemp *sfctemp = dev_get_drvdata(dev);
- dev_dbg(dev, "starfive temp runtime suspend");
-
- return sfctemp_disable(sfctemp);
+ dev_dbg(dev, "starfive temp runtime suspend\n");
+ sfctemp_power_down(sfctemp);
+ return sfctemp_clk_disable(sfctemp);
}
static int starfive_temp_resume(struct device *dev)
{
struct sfctemp *sfctemp = dev_get_drvdata(dev);
+ int ret;
- dev_dbg(dev, "starfive temp runtime resume");
+ dev_dbg(dev, "starfive temp runtime resume\n");
- return sfctemp_enable(sfctemp);
+ ret = sfctemp_clk_enable(sfctemp);
+ sfctemp_power_up(sfctemp);
+ return ret;
}
#endif /* CONFIG_PM */