Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 3/3] Input: adxl34x- switch to using "guard" notation
From: Nuno Sá @ 2024-06-10  9:26 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input; +Cc: Michael Hennerich, linux-kernel
In-Reply-To: <20240609234122.603796-3-dmitry.torokhov@gmail.com>

On Sun, 2024-06-09 at 16:41 -0700, Dmitry Torokhov wrote:
> Switch to using guard(mutex)() notation to acquire and automatically
> release mutexes.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---

Reviewed-by: Nuno Sa <nuno.sa@analog.com>



^ permalink raw reply

* Re: [PATCH 2/3] Input: adxl34x - switch to using managed resources
From: Nuno Sá @ 2024-06-10  9:25 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input; +Cc: Michael Hennerich, linux-kernel
In-Reply-To: <20240609234122.603796-2-dmitry.torokhov@gmail.com>

On Sun, 2024-06-09 at 16:41 -0700, Dmitry Torokhov wrote:
> Switch the driver to use managed resources to simplify error handling.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---
>  drivers/input/misc/adxl34x-i2c.c |  8 ---
>  drivers/input/misc/adxl34x-spi.c |  8 ---
>  drivers/input/misc/adxl34x.c     | 85 +++++++++++---------------------
>  drivers/input/misc/adxl34x.h     |  1 -
>  4 files changed, 30 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-
> i2c.c
> index 7531c7b2d657..c05d898898e8 100644
> --- a/drivers/input/misc/adxl34x-i2c.c
> +++ b/drivers/input/misc/adxl34x-i2c.c
> @@ -98,13 +98,6 @@ static int adxl34x_i2c_probe(struct i2c_client *client)
>  	return 0;
>  }
>  
> -static void adxl34x_i2c_remove(struct i2c_client *client)
> -{
> -	struct adxl34x *ac = i2c_get_clientdata(client);
> -
> -	adxl34x_remove(ac);
> -}
> -
>  static const struct i2c_device_id adxl34x_id[] = {
>  	{ "adxl34x" },
>  	{ }
> @@ -137,7 +130,6 @@ static struct i2c_driver adxl34x_driver = {
>  		.of_match_table = adxl34x_of_id,
>  	},
>  	.probe    = adxl34x_i2c_probe,
> -	.remove   = adxl34x_i2c_remove,
>  	.id_table = adxl34x_id,
>  };
>  
> diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-
> spi.c
> index 2befcc4df0be..fd716d861832 100644
> --- a/drivers/input/misc/adxl34x-spi.c
> +++ b/drivers/input/misc/adxl34x-spi.c
> @@ -87,13 +87,6 @@ static int adxl34x_spi_probe(struct spi_device *spi)
>  	return 0;
>  }
>  
> -static void adxl34x_spi_remove(struct spi_device *spi)
> -{
> -	struct adxl34x *ac = spi_get_drvdata(spi);
> -
> -	adxl34x_remove(ac);
> -}
> -
>  static struct spi_driver adxl34x_driver = {
>  	.driver = {
>  		.name = "adxl34x",
> @@ -101,7 +94,6 @@ static struct spi_driver adxl34x_driver = {
>  		.pm = pm_sleep_ptr(&adxl34x_pm),
>  	},
>  	.probe   = adxl34x_spi_probe,
> -	.remove  = adxl34x_spi_remove,
>  };
>  
>  module_spi_driver(adxl34x_driver);
> diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
> index fbe5a56c19d1..c6c34005f5d2 100644
> --- a/drivers/input/misc/adxl34x.c
> +++ b/drivers/input/misc/adxl34x.c
> @@ -707,21 +707,21 @@ struct adxl34x *adxl34x_probe(struct device *dev, int
> irq,
>  	struct adxl34x *ac;
>  	struct input_dev *input_dev;
>  	const struct adxl34x_platform_data *pdata;
> -	int err, range, i;
> +	int error, range, i;
>  	int revid;
>  
>  	if (!irq) {
>  		dev_err(dev, "no IRQ?\n");
> -		err = -ENODEV;
> -		goto err_out;
> +		return ERR_PTR(-ENODEV);
>  	}
>  
> -	ac = kzalloc(sizeof(*ac), GFP_KERNEL);
> -	input_dev = input_allocate_device();
> -	if (!ac || !input_dev) {
> -		err = -ENOMEM;
> -		goto err_free_mem;
> -	}
> +	ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
> +	if (!ac)
> +		return ERR_PTR(-ENOMEM);
> +
> +	input_dev = devm_input_allocate_device(dev);
> +	if (!input_dev)
> +		return ERR_PTR(-ENOMEM);
>  
>  	ac->fifo_delay = fifo_delay_default;
>  
> @@ -754,14 +754,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int
> irq,
>  		break;
>  	default:
>  		dev_err(dev, "Failed to probe %s\n", input_dev->name);
> -		err = -ENODEV;
> -		goto err_free_mem;
> +		return ERR_PTR(-ENODEV);
>  	}
>  
>  	snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(dev));
>  
>  	input_dev->phys = ac->phys;
> -	input_dev->dev.parent = dev;
>  	input_dev->id.product = ac->model;
>  	input_dev->id.bustype = bops->bustype;
>  	input_dev->open = adxl34x_input_open;
> @@ -769,18 +767,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int
> irq,
>  
>  	input_set_drvdata(input_dev, ac);
>  
> -	__set_bit(ac->pdata.ev_type, input_dev->evbit);
> -
>  	if (ac->pdata.ev_type == EV_REL) {
> -		__set_bit(REL_X, input_dev->relbit);
> -		__set_bit(REL_Y, input_dev->relbit);
> -		__set_bit(REL_Z, input_dev->relbit);
> +		input_set_capability(input_dev, EV_REL, REL_X);
> +		input_set_capability(input_dev, EV_REL, REL_Y);
> +		input_set_capability(input_dev, EV_REL, REL_Z);
>  	} else {
>  		/* EV_ABS */
> -		__set_bit(ABS_X, input_dev->absbit);
> -		__set_bit(ABS_Y, input_dev->absbit);
> -		__set_bit(ABS_Z, input_dev->absbit);

Are these somehow default or already set? I guess in input_set_abs_params()...
Anyways, the move from "raw" __set_bits() to input APIs should maybe be done in
a separate patch? They are unrelated with the current one.

- Nuno Sá 



^ permalink raw reply

* Re: [PATCH 1/3] Input: adxl34x - use device core to create driver-specific device attributes
From: Nuno Sá @ 2024-06-10  9:17 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input; +Cc: Michael Hennerich, linux-kernel
In-Reply-To: <20240609234122.603796-1-dmitry.torokhov@gmail.com>

On Sun, 2024-06-09 at 16:41 -0700, Dmitry Torokhov wrote:
> Instead of creating driver-specific device attributes with
> sysfs_create_group() have device core do this by setting up dev_groups
> pointer in the driver structure.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> ---

Reviewed-by: Nuno Sa <nuno.sa@analog.com>



^ permalink raw reply

* Re: [PATCH] HID: uclogic: avoid linking common code into multiple modules
From: Arnd Bergmann @ 2024-06-10  6:24 UTC (permalink / raw)
  To: José Expósito, Arnd Bergmann
  Cc: Jiri Kosina, Benjamin Tissoires, Rahul Rameshbabu, Fabio Baltieri,
	Ivan Gorinov, Johannes Roith, linux-input, linux-kernel
In-Reply-To: <ZmSi5_-4mD4AaIJW@fedora>

On Sat, Jun 8, 2024, at 20:28, José Expósito wrote:
> On Wed, May 29, 2024 at 11:48:05AM +0200, Arnd Bergmann wrote:

>> @@ -154,10 +152,8 @@ obj-$(CONFIG_HID_WINWING)	+= hid-winwing.o
>>  obj-$(CONFIG_HID_SENSOR_HUB)	+= hid-sensor-hub.o
>>  obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR)	+= hid-sensor-custom.o
>>  
>> -hid-uclogic-test-objs		:= hid-uclogic-rdesc.o \
>> -				   hid-uclogic-params.o \
>> -				   hid-uclogic-rdesc-test.o
>> -obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic-test.o
>> +hid-uclogic-test-objs		:= hid-uclogic-rdesc-test.o
>> +obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic-test.o hid-uclogic-params.o hid-uclogic-params.o
>>  
>>  obj-$(CONFIG_USB_HID)		+= usbhid/
>>  obj-$(CONFIG_USB_MOUSE)		+= usbhid/
>
> I tested your patch with:
>
> 	hid-uclogic-objs		:= hid-uclogic-core.o \
> 					   hid-uclogic-rdesc.o \
> 					   hid-uclogic-params.o
> 	obj-$(CONFIG_HID_UCLOGIC)	+= hid-uclogic.o
> 	[...]
> 	hid-uclogic-test-objs		:= hid-uclogic-rdesc-test.o
> 	obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic.o hid-uclogic-test.o
>
> And I think it is a bit more clear and it looks like it does the trick
> removing the warning.

Right, that seems fine.

> Also, with that change only "EXPORT_SYMBOL_GPL(uclogic_rdesc_template_apply);"
> is required. The other EXPORT_SYMBOL_GPL can be removed.
>
> However, I'm not sure about what are the best practices using EXPORT_SYMBOL_GPL
> and if it should be used for each function/data in the .h file. Maybe that's
> why you added them.

No, having only the single export is better here, you should
have as few of them as possible. I did picked the more complicated
approach as I wasn't sure if loading the entire driver from the
test module caused any problems. Let's use your simpler patch
then.

     Arnd

^ permalink raw reply

* Re: [PATCH] Input: adc-joystick - move axes data into the main structure
From: kernel test robot @ 2024-06-10  6:13 UTC (permalink / raw)
  To: Dmitry Torokhov, linux-input
  Cc: llvm, oe-kbuild-all, Artur Rojek, Chris Morgan, linux-kernel
In-Reply-To: <ZmYlfKDm5sgB44EU@google.com>

Hi Dmitry,

kernel test robot noticed the following build warnings:

[auto build test WARNING on dtor-input/next]
[cannot apply to dtor-input/for-linus hid/for-next linus/master v6.10-rc3 next-20240607]
[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#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Dmitry-Torokhov/Input-adc-joystick-move-axes-data-into-the-main-structure/20240610-060124
base:   https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link:    https://lore.kernel.org/r/ZmYlfKDm5sgB44EU%40google.com
patch subject: [PATCH] Input: adc-joystick - move axes data into the main structure
config: i386-buildonly-randconfig-006-20240610 (https://download.01.org/0day-ci/archive/20240610/202406101440.sNrwqJte-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240610/202406101440.sNrwqJte-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406101440.sNrwqJte-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/input/joystick/adc-joystick.c:166:9: warning: variable 'axes' is uninitialized when used here [-Wuninitialized]
     166 |                                                  &axes[i].code);
         |                                                   ^~~~
   drivers/input/joystick/adc-joystick.c:134:32: note: initialize the variable 'axes' to silence this warning
     134 |         struct adc_joystick_axis *axes;
         |                                       ^
         |                                        = NULL
>> drivers/input/joystick/adc-joystick.c:241:19: warning: variable 'joy' is uninitialized when used here [-Wuninitialized]
     241 |                 error = PTR_ERR(joy->chans);
         |                                 ^~~
   drivers/input/joystick/adc-joystick.c:233:26: note: initialize the variable 'joy' to silence this warning
     233 |         struct adc_joystick *joy;
         |                                 ^
         |                                  = NULL
   2 warnings generated.


vim +/axes +166 drivers/input/joystick/adc-joystick.c

2c2b364fddd551 Artur Rojek     2020-09-28  131  
2c2b364fddd551 Artur Rojek     2020-09-28  132  static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
2c2b364fddd551 Artur Rojek     2020-09-28  133  {
2c2b364fddd551 Artur Rojek     2020-09-28  134  	struct adc_joystick_axis *axes;
2c2b364fddd551 Artur Rojek     2020-09-28  135  	struct fwnode_handle *child;
815b74328f141f Dmitry Torokhov 2024-06-09  136  	s32 range[2], fuzz, flat;
815b74328f141f Dmitry Torokhov 2024-06-09  137  	unsigned int num_axes;
815b74328f141f Dmitry Torokhov 2024-06-09  138  	int error, i;
2c2b364fddd551 Artur Rojek     2020-09-28  139  
2c2b364fddd551 Artur Rojek     2020-09-28  140  	num_axes = device_get_child_node_count(dev);
2c2b364fddd551 Artur Rojek     2020-09-28  141  	if (!num_axes) {
2c2b364fddd551 Artur Rojek     2020-09-28  142  		dev_err(dev, "Unable to find child nodes\n");
2c2b364fddd551 Artur Rojek     2020-09-28  143  		return -EINVAL;
2c2b364fddd551 Artur Rojek     2020-09-28  144  	}
2c2b364fddd551 Artur Rojek     2020-09-28  145  
2c2b364fddd551 Artur Rojek     2020-09-28  146  	if (num_axes != joy->num_chans) {
2c2b364fddd551 Artur Rojek     2020-09-28  147  		dev_err(dev, "Got %d child nodes for %d channels\n",
2c2b364fddd551 Artur Rojek     2020-09-28  148  			num_axes, joy->num_chans);
2c2b364fddd551 Artur Rojek     2020-09-28  149  		return -EINVAL;
2c2b364fddd551 Artur Rojek     2020-09-28  150  	}
2c2b364fddd551 Artur Rojek     2020-09-28  151  
2c2b364fddd551 Artur Rojek     2020-09-28  152  	device_for_each_child_node(dev, child) {
2c2b364fddd551 Artur Rojek     2020-09-28  153  		error = fwnode_property_read_u32(child, "reg", &i);
2c2b364fddd551 Artur Rojek     2020-09-28  154  		if (error) {
2c2b364fddd551 Artur Rojek     2020-09-28  155  			dev_err(dev, "reg invalid or missing\n");
2c2b364fddd551 Artur Rojek     2020-09-28  156  			goto err_fwnode_put;
2c2b364fddd551 Artur Rojek     2020-09-28  157  		}
2c2b364fddd551 Artur Rojek     2020-09-28  158  
2c2b364fddd551 Artur Rojek     2020-09-28  159  		if (i >= num_axes) {
2c2b364fddd551 Artur Rojek     2020-09-28  160  			error = -EINVAL;
2c2b364fddd551 Artur Rojek     2020-09-28  161  			dev_err(dev, "No matching axis for reg %d\n", i);
2c2b364fddd551 Artur Rojek     2020-09-28  162  			goto err_fwnode_put;
2c2b364fddd551 Artur Rojek     2020-09-28  163  		}
2c2b364fddd551 Artur Rojek     2020-09-28  164  
2c2b364fddd551 Artur Rojek     2020-09-28  165  		error = fwnode_property_read_u32(child, "linux,code",
2c2b364fddd551 Artur Rojek     2020-09-28 @166  						 &axes[i].code);
2c2b364fddd551 Artur Rojek     2020-09-28  167  		if (error) {
2c2b364fddd551 Artur Rojek     2020-09-28  168  			dev_err(dev, "linux,code invalid or missing\n");
2c2b364fddd551 Artur Rojek     2020-09-28  169  			goto err_fwnode_put;
2c2b364fddd551 Artur Rojek     2020-09-28  170  		}
2c2b364fddd551 Artur Rojek     2020-09-28  171  
2c2b364fddd551 Artur Rojek     2020-09-28  172  		error = fwnode_property_read_u32_array(child, "abs-range",
815b74328f141f Dmitry Torokhov 2024-06-09  173  						       range, 2);
2c2b364fddd551 Artur Rojek     2020-09-28  174  		if (error) {
2c2b364fddd551 Artur Rojek     2020-09-28  175  			dev_err(dev, "abs-range invalid or missing\n");
2c2b364fddd551 Artur Rojek     2020-09-28  176  			goto err_fwnode_put;
2c2b364fddd551 Artur Rojek     2020-09-28  177  		}
2c2b364fddd551 Artur Rojek     2020-09-28  178  
815b74328f141f Dmitry Torokhov 2024-06-09  179  		if (range[0] > range[1]) {
6560cfcfb46511 Chris Morgan    2024-01-19  180  			dev_dbg(dev, "abs-axis %d inverted\n", i);
6560cfcfb46511 Chris Morgan    2024-01-19  181  			axes[i].inverted = true;
815b74328f141f Dmitry Torokhov 2024-06-09  182  			swap(range[0], range[1]);
6560cfcfb46511 Chris Morgan    2024-01-19  183  		}
6560cfcfb46511 Chris Morgan    2024-01-19  184  
815b74328f141f Dmitry Torokhov 2024-06-09  185  		fwnode_property_read_u32(child, "abs-fuzz", &fuzz);
815b74328f141f Dmitry Torokhov 2024-06-09  186  		fwnode_property_read_u32(child, "abs-flat", &flat);
2c2b364fddd551 Artur Rojek     2020-09-28  187  
2c2b364fddd551 Artur Rojek     2020-09-28  188  		input_set_abs_params(joy->input, axes[i].code,
815b74328f141f Dmitry Torokhov 2024-06-09  189  				     range[0], range[1], fuzz, flat);
2c2b364fddd551 Artur Rojek     2020-09-28  190  	}
2c2b364fddd551 Artur Rojek     2020-09-28  191  
2c2b364fddd551 Artur Rojek     2020-09-28  192  	return 0;
2c2b364fddd551 Artur Rojek     2020-09-28  193  
2c2b364fddd551 Artur Rojek     2020-09-28  194  err_fwnode_put:
2c2b364fddd551 Artur Rojek     2020-09-28  195  	fwnode_handle_put(child);
2c2b364fddd551 Artur Rojek     2020-09-28  196  	return error;
2c2b364fddd551 Artur Rojek     2020-09-28  197  }
2c2b364fddd551 Artur Rojek     2020-09-28  198  
815b74328f141f Dmitry Torokhov 2024-06-09  199  
815b74328f141f Dmitry Torokhov 2024-06-09  200  /*
815b74328f141f Dmitry Torokhov 2024-06-09  201   * Count how many channels we got. NULL terminated.
815b74328f141f Dmitry Torokhov 2024-06-09  202   * Do not check the storage size if using polling.
815b74328f141f Dmitry Torokhov 2024-06-09  203   */
815b74328f141f Dmitry Torokhov 2024-06-09  204  static int adc_joystick_count_channels(struct device *dev,
815b74328f141f Dmitry Torokhov 2024-06-09  205  				       const struct iio_channel *chans,
815b74328f141f Dmitry Torokhov 2024-06-09  206  				       bool polled,
815b74328f141f Dmitry Torokhov 2024-06-09  207  				       unsigned int *num_chans)
815b74328f141f Dmitry Torokhov 2024-06-09  208  {
815b74328f141f Dmitry Torokhov 2024-06-09  209  	int bits;
815b74328f141f Dmitry Torokhov 2024-06-09  210  	int i;
815b74328f141f Dmitry Torokhov 2024-06-09  211  
815b74328f141f Dmitry Torokhov 2024-06-09  212  	for (i = 0; chans[i].indio_dev; i++) {
815b74328f141f Dmitry Torokhov 2024-06-09  213  		if (polled)
815b74328f141f Dmitry Torokhov 2024-06-09  214  			continue;
815b74328f141f Dmitry Torokhov 2024-06-09  215  		bits = chans[i].channel->scan_type.storagebits;
815b74328f141f Dmitry Torokhov 2024-06-09  216  		if (!bits || bits > 16) {
815b74328f141f Dmitry Torokhov 2024-06-09  217  			dev_err(dev, "Unsupported channel storage size\n");
815b74328f141f Dmitry Torokhov 2024-06-09  218  			return -EINVAL;
815b74328f141f Dmitry Torokhov 2024-06-09  219  		}
815b74328f141f Dmitry Torokhov 2024-06-09  220  		if (bits != chans[0].channel->scan_type.storagebits) {
815b74328f141f Dmitry Torokhov 2024-06-09  221  			dev_err(dev, "Channels must have equal storage size\n");
815b74328f141f Dmitry Torokhov 2024-06-09  222  			return -EINVAL;
815b74328f141f Dmitry Torokhov 2024-06-09  223  		}
815b74328f141f Dmitry Torokhov 2024-06-09  224  	}
815b74328f141f Dmitry Torokhov 2024-06-09  225  
815b74328f141f Dmitry Torokhov 2024-06-09  226  	return i;
815b74328f141f Dmitry Torokhov 2024-06-09  227  }
815b74328f141f Dmitry Torokhov 2024-06-09  228  
2c2b364fddd551 Artur Rojek     2020-09-28  229  static int adc_joystick_probe(struct platform_device *pdev)
2c2b364fddd551 Artur Rojek     2020-09-28  230  {
2c2b364fddd551 Artur Rojek     2020-09-28  231  	struct device *dev = &pdev->dev;
815b74328f141f Dmitry Torokhov 2024-06-09  232  	struct iio_channel *chans;
2c2b364fddd551 Artur Rojek     2020-09-28  233  	struct adc_joystick *joy;
2c2b364fddd551 Artur Rojek     2020-09-28  234  	struct input_dev *input;
815b74328f141f Dmitry Torokhov 2024-06-09  235  	unsigned int poll_interval = 0;
815b74328f141f Dmitry Torokhov 2024-06-09  236  	unsigned int num_chans;
2c2b364fddd551 Artur Rojek     2020-09-28  237  	int error;
2c2b364fddd551 Artur Rojek     2020-09-28  238  
815b74328f141f Dmitry Torokhov 2024-06-09  239  	chans = devm_iio_channel_get_all(dev);
815b74328f141f Dmitry Torokhov 2024-06-09  240  	if (IS_ERR(chans)) {
2c2b364fddd551 Artur Rojek     2020-09-28 @241  		error = PTR_ERR(joy->chans);
2c2b364fddd551 Artur Rojek     2020-09-28  242  		if (error != -EPROBE_DEFER)
2c2b364fddd551 Artur Rojek     2020-09-28  243  			dev_err(dev, "Unable to get IIO channels");
2c2b364fddd551 Artur Rojek     2020-09-28  244  		return error;
2c2b364fddd551 Artur Rojek     2020-09-28  245  	}
2c2b364fddd551 Artur Rojek     2020-09-28  246  
24c06e000e8fa2 Chris Morgan    2022-08-16  247  	error = device_property_read_u32(dev, "poll-interval", &poll_interval);
24c06e000e8fa2 Chris Morgan    2022-08-16  248  	if (error) {
24c06e000e8fa2 Chris Morgan    2022-08-16  249  		/* -EINVAL means the property is absent. */
24c06e000e8fa2 Chris Morgan    2022-08-16  250  		if (error != -EINVAL)
24c06e000e8fa2 Chris Morgan    2022-08-16  251  			return error;
24c06e000e8fa2 Chris Morgan    2022-08-16  252  	} else if (poll_interval == 0) {
24c06e000e8fa2 Chris Morgan    2022-08-16  253  		dev_err(dev, "Unable to get poll-interval\n");
24c06e000e8fa2 Chris Morgan    2022-08-16  254  		return -EINVAL;
24c06e000e8fa2 Chris Morgan    2022-08-16  255  	}
24c06e000e8fa2 Chris Morgan    2022-08-16  256  
815b74328f141f Dmitry Torokhov 2024-06-09  257  	error = adc_joystick_count_channels(dev, chans, poll_interval != 0,
815b74328f141f Dmitry Torokhov 2024-06-09  258  					    &num_chans);
815b74328f141f Dmitry Torokhov 2024-06-09  259  	if (error)
815b74328f141f Dmitry Torokhov 2024-06-09  260  		return error;
815b74328f141f Dmitry Torokhov 2024-06-09  261  
815b74328f141f Dmitry Torokhov 2024-06-09  262  	joy = devm_kzalloc(dev, struct_size(joy, axes, num_chans), GFP_KERNEL);
815b74328f141f Dmitry Torokhov 2024-06-09  263  	if (!joy)
815b74328f141f Dmitry Torokhov 2024-06-09  264  		return -ENOMEM;
815b74328f141f Dmitry Torokhov 2024-06-09  265  
815b74328f141f Dmitry Torokhov 2024-06-09  266  	joy->chans = chans;
815b74328f141f Dmitry Torokhov 2024-06-09  267  	joy->num_chans = num_chans;
2c2b364fddd551 Artur Rojek     2020-09-28  268  
2c2b364fddd551 Artur Rojek     2020-09-28  269  	input = devm_input_allocate_device(dev);
2c2b364fddd551 Artur Rojek     2020-09-28  270  	if (!input) {
2c2b364fddd551 Artur Rojek     2020-09-28  271  		dev_err(dev, "Unable to allocate input device\n");
2c2b364fddd551 Artur Rojek     2020-09-28  272  		return -ENOMEM;
2c2b364fddd551 Artur Rojek     2020-09-28  273  	}
2c2b364fddd551 Artur Rojek     2020-09-28  274  
2c2b364fddd551 Artur Rojek     2020-09-28  275  	joy->input = input;
2c2b364fddd551 Artur Rojek     2020-09-28  276  	input->name = pdev->name;
2c2b364fddd551 Artur Rojek     2020-09-28  277  	input->id.bustype = BUS_HOST;
2c2b364fddd551 Artur Rojek     2020-09-28  278  
2c2b364fddd551 Artur Rojek     2020-09-28  279  	error = adc_joystick_set_axes(dev, joy);
2c2b364fddd551 Artur Rojek     2020-09-28  280  	if (error)
2c2b364fddd551 Artur Rojek     2020-09-28  281  		return error;
2c2b364fddd551 Artur Rojek     2020-09-28  282  
815b74328f141f Dmitry Torokhov 2024-06-09  283  	if (poll_interval != 0) {
24c06e000e8fa2 Chris Morgan    2022-08-16  284  		input_setup_polling(input, adc_joystick_poll);
24c06e000e8fa2 Chris Morgan    2022-08-16  285  		input_set_poll_interval(input, poll_interval);
24c06e000e8fa2 Chris Morgan    2022-08-16  286  	} else {
24c06e000e8fa2 Chris Morgan    2022-08-16  287  		input->open = adc_joystick_open;
24c06e000e8fa2 Chris Morgan    2022-08-16  288  		input->close = adc_joystick_close;
24c06e000e8fa2 Chris Morgan    2022-08-16  289  
24c06e000e8fa2 Chris Morgan    2022-08-16  290  		joy->buffer = iio_channel_get_all_cb(dev, adc_joystick_handle,
24c06e000e8fa2 Chris Morgan    2022-08-16  291  						     joy);
2c2b364fddd551 Artur Rojek     2020-09-28  292  		if (IS_ERR(joy->buffer)) {
2c2b364fddd551 Artur Rojek     2020-09-28  293  			dev_err(dev, "Unable to allocate callback buffer\n");
2c2b364fddd551 Artur Rojek     2020-09-28  294  			return PTR_ERR(joy->buffer);
2c2b364fddd551 Artur Rojek     2020-09-28  295  		}
2c2b364fddd551 Artur Rojek     2020-09-28  296  
24c06e000e8fa2 Chris Morgan    2022-08-16  297  		error = devm_add_action_or_reset(dev, adc_joystick_cleanup,
24c06e000e8fa2 Chris Morgan    2022-08-16  298  						 joy->buffer);
2c2b364fddd551 Artur Rojek     2020-09-28  299  		if (error)  {
2c2b364fddd551 Artur Rojek     2020-09-28  300  			dev_err(dev, "Unable to add action\n");
2c2b364fddd551 Artur Rojek     2020-09-28  301  			return error;
2c2b364fddd551 Artur Rojek     2020-09-28  302  		}
24c06e000e8fa2 Chris Morgan    2022-08-16  303  	}
2c2b364fddd551 Artur Rojek     2020-09-28  304  
7c744d00990ea9 Dmitry Torokhov 2022-08-02  305  	input_set_drvdata(input, joy);
7c744d00990ea9 Dmitry Torokhov 2022-08-02  306  
7c744d00990ea9 Dmitry Torokhov 2022-08-02  307  	error = input_register_device(input);
7c744d00990ea9 Dmitry Torokhov 2022-08-02  308  	if (error) {
7c744d00990ea9 Dmitry Torokhov 2022-08-02  309  		dev_err(dev, "Unable to register input device\n");
7c744d00990ea9 Dmitry Torokhov 2022-08-02  310  		return error;
7c744d00990ea9 Dmitry Torokhov 2022-08-02  311  	}
7c744d00990ea9 Dmitry Torokhov 2022-08-02  312  
2c2b364fddd551 Artur Rojek     2020-09-28  313  	return 0;
2c2b364fddd551 Artur Rojek     2020-09-28  314  }
2c2b364fddd551 Artur Rojek     2020-09-28  315  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH 2/2] Input: ims-pcu - switch to using cleanup functions
From: Dmitry Torokhov @ 2024-06-10  4:18 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel
In-Reply-To: <20240610041813.722445-1-dmitry.torokhov@gmail.com>

Start using __free() and guard() primitives to simplify the code
and error handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/misc/ims-pcu.c | 135 ++++++++++++++++-------------------
 1 file changed, 62 insertions(+), 73 deletions(-)

diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 0e61d969662f..e7bd8f9858ac 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -928,9 +928,8 @@ static void ims_pcu_process_async_firmware(const struct firmware *fw,
 		goto out;
 	}
 
-	mutex_lock(&pcu->cmd_mutex);
-	ims_pcu_handle_firmware_update(pcu, fw);
-	mutex_unlock(&pcu->cmd_mutex);
+	scoped_guard(mutex, &pcu->cmd_mutex)
+		ims_pcu_handle_firmware_update(pcu, fw);
 
 	release_firmware(fw);
 
@@ -954,7 +953,7 @@ static int ims_pcu_backlight_set_brightness(struct led_classdev *cdev,
 	__le16 br_val = cpu_to_le16(value);
 	int error;
 
-	mutex_lock(&pcu->cmd_mutex);
+	guard(mutex)(&pcu->cmd_mutex);
 
 	error = ims_pcu_execute_command(pcu, SET_BRIGHTNESS,
 					&br_val, sizeof(br_val));
@@ -963,8 +962,6 @@ static int ims_pcu_backlight_set_brightness(struct led_classdev *cdev,
 			 "Failed to set desired brightness %u, error: %d\n",
 			 value, error);
 
-	mutex_unlock(&pcu->cmd_mutex);
-
 	return error;
 }
 
@@ -978,7 +975,7 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev)
 	int brightness;
 	int error;
 
-	mutex_lock(&pcu->cmd_mutex);
+	guard(mutex)(&pcu->cmd_mutex);
 
 	error = ims_pcu_execute_query(pcu, GET_BRIGHTNESS);
 	if (error) {
@@ -992,8 +989,6 @@ ims_pcu_backlight_get_brightness(struct led_classdev *cdev)
 			get_unaligned_le16(&pcu->cmd_buf[IMS_PCU_DATA_OFFSET]);
 	}
 
-	mutex_unlock(&pcu->cmd_mutex);
-
 	return brightness;
 }
 
@@ -1073,24 +1068,23 @@ static ssize_t ims_pcu_attribute_store(struct device *dev,
 	if (data_len > attr->field_length)
 		return -EINVAL;
 
-	error = mutex_lock_interruptible(&pcu->cmd_mutex);
-	if (error)
-		return error;
+	scoped_cond_guard(mutex, return -EINTR, &pcu->cmd_mutex) {
+		memset(field, 0, attr->field_length);
+		memcpy(field, buf, data_len);
 
-	memset(field, 0, attr->field_length);
-	memcpy(field, buf, data_len);
+		error = ims_pcu_set_info(pcu);
 
-	error = ims_pcu_set_info(pcu);
-
-	/*
-	 * Even if update failed, let's fetch the info again as we just
-	 * clobbered one of the fields.
-	 */
-	ims_pcu_get_info(pcu);
+		/*
+		 * Even if update failed, let's fetch the info again as we just
+		 * clobbered one of the fields.
+		 */
+		ims_pcu_get_info(pcu);
 
-	mutex_unlock(&pcu->cmd_mutex);
+		if (error)
+			return error;
+	}
 
-	return error < 0 ? error : count;
+	return count;
 }
 
 #define IMS_PCU_ATTR(_field, _mode)					\
@@ -1153,7 +1147,6 @@ static ssize_t ims_pcu_update_firmware_store(struct device *dev,
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct ims_pcu *pcu = usb_get_intfdata(intf);
-	const struct firmware *fw = NULL;
 	int value;
 	int error;
 
@@ -1164,35 +1157,33 @@ static ssize_t ims_pcu_update_firmware_store(struct device *dev,
 	if (value != 1)
 		return -EINVAL;
 
-	error = mutex_lock_interruptible(&pcu->cmd_mutex);
-	if (error)
-		return error;
-
+	const struct firmware *fw __free(firmware) = NULL;
 	error = request_ihex_firmware(&fw, IMS_PCU_FIRMWARE_NAME, pcu->dev);
 	if (error) {
 		dev_err(pcu->dev, "Failed to request firmware %s, error: %d\n",
 			IMS_PCU_FIRMWARE_NAME, error);
-		goto out;
+		return error;
 	}
 
-	/*
-	 * If we are already in bootloader mode we can proceed with
-	 * flashing the firmware.
-	 *
-	 * If we are in application mode, then we need to switch into
-	 * bootloader mode, which will cause the device to disconnect
-	 * and reconnect as different device.
-	 */
-	if (pcu->bootloader_mode)
-		error = ims_pcu_handle_firmware_update(pcu, fw);
-	else
-		error = ims_pcu_switch_to_bootloader(pcu);
+	scoped_cond_guard(mutex_intr, return -EINTR, &pcu->cmd_mutex) {
+		/*
+		 * If we are already in bootloader mode we can proceed with
+		 * flashing the firmware.
+		 *
+		 * If we are in application mode, then we need to switch into
+		 * bootloader mode, which will cause the device to disconnect
+		 * and reconnect as different device.
+		 */
+		if (pcu->bootloader_mode)
+			error = ims_pcu_handle_firmware_update(pcu, fw);
+		else
+			error = ims_pcu_switch_to_bootloader(pcu);
 
-	release_firmware(fw);
+		if (error)
+			return error;
+	}
 
-out:
-	mutex_unlock(&pcu->cmd_mutex);
-	return error ?: count;
+	return count;
 }
 
 static DEVICE_ATTR(update_firmware, S_IWUSR,
@@ -1302,12 +1293,11 @@ static ssize_t ims_pcu_ofn_reg_data_show(struct device *dev,
 	int error;
 	u8 data;
 
-	mutex_lock(&pcu->cmd_mutex);
-	error = ims_pcu_read_ofn_config(pcu, pcu->ofn_reg_addr, &data);
-	mutex_unlock(&pcu->cmd_mutex);
-
-	if (error)
-		return error;
+	scoped_guard(mutex, &pcu->cmd_mutex) {
+		error = ims_pcu_read_ofn_config(pcu, pcu->ofn_reg_addr, &data);
+		if (error)
+			return error;
+	}
 
 	return sysfs_emit(buf, "%x\n", data);
 }
@@ -1325,11 +1315,13 @@ static ssize_t ims_pcu_ofn_reg_data_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&pcu->cmd_mutex);
+	guard(mutex)(&pcu->cmd_mutex);
+
 	error = ims_pcu_write_ofn_config(pcu, pcu->ofn_reg_addr, value);
-	mutex_unlock(&pcu->cmd_mutex);
+	if (error)
+		return error;
 
-	return error ?: count;
+	return count;
 }
 
 static DEVICE_ATTR(reg_data, S_IRUGO | S_IWUSR,
@@ -1341,13 +1333,10 @@ static ssize_t ims_pcu_ofn_reg_addr_show(struct device *dev,
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct ims_pcu *pcu = usb_get_intfdata(intf);
-	int error;
 
-	mutex_lock(&pcu->cmd_mutex);
-	error = sysfs_emit(buf, "%x\n", pcu->ofn_reg_addr);
-	mutex_unlock(&pcu->cmd_mutex);
+	guard(mutex)(&pcu->cmd_mutex);
 
-	return error;
+	return sysfs_emit(buf, "%x\n", pcu->ofn_reg_addr);
 }
 
 static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev,
@@ -1363,9 +1352,9 @@ static ssize_t ims_pcu_ofn_reg_addr_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&pcu->cmd_mutex);
+	guard(mutex)(&pcu->cmd_mutex);
+
 	pcu->ofn_reg_addr = value;
-	mutex_unlock(&pcu->cmd_mutex);
 
 	return count;
 }
@@ -1390,12 +1379,11 @@ static ssize_t ims_pcu_ofn_bit_show(struct device *dev,
 	int error;
 	u8 data;
 
-	mutex_lock(&pcu->cmd_mutex);
-	error = ims_pcu_read_ofn_config(pcu, attr->addr, &data);
-	mutex_unlock(&pcu->cmd_mutex);
-
-	if (error)
-		return error;
+	scoped_guard(mutex, &pcu->cmd_mutex) {
+		error = ims_pcu_read_ofn_config(pcu, attr->addr, &data);
+		if (error)
+			return error;
+	}
 
 	return sysfs_emit(buf, "%d\n", !!(data & (1 << attr->nr)));
 }
@@ -1419,21 +1407,22 @@ static ssize_t ims_pcu_ofn_bit_store(struct device *dev,
 	if (value > 1)
 		return -EINVAL;
 
-	mutex_lock(&pcu->cmd_mutex);
+	scoped_guard(mutex, &pcu->cmd_mutex) {
+		error = ims_pcu_read_ofn_config(pcu, attr->addr, &data);
+		if (error)
+			return error;
 
-	error = ims_pcu_read_ofn_config(pcu, attr->addr, &data);
-	if (!error) {
 		if (value)
 			data |= 1U << attr->nr;
 		else
 			data &= ~(1U << attr->nr);
 
 		error = ims_pcu_write_ofn_config(pcu, attr->addr, data);
+		if (error)
+			return error;
 	}
 
-	mutex_unlock(&pcu->cmd_mutex);
-
-	return error ?: count;
+	return count;
 }
 
 #define IMS_PCU_OFN_BIT_ATTR(_field, _addr, _nr)			\
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 1/2] Input: ims-pcu - use driver core to instantiate device attributes
From: Dmitry Torokhov @ 2024-06-10  4:18 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel

Instead of manually creating driver-specific device attributes
set struct usb_driver->dev_groups pointer to have the driver core
do it.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/misc/ims-pcu.c | 53 +++++++++++++++++++-----------------
 1 file changed, 28 insertions(+), 25 deletions(-)

diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 408a586f8c36..0e61d969662f 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1466,9 +1466,27 @@ static struct attribute *ims_pcu_ofn_attrs[] = {
 	NULL
 };
 
+static umode_t ims_pcu_ofn_is_attr_visible(struct kobject *kobj,
+					   struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct ims_pcu *pcu = usb_get_intfdata(intf);
+	umode_t mode = attr->mode;
+
+	/*
+	 * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor.
+	 */
+	if (pcu->bootloader_mode || pcu->device_id == IMS_PCU_PCU_B_DEVICE_ID)
+		mode = 0;
+
+	return mode;
+}
+
 static const struct attribute_group ims_pcu_ofn_attr_group = {
-	.name	= "ofn",
-	.attrs	= ims_pcu_ofn_attrs,
+	.name		= "ofn",
+	.is_visible	= ims_pcu_ofn_is_attr_visible,
+	.attrs		= ims_pcu_ofn_attrs,
 };
 
 static void ims_pcu_irq(struct urb *urb)
@@ -1890,16 +1908,6 @@ static int ims_pcu_init_application_mode(struct ims_pcu *pcu)
 	/* Device appears to be operable, complete initialization */
 	pcu->device_no = atomic_inc_return(&device_no);
 
-	/*
-	 * PCU-B devices, both GEN_1 and GEN_2 do not have OFN sensor
-	 */
-	if (pcu->device_id != IMS_PCU_PCU_B_DEVICE_ID) {
-		error = sysfs_create_group(&pcu->dev->kobj,
-					   &ims_pcu_ofn_attr_group);
-		if (error)
-			return error;
-	}
-
 	error = ims_pcu_setup_backlight(pcu);
 	if (error)
 		return error;
@@ -1936,10 +1944,6 @@ static void ims_pcu_destroy_application_mode(struct ims_pcu *pcu)
 			ims_pcu_destroy_gamepad(pcu);
 		ims_pcu_destroy_buttons(pcu);
 		ims_pcu_destroy_backlight(pcu);
-
-		if (pcu->device_id != IMS_PCU_PCU_B_DEVICE_ID)
-			sysfs_remove_group(&pcu->dev->kobj,
-					   &ims_pcu_ofn_attr_group);
 	}
 }
 
@@ -2031,20 +2035,14 @@ static int ims_pcu_probe(struct usb_interface *intf,
 	if (error)
 		goto err_stop_io;
 
-	error = sysfs_create_group(&intf->dev.kobj, &ims_pcu_attr_group);
-	if (error)
-		goto err_stop_io;
-
 	error = pcu->bootloader_mode ?
 			ims_pcu_init_bootloader_mode(pcu) :
 			ims_pcu_init_application_mode(pcu);
 	if (error)
-		goto err_remove_sysfs;
+		goto err_stop_io;
 
 	return 0;
 
-err_remove_sysfs:
-	sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group);
 err_stop_io:
 	ims_pcu_stop_io(pcu);
 err_free_buffers:
@@ -2070,8 +2068,6 @@ static void ims_pcu_disconnect(struct usb_interface *intf)
 	if (alt->desc.bInterfaceClass != USB_CLASS_COMM)
 		return;
 
-	sysfs_remove_group(&intf->dev.kobj, &ims_pcu_attr_group);
-
 	ims_pcu_stop_io(pcu);
 
 	if (pcu->bootloader_mode)
@@ -2130,9 +2126,16 @@ static const struct usb_device_id ims_pcu_id_table[] = {
 	{ }
 };
 
+static const struct attribute_group *ims_pcu_sysfs_groups[] = {
+	&ims_pcu_attr_group,
+	&ims_pcu_ofn_attr_group,
+	NULL
+};
+
 static struct usb_driver ims_pcu_driver = {
 	.name			= "ims_pcu",
 	.id_table		= ims_pcu_id_table,
+	.dev_groups		= ims_pcu_sysfs_groups,
 	.probe			= ims_pcu_probe,
 	.disconnect		= ims_pcu_disconnect,
 #ifdef CONFIG_PM
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 3/3] Input: rohm_bu21023 - switch to using cleanup functions
From: Dmitry Torokhov @ 2024-06-09 23:51 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel
In-Reply-To: <20240609235134.614592-1-dmitry.torokhov@gmail.com>

