Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: ipaq-micro-ts - introduce open/close

Wire up open/close so we do not try to send events until someone uses them;
this also allows us to remove micro_ts_remove() and rely fully on managed
resources.

Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

+56 -32
+56 -32
drivers/input/touchscreen/ipaq-micro-ts.c
··· 46 46 } 47 47 } 48 48 49 + static void micro_ts_toggle_receive(struct touchscreen_data *ts, bool enable) 50 + { 51 + struct ipaq_micro *micro = ts->micro; 52 + 53 + spin_lock_irq(&micro->lock); 54 + 55 + if (enable) { 56 + micro->ts = micro_ts_receive; 57 + micro->ts_data = ts; 58 + } else { 59 + micro->ts = NULL; 60 + micro->ts_data = NULL; 61 + } 62 + 63 + spin_unlock_irq(&ts->micro->lock); 64 + } 65 + 66 + static int micro_ts_open(struct input_dev *input) 67 + { 68 + struct touchscreen_data *ts = input_get_drvdata(input); 69 + 70 + micro_ts_toggle_receive(ts, true); 71 + 72 + return 0; 73 + } 74 + 75 + static void micro_ts_close(struct input_dev *input) 76 + { 77 + struct touchscreen_data *ts = input_get_drvdata(input); 78 + 79 + micro_ts_toggle_receive(ts, false); 80 + } 81 + 49 82 static int micro_ts_probe(struct platform_device *pdev) 50 83 { 84 + struct ipaq_micro *micro = dev_get_drvdata(pdev->dev.parent); 51 85 struct touchscreen_data *ts; 52 - int ret; 86 + int error; 53 87 54 88 ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); 55 89 if (!ts) 56 90 return -ENOMEM; 57 - ts->micro = dev_get_drvdata(pdev->dev.parent); 58 91 59 - platform_set_drvdata(pdev, ts); 92 + ts->micro = micro; 60 93 61 94 ts->input = devm_input_allocate_device(&pdev->dev); 62 95 if (!ts->input) { ··· 97 64 return -ENOMEM; 98 65 } 99 66 67 + ts->input->name = "ipaq micro ts"; 68 + ts->input->open = micro_ts_open; 69 + ts->input->close = micro_ts_close; 70 + 71 + input_set_drvdata(ts->input, ts); 72 + 100 73 input_set_capability(ts->input, EV_KEY, BTN_TOUCH); 101 74 input_set_capability(ts->input, EV_ABS, ABS_X); 102 75 input_set_capability(ts->input, EV_ABS, ABS_Y); 103 76 input_set_abs_params(ts->input, ABS_X, 0, 1023, 0, 0); 104 77 input_set_abs_params(ts->input, ABS_Y, 0, 1023, 0, 0); 105 78 106 - ts->input->name = "ipaq micro ts"; 107 - 108 - ret = input_register_device(ts->input); 109 - if (ret) { 79 + error = input_register_device(ts->input); 80 + if (error) { 110 81 dev_err(&pdev->dev, "error registering touch input\n"); 111 - return ret; 82 + return error; 112 83 } 113 84 114 - spin_lock_irq(&ts->micro->lock); 115 - ts->micro->ts = micro_ts_receive; 116 - ts->micro->ts_data = ts; 117 - spin_unlock_irq(&ts->micro->lock); 85 + platform_set_drvdata(pdev, ts); 118 86 119 87 dev_info(&pdev->dev, "iPAQ micro touchscreen\n"); 120 - return 0; 121 - } 122 - 123 - static int micro_ts_remove(struct platform_device *pdev) 124 - { 125 - struct touchscreen_data *ts = platform_get_drvdata(pdev); 126 - 127 - spin_lock_irq(&ts->micro->lock); 128 - ts->micro->ts = NULL; 129 - ts->micro->ts_data = NULL; 130 - spin_unlock_irq(&ts->micro->lock); 131 88 132 89 return 0; 133 90 } ··· 127 104 { 128 105 struct touchscreen_data *ts = dev_get_drvdata(dev); 129 106 130 - spin_lock_irq(&ts->micro->lock); 131 - ts->micro->ts = NULL; 132 - ts->micro->ts_data = NULL; 133 - spin_unlock_irq(&ts->micro->lock); 107 + micro_ts_toggle_receive(ts, false); 108 + 134 109 return 0; 135 110 } 136 111 137 112 static int micro_ts_resume(struct device *dev) 138 113 { 139 114 struct touchscreen_data *ts = dev_get_drvdata(dev); 115 + struct input_dev *input = ts->input; 140 116 141 - spin_lock_irq(&ts->micro->lock); 142 - ts->micro->ts = micro_ts_receive; 143 - ts->micro->ts_data = ts; 144 - spin_unlock_irq(&ts->micro->lock); 117 + mutex_lock(&input->mutex); 118 + 119 + if (input->users) 120 + micro_ts_toggle_receive(ts, true); 121 + 122 + mutex_unlock(&input->mutex); 123 + 145 124 return 0; 146 125 } 147 126 #endif ··· 158 133 .pm = &micro_ts_dev_pm_ops, 159 134 }, 160 135 .probe = micro_ts_probe, 161 - .remove = micro_ts_remove, 162 136 }; 163 137 module_platform_driver(micro_ts_device_driver); 164 138