| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Driver for keys on GPIO lines capable of generating interrupts. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2005 Phil Blundell |
|---|
| 5 | 6 | * Copyright 2010, 2011 David Jander <david@protonic.nl> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 9 | | - * published by the Free Software Foundation. |
|---|
| 10 | 7 | */ |
|---|
| 11 | 8 | |
|---|
| 12 | 9 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 58 | 55 | struct input_dev *input; |
|---|
| 59 | 56 | struct mutex disable_lock; |
|---|
| 60 | 57 | unsigned short *keymap; |
|---|
| 61 | | - struct gpio_button_data data[0]; |
|---|
| 58 | + struct gpio_button_data data[]; |
|---|
| 62 | 59 | }; |
|---|
| 63 | 60 | |
|---|
| 64 | 61 | /* |
|---|
| .. | .. |
|---|
| 354 | 351 | &dev_attr_disabled_switches.attr, |
|---|
| 355 | 352 | NULL, |
|---|
| 356 | 353 | }; |
|---|
| 357 | | - |
|---|
| 358 | | -static const struct attribute_group gpio_keys_attr_group = { |
|---|
| 359 | | - .attrs = gpio_keys_attrs, |
|---|
| 360 | | -}; |
|---|
| 354 | +ATTRIBUTE_GROUPS(gpio_keys); |
|---|
| 361 | 355 | |
|---|
| 362 | 356 | static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) |
|---|
| 363 | 357 | { |
|---|
| .. | .. |
|---|
| 500 | 494 | spin_lock_init(&bdata->lock); |
|---|
| 501 | 495 | |
|---|
| 502 | 496 | if (child) { |
|---|
| 503 | | - bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, |
|---|
| 504 | | - child, |
|---|
| 505 | | - GPIOD_IN, |
|---|
| 506 | | - desc); |
|---|
| 497 | + bdata->gpiod = devm_fwnode_gpiod_get(dev, child, |
|---|
| 498 | + NULL, GPIOD_IN, desc); |
|---|
| 507 | 499 | if (IS_ERR(bdata->gpiod)) { |
|---|
| 508 | 500 | error = PTR_ERR(bdata->gpiod); |
|---|
| 509 | 501 | if (error == -ENOENT) { |
|---|
| .. | .. |
|---|
| 582 | 574 | IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING; |
|---|
| 583 | 575 | break; |
|---|
| 584 | 576 | case EV_ACT_ANY: |
|---|
| 585 | | - /* fall through */ |
|---|
| 586 | 577 | default: |
|---|
| 587 | 578 | /* |
|---|
| 588 | 579 | * For other cases, we are OK letting suspend/resume |
|---|
| .. | .. |
|---|
| 774 | 765 | struct fwnode_handle *child = NULL; |
|---|
| 775 | 766 | struct gpio_keys_drvdata *ddata; |
|---|
| 776 | 767 | struct input_dev *input; |
|---|
| 777 | | - size_t size; |
|---|
| 778 | 768 | int i, error; |
|---|
| 779 | 769 | int wakeup = 0; |
|---|
| 780 | 770 | |
|---|
| .. | .. |
|---|
| 784 | 774 | return PTR_ERR(pdata); |
|---|
| 785 | 775 | } |
|---|
| 786 | 776 | |
|---|
| 787 | | - size = sizeof(struct gpio_keys_drvdata) + |
|---|
| 788 | | - pdata->nbuttons * sizeof(struct gpio_button_data); |
|---|
| 789 | | - ddata = devm_kzalloc(dev, size, GFP_KERNEL); |
|---|
| 777 | + ddata = devm_kzalloc(dev, struct_size(ddata, data, pdata->nbuttons), |
|---|
| 778 | + GFP_KERNEL); |
|---|
| 790 | 779 | if (!ddata) { |
|---|
| 791 | 780 | dev_err(dev, "failed to allocate state\n"); |
|---|
| 792 | 781 | return -ENOMEM; |
|---|
| .. | .. |
|---|
| 855 | 844 | } |
|---|
| 856 | 845 | |
|---|
| 857 | 846 | fwnode_handle_put(child); |
|---|
| 858 | | - |
|---|
| 859 | | - error = devm_device_add_group(dev, &gpio_keys_attr_group); |
|---|
| 860 | | - if (error) { |
|---|
| 861 | | - dev_err(dev, "Unable to export keys/switches, error: %d\n", |
|---|
| 862 | | - error); |
|---|
| 863 | | - return error; |
|---|
| 864 | | - } |
|---|
| 865 | 847 | |
|---|
| 866 | 848 | error = input_register_device(input); |
|---|
| 867 | 849 | if (error) { |
|---|
| .. | .. |
|---|
| 1015 | 997 | |
|---|
| 1016 | 998 | static SIMPLE_DEV_PM_OPS(gpio_keys_pm_ops, gpio_keys_suspend, gpio_keys_resume); |
|---|
| 1017 | 999 | |
|---|
| 1000 | +static void gpio_keys_shutdown(struct platform_device *pdev) |
|---|
| 1001 | +{ |
|---|
| 1002 | + int ret; |
|---|
| 1003 | + |
|---|
| 1004 | + ret = gpio_keys_suspend(&pdev->dev); |
|---|
| 1005 | + if (ret) |
|---|
| 1006 | + dev_err(&pdev->dev, "failed to shutdown\n"); |
|---|
| 1007 | +} |
|---|
| 1008 | + |
|---|
| 1018 | 1009 | static struct platform_driver gpio_keys_device_driver = { |
|---|
| 1019 | 1010 | .probe = gpio_keys_probe, |
|---|
| 1011 | + .shutdown = gpio_keys_shutdown, |
|---|
| 1020 | 1012 | .driver = { |
|---|
| 1021 | 1013 | .name = "gpio-keys", |
|---|
| 1022 | 1014 | .pm = &gpio_keys_pm_ops, |
|---|
| 1023 | 1015 | .of_match_table = gpio_keys_of_match, |
|---|
| 1016 | + .dev_groups = gpio_keys_groups, |
|---|
| 1024 | 1017 | } |
|---|
| 1025 | 1018 | }; |
|---|
| 1026 | 1019 | |
|---|