* Re: [PATCH v5 1/3] dt-bindings: touchscreen: convert eeti bindings to json schema
From: Sebastian Reichel @ 2025-09-20 20:39 UTC (permalink / raw)
To: Dario Binacchi
Cc: linux-kernel, linux-amarula, Conor Dooley, Dmitry Torokhov,
Krzysztof Kozlowski, Rob Herring, devicetree, linux-input
In-Reply-To: <20250919075823.2557865-1-dario.binacchi@amarulasolutions.com>
[-- Attachment #1: Type: text/plain, Size: 5413 bytes --]
Hi,
On Fri, Sep 19, 2025 at 09:58:09AM +0200, Dario Binacchi wrote:
> Convert EETI touchscreen controller device tree binding to json-schema.
>
> Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> ---
>
> Changes in v5:
> - Move bindings into eeti,exc3000.yaml
> - Remove eeti.yaml
>
> Changes in v2:
> - Added in v2
>
> .../input/touchscreen/eeti,exc3000.yaml | 41 ++++++++++++++++---
> .../bindings/input/touchscreen/eeti.txt | 30 --------------
> 2 files changed, 36 insertions(+), 35 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/input/touchscreen/eeti.txt
>
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml b/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml
> index 1c7ae05a8c15..13b865d3ee58 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml
> +++ b/Documentation/devicetree/bindings/input/touchscreen/eeti,exc3000.yaml
> @@ -9,15 +9,13 @@ title: EETI EXC3000 series touchscreen controller
> maintainers:
> - Dmitry Torokhov <dmitry.torokhov@gmail.com>
>
> -allOf:
> - - $ref: touchscreen.yaml#
> -
> properties:
> compatible:
> oneOf:
> - const: eeti,exc3000
> - const: eeti,exc80h60
> - const: eeti,exc80h84
> + - const: eeti,exc3000-i2c
I think this should be
- const: eeti,exc3000-i2c
deprecated: true
The compatible is obviously not something that should be used
anymore.
> - items:
> - enum:
> - eeti,exc81w32
> @@ -30,18 +28,34 @@ properties:
> maxItems: 1
> vdd-supply:
> description: Power supply regulator for the chip
> + attn-gpios:
> + maxItems: 1
> + description: Phandle to a GPIO to check whether interrupt is still
> + latched. This is necessary for platforms that lack
> + support for level-triggered IRQs.
deprecated: true
(see below)
> touchscreen-size-x: true
> touchscreen-size-y: true
> touchscreen-inverted-x: true
> touchscreen-inverted-y: true
> touchscreen-swapped-x-y: true
>
> +allOf:
> + - $ref: touchscreen.yaml#
> + - if:
> + not:
> + properties:
> + compatible:
> + contains:
> + const: eeti,exc3000-i2c
> + then:
> + required:
> + - touchscreen-size-x
> + - touchscreen-size-y
And I think it makes sense to add this to disallow using this ugly
hack with the normal compatibles:
else:
attn-gpios: false
Looking at the only user (pxa300-raumfeld-controller), it supplies
the same GPIO as IRQ and as GPIO, so it is actually a software
limitation. Instead of implementing the software level based IRQ
handling in the gpio driver, it was hacked into the EETI driver.
Looks like this legacy platform is pretty much dead, otherwise I
would have suggested to simply switch it to the new binding/driver.
Greetings,
-- Sebastian
> required:
> - compatible
> - reg
> - interrupts
> - - touchscreen-size-x
> - - touchscreen-size-y
>
> additionalProperties: false
>
> @@ -51,6 +65,7 @@ examples:
> i2c {
> #address-cells = <1>;
> #size-cells = <0>;
> +
> touchscreen@2a {
> compatible = "eeti,exc3000";
> reg = <0x2a>;
> @@ -62,3 +77,19 @@ examples:
> touchscreen-swapped-x-y;
> };
> };
> +
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + #include "dt-bindings/interrupt-controller/irq.h"
> + i2c {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + touchscreen@2a {
> + compatible = "eeti,exc3000-i2c";
> + reg = <0x2a>;
> + interrupt-parent = <&gpio>;
> + interrupts = <123 IRQ_TYPE_EDGE_RISING>;
> + attn-gpios = <&gpio 123 GPIO_ACTIVE_HIGH>;
> + };
> + };
I would also drop the example, nobody should use this :)
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/eeti.txt b/Documentation/devicetree/bindings/input/touchscreen/eeti.txt
> deleted file mode 100644
> index 32b3712c916e..000000000000
> --- a/Documentation/devicetree/bindings/input/touchscreen/eeti.txt
> +++ /dev/null
> @@ -1,30 +0,0 @@
> -Bindings for EETI touchscreen controller
> -
> -Required properties:
> -- compatible: should be "eeti,exc3000-i2c"
> -- reg: I2C address of the chip. Should be set to <0xa>
> -- interrupts: interrupt to which the chip is connected
> -
> -Optional properties:
> -- attn-gpios: A handle to a GPIO to check whether interrupt is still
> - latched. This is necessary for platforms that lack
> - support for level-triggered IRQs.
> -
> -The following optional properties described in touchscreen.txt are
> -also supported:
> -
> -- touchscreen-inverted-x
> -- touchscreen-inverted-y
> -- touchscreen-swapped-x-y
> -
> -Example:
> -
> -i2c-master {
> - touchscreen@a {
> - compatible = "eeti,exc3000-i2c";
> - reg = <0xa>;
> - interrupt-parent = <&gpio>;
> - interrupts = <123 IRQ_TYPE_EDGE_RISING>;
> - attn-gpios = <&gpio 123 GPIO_ACTIVE_HIGH>;
> - };
> -};
> --
> 2.43.0
>
> base-commit: 8b789f2b7602a818e7c7488c74414fae21392b63
> branch: drop-touchscreen.txt
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH v1 2/2] Input: add support for the STM FTS2BA61Y touchscreen
From: kernel test robot @ 2025-09-20 18:36 UTC (permalink / raw)
To: Eric Gonçalves, Henrik Rydberg, Dmitry Torokhov, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: oe-kbuild-all, Ivaylo Ivanov, devicetree, linux-input,
linux-kernel
In-Reply-To: <20250920014450.37787-3-ghatto404@gmail.com>
Hi Eric,
kernel test robot noticed the following build errors:
[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus robh/for-next linus/master v6.17-rc6 next-20250919]
[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/Eric-Gon-alves/dt-bindings-input-Add-ST-Microelectronics-FTS2BA61Y-touchscreen/20250920-094849
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link: https://lore.kernel.org/r/20250920014450.37787-3-ghatto404%40gmail.com
patch subject: [PATCH v1 2/2] Input: add support for the STM FTS2BA61Y touchscreen
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20250921/202509210247.oVPW8pop-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250921/202509210247.oVPW8pop-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/202509210247.oVPW8pop-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/input/touchscreen/fts2ba61y.c: In function 'fts2ba61y_wait_for_ready':
>> drivers/input/touchscreen/fts2ba61y.c:250:25: error: implicit declaration of function 'FIELD_GET' [-Wimplicit-function-declaration]
250 | stype = FIELD_GET(FTS2BA61Y_MASK_STYPE, buffer[0]);
| ^~~~~~~~~
drivers/input/touchscreen/fts2ba61y.c: In function 'fts2ba61y_irq_handler':
>> drivers/input/touchscreen/fts2ba61y.c:442:9: error: implicit declaration of function 'usleep'; did you mean 'fsleep'? [-Wimplicit-function-declaration]
442 | usleep(1);
| ^~~~~~
| fsleep
vim +/FIELD_GET +250 drivers/input/touchscreen/fts2ba61y.c
239
240 static int fts2ba61y_wait_for_ready(struct fts2ba61y_data *ts)
241 {
242 u8 buffer[FTS2BA61Y_EVENT_BUFF_SIZE];
243 u8 cmd = FTS2BA61Y_CMD_READ_EVENT;
244 u8 status_id, stype;
245 int ret;
246
247 for (int retries = 5; retries > 0; retries--) {
248 ret = fts2ba61y_read(ts, &cmd, 1, buffer, FTS2BA61Y_EVENT_BUFF_SIZE);
249
> 250 stype = FIELD_GET(FTS2BA61Y_MASK_STYPE, buffer[0]);
251 status_id = buffer[1];
252
253 if (stype == FTS2BA61Y_EVENT_STATUSTYPE_INFO &&
254 status_id == FTS2BA61Y_INFO_READY_STATUS) {
255 ret = 0;
256 break;
257 } else
258 ret = -ENODEV;
259
260 msleep(20);
261 }
262
263 return ret;
264 }
265
266 static int fts2ba61y_reset(struct fts2ba61y_data *ts)
267 {
268 u8 cmd = FTS2BA61Y_CMD_REG_W;
269 /* the following sequence is undocumented */
270 u8 reset[FTS2BA61Y_RESET_CMD_SIZE] = { 0x20, 0x00,
271 0x00, 0x24, 0x81 };
272 int ret;
273
274 disable_irq(ts->spi->irq);
275
276 ret = fts2ba61y_write(ts, &cmd, 1, &reset[0], FTS2BA61Y_RESET_CMD_SIZE);
277 if (ret)
278 return ret;
279 msleep(30);
280
281 ret = fts2ba61y_wait_for_ready(ts);
282 if (ret)
283 return ret;
284
285 enable_irq(ts->spi->irq);
286
287 return 0;
288 }
289
290 static int fts2ba61y_set_channels(struct fts2ba61y_data *ts)
291 {
292 int ret;
293 u8 cmd = FTS2BA61Y_CMD_READ_PANEL_INFO;
294 u8 data[FTS2BA61Y_PANEL_INFO_SIZE];
295
296 ret = fts2ba61y_read(ts, &cmd, 1, data, FTS2BA61Y_PANEL_INFO_SIZE);
297 if (ret)
298 return ret;
299
300 ts->max_x = get_unaligned_be16(data);
301 ts->max_y = get_unaligned_be16(data + 2);
302
303 /* if no tx channels defined, at least keep one */
304 ts->tx_count = max_t(u8, data[8], 1);
305
306 return 0;
307 }
308
309 static int fts2ba61y_set_touch_func(struct fts2ba61y_data *ts)
310 {
311 u8 cmd = FTS2BA61Y_CMD_TOUCHTYPE;
312 u16 touchtype = cpu_to_le16(FTS2BA61Y_TOUCHTYPE_DEFAULT);
313
314 return fts2ba61y_write(ts, &cmd, 1, (u8 *)&touchtype, 2);
315 }
316
317 static int fts2ba61y_hw_init(struct fts2ba61y_data *ts)
318 {
319 int ret;
320
321 ret = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
322 ts->regulators);
323 if (ret)
324 return ret;
325
326 msleep(140);
327
328 ret = fts2ba61y_reset(ts);
329 if (ret)
330 return ret;
331
332 ret = fts2ba61y_set_channels(ts);
333 if (ret)
334 return ret;
335
336 return fts2ba61y_set_touch_func(ts);
337 }
338
339 static int fts2ba61y_get_event(struct fts2ba61y_data *ts, u8 *data, int *n_events)
340 {
341 int ret;
342 u8 cmd = FTS2BA61Y_CMD_READ_EVENT;
343
344 ret = fts2ba61y_read(ts, &cmd, 1, data, FTS2BA61Y_EVENT_BUFF_SIZE);
345 if (ret < 0)
346 return ret;
347
348 if (!data[0]) {
349 *n_events = 0;
350 return 0;
351 }
352
353 *n_events = FIELD_GET(FTS2BA61Y_MASK_LEFT_EVENTS, data[7]);
354 if (unlikely(*n_events >= FTS2BA61Y_EVENT_COUNT)) {
355 cmd = FTS2BA61Y_CMD_CLEAR_EVENTS;
356 fts2ba61y_write(ts, &cmd, 1, NULL, 0);
357 *n_events = 0;
358 return -EINVAL;
359 }
360
361 if (*n_events > 0) {
362 ret = fts2ba61y_read(ts, &cmd, 1,
363 &data[1 * FTS2BA61Y_EVENT_BUFF_SIZE],
364 FTS2BA61Y_EVENT_BUFF_SIZE * (*n_events));
365 if (ret)
366 return ret;
367 }
368
369 return 0;
370 }
371
372 static void fts2ba61y_report_coordinates(struct fts2ba61y_data *ts,
373 u8 *event, u8 tid)
374 {
375 u8 major = event[4];
376 u8 minor = event[5];
377 u8 z = FIELD_GET(FTS2BA61Y_MASK_Z, event[6]);
378
379 u16 x = (event[1] << 4) |
380 FIELD_GET(FTS2BA61Y_MASK_X_3_0, event[3]);
381 u16 y = (event[2] << 4) |
382 FIELD_GET(FTS2BA61Y_MASK_Y_3_0, event[3]);
383 u16 ttype = (FIELD_GET(FTS2BA61Y_MASK_TTYPE_3_2, event[6]) << 2) |
384 (FIELD_GET(FTS2BA61Y_MASK_TTYPE_1_0, event[7]) << 0);
385
386 if (ttype != FTS2BA61Y_TOUCHTYPE_NORMAL &&
387 ttype != FTS2BA61Y_TOUCHTYPE_PALM &&
388 ttype != FTS2BA61Y_TOUCHTYPE_WET &&
389 ttype != FTS2BA61Y_TOUCHTYPE_GLOVE)
390 return;
391
392 input_mt_slot(ts->input_dev, tid);
393 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
394 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
395 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
396 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, major);
397 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, minor);
398 input_report_abs(ts->input_dev, ABS_MT_PRESSURE, z);
399
400 input_mt_sync_frame(ts->input_dev);
401 input_sync(ts->input_dev);
402 }
403
404 static void fts2ba61y_report_release(struct fts2ba61y_data *ts, u8 tid)
405 {
406 input_mt_slot(ts->input_dev, tid);
407 input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
408
409 input_mt_sync_frame(ts->input_dev);
410 input_sync(ts->input_dev);
411 }
412
413 static void fts2ba61y_handle_coordinates(struct fts2ba61y_data *ts, u8 *event)
414 {
415 u8 t_id = FIELD_GET(FTS2BA61Y_MASK_TID, event[0]);
416 u8 action = FIELD_GET(FTS2BA61Y_MASK_TCHSTA, event[0]);
417
418 if (t_id > ts->tx_count)
419 return;
420
421 switch (action) {
422 case FTS2BA61Y_COORDINATE_ACTION_PRESS:
423 case FTS2BA61Y_COORDINATE_ACTION_MOVE:
424 fts2ba61y_report_coordinates(ts, event, t_id);
425 break;
426
427 case FTS2BA61Y_COORDINATE_ACTION_RELEASE:
428 fts2ba61y_report_release(ts, t_id);
429 break;
430 }
431 }
432
433 static irqreturn_t fts2ba61y_irq_handler(int irq, void *handle)
434 {
435 struct fts2ba61y_data *ts = handle;
436 u8 buffer[FTS2BA61Y_EVENT_COUNT * FTS2BA61Y_EVENT_BUFF_SIZE];
437 u8 *event;
438 u8 event_id;
439 int n_events = 0;
440 int ret;
441
> 442 usleep(1);
443
444 ret = fts2ba61y_get_event(ts, buffer, &n_events);
445 if (ret < 0) {
446 dev_dbg(&ts->spi->dev, "failed to get event: %d", ret);
447 return IRQ_HANDLED;
448 }
449
450 for (int i = 0; i <= n_events; i++) {
451 event = &buffer[i * FTS2BA61Y_EVENT_BUFF_SIZE];
452 event_id = FIELD_GET(FTS2BA61Y_MASK_EVENT_ID, event[0]);
453
454 if (event_id == FTS2BA61Y_COORDINATE_EVENT)
455 fts2ba61y_handle_coordinates(ts, event);
456 }
457
458 return IRQ_HANDLED;
459 }
460
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [syzbot] [kernel?] INFO: task hung in hidp_session_remove
From: syzbot @ 2025-09-20 14:49 UTC (permalink / raw)
To: anna-maria, bentiss, chenl311, frederic, jikos, jkosina,
linux-input, linux-kernel, netdev, syzkaller-bugs, tglx
In-Reply-To: <688aa543.a00a0220.26d0e1.0030.GAE@google.com>
syzbot suspects this issue was fixed by commit:
commit 4051ead99888f101be92c7ce90d2de09aac6fd1c
Author: Li Chen <chenl311@chinatelecom.cn>
Date: Fri Jun 20 12:02:31 2025 +0000
HID: rate-limit hid_warn to prevent log flooding
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=1128a712580000
start commit: afd8c2c9e2e2 Merge branch 'ipv6-f6i-fib6_siblings-and-rt-f..
git tree: net
kernel config: https://syzkaller.appspot.com/x/.config?x=a4bcc0a11b3192be
dashboard link: https://syzkaller.appspot.com/bug?extid=234fdcc5f6633833a35c
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=15f458a2580000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=1796c782580000
If the result looks correct, please mark the issue as fixed by replying with:
#syz fix: HID: rate-limit hid_warn to prevent log flooding
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
^ permalink raw reply
* Re: [PATCH v2 00/10] media: Introduce video device state management
From: Andy Shevchenko @ 2025-09-20 10:48 UTC (permalink / raw)
To: Jai Luthra
Cc: Hans Verkuil, Mauro Carvalho Chehab, Sakari Ailus,
Laurent Pinchart, Tomi Valkeinen, Jacopo Mondi, linux-media,
Ricardo Ribalda, Laurent Pinchart, Al Viro, Ma Ke, linux-kernel,
Bartosz Golaszewski, Hans de Goede, Dmitry Torokhov, Nick Dyer,
Tomasz Figa, Marek Szyprowski, Matt Ranostay, Andy Walls,
Yong Zhi, Bingbu Cao, Dan Scally, Tianshu Qiu, Martin Tuma,
Bluecherry Maintainers, Andrey Utkin, Ismael Luceno,
Ezequiel Garcia, Corentin Labbe, Michael Tretter,
Pengutronix Kernel Team, Keke Li, Neil Armstrong, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl, Ming Qian, Zhou Peng,
Eddie James, Joel Stanley, Andrew Jeffery, Eugen Hristev,
Nicolas Ferre, Alexandre Belloni, Claudiu Beznea,
Raspberry Pi Kernel Maintenance, Florian Fainelli,
Broadcom internal kernel review list, Ray Jui, Scott Branden,
Philipp Zabel, Nas Chung, Jackson Lee, Devarsh Thakkar, Bin Liu,
Matthias Brugger, AngeloGioacchino Del Regno, Minghsiu Tsai,
Houlong Wei, Andrew-CT Chen, Tiffany Lin, Yunfei Dong, Joseph Liu,
Marvin Lin, Dmitry Osipenko, Thierry Reding, Jonathan Hunter,
Xavier Roumegue, Mirela Rabulea, Shawn Guo, Sascha Hauer,
Fabio Estevam, Rui Miguel Silva, Martin Kepplinger,
Purism Kernel Team, Robert Foss, Todor Tomov,
Bryan O'Donoghue, Vladimir Zapolskiy, Vikash Garodia,
Dikshita Agarwal, Abhinav Kumar, Niklas Söderlund,
Geert Uytterhoeven, Magnus Damm, Fabrizio Castro, Kieran Bingham,
Nikita Yushchenko, Jacob Chen, Heiko Stuebner, Dafna Hirschfeld,
Detlev Casanova, Krzysztof Kozlowski, Alim Akhtar,
Sylwester Nawrocki, Łukasz Stelmach, Andrzej Pietrasiewicz,
Jacek Anaszewski, Andrzej Hajda, Fabien Dessenne, Hugues Fruchet,
Jean-Christophe Trotin, Maxime Coquelin, Alexandre Torgue,
Alain Volmat, Maxime Ripard, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, Yong Deng, Paul Kocialkowski, Shreeya Patel,
Lad, Prabhakar, Yemike Abhilash Chandra, Jai Luthra,
Nicolas Dufresne, Benjamin Gaignard, Michal Simek, Alexey Klimov,
Eduardo Valentin, Shuah Khan, Daniel Almeida, Michael Krufky,
Mike Isely, Andy Shevchenko, Greg Kroah-Hartman, Steve Longerbeam,
Jack Zhu, Changhuang Liang, Sowjanya Komatineni, Luca Ceresoli,
Parthiban Veerasooran, Christian Gromm, Uwe Kleine-König,
Ingo Molnar, Thomas Gleixner, Plamen Atanasov, Sean Young,
Ariel Otilibili, Dr. David Alan Gilbert, Jiasheng Jiang,
Lad Prabhakar, Tommaso Merciai, Biju Das, Daniel Scally,
Matthew Majewski, Yunseong Kim, Chen Ni, Fabio Luongo, Mark Brown,
Yang Yingliang, Ludwig Disterhof, Everest K.C., Stefan Wahren,
Dave Stevenson, Michael Grzeschik, Akash Kumar, linux-input,
mjpeg-users, linux-amlogic, linux-arm-kernel, openbmc,
linux-aspeed, linux-rpi-kernel, linux-mediatek, linux-tegra, imx,
linux-arm-msm, linux-renesas-soc, linux-rockchip,
linux-samsung-soc, linux-stm32, linux-sunxi, kernel,
linux-staging, linux-usb
In-Reply-To: <20250919-vdev-state-v2-0-b2c42426965c@ideasonboard.com>
On Fri, Sep 19, 2025 at 12:57 PM Jai Luthra <jai.luthra@ideasonboard.com> wrote:
>
> Hi,
>
> This patch series introduces state management for video devices.
>
> Currently, V4L2 subdevices have a well-established state management
> system [1] that allows the framework to store the subdevice state
> at a central location.
>
> Video devices however lack this, leading to inconsistent state handling
> across drivers and making it difficult to implement features like
> hardware multiplexing in complex media pipelines [2].
>
> The series is composed of three parts:
>
> - Core Infrastructure (PATCH 1-4)
> Introduces the basic state structure, try state support,
> initialization callbacks, and driver helpers
> - Framework Integration (PATCH 5-7)
> Integrates state passing through the ioctl wrappers and driver
> implementations
> - Driver Examples (PATCH 8-10)
> Use the state to store formats in TI J721E CSI2RX and Rockchip
> RKISP1 drivers
>
> This should also provide a foundation for drivers to extend or subclass
> the state structure with device-specific variables in future.
>
> I have tested capture and format negotiation with the converted drivers
> on SK AM62A (j721e-csi2rx) and Debix Model A (rkisp1).
>
> [1]: https://lore.kernel.org/linux-media/20210610145606.3468235-1-tomi.valkeinen@ideasonboard.com/
> [2]: https://lore.kernel.org/linux-media/20250724-multicontext-mainline-2025-v2-0-c9b316773486@ideasonboard.com/
When you add a Cc list., do it after the '---' (three minus signs)
line, otherwise that huge unneeded noise will become part of the
commit message.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 00/27 5.10.y] Backport minmax.h updates from v6.17-rc6
From: David Laight @ 2025-09-20 10:21 UTC (permalink / raw)
To: Christian König
Cc: linux, jdike, anton.ivanov, dave.hansen, peterz, tglx, x86, hpa,
tony.luck, qiuxu.zhuo, mchehab, james.morse, rric, harry.wentland,
sunpeng.li, alexander.deucher, airlied, daniel, evan.quan,
james.qian.wang, liviu.dudau, mihail.atanassov, brian.starkey,
maarten.lankhorst, mripard, tzimmermann, robdclark, sean,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, dushistov,
luc.vanoostenryck, rostedt, pmladek, sergey.senozhatsky,
andriy.shevchenko, linux, akpm, kuznet, yoshfuji, pablo, kadlec,
jmaloy, ying.xue, willy, sashal, ruanjinjie, David.Laight,
herve.codina, Jason, bvanassche, keescook, linux-arm-kernel,
linux-kernel, linux-um, linux-edac, amd-gfx, dri-devel,
linux-arm-msm, freedreno, linux-hwmon, linux-input, linux-media,
netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable, jonnyc
In-Reply-To: <184ce83f-0063-43a0-a1c8-da23c5d03cf7@amd.com>
On Fri, 19 Sep 2025 14:11:37 +0200
Christian König <christian.koenig@amd.com> wrote:
> On 19.09.25 12:17, Eliav Farber wrote:
> > This series includes a total of 27 patches, to align minmax.h of
> > v5.15.y with v6.17-rc6.
> >
> > The set consists of 24 commits that directly update minmax.h:
> > 1) 92d23c6e9415 ("overflow, tracing: Define the is_signed_type() macro
> > once")
> > 2) 5efcecd9a3b1 ("minmax: sanity check constant bounds when clamping")
> > 3) 2122e2a4efc2 ("minmax: clamp more efficiently by avoiding extra
> > comparison")
> > 4) f9bff0e31881 ("minmax: add in_range() macro")
> > 5) c952c748c7a9 ("minmax: Introduce {min,max}_array()")
> > 6) 5e57418a2031 ("minmax: deduplicate __unconst_integer_typeof()")
> > 7) f6e9d38f8eb0 ("minmax: fix header inclusions")
> > 8) d03eba99f5bf ("minmax: allow min()/max()/clamp() if the arguments
> > have the same signedness.")
> > 9) f4b84b2ff851 ("minmax: fix indentation of __cmp_once() and
> > __clamp_once()")
> > 10) 4ead534fba42 ("minmax: allow comparisons of 'int' against 'unsigned
> > char/short'")
> > 11) 867046cc7027 ("minmax: relax check to allow comparison between
> > unsigned arguments and signed constants")
> > 12) 3a7e02c040b1 ("minmax: avoid overly complicated constant
> > expressions in VM code")
> > 14) 017fa3e89187 ("minmax: simplify and clarify min_t()/max_t()
> > implementation")
> > 15) 1a251f52cfdc ("minmax: make generic MIN() and MAX() macros
> > available everywhere")
> > 18) dc1c8034e31b ("minmax: simplify min()/max()/clamp()
> > implementation")
> > 19) 22f546873149 ("minmax: improve macro expansion and type
> > checking")
> > 20) 21b136cc63d2 ("minmax: fix up min3() and max3() too")
> > 21) 71ee9b16251e ("minmax.h: add whitespace around operators and after
> > commas")
> > 22) 10666e992048 ("minmax.h: update some comments")
> > 23) b280bb27a9f7 ("minmax.h: reduce the #define expansion of min(),
> > max() and clamp()")
> > 24) a5743f32baec ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi
> > test in clamp()")
> > 25) c3939872ee4a ("minmax.h: move all the clamp() definitions after the
> > min/max() ones")
> > 26) 495bba17cdf9 ("minmax.h: simplify the variants of clamp()")
> > 27) 2b97aaf74ed5 ("minmax.h: remove some #defines that are only
> > expanded once")
> >
> > 2 prerequisite commits that adjust users of MIN and MAX macros (to
> > prevent compilation issues):
> > 13) 4477b39c32fd ("minmax: add a few more MIN_T/MAX_T users")
> > 17) cb04e8b1d2f2 ("minmax: don't use max() in situations that want a C
> > constant expression")
> >
> > 1 additional commit introduced to resolve a build failures during the
> > backport:
> > 16) lib: zstd: drop local MIN/MAX macros in favor of generic ones
> >
> > The primary motivation is to bring in commit (8).
> > In mainline, this change allows min()/max()/clamp() to accept mixed
> > argument types when both share the same signedness.
> > Backported patches to v5.10.y that use such forms trigger compiler
> > warnings, which in turn cause build failures when -Werror is enabled.
> >
> > Originaly I aligned 5.10.y to 5.15.y, but David Laight commented that I
> > need to pick up the later changes (from Linus) as well.
> >
> > Andy Shevchenko (2):
> > minmax: deduplicate __unconst_integer_typeof()
> > minmax: fix header inclusions
> >
> > Bart Van Assche (1):
> > overflow, tracing: Define the is_signed_type() macro once
> >
> > David Laight (11):
> > minmax: allow min()/max()/clamp() if the arguments have the same
> > signedness.
> > minmax: fix indentation of __cmp_once() and __clamp_once()
> > minmax: allow comparisons of 'int' against 'unsigned char/short'
> > minmax: relax check to allow comparison between unsigned arguments and
> > signed constants
> > minmax.h: add whitespace around operators and after commas
> > minmax.h: update some comments
> > minmax.h: reduce the #define expansion of min(), max() and clamp()
> > minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> > minmax.h: move all the clamp() definitions after the min/max() ones
> > minmax.h: simplify the variants of clamp()
> > minmax.h: remove some #defines that are only expanded once
> >
> > Eliav Farber (1):
> > lib: zstd: drop local MIN/MAX macros in favor of generic ones
> >
> > Herve Codina (1):
> > minmax: Introduce {min,max}_array()
> >
> > Jason A. Donenfeld (2):
> > minmax: sanity check constant bounds when clamping
> > minmax: clamp more efficiently by avoiding extra comparison
> >
> > Linus Torvalds (8):
> > minmax: avoid overly complicated constant expressions in VM code
> > minmax: add a few more MIN_T/MAX_T users
> > minmax: simplify and clarify min_t()/max_t() implementation
> > minmax: make generic MIN() and MAX() macros available everywhere
> > minmax: don't use max() in situations that want a C constant
> > expression
> > minmax: simplify min()/max()/clamp() implementation
> > minmax: improve macro expansion and type checking
> > minmax: fix up min3() and max3() too
> >
> > Matthew Wilcox (Oracle) (1):
> > minmax: add in_range() macro
> >
> > arch/arm/mm/pageattr.c | 6 +-
> > arch/um/drivers/mconsole_user.c | 2 +
> > arch/x86/mm/pgtable.c | 2 +-
>
> > drivers/edac/sb_edac.c | 4 +-
> > drivers/edac/skx_common.h | 1 -
> > .../drm/amd/display/modules/hdcp/hdcp_ddc.c | 2 +
> > .../drm/amd/pm/powerplay/hwmgr/ppevvmath.h | 14 +-
> > .../drm/arm/display/include/malidp_utils.h | 2 +-
> > .../display/komeda/komeda_pipeline_state.c | 24 +-
> > drivers/gpu/drm/drm_color_mgmt.c | 2 +-
> > drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 -
> > drivers/gpu/drm/radeon/evergreen_cs.c | 2 +
> > drivers/hwmon/adt7475.c | 24 +-
> > drivers/input/touchscreen/cyttsp4_core.c | 2 +-
> > drivers/md/dm-integrity.c | 2 +-
> > drivers/media/dvb-frontends/stv0367_priv.h | 3 +
> > .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 18 +-
> > .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> > drivers/net/fjes/fjes_main.c | 4 +-
> > drivers/nfc/pn544/i2c.c | 2 -
> > drivers/platform/x86/sony-laptop.c | 1 -
> > drivers/scsi/isci/init.c | 6 +-
>
> I do see the value to backport the infrastructure, but why are driver specific changes backported as well?
They will be about removing local definitions of MIN() and MAX() freeing
them up for simple implementations (usable as constant initialisers) and then
using them in places where the compound statements in min() and max() can't
be used.
Linus did all those changes - so he didn't have to wait for the maintainers
to apply the changes (etc).
David
>
> I mean the changes are most likely correct but also not valuable in anyway as bug fix.
>
> Regards,
> Christian.
>
> > .../pci/hive_isp_css_include/math_support.h | 5 -
> > fs/btrfs/misc.h | 2 -
> > fs/btrfs/tree-checker.c | 2 +-
> > fs/ext2/balloc.c | 2 -
> > fs/ext4/ext4.h | 2 -
> > fs/ufs/util.h | 6 -
> > include/linux/compiler.h | 15 +
> > include/linux/minmax.h | 267 ++++++++++++++----
> > include/linux/overflow.h | 1 -
> > include/linux/trace_events.h | 2 -
> > kernel/trace/preemptirq_delay_test.c | 2 -
> > lib/btree.c | 1 -
> > lib/decompress_unlzma.c | 2 +
> > lib/logic_pio.c | 3 -
> > lib/vsprintf.c | 2 +-
> > lib/zstd/zstd_internal.h | 2 -
> > mm/zsmalloc.c | 1 -
> > net/ipv4/proc.c | 2 +-
> > net/ipv6/proc.c | 2 +-
> > net/netfilter/nf_nat_core.c | 6 +-
> > net/tipc/core.h | 2 +-
> > net/tipc/link.c | 10 +-
> > 44 files changed, 306 insertions(+), 164 deletions(-)
> >
>
>
^ permalink raw reply
* Re: [PATCH v5 3/6] dt-bindings: touchscreen: add touchscreen-glitch-threshold-ns property
From: Dario Binacchi @ 2025-09-20 9:39 UTC (permalink / raw)
To: Rob Herring
Cc: linux-kernel, Frank Li, linux-amarula, Conor Dooley, Conor Dooley,
Dmitry Torokhov, Javier Carrasco, Jeff LaBundy,
Krzysztof Kozlowski, devicetree, linux-input
In-Reply-To: <20250919204436.GA2176045-robh@kernel.org>
On Fri, Sep 19, 2025 at 10:44 PM Rob Herring <robh@kernel.org> wrote:
>
> On Fri, Sep 19, 2025 at 05:12:42PM +0200, Dario Binacchi wrote:
> > On Fri, Sep 19, 2025 at 4:38 PM Rob Herring <robh@kernel.org> wrote:
> > >
> > > On Thu, Sep 18, 2025 at 10:37:37PM +0200, Dario Binacchi wrote:
> > > > On Thu, Sep 18, 2025 at 10:04 PM Rob Herring <robh@kernel.org> wrote:
> > > > >
> > > > > On Thu, Sep 18, 2025 at 05:52:31PM +0200, Dario Binacchi wrote:
> > > > > > Add support for glitch threshold configuration. A detected signal is valid
> > > > > > only if it lasts longer than the set threshold; otherwise, it is regarded
> > > > > > as a glitch.
> > > > > >
> > > > > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > > > > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > > > > >
> > > > > > ---
> > > > > >
> > > > > > Changes in v5:
> > > > > > - Add Acked-by tag of Conor Dooley
> > > > > >
> > > > > > Changes in v2:
> > > > > > - Added in v2.
> > > > > >
> > > > > > .../devicetree/bindings/input/touchscreen/touchscreen.yaml | 4 ++++
> > > > > > 1 file changed, 4 insertions(+)
> > > > > >
> > > > > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > > index 3e3572aa483a..a60b4d08620d 100644
> > > > > > --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > > +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > > @@ -206,6 +206,10 @@ properties:
> > > > > >
> > > > > > unevaluatedProperties: false
> > > > > >
> > > > > > + touchscreen-glitch-threshold-ns:
> > > > > > + description: Minimum duration in nanoseconds a signal must remain stable
> > > > > > + to be considered valid.
> > > > >
> > > > > What's wrong with debounce-delay-ms?
> > > >
> > > > Do you mean that I should rename touchscreen-glitch-threshold-ns to
> > > > debounce-delay-ms?
> > >
> > > I mean that's the common property we already have, so use it or explain
> > > why you aren't using it. I suppose the definition is technically a bit
> > > different if it's purely a s/w delay vs. h/w monitoring of the signal
> > > state. I don't think it matters if the interpretation by each driver is
> > > a bit different.
> > >
> > > Maybe msec is not enough resolution for you could be another reason?
> >
> > Yes, this is the main reason. As specified in the following patch:
> > v5 4/6 dt-bindings: touchscreen: fsl,imx6ul-tsc: support glitch threshold
> >
> > Drivers must convert this value to IPG clock cycles and map
> > it to one of the four discrete thresholds exposed by the
> > TSC_DEBUG_MODE2 register:
> >
> > 0: 8191 IPG cycles
> > 1: 4095 IPG cycles
> > 2: 2047 IPG cycles
> > 3: 1023 IPG cycles
> >
> > In my case, the IPG clock runs at 66 MHz, which corresponds to:
> >
> > 124 µs for 0
> > 62 µs for 1
> > 31 us for 2
> > 15 us for 3
> >
> > So using milliseconds would not fit my use case. A possible trade-off
> > could be to use debounce-delay-us. Would that be acceptable?
>
> I agree it wouldn't map to what the h/w provides, but is what the h/w
> provides actually useful? There's plenty of h/w designed that's not
> useful. 15us is quite short for a glitch. Do you have an actual cases
> where the different values above are needed?
Considering an IPG clock at 66 MHz, currently at reset the deglitch
filter is set to 124 µs,
the driver sets it to 31 µs with a hardcoded value, and in my use case
I need to set it to 62 µs,
as you can see in the patch:
https://lore.kernel.org/all/20250918155240.2536852-6-dario.binacchi@amarulasolutions.com/
and its handling in
https://lore.kernel.org/all/20250918155240.2536852-7-dario.binacchi@amarulasolutions.com/
Another option could be to use a specific binding for the
fsl,imx6ul-tsc controller, as I did in the
earlier versions of the series.
Thanks and regards,
Dario
>
> Rob
--
Dario Binacchi
Senior Embedded Linux Developer
dario.binacchi@amarulasolutions.com
__________________________________
Amarula Solutions SRL
Via Le Canevare 30, 31100 Treviso, Veneto, IT
T. +39 042 243 5310
info@amarulasolutions.com
www.amarulasolutions.com
^ permalink raw reply
* [PATCH v1 2/2] Input: add support for the STM FTS2BA61Y touchscreen
From: Eric Gonçalves @ 2025-09-20 1:44 UTC (permalink / raw)
To: Henrik Rydberg, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Ivaylo Ivanov, devicetree, linux-input, linux-kernel
In-Reply-To: <20250920014450.37787-1-ghatto404@gmail.com>
The ST-Microelectronics FTS2BA61Y touchscreen is a capacitive multi-touch
controller connected through SPI at 0x0, the touchscreen is typically
used in mobile devices (like the Galaxy S22 series)
Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
Signed-off-by: Eric Gonçalves <ghatto404@gmail.com>
---
drivers/input/touchscreen/Kconfig | 11 +
drivers/input/touchscreen/Makefile | 1 +
drivers/input/touchscreen/fts2ba61y.c | 588 ++++++++++++++++++++++++++
3 files changed, 600 insertions(+)
create mode 100644 drivers/input/touchscreen/fts2ba61y.c
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 196905162945..1e199191f527 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -370,6 +370,17 @@ config TOUCHSCREEN_EXC3000
To compile this driver as a module, choose M here: the
module will be called exc3000.
+config TOUCHSCREEN_FTS2BA61Y
+ tristate "ST-Microelectronics FTS2BA61Y touchscreen"
+ depends on SPI
+ help
+ Say Y here if you have the ST-Microelectronics FTS2BA61Y touchscreen
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called fts2ba61y.
+
config TOUCHSCREEN_FUJITSU
tristate "Fujitsu serial touchscreen"
select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 97a025c6a377..408a9fd5bd35 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX) += egalax_ts.o
obj-$(CONFIG_TOUCHSCREEN_EGALAX_SERIAL) += egalax_ts_serial.o
obj-$(CONFIG_TOUCHSCREEN_EXC3000) += exc3000.o
+obj-$(CONFIG_TOUCHSCREEN_FTS2BA61Y) += fts2ba61y.o
obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE) += goodix_berlin_core.o
diff --git a/drivers/input/touchscreen/fts2ba61y.c b/drivers/input/touchscreen/fts2ba61y.c
new file mode 100644
index 000000000000..b3b3abca5404
--- /dev/null
+++ b/drivers/input/touchscreen/fts2ba61y.c
@@ -0,0 +1,588 @@
+// SPDX-License-Identifier: GPL-2.0
+// Based loosely on s6sy761.c
+
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/input/mt.h>
+#include <linux/spi/spi.h>
+#include <linux/input/touchscreen.h>
+#include <linux/unaligned.h>
+#include <linux/regulator/consumer.h>
+
+/* commands */
+#define FTS2BA61Y_CMD_SENSE_ON 0x10
+#define FTS2BA61Y_CMD_SENSE_OFF 0x11
+#define FTS2BA61Y_CMD_READ_PANEL_INFO 0x23
+#define FTS2BA61Y_CMD_READ_FW_VER 0x24
+#define FTS2BA61Y_CMD_TOUCHTYPE 0x30 /* R/W for get/set */
+#define FTS2BA61Y_CMD_CLEAR_EVENTS 0x62
+#define FTS2BA61Y_CMD_READ_EVENT 0x87
+#define FTS2BA61Y_CMD_CUSTOM_W 0xC0
+#define FTS2BA61Y_CMD_CUSTOM_R 0xD1
+#define FTS2BA61Y_CMD_REG_W 0xFA
+#define FTS2BA61Y_CMD_REG_R 0xFB
+
+/* touch type masks */
+#define FTS2BA61Y_MASK_TOUCH BIT(0)
+#define FTS2BA61Y_MASK_HOVER BIT(1)
+#define FTS2BA61Y_MASK_COVER BIT(2)
+#define FTS2BA61Y_MASK_GLOVE BIT(3)
+#define FTS2BA61Y_MASK_STYLUS BIT(4)
+#define FTS2BA61Y_MASK_PALM BIT(5)
+#define FTS2BA61Y_MASK_WET BIT(6)
+#define FTS2BA61Y_TOUCHTYPE_DEFAULT (FTS2BA61Y_MASK_TOUCH | \
+ FTS2BA61Y_MASK_PALM | \
+ FTS2BA61Y_MASK_WET)
+
+/* event status masks */
+#define FTS2BA61Y_MASK_STYPE GENMASK(5, 2)
+#define FTS2BA61Y_MASK_EVENT_ID GENMASK(1, 0)
+
+/* event coordinate masks */
+#define FTS2BA61Y_MASK_TCHSTA GENMASK(7, 6)
+#define FTS2BA61Y_MASK_TID GENMASK(5, 2)
+#define FTS2BA61Y_MASK_X_3_0 GENMASK(7, 4)
+#define FTS2BA61Y_MASK_Y_3_0 GENMASK(3, 0)
+#define FTS2BA61Y_MASK_Z GENMASK(5, 0)
+#define FTS2BA61Y_MASK_TTYPE_3_2 GENMASK(7, 6)
+#define FTS2BA61Y_MASK_TTYPE_1_0 GENMASK(1, 0)
+#define FTS2BA61Y_MASK_LEFT_EVENTS GENMASK(4, 0)
+
+/* event error status */
+#define FTS2BA61Y_EVENT_STATUSTYPE_INFO 0x2
+
+/* information report */
+#define FTS2BA61Y_INFO_READY_STATUS 0x0
+
+/* event status */
+#define FTS2BA61Y_COORDINATE_EVENT 0x0
+
+/* touch types */
+#define FTS2BA61Y_TOUCHTYPE_NORMAL 0x0
+#define FTS2BA61Y_TOUCHTYPE_HOVER 0x1
+#define FTS2BA61Y_TOUCHTYPE_FLIPCOVER 0x2
+#define FTS2BA61Y_TOUCHTYPE_GLOVE 0x3
+#define FTS2BA61Y_TOUCHTYPE_STYLUS 0x4
+#define FTS2BA61Y_TOUCHTYPE_PALM 0x5
+#define FTS2BA61Y_TOUCHTYPE_WET 0x6
+#define FTS2BA61Y_TOUCHTYPE_PROXIMITY 0x7
+#define FTS2BA61Y_TOUCHTYPE_JIG 0x8
+
+#define FTS2BA61Y_COORDINATE_ACTION_NONE 0x0
+#define FTS2BA61Y_COORDINATE_ACTION_PRESS 0x1
+#define FTS2BA61Y_COORDINATE_ACTION_MOVE 0x2
+#define FTS2BA61Y_COORDINATE_ACTION_RELEASE 0x3
+
+#define FTS2BA61Y_DEV_NAME "fts2ba61y"
+#define FTS2BA61Y_EVENT_BUFF_SIZE 16
+#define FTS2BA61Y_PANEL_INFO_SIZE 11
+#define FTS2BA61Y_RESET_CMD_SIZE 5
+#define FTS2BA61Y_EVENT_COUNT 31
+#define MAX_TRANSFER_SIZE 256
+
+enum fts2ba61y_regulators {
+ FTS2BA61Y_REGULATOR_VDD,
+ FTS2BA61Y_REGULATOR_AVDD,
+};
+
+struct fts2ba61y_data {
+ struct spi_device *spi;
+ struct regulator_bulk_data regulators[2];
+ struct input_dev *input_dev;
+ struct mutex mutex;
+ struct touchscreen_properties prop;
+
+ u8 tx_count;
+
+ unsigned int max_x;
+ unsigned int max_y;
+};
+
+static int fts2ba61y_write(struct fts2ba61y_data *ts,
+ u8 *reg, int cmd_len, u8 *data, int data_len)
+{
+ struct spi_message msg;
+ struct spi_transfer xfers;
+ char *tx_buf;
+ int len;
+ int ret;
+
+ tx_buf = kzalloc(cmd_len + data_len + 1, GFP_KERNEL);
+ if (!tx_buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memset(&xfers, 0, sizeof(xfers));
+ spi_message_init(&msg);
+
+ memcpy(&tx_buf[0], reg, cmd_len);
+ if (data_len && data)
+ memcpy(&tx_buf[cmd_len], data, data_len);
+
+ len = cmd_len + data_len;
+
+ /* custom write cmd */
+ if (reg[0] != FTS2BA61Y_CMD_REG_W &&
+ reg[0] != FTS2BA61Y_CMD_REG_R) {
+ memmove(tx_buf + 1, tx_buf, len);
+ tx_buf[0] = FTS2BA61Y_CMD_CUSTOM_W;
+ len++;
+ }
+
+ xfers.len = len;
+ xfers.tx_buf = tx_buf;
+
+ spi_message_add_tail(&xfers, &msg);
+
+ mutex_lock(&ts->mutex);
+ ret = spi_sync(ts->spi, &msg);
+ if (ret)
+ dev_err(&ts->spi->dev, "spi transfer error, %d", ret);
+ mutex_unlock(&ts->mutex);
+
+out:
+ kfree(tx_buf);
+ return ret;
+}
+
+static int fts2ba61y_spi_raw_read(struct fts2ba61y_data *ts,
+ u8 *tx_buf, u8 *rx_buf, int len)
+{
+ struct spi_message msg;
+ struct spi_transfer xfer;
+ int ret;
+
+ memset(&xfer, 0, sizeof(xfer));
+ spi_message_init(&msg);
+
+ xfer.len = len;
+ xfer.tx_buf = tx_buf;
+ xfer.rx_buf = rx_buf;
+ spi_message_add_tail(&xfer, &msg);
+
+ mutex_lock(&ts->mutex);
+ ret = spi_sync(ts->spi, &msg);
+ if (ret)
+ dev_err(&ts->spi->dev, "spi transfer error, %d", ret);
+ mutex_unlock(&ts->mutex);
+
+ return ret;
+}
+
+/*
+ * higher-level wrapper that prepares the buffers for a read.
+ */
+static int fts2ba61y_read(struct fts2ba61y_data *ts,
+ u8 reg[], int tx_len, u8 buf[], int rx_len)
+{
+ char *tx_buf, *rx_buf;
+ int ret, mem_len;
+ u16 reg_val;
+
+ if (tx_len > 3)
+ mem_len = rx_len + 1 + tx_len;
+ else
+ mem_len = rx_len + 4;
+
+ tx_buf = kzalloc(mem_len, GFP_KERNEL);
+ rx_buf = kzalloc(mem_len, GFP_KERNEL);
+ if (!tx_buf || !rx_buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ switch (reg[0]) {
+ case FTS2BA61Y_CMD_READ_EVENT:
+ case FTS2BA61Y_CMD_REG_W:
+ case FTS2BA61Y_CMD_REG_R:
+ memcpy(tx_buf, reg, tx_len);
+ break;
+
+ default:
+ tx_buf[0] = FTS2BA61Y_CMD_CUSTOM_R;
+
+ if (tx_len == 1)
+ reg_val = 0;
+ else if (tx_len == 2)
+ reg_val = reg[0];
+ else if (tx_len == 3)
+ reg_val = reg[0] | (reg[1] << 8);
+ else {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ tx_len = 3;
+ put_unaligned_be16(reg_val, &tx_buf[1]);
+
+ ret = fts2ba61y_write(ts, reg, 1, NULL, 0);
+ if (ret < 0)
+ goto out;
+ break;
+ }
+
+ ret = fts2ba61y_spi_raw_read(ts, tx_buf, rx_buf, rx_len + 1 + tx_len);
+ if (ret < 0)
+ goto out;
+
+ memcpy(buf, &rx_buf[1 + tx_len], rx_len);
+
+out:
+ kfree(tx_buf);
+ kfree(rx_buf);
+ return ret;
+}
+
+static int fts2ba61y_wait_for_ready(struct fts2ba61y_data *ts)
+{
+ u8 buffer[FTS2BA61Y_EVENT_BUFF_SIZE];
+ u8 cmd = FTS2BA61Y_CMD_READ_EVENT;
+ u8 status_id, stype;
+ int ret;
+
+ for (int retries = 5; retries > 0; retries--) {
+ ret = fts2ba61y_read(ts, &cmd, 1, buffer, FTS2BA61Y_EVENT_BUFF_SIZE);
+
+ stype = FIELD_GET(FTS2BA61Y_MASK_STYPE, buffer[0]);
+ status_id = buffer[1];
+
+ if (stype == FTS2BA61Y_EVENT_STATUSTYPE_INFO &&
+ status_id == FTS2BA61Y_INFO_READY_STATUS) {
+ ret = 0;
+ break;
+ } else
+ ret = -ENODEV;
+
+ msleep(20);
+ }
+
+ return ret;
+}
+
+static int fts2ba61y_reset(struct fts2ba61y_data *ts)
+{
+ u8 cmd = FTS2BA61Y_CMD_REG_W;
+ /* the following sequence is undocumented */
+ u8 reset[FTS2BA61Y_RESET_CMD_SIZE] = { 0x20, 0x00,
+ 0x00, 0x24, 0x81 };
+ int ret;
+
+ disable_irq(ts->spi->irq);
+
+ ret = fts2ba61y_write(ts, &cmd, 1, &reset[0], FTS2BA61Y_RESET_CMD_SIZE);
+ if (ret)
+ return ret;
+ msleep(30);
+
+ ret = fts2ba61y_wait_for_ready(ts);
+ if (ret)
+ return ret;
+
+ enable_irq(ts->spi->irq);
+
+ return 0;
+}
+
+static int fts2ba61y_set_channels(struct fts2ba61y_data *ts)
+{
+ int ret;
+ u8 cmd = FTS2BA61Y_CMD_READ_PANEL_INFO;
+ u8 data[FTS2BA61Y_PANEL_INFO_SIZE];
+
+ ret = fts2ba61y_read(ts, &cmd, 1, data, FTS2BA61Y_PANEL_INFO_SIZE);
+ if (ret)
+ return ret;
+
+ ts->max_x = get_unaligned_be16(data);
+ ts->max_y = get_unaligned_be16(data + 2);
+
+ /* if no tx channels defined, at least keep one */
+ ts->tx_count = max_t(u8, data[8], 1);
+
+ return 0;
+}
+
+static int fts2ba61y_set_touch_func(struct fts2ba61y_data *ts)
+{
+ u8 cmd = FTS2BA61Y_CMD_TOUCHTYPE;
+ u16 touchtype = cpu_to_le16(FTS2BA61Y_TOUCHTYPE_DEFAULT);
+
+ return fts2ba61y_write(ts, &cmd, 1, (u8 *)&touchtype, 2);
+}
+
+static int fts2ba61y_hw_init(struct fts2ba61y_data *ts)
+{
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+ if (ret)
+ return ret;
+
+ msleep(140);
+
+ ret = fts2ba61y_reset(ts);
+ if (ret)
+ return ret;
+
+ ret = fts2ba61y_set_channels(ts);
+ if (ret)
+ return ret;
+
+ return fts2ba61y_set_touch_func(ts);
+}
+
+static int fts2ba61y_get_event(struct fts2ba61y_data *ts, u8 *data, int *n_events)
+{
+ int ret;
+ u8 cmd = FTS2BA61Y_CMD_READ_EVENT;
+
+ ret = fts2ba61y_read(ts, &cmd, 1, data, FTS2BA61Y_EVENT_BUFF_SIZE);
+ if (ret < 0)
+ return ret;
+
+ if (!data[0]) {
+ *n_events = 0;
+ return 0;
+ }
+
+ *n_events = FIELD_GET(FTS2BA61Y_MASK_LEFT_EVENTS, data[7]);
+ if (unlikely(*n_events >= FTS2BA61Y_EVENT_COUNT)) {
+ cmd = FTS2BA61Y_CMD_CLEAR_EVENTS;
+ fts2ba61y_write(ts, &cmd, 1, NULL, 0);
+ *n_events = 0;
+ return -EINVAL;
+ }
+
+ if (*n_events > 0) {
+ ret = fts2ba61y_read(ts, &cmd, 1,
+ &data[1 * FTS2BA61Y_EVENT_BUFF_SIZE],
+ FTS2BA61Y_EVENT_BUFF_SIZE * (*n_events));
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void fts2ba61y_report_coordinates(struct fts2ba61y_data *ts,
+ u8 *event, u8 tid)
+{
+ u8 major = event[4];
+ u8 minor = event[5];
+ u8 z = FIELD_GET(FTS2BA61Y_MASK_Z, event[6]);
+
+ u16 x = (event[1] << 4) |
+ FIELD_GET(FTS2BA61Y_MASK_X_3_0, event[3]);
+ u16 y = (event[2] << 4) |
+ FIELD_GET(FTS2BA61Y_MASK_Y_3_0, event[3]);
+ u16 ttype = (FIELD_GET(FTS2BA61Y_MASK_TTYPE_3_2, event[6]) << 2) |
+ (FIELD_GET(FTS2BA61Y_MASK_TTYPE_1_0, event[7]) << 0);
+
+ if (ttype != FTS2BA61Y_TOUCHTYPE_NORMAL &&
+ ttype != FTS2BA61Y_TOUCHTYPE_PALM &&
+ ttype != FTS2BA61Y_TOUCHTYPE_WET &&
+ ttype != FTS2BA61Y_TOUCHTYPE_GLOVE)
+ return;
+
+ input_mt_slot(ts->input_dev, tid);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
+ input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, major);
+ input_report_abs(ts->input_dev, ABS_MT_TOUCH_MINOR, minor);
+ input_report_abs(ts->input_dev, ABS_MT_PRESSURE, z);
+
+ input_mt_sync_frame(ts->input_dev);
+ input_sync(ts->input_dev);
+}
+
+static void fts2ba61y_report_release(struct fts2ba61y_data *ts, u8 tid)
+{
+ input_mt_slot(ts->input_dev, tid);
+ input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false);
+
+ input_mt_sync_frame(ts->input_dev);
+ input_sync(ts->input_dev);
+}
+
+static void fts2ba61y_handle_coordinates(struct fts2ba61y_data *ts, u8 *event)
+{
+ u8 t_id = FIELD_GET(FTS2BA61Y_MASK_TID, event[0]);
+ u8 action = FIELD_GET(FTS2BA61Y_MASK_TCHSTA, event[0]);
+
+ if (t_id > ts->tx_count)
+ return;
+
+ switch (action) {
+ case FTS2BA61Y_COORDINATE_ACTION_PRESS:
+ case FTS2BA61Y_COORDINATE_ACTION_MOVE:
+ fts2ba61y_report_coordinates(ts, event, t_id);
+ break;
+
+ case FTS2BA61Y_COORDINATE_ACTION_RELEASE:
+ fts2ba61y_report_release(ts, t_id);
+ break;
+ }
+}
+
+static irqreturn_t fts2ba61y_irq_handler(int irq, void *handle)
+{
+ struct fts2ba61y_data *ts = handle;
+ u8 buffer[FTS2BA61Y_EVENT_COUNT * FTS2BA61Y_EVENT_BUFF_SIZE];
+ u8 *event;
+ u8 event_id;
+ int n_events = 0;
+ int ret;
+
+ usleep(1);
+
+ ret = fts2ba61y_get_event(ts, buffer, &n_events);
+ if (ret < 0) {
+ dev_dbg(&ts->spi->dev, "failed to get event: %d", ret);
+ return IRQ_HANDLED;
+ }
+
+ for (int i = 0; i <= n_events; i++) {
+ event = &buffer[i * FTS2BA61Y_EVENT_BUFF_SIZE];
+ event_id = FIELD_GET(FTS2BA61Y_MASK_EVENT_ID, event[0]);
+
+ if (event_id == FTS2BA61Y_COORDINATE_EVENT)
+ fts2ba61y_handle_coordinates(ts, event);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int fts2ba61y_input_open(struct input_dev *dev)
+{
+ struct fts2ba61y_data *ts = input_get_drvdata(dev);
+ u8 cmd = FTS2BA61Y_CMD_SENSE_ON;
+
+ return fts2ba61y_write(ts, &cmd, 1, NULL, 0);
+}
+
+static void fts2ba61y_input_close(struct input_dev *dev)
+{
+ struct fts2ba61y_data *ts = input_get_drvdata(dev);
+ int ret;
+ u8 cmd = FTS2BA61Y_CMD_SENSE_OFF;
+
+ ret = fts2ba61y_write(ts, &cmd, 1, NULL, 0);
+ if (ret)
+ dev_err(&ts->spi->dev, "failed to turn off sensing\n");
+}
+
+static void fts2ba61y_power_off(void *data)
+{
+ struct fts2ba61y_data *ts = data;
+
+ disable_irq(ts->spi->irq);
+ regulator_bulk_disable(ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+}
+
+static int fts2ba61y_probe(struct spi_device *spi) {
+ struct fts2ba61y_data *ts;
+ struct input_dev *input_dev;
+ int error;
+
+ ts = devm_kzalloc(&spi->dev, sizeof(*ts), GFP_KERNEL);
+ if (!ts)
+ return -ENOMEM;
+
+ ts->spi = spi;
+ mutex_init(&ts->mutex);
+
+ spi->mode = SPI_MODE_0;
+ spi->bits_per_word = 8;
+
+ error = spi_setup(spi);
+ if (error)
+ return error;
+
+ ts->regulators[FTS2BA61Y_REGULATOR_VDD].supply = "vdd";
+ ts->regulators[FTS2BA61Y_REGULATOR_AVDD].supply = "avdd";
+ error = devm_regulator_bulk_get(&spi->dev,
+ ARRAY_SIZE(ts->regulators),
+ ts->regulators);
+ if (error)
+ return error;
+
+ error = fts2ba61y_hw_init(ts);
+ if (error)
+ return error;
+
+ error = devm_add_action_or_reset(&ts->spi->dev, fts2ba61y_power_off, ts);
+ if (error)
+ return error;
+
+ input_dev = devm_input_allocate_device(&spi->dev);
+ if (!input_dev)
+ return -ENOMEM;
+
+ ts->input_dev = input_dev;
+
+ input_dev->name = FTS2BA61Y_DEV_NAME;
+ input_dev->id.bustype = BUS_SPI;
+ input_dev->open = fts2ba61y_input_open;
+ input_dev->close = fts2ba61y_input_close;
+
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ts->max_x, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ts->max_y, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
+
+ touchscreen_parse_properties(input_dev, true, &ts->prop);
+
+ spi_set_drvdata(spi, ts);
+ input_set_drvdata(input_dev, ts);
+
+ error = input_mt_init_slots(input_dev, ts->tx_count, INPUT_MT_DIRECT);
+ if (error)
+ return error;
+
+ error = input_register_device(input_dev);
+ if (error)
+ return error;
+
+ error = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
+ fts2ba61y_irq_handler,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ "fts2ba61y_irq", ts);
+ return error;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id spi_touchscreen_dt_ids[] = {
+ { .compatible = "st,fts2ba61y" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, spi_touchscreen_dt_ids);
+#endif
+
+static const struct spi_device_id fts2ba61y_spi_ids[] = {
+ { "fts2ba61y" },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, fts2ba61y_spi_ids);
+
+static struct spi_driver spi_touchscreen_driver = {
+ .driver = {
+ .name = FTS2BA61Y_DEV_NAME,
+ .of_match_table = of_match_ptr(spi_touchscreen_dt_ids),
+ },
+ .probe = fts2ba61y_probe,
+ .id_table = fts2ba61y_spi_ids,
+};
+
+module_spi_driver(spi_touchscreen_driver);
+
+MODULE_AUTHOR("Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>");
+MODULE_DESCRIPTION("ST-Microelectronics FTS2BA61Y Touch Screen");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related
* [PATCH v1 1/2] dt-bindings: input: Add ST-Microelectronics FTS2BA61Y touchscreen
From: Eric Gonçalves @ 2025-09-20 1:44 UTC (permalink / raw)
To: Henrik Rydberg, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Ivaylo Ivanov, devicetree, linux-input, linux-kernel
In-Reply-To: <20250920014450.37787-1-ghatto404@gmail.com>
Add the bindings for ST-Microelectronics FTS2BA61Y capacitive touchscreen.
Signed-off-by: Eric Gonçalves <ghatto404@gmail.com>
---
.../input/touchscreen/st,fts2ba61y.yaml | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100755 Documentation/devicetree/bindings/input/touchscreen/st,fts2ba61y.yaml
diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,fts2ba61y.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,fts2ba61y.yaml
new file mode 100644
index 000000000000..d5565b5360fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/st,fts2ba61y.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/st,fts2ba61y.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ST-Microelectronics FTS2BA61Y touchscreen controller
+
+maintainers:
+ - Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+properties:
+ compatible:
+ const: st,fts2ba61y
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ avdd-supply: true
+ vdd-supply: true
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - avdd-supply
+ - vdd-supply
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@0 {
+ compatible = "st,fts2ba61y";
+ reg = <0x0>;
+ interrupt-parent = <&gpa2>;
+ interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+ avdd-supply = <&ldo17_reg>;
+ vdd-supply = <&ldo28_reg>;
+ };
+ };
--
2.51.0
^ permalink raw reply related
* [PATCH v1 0/2] Input: add fts2ba61y touchscreen driver
From: Eric Gonçalves @ 2025-09-20 1:44 UTC (permalink / raw)
To: Henrik Rydberg, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: Ivaylo Ivanov, devicetree, linux-input, linux-kernel
This patchset adds support for the ST-Microelectronics FTS2BA61Y,
a capacitive multi-touch touchscreen controller. this touchscreen
is used in many mobile devices, like ones from the Galaxy S22 series
and the Z Fold 5. Ivaylo Ivanov wrote the driver originally,
and I'm upstreaming it on his behalf.
Shortly after this patchset, I'll be sending another one that
enables touchscreen on the Galaxy S22 (r0q) board.
Thanks!
Changes from RFC->v1:
- move unevaluatedProperties to after the required: field
- set Ivaylo as the author of driver commit
Eric Gonçalves (1):
dt-bindings: input: Add ST-Microelectronics FTS2BA61Y touchscreen
Ivaylo Ivanov (1):
Input: add support for the STM FTS2BA61Y touchscreen
.../input/touchscreen/st,fts2ba61y.yaml | 52 ++
drivers/input/touchscreen/Kconfig | 11 +
drivers/input/touchscreen/Makefile | 1 +
drivers/input/touchscreen/fts2ba61y.c | 588 ++++++++++++++++++
4 files changed, 652 insertions(+)
create mode 100755 Documentation/devicetree/bindings/input/touchscreen/st,fts2ba61y.yaml
create mode 100644 drivers/input/touchscreen/fts2ba61y.c
--
2.51.0
^ permalink raw reply
* Re: [PATCH v6] HID: lg-g15 - Add support for Logitech G13.
From: Hans de Goede @ 2025-09-19 21:09 UTC (permalink / raw)
To: Leo L. Schwab
Cc: Kate Hsuan, Jiri Kosina, Benjamin Tissoires, linux-input,
linux-kernel
In-Reply-To: <20250917230550.1160621-1-ewhac@ewhac.org>
Hi,
On 18-Sep-25 1:05 AM, Leo L. Schwab wrote:
> The Logitech G13 is a gaming keypad with general-purpose macro keys,
> four LED-backlit macro preset keys, five "menu" keys, backlight toggle
> key, an analog thumbstick, RGB LED backlight, and a monochrome LCD
> display.
>
> Support input event generation for all keys and the thumbstick, and
> expose all LEDs.
>
> Signed-off-by: Leo L. Schwab <ewhac@ewhac.org>
> Reviewed-by: Hans de Goede <hansg@kernel.org>
> Tested-by: Kate Hsuan <hpa@redhat.com>
> ---
> Changes in v6:
> - Alter interaction between `brightness` and `brightness_hw_changed`
> for the backlight as advised by Hans de Goede <hansg@kernel.org>.
> - On probe, query device for current state of HW backlight toggle;
> track in `backlight_disabled` and update sysfs.
> - Ensure non-backlight LED brightnesses report either 0 or 1.
Thanks, this latest version looks good to me:
Reviewed-by: Hans de Goede <hansg@kernel.org>
note this is already there, just making clear that all me
remarks are resolved now and this is ready to merge.
Regards,
Hans
> Changes in v5:
> - None; resend v4 due to bounced email submission.
> Changes in v4:
> - Minor changes recommended by Hans de Goede <hansg@kernel.org>.
> Changes in v3:
> - Re-revise commit message.
> - Conditionally compile the section depending on
> CONFIG_LEDS_BRIGHTNESS_HW_CHANGED correctly this time.
> - Use led-class-multicolor facilities for the RGB backlight.
> - Changes recommended by Kate Hsuan <hpa@redhat.com>:
> - Use guard(mutex) construct.
> - Fix numerous style nits.
> Changes in v2:
> - Add `#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED` bracket around new
> code segment dependent on that feature (fixes test robot build
> error).
> - Use `guard(mutex)` construct in new code (existing code left
> unmodified).
> - Commit message revised.
>
> drivers/hid/hid-ids.h | 1 +
> drivers/hid/hid-lg-g15.c | 448 +++++++++++++++++++++++++++++++++++++--
> 2 files changed, 433 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 33cc5820f2be..7ed1e402b80a 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -870,6 +870,7 @@
> #define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219
> +#define USB_DEVICE_ID_LOGITECH_G13 0xc21c
> #define USB_DEVICE_ID_LOGITECH_G15_LCD 0xc222
> #define USB_DEVICE_ID_LOGITECH_G11 0xc225
> #define USB_DEVICE_ID_LOGITECH_G15_V2_LCD 0xc227
> diff --git a/drivers/hid/hid-lg-g15.c b/drivers/hid/hid-lg-g15.c
> index f8605656257b..7b8df2d5b57f 100644
> --- a/drivers/hid/hid-lg-g15.c
> +++ b/drivers/hid/hid-lg-g15.c
> @@ -26,7 +26,21 @@
> #define LG_G510_FEATURE_BACKLIGHT_RGB 0x05
> #define LG_G510_FEATURE_POWER_ON_RGB 0x06
>
> +#define LG_G13_INPUT_REPORT 0x01
> +#define LG_G13_FEATURE_M_KEYS_LEDS 0x05
> +#define LG_G13_FEATURE_BACKLIGHT_RGB 0x07
> +#define LG_G13_BACKLIGHT_HW_ON_BIT 23
> +
> +/**
> + * g13_input_report.keybits[] is not 32-bit aligned, so we can't use the bitops macros.
> + *
> + * @ary: Pointer to array of u8s
> + * @b: Bit index into ary, LSB first. Not range checked.
> + */
> +#define TEST_BIT(ary, b) ((1 << ((b) & 7)) & (ary)[(b) >> 3])
> +
> enum lg_g15_model {
> + LG_G13,
> LG_G15,
> LG_G15_V2,
> LG_G510,
> @@ -45,6 +59,12 @@ enum lg_g15_led_type {
> LG_G15_LED_MAX
> };
>
> +struct g13_input_report {
> + u8 report_id; /* Report ID is always set to 1. */
> + u8 joy_x, joy_y;
> + u8 keybits[5];
> +};
> +
> struct lg_g15_led {
> union {
> struct led_classdev cdev;
> @@ -63,12 +83,188 @@ struct lg_g15_data {
> struct mutex mutex;
> struct work_struct work;
> struct input_dev *input;
> + struct input_dev *input_js; /* Separate joystick device for G13. */
> struct hid_device *hdev;
> enum lg_g15_model model;
> struct lg_g15_led leds[LG_G15_LED_MAX];
> bool game_mode_enabled;
> + bool backlight_disabled; /* true == HW backlight toggled *OFF* */
> };
>
> +/********* G13 LED functions ***********/
> +/*
> + * G13 retains no state across power cycles, and always powers up with the backlight on,
> + * color #5AFF6E, all macro key LEDs off.
> + */
> +static int lg_g13_get_leds_state(struct lg_g15_data *g15)
> +{
> + u8 * const tbuf = g15->transfer_buf;
> + int ret, high;
> +
> + /* RGB backlight. */
> + ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_BACKLIGHT_RGB,
> + tbuf, 5,
> + HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
> + if (ret != 5) {
> + hid_err(g15->hdev, "Error getting backlight brightness: %d\n", ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> +
> + /* Normalize RGB intensities against the highest component. */
> + high = max3(tbuf[1], tbuf[2], tbuf[3]);
> + if (high) {
> + g15->leds[LG_G15_KBD_BRIGHTNESS].red =
> + DIV_ROUND_CLOSEST(tbuf[1] * 255, high);
> + g15->leds[LG_G15_KBD_BRIGHTNESS].green =
> + DIV_ROUND_CLOSEST(tbuf[2] * 255, high);
> + g15->leds[LG_G15_KBD_BRIGHTNESS].blue =
> + DIV_ROUND_CLOSEST(tbuf[3] * 255, high);
> + g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = high;
> + } else {
> + g15->leds[LG_G15_KBD_BRIGHTNESS].red = 255;
> + g15->leds[LG_G15_KBD_BRIGHTNESS].green = 255;
> + g15->leds[LG_G15_KBD_BRIGHTNESS].blue = 255;
> + g15->leds[LG_G15_KBD_BRIGHTNESS].brightness = 0;
> + }
> +
> + /* Macro LEDs. */
> + ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_M_KEYS_LEDS,
> + tbuf, 5,
> + HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
> + if (ret != 5) {
> + hid_err(g15->hdev, "Error getting macro LED brightness: %d\n", ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> +
> + for (int i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; ++i)
> + g15->leds[i].brightness = !!(tbuf[1] & (1 << (i - LG_G15_MACRO_PRESET1)));
> +
> + /*
> + * Bit 23 of g13_input_report.keybits[] contains the backlight's
> + * current HW toggle state. Retrieve it from the device.
> + */
> + ret = hid_hw_raw_request(g15->hdev, LG_G13_INPUT_REPORT,
> + tbuf, sizeof(struct g13_input_report),
> + HID_INPUT_REPORT, HID_REQ_GET_REPORT);
> + if (ret != sizeof(struct g13_input_report)) {
> + hid_err(g15->hdev, "Error getting backlight on/off state: %d\n", ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> + g15->backlight_disabled =
> + !TEST_BIT(((struct g13_input_report *) tbuf)->keybits,
> + LG_G13_BACKLIGHT_HW_ON_BIT);
> +
> + return 0;
> +}
> +
> +static int lg_g13_kbd_led_write(struct lg_g15_data *g15,
> + struct lg_g15_led *g15_led,
> + enum led_brightness brightness)
> +{
> + struct mc_subled const * const subleds = g15_led->mcdev.subled_info;
> + u8 * const tbuf = g15->transfer_buf;
> + int ret;
> +
> + guard(mutex)(&g15->mutex);
> +
> + led_mc_calc_color_components(&g15_led->mcdev, brightness);
> +
> + tbuf[0] = 5;
> + tbuf[1] = subleds[0].brightness;
> + tbuf[2] = subleds[1].brightness;
> + tbuf[3] = subleds[2].brightness;
> + tbuf[4] = 0;
> +
> + ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_BACKLIGHT_RGB,
> + tbuf, 5,
> + HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
> + if (ret != 5) {
> + hid_err(g15->hdev, "Error setting backlight brightness: %d\n", ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> +
> + g15_led->brightness = brightness;
> + return 0;
> +}
> +
> +static int lg_g13_kbd_led_set(struct led_classdev *led_cdev, enum led_brightness brightness)
> +{
> + struct led_classdev_mc *mc = lcdev_to_mccdev(led_cdev);
> + struct lg_g15_led *g15_led =
> + container_of(mc, struct lg_g15_led, mcdev);
> + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
> +
> + /* Ignore LED off on unregister / keyboard unplug */
> + if (led_cdev->flags & LED_UNREGISTERING)
> + return 0;
> +
> + return lg_g13_kbd_led_write(g15, g15_led, brightness);
> +}
> +
> +static enum led_brightness lg_g13_kbd_led_get(struct led_classdev *led_cdev)
> +{
> + struct led_classdev_mc const * const mc = lcdev_to_mccdev(led_cdev);
> + struct lg_g15_led const *g15_led =
> + container_of(mc, struct lg_g15_led, mcdev);
> +
> + return g15_led->brightness;
> +}
> +
> +static int lg_g13_mkey_led_set(struct led_classdev *led_cdev, enum led_brightness brightness)
> +{
> + struct lg_g15_led *g15_led =
> + container_of(led_cdev, struct lg_g15_led, cdev);
> + struct lg_g15_data *g15 = dev_get_drvdata(led_cdev->dev->parent);
> + int i, ret;
> + u8 * const tbuf = g15->transfer_buf;
> + u8 val, mask = 0;
> +
> + /* Ignore LED off on unregister / keyboard unplug */
> + if (led_cdev->flags & LED_UNREGISTERING)
> + return 0;
> +
> + guard(mutex)(&g15->mutex);
> +
> + for (i = LG_G15_MACRO_PRESET1; i < LG_G15_LED_MAX; ++i) {
> + if (i == g15_led->led)
> + val = brightness;
> + else
> + val = g15->leds[i].brightness;
> +
> + if (val)
> + mask |= 1 << (i - LG_G15_MACRO_PRESET1);
> + }
> +
> + tbuf[0] = 5;
> + tbuf[1] = mask;
> + tbuf[2] = 0;
> + tbuf[3] = 0;
> + tbuf[4] = 0;
> +
> + ret = hid_hw_raw_request(g15->hdev, LG_G13_FEATURE_M_KEYS_LEDS,
> + tbuf, 5,
> + HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
> + if (ret != 5) {
> + hid_err(g15->hdev, "Error setting LED brightness: %d\n", ret);
> + return (ret < 0) ? ret : -EIO;
> + }
> +
> + g15_led->brightness = brightness;
> + return 0;
> +}
> +
> +static enum led_brightness lg_g13_mkey_led_get(struct led_classdev *led_cdev)
> +{
> + /*
> + * G13 doesn't change macro key LEDs behind our back, so they're
> + * whatever we last set them to.
> + */
> + struct lg_g15_led *g15_led =
> + container_of(led_cdev, struct lg_g15_led, cdev);
> +
> + return g15_led->brightness;
> +}
> +
> /******** G15 and G15 v2 LED functions ********/
>
> static int lg_g15_update_led_brightness(struct lg_g15_data *g15)
> @@ -390,6 +586,8 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15)
> int ret;
>
> switch (g15->model) {
> + case LG_G13:
> + return lg_g13_get_leds_state(g15);
> case LG_G15:
> case LG_G15_V2:
> return lg_g15_update_led_brightness(g15);
> @@ -417,6 +615,108 @@ static int lg_g15_get_initial_led_brightness(struct lg_g15_data *g15)
>
> /******** Input functions ********/
>
> +/* Table mapping keybits[] bit positions to event codes. */
> +/* Note: Indices are discontinuous to aid readability. */
> +static const u16 g13_keys_for_bits[] = {
> + /* Main keypad - keys G1 - G22 */
> + [0] = KEY_MACRO1,
> + [1] = KEY_MACRO2,
> + [2] = KEY_MACRO3,
> + [3] = KEY_MACRO4,
> + [4] = KEY_MACRO5,
> + [5] = KEY_MACRO6,
> + [6] = KEY_MACRO7,
> + [7] = KEY_MACRO8,
> + [8] = KEY_MACRO9,
> + [9] = KEY_MACRO10,
> + [10] = KEY_MACRO11,
> + [11] = KEY_MACRO12,
> + [12] = KEY_MACRO13,
> + [13] = KEY_MACRO14,
> + [14] = KEY_MACRO15,
> + [15] = KEY_MACRO16,
> + [16] = KEY_MACRO17,
> + [17] = KEY_MACRO18,
> + [18] = KEY_MACRO19,
> + [19] = KEY_MACRO20,
> + [20] = KEY_MACRO21,
> + [21] = KEY_MACRO22,
> +
> + /* LCD menu buttons. */
> + [24] = KEY_KBD_LCD_MENU5, /* "Next page" button */
> + [25] = KEY_KBD_LCD_MENU1, /* Left-most */
> + [26] = KEY_KBD_LCD_MENU2,
> + [27] = KEY_KBD_LCD_MENU3,
> + [28] = KEY_KBD_LCD_MENU4, /* Right-most */
> +
> + /* Macro preset and record buttons; have red LEDs under them. */
> + [29] = KEY_MACRO_PRESET1,
> + [30] = KEY_MACRO_PRESET2,
> + [31] = KEY_MACRO_PRESET3,
> + [32] = KEY_MACRO_RECORD_START,
> +
> + /* 33-35 handled by joystick device. */
> +
> + /* Backlight toggle. */
> + [37] = KEY_LIGHTS_TOGGLE,
> +};
> +
> +#define G13_JS_KEYBITS_OFFSET 33
> +
> +static const u16 g13_keys_for_bits_js[] = {
> + /* Joystick buttons */
> + /* These keybits are at bit indices 33, 34, and 35. */
> + BTN_BASE, /* Left side */
> + BTN_BASE2, /* Bottom side */
> + BTN_THUMB, /* Stick depress */
> +};
> +
> +static int lg_g13_event(struct lg_g15_data *g15, u8 const *data)
> +{
> + struct g13_input_report const * const rep = (struct g13_input_report *) data;
> + int i, val;
> + bool backlight_disabled;
> +
> + /*
> + * Main macropad and menu keys.
> + * Emit key events defined for each bit position.
> + */
> + for (i = 0; i < ARRAY_SIZE(g13_keys_for_bits); ++i) {
> + if (g13_keys_for_bits[i]) {
> + val = TEST_BIT(rep->keybits, i);
> + input_report_key(g15->input, g13_keys_for_bits[i], val);
> + }
> + }
> + input_sync(g15->input);
> +
> + /*
> + * Joystick.
> + * Emit button and deflection events.
> + */
> + for (i = 0; i < ARRAY_SIZE(g13_keys_for_bits_js); ++i) {
> + val = TEST_BIT(rep->keybits, i + G13_JS_KEYBITS_OFFSET);
> + input_report_key(g15->input_js, g13_keys_for_bits_js[i], val);
> + }
> + input_report_abs(g15->input_js, ABS_X, rep->joy_x);
> + input_report_abs(g15->input_js, ABS_Y, rep->joy_y);
> + input_sync(g15->input_js);
> +
> + /*
> + * Bit 23 of keybits[] reports the current backlight on/off state. If
> + * it has changed from the last cached value, apply an update.
> + */
> + backlight_disabled = !TEST_BIT(rep->keybits, LG_G13_BACKLIGHT_HW_ON_BIT);
> + if (backlight_disabled ^ g15->backlight_disabled) {
> + led_classdev_notify_brightness_hw_changed(
> + &g15->leds[LG_G15_KBD_BRIGHTNESS].mcdev.led_cdev,
> + backlight_disabled
> + ? 0 : g15->leds[LG_G15_KBD_BRIGHTNESS].brightness);
> + g15->backlight_disabled = backlight_disabled;
> + }
> +
> + return 0;
> +}
> +
> /* On the G15 Mark I Logitech has been quite creative with which bit is what */
> static void lg_g15_handle_lcd_menu_keys(struct lg_g15_data *g15, u8 *data)
> {
> @@ -572,6 +872,10 @@ static int lg_g15_raw_event(struct hid_device *hdev, struct hid_report *report,
> return 0;
>
> switch (g15->model) {
> + case LG_G13:
> + if (data[0] == 0x01 && size == sizeof(struct g13_input_report))
> + return lg_g13_event(g15, data);
> + break;
> case LG_G15:
> if (data[0] == 0x02 && size == 9)
> return lg_g15_event(g15, data);
> @@ -616,13 +920,22 @@ static void lg_g15_setup_led_rgb(struct lg_g15_data *g15, int index)
> {
> int i;
> struct mc_subled *subled_info;
> -
> - g15->leds[index].mcdev.led_cdev.brightness_set_blocking =
> - lg_g510_kbd_led_set;
> - g15->leds[index].mcdev.led_cdev.brightness_get =
> - lg_g510_kbd_led_get;
> - g15->leds[index].mcdev.led_cdev.max_brightness = 255;
> - g15->leds[index].mcdev.num_colors = 3;
> + struct lg_g15_led * const gled = &g15->leds[index];
> +
> + if (g15->model == LG_G13) {
> + gled->mcdev.led_cdev.brightness_set_blocking =
> + lg_g13_kbd_led_set;
> + gled->mcdev.led_cdev.brightness_get =
> + lg_g13_kbd_led_get;
> + gled->mcdev.led_cdev.flags = LED_BRIGHT_HW_CHANGED;
> + } else {
> + gled->mcdev.led_cdev.brightness_set_blocking =
> + lg_g510_kbd_led_set;
> + gled->mcdev.led_cdev.brightness_get =
> + lg_g510_kbd_led_get;
> + }
> + gled->mcdev.led_cdev.max_brightness = 255;
> + gled->mcdev.num_colors = 3;
>
> subled_info = devm_kcalloc(&g15->hdev->dev, 3, sizeof(*subled_info), GFP_KERNEL);
> if (!subled_info)
> @@ -632,20 +945,20 @@ static void lg_g15_setup_led_rgb(struct lg_g15_data *g15, int index)
> switch (i + 1) {
> case LED_COLOR_ID_RED:
> subled_info[i].color_index = LED_COLOR_ID_RED;
> - subled_info[i].intensity = g15->leds[index].red;
> + subled_info[i].intensity = gled->red;
> break;
> case LED_COLOR_ID_GREEN:
> subled_info[i].color_index = LED_COLOR_ID_GREEN;
> - subled_info[i].intensity = g15->leds[index].green;
> + subled_info[i].intensity = gled->green;
> break;
> case LED_COLOR_ID_BLUE:
> subled_info[i].color_index = LED_COLOR_ID_BLUE;
> - subled_info[i].intensity = g15->leds[index].blue;
> + subled_info[i].intensity = gled->blue;
> break;
> }
> subled_info[i].channel = i;
> }
> - g15->leds[index].mcdev.subled_info = subled_info;
> + gled->mcdev.subled_info = subled_info;
> }
>
> static int lg_g15_register_led(struct lg_g15_data *g15, int i, const char *name)
> @@ -656,6 +969,23 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i, const char *name)
> g15->leds[i].cdev.name = name;
>
> switch (g15->model) {
> + case LG_G13:
> + if (i < LG_G15_BRIGHTNESS_MAX) {
> + /* RGB backlight. */
> + lg_g15_setup_led_rgb(g15, i);
> + ret = devm_led_classdev_multicolor_register_ext(&g15->hdev->dev,
> + &g15->leds[i].mcdev,
> + NULL);
> + } else {
> + /* Macro keys */
> + g15->leds[i].cdev.brightness_set_blocking = lg_g13_mkey_led_set;
> + g15->leds[i].cdev.brightness_get = lg_g13_mkey_led_get;
> + g15->leds[i].cdev.max_brightness = 1;
> +
> + ret = devm_led_classdev_register(&g15->hdev->dev,
> + &g15->leds[i].cdev);
> + }
> + break;
> case LG_G15:
> case LG_G15_V2:
> g15->leds[i].cdev.brightness_get = lg_g15_led_get;
> @@ -702,11 +1032,9 @@ static int lg_g15_register_led(struct lg_g15_data *g15, int i, const char *name)
> }
>
> /* Common input device init code shared between keyboards and Z-10 speaker handling */
> -static void lg_g15_init_input_dev(struct hid_device *hdev, struct input_dev *input,
> - const char *name)
> +static void lg_g15_init_input_dev_core(struct hid_device *hdev, struct input_dev *input,
> + char const *name)
> {
> - int i;
> -
> input->name = name;
> input->phys = hdev->phys;
> input->uniq = hdev->uniq;
> @@ -717,12 +1045,42 @@ static void lg_g15_init_input_dev(struct hid_device *hdev, struct input_dev *inp
> input->dev.parent = &hdev->dev;
> input->open = lg_g15_input_open;
> input->close = lg_g15_input_close;
> +}
> +
> +static void lg_g15_init_input_dev(struct hid_device *hdev, struct input_dev *input,
> + const char *name)
> +{
> + int i;
> +
> + lg_g15_init_input_dev_core(hdev, input, name);
>
> /* Keys below the LCD, intended for controlling a menu on the LCD */
> for (i = 0; i < 5; i++)
> input_set_capability(input, EV_KEY, KEY_KBD_LCD_MENU1 + i);
> }
>
> +static void lg_g13_init_input_dev(struct hid_device *hdev,
> + struct input_dev *input, const char *name,
> + struct input_dev *input_js, const char *name_js)
> +{
> + /* Macropad. */
> + lg_g15_init_input_dev_core(hdev, input, name);
> + for (int i = 0; i < ARRAY_SIZE(g13_keys_for_bits); ++i) {
> + if (g13_keys_for_bits[i])
> + input_set_capability(input, EV_KEY, g13_keys_for_bits[i]);
> + }
> +
> + /* OBTW, we're a joystick, too... */
> + lg_g15_init_input_dev_core(hdev, input_js, name_js);
> + for (int i = 0; i < ARRAY_SIZE(g13_keys_for_bits_js); ++i)
> + input_set_capability(input_js, EV_KEY, g13_keys_for_bits_js[i]);
> +
> + input_set_capability(input_js, EV_ABS, ABS_X);
> + input_set_abs_params(input_js, ABS_X, 0, 255, 0, 0);
> + input_set_capability(input_js, EV_ABS, ABS_Y);
> + input_set_abs_params(input_js, ABS_Y, 0, 255, 0, 0);
> +}
> +
> static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> {
> static const char * const led_names[] = {
> @@ -739,7 +1097,7 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> unsigned int connect_mask = 0;
> bool has_ff000000 = false;
> struct lg_g15_data *g15;
> - struct input_dev *input;
> + struct input_dev *input, *input_js;
> struct hid_report *rep;
> int ret, i, gkeys = 0;
>
> @@ -778,6 +1136,25 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> hid_set_drvdata(hdev, (void *)g15);
>
> switch (g15->model) {
> + case LG_G13:
> + /*
> + * The G13 has an analog thumbstick with nearby buttons. Some
> + * libraries and applications are known to ignore devices that
> + * don't "look like" a joystick, and a device with two ABS axes
> + * and 25+ macro keys would confuse them.
> + *
> + * Create an additional input device dedicated to appear as a
> + * simplified joystick (two ABS axes, three BTN buttons).
> + */
> + input_js = devm_input_allocate_device(&hdev->dev);
> + if (!input_js)
> + return -ENOMEM;
> + g15->input_js = input_js;
> + input_set_drvdata(input_js, hdev);
> +
> + connect_mask = HID_CONNECT_HIDRAW;
> + gkeys = 25;
> + break;
> case LG_G15:
> INIT_WORK(&g15->work, lg_g15_leds_changed_work);
> /*
> @@ -859,6 +1236,38 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> goto error_hw_stop;
>
> return 0; /* All done */
> + } else if (g15->model == LG_G13) {
> + static char const * const g13_led_names[] = {
> + /* Backlight is shared between LCD and keys. */
> + "g13:rgb:kbd_backlight",
> + NULL, /* Keep in sync with led_type enum */
> + "g13:red:macro_preset_1",
> + "g13:red:macro_preset_2",
> + "g13:red:macro_preset_3",
> + "g13:red:macro_record",
> + };
> + lg_g13_init_input_dev(hdev,
> + input, "Logitech G13 Gaming Keypad",
> + input_js, "Logitech G13 Thumbstick");
> + ret = input_register_device(input);
> + if (ret)
> + goto error_hw_stop;
> + ret = input_register_device(input_js);
> + if (ret)
> + goto error_hw_stop;
> +
> + for (i = 0; i < ARRAY_SIZE(g13_led_names); ++i) {
> + if (g13_led_names[i]) {
> + ret = lg_g15_register_led(g15, i, g13_led_names[i]);
> + if (ret)
> + goto error_hw_stop;
> + }
> + }
> + led_classdev_notify_brightness_hw_changed(
> + &g15->leds[LG_G15_KBD_BRIGHTNESS].mcdev.led_cdev,
> + g15->backlight_disabled
> + ? 0 : g15->leds[LG_G15_KBD_BRIGHTNESS].brightness);
> + return 0;
> }
>
> /* Setup and register input device */
> @@ -903,6 +1312,13 @@ static int lg_g15_probe(struct hid_device *hdev, const struct hid_device_id *id)
> }
>
> static const struct hid_device_id lg_g15_devices[] = {
> + /*
> + * The G13 is a macropad-only device with an LCD, LED backlighing,
> + * and joystick.
> + */
> + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_G13),
> + .driver_data = LG_G13 },
> /* The G11 is a G15 without the LCD, treat it as a G15 */
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
> USB_DEVICE_ID_LOGITECH_G11),
^ permalink raw reply
* Re: [PATCH v5 3/6] dt-bindings: touchscreen: add touchscreen-glitch-threshold-ns property
From: Rob Herring @ 2025-09-19 20:44 UTC (permalink / raw)
To: Dario Binacchi
Cc: linux-kernel, Frank Li, linux-amarula, Conor Dooley, Conor Dooley,
Dmitry Torokhov, Javier Carrasco, Jeff LaBundy,
Krzysztof Kozlowski, devicetree, linux-input
In-Reply-To: <CABGWkvrxOTzAcqWHLvuqk_7WFxybheSZFnMkqnksfkPi6wXcpQ@mail.gmail.com>
On Fri, Sep 19, 2025 at 05:12:42PM +0200, Dario Binacchi wrote:
> On Fri, Sep 19, 2025 at 4:38 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Thu, Sep 18, 2025 at 10:37:37PM +0200, Dario Binacchi wrote:
> > > On Thu, Sep 18, 2025 at 10:04 PM Rob Herring <robh@kernel.org> wrote:
> > > >
> > > > On Thu, Sep 18, 2025 at 05:52:31PM +0200, Dario Binacchi wrote:
> > > > > Add support for glitch threshold configuration. A detected signal is valid
> > > > > only if it lasts longer than the set threshold; otherwise, it is regarded
> > > > > as a glitch.
> > > > >
> > > > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > > > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > > > >
> > > > > ---
> > > > >
> > > > > Changes in v5:
> > > > > - Add Acked-by tag of Conor Dooley
> > > > >
> > > > > Changes in v2:
> > > > > - Added in v2.
> > > > >
> > > > > .../devicetree/bindings/input/touchscreen/touchscreen.yaml | 4 ++++
> > > > > 1 file changed, 4 insertions(+)
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > index 3e3572aa483a..a60b4d08620d 100644
> > > > > --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > > @@ -206,6 +206,10 @@ properties:
> > > > >
> > > > > unevaluatedProperties: false
> > > > >
> > > > > + touchscreen-glitch-threshold-ns:
> > > > > + description: Minimum duration in nanoseconds a signal must remain stable
> > > > > + to be considered valid.
> > > >
> > > > What's wrong with debounce-delay-ms?
> > >
> > > Do you mean that I should rename touchscreen-glitch-threshold-ns to
> > > debounce-delay-ms?
> >
> > I mean that's the common property we already have, so use it or explain
> > why you aren't using it. I suppose the definition is technically a bit
> > different if it's purely a s/w delay vs. h/w monitoring of the signal
> > state. I don't think it matters if the interpretation by each driver is
> > a bit different.
> >
> > Maybe msec is not enough resolution for you could be another reason?
>
> Yes, this is the main reason. As specified in the following patch:
> v5 4/6 dt-bindings: touchscreen: fsl,imx6ul-tsc: support glitch threshold
>
> Drivers must convert this value to IPG clock cycles and map
> it to one of the four discrete thresholds exposed by the
> TSC_DEBUG_MODE2 register:
>
> 0: 8191 IPG cycles
> 1: 4095 IPG cycles
> 2: 2047 IPG cycles
> 3: 1023 IPG cycles
>
> In my case, the IPG clock runs at 66 MHz, which corresponds to:
>
> 124 µs for 0
> 62 µs for 1
> 31 us for 2
> 15 us for 3
>
> So using milliseconds would not fit my use case. A possible trade-off
> could be to use debounce-delay-us. Would that be acceptable?
I agree it wouldn't map to what the h/w provides, but is what the h/w
provides actually useful? There's plenty of h/w designed that's not
useful. 15us is quite short for a glitch. Do you have an actual cases
where the different values above are needed?
Rob
^ permalink raw reply
* Re: [PATCH] HID: amd_sfh: Add sync across amd sfh work functions
From: Jiri Kosina @ 2025-09-19 15:30 UTC (permalink / raw)
To: Basavaraj Natikar
Cc: bentiss, linux-input, Matthew Schwartz, Prakruthi SP,
Akshata MukundShetty
In-Reply-To: <20250918123202.1076393-1-Basavaraj.Natikar@amd.com>
On Thu, 18 Sep 2025, Basavaraj Natikar wrote:
> The process of the report is delegated across different work functions.
> Hence, add a sync mechanism to protect SFH work data across functions.
>
> Fixes: 4b2c53d93a4b ("SFH:Transport Driver to add support of AMD Sensor Fusion Hub (SFH)")
> Reported-by: Matthew Schwartz <matthew.schwartz@linux.dev>
> Closes: https://lore.kernel.org/all/a21abca5-4268-449d-95f1-bdd7a25894a5@linux.dev/
> Tested-by: Prakruthi SP <Prakruthi.SP@amd.com>
> Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
> Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@amd.com>
> Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 RESEND] hid: intel-thc-hid: intel-quicki2c: support ACPI config for advanced features
From: Jiri Kosina @ 2025-09-19 15:13 UTC (permalink / raw)
To: Xinpeng Sun
Cc: bentiss, srinivas.pandruvada, linux-input, linux-kernel, even.xu,
Rui Zhang
In-Reply-To: <20250917015344.1169412-1-xinpeng.sun@intel.com>
On Wed, 17 Sep 2025, Xinpeng Sun wrote:
> There is a new BIOS enhancement that adds the capability to configure the
> following two features of I2C subsystem introduced in commit 1ed0b48
> ("Intel-thc: Introduce max input size control") and commit 3f2a921
> ("Intel-thc: Introduce interrupt delay control"):
> - Max input size control
> - Interrupt delay control
>
> As BIOS is used for the configuration of these two features, change driver
> data usage to indicate hardware capability, and add corresponding ACPI
> configuration support in QuickI2C driver.
Applied to hid.git#for-6.18/intel-thc-hid, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v5 3/6] dt-bindings: touchscreen: add touchscreen-glitch-threshold-ns property
From: Dario Binacchi @ 2025-09-19 15:12 UTC (permalink / raw)
To: Rob Herring
Cc: linux-kernel, Frank Li, linux-amarula, Conor Dooley, Conor Dooley,
Dmitry Torokhov, Javier Carrasco, Jeff LaBundy,
Krzysztof Kozlowski, devicetree, linux-input
In-Reply-To: <20250919143831.GA862818-robh@kernel.org>
On Fri, Sep 19, 2025 at 4:38 PM Rob Herring <robh@kernel.org> wrote:
>
> On Thu, Sep 18, 2025 at 10:37:37PM +0200, Dario Binacchi wrote:
> > On Thu, Sep 18, 2025 at 10:04 PM Rob Herring <robh@kernel.org> wrote:
> > >
> > > On Thu, Sep 18, 2025 at 05:52:31PM +0200, Dario Binacchi wrote:
> > > > Add support for glitch threshold configuration. A detected signal is valid
> > > > only if it lasts longer than the set threshold; otherwise, it is regarded
> > > > as a glitch.
> > > >
> > > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > > >
> > > > ---
> > > >
> > > > Changes in v5:
> > > > - Add Acked-by tag of Conor Dooley
> > > >
> > > > Changes in v2:
> > > > - Added in v2.
> > > >
> > > > .../devicetree/bindings/input/touchscreen/touchscreen.yaml | 4 ++++
> > > > 1 file changed, 4 insertions(+)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > index 3e3572aa483a..a60b4d08620d 100644
> > > > --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > > @@ -206,6 +206,10 @@ properties:
> > > >
> > > > unevaluatedProperties: false
> > > >
> > > > + touchscreen-glitch-threshold-ns:
> > > > + description: Minimum duration in nanoseconds a signal must remain stable
> > > > + to be considered valid.
> > >
> > > What's wrong with debounce-delay-ms?
> >
> > Do you mean that I should rename touchscreen-glitch-threshold-ns to
> > debounce-delay-ms?
>
> I mean that's the common property we already have, so use it or explain
> why you aren't using it. I suppose the definition is technically a bit
> different if it's purely a s/w delay vs. h/w monitoring of the signal
> state. I don't think it matters if the interpretation by each driver is
> a bit different.
>
> Maybe msec is not enough resolution for you could be another reason?
Yes, this is the main reason. As specified in the following patch:
v5 4/6 dt-bindings: touchscreen: fsl,imx6ul-tsc: support glitch threshold
Drivers must convert this value to IPG clock cycles and map
it to one of the four discrete thresholds exposed by the
TSC_DEBUG_MODE2 register:
0: 8191 IPG cycles
1: 4095 IPG cycles
2: 2047 IPG cycles
3: 1023 IPG cycles
In my case, the IPG clock runs at 66 MHz, which corresponds to:
124 µs for 0
62 µs for 1
31 us for 2
15 us for 3
So using milliseconds would not fit my use case. A possible trade-off
could be to use debounce-delay-us. Would that be acceptable?
Thanks and regards
Dario
> Looks like your h/w supports that assuming the clock frequency is 10s
> of MHz. But are touchscreen glitches really in sub msec times? Not in my
> experience, but that's 20 years ago on resistive touchscreens...
>
> Rob
--
Dario Binacchi
Senior Embedded Linux Developer
dario.binacchi@amarulasolutions.com
__________________________________
Amarula Solutions SRL
Via Le Canevare 30, 31100 Treviso, Veneto, IT
T. +39 042 243 5310
info@amarulasolutions.com
www.amarulasolutions.com
^ permalink raw reply
* Re: The zero power level of the HID device in kernel 6.12 is not reported from the kernel to the upper layer.
From: Dmitry Torokhov @ 2025-09-19 15:04 UTC (permalink / raw)
To: José Expósito
Cc: 卢国宏, linux-input, linux-kernel, jikos,
bentiss, 李鹏, Fei1 Jiang 蒋飞,
宋密密
In-Reply-To: <aM0XBudxlXuzALbg@fedora>
Hi,
On Fri, Sep 19, 2025 at 10:40:38AM +0200, José Expósito wrote:
> Hi 卢国宏,
>
> Thanks for reporting this issue.
>
> In the furure, when reporting bugs, it is prefered to send them to the
> mailing list (linux-input@vger.kernel.org and linux-kernel@vger.kernel.org)
> to discuss them in public.
>
> Let me forward your email to the mailing list and also CC Dmitry, the
> author of that code, who might help us understand the problem.
>
> On Tue, Sep 16, 2025 at 12:29:32PM +0000, 卢国宏 wrote:
> > Hi, jose!
> >
> > We encountered a problem where the zero battery level of the HID device
> > in kernel 6.12 was not reported from the kernel to the upper layer.
> > I checked the HID protocol and it doesn't say that there is no need to
> > report the zero power of the HID device. For details, see page 381 of
> > the HID protocol, 31.4 Battery Measures. "Absolute State Of Charge DV
> > The predicted remaining battery capacity expressed as a percentage of
> > design capacity. (Units are %. The value may be greater than 100%.)".
> > However, in the file hid-input.c in kernel 6.12, the following code:
> >
> > static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
> > int value)
> > {
> > int capacity;
> >
> > if (!dev->battery)
> > return;
> >
> > if (hidinput_update_battery_charge_status(dev, usage, value)) {
> > power_supply_changed(dev->battery);
> > return;
> > }
> >
> > if (value == 0 || value < dev->battery_min || value > dev->battery_max)
> > return;
> >
> > capacity = hidinput_scale_battery_capacity(dev, value);
> >
> > ......
> >
> > }
> >
> > The parameter value is the power level. When the value is 0, the above code
> > returns without reporting.
> > Is this a problem?
> > We're currently experiencing this issue on Android 16. The upper layer of
> > Android needs to receive a zero battery level before it can take appropriate
> > action.
What kind of action are we talking about? Section 31 of the HID
specification defines events for "Smart Battery" ("To comply with the
Smart Battery Specification, the Battery System must support the
functions defined in the Battery and Charger usage tables. For details,
see Section 4.2, “Battery System Page (x85).”) and is typically used for
"battery pack for cellular phones (principal source), the battery
pack(s) for notebook computers (auxiliary source), and the sealed
batteries in uninterruptible power supplies (auxiliary source)."
Is your use case main battery or battery in a stylus or some other
peripheral?
> > Could you please help me evaluate whether we should remove the behavior of
> > returning to zero battery?
> >
> > Thanks!
> > #/******本邮件及其附件含有小米公司的保密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制、或散发)本邮件中的信息。如果您错收了本邮件,请您立即电话或邮件通知发件人并删除本邮件! This e-mail and its attachments contain confidential information from XIAOMI, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!******/#
>
> It indeed looks like it could be problematic.
>
> Values are allowed ot be grater than 100, however, I didn't find
> any references to negative values. Since it is a percentage, it
> make sense to limit it to 0%, i.e., not allowing negative values.
>
> I think that removing the "value == 0" check, or replacing it with
> "value < 0" should fix the issue.
If we are dealing with peripherals (stylus for example) - for which this
piece of code was written - how a battery powered peripheral that is
fully discharged can communicate it's battery state of 0?
I think we have observed bogus reports with 0 values (IIRC trying to
query battery strength when stylus is not in proximity would yield
responses with 0 strength).
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v5 3/6] dt-bindings: touchscreen: add touchscreen-glitch-threshold-ns property
From: Rob Herring @ 2025-09-19 14:38 UTC (permalink / raw)
To: Dario Binacchi
Cc: linux-kernel, Frank Li, linux-amarula, Conor Dooley, Conor Dooley,
Dmitry Torokhov, Javier Carrasco, Jeff LaBundy,
Krzysztof Kozlowski, devicetree, linux-input
In-Reply-To: <CABGWkvqX9aCxam6UMYsUBkwnMJrMNKjVKrqi5Ca7O5Jk8xRTAA@mail.gmail.com>
On Thu, Sep 18, 2025 at 10:37:37PM +0200, Dario Binacchi wrote:
> On Thu, Sep 18, 2025 at 10:04 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Thu, Sep 18, 2025 at 05:52:31PM +0200, Dario Binacchi wrote:
> > > Add support for glitch threshold configuration. A detected signal is valid
> > > only if it lasts longer than the set threshold; otherwise, it is regarded
> > > as a glitch.
> > >
> > > Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
> > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > >
> > > ---
> > >
> > > Changes in v5:
> > > - Add Acked-by tag of Conor Dooley
> > >
> > > Changes in v2:
> > > - Added in v2.
> > >
> > > .../devicetree/bindings/input/touchscreen/touchscreen.yaml | 4 ++++
> > > 1 file changed, 4 insertions(+)
> > >
> > > diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > index 3e3572aa483a..a60b4d08620d 100644
> > > --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
> > > @@ -206,6 +206,10 @@ properties:
> > >
> > > unevaluatedProperties: false
> > >
> > > + touchscreen-glitch-threshold-ns:
> > > + description: Minimum duration in nanoseconds a signal must remain stable
> > > + to be considered valid.
> >
> > What's wrong with debounce-delay-ms?
>
> Do you mean that I should rename touchscreen-glitch-threshold-ns to
> debounce-delay-ms?
I mean that's the common property we already have, so use it or explain
why you aren't using it. I suppose the definition is technically a bit
different if it's purely a s/w delay vs. h/w monitoring of the signal
state. I don't think it matters if the interpretation by each driver is
a bit different.
Maybe msec is not enough resolution for you could be another reason?
Looks like your h/w supports that assuming the clock frequency is 10s
of MHz. But are touchscreen glitches really in sub msec times? Not in my
experience, but that's 20 years ago on resistive touchscreens...
Rob
^ permalink raw reply
* Re: [PATCH v3 RESEND] hid: intel-thc-hid: intel-quicki2c: support ACPI config for advanced features
From: Pandruvada, Srinivas @ 2025-09-19 14:20 UTC (permalink / raw)
To: Sun, Xinpeng, jikos@kernel.org, Xu, Even, bentiss@kernel.org
Cc: linux-input@vger.kernel.org, Zhang, Rui1,
linux-kernel@vger.kernel.org
In-Reply-To: <IA1PR11MB6098555DA1279BFFCC9CDD89F411A@IA1PR11MB6098.namprd11.prod.outlook.com>
On Fri, 2025-09-19 at 07:56 +0000, Xu, Even wrote:
>
>
> > -----Original Message-----
> > From: Sun, Xinpeng <xinpeng.sun@intel.com>
> > Sent: Wednesday, September 17, 2025 9:54 AM
> > To: jikos@kernel.org; bentiss@kernel.org
> > Cc: srinivas.pandruvada@linux.intel.com;
> > linux-input@vger.kernel.org; linux-
> > kernel@vger.kernel.org; Xu, Even <even.xu@intel.com>; Sun, Xinpeng
> > <xinpeng.sun@intel.com>; Zhang, Rui1 <rui1.zhang@intel.com>
> > Subject: [PATCH v3 RESEND] hid: intel-thc-hid: intel-quicki2c:
> > support ACPI config
> > for advanced features
> >
> > There is a new BIOS enhancement that adds the capability to
> > configure the
> > following two features of I2C subsystem introduced in commit
> > 1ed0b48
> > ("Intel-thc: Introduce max input size control") and commit 3f2a921
> > ("Intel-thc: Introduce interrupt delay control"):
> > - Max input size control
> > - Interrupt delay control
> >
> > As BIOS is used for the configuration of these two features, change
> > driver data
> > usage to indicate hardware capability, and add corresponding ACPI
> > configuration
> > support in QuickI2C driver.
> >
> > Signed-off-by: Xinpeng Sun <xinpeng.sun@intel.com>
> > Tested-by: Rui Zhang <rui1.zhang@intel.com>
Add your reviewed-by here..
> >
> > ---
> > Changes in v3:
> > - remove unnecessary initialization of local variables Changes in
> > v2:
> > - refine the commit message
> > ---
> > .../intel-quicki2c/pci-quicki2c.c | 39
> > +++++++++++++++----
> > .../intel-quicki2c/quicki2c-dev.h | 24 +++++++++++-
> > 2 files changed, 53 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-
> > quicki2c.c
> > b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> > index 854926b3cfd4..3ce5a692b92b 100644
> > --- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> > +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
> > @@ -23,6 +23,7 @@
> >
> > static struct quicki2c_ddata ptl_ddata = {
> > .max_detect_size = MAX_RX_DETECT_SIZE_PTL,
> > + .max_interrupt_delay = MAX_RX_INTERRUPT_DELAY,
> > };
> >
> > /* THC QuickI2C ACPI method to get device properties */ @@ -200,6
> > +201,21
> > @@ static int quicki2c_get_acpi_resources(struct quicki2c_device
> > *qcdev)
> > return -EOPNOTSUPP;
> > }
> >
> > + if (qcdev->ddata) {
> > + qcdev->i2c_max_frame_size_enable =
> > i2c_config.FSEN;
> > + qcdev->i2c_int_delay_enable = i2c_config.INDE;
> > +
> > + if (i2c_config.FSVL <= qcdev->ddata-
> > >max_detect_size)
> > + qcdev->i2c_max_frame_size =
> > i2c_config.FSVL;
> > + else
> > + qcdev->i2c_max_frame_size = qcdev->ddata-
> > > max_detect_size;
> > +
> > + if (i2c_config.INDV <= qcdev->ddata-
> > >max_interrupt_delay)
> > + qcdev->i2c_int_delay = i2c_config.INDV;
> > + else
> > + qcdev->i2c_int_delay = qcdev->ddata-
> > > max_interrupt_delay;
> > + }
> > +
> > return 0;
> > }
> >
> > @@ -441,17 +457,24 @@ static void quicki2c_dma_adv_enable(struct
> > quicki2c_device *qcdev)
> > * max input length <= THC detect capability, enable the
> > feature with
> > device
> > * max input length.
> > */
> > - if (qcdev->ddata->max_detect_size >=
> > - le16_to_cpu(qcdev->dev_desc.max_input_len)) {
> > - thc_i2c_set_rx_max_size(qcdev->thc_hw,
> > - le16_to_cpu(qcdev-
> > > dev_desc.max_input_len));
> > + if (qcdev->i2c_max_frame_size_enable) {
> > + if (qcdev->i2c_max_frame_size >=
> > + le16_to_cpu(qcdev->dev_desc.max_input_len)) {
> > + thc_i2c_set_rx_max_size(qcdev->thc_hw,
> > + le16_to_cpu(qcdev-
> > > dev_desc.max_input_len));
> > + } else {
> > + dev_warn(qcdev->dev,
> > + "Max frame size is smaller than
> > hid max input
> > length!");
> > + thc_i2c_set_rx_max_size(qcdev->thc_hw,
> > + le16_to_cpu(qcdev-
> > > i2c_max_frame_size));
> > + }
> > thc_i2c_rx_max_size_enable(qcdev->thc_hw, true);
> > }
> >
> > /* If platform supports interrupt delay feature, enable it
> > with given delay
> > */
> > - if (qcdev->ddata->interrupt_delay) {
> > + if (qcdev->i2c_int_delay_enable) {
> > thc_i2c_set_rx_int_delay(qcdev->thc_hw,
> > - qcdev->ddata-
> > >interrupt_delay);
> > + qcdev->i2c_int_delay *
> > 10);
> > thc_i2c_rx_int_delay_enable(qcdev->thc_hw, true);
> > }
> > }
> > @@ -464,10 +487,10 @@ static void quicki2c_dma_adv_enable(struct
> > quicki2c_device *qcdev)
> > */
> > static void quicki2c_dma_adv_disable(struct quicki2c_device
> > *qcdev) {
> > - if (qcdev->ddata->max_detect_size)
> > + if (qcdev->i2c_max_frame_size_enable)
> > thc_i2c_rx_max_size_enable(qcdev->thc_hw, false);
> >
> > - if (qcdev->ddata->interrupt_delay)
> > + if (qcdev->i2c_int_delay_enable)
> > thc_i2c_rx_int_delay_enable(qcdev->thc_hw,
> > false); }
> >
> > diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-
> > dev.h
> > b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
> > index d412eafcf9ea..0d423d5dd7a7 100644
> > --- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
> > +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
> > @@ -38,6 +38,8 @@
> >
> > /* PTL Max packet size detection capability is 255 Bytes */
> > #define MAX_RX_DETECT_SIZE_PTL 255
> > +/* Max interrupt delay capability is 2.56ms */
> > +#define MAX_RX_INTERRUPT_DELAY 256
> >
> > /* Default interrupt delay is 1ms, suitable for most devices */
> > #define DEFAULT_INTERRUPT_DELAY_US (1 *
> > USEC_PER_MSEC)
> > @@ -101,6 +103,10 @@ struct quicki2c_subip_acpi_parameter {
> > * @HMTD: High Speed Mode Plus (3.4Mbits/sec) Serial Data Line
> > Transmit
> > HOLD Period
> > * @HMRD: High Speed Mode Plus (3.4Mbits/sec) Serial Data Line
> > Receive HOLD
> > Period
> > * @HMSL: Maximum length (in ic_clk_cycles) of suppressed spikes
> > in High Speed
> > Mode
> > + * @FSEN: Maximum Frame Size Feature Enable Control
> > + * @FSVL: Maximum Frame Size Value (unit in Bytes)
> > + * @INDE: Interrupt Delay Feature Enable Control
> > + * @INDV: Interrupt Delay Value (unit in 10 us)
> > *
> > * Those properties get from QUICKI2C_ACPI_METHOD_NAME_ISUB
> > method,
> > used for
> > * I2C timing configure.
> > @@ -127,17 +133,22 @@ struct quicki2c_subip_acpi_config {
> > u64 HMTD;
> > u64 HMRD;
> > u64 HMSL;
> > +
> > + u64 FSEN;
> > + u64 FSVL;
> > + u64 INDE;
> > + u64 INDV;
> > u8 reserved;
> > };
> >
> > /**
> > * struct quicki2c_ddata - Driver specific data for quicki2c
> > device
> > * @max_detect_size: Identify max packet size detect for rx
> > - * @interrupt_delay: Identify interrupt detect delay for rx
> > + * @interrupt_delay: Identify max interrupt detect delay for rx
> > */
> > struct quicki2c_ddata {
> > u32 max_detect_size;
> > - u32 interrupt_delay;
> > + u32 max_interrupt_delay;
> > };
> >
> > struct device;
> > @@ -170,6 +181,10 @@ struct acpi_device;
> > * @report_len: The length of input/output report packet
> > * @reset_ack_wq: Workqueue for waiting reset response from device
> > * @reset_ack: Indicate reset response received or not
> > + * @i2c_max_frame_size_enable: Indicate max frame size feature
> > enabled
> > + or not
> > + * @i2c_max_frame_size: Max RX frame size (unit in Bytes)
> > + * @i2c_int_delay_enable: Indicate interrupt delay feature enabled
> > or
> > + not
> > + * @i2c_int_delay: Interrupt detection delay value (unit in 10 us)
> > */
> > struct quicki2c_device {
> > struct device *dev;
> > @@ -200,6 +215,11 @@ struct quicki2c_device {
> >
> > wait_queue_head_t reset_ack_wq;
> > bool reset_ack;
> > +
> > + u32 i2c_max_frame_size_enable;
> > + u32 i2c_max_frame_size;
> > + u32 i2c_int_delay_enable;
> > + u32 i2c_int_delay;
> > };
> >
>
> Thanks for the patch!
>
> Reviewed-by: Even Xu <even.xu@intel.com>
>
> > #endif /* _QUICKI2C_DEV_H_ */
> > --
> > 2.40.1
>
^ permalink raw reply
* Re: [PATCH 00/27 5.10.y] Backport minmax.h updates from v6.17-rc6
From: Christian König @ 2025-09-19 12:11 UTC (permalink / raw)
To: Eliav Farber, linux, jdike, richard, anton.ivanov, dave.hansen,
luto, peterz, tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo,
mchehab, james.morse, rric, harry.wentland, sunpeng.li,
alexander.deucher, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, sashal, ruanjinjie, David.Laight,
herve.codina, Jason, bvanassche, keescook, linux-arm-kernel,
linux-kernel, linux-um, linux-edac, amd-gfx, dri-devel,
linux-arm-msm, freedreno, linux-hwmon, linux-input, linux-media,
netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
On 19.09.25 12:17, Eliav Farber wrote:
> This series includes a total of 27 patches, to align minmax.h of
> v5.15.y with v6.17-rc6.
>
> The set consists of 24 commits that directly update minmax.h:
> 1) 92d23c6e9415 ("overflow, tracing: Define the is_signed_type() macro
> once")
> 2) 5efcecd9a3b1 ("minmax: sanity check constant bounds when clamping")
> 3) 2122e2a4efc2 ("minmax: clamp more efficiently by avoiding extra
> comparison")
> 4) f9bff0e31881 ("minmax: add in_range() macro")
> 5) c952c748c7a9 ("minmax: Introduce {min,max}_array()")
> 6) 5e57418a2031 ("minmax: deduplicate __unconst_integer_typeof()")
> 7) f6e9d38f8eb0 ("minmax: fix header inclusions")
> 8) d03eba99f5bf ("minmax: allow min()/max()/clamp() if the arguments
> have the same signedness.")
> 9) f4b84b2ff851 ("minmax: fix indentation of __cmp_once() and
> __clamp_once()")
> 10) 4ead534fba42 ("minmax: allow comparisons of 'int' against 'unsigned
> char/short'")
> 11) 867046cc7027 ("minmax: relax check to allow comparison between
> unsigned arguments and signed constants")
> 12) 3a7e02c040b1 ("minmax: avoid overly complicated constant
> expressions in VM code")
> 14) 017fa3e89187 ("minmax: simplify and clarify min_t()/max_t()
> implementation")
> 15) 1a251f52cfdc ("minmax: make generic MIN() and MAX() macros
> available everywhere")
> 18) dc1c8034e31b ("minmax: simplify min()/max()/clamp()
> implementation")
> 19) 22f546873149 ("minmax: improve macro expansion and type
> checking")
> 20) 21b136cc63d2 ("minmax: fix up min3() and max3() too")
> 21) 71ee9b16251e ("minmax.h: add whitespace around operators and after
> commas")
> 22) 10666e992048 ("minmax.h: update some comments")
> 23) b280bb27a9f7 ("minmax.h: reduce the #define expansion of min(),
> max() and clamp()")
> 24) a5743f32baec ("minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi
> test in clamp()")
> 25) c3939872ee4a ("minmax.h: move all the clamp() definitions after the
> min/max() ones")
> 26) 495bba17cdf9 ("minmax.h: simplify the variants of clamp()")
> 27) 2b97aaf74ed5 ("minmax.h: remove some #defines that are only
> expanded once")
>
> 2 prerequisite commits that adjust users of MIN and MAX macros (to
> prevent compilation issues):
> 13) 4477b39c32fd ("minmax: add a few more MIN_T/MAX_T users")
> 17) cb04e8b1d2f2 ("minmax: don't use max() in situations that want a C
> constant expression")
>
> 1 additional commit introduced to resolve a build failures during the
> backport:
> 16) lib: zstd: drop local MIN/MAX macros in favor of generic ones
>
> The primary motivation is to bring in commit (8).
> In mainline, this change allows min()/max()/clamp() to accept mixed
> argument types when both share the same signedness.
> Backported patches to v5.10.y that use such forms trigger compiler
> warnings, which in turn cause build failures when -Werror is enabled.
>
> Originaly I aligned 5.10.y to 5.15.y, but David Laight commented that I
> need to pick up the later changes (from Linus) as well.
>
> Andy Shevchenko (2):
> minmax: deduplicate __unconst_integer_typeof()
> minmax: fix header inclusions
>
> Bart Van Assche (1):
> overflow, tracing: Define the is_signed_type() macro once
>
> David Laight (11):
> minmax: allow min()/max()/clamp() if the arguments have the same
> signedness.
> minmax: fix indentation of __cmp_once() and __clamp_once()
> minmax: allow comparisons of 'int' against 'unsigned char/short'
> minmax: relax check to allow comparison between unsigned arguments and
> signed constants
> minmax.h: add whitespace around operators and after commas
> minmax.h: update some comments
> minmax.h: reduce the #define expansion of min(), max() and clamp()
> minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
> minmax.h: move all the clamp() definitions after the min/max() ones
> minmax.h: simplify the variants of clamp()
> minmax.h: remove some #defines that are only expanded once
>
> Eliav Farber (1):
> lib: zstd: drop local MIN/MAX macros in favor of generic ones
>
> Herve Codina (1):
> minmax: Introduce {min,max}_array()
>
> Jason A. Donenfeld (2):
> minmax: sanity check constant bounds when clamping
> minmax: clamp more efficiently by avoiding extra comparison
>
> Linus Torvalds (8):
> minmax: avoid overly complicated constant expressions in VM code
> minmax: add a few more MIN_T/MAX_T users
> minmax: simplify and clarify min_t()/max_t() implementation
> minmax: make generic MIN() and MAX() macros available everywhere
> minmax: don't use max() in situations that want a C constant
> expression
> minmax: simplify min()/max()/clamp() implementation
> minmax: improve macro expansion and type checking
> minmax: fix up min3() and max3() too
>
> Matthew Wilcox (Oracle) (1):
> minmax: add in_range() macro
>
> arch/arm/mm/pageattr.c | 6 +-
> arch/um/drivers/mconsole_user.c | 2 +
> arch/x86/mm/pgtable.c | 2 +-
> drivers/edac/sb_edac.c | 4 +-
> drivers/edac/skx_common.h | 1 -
> .../drm/amd/display/modules/hdcp/hdcp_ddc.c | 2 +
> .../drm/amd/pm/powerplay/hwmgr/ppevvmath.h | 14 +-
> .../drm/arm/display/include/malidp_utils.h | 2 +-
> .../display/komeda/komeda_pipeline_state.c | 24 +-
> drivers/gpu/drm/drm_color_mgmt.c | 2 +-
> drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 -
> drivers/gpu/drm/radeon/evergreen_cs.c | 2 +
> drivers/hwmon/adt7475.c | 24 +-
> drivers/input/touchscreen/cyttsp4_core.c | 2 +-
> drivers/md/dm-integrity.c | 2 +-
> drivers/media/dvb-frontends/stv0367_priv.h | 3 +
> .../net/ethernet/chelsio/cxgb3/cxgb3_main.c | 18 +-
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> drivers/net/fjes/fjes_main.c | 4 +-
> drivers/nfc/pn544/i2c.c | 2 -
> drivers/platform/x86/sony-laptop.c | 1 -
> drivers/scsi/isci/init.c | 6 +-
I do see the value to backport the infrastructure, but why are driver specific changes backported as well?
I mean the changes are most likely correct but also not valuable in anyway as bug fix.
Regards,
Christian.
> .../pci/hive_isp_css_include/math_support.h | 5 -
> fs/btrfs/misc.h | 2 -
> fs/btrfs/tree-checker.c | 2 +-
> fs/ext2/balloc.c | 2 -
> fs/ext4/ext4.h | 2 -
> fs/ufs/util.h | 6 -
> include/linux/compiler.h | 15 +
> include/linux/minmax.h | 267 ++++++++++++++----
> include/linux/overflow.h | 1 -
> include/linux/trace_events.h | 2 -
> kernel/trace/preemptirq_delay_test.c | 2 -
> lib/btree.c | 1 -
> lib/decompress_unlzma.c | 2 +
> lib/logic_pio.c | 3 -
> lib/vsprintf.c | 2 +-
> lib/zstd/zstd_internal.h | 2 -
> mm/zsmalloc.c | 1 -
> net/ipv4/proc.c | 2 +-
> net/ipv6/proc.c | 2 +-
> net/netfilter/nf_nat_core.c | 6 +-
> net/tipc/core.h | 2 +-
> net/tipc/link.c | 10 +-
> 44 files changed, 306 insertions(+), 164 deletions(-)
>
^ permalink raw reply
* [PATCH 27/27 5.10.y] minmax.h: remove some #defines that are only expanded once
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit 2b97aaf74ed534fb838d09867d09a3ca5d795208 ]
The bodies of __signed_type_use() and __unsigned_type_use() are much the
same size as their names - so put the bodies in the only line that expands
them.
Similarly __signed_type() is defined separately for 64bit and then used
exactly once just below.
Change the test for __signed_type from CONFIG_64BIT to one based on gcc
defined macros so that the code is valid if it gets used outside of a
kernel build.
Link: https://lkml.kernel.org/r/9386d1ebb8974fbabbed2635160c3975@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 2bbdd5b5e07e..eaaf5c008e4d 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -46,10 +46,8 @@
* comparison, and these expressions only need to be careful to not cause
* warnings for pointer use.
*/
-#define __signed_type_use(ux) (2 + __is_nonneg(ux))
-#define __unsigned_type_use(ux) (1 + 2 * (sizeof(ux) < 4))
#define __sign_use(ux) (is_signed_type(typeof(ux)) ? \
- __signed_type_use(ux) : __unsigned_type_use(ux))
+ (2 + __is_nonneg(ux)) : (1 + 2 * (sizeof(ux) < 4)))
/*
* Check whether a signed value is always non-negative.
@@ -57,7 +55,7 @@
* A cast is needed to avoid any warnings from values that aren't signed
* integer types (in which case the result doesn't matter).
*
- * On 64-bit any integer or pointer type can safely be cast to 'long'.
+ * On 64-bit any integer or pointer type can safely be cast to 'long long'.
* But on 32-bit we need to avoid warnings about casting pointers to integers
* of different sizes without truncating 64-bit values so 'long' or 'long long'
* must be used depending on the size of the value.
@@ -66,12 +64,12 @@
* them, but we do not use s128 types in the kernel (we do use 'u128',
* but they are handled by the !is_signed_type() case).
*/
-#ifdef CONFIG_64BIT
- #define __signed_type(ux) long
+#if __SIZEOF_POINTER__ == __SIZEOF_LONG_LONG__
+#define __is_nonneg(ux) statically_true((long long)(ux) >= 0)
#else
- #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L))
+#define __is_nonneg(ux) statically_true( \
+ (typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)))(ux) >= 0)
#endif
-#define __is_nonneg(ux) statically_true((__signed_type(ux))(ux) >= 0)
#define __types_ok(ux, uy) \
(__sign_use(ux) & __sign_use(uy))
--
2.47.3
^ permalink raw reply related
* [PATCH 26/27 5.10.y] minmax.h: simplify the variants of clamp()
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit 495bba17cdf95e9703af1b8ef773c55ef0dfe703 ]
Always pass a 'type' through to __clamp_once(), pass '__auto_type' from
clamp() itself.
The expansion of __types_ok3() is reasonable so it isn't worth the added
complexity of avoiding it when a fixed type is used for all three values.
Link: https://lkml.kernel.org/r/8f69f4deac014f558bab186444bac2e8@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 75fb7a6ad4c6..2bbdd5b5e07e 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -183,29 +183,29 @@
#define __clamp(val, lo, hi) \
((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
-#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \
- __auto_type uval = (val); \
- __auto_type ulo = (lo); \
- __auto_type uhi = (hi); \
+#define __clamp_once(type, val, lo, hi, uval, ulo, uhi) ({ \
+ type uval = (val); \
+ type ulo = (lo); \
+ type uhi = (hi); \
BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \
"clamp() low limit " #lo " greater than high limit " #hi); \
BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
"clamp("#val", "#lo", "#hi") signedness error"); \
__clamp(uval, ulo, uhi); })
-#define __careful_clamp(val, lo, hi) \
- __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
+#define __careful_clamp(type, val, lo, hi) \
+ __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
/**
- * clamp - return a value clamped to a given range with strict typechecking
+ * clamp - return a value clamped to a given range with typechecking
* @val: current value
* @lo: lowest allowable value
* @hi: highest allowable value
*
- * This macro does strict typechecking of @lo/@hi to make sure they are of the
- * same type as @val. See the unnecessary pointer comparisons.
+ * This macro checks @val/@lo/@hi to make sure they have compatible
+ * signedness.
*/
-#define clamp(val, lo, hi) __careful_clamp(val, lo, hi)
+#define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi)
/**
* clamp_t - return a value clamped to a given range using a given type
@@ -217,7 +217,7 @@
* This macro does no typechecking and uses temporary variables of type
* @type to make all the comparisons.
*/
-#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi))
+#define clamp_t(type, val, lo, hi) __careful_clamp(type, val, lo, hi)
/**
* clamp_val - return a value clamped to a given range using val's type
@@ -230,7 +230,7 @@
* type and @lo and @hi are literals that will otherwise be assigned a signed
* integer type.
*/
-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
+#define clamp_val(val, lo, hi) __careful_clamp(typeof(val), val, lo, hi)
/*
* Do not check the array parameter using __must_be_array().
--
2.47.3
^ permalink raw reply related
* [PATCH 25/27 5.10.y] minmax.h: move all the clamp() definitions after the min/max() ones
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit c3939872ee4a6b8bdcd0e813c66823b31e6e26f7 ]
At some point the definitions for clamp() got added in the middle of the
ones for min() and max(). Re-order the definitions so they are more
sensibly grouped.
Link: https://lkml.kernel.org/r/8bb285818e4846469121c8abc3dfb6e2@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 109 +++++++++++++++++++----------------------
1 file changed, 51 insertions(+), 58 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 91aa1b90c1bb..75fb7a6ad4c6 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -99,22 +99,6 @@
#define __careful_cmp(op, x, y) \
__careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
-#define __clamp(val, lo, hi) \
- ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
-
-#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \
- __auto_type uval = (val); \
- __auto_type ulo = (lo); \
- __auto_type uhi = (hi); \
- BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \
- "clamp() low limit " #lo " greater than high limit " #hi); \
- BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
- "clamp("#val", "#lo", "#hi") signedness error"); \
- __clamp(uval, ulo, uhi); })
-
-#define __careful_clamp(val, lo, hi) \
- __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
-
/**
* min - return minimum of two values of the same or compatible types
* @x: first value
@@ -170,6 +154,22 @@
#define max3(x, y, z) \
__careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_))
+/**
+ * min_t - return minimum of two values, using the specified type
+ * @type: data type to use
+ * @x: first value
+ * @y: second value
+ */
+#define min_t(type, x, y) __cmp_once(min, type, x, y)
+
+/**
+ * max_t - return maximum of two values, using the specified type
+ * @type: data type to use
+ * @x: first value
+ * @y: second value
+ */
+#define max_t(type, x, y) __cmp_once(max, type, x, y)
+
/**
* min_not_zero - return the minimum that is _not_ zero, unless both are zero
* @x: value1
@@ -180,6 +180,22 @@
typeof(y) __y = (y); \
__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
+#define __clamp(val, lo, hi) \
+ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
+
+#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \
+ __auto_type uval = (val); \
+ __auto_type ulo = (lo); \
+ __auto_type uhi = (hi); \
+ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \
+ "clamp() low limit " #lo " greater than high limit " #hi); \
+ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
+ "clamp("#val", "#lo", "#hi") signedness error"); \
+ __clamp(uval, ulo, uhi); })
+
+#define __careful_clamp(val, lo, hi) \
+ __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_))
+
/**
* clamp - return a value clamped to a given range with strict typechecking
* @val: current value
@@ -191,28 +207,30 @@
*/
#define clamp(val, lo, hi) __careful_clamp(val, lo, hi)
-/*
- * ..and if you can't take the strict
- * types, you can specify one yourself.
- *
- * Or not use min/max/clamp at all, of course.
- */
-
/**
- * min_t - return minimum of two values, using the specified type
- * @type: data type to use
- * @x: first value
- * @y: second value
+ * clamp_t - return a value clamped to a given range using a given type
+ * @type: the type of variable to use
+ * @val: current value
+ * @lo: minimum allowable value
+ * @hi: maximum allowable value
+ *
+ * This macro does no typechecking and uses temporary variables of type
+ * @type to make all the comparisons.
*/
-#define min_t(type, x, y) __cmp_once(min, type, x, y)
+#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi))
/**
- * max_t - return maximum of two values, using the specified type
- * @type: data type to use
- * @x: first value
- * @y: second value
+ * clamp_val - return a value clamped to a given range using val's type
+ * @val: current value
+ * @lo: minimum allowable value
+ * @hi: maximum allowable value
+ *
+ * This macro does no typechecking and uses temporary variables of whatever
+ * type the input argument @val is. This is useful when @val is an unsigned
+ * type and @lo and @hi are literals that will otherwise be assigned a signed
+ * integer type.
*/
-#define max_t(type, x, y) __cmp_once(max, type, x, y)
+#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
/*
* Do not check the array parameter using __must_be_array().
@@ -257,31 +275,6 @@
*/
#define max_array(array, len) __minmax_array(max, array, len)
-/**
- * clamp_t - return a value clamped to a given range using a given type
- * @type: the type of variable to use
- * @val: current value
- * @lo: minimum allowable value
- * @hi: maximum allowable value
- *
- * This macro does no typechecking and uses temporary variables of type
- * @type to make all the comparisons.
- */
-#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi))
-
-/**
- * clamp_val - return a value clamped to a given range using val's type
- * @val: current value
- * @lo: minimum allowable value
- * @hi: maximum allowable value
- *
- * This macro does no typechecking and uses temporary variables of whatever
- * type the input argument @val is. This is useful when @val is an unsigned
- * type and @lo and @hi are literals that will otherwise be assigned a signed
- * integer type.
- */
-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
-
static inline bool in_range64(u64 val, u64 start, u64 len)
{
return (val - start) < len;
--
2.47.3
^ permalink raw reply related
* [PATCH 24/27 5.10.y] minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp()
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit a5743f32baec4728711bbc01d6ac2b33d4c67040 ]
Use BUILD_BUG_ON_MSG(statically_true(ulo > uhi), ...) for the sanity check
of the bounds in clamp(). Gives better error coverage and one less
expansion of the arguments.
Link: https://lkml.kernel.org/r/34d53778977747f19cce2abb287bb3e6@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 6f7ea669d305..91aa1b90c1bb 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -106,8 +106,7 @@
__auto_type uval = (val); \
__auto_type ulo = (lo); \
__auto_type uhi = (hi); \
- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
- (lo) <= (hi), true), \
+ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \
"clamp() low limit " #lo " greater than high limit " #hi); \
BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
"clamp("#val", "#lo", "#hi") signedness error"); \
--
2.47.3
^ permalink raw reply related
* [PATCH 23/27 5.10.y] minmax.h: reduce the #define expansion of min(), max() and clamp()
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit b280bb27a9f7c91ddab730e1ad91a9c18a051f41 ]
Since the test for signed values being non-negative only relies on
__builtion_constant_p() (not is_constexpr()) it can use the 'ux' variable
instead of the caller supplied expression. This means that the #define
parameters are only expanded twice. Once in the code and once quoted in
the error message.
Link: https://lkml.kernel.org/r/051afc171806425da991908ed8688a98@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 24e4b372649a..6f7ea669d305 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -46,10 +46,10 @@
* comparison, and these expressions only need to be careful to not cause
* warnings for pointer use.
*/
-#define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux))
-#define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4))
-#define __sign_use(x, ux) (is_signed_type(typeof(ux)) ? \
- __signed_type_use(x, ux) : __unsigned_type_use(x, ux))
+#define __signed_type_use(ux) (2 + __is_nonneg(ux))
+#define __unsigned_type_use(ux) (1 + 2 * (sizeof(ux) < 4))
+#define __sign_use(ux) (is_signed_type(typeof(ux)) ? \
+ __signed_type_use(ux) : __unsigned_type_use(ux))
/*
* Check whether a signed value is always non-negative.
@@ -71,13 +71,13 @@
#else
#define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L))
#endif
-#define __is_nonneg(x, ux) statically_true((__signed_type(ux))(x) >= 0)
+#define __is_nonneg(ux) statically_true((__signed_type(ux))(ux) >= 0)
-#define __types_ok(x, y, ux, uy) \
- (__sign_use(x, ux) & __sign_use(y, uy))
+#define __types_ok(ux, uy) \
+ (__sign_use(ux) & __sign_use(uy))
-#define __types_ok3(x, y, z, ux, uy, uz) \
- (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz))
+#define __types_ok3(ux, uy, uz) \
+ (__sign_use(ux) & __sign_use(uy) & __sign_use(uz))
#define __cmp_op_min <
#define __cmp_op_max >
@@ -92,7 +92,7 @@
#define __careful_cmp_once(op, x, y, ux, uy) ({ \
__auto_type ux = (x); __auto_type uy = (y); \
- BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \
+ BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \
#op"("#x", "#y") signedness error"); \
__cmp(op, ux, uy); })
@@ -109,7 +109,7 @@
static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
(lo) <= (hi), true), \
"clamp() low limit " #lo " greater than high limit " #hi); \
- BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \
+ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \
"clamp("#val", "#lo", "#hi") signedness error"); \
__clamp(uval, ulo, uhi); })
@@ -149,7 +149,7 @@
#define __careful_op3(op, x, y, z, ux, uy, uz) ({ \
__auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\
- BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \
+ BUILD_BUG_ON_MSG(!__types_ok3(ux, uy, uz), \
#op"3("#x", "#y", "#z") signedness error"); \
__cmp(op, ux, __cmp(op, uy, uz)); })
--
2.47.3
^ permalink raw reply related
* [PATCH 22/27 5.10.y] minmax.h: update some comments
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit 10666e99204818ef45c702469488353b5bb09ec7 ]
- Change three to several.
- Remove the comment about retaining constant expressions, no longer true.
- Realign to nearer 80 columns and break on major punctiation.
- Add a leading comment to the block before __signed_type() and __is_nonneg()
Otherwise the block explaining the cast is a bit 'floating'.
Reword the rest of that comment to improve readability.
Link: https://lkml.kernel.org/r/85b050c81c1d4076aeb91a6cded45fee@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 53 +++++++++++++++++++-----------------------
1 file changed, 24 insertions(+), 29 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 51b0d988e322..24e4b372649a 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -8,13 +8,10 @@
#include <linux/types.h>
/*
- * min()/max()/clamp() macros must accomplish three things:
+ * min()/max()/clamp() macros must accomplish several things:
*
* - Avoid multiple evaluations of the arguments (so side-effects like
* "x++" happen only once) when non-constant.
- * - Retain result as a constant expressions when called with only
- * constant expressions (to avoid tripping VLA warnings in stack
- * allocation usage).
* - Perform signed v unsigned type-checking (to generate compile
* errors instead of nasty runtime surprises).
* - Unsigned char/short are always promoted to signed int and can be
@@ -31,25 +28,23 @@
* bit #0 set if ok for unsigned comparisons
* bit #1 set if ok for signed comparisons
*
- * In particular, statically non-negative signed integer
- * expressions are ok for both.
+ * In particular, statically non-negative signed integer expressions
+ * are ok for both.
*
- * NOTE! Unsigned types smaller than 'int' are implicitly
- * converted to 'int' in expressions, and are accepted for
- * signed conversions for now. This is debatable.
+ * NOTE! Unsigned types smaller than 'int' are implicitly converted to 'int'
+ * in expressions, and are accepted for signed conversions for now.
+ * This is debatable.
*
- * Note that 'x' is the original expression, and 'ux' is
- * the unique variable that contains the value.
+ * Note that 'x' is the original expression, and 'ux' is the unique variable
+ * that contains the value.
*
- * We use 'ux' for pure type checking, and 'x' for when
- * we need to look at the value (but without evaluating
- * it for side effects! Careful to only ever evaluate it
- * with sizeof() or __builtin_constant_p() etc).
+ * We use 'ux' for pure type checking, and 'x' for when we need to look at the
+ * value (but without evaluating it for side effects!
+ * Careful to only ever evaluate it with sizeof() or __builtin_constant_p() etc).
*
- * Pointers end up being checked by the normal C type
- * rules at the actual comparison, and these expressions
- * only need to be careful to not cause warnings for
- * pointer use.
+ * Pointers end up being checked by the normal C type rules at the actual
+ * comparison, and these expressions only need to be careful to not cause
+ * warnings for pointer use.
*/
#define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux))
#define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4))
@@ -57,19 +52,19 @@
__signed_type_use(x, ux) : __unsigned_type_use(x, ux))
/*
- * To avoid warnings about casting pointers to integers
- * of different sizes, we need that special sign type.
+ * Check whether a signed value is always non-negative.
*
- * On 64-bit we can just always use 'long', since any
- * integer or pointer type can just be cast to that.
+ * A cast is needed to avoid any warnings from values that aren't signed
+ * integer types (in which case the result doesn't matter).
*
- * This does not work for 128-bit signed integers since
- * the cast would truncate them, but we do not use s128
- * types in the kernel (we do use 'u128', but they will
- * be handled by the !is_signed_type() case).
+ * On 64-bit any integer or pointer type can safely be cast to 'long'.
+ * But on 32-bit we need to avoid warnings about casting pointers to integers
+ * of different sizes without truncating 64-bit values so 'long' or 'long long'
+ * must be used depending on the size of the value.
*
- * NOTE! The cast is there only to avoid any warnings
- * from when values that aren't signed integer types.
+ * This does not work for 128-bit signed integers since the cast would truncate
+ * them, but we do not use s128 types in the kernel (we do use 'u128',
+ * but they are handled by the !is_signed_type() case).
*/
#ifdef CONFIG_64BIT
#define __signed_type(ux) long
--
2.47.3
^ permalink raw reply related
* [PATCH 21/27 5.10.y] minmax.h: add whitespace around operators and after commas
From: Eliav Farber @ 2025-09-19 10:17 UTC (permalink / raw)
To: linux, jdike, richard, anton.ivanov, dave.hansen, luto, peterz,
tglx, mingo, bp, x86, hpa, tony.luck, qiuxu.zhuo, mchehab,
james.morse, rric, harry.wentland, sunpeng.li, alexander.deucher,
christian.koenig, airlied, daniel, evan.quan, james.qian.wang,
liviu.dudau, mihail.atanassov, brian.starkey, maarten.lankhorst,
mripard, tzimmermann, robdclark, sean, jdelvare, linux, fery,
dmitry.torokhov, agk, snitzer, dm-devel, rajur, davem, kuba,
peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
malattia, hdegoede, mgross, intel-linux-scu, artur.paszkiewicz,
jejb, martin.petersen, sakari.ailus, gregkh, clm, josef, dsterba,
jack, tytso, adilger.kernel, dushistov, luc.vanoostenryck,
rostedt, pmladek, sergey.senozhatsky, andriy.shevchenko, linux,
minchan, ngupta, akpm, kuznet, yoshfuji, pablo, kadlec, fw,
jmaloy, ying.xue, willy, farbere, sashal, ruanjinjie,
David.Laight, herve.codina, Jason, bvanassche, keescook,
linux-arm-kernel, linux-kernel, linux-um, linux-edac, amd-gfx,
dri-devel, linux-arm-msm, freedreno, linux-hwmon, linux-input,
linux-media, netdev, linux-stm32, platform-driver-x86, linux-scsi,
linux-staging, linux-btrfs, linux-ext4, linux-sparse, linux-mm,
netfilter-devel, coreteam, tipc-discussion, stable
Cc: jonnyc, Arnd Bergmann, Christoph Hellwig, Dan Carpenter,
Jens Axboe, Lorenzo Stoakes, Mateusz Guzik, Pedro Falcato
In-Reply-To: <20250919101727.16152-1-farbere@amazon.com>
From: David Laight <David.Laight@ACULAB.COM>
[ Upstream commit 71ee9b16251ea4bf7c1fe222517c82bdb3220acc ]
Patch series "minmax.h: Cleanups and minor optimisations".
Some tidyups and minor changes to minmax.h.
This patch (of 7):
Link: https://lkml.kernel.org/r/c50365d214e04f9ba256d417c8bebbc0@AcuMS.aculab.com
Link: https://lkml.kernel.org/r/f04b2e1310244f62826267346fde0553@AcuMS.aculab.com
Signed-off-by: David Laight <david.laight@aculab.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Arnd Bergmann <arnd@kernel.org>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Jason A. Donenfeld <Jason@zx2c4.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Mateusz Guzik <mjguzik@gmail.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Eliav Farber <farbere@amazon.com>
---
include/linux/minmax.h | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/linux/minmax.h b/include/linux/minmax.h
index 98008dd92153..51b0d988e322 100644
--- a/include/linux/minmax.h
+++ b/include/linux/minmax.h
@@ -51,10 +51,10 @@
* only need to be careful to not cause warnings for
* pointer use.
*/
-#define __signed_type_use(x,ux) (2+__is_nonneg(x,ux))
-#define __unsigned_type_use(x,ux) (1+2*(sizeof(ux)<4))
-#define __sign_use(x,ux) (is_signed_type(typeof(ux))? \
- __signed_type_use(x,ux):__unsigned_type_use(x,ux))
+#define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux))
+#define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4))
+#define __sign_use(x, ux) (is_signed_type(typeof(ux)) ? \
+ __signed_type_use(x, ux) : __unsigned_type_use(x, ux))
/*
* To avoid warnings about casting pointers to integers
@@ -74,15 +74,15 @@
#ifdef CONFIG_64BIT
#define __signed_type(ux) long
#else
- #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L))
+ #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L))
#endif
-#define __is_nonneg(x,ux) statically_true((__signed_type(ux))(x)>=0)
+#define __is_nonneg(x, ux) statically_true((__signed_type(ux))(x) >= 0)
-#define __types_ok(x,y,ux,uy) \
- (__sign_use(x,ux) & __sign_use(y,uy))
+#define __types_ok(x, y, ux, uy) \
+ (__sign_use(x, ux) & __sign_use(y, uy))
-#define __types_ok3(x,y,z,ux,uy,uz) \
- (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz))
+#define __types_ok3(x, y, z, ux, uy, uz) \
+ (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz))
#define __cmp_op_min <
#define __cmp_op_max >
@@ -97,7 +97,7 @@
#define __careful_cmp_once(op, x, y, ux, uy) ({ \
__auto_type ux = (x); __auto_type uy = (y); \
- BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \
+ BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \
#op"("#x", "#y") signedness error"); \
__cmp(op, ux, uy); })
@@ -114,7 +114,7 @@
static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \
(lo) <= (hi), true), \
"clamp() low limit " #lo " greater than high limit " #hi); \
- BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \
+ BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \
"clamp("#val", "#lo", "#hi") signedness error"); \
__clamp(uval, ulo, uhi); })
@@ -154,7 +154,7 @@
#define __careful_op3(op, x, y, z, ux, uy, uz) ({ \
__auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\
- BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \
+ BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \
#op"3("#x", "#y", "#z") signedness error"); \
__cmp(op, ux, __cmp(op, uy, uz)); })
@@ -326,9 +326,9 @@ static inline bool in_range32(u32 val, u32 start, u32 len)
* Use these carefully: no type checking, and uses the arguments
* multiple times. Use for obvious constants only.
*/
-#define MIN(a,b) __cmp(min,a,b)
-#define MAX(a,b) __cmp(max,a,b)
-#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b))
-#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b))
+#define MIN(a, b) __cmp(min, a, b)
+#define MAX(a, b) __cmp(max, a, b)
+#define MIN_T(type, a, b) __cmp(min, (type)(a), (type)(b))
+#define MAX_T(type, a, b) __cmp(max, (type)(a), (type)(b))
#endif /* _LINUX_MINMAX_H */
--
2.47.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox