aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Gernoth <michael@gernoth.net>2016-01-14 08:25:18 +0100
committerZiyan <jaraidaniel@gmail.com>2016-01-24 13:32:21 +0100
commitb305089a2131e5417dd73754e7701e617669f03a (patch)
treed3872c6f6d07e147ecc89aef87b824e1c550e8d3
parent56600c47604785dfe60e0849dbbe756116677902 (diff)
downloadkernel_samsung_tuna-b305089a2131e5417dd73754e7701e617669f03a.tar.gz
kernel_samsung_tuna-b305089a2131e5417dd73754e7701e617669f03a.tar.bz2
kernel_samsung_tuna-b305089a2131e5417dd73754e7701e617669f03a.zip
dss/manager: fix possible race by only touching cpr_coefs
If manager info got changed in between the get_info and the set_info_nocb in cpr_coef_store, this might lead to dropping important changes in the manager info. Fix this by just modifying the cpr_coefs in the existing info and not touching the rest. Change-Id: Iaab095e7532ff4f69c204e1c7322d64099957f84
-rw-r--r--drivers/video/omap2/dss/manager.c34
1 files changed, 9 insertions, 25 deletions
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 5f1c5692cde..7b6bbd797cc 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -343,13 +343,12 @@ static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
info.cpr_coefs.bb);
}
-static int omap_dss_mgr_set_info_nocb(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info);
+static int omap_dss_mgr_set_cpr_coefs(struct omap_overlay_manager *mgr,
+ struct omap_dss_cpr_coefs *coefs);
static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
const char *buf, size_t size)
{
- struct omap_overlay_manager_info info;
struct omap_dss_cpr_coefs coefs;
int r, i;
s16 *arr;
@@ -372,11 +371,7 @@ static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
return -EINVAL;
}
- mgr->get_manager_info(mgr, &info);
-
- info.cpr_coefs = coefs;
-
- r = omap_dss_mgr_set_info_nocb(mgr, &info);
+ r = omap_dss_mgr_set_cpr_coefs(mgr, &coefs);
if (r)
return r;
@@ -2449,28 +2444,17 @@ static int omap_dss_mgr_set_info(struct omap_overlay_manager *mgr,
}
/*
- * Don't call the callback with the old_info, just drop it.
- * Only use this when explicitly modifying the old config.
- * TODO: Fix interrupt races
+ * Don't call the callback with the old_info, just drop it,
+ * We only change cpr_coefs here, so nothing of valyue gets
+ * lost (only intermediate previous cpr values).
*/
-static int omap_dss_mgr_set_info_nocb(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info)
+static int omap_dss_mgr_set_cpr_coefs(struct omap_overlay_manager *mgr,
+ struct omap_dss_cpr_coefs *coefs)
{
- int r;
- struct omap_overlay_manager_info old_info;
unsigned long flags;
spin_lock_irqsave(&dss_cache.lock, flags);
- old_info = mgr->info;
- mgr->info = *info;
-
- r = dss_check_manager(mgr);
- if (r) {
- mgr->info = old_info;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
- return r;
- }
-
+ mgr->info.cpr_coefs = *coefs;
mgr->info_dirty = true;
spin_unlock_irqrestore(&dss_cache.lock, flags);