Skip to content

Commit

Permalink
thermal/drivers/exynos: Split initialization of TMU and the thermal zone
Browse files Browse the repository at this point in the history
This will be needed in the future, as the thermal zone subsystem might
call our callbacks right after devm_thermal_of_zone_register. Currently
we just make get_temp return EAGAIN in such case, but this will not be
possible with state-modifying callbacks, for instance set_trips.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Mateusz Majewski <m.majewski2@samsung.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20231201095625.301884-8-m.majewski2@samsung.com
  • Loading branch information
Mateusz Majewski authored and Daniel Lezcano committed Jan 2, 2024
1 parent d7a5b43 commit b72ba67
Showing 1 changed file with 50 additions and 34 deletions.
84 changes: 50 additions & 34 deletions drivers/thermal/samsung/exynos_tmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,18 +251,47 @@ static void sanitize_temp_error(struct exynos_tmu_data *data, u32 trim_info)
static int exynos_tmu_initialize(struct platform_device *pdev)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tzd = data->tzd;
int num_trips = thermal_zone_get_num_trips(tzd);
unsigned int status;
int ret = 0;

mutex_lock(&data->lock);
clk_enable(data->clk);
if (!IS_ERR(data->clk_sec))
clk_enable(data->clk_sec);

status = readb(data->base + EXYNOS_TMU_REG_STATUS);
if (!status) {
ret = -EBUSY;
} else {
data->tmu_initialize(pdev);
data->tmu_clear_irqs(data);
}

if (!IS_ERR(data->clk_sec))
clk_disable(data->clk_sec);
clk_disable(data->clk);
mutex_unlock(&data->lock);

return ret;
}

static int exynos_thermal_zone_configure(struct platform_device *pdev)
{
struct exynos_tmu_data *data = platform_get_drvdata(pdev);
struct thermal_zone_device *tzd = data->tzd;
int i, num_trips = thermal_zone_get_num_trips(tzd);
int ret = 0, temp;

ret = thermal_zone_get_crit_temp(tzd, &temp);

if (ret && data->soc != SOC_ARCH_EXYNOS5433) { /* FIXME */
dev_err(&pdev->dev,
"No CRITICAL trip point defined in device tree!\n");
goto out;
}

mutex_lock(&data->lock);

if (num_trips > data->ntrip) {
dev_info(&pdev->dev,
"More trip points than supported by this TMU.\n");
Expand All @@ -271,41 +300,26 @@ static int exynos_tmu_initialize(struct platform_device *pdev)
num_trips - data->ntrip);
}

mutex_lock(&data->lock);
clk_enable(data->clk);
if (!IS_ERR(data->clk_sec))
clk_enable(data->clk_sec);

status = readb(data->base + EXYNOS_TMU_REG_STATUS);
if (!status) {
ret = -EBUSY;
} else {
int i, ntrips =
min_t(int, num_trips, data->ntrip);

data->tmu_initialize(pdev);

/* Write temperature code for rising and falling threshold */
for (i = 0; i < ntrips; i++) {
num_trips = min_t(int, num_trips, data->ntrip);

struct thermal_trip trip;
/* Write temperature code for rising and falling threshold */
for (i = 0; i < num_trips; i++) {
struct thermal_trip trip;

ret = thermal_zone_get_trip(tzd, i, &trip);
if (ret)
goto err;
ret = thermal_zone_get_trip(tzd, i, &trip);
if (ret)
goto err;

data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS);
data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS,
trip.hysteresis / MCELSIUS);
}

data->tmu_clear_irqs(data);
data->tmu_set_trip_temp(data, i, trip.temperature / MCELSIUS);
data->tmu_set_trip_hyst(data, i, trip.temperature / MCELSIUS,
trip.hysteresis / MCELSIUS);
}

err:
clk_disable(data->clk);
mutex_unlock(&data->lock);
if (!IS_ERR(data->clk_sec))
clk_disable(data->clk_sec);
out:
return ret;
}
Expand Down Expand Up @@ -1044,10 +1058,12 @@ static int exynos_tmu_probe(struct platform_device *pdev)
break;
}

/*
* data->tzd must be registered before calling exynos_tmu_initialize(),
* requesting irq and calling exynos_tmu_control().
*/
ret = exynos_tmu_initialize(pdev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize TMU\n");
goto err_sclk;
}

data->tzd = devm_thermal_of_zone_register(&pdev->dev, 0, data,
&exynos_sensor_ops);
if (IS_ERR(data->tzd)) {
Expand All @@ -1058,9 +1074,9 @@ static int exynos_tmu_probe(struct platform_device *pdev)
goto err_sclk;
}

ret = exynos_tmu_initialize(pdev);
ret = exynos_thermal_zone_configure(pdev);
if (ret) {
dev_err(&pdev->dev, "Failed to initialize TMU\n");
dev_err(&pdev->dev, "Failed to configure the thermal zone\n");
goto err_sclk;
}

Expand Down

0 comments on commit b72ba67

Please sign in to comment.