On Sat, 27 Feb 2021 17:26:42 -0800 Ronald Tschalär <ronald@xxxxxxxxxxxxx> wrote: > The iBridge device provides access to several devices, including: > - the Touch Bar > - the iSight webcam > - the light sensor > - the fingerprint sensor > > This driver provides the core support for managing the iBridge device > and the access to the underlying devices. In particular, the > functionality for the touch bar and light sensor is exposed via USB HID > interfaces, and on devices with the T1 chip one of the HID devices is > used for both functions. So this driver creates virtual HID devices, one > per top-level report collection on each HID device (for a total of 3 > virtual HID devices). The sub-drivers then bind to these virtual HID > devices. > > This way the Touch Bar and ALS drivers can be kept in their own modules, > while at the same time making them look very much like as if they were > connected to the real HID devices. And those drivers then work (mostly) > without further changes on MacBooks with the T2 chip that don't need > this driver. > > Signed-off-by: Ronald Tschalär <ronald@xxxxxxxxxxxxx> Hi Ronald. This is far from my specialty but mostly looks sensible to me. Just one thing stood out that I couldn't understand. See below. Jonathan > new file mode 100644 > index 0000000000000..5f2b71c199746 > --- /dev/null > +++ b/drivers/hid/apple-ibridge.c > @@ -0,0 +1,682 @@ ... > + > +#ifdef CONFIG_PM > +/** > + * appleib_forward_int_op() - Forward a hid-driver callback to all drivers on > + * all virtual HID devices attached to the given real HID device. > + * @hdev the real hid-device > + * @forward a function that calls the callback on the given driver > + * @args arguments for the forward function > + * > + * This is for callbacks that return a status as an int. > + * > + * Returns: 0 on success, or the first error returned by the @forward function. > + */ > +static int appleib_forward_int_op(struct hid_device *hdev, > + int (*forward)(struct hid_driver *, > + struct hid_device *, void *), > + void *args) > +{ > + struct appleib_hid_dev_info *hdev_info = hid_get_drvdata(hdev); > + struct hid_device *sub_hdev; > + int rc = 0; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(hdev_info->sub_hdevs); i++) { > + sub_hdev = hdev_info->sub_hdevs[i]; > + if (sub_hdev->driver) { > + rc = forward(sub_hdev->driver, sub_hdev, args); > + if (rc) > + break; return rc; here would be cleaner. > + } > + > + break; This is unusual. It's a for loop but as far as I can see only first iteration can ever run as we exit the loop at this break if we haven't done so earlier. What is the intent here? > + } > + > + return rc; > +}