Start using __free() and guard() primitives to simplify the code
and error handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/rohm_bu21023.c | 40 +++++++++++-------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 7be2549fde85..0e5cc9fbad17 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -643,12 +643,12 @@ static int rohm_ts_load_firmware(struct i2c_client *client,
 				 const char *firmware_name)
 {
 	struct device *dev = &client->dev;
-	const struct firmware *fw;
 	s32 status;
 	unsigned int offset, len, xfer_len;
 	unsigned int retry = 0;
 	int error, error2;
 
+	const struct firmware *fw __free(firmware) = NULL;
 	error = request_firmware(&fw, firmware_name, dev);
 	if (error) {
 		dev_err(dev, "unable to retrieve firmware %s: %d\n",
@@ -722,8 +722,6 @@ static int rohm_ts_load_firmware(struct i2c_client *client,
 out:
 	error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
 
-	release_firmware(fw);
-
 	return error ? error : error2;
 }
 
@@ -732,22 +730,22 @@ static int rohm_ts_update_setting(struct rohm_ts_data *ts,
 {
 	int error;
 
-	error = mutex_lock_interruptible(&ts->input->mutex);
-	if (error)
-		return error;
-
-	if (on)
-		ts->setup2 |= setting_bit;
-	else
-		ts->setup2 &= ~setting_bit;
+	scoped_cond_guard(mutex_intr, return -EINTR, &ts->input->mutex) {
+		if (on)
+			ts->setup2 |= setting_bit;
+		else
+			ts->setup2 &= ~setting_bit;
 
-	if (ts->initialized)
-		error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
-						  ts->setup2);
-
-	mutex_unlock(&ts->input->mutex);
+		if (ts->initialized) {
+			error = i2c_smbus_write_byte_data(ts->client,
+							  COMMON_SETUP2,
+							  ts->setup2);
+			if (error)
+				return error;
+		}
+	}
 
-	return error;
+	return 0;
 }
 
 static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
@@ -842,7 +840,7 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
 	struct device *dev = &client->dev;
 	int error;
 
-	disable_irq(client->irq);
+	guard(disable_irq)(&client->irq);
 
 	/*
 	 * Wait 200usec for reset
@@ -1017,10 +1015,10 @@ static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
 	/* controller CPU power on */
 	error = i2c_smbus_write_byte_data(client, SYSTEM,
 					  ANALOG_POWER_ON | CPU_POWER_ON);
+	if (error)
+		return error;
 
-	enable_irq(client->irq);
-
-	return error;
+	return 0;
 }
 
 static int rohm_ts_power_off(struct i2c_client *client)
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 2/3] Input: rohm_bu21023 - switch to using sysfs_emit()
From: Dmitry Torokhov @ 2024-06-09 23:51 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel
In-Reply-To: <20240609235134.614592-1-dmitry.torokhov@gmail.com>

sysfs_emit() is preferred over snprintf() for sysfs attribute handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/rohm_bu21023.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index c432ed682d31..7be2549fde85 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -756,7 +756,7 @@ static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct rohm_ts_data *ts = i2c_get_clientdata(client);
 
-	return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
+	return sysfs_emit(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
 }
 
 static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
@@ -781,7 +781,7 @@ static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct rohm_ts_data *ts = i2c_get_clientdata(client);
 
-	return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X));
+	return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_X));
 }
 
 static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
@@ -806,7 +806,7 @@ static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
 	struct i2c_client *client = to_i2c_client(dev);
 	struct rohm_ts_data *ts = i2c_get_clientdata(client);
 
-	return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y));
+	return sysfs_emit(buf, "%d\n", !!(ts->setup2 & INV_Y));
 }
 
 static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 1/3] Input: rohm_bu21023 - factor out settings update code
From: Dmitry Torokhov @ 2024-06-09 23:51 UTC (permalink / raw)
  To: linux-input; +Cc: linux-kernel

The code to toggle axis swapping and inversion is repetitive and can
be factored out.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/rohm_bu21023.c | 77 +++++++++---------------
 1 file changed, 29 insertions(+), 48 deletions(-)

diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c
index 06fa3a19d266..c432ed682d31 100644
--- a/drivers/input/touchscreen/rohm_bu21023.c
+++ b/drivers/input/touchscreen/rohm_bu21023.c
@@ -727,6 +727,29 @@ static int rohm_ts_load_firmware(struct i2c_client *client,
 	return error ? error : error2;
 }
 
+static int rohm_ts_update_setting(struct rohm_ts_data *ts,
+				  unsigned int setting_bit, bool on)
+{
+	int error;
+
+	error = mutex_lock_interruptible(&ts->input->mutex);
+	if (error)
+		return error;
+
+	if (on)
+		ts->setup2 |= setting_bit;
+	else
+		ts->setup2 &= ~setting_bit;
+
+	if (ts->initialized)
+		error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
+						  ts->setup2);
+
+	mutex_unlock(&ts->input->mutex);
+
+	return error;
+}
+
 static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
 			    char *buf)
 {
@@ -748,22 +771,8 @@ static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
 	if (error)
 		return error;
 
-	error = mutex_lock_interruptible(&ts->input->mutex);
-	if (error)
-		return error;
-
-	if (val)
-		ts->setup2 |= SWAP_XY;
-	else
-		ts->setup2 &= ~SWAP_XY;
-
-	if (ts->initialized)
-		error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
-						  ts->setup2);
-
-	mutex_unlock(&ts->input->mutex);
-
-	return error ? error : count;
+	error = rohm_ts_update_setting(ts, SWAP_XY, val);
+	return error ?: count;
 }
 
 static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
@@ -787,22 +796,8 @@ static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
 	if (error)
 		return error;
 
-	error = mutex_lock_interruptible(&ts->input->mutex);
-	if (error)
-		return error;
-
-	if (val)
-		ts->setup2 |= INV_X;
-	else
-		ts->setup2 &= ~INV_X;
-
-	if (ts->initialized)
-		error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
-						  ts->setup2);
-
-	mutex_unlock(&ts->input->mutex);
-
-	return error ? error : count;
+	error = rohm_ts_update_setting(ts, INV_X, val);
+	return error ?: count;
 }
 
 static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
@@ -826,22 +821,8 @@ static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
 	if (error)
 		return error;
 
-	error = mutex_lock_interruptible(&ts->input->mutex);
-	if (error)
-		return error;
-
-	if (val)
-		ts->setup2 |= INV_Y;
-	else
-		ts->setup2 &= ~INV_Y;
-
-	if (ts->initialized)
-		error = i2c_smbus_write_byte_data(client, COMMON_SETUP2,
-						  ts->setup2);
-
-	mutex_unlock(&ts->input->mutex);
-
-	return error ? error : count;
+	error = rohm_ts_update_setting(ts, INV_Y, val);
+	return error ?: count;
 }
 
 static DEVICE_ATTR_RW(swap_xy);
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 3/3] Input: ili210x - use guard notation when disabling and reenabling IRQ
From: Dmitry Torokhov @ 2024-06-09 23:47 UTC (permalink / raw)
  To: linux-input; +Cc: John Keeping, Marek Vasut, linux-kernel
In-Reply-To: <20240609234757.610273-1-dmitry.torokhov@gmail.com>

This makes the code more compact and error handling more robust.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/ili210x.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index 55f3852c8dae..4573844c3395 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -860,19 +860,17 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	 * the touch controller to disable the IRQs during update, so we have
 	 * to do it this way here.
 	 */
-	disable_irq(client->irq);
+	scoped_guard(disable_irq, &client->irq) {
+		dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
 
-	dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
+		ili210x_hardware_reset(priv->reset_gpio);
 
-	ili210x_hardware_reset(priv->reset_gpio);
+		error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
 
-	error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
+		ili210x_hardware_reset(priv->reset_gpio);
 
-	ili210x_hardware_reset(priv->reset_gpio);
-
-	dev_dbg(dev, "Firmware update ended, error=%i\n", error);
-
-	enable_irq(client->irq);
+		dev_dbg(dev, "Firmware update ended, error=%i\n", error);
+	}
 
 	return error ?: count;
 }
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 2/3] Input: ili210x - switch to using cleanup functions in firmware code
From: Dmitry Torokhov @ 2024-06-09 23:47 UTC (permalink / raw)
  To: linux-input; +Cc: John Keeping, Marek Vasut, linux-kernel
In-Reply-To: <20240609234757.610273-1-dmitry.torokhov@gmail.com>

Start using __free() attributes to simplify the code and error handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/ili210x.c | 123 ++++++++++++++--------------
 1 file changed, 63 insertions(+), 60 deletions(-)

diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index f3c3ad70244f..55f3852c8dae 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -582,14 +582,12 @@ static ssize_t ili210x_calibrate(struct device *dev,
 }
 static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate);
 
-static int ili251x_firmware_to_buffer(const struct firmware *fw,
-				      u8 **buf, u16 *ac_end, u16 *df_end)
+static const u8 *ili251x_firmware_to_buffer(const struct firmware *fw,
+					    u16 *ac_end, u16 *df_end)
 {
 	const struct ihex_binrec *rec;
 	u32 fw_addr, fw_last_addr = 0;
 	u16 fw_len;
-	u8 *fw_buf;
-	int error;
 
 	/*
 	 * The firmware ihex blob can never be bigger than 64 kiB, so make this
@@ -597,9 +595,9 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
 	 * once, copy them all into this buffer at the right locations, and then
 	 * do all operations on this linear buffer.
 	 */
-	fw_buf = kvmalloc(SZ_64K, GFP_KERNEL);
+	u8* fw_buf __free(kvfree) = kvmalloc(SZ_64K, GFP_KERNEL);
 	if (!fw_buf)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	rec = (const struct ihex_binrec *)fw->data;
 	while (rec) {
@@ -607,10 +605,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
 		fw_len = be16_to_cpu(rec->len);
 
 		/* The last 32 Byte firmware block can be 0xffe0 */
-		if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32) {
-			error = -EFBIG;
-			goto err_big;
-		}
+		if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32)
+			return ERR_PTR(-EFBIG);
 
 		/* Find the last address before DF start address, that is AC end */
 		if (fw_addr == 0xf000)
@@ -623,12 +619,8 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
 
 	/* DF end address is the last address in the firmware blob */
 	*df_end = fw_addr + fw_len;
-	*buf = fw_buf;
-	return 0;
 
-err_big:
-	kvfree(fw_buf);
-	return error;
+	return_ptr(fw_buf);
 }
 
 /* Switch mode between Application and BootLoader */
@@ -691,7 +683,7 @@ static int ili251x_firmware_busy(struct i2c_client *client)
 	return 0;
 }
 
-static int ili251x_firmware_write_to_ic(struct device *dev, u8 *fwbuf,
+static int ili251x_firmware_write_to_ic(struct device *dev, const u8 *fwbuf,
 					u16 start, u16 end, u8 dataflash)
 {
 	struct i2c_client *client = to_i2c_client(dev);
@@ -776,47 +768,17 @@ static void ili210x_hardware_reset(struct gpio_desc *reset_gpio)
 	msleep(300);
 }
 
-static ssize_t ili210x_firmware_update_store(struct device *dev,
-					     struct device_attribute *attr,
-					     const char *buf, size_t count)
+static int ili210x_do_firmware_update(struct ili210x *priv,
+				      const u8 *fwbuf, u16 ac_end, u16 df_end)
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ili210x *priv = i2c_get_clientdata(client);
-	const char *fwname = ILI251X_FW_FILENAME;
-	const struct firmware *fw;
-	u16 ac_end, df_end;
-	u8 *fwbuf;
+	struct i2c_client *client = priv->client;
+	struct device *dev = &client->dev;
 	int error;
 	int i;
 
-	error = request_ihex_firmware(&fw, fwname, dev);
-	if (error) {
-		dev_err(dev, "Failed to request firmware %s, error=%d\n",
-			fwname, error);
-		return error;
-	}
-
-	error = ili251x_firmware_to_buffer(fw, &fwbuf, &ac_end, &df_end);
-	release_firmware(fw);
-	if (error)
-		return error;
-
-	/*
-	 * Disable touchscreen IRQ, so that we would not get spurious touch
-	 * interrupt during firmware update, and so that the IRQ handler won't
-	 * trigger and interfere with the firmware update. There is no bit in
-	 * the touch controller to disable the IRQs during update, so we have
-	 * to do it this way here.
-	 */
-	disable_irq(client->irq);
-
-	dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
-
-	ili210x_hardware_reset(priv->reset_gpio);
-
 	error = ili251x_firmware_reset(client);
 	if (error)
-		goto exit;
+		return error;
 
 	/* This may not succeed on first try, so re-try a few times. */
 	for (i = 0; i < 5; i++) {
@@ -826,7 +788,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	}
 
 	if (error)
-		goto exit;
+		return error;
 
 	dev_dbg(dev, "IC is now in BootLoader mode\n");
 
@@ -835,7 +797,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	error = ili251x_firmware_write_to_ic(dev, fwbuf, 0xf000, df_end, 1);
 	if (error) {
 		dev_err(dev, "DF firmware update failed, error=%d\n", error);
-		goto exit;
+		return error;
 	}
 
 	dev_dbg(dev, "DataFlash firmware written\n");
@@ -843,7 +805,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	error = ili251x_firmware_write_to_ic(dev, fwbuf, 0x2000, ac_end, 0);
 	if (error) {
 		dev_err(dev, "AC firmware update failed, error=%d\n", error);
-		goto exit;
+		return error;
 	}
 
 	dev_dbg(dev, "Application firmware written\n");
@@ -856,22 +818,63 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	}
 
 	if (error)
-		goto exit;
+		return error;
 
 	dev_dbg(dev, "IC is now in Application mode\n");
 
 	error = ili251x_firmware_update_cached_state(dev);
 	if (error)
-		goto exit;
+		return error;
 
-	error = count;
+	return 0;
+}
+
+static ssize_t ili210x_firmware_update_store(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ili210x *priv = i2c_get_clientdata(client);
+	const char *fwname = ILI251X_FW_FILENAME;
+	u16 ac_end, df_end;
+	int error;
+
+	const struct firmware *fw __free(firmware) = NULL;
+	error = request_ihex_firmware(&fw, fwname, dev);
+	if (error) {
+		dev_err(dev, "Failed to request firmware %s, error=%d\n",
+			fwname, error);
+		return error;
+	}
+
+	const u8* fwbuf __free(kvfree) =
+			ili251x_firmware_to_buffer(fw, &ac_end, &df_end);
+	error = PTR_ERR_OR_ZERO(fwbuf);
+	if (error)
+		return error;
+
+	/*
+	 * Disable touchscreen IRQ, so that we would not get spurious touch
+	 * interrupt during firmware update, and so that the IRQ handler won't
+	 * trigger and interfere with the firmware update. There is no bit in
+	 * the touch controller to disable the IRQs during update, so we have
+	 * to do it this way here.
+	 */
+	disable_irq(client->irq);
+
+	dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);
+
+	ili210x_hardware_reset(priv->reset_gpio);
+
+	error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);
 
-exit:
 	ili210x_hardware_reset(priv->reset_gpio);
+
 	dev_dbg(dev, "Firmware update ended, error=%i\n", error);
+
 	enable_irq(client->irq);
-	kvfree(fwbuf);
-	return error;
+
+	return error ?: count;
 }
 
 static DEVICE_ATTR(firmware_update, 0200, NULL, ili210x_firmware_update_store);
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 1/3] Input: ili210x - use kvmalloc() to allocate buffer for firmware update
From: Dmitry Torokhov @ 2024-06-09 23:47 UTC (permalink / raw)
  To: linux-input; +Cc: John Keeping, Marek Vasut, linux-kernel

