This driver defines dcon_set_source() and dcon_set_source_sync(), where the latter calls flush_scheduled_work() which we want to remove. Since "struct dcon_priv" is per a device struct, I assume that dcon_set_source_sync() needs to wait for only one work associated with that device. Therefore, add bool argument to dcon_set_source() and wait for only one work using flush_work(). Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> --- Please see commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue() using a macro") for background. drivers/staging/olpc_dcon/olpc_dcon.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 7284cb4ac395..e0b1c91bb1a7 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -369,21 +369,18 @@ static void dcon_source_switch(struct work_struct *work) dcon->curr_src = source; } -static void dcon_set_source(struct dcon_priv *dcon, int arg) +static void dcon_set_source(struct dcon_priv *dcon, int arg, bool sync) { if (dcon->pending_src == arg) - return; + goto flush; dcon->pending_src = arg; if (dcon->curr_src != arg) schedule_work(&dcon->switch_source); -} - -static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) -{ - dcon_set_source(dcon, arg); - flush_scheduled_work(); +flush: + if (sync) + flush_work(&dcon->switch_source); } static ssize_t dcon_mode_show(struct device *dev, @@ -459,13 +456,13 @@ static ssize_t dcon_freeze_store(struct device *dev, switch (output) { case 0: - dcon_set_source(dcon, DCON_SOURCE_CPU); + dcon_set_source(dcon, DCON_SOURCE_CPU, false); break; case 1: - dcon_set_source_sync(dcon, DCON_SOURCE_DCON); + dcon_set_source(dcon, DCON_SOURCE_DCON, true); break; case 2: /* normally unused */ - dcon_set_source(dcon, DCON_SOURCE_DCON); + dcon_set_source(dcon, DCON_SOURCE_DCON, false); break; default: return -EINVAL; @@ -699,7 +696,7 @@ static int dcon_suspend(struct device *dev) if (!dcon->asleep) { /* Set up the DCON to have the source */ - dcon_set_source_sync(dcon, DCON_SOURCE_DCON); + dcon_set_source(dcon, DCON_SOURCE_DCON, true); } return 0; @@ -712,7 +709,7 @@ static int dcon_resume(struct device *dev) if (!dcon->asleep) { dcon_bus_stabilize(dcon, 0); - dcon_set_source(dcon, DCON_SOURCE_CPU); + dcon_set_source(dcon, DCON_SOURCE_CPU, false); } return 0; -- 2.18.4