diff options
author | Michael Gernoth <michael@gernoth.net> | 2016-01-14 08:25:18 +0100 |
---|---|---|
committer | Ziyan <jaraidaniel@gmail.com> | 2016-01-24 13:32:21 +0100 |
commit | b305089a2131e5417dd73754e7701e617669f03a (patch) | |
tree | d3872c6f6d07e147ecc89aef87b824e1c550e8d3 | |
parent | 56600c47604785dfe60e0849dbbe756116677902 (diff) | |
download | kernel_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.c | 34 |
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); |