From 42b9fb5937c75bff0bfe7201742879979a759af0 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Mon, 25 Nov 2019 14:41:21 -0500 Subject: [PATCH] disp: msm: sde: check power event before set clk rate Clock rate can be set from debugfs, and this can attempt to set clock rate even when display power is not enabled. Set clock rate should check the last power event first. Change-Id: Ibf01753a288e5a3003928664c99aa6dbf26350d6 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_core_perf.c | 5 +++-- msm/sde_power_handle.c | 14 +++++++++++++- msm/sde_power_handle.h | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index eefe21aab6..03454951ed 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -1041,7 +1041,8 @@ static ssize_t _sde_core_perf_mode_write(struct file *file, SDE_ERROR("failed to set %s clock rate %llu\n", perf->clk_name, perf->max_core_clk_rate); - DRM_INFO("minimum performance mode\n"); + else + DRM_INFO("minimum performance mode\n"); } else if (perf_mode == SDE_PERF_MODE_NORMAL) { /* reset the perf tune params to 0 */ perf->perf_tune.min_core_clk = 0; diff --git a/msm/sde_power_handle.c b/msm/sde_power_handle.c index 3eb646d58c..7e52d2705e 100644 --- a/msm/sde_power_handle.c +++ b/msm/sde_power_handle.c @@ -48,8 +48,10 @@ static void sde_power_event_trigger_locked(struct sde_power_handle *phandle, struct sde_power_event *event; list_for_each_entry(event, &phandle->event_list, list) { - if (event->event_type & event_type) + if (event->event_type & event_type) { event->cb_fnc(event_type, event->usr); + phandle->last_event_handled = event_type; + } } } @@ -768,6 +770,15 @@ int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, pr_err("invalid input power handle\n"); return -EINVAL; } + + mutex_lock(&phandle->phandle_lock); + if (phandle->last_event_handled & SDE_POWER_EVENT_POST_DISABLE) { + pr_debug("invalid power state %u\n", + phandle->last_event_handled); + mutex_unlock(&phandle->phandle_lock); + return -EINVAL; + } + mp = &phandle->mp; for (i = 0; i < mp->num_clk; i++) { @@ -781,6 +792,7 @@ int sde_power_clk_set_rate(struct sde_power_handle *phandle, char *clock_name, break; } } + mutex_unlock(&phandle->phandle_lock); return rc; } diff --git a/msm/sde_power_handle.h b/msm/sde_power_handle.h index c764ccc0da..5b7c2197b3 100644 --- a/msm/sde_power_handle.h +++ b/msm/sde_power_handle.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_POWER_HANDLE_H_ @@ -154,6 +154,7 @@ struct sde_power_handle { struct sde_power_data_bus_handle data_bus_handle [SDE_POWER_HANDLE_DBUS_ID_MAX]; struct list_head event_list; + u32 last_event_handled; struct sde_rsc_client *rsc_client; bool rsc_client_init; };