aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorBhaktipriya Shridhar <bhaktipriya96@gmail.com>2016-08-23 16:47:03 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2016-08-25 13:11:00 -0400
commit62e5147568968e0679ab413c7cb2ef35c8a0a4e3 (patch)
tree3f840b28a599839cdd5031c7d7e715fcc003d154 /drivers/input
parent24dde60f564b1e2eb588761ba797c7b99a374860 (diff)
Input: mc13783_ts - remove deprecated create_singletheread_workqueue
The workqueue "workqueue" has a single workitem(&priv->work) and hence doesn't require ordering. Also, it is not being used on a memory reclaim path. Hence, the singlethreaded workqueue has been replaced with the use of system_wq. System workqueues have been able to handle high level of concurrency for a long time now and hence it's not required to have a singlethreaded workqueue just to gain concurrency. Unlike a dedicated per-cpu workqueue created with create_singlethread_workqueue(), system_wq allows multiple work items to overlap executions even on the same CPU; however, a per-cpu workqueue doesn't have any CPU locality or global ordering guarantee unless the target CPU is explicitly specified and thus the increase of local concurrency shouldn't make any difference. Workitem is sync cancelled in mc13783_ts_remove() to ensure that there are no workitems pending when the driver is disconnected. Signed-off-by: Bhaktipriya Shridhar <bhaktipriya96@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index 913e25a994b4..ef64f36c5ffc 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -37,7 +37,6 @@ struct mc13783_ts_priv {
37 struct input_dev *idev; 37 struct input_dev *idev;
38 struct mc13xxx *mc13xxx; 38 struct mc13xxx *mc13xxx;
39 struct delayed_work work; 39 struct delayed_work work;
40 struct workqueue_struct *workq;
41 unsigned int sample[4]; 40 unsigned int sample[4];
42 struct mc13xxx_ts_platform_data *touch; 41 struct mc13xxx_ts_platform_data *touch;
43}; 42};
@@ -54,7 +53,7 @@ static irqreturn_t mc13783_ts_handler(int irq, void *data)
54 * be rescheduled for immediate execution here. However the rearm 53 * be rescheduled for immediate execution here. However the rearm
55 * delay is HZ / 50 which is acceptable. 54 * delay is HZ / 50 which is acceptable.
56 */ 55 */
57 queue_delayed_work(priv->workq, &priv->work, 0); 56 schedule_delayed_work(&priv->work, 0);
58 57
59 return IRQ_HANDLED; 58 return IRQ_HANDLED;
60} 59}
@@ -106,16 +105,18 @@ static void mc13783_ts_report_sample(struct mc13783_ts_priv *priv)
106 105
107 dev_dbg(&idev->dev, "report (%d, %d, %d)\n", 106 dev_dbg(&idev->dev, "report (%d, %d, %d)\n",
108 x1, y1, 0x1000 - cr0); 107 x1, y1, 0x1000 - cr0);
109 queue_delayed_work(priv->workq, &priv->work, HZ / 50); 108 schedule_delayed_work(&priv->work, HZ / 50);
110 } else 109 } else {
111 dev_dbg(&idev->dev, "report release\n"); 110 dev_dbg(&idev->dev, "report release\n");
111 }
112 112
113 input_report_abs(idev, ABS_PRESSURE, 113 input_report_abs(idev, ABS_PRESSURE,
114 cr0 ? 0x1000 - cr0 : cr0); 114 cr0 ? 0x1000 - cr0 : cr0);
115 input_report_key(idev, BTN_TOUCH, cr0); 115 input_report_key(idev, BTN_TOUCH, cr0);
116 input_sync(idev); 116 input_sync(idev);
117 } else 117 } else {
118 dev_dbg(&idev->dev, "discard event\n"); 118 dev_dbg(&idev->dev, "discard event\n");
119 }
119} 120}
120 121
121static void mc13783_ts_work(struct work_struct *work) 122static void mc13783_ts_work(struct work_struct *work)
@@ -189,14 +190,6 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
189 goto err_free_mem; 190 goto err_free_mem;
190 } 191 }
191 192
192 /*
193 * We need separate workqueue because mc13783_adc_do_conversion
194 * uses keventd and thus would deadlock.
195 */
196 priv->workq = create_singlethread_workqueue("mc13783_ts");
197 if (!priv->workq)
198 goto err_free_mem;
199
200 idev->name = MC13783_TS_NAME; 193 idev->name = MC13783_TS_NAME;
201 idev->dev.parent = &pdev->dev; 194 idev->dev.parent = &pdev->dev;
202 195
@@ -215,14 +208,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
215 if (ret) { 208 if (ret) {
216 dev_err(&pdev->dev, 209 dev_err(&pdev->dev,
217 "register input device failed with %d\n", ret); 210 "register input device failed with %d\n", ret);
218 goto err_destroy_wq; 211 goto err_free_mem;
219 } 212 }
220 213
221 platform_set_drvdata(pdev, priv); 214 platform_set_drvdata(pdev, priv);
222 return 0; 215 return 0;
223 216
224err_destroy_wq:
225 destroy_workqueue(priv->workq);
226err_free_mem: 217err_free_mem:
227 input_free_device(idev); 218 input_free_device(idev);
228 kfree(priv); 219 kfree(priv);
@@ -233,7 +224,6 @@ static int mc13783_ts_remove(struct platform_device *pdev)
233{ 224{
234 struct mc13783_ts_priv *priv = platform_get_drvdata(pdev); 225 struct mc13783_ts_priv *priv = platform_get_drvdata(pdev);
235 226
236 destroy_workqueue(priv->workq);
237 input_unregister_device(priv->idev); 227 input_unregister_device(priv->idev);
238 kfree(priv); 228 kfree(priv);
239 229