Allocating a contiguous buffer of 64K may fail is memory is sufficiently
fragmented, and may cause OOM kill of an unrelated process. However we
do not need to have contiguous memory. We also do not need to zero
out the buffer since it will be overwritten with firmware data.

Switch to using kvmalloc() instead of kzalloc().

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/ili210x.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c
index 79bdb2b10949..f3c3ad70244f 100644
--- a/drivers/input/touchscreen/ili210x.c
+++ b/drivers/input/touchscreen/ili210x.c
@@ -597,7 +597,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
 	 * once, copy them all into this buffer at the right locations, and then
 	 * do all operations on this linear buffer.
 	 */
-	fw_buf = kzalloc(SZ_64K, GFP_KERNEL);
+	fw_buf = kvmalloc(SZ_64K, GFP_KERNEL);
 	if (!fw_buf)
 		return -ENOMEM;
 
@@ -627,7 +627,7 @@ static int ili251x_firmware_to_buffer(const struct firmware *fw,
 	return 0;
 
 err_big:
-	kfree(fw_buf);
+	kvfree(fw_buf);
 	return error;
 }
 
@@ -870,7 +870,7 @@ static ssize_t ili210x_firmware_update_store(struct device *dev,
 	ili210x_hardware_reset(priv->reset_gpio);
 	dev_dbg(dev, "Firmware update ended, error=%i\n", error);
 	enable_irq(client->irq);
-	kfree(fwbuf);
+	kvfree(fwbuf);
 	return error;
 }
 
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 3/3] Input: adxl34x- switch to using "guard" notation
From: Dmitry Torokhov @ 2024-06-09 23:41 UTC (permalink / raw)
  To: linux-input; +Cc: Michael Hennerich, linux-kernel
In-Reply-To: <20240609234122.603796-1-dmitry.torokhov@gmail.com>

Switch to using guard(mutex)() notation to acquire and automatically
release mutexes.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/misc/adxl34x.c | 61 ++++++++++++------------------------
 1 file changed, 20 insertions(+), 41 deletions(-)

diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
index c6c34005f5d2..7cafbf8d5f1a 100644
--- a/drivers/input/misc/adxl34x.c
+++ b/drivers/input/misc/adxl34x.c
@@ -241,7 +241,8 @@ static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis)
 
 	ac->bops->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1, buf);
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
+
 	ac->saved.x = (s16) le16_to_cpu(buf[0]);
 	axis->x = ac->saved.x;
 
@@ -250,7 +251,6 @@ static void adxl34x_get_triple(struct adxl34x *ac, struct axis_triple *axis)
 
 	ac->saved.z = (s16) le16_to_cpu(buf[2]);
 	axis->z = ac->saved.z;
-	mutex_unlock(&ac->mutex);
 }
 
 static void adxl34x_service_ev_fifo(struct adxl34x *ac)
@@ -416,15 +416,13 @@ static int adxl34x_suspend(struct device *dev)
 {
 	struct adxl34x *ac = dev_get_drvdata(dev);
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (!ac->suspended && !ac->disabled && ac->opened)
 		__adxl34x_disable(ac);
 
 	ac->suspended = true;
 
-	mutex_unlock(&ac->mutex);
-
 	return 0;
 }
 
@@ -432,15 +430,13 @@ static int adxl34x_resume(struct device *dev)
 {
 	struct adxl34x *ac = dev_get_drvdata(dev);
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (ac->suspended && !ac->disabled && ac->opened)
 		__adxl34x_enable(ac);
 
 	ac->suspended = false;
 
-	mutex_unlock(&ac->mutex);
-
 	return 0;
 }
 
@@ -464,7 +460,7 @@ static ssize_t adxl34x_disable_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (!ac->suspended && ac->opened) {
 		if (val) {
@@ -478,8 +474,6 @@ static ssize_t adxl34x_disable_store(struct device *dev,
 
 	ac->disabled = !!val;
 
-	mutex_unlock(&ac->mutex);
-
 	return count;
 }
 
@@ -489,16 +483,13 @@ static ssize_t adxl34x_calibrate_show(struct device *dev,
 				      struct device_attribute *attr, char *buf)
 {
 	struct adxl34x *ac = dev_get_drvdata(dev);
-	ssize_t count;
 
-	mutex_lock(&ac->mutex);
-	count = sprintf(buf, "%d,%d,%d\n",
-			ac->hwcal.x * 4 + ac->swcal.x,
-			ac->hwcal.y * 4 + ac->swcal.y,
-			ac->hwcal.z * 4 + ac->swcal.z);
-	mutex_unlock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
-	return count;
+	return sprintf(buf, "%d,%d,%d\n",
+		       ac->hwcal.x * 4 + ac->swcal.x,
+		       ac->hwcal.y * 4 + ac->swcal.y,
+		       ac->hwcal.z * 4 + ac->swcal.z);
 }
 
 static ssize_t adxl34x_calibrate_store(struct device *dev,
@@ -512,7 +503,8 @@ static ssize_t adxl34x_calibrate_store(struct device *dev,
 	 * We use HW calibration and handle the remaining bits in SW. (4mg/LSB)
 	 */
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
+
 	ac->hwcal.x -= (ac->saved.x / 4);
 	ac->swcal.x = ac->saved.x % 4;
 
@@ -525,7 +517,6 @@ static ssize_t adxl34x_calibrate_store(struct device *dev,
 	AC_WRITE(ac, OFSX, (s8) ac->hwcal.x);
 	AC_WRITE(ac, OFSY, (s8) ac->hwcal.y);
 	AC_WRITE(ac, OFSZ, (s8) ac->hwcal.z);
-	mutex_unlock(&ac->mutex);
 
 	return count;
 }
@@ -553,15 +544,13 @@ static ssize_t adxl34x_rate_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	ac->pdata.data_rate = RATE(val);
 	AC_WRITE(ac, BW_RATE,
 		 ac->pdata.data_rate |
 			(ac->pdata.low_power_mode ? LOW_POWER : 0));
 
-	mutex_unlock(&ac->mutex);
-
 	return count;
 }
 
@@ -588,7 +577,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (val)
 		ac->pdata.power_mode |= (PCTL_AUTO_SLEEP | PCTL_LINK);
@@ -598,8 +587,6 @@ static ssize_t adxl34x_autosleep_store(struct device *dev,
 	if (!ac->disabled && !ac->suspended && ac->opened)
 		AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
 
-	mutex_unlock(&ac->mutex);
-
 	return count;
 }
 
@@ -610,14 +597,11 @@ static ssize_t adxl34x_position_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	struct adxl34x *ac = dev_get_drvdata(dev);
-	ssize_t count;
 
-	mutex_lock(&ac->mutex);
-	count = sprintf(buf, "(%d, %d, %d)\n",
-			ac->saved.x, ac->saved.y, ac->saved.z);
-	mutex_unlock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
-	return count;
+	return sprintf(buf, "(%d, %d, %d)\n",
+		       ac->saved.x, ac->saved.y, ac->saved.z);
 }
 
 static DEVICE_ATTR(position, S_IRUGO, adxl34x_position_show, NULL);
@@ -638,9 +622,8 @@ static ssize_t adxl34x_write_store(struct device *dev,
 	if (error)
 		return error;
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 	AC_WRITE(ac, val >> 8, val & 0xFF);
-	mutex_unlock(&ac->mutex);
 
 	return count;
 }
@@ -674,15 +657,13 @@ static int adxl34x_input_open(struct input_dev *input)
 {
 	struct adxl34x *ac = input_get_drvdata(input);
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (!ac->suspended && !ac->disabled)
 		__adxl34x_enable(ac);
 
 	ac->opened = true;
 
-	mutex_unlock(&ac->mutex);
-
 	return 0;
 }
 
@@ -690,14 +671,12 @@ static void adxl34x_input_close(struct input_dev *input)
 {
 	struct adxl34x *ac = input_get_drvdata(input);
 
-	mutex_lock(&ac->mutex);
+	guard(mutex)(&ac->mutex);
 
 	if (!ac->suspended && !ac->disabled)
 		__adxl34x_disable(ac);
 
 	ac->opened = false;
-
-	mutex_unlock(&ac->mutex);
 }
 
 struct adxl34x *adxl34x_probe(struct device *dev, int irq,
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 2/3] Input: adxl34x - switch to using managed resources
From: Dmitry Torokhov @ 2024-06-09 23:41 UTC (permalink / raw)
  To: linux-input; +Cc: Michael Hennerich, linux-kernel
In-Reply-To: <20240609234122.603796-1-dmitry.torokhov@gmail.com>

Switch the driver to use managed resources to simplify error handling.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/misc/adxl34x-i2c.c |  8 ---
 drivers/input/misc/adxl34x-spi.c |  8 ---
 drivers/input/misc/adxl34x.c     | 85 +++++++++++---------------------
 drivers/input/misc/adxl34x.h     |  1 -
 4 files changed, 30 insertions(+), 72 deletions(-)

diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index 7531c7b2d657..c05d898898e8 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -98,13 +98,6 @@ static int adxl34x_i2c_probe(struct i2c_client *client)
 	return 0;
 }
 
-static void adxl34x_i2c_remove(struct i2c_client *client)
-{
-	struct adxl34x *ac = i2c_get_clientdata(client);
-
-	adxl34x_remove(ac);
-}
-
 static const struct i2c_device_id adxl34x_id[] = {
 	{ "adxl34x" },
 	{ }
@@ -137,7 +130,6 @@ static struct i2c_driver adxl34x_driver = {
 		.of_match_table = adxl34x_of_id,
 	},
 	.probe    = adxl34x_i2c_probe,
-	.remove   = adxl34x_i2c_remove,
 	.id_table = adxl34x_id,
 };
 
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c
index 2befcc4df0be..fd716d861832 100644
--- a/drivers/input/misc/adxl34x-spi.c
+++ b/drivers/input/misc/adxl34x-spi.c
@@ -87,13 +87,6 @@ static int adxl34x_spi_probe(struct spi_device *spi)
 	return 0;
 }
 
-static void adxl34x_spi_remove(struct spi_device *spi)
-{
-	struct adxl34x *ac = spi_get_drvdata(spi);
-
-	adxl34x_remove(ac);
-}
-
 static struct spi_driver adxl34x_driver = {
 	.driver = {
 		.name = "adxl34x",
@@ -101,7 +94,6 @@ static struct spi_driver adxl34x_driver = {
 		.pm = pm_sleep_ptr(&adxl34x_pm),
 	},
 	.probe   = adxl34x_spi_probe,
-	.remove  = adxl34x_spi_remove,
 };
 
 module_spi_driver(adxl34x_driver);
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
index fbe5a56c19d1..c6c34005f5d2 100644
--- a/drivers/input/misc/adxl34x.c
+++ b/drivers/input/misc/adxl34x.c
@@ -707,21 +707,21 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 	struct adxl34x *ac;
 	struct input_dev *input_dev;
 	const struct adxl34x_platform_data *pdata;
-	int err, range, i;
+	int error, range, i;
 	int revid;
 
 	if (!irq) {
 		dev_err(dev, "no IRQ?\n");
-		err = -ENODEV;
-		goto err_out;
+		return ERR_PTR(-ENODEV);
 	}
 
-	ac = kzalloc(sizeof(*ac), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!ac || !input_dev) {
-		err = -ENOMEM;
-		goto err_free_mem;
-	}
+	ac = devm_kzalloc(dev, sizeof(*ac), GFP_KERNEL);
+	if (!ac)
+		return ERR_PTR(-ENOMEM);
+
+	input_dev = devm_input_allocate_device(dev);
+	if (!input_dev)
+		return ERR_PTR(-ENOMEM);
 
 	ac->fifo_delay = fifo_delay_default;
 
@@ -754,14 +754,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 		break;
 	default:
 		dev_err(dev, "Failed to probe %s\n", input_dev->name);
-		err = -ENODEV;
-		goto err_free_mem;
+		return ERR_PTR(-ENODEV);
 	}
 
 	snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(dev));
 
 	input_dev->phys = ac->phys;
-	input_dev->dev.parent = dev;
 	input_dev->id.product = ac->model;
 	input_dev->id.bustype = bops->bustype;
 	input_dev->open = adxl34x_input_open;
@@ -769,18 +767,12 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 
 	input_set_drvdata(input_dev, ac);
 
-	__set_bit(ac->pdata.ev_type, input_dev->evbit);
-
 	if (ac->pdata.ev_type == EV_REL) {
-		__set_bit(REL_X, input_dev->relbit);
-		__set_bit(REL_Y, input_dev->relbit);
-		__set_bit(REL_Z, input_dev->relbit);
+		input_set_capability(input_dev, EV_REL, REL_X);
+		input_set_capability(input_dev, EV_REL, REL_Y);
+		input_set_capability(input_dev, EV_REL, REL_Z);
 	} else {
 		/* EV_ABS */
-		__set_bit(ABS_X, input_dev->absbit);
-		__set_bit(ABS_Y, input_dev->absbit);
-		__set_bit(ABS_Z, input_dev->absbit);
-
 		if (pdata->data_range & FULL_RES)
 			range = ADXL_FULLRES_MAX_VAL;	/* Signed 13-bit */
 		else
@@ -791,18 +783,18 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 		input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3);
 	}
 
-	__set_bit(EV_KEY, input_dev->evbit);
-	__set_bit(pdata->ev_code_tap[ADXL_X_AXIS], input_dev->keybit);
-	__set_bit(pdata->ev_code_tap[ADXL_Y_AXIS], input_dev->keybit);
-	__set_bit(pdata->ev_code_tap[ADXL_Z_AXIS], input_dev->keybit);
+	input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_X_AXIS]);
+	input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_Y_AXIS]);
+	input_set_capability(input_dev, EV_KEY, pdata->ev_code_tap[ADXL_Z_AXIS]);
 
 	if (pdata->ev_code_ff) {
 		ac->int_mask = FREE_FALL;
-		__set_bit(pdata->ev_code_ff, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, pdata->ev_code_ff);
 	}
 
 	if (pdata->ev_code_act_inactivity)
-		__set_bit(pdata->ev_code_act_inactivity, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY,
+				     pdata->ev_code_act_inactivity);
 
 	ac->int_mask |= ACTIVITY | INACTIVITY;
 
@@ -822,16 +814,16 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 
 	AC_WRITE(ac, POWER_CTL, 0);
 
