This patch add a routine to judge if the usb device is a mouse or not. The is_usb_mouse only has one input parameter of usb_device. The return value is bool type, and true means this device is mouse and vice-versa. It also add a remote wakeup quirk for some special AMD platforms. This quirk filters southbridge revision which is 0x39 or 0x3a. Signed-off-by: Huang Rui <ray.huang@xxxxxxx> --- drivers/usb/core/hub.c | 27 +++++++++++++++++++++++++++ drivers/usb/host/pci-quirks.c | 14 +++++++++++++- drivers/usb/host/pci-quirks.h | 1 + include/linux/usb.h | 1 + 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5d859fc..be5ebf8 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -27,6 +27,7 @@ #include <linux/freezer.h> #include <linux/random.h> #include <linux/pm_qos.h> +#include <linux/hid.h> #include <asm/uaccess.h> #include <asm/byteorder.h> @@ -5442,3 +5443,29 @@ acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev, return DEVICE_ACPI_HANDLE(&hub->ports[port1 - 1]->dev); } #endif + +bool is_usb_mouse(struct usb_device *udev) +{ + struct usb_interface *intf; + struct usb_interface_descriptor intf_desc; + + if (!udev) { + dev_warn(&udev->dev, "Warn: no device attached!\n"); + return false; + } + + intf = usb_ifnum_to_if(udev, 0); + intf_desc = intf->cur_altsetting->desc; + if (intf_desc.bInterfaceClass == USB_INTERFACE_CLASS_HID && + intf_desc.bInterfaceSubClass == + USB_INTERFACE_SUBCLASS_BOOT && + intf_desc.bInterfaceProtocol == + USB_INTERFACE_PROTOCOL_MOUSE) { + dev_dbg(&udev->dev, "The attached usb device is mouse\n"); + return true; + } + + dev_dbg(&udev->dev, "The attached usb device is NOT mouse\n"); + return false; +} +EXPORT_SYMBOL_GPL(is_usb_mouse); diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2c76ef1..03187b5 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -140,9 +140,11 @@ int usb_amd_find_chipset_info(void) rev = info.smbus_dev->revision; if (rev >= 0x11 && rev <= 0x18) info.sb_type = 2; + if (rev >= 0x39 && rev <= 0x3a) + info.sb_type = 4; } - if (info.sb_type == 0) { + if (info.sb_type == 0 || info.sb_type == 4) { if (info.smbus_dev) { pci_dev_put(info.smbus_dev); info.smbus_dev = NULL; @@ -197,6 +199,16 @@ commit: } EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); +int usb_amd_remote_wakeup_quirk(void) +{ + if (amd_chipset.sb_type != 4) + return 0; + + printk(KERN_DEBUG "QUIRK: Enable AMD remote wakup fix\n"); + return 1; +} +EXPORT_SYMBOL_GPL(usb_amd_remote_wakeup_quirk); + /* * The hardware normally enables the A-link power management feature, which * lets the system lower the power consumption in idle states. diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ed6700d..e28bbbe 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -5,6 +5,7 @@ void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); int usb_amd_find_chipset_info(void); +int usb_amd_remote_wakeup_quirk(void); void usb_amd_dev_put(void); void usb_amd_quirk_pll_disable(void); void usb_amd_quirk_pll_enable(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index 001629c..f7b1a6c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -591,6 +591,7 @@ extern struct usb_device *usb_get_dev(struct usb_device *dev); extern void usb_put_dev(struct usb_device *dev); extern struct usb_device *usb_hub_find_child(struct usb_device *hdev, int port1); +extern bool is_usb_mouse(struct usb_device *udev); /** * usb_hub_for_each_child - iterate over all child devices on the hub -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html