New USB driver that sets power/control to autosuspend for Motorola Solutions security accessories. The new driver only changes the power control for specific USB devices, normal read/write/ioctl of the usb device uses the unmodified usbfs. The rationale for a vendor specific driver was to allow for autosuspend behavior on Linux installations that are battery powered and do not allow user modifications to udev settings (e.g. embedded Linux, Android, etc.). The idealistic generic approach that would allow any USB device that supports autosuspend to change the power control could not be found without a change to the USB standard or substantial change to the usbfs architecture. Signed-off-by: Yinghua Yang <Yinghua.Yang@xxxxxxxxxxxxxxxxxxxxx> --- MAINTAINERS | 6 +++ drivers/usb/misc/Kconfig | 10 ++++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/motsolsa.c | 100 ++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+) create mode 100644 drivers/usb/misc/motsolsa.c diff --git a/MAINTAINERS b/MAINTAINERS index e2c6187a3ac8..eb9ad6ab9c20 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22423,6 +22423,12 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/usb/midi.* +USB MOTOROLA SOLUTIONS SECURITY ACCESSORIES DRIVER +M: Yinghua Yang <Yinghua.Yang@xxxxxxxxxxxxxxxxxxxxx> +L: linux-usb@xxxxxxxxxxxxxxx +S: Maintained +F: drivers/usb/misc/motsolsa.c + USB NETWORKING DRIVERS L: linux-usb@xxxxxxxxxxxxxxx S: Odd Fixes diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index c510af7baa0d..cb1fa63cc0d1 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -331,3 +331,13 @@ config USB_ONBOARD_HUB this config will enable the driver and it will automatically match the state of the USB subsystem. If this driver is a module it will be called onboard_usb_hub. + +config USB_MOTSOL_SA + tristate "Motorola Solutions Security Accessories Driver" + help + Say Y here if you want to enables auto suspend mode for + Motorola Solutions Security Accessory devices. + + The new driver only changes the power control for specific + USB devices, normal read/write/ioctl of the usb device uses + the unmodified usbfs. diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 0bc732bcb162..4e639693b8c5 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_BRCM_USB_PINMAP) += brcmstb-usb-pinmap.o obj-$(CONFIG_USB_ONBOARD_HUB) += onboard_usb_hub.o +obj-$(CONFIG_USB_MOTSOL_SA) += motsolsa.o diff --git a/drivers/usb/misc/motsolsa.c b/drivers/usb/misc/motsolsa.c new file mode 100644 index 000000000000..69f6be9bd8d1 --- /dev/null +++ b/drivers/usb/misc/motsolsa.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for setting auto suspend mode for Motorola Solutions security accessories + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/usb.h> + +#define DRIVER_DESC "Motorola Solutions security accessory driver" + +static int motsol_sa_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + + dev_dbg(&(interface)->dev, "probe (%04X:%04X)\n", id->idVendor, + id->idProduct); + usb_enable_autosuspend(udev); + return 0; +} + +static void motsol_sa_disconnect(struct usb_interface *interface) +{ + dev_dbg(&(interface)->dev, "disconnect\n"); +} + +#define MOTSOL_VENDOR_ID 0x0cad +#define MOTSOL_SA_PRODUCT_ID 0x01901 + +static struct usb_device_id motsol_sa_table[] = { + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 1) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 2) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 3) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 4) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 5) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 6) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 7) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 8) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 9) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 10) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 11) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 12) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 13) }, + { USB_DEVICE(MOTSOL_VENDOR_ID, MOTSOL_SA_PRODUCT_ID + 14) }, + {} +}; + +MODULE_DEVICE_TABLE(usb, motsol_sa_table); + +#ifdef CONFIG_PM +static int motsol_sa_suspend(struct usb_interface *interface, + pm_message_t message) +{ + dev_dbg(&(interface)->dev, "suspend"); + return 0; +} + +static int motsol_sa_resume(struct usb_interface *interface) +{ + dev_dbg(&(interface)->dev, "resume"); + return 0; +} +#else +#define motsol_sa_suspend NULL +#define motsol_sa_resume NULL +#endif + +static struct usb_driver motsol_sa_driver = { + .name = "motsol_sa", + .id_table = motsol_sa_table, + .probe = motsol_sa_probe, + .suspend = motsol_sa_suspend, + .resume = motsol_sa_resume, + .reset_resume = motsol_sa_resume, + .supports_autosuspend = 1, + .disconnect = motsol_sa_disconnect, +}; + +static int __init motsol_sa_init(void) +{ + int ret = -1; + + ret = usb_register(&motsol_sa_driver); + pr_debug("%s: %s\n", KBUILD_MODNAME, DRIVER_DESC); + return ret; +} + +static void __exit motsol_sa_exit(void) +{ + usb_deregister(&motsol_sa_driver); + pr_debug("%s driver deregistered\n", motsol_sa_driver.name); +} + +module_init(motsol_sa_init); +module_exit(motsol_sa_exit); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); -- 2.34.1 -- *For more information on how and why we collect your personal information, please visit our Privacy Policy <https://www.motorolasolutions.com/en_us/about/privacy-policy.html?elqTrackId=8980d888905940e39a2613a7a3dcb0a7&elqaid=2786&elqat=2#privacystatement>.*