-	err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
-				   IRQF_ONESHOT, dev_name(dev), ac);
-	if (err) {
+	error = devm_request_threaded_irq(dev, ac->irq, NULL, adxl34x_irq,
+					  IRQF_ONESHOT, dev_name(dev), ac);
+	if (error) {
 		dev_err(dev, "irq %d busy?\n", ac->irq);
-		goto err_free_mem;
+		return ERR_PTR(error);
 	}
 
-	err = input_register_device(input_dev);
-	if (err)
-		goto err_free_irq;
+	error = input_register_device(input_dev);
+	if (error)
+		return ERR_PTR(error);
 
 	AC_WRITE(ac, OFSX, pdata->x_axis_offset);
 	ac->hwcal.x = pdata->x_axis_offset;
@@ -874,13 +866,13 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 
 		if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D)
 			for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++)
-				__set_bit(pdata->ev_codes_orient_3d[i],
-					  input_dev->keybit);
+				input_set_capability(input_dev, EV_KEY,
+						     pdata->ev_codes_orient_3d[i]);
 
 		if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D)
 			for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++)
-				__set_bit(pdata->ev_codes_orient_2d[i],
-					  input_dev->keybit);
+				input_set_capability(input_dev, EV_KEY,
+						     pdata->ev_codes_orient_2d[i]);
 	} else {
 		ac->pdata.orientation_enable = 0;
 	}
@@ -890,26 +882,9 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 	ac->pdata.power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK);
 
 	return ac;
-
- err_free_irq:
-	free_irq(ac->irq, ac);
- err_free_mem:
-	input_free_device(input_dev);
-	kfree(ac);
- err_out:
-	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(adxl34x_probe);
 
-void adxl34x_remove(struct adxl34x *ac)
-{
-	free_irq(ac->irq, ac);
-	input_unregister_device(ac->input);
-	dev_dbg(ac->dev, "unregistered accelerometer\n");
-	kfree(ac);
-}
-EXPORT_SYMBOL_GPL(adxl34x_remove);
-
 EXPORT_GPL_SIMPLE_DEV_PM_OPS(adxl34x_pm, adxl34x_suspend, adxl34x_resume);
 
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h
index 67e0ddc5c3eb..718e90c2046d 100644
--- a/drivers/input/misc/adxl34x.h
+++ b/drivers/input/misc/adxl34x.h
@@ -23,7 +23,6 @@ struct adxl34x_bus_ops {
 struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 			      bool fifo_delay_default,
 			      const struct adxl34x_bus_ops *bops);
-void adxl34x_remove(struct adxl34x *ac);
 
 extern const struct dev_pm_ops adxl34x_pm;
 extern const struct attribute_group *adxl34x_groups[];
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH 1/3] Input: adxl34x - use device core to create driver-specific device attributes
From: Dmitry Torokhov @ 2024-06-09 23:41 UTC (permalink / raw)
  To: linux-input; +Cc: Michael Hennerich, linux-kernel

