Hi Carl,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on input/next]
[also build test WARNING on v5.10-rc2 next-20201103]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Carl-Philipp-Klemm/Drivers-input-misc-Add-driver-touchscreen-buttons-to-support-physically-labeled-buttons-on-touch-screen-surfaces/20201030-010622
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
config: x86_64-randconfig-m001-20201103 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <redacted>
smatch warnings:
drivers/input/misc/touchscreen-buttons.c:179 touchscreen_buttons_input_event() warn: always true condition '(buttons->queue.lastindex >= 0) => (0-u32max >= 0)'
drivers/input/misc/touchscreen-buttons.c:348 touchscreen_buttons_get_devtree_pdata() warn: possible memory leak of 'map'
drivers/input/misc/touchscreen-buttons.c:397 touchscreen_buttons_idev_opened() error: we previously assumed 'buttons' could be null (see line 389)
vim +179 drivers/input/misc/touchscreen-buttons.c
166
167 static void touchscreen_buttons_input_event(struct input_handle *handle,
168 unsigned int type, unsigned int code, int value)
169 {
170 struct touchscreen_buttons *buttons;
171
172 buttons = handle->private;
173
174 if (type == EV_SYN && code == SYN_REPORT) {
175 if (touchscreen_buttons_process_syn(&buttons->queue,
176 buttons->map, buttons->buttons_idev) == 0)
177 touchscreen_buttons_resend_events(&buttons->queue, buttons->filtered_ts_idev);
178 buttons->queue.lastindex = 0;
> 179 } else if (buttons->queue.lastindex < EVENT_QUEUE_SIZE && buttons->queue.lastindex >= 0) {
180 buttons->queue.events[buttons->queue.lastindex].type = type;
181 buttons->queue.events[buttons->queue.lastindex].code = code;
182 buttons->queue.events[buttons->queue.lastindex].value = value;
183 ++buttons->queue.lastindex;
184 } else {
185 dev_warn(buttons->dev,
186 "event_qeue overrun, will not capture events until next SYN_REPORT\n");
187 }
188 }
189
190 static void touchscreen_buttons_merge_capabilitys(struct input_dev *target, struct input_dev *source)
191 {
192 unsigned int i;
193
194 mutex_lock(&target->mutex);
195 mutex_lock(&source->mutex);
196 for (i = 0; i < BITS_TO_LONGS(INPUT_PROP_CNT); ++i)
197 target->propbit[i] = target->propbit[i] | source->propbit[i];
198 for (i = 0; i < BITS_TO_LONGS(EV_CNT); ++i)
199 target->evbit[i] = target->evbit[i] | source->evbit[i];
200 for (i = 0; i < BITS_TO_LONGS(KEY_CNT); ++i)
201 target->keybit[i] = target->keybit[i] | source->keybit[i];
202 for (i = 0; i < BITS_TO_LONGS(REL_CNT); ++i)
203 target->relbit[i] = target->relbit[i] | source->relbit[i];
204 for (i = 0; i < BITS_TO_LONGS(ABS_CNT); ++i)
205 target->absbit[i] = target->absbit[i] | source->absbit[i];
206 for (i = 0; i < BITS_TO_LONGS(MSC_CNT); ++i)
207 target->mscbit[i] = target->mscbit[i] | source->mscbit[i];
208 for (i = 0; i < BITS_TO_LONGS(LED_CNT); ++i)
209 target->ledbit[i] = target->ledbit[i] | source->ledbit[i];
210 for (i = 0; i < BITS_TO_LONGS(SND_CNT); ++i)
211 target->sndbit[i] = target->sndbit[i] | source->sndbit[i];
212 for (i = 0; i < BITS_TO_LONGS(FF_CNT); ++i)
213 target->ffbit[i] = target->ffbit[i] | source->ffbit[i];
214 for (i = 0; i < BITS_TO_LONGS(SW_CNT); ++i)
215 target->swbit[i] = target->swbit[i] | source->swbit[i];
216
217 if (*source->evbit & (1 << EV_ABS)) {
218 input_alloc_absinfo(target);
219 for (i = 0; i < ABS_CNT; ++i)
220 target->absinfo[i] = source->absinfo[i];
221 if (source->mt) {
222 input_mt_init_slots(target, source->mt->num_slots, source->mt->flags);
223 touchscreen_buttons_copy_mt_slots(target, source);
224 }
225 }
226 mutex_unlock(&source->mutex);
227 mutex_unlock(&target->mutex);
228 }
229
230 void merge_task_handler(struct work_struct *work)
231 {
232 struct touchscreen_buttons *buttons = container_of(work, struct touchscreen_buttons, merge_task);
233
234 mutex_lock(&buttons->mutex);
235 if (buttons->ts_handle && buttons->ts_handle->dev)
236 touchscreen_buttons_merge_capabilitys(buttons->filtered_ts_idev, buttons->ts_handle->dev);
237 mutex_unlock(&buttons->mutex);
238 }
239
240 void close_task_handler(struct work_struct *work)
241 {
242 struct touchscreen_buttons *buttons = container_of(work, struct touchscreen_buttons, close_task);
243
244 mutex_lock(&buttons->mutex);
245 if (buttons && buttons->ts_handle && buttons->ts_handle->open != 0)
246 input_close_device(buttons->ts_handle);
247 mutex_unlock(&buttons->mutex);
248 }
249
250 void open_task_handler(struct work_struct *work)
251 {
252 struct touchscreen_buttons *buttons = container_of(work, struct touchscreen_buttons, open_task);
253 int error;
254
255 mutex_lock(&buttons->mutex);
256 if (buttons && buttons->ts_handle) {
257 error = input_open_device(buttons->ts_handle);
258 if (error) {
259 dev_err(buttons->dev, "Failed to open input device, error %d\n", error);
260 input_unregister_handle(buttons->ts_handle);
261 kfree(buttons->ts_handle);
262 buttons->ts_handle = NULL;
263 }
264 }
265 mutex_unlock(&buttons->mutex);
266 }
267
268 static int touchscreen_buttons_input_connect(struct input_handler *handler,
269 struct input_dev *dev, const struct input_device_id *id)
270 {
271 struct touchscreen_buttons *buttons;
272
273 buttons = handler->private;
274
275 mutex_lock(&buttons->mutex);
276
277 if ((!buttons->ts_handle && device_match_of_node(&dev->dev, buttons->map->ts_node)) ||
278 (dev->dev.parent && device_match_of_node(dev->dev.parent, buttons->map->ts_node))) {
279 int error;
280
281 dev_info(buttons->dev, "Binding to device: %s\n", dev_name(&dev->dev));
282
283 buttons->ts_handle = kzalloc(sizeof(*buttons->ts_handle), GFP_KERNEL);
284 if (!buttons->ts_handle) {
285 mutex_unlock(&buttons->mutex);
286 return -ENOMEM;
287 }
288
289 buttons->ts_handle->dev = dev;
290 buttons->ts_handle->handler = handler;
291 buttons->ts_handle->name = "touchscreen-buttons";
292 buttons->ts_handle->private = handler->private;
293 buttons->queue.lastindex = 0;
294
295 error = input_register_handle(buttons->ts_handle);
296 if (error) {
297 dev_err(buttons->dev, "Failed to register input handler, error %d\n", error);
298 kfree(buttons->ts_handle);
299 buttons->ts_handle = NULL;
300 mutex_unlock(&buttons->mutex);
301 return error;
302 }
303
304 queue_work(buttons->workqueue, &buttons->merge_task);
305
306 if (buttons->filtered_ts_idev->users > 0 && buttons->ts_handle->open == 0)
307 queue_work(buttons->workqueue, &buttons->open_task);
308 }
309
310 mutex_unlock(&buttons->mutex);
311 return 0;
312 }
313
314 static void touchscreen_buttons_input_disconnect(struct input_handle *handle)
315 {
316 struct touchscreen_buttons *buttons;
317
318 buttons = handle->private;
319
320 mutex_lock(&buttons->mutex);
321 if (handle == buttons->ts_handle) {
322 input_close_device(handle);
323 input_unregister_handle(handle);
324 kfree(handle);
325 buttons->ts_handle = NULL;
326 dev_info(buttons->dev, "Touchscreen device disconnected buttons disabled\n");
327 } else {
328 dev_err(buttons->dev, "Unknown device disconnected, %p should be %p", handle,
329 buttons->ts_handle);
330 }
331 mutex_unlock(&buttons->mutex);
332 }
333
334 static struct touchscreen_button_map
335 *touchscreen_buttons_get_devtree_pdata(struct device *dev)
336 {
337 struct touchscreen_button_map *map;
338 struct fwnode_handle *child_node;
339 struct device_node *node;
340 int i;
341
342 map = kzalloc(sizeof(*map), GFP_KERNEL);
343 if (!map)
344 return ERR_PTR(-ENOMEM);
345
346 map->count = device_get_child_node_count(dev);
347 if (map->count == 0)
> 348 return ERR_PTR(-ENODEV);
349
350 map->buttons = kcalloc(map->count, sizeof(*map->buttons), GFP_KERNEL);
351 if (!map->buttons)
352 return ERR_PTR(-ENOMEM);
353
354 node = dev->of_node;
355 map->ts_node = of_parse_phandle(node, "touchscreen_phandle", 0);
356 if (!map->ts_node) {
357 dev_err(dev, "touchscreen_phandle node missing\n");
358 return ERR_PTR(-ENODEV);
359 }
360
361 dev_info(dev, "Device_node name: %s\n", map->ts_node->name);
362
363 i = 0;
364 device_for_each_child_node(dev, child_node) {
365 struct touchscreen_button *button;
366
367 button = &map->buttons[i];
368
369 fwnode_property_read_u32(child_node, "x-position", &button->x);
370 fwnode_property_read_u32(child_node, "y-position", &button->y);
371 fwnode_property_read_u32(child_node, "x-size", &button->width);
372 fwnode_property_read_u32(child_node, "y-size", &button->height);
373 fwnode_property_read_u32(child_node, "keycode", &button->keycode);
374 dev_info(dev,
375 "Adding button at x=%u y=%u size %u x %u keycode=%u\n",
376 button->x, button->y, button->width, button->height, button->keycode);
377 ++i;
378 }
379 return map;
380 }
381
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org