Instead of creating driver-specific device attributes with
sysfs_create_group() have device core do this by setting up dev_groups
pointer in the driver structure.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/misc/adxl34x-i2c.c |  1 +
 drivers/input/misc/adxl34x-spi.c |  1 +
 drivers/input/misc/adxl34x.c     | 15 +++++++--------
 drivers/input/misc/adxl34x.h     |  1 +
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/input/misc/adxl34x-i2c.c b/drivers/input/misc/adxl34x-i2c.c
index d4014e367c77..7531c7b2d657 100644
--- a/drivers/input/misc/adxl34x-i2c.c
+++ b/drivers/input/misc/adxl34x-i2c.c
@@ -132,6 +132,7 @@ MODULE_DEVICE_TABLE(of, adxl34x_of_id);
 static struct i2c_driver adxl34x_driver = {
 	.driver = {
 		.name = "adxl34x",
+		.dev_groups = adxl34x_groups,
 		.pm = pm_sleep_ptr(&adxl34x_pm),
 		.of_match_table = adxl34x_of_id,
 	},
diff --git a/drivers/input/misc/adxl34x-spi.c b/drivers/input/misc/adxl34x-spi.c
index f1094a8ccdd5..2befcc4df0be 100644
--- a/drivers/input/misc/adxl34x-spi.c
+++ b/drivers/input/misc/adxl34x-spi.c
@@ -97,6 +97,7 @@ static void adxl34x_spi_remove(struct spi_device *spi)
 static struct spi_driver adxl34x_driver = {
 	.driver = {
 		.name = "adxl34x",
+		.dev_groups = adxl34x_groups,
 		.pm = pm_sleep_ptr(&adxl34x_pm),
 	},
 	.probe   = adxl34x_spi_probe,
diff --git a/drivers/input/misc/adxl34x.c b/drivers/input/misc/adxl34x.c
index a3f45e0ee0c7..fbe5a56c19d1 100644
--- a/drivers/input/misc/adxl34x.c
+++ b/drivers/input/misc/adxl34x.c
@@ -664,6 +664,12 @@ static const struct attribute_group adxl34x_attr_group = {
 	.attrs = adxl34x_attributes,
 };
 
+const struct attribute_group *adxl34x_groups[] = {
+	&adxl34x_attr_group,
+	NULL
+};
+EXPORT_SYMBOL_GPL(adxl34x_groups);
+
 static int adxl34x_input_open(struct input_dev *input)
 {
 	struct adxl34x *ac = input_get_drvdata(input);
@@ -823,13 +829,9 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 		goto err_free_mem;
 	}
 
-	err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group);
-	if (err)
-		goto err_free_irq;
-
 	err = input_register_device(input_dev);
 	if (err)
-		goto err_remove_attr;
+		goto err_free_irq;
 
 	AC_WRITE(ac, OFSX, pdata->x_axis_offset);
 	ac->hwcal.x = pdata->x_axis_offset;
@@ -889,8 +891,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 
 	return ac;
 
- err_remove_attr:
-	sysfs_remove_group(&dev->kobj, &adxl34x_attr_group);
  err_free_irq:
 	free_irq(ac->irq, ac);
  err_free_mem:
@@ -903,7 +903,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe);
 
 void adxl34x_remove(struct adxl34x *ac)
 {
-	sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
 	free_irq(ac->irq, ac);
 	input_unregister_device(ac->input);
 	dev_dbg(ac->dev, "unregistered accelerometer\n");
diff --git a/drivers/input/misc/adxl34x.h b/drivers/input/misc/adxl34x.h
index f9272a2e7a96..67e0ddc5c3eb 100644
--- a/drivers/input/misc/adxl34x.h
+++ b/drivers/input/misc/adxl34x.h
@@ -26,5 +26,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
 void adxl34x_remove(struct adxl34x *ac);
 
 extern const struct dev_pm_ops adxl34x_pm;
+extern const struct attribute_group *adxl34x_groups[];
 
 #endif
-- 
2.45.2.505.gda0bf45e8d-goog


^ permalink raw reply related

* [PATCH] Input: adc-joystick - move axes data into the main structure
From: Dmitry Torokhov @ 2024-06-09 21:58 UTC (permalink / raw)
  To: linux-input; +Cc: Artur Rojek, Chris Morgan, linux-kernel

There is no need to allocate axes information separately from the main
joystick structure so let's fold the allocation and also drop members
(such as range, flat and fuzz) that are only used during initialization
of the device.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/joystick/adc-joystick.c | 109 ++++++++++++++------------
 1 file changed, 58 insertions(+), 51 deletions(-)

diff --git a/drivers/input/joystick/adc-joystick.c b/drivers/input/joystick/adc-joystick.c
index 916e78e4dc9f..c71e582aa32d 100644
--- a/drivers/input/joystick/adc-joystick.c
+++ b/drivers/input/joystick/adc-joystick.c
@@ -15,19 +15,15 @@
 
 struct adc_joystick_axis {
 	u32 code;
-	s32 range[2];
-	s32 fuzz;
-	s32 flat;
 	bool inverted;
 };
 
 struct adc_joystick {
 	struct input_dev *input;
 	struct iio_cb_buffer *buffer;
-	struct adc_joystick_axis *axes;
 	struct iio_channel *chans;
-	int num_chans;
-	bool polled;
+	unsigned int num_chans;
+	struct adc_joystick_axis axes[] __counted_by(num_chans);
 };
 
 static int adc_joystick_invert(struct input_dev *dev,
@@ -137,7 +133,9 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
 {
 	struct adc_joystick_axis *axes;
 	struct fwnode_handle *child;
-	int num_axes, error, i;
+	s32 range[2], fuzz, flat;
+	unsigned int num_axes;
+	int error, i;
 
 	num_axes = device_get_child_node_count(dev);
 	if (!num_axes) {
@@ -151,10 +149,6 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
 		return -EINVAL;
 	}
 
-	axes = devm_kmalloc_array(dev, num_axes, sizeof(*axes), GFP_KERNEL);
-	if (!axes)
-		return -ENOMEM;
-
 	device_for_each_child_node(dev, child) {
 		error = fwnode_property_read_u32(child, "reg", &i);
 		if (error) {
@@ -176,29 +170,25 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
 		}
 
 		error = fwnode_property_read_u32_array(child, "abs-range",
-						       axes[i].range, 2);
+						       range, 2);
 		if (error) {
 			dev_err(dev, "abs-range invalid or missing\n");
 			goto err_fwnode_put;
 		}
 
-		if (axes[i].range[0] > axes[i].range[1]) {
+		if (range[0] > range[1]) {
 			dev_dbg(dev, "abs-axis %d inverted\n", i);
 			axes[i].inverted = true;
-			swap(axes[i].range[0], axes[i].range[1]);
+			swap(range[0], range[1]);
 		}
 
-		fwnode_property_read_u32(child, "abs-fuzz", &axes[i].fuzz);
-		fwnode_property_read_u32(child, "abs-flat", &axes[i].flat);
+		fwnode_property_read_u32(child, "abs-fuzz", &fuzz);
+		fwnode_property_read_u32(child, "abs-flat", &flat);
 
 		input_set_abs_params(joy->input, axes[i].code,
-				     axes[i].range[0], axes[i].range[1],
-				     axes[i].fuzz, axes[i].flat);
-		input_set_capability(joy->input, EV_ABS, axes[i].code);
+				     range[0], range[1], fuzz, flat);
 	}
 
-	joy->axes = axes;
-
 	return 0;
 
 err_fwnode_put:
@@ -206,22 +196,48 @@ static int adc_joystick_set_axes(struct device *dev, struct adc_joystick *joy)
 	return error;
 }
 
+
+/*
+ * Count how many channels we got. NULL terminated.
+ * Do not check the storage size if using polling.
+ */
+static int adc_joystick_count_channels(struct device *dev,
+				       const struct iio_channel *chans,
+				       bool polled,
+				       unsigned int *num_chans)
+{
+	int bits;
+	int i;
+
+	for (i = 0; chans[i].indio_dev; i++) {
+		if (polled)
+			continue;
+		bits = chans[i].channel->scan_type.storagebits;
+		if (!bits || bits > 16) {
+			dev_err(dev, "Unsupported channel storage size\n");
+			return -EINVAL;
+		}
+		if (bits != chans[0].channel->scan_type.storagebits) {
+			dev_err(dev, "Channels must have equal storage size\n");
+			return -EINVAL;
+		}
+	}
+
+	return i;
+}
+
 static int adc_joystick_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	struct iio_channel *chans;
 	struct adc_joystick *joy;
 	struct input_dev *input;
+	unsigned int poll_interval = 0;
+	unsigned int num_chans;
 	int error;
-	int bits;
-	int i;
-	unsigned int poll_interval;
-
-	joy = devm_kzalloc(dev, sizeof(*joy), GFP_KERNEL);
-	if (!joy)
-		return -ENOMEM;
 
-	joy->chans = devm_iio_channel_get_all(dev);
-	if (IS_ERR(joy->chans)) {
+	chans = devm_iio_channel_get_all(dev);
+	if (IS_ERR(chans)) {
 		error = PTR_ERR(joy->chans);
 		if (error != -EPROBE_DEFER)
 			dev_err(dev, "Unable to get IIO channels");
@@ -236,28 +252,19 @@ static int adc_joystick_probe(struct platform_device *pdev)
 	} else if (poll_interval == 0) {
 		dev_err(dev, "Unable to get poll-interval\n");
 		return -EINVAL;
-	} else {
-		joy->polled = true;
 	}
 
-	/*
-	 * Count how many channels we got. NULL terminated.
-	 * Do not check the storage size if using polling.
-	 */
-	for (i = 0; joy->chans[i].indio_dev; i++) {
-		if (joy->polled)
-			continue;
-		bits = joy->chans[i].channel->scan_type.storagebits;
-		if (!bits || bits > 16) {
-			dev_err(dev, "Unsupported channel storage size\n");
-			return -EINVAL;
-		}
-		if (bits != joy->chans[0].channel->scan_type.storagebits) {
-			dev_err(dev, "Channels must have equal storage size\n");
-			return -EINVAL;
-		}
-	}
-	joy->num_chans = i;
+	error = adc_joystick_count_channels(dev, chans, poll_interval != 0,
+					    &num_chans);
+	if (error)
+		return error;
+
+	joy = devm_kzalloc(dev, struct_size(joy, axes, num_chans), GFP_KERNEL);
+	if (!joy)
+		return -ENOMEM;
+
+	joy->chans = chans;
+	joy->num_chans = num_chans;
 
 	input = devm_input_allocate_device(dev);
 	if (!input) {
@@ -273,7 +280,7 @@ static int adc_joystick_probe(struct platform_device *pdev)
 	if (error)
 		return error;
 
-	if (joy->polled) {
+	if (poll_interval != 0) {
 		input_setup_polling(input, adc_joystick_poll);
 		input_set_poll_interval(input, poll_interval);
 	} else {
-- 
2.45.2.505.gda0bf45e8d-goog


-- 
Dmitry

^ permalink raw reply related

* Re: [PATCH] Input: add missing MODULE_DESCRIPTION() macros
From: Dmitry Torokhov @ 2024-06-09 21:41 UTC (permalink / raw)
  To: Jeff Johnson; +Cc: Linus Walleij, linux-input, linux-kernel, kernel-janitors
In-Reply-To: <20240609-md-drivers-input-v1-1-a2f394e0f9d8@quicinc.com>

On Sun, Jun 09, 2024 at 01:03:30PM -0700, Jeff Johnson wrote:
> On x86, make allmodconfig && make W=1 C=1 reports:
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/touchscreen/cyttsp_i2c_common.o
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/misc/soc_button_array.o
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/matrix-keymap.o
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/vivaldi-fmap.o
> WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/tests/input_test.o
> 
> Add the missing invocation of the MODULE_DESCRIPTION() macro to all
> files which have a MODULE_LICENSE().
> 
> This includes drivers/input/misc/sgi_btns.c which, although it did not
> produce a warning with the x86 allmodconfig configuration, may cause
> this warning with other configurations when either CONFIG_SGI_IP22 or
> CONFIG_SGI_IP32 is enabled.
> 
> Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Input: joystick - use sizeof(*pointer) instead of sizeof(type)
From: Dmitry Torokhov @ 2024-06-09 21:41 UTC (permalink / raw)
  To: Erick Archer
  Cc: Linus Walleij, Uwe Kleine-König, Vicki Pfau, Brenton Simpson,
	Max Nguyen, Carl Ng, Matt Scialabba, Christophe JAILLET,
	Kees Cook, Gustavo A. R. Silva, Justin Stitt, linux-input,
	linux-kernel, linux-hardening
In-Reply-To: <AS8PR02MB7237FEA55FAC8A9453F2DA6F8BC42@AS8PR02MB7237.eurprd02.prod.outlook.com>

On Sat, Jun 08, 2024 at 05:13:57PM +0200, Erick Archer wrote:
> It is preferred to use sizeof(*pointer) instead of sizeof(type)
> due to the type of the variable can change and one needs not
> change the former (unlike the latter).
> 
> At the same time refactor the code to not use assignment in "if"
> conditions.
> 
> This patch has no effect on runtime behavior.
> 
> Signed-off-by: Erick Archer <erick.archer@outlook.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Input: touchscreen - use sizeof(*pointer) instead of sizeof(type)
From: Dmitry Torokhov @ 2024-06-09 21:41 UTC (permalink / raw)
  To: Erick Archer
  Cc: Benjamin Gaignard, Hans Verkuil, Ricardo Ribalda,
	Andrzej Pietrasiewicz, Oliver Graute, Uwe Kleine-König,
	ye xingchen, Jason Gerecke, Kees Cook, Gustavo A. R. Silva,
	Justin Stitt, Support Opensource, linux-input, linux-kernel,
	linux-hardening
In-Reply-To: <AS8PR02MB723708364CC0DF2EAAFEE5968BC42@AS8PR02MB7237.eurprd02.prod.outlook.com>

On Sat, Jun 08, 2024 at 04:34:49PM +0200, Erick Archer wrote:
> It is preferred to use sizeof(*pointer) instead of sizeof(type)
> due to the type of the variable can change and one needs not
> change the former (unlike the latter).
> 
> The refactoring is mostly trivial except for "usbtouchscreen.c"
> file. Here, in the "mtouch_alloc" and "nexio_alloc" functions,
> it is necessary to use a variable with a predefined type instead
> of the "usbtouch->priv" variable (void * type). This way, the
> "sizeof" operator can now know the correct size. Moreover, we
> need to set the "usbtouch->priv" pointer after the memory
> allocation since now the "kmalloc" return value is not assigned
> directly.
> 
> This patch has no effect on runtime behavior.
> 
> Signed-off-by: Erick Archer <erick.archer@outlook.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply

* [PATCH] Input: add missing MODULE_DESCRIPTION() macros
From: Jeff Johnson @ 2024-06-09 20:03 UTC (permalink / raw)
  To: Dmitry Torokhov, Linus Walleij
  Cc: linux-input, linux-kernel, kernel-janitors, Jeff Johnson

On x86, make allmodconfig && make W=1 C=1 reports:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/touchscreen/cyttsp_i2c_common.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/misc/soc_button_array.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/matrix-keymap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/vivaldi-fmap.o
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/input/tests/input_test.o

Add the missing invocation of the MODULE_DESCRIPTION() macro to all
files which have a MODULE_LICENSE().

This includes drivers/input/misc/sgi_btns.c which, although it did not
produce a warning with the x86 allmodconfig configuration, may cause
this warning with other configurations when either CONFIG_SGI_IP22 or
CONFIG_SGI_IP32 is enabled.

Signed-off-by: Jeff Johnson <quic_jjohnson@quicinc.com>
---
 drivers/input/matrix-keymap.c                 | 1 +
 drivers/input/misc/sgi_btns.c                 | 1 +
 drivers/input/misc/soc_button_array.c         | 1 +
 drivers/input/tests/input_test.c              | 1 +
 drivers/input/touchscreen/cyttsp_i2c_common.c | 1 +
 drivers/input/vivaldi-fmap.c                  | 1 +
 6 files changed, 6 insertions(+)

diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c
index 4fa53423f56c..5d93043bad8e 100644
--- a/drivers/input/matrix-keymap.c
+++ b/drivers/input/matrix-keymap.c
@@ -199,4 +199,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
 }
 EXPORT_SYMBOL(matrix_keypad_build_keymap);
 
+MODULE_DESCRIPTION("Helpers for matrix keyboard bindings");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c
index 0657d785b3cc..39c2882b8e1a 100644
--- a/drivers/input/misc/sgi_btns.c
+++ b/drivers/input/misc/sgi_btns.c
@@ -128,4 +128,5 @@ static struct platform_driver sgi_buttons_driver = {
 };
 module_platform_driver(sgi_buttons_driver);
 
+MODULE_DESCRIPTION("SGI Indy/O2 volume button interface driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index f6d060377d18..5c5d407fe965 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -620,4 +620,5 @@ static struct platform_driver soc_button_driver = {
 };
 module_platform_driver(soc_button_driver);
 
+MODULE_DESCRIPTION("Windows-compatible SoC Button Array driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/tests/input_test.c b/drivers/input/tests/input_test.c
index 2fa5b725ae0a..e11cf4bbead9 100644
--- a/drivers/input/tests/input_test.c
+++ b/drivers/input/tests/input_test.c
@@ -179,4 +179,5 @@ static struct kunit_suite input_test_suite = {
 kunit_test_suite(input_test_suite);
 
 MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>");
+MODULE_DESCRIPTION("KUnit test for the input core");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/cyttsp_i2c_common.c b/drivers/input/touchscreen/cyttsp_i2c_common.c
index 1f0b6d6f48e2..7e752fb9fad7 100644
--- a/drivers/input/touchscreen/cyttsp_i2c_common.c
+++ b/drivers/input/touchscreen/cyttsp_i2c_common.c
@@ -81,5 +81,6 @@ int cyttsp_i2c_write_block_data(struct device *dev, u8 *xfer_buf,
 EXPORT_SYMBOL_GPL(cyttsp_i2c_write_block_data);
 
 
+MODULE_DESCRIPTION("Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Cypress");
diff --git a/drivers/input/vivaldi-fmap.c b/drivers/input/vivaldi-fmap.c
index 0d29ec014e2f..978949eba9eb 100644
--- a/drivers/input/vivaldi-fmap.c
+++ b/drivers/input/vivaldi-fmap.c
@@ -36,4 +36,5 @@ ssize_t vivaldi_function_row_physmap_show(const struct vivaldi_data *data,
 }
 EXPORT_SYMBOL_GPL(vivaldi_function_row_physmap_show);
 
+MODULE_DESCRIPTION("Helpers for ChromeOS Vivaldi keyboard function row mapping");
 MODULE_LICENSE("GPL");

---
base-commit: 19ca0d8a433ff37018f9429f7e7739e9f3d3d2b4
change-id: 20240609-md-drivers-input-beea779cc2a3


^ permalink raw reply related

* [dtor-input:next] BUILD SUCCESS f4c7fa7c058b9893b7a949cdb2f2aa504903f497
From: kernel test robot @ 2024-06-09  0:15 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: f4c7fa7c058b9893b7a949cdb2f2aa504903f497  Input: cap11xx - stop using chip ID when configuring it

elapsed time: 1671m

configs tested: 21
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
openrisc                          allnoconfig   gcc  
openrisc                            defconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                              defconfig   gcc  
parisc64                            defconfig   gcc  
powerpc                           allnoconfig   gcc  
riscv                             allnoconfig   gcc  
riscv                               defconfig   clang
s390                              allnoconfig   clang
s390                                defconfig   clang
sh                                allnoconfig   gcc  
sh                                  defconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                             defconfig   gcc  
um                               allmodconfig   clang
um                                allnoconfig   clang
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   clang
xtensa                            allnoconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [dtor-input:for-linus] BUILD SUCCESS cee77149ebe9cd971ba238d87aa10e09bd98f1c9
From: kernel test robot @ 2024-06-09  0:15 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
branch HEAD: cee77149ebe9cd971ba238d87aa10e09bd98f1c9  Input: xpad - add support for ASUS ROG RAIKIRI PRO

elapsed time: 1452m

configs tested: 20
configs skipped: 1

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
openrisc                          allnoconfig   gcc  
openrisc                            defconfig   gcc  
parisc                            allnoconfig   gcc  
parisc                              defconfig   gcc  
parisc64                            defconfig   gcc  
powerpc                           allnoconfig   gcc  
riscv                             allnoconfig   gcc  
riscv                               defconfig   clang
s390                              allnoconfig   clang
s390                                defconfig   clang
sh                                allnoconfig   gcc  
sh                                  defconfig   gcc  
sparc                             allnoconfig   gcc  
sparc                               defconfig   gcc  
sparc64                             defconfig   gcc  
um                                allnoconfig   clang
um                                  defconfig   clang
um                             i386_defconfig   gcc  
um                           x86_64_defconfig   clang
xtensa                            allnoconfig   gcc  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* input: Adding definitions for recovery and maskrom button?
From: Sebastian Kropatsch @ 2024-06-08 22:23 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input

Hello!

Many Single Board Computers (SBCs), especially those based on Rockchip
SoCs, come with on-board buttons labeled "Recovery" (for entering some
recovery mode) and "MaskROM" (for entering MaskROM mode for software
flashing). These are usually GPIO-based keys or ADC attached resistor
ladder buttons.

When defining devicetrees for these boards, the current approaches
include e.g. using "linux,code = <KEY_VENDOR>;", <KEY_SETUP>,
<KEY_PROG2> or <BTN_1> if these butons are even defined in the
devicetree source. So basically, there is no common approach
currently, since a clearly defined key label is missing.

The "linux,code" symbols used in the .dts files come from
"include/uapi/linux/input-event-codes.h" which is included by
"#include <dt-bindings/input/input.h>".

Would it be a sensible approach to add two defines to input-event-codes.h
e.g. KEY_RECOVERY and KEY_MASKROM (or a more generalized name)? Or is
this out-of-scope for input-event-codes.h?

Please let me know. Thanks! I can send a patch if I get green light :)

In case you'd like to see examples of these buttons, you may have
a look at devices like FriendlyElec NanoPC T6 [1] or Orange Pi 5 Plus [2].


Cheers,
Sebastian

[1] https://wiki.friendlyelec.com/wiki/index.php/NanoPC-T6
[2] http://www.orangepi.org/orangepiwiki/index.php/Orange_Pi_5_Plus

^ permalink raw reply

* Re: [PATCH] HID: uclogic: avoid linking common code into multiple modules
From: José Expósito @ 2024-06-08 18:28 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Jiri Kosina, Benjamin Tissoires, Arnd Bergmann, Rahul Rameshbabu,
	Fabio Baltieri, Ivan Gorinov, Johannes Roith, linux-input,
	linux-kernel
In-Reply-To: <20240529094816.1859073-1-arnd@kernel.org>

Hi Arnd,

On Wed, May 29, 2024 at 11:48:05AM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
> 
> The hid-uclogic-params.o and hid-uclogic-rdesc.o files are linked
> into both the driver module and the unit test, which triggers a
> W=1 warning:
> 
> scripts/Makefile.build:236: drivers/hid/Makefile: hid-uclogic-rdesc.o is added to multiple modules: hid-uclogic hid-uclogic-test
> scripts/Makefile.build:236: drivers/hid/Makefile: hid-uclogic-params.o is added to multiple modules: hid-uclogic hid-uclogic-test
> 
> Avoids this by moving these two files into a separate module
> that is used by the driver and the unit test.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> I have made patches for all such warnings in the tree, this is one I'm not
> sure about, maybe there is a better fix.
> ---
>  drivers/hid/Makefile             | 12 ++----
>  drivers/hid/hid-uclogic-params.c |  8 ++++
>  drivers/hid/hid-uclogic-rdesc.c  | 72 ++++++++++++++++++++++++++++++++
>  3 files changed, 84 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index ce71b53ea6c5..864dfbae8ace 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -133,10 +133,8 @@ obj-$(CONFIG_HID_TOPSEED)	+= hid-topseed.o
>  obj-$(CONFIG_HID_TOPRE)	+= hid-topre.o
>  obj-$(CONFIG_HID_TWINHAN)	+= hid-twinhan.o
>  obj-$(CONFIG_HID_U2FZERO)	+= hid-u2fzero.o
> -hid-uclogic-objs		:= hid-uclogic-core.o \
> -				   hid-uclogic-rdesc.o \
> -				   hid-uclogic-params.o
> -obj-$(CONFIG_HID_UCLOGIC)	+= hid-uclogic.o
> +hid-uclogic-objs		:= hid-uclogic-core.o
> +obj-$(CONFIG_HID_UCLOGIC)	+= hid-uclogic.o hid-uclogic-rdesc.o hid-uclogic-params.o
>  obj-$(CONFIG_HID_UDRAW_PS3)	+= hid-udraw-ps3.o
>  obj-$(CONFIG_HID_LED)		+= hid-led.o
>  obj-$(CONFIG_HID_XIAOMI)	+= hid-xiaomi.o
> @@ -154,10 +152,8 @@ obj-$(CONFIG_HID_WINWING)	+= hid-winwing.o
>  obj-$(CONFIG_HID_SENSOR_HUB)	+= hid-sensor-hub.o
>  obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR)	+= hid-sensor-custom.o
>  
> -hid-uclogic-test-objs		:= hid-uclogic-rdesc.o \
> -				   hid-uclogic-params.o \
> -				   hid-uclogic-rdesc-test.o
> -obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic-test.o
> +hid-uclogic-test-objs		:= hid-uclogic-rdesc-test.o
> +obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic-test.o hid-uclogic-params.o hid-uclogic-params.o
>  
>  obj-$(CONFIG_USB_HID)		+= usbhid/
>  obj-$(CONFIG_USB_MOUSE)		+= usbhid/

I tested your patch with:

	hid-uclogic-objs		:= hid-uclogic-core.o \
					   hid-uclogic-rdesc.o \
					   hid-uclogic-params.o
	obj-$(CONFIG_HID_UCLOGIC)	+= hid-uclogic.o
	[...]
	hid-uclogic-test-objs		:= hid-uclogic-rdesc-test.o
	obj-$(CONFIG_HID_KUNIT_TEST)	+= hid-uclogic.o hid-uclogic-test.o

And I think it is a bit more clear and it looks like it does the trick
removing the warning.

Also, with that change only "EXPORT_SYMBOL_GPL(uclogic_rdesc_template_apply);"
is required. The other EXPORT_SYMBOL_GPL can be removed.

However, I'm not sure about what are the best practices using EXPORT_SYMBOL_GPL
and if it should be used for each function/data in the .h file. Maybe that's
why you added them.

Best wishes,
Jose

> diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
> index 5bab006ec165..97ae7e4f61e1 100644
> --- a/drivers/hid/hid-uclogic-params.c
> +++ b/drivers/hid/hid-uclogic-params.c
> @@ -133,6 +133,7 @@ void uclogic_params_hid_dbg(const struct hid_device *hdev,
>  	}
>  	hid_dbg(hdev, "}\n");
>  }
> +EXPORT_SYMBOL_GPL(uclogic_params_hid_dbg);
>  
>  /**
>   * uclogic_params_get_str_desc - retrieve a string descriptor from a HID
> @@ -660,6 +661,7 @@ void uclogic_params_cleanup(struct uclogic_params *params)
>  		memset(params, 0, sizeof(*params));
>  	}
>  }
> +EXPORT_SYMBOL_GPL(uclogic_params_cleanup);
>  
>  /**
>   * uclogic_params_get_desc() - Get a replacement report descriptor for a
> @@ -732,6 +734,7 @@ int uclogic_params_get_desc(const struct uclogic_params *params,
>  	kfree(desc);
>  	return rc;
>  }
> +EXPORT_SYMBOL_GPL(uclogic_params_get_desc);
>  
>  /**
>   * uclogic_params_init_invalid() - initialize tablet interface parameters,
> @@ -1859,7 +1862,12 @@ int uclogic_params_init(struct uclogic_params *params,
>  	uclogic_params_cleanup(&p);
>  	return rc;
>  }
> +EXPORT_SYMBOL_GPL(uclogic_params_init);
>  
>  #ifdef CONFIG_HID_KUNIT_TEST
>  #include "hid-uclogic-params-test.c"
>  #endif
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Nikolai Kondrashov");
> +MODULE_DESCRIPTION("HID driver for UC-Logic devices tablet initialization and parameter retrieval");
> diff --git a/drivers/hid/hid-uclogic-rdesc.c b/drivers/hid/hid-uclogic-rdesc.c
> index b6dfdf6356a6..d4f1ee79e0a1 100644
> --- a/drivers/hid/hid-uclogic-rdesc.c
> +++ b/drivers/hid/hid-uclogic-rdesc.c
> @@ -59,9 +59,11 @@ __u8 uclogic_rdesc_wp4030u_fixed_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp4030u_fixed_arr);
>  
>  const size_t uclogic_rdesc_wp4030u_fixed_size =
>  			sizeof(uclogic_rdesc_wp4030u_fixed_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp4030u_fixed_size);
>  
>  /* Fixed WP5540U report descriptor */
>  __u8 uclogic_rdesc_wp5540u_fixed_arr[] = {
> @@ -136,9 +138,11 @@ __u8 uclogic_rdesc_wp5540u_fixed_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp5540u_fixed_arr);
>  
>  const size_t uclogic_rdesc_wp5540u_fixed_size =
>  			sizeof(uclogic_rdesc_wp5540u_fixed_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp5540u_fixed_size);
>  
>  /* Fixed WP8060U report descriptor */
>  __u8 uclogic_rdesc_wp8060u_fixed_arr[] = {
> @@ -213,9 +217,11 @@ __u8 uclogic_rdesc_wp8060u_fixed_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp8060u_fixed_arr);
>  
>  const size_t uclogic_rdesc_wp8060u_fixed_size =
>  			sizeof(uclogic_rdesc_wp8060u_fixed_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp8060u_fixed_size);
>  
>  /* Fixed WP1062 report descriptor */
>  __u8 uclogic_rdesc_wp1062_fixed_arr[] = {
> @@ -261,9 +267,11 @@ __u8 uclogic_rdesc_wp1062_fixed_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp1062_fixed_arr);
>  
>  const size_t uclogic_rdesc_wp1062_fixed_size =
>  			sizeof(uclogic_rdesc_wp1062_fixed_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_wp1062_fixed_size);
>  
>  /* Fixed PF1209 report descriptor */
>  __u8 uclogic_rdesc_pf1209_fixed_arr[] = {
> @@ -338,9 +346,11 @@ __u8 uclogic_rdesc_pf1209_fixed_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_pf1209_fixed_arr);
>  
>  const size_t uclogic_rdesc_pf1209_fixed_size =
>  			sizeof(uclogic_rdesc_pf1209_fixed_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_pf1209_fixed_size);
>  
>  /* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
>  __u8 uclogic_rdesc_twhl850_fixed0_arr[] = {
> @@ -384,9 +394,11 @@ __u8 uclogic_rdesc_twhl850_fixed0_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed0_arr);
>  
>  const size_t uclogic_rdesc_twhl850_fixed0_size =
>  			sizeof(uclogic_rdesc_twhl850_fixed0_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed0_size);
>  
>  /* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */
>  __u8 uclogic_rdesc_twhl850_fixed1_arr[] = {
> @@ -424,9 +436,11 @@ __u8 uclogic_rdesc_twhl850_fixed1_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed1_arr);
>  
>  const size_t uclogic_rdesc_twhl850_fixed1_size =
>  			sizeof(uclogic_rdesc_twhl850_fixed1_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed1_size);
>  
>  /* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */
>  __u8 uclogic_rdesc_twhl850_fixed2_arr[] = {
> @@ -450,9 +464,11 @@ __u8 uclogic_rdesc_twhl850_fixed2_arr[] = {
>  	0x80,               /*      Input,                          */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed2_arr);
>  
>  const size_t uclogic_rdesc_twhl850_fixed2_size =
>  			sizeof(uclogic_rdesc_twhl850_fixed2_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twhl850_fixed2_size);
>  
>  /* Fixed TWHA60 report descriptor, interface 0 (stylus) */
>  __u8 uclogic_rdesc_twha60_fixed0_arr[] = {
> @@ -499,9 +515,11 @@ __u8 uclogic_rdesc_twha60_fixed0_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twha60_fixed0_arr);
>  
>  const size_t uclogic_rdesc_twha60_fixed0_size =
>  			sizeof(uclogic_rdesc_twha60_fixed0_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twha60_fixed0_size);
>  
>  /* Fixed TWHA60 report descriptor, interface 1 (frame buttons) */
>  __u8 uclogic_rdesc_twha60_fixed1_arr[] = {
> @@ -527,9 +545,11 @@ __u8 uclogic_rdesc_twha60_fixed1_arr[] = {
>  	0x81, 0x01, /*      Input (Constant),       */
>  	0xC0        /*  End Collection              */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twha60_fixed1_arr);
>  
>  const size_t uclogic_rdesc_twha60_fixed1_size =
>  			sizeof(uclogic_rdesc_twha60_fixed1_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_twha60_fixed1_size);
>  
>  /* Fixed report descriptor template for (tweaked) v1 pen reports */
>  const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
> @@ -581,9 +601,11 @@ const __u8 uclogic_rdesc_v1_pen_template_arr[] = {
>  	0xC0,                   /*      End Collection,                     */
>  	0xC0                    /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v1_pen_template_arr);
>  
>  const size_t uclogic_rdesc_v1_pen_template_size =
>  			sizeof(uclogic_rdesc_v1_pen_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v1_pen_template_size);
>  
>  /* Fixed report descriptor template for (tweaked) v2 pen reports */
>  const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
> @@ -647,9 +669,11 @@ const __u8 uclogic_rdesc_v2_pen_template_arr[] = {
>  	0xC0,                   /*      End Collection,                     */
>  	0xC0                    /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_pen_template_arr);
>  
>  const size_t uclogic_rdesc_v2_pen_template_size =
>  			sizeof(uclogic_rdesc_v2_pen_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_pen_template_size);
>  
>  /*
>   * Expand to the contents of a generic frame buttons report descriptor.
> @@ -702,16 +726,22 @@ const size_t uclogic_rdesc_v2_pen_template_size =
>  const __u8 uclogic_rdesc_v1_frame_arr[] = {
>  	UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V1_FRAME_ID, 8)
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v1_frame_arr);
> +
>  const size_t uclogic_rdesc_v1_frame_size =
>  			sizeof(uclogic_rdesc_v1_frame_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v1_frame_size);
>  
>  /* Fixed report descriptor for (tweaked) v2 frame button reports */
>  const __u8 uclogic_rdesc_v2_frame_buttons_arr[] = {
>  	UCLOGIC_RDESC_FRAME_BUTTONS_BYTES(UCLOGIC_RDESC_V2_FRAME_BUTTONS_ID,
>  					  12)
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_buttons_arr);
> +
>  const size_t uclogic_rdesc_v2_frame_buttons_size =
>  			sizeof(uclogic_rdesc_v2_frame_buttons_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_buttons_size);
>  
>  /* Fixed report descriptor for (tweaked) v2 frame touch ring reports */
>  const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = {
> @@ -758,8 +788,11 @@ const __u8 uclogic_rdesc_v2_frame_touch_ring_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_touch_ring_arr);
> +
>  const size_t uclogic_rdesc_v2_frame_touch_ring_size =
>  			sizeof(uclogic_rdesc_v2_frame_touch_ring_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_touch_ring_size);
>  
>  /* Fixed report descriptor for (tweaked) v2 frame touch strip reports */
>  const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = {
> @@ -806,8 +839,11 @@ const __u8 uclogic_rdesc_v2_frame_touch_strip_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_touch_strip_arr);
> +
>  const size_t uclogic_rdesc_v2_frame_touch_strip_size =
>  			sizeof(uclogic_rdesc_v2_frame_touch_strip_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_touch_strip_size);
>  
>  /* Fixed report descriptor for (tweaked) v2 frame dial reports */
>  const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
> @@ -856,14 +892,22 @@ const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_dial_arr);
> +
>  const size_t uclogic_rdesc_v2_frame_dial_size =
>  			sizeof(uclogic_rdesc_v2_frame_dial_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_v2_frame_dial_size);
>  
>  const __u8 uclogic_ugee_v2_probe_arr[] = {
>  	0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
>  };
> +EXPORT_SYMBOL_GPL(uclogic_ugee_v2_probe_arr);
> +
>  const size_t uclogic_ugee_v2_probe_size = sizeof(uclogic_ugee_v2_probe_arr);
> +EXPORT_SYMBOL_GPL(uclogic_ugee_v2_probe_size);
> +
>  const int uclogic_ugee_v2_probe_endpoint = 0x03;
> +EXPORT_SYMBOL_GPL(uclogic_ugee_v2_probe_endpoint);
>  
>  /* Fixed report descriptor template for UGEE v2 pen reports */
>  const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = {
> @@ -935,8 +979,11 @@ const __u8 uclogic_rdesc_ugee_v2_pen_template_arr[] = {
>  	0xc0,               /*      End Collection,                     */
>  	0xc0,               /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_pen_template_arr);
> +
>  const size_t uclogic_rdesc_ugee_v2_pen_template_size =
>  			sizeof(uclogic_rdesc_ugee_v2_pen_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_pen_template_size);
>  
>  /* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
>  const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
> @@ -964,8 +1011,11 @@ const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
>  	0xC0,               /*      End Collection,                     */
>  	0xC0                /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
> +
>  const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
>  			sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_btn_template_size);
>  
>  /* Fixed report descriptor template for UGEE v2 frame reports (dial) */
>  const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = {
> @@ -1004,8 +1054,11 @@ const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = {
>  	0xC0,               /*      End Collection,                     */
>  	0xC0                /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_dial_template_arr);
> +
>  const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size =
>  			sizeof(uclogic_rdesc_ugee_v2_frame_dial_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_dial_template_size);
>  
>  /* Fixed report descriptor template for UGEE v2 frame reports (mouse) */
>  const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
> @@ -1038,8 +1091,11 @@ const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
>  	0xC0,               /*      End Collection,                     */
>  	0xC0                /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
> +
>  const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
>  			sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_frame_mouse_template_size);
>  
>  /* Fixed report descriptor template for UGEE v2 battery reports */
>  const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
> @@ -1072,8 +1128,11 @@ const __u8 uclogic_rdesc_ugee_v2_battery_template_arr[] = {
>  	0x81, 0x01,         /*      Input (Constant),                   */
>  	0xC0                /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_battery_template_arr);
> +
>  const size_t uclogic_rdesc_ugee_v2_battery_template_size =
>  			sizeof(uclogic_rdesc_ugee_v2_battery_template_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_v2_battery_template_size);
>  
>  /* Fixed report descriptor for Ugee EX07 frame */
>  const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
> @@ -1099,8 +1158,11 @@ const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
>  	0xC0,                   /*      End Collection,                     */
>  	0xC0                    /*  End Collection                          */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_ex07_frame_arr);
> +
>  const size_t uclogic_rdesc_ugee_ex07_frame_size =
>  			sizeof(uclogic_rdesc_ugee_ex07_frame_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_ex07_frame_size);
>  
>  /* Fixed report descriptor for Ugee G5 frame controls */
>  const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
> @@ -1153,8 +1215,10 @@ const __u8 uclogic_rdesc_ugee_g5_frame_arr[] = {
>  	0xC0,               /*      End Collection,                 */
>  	0xC0                /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_g5_frame_arr);
>  const size_t uclogic_rdesc_ugee_g5_frame_size =
>  			sizeof(uclogic_rdesc_ugee_g5_frame_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_ugee_g5_frame_size);
>  
>  /* Fixed report descriptor for XP-Pen Deco 01 frame controls */
>  const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
> @@ -1187,9 +1251,11 @@ const __u8 uclogic_rdesc_xppen_deco01_frame_arr[] = {
>  	0xC0,       /*      End Collection,                 */
>  	0xC0        /*  End Collection                      */
>  };
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_xppen_deco01_frame_arr);
>  
>  const size_t uclogic_rdesc_xppen_deco01_frame_size =
>  			sizeof(uclogic_rdesc_xppen_deco01_frame_arr);
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_xppen_deco01_frame_size);
>  
>  /**
>   * uclogic_rdesc_template_apply() - apply report descriptor parameters to a
> @@ -1242,3 +1308,9 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
>  
>  	return rdesc_ptr;
>  }
> +EXPORT_SYMBOL_GPL(uclogic_rdesc_template_apply);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Martin Rusko");
> +MODULE_AUTHOR("Nikolai Kondrashov");
> +MODULE_DESCRIPTION("HID driver for UC-Logic devices original and fixed report descriptors");
> -- 
> 2.39.2
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox