Pull USB/Thunderbolt driver fixes from Greg KH: "Here are a lot of small USB and Thunderbolt driver fixes for 6.0-rc4 for reported problems. Included in here are: - new usb-serial driver ids - dwc3 driver bugfixes for reported problems with 6.0-rc1 - new device quirks, and reverts of some quirks that were incorrect - gadget driver bugfixes for reported problems - USB host controller bugfixes (xhci and others) - other small USB fixes, details in the shortlog - small thunderbolt driver fixes All of these have been in linux-next with no reported issues" * tag 'usb-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (51 commits) Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio" usb: storage: Add ASUS <0x0b05:0x1932> to IGNORE_UAS USB: serial: ch341: fix disabled rx timer on older devices USB: serial: ch341: fix lost character on LCR updates USB: serial: cp210x: add Decagon UCA device id Revert "usb: add quirks for Lenovo OneLink+ Dock" usb: cdns3: fix issue with rearming ISO OUT endpoint usb: cdns3: fix incorrect handling TRB_SMM flag for ISOC transfer usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS media: mceusb: Use new usb_control_msg_*() routines USB: core: Prevent nested device-reset calls USB: gadget: Fix obscure lockdep violation for udc_mutex usb: dwc2: fix wrong order of phy_power_on and phy_init usb: gadget: udc-xilinx: replace memcpy with memcpy_toio usb: typec: Remove retimers properly usb: dwc3: disable USB core PHY management usb: add quirks for Lenovo OneLink+ Dock USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id USB: serial: option: add Quectel EM060K modem ...
Unified · Split
| @@ -24,6 +24,7 @@ properties: · 23 unmodified lines | |||
| 24 | - mediatek,mt2712-mtu3 | 24 | - mediatek,mt2712-mtu3 |
| 25 | - mediatek,mt8173-mtu3 | 25 | - mediatek,mt8173-mtu3 |
| 26 | - mediatek,mt8183-mtu3 | 26 | - mediatek,mt8183-mtu3 |
| 27 | - mediatek,mt8188-mtu3 | ||
| 27 | - mediatek,mt8192-mtu3 | 28 | - mediatek,mt8192-mtu3 |
| 28 | - mediatek,mt8195-mtu3 | 29 | - mediatek,mt8195-mtu3 |
| 29 | - const: mediatek,mtu3 | 30 | - const: mediatek,mtu3 |
| @@ -33,6 +33,7 @@ properties: · 32 unmodified lines | |||
| 33 | - qcom,sm6115-dwc3 | 33 | - qcom,sm6115-dwc3 |
| 34 | - qcom,sm6125-dwc3 | 34 | - qcom,sm6125-dwc3 |
| 35 | - qcom,sm6350-dwc3 | 35 | - qcom,sm6350-dwc3 |
| 36 | - qcom,sm6375-dwc3 | ||
| 36 | - qcom,sm8150-dwc3 | 37 | - qcom,sm8150-dwc3 |
| 37 | - qcom,sm8250-dwc3 | 38 | - qcom,sm8250-dwc3 |
| 38 | - qcom,sm8350-dwc3 | 39 | - qcom,sm8350-dwc3 |
| @@ -108,12 +109,17 @@ properties: · 69 unmodified lines | |||
| 108 | HS/FS/LS modes are supported. | 109 | HS/FS/LS modes are supported. |
| 109 | type: boolean | 110 | type: boolean |
| 110 | 111 | ||
| 112 | wakeup-source: true | ||
| 113 | |||
| 111 | # Required child node: | 114 | # Required child node: |
| 112 | 115 | ||
| 113 | patternProperties: | 116 | patternProperties: |
| 114 | "^usb@[0-9a-f]+$": | 117 | "^usb@[0-9a-f]+$": |
| 115 | $ref: snps,dwc3.yaml# | 118 | $ref: snps,dwc3.yaml# |
| 116 | 119 | ||
| 120 | properties: | ||
| 121 | wakeup-source: false | ||
| 122 | |||
| 117 | required: | 123 | required: |
| 118 | - compatible | 124 | - compatible |
| 119 | - reg | 125 | - reg |
| @@ -1416,42 +1416,37 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) · 1415 unmodified lines | |||
| 1416 | { | 1416 | { |
| 1417 | int ret; | 1417 | int ret; |
| 1418 | struct device *dev = ir->dev; | 1418 | struct device *dev = ir->dev; |
| 1419 | char *data; | 1419 | char data[USB_CTRL_MSG_SZ]; |
| 1420 | |||
| 1421 | data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); | ||
| 1422 | if (!data) { | ||
| 1423 | dev_err(dev, "%s: memory allocation failed!", __func__); | ||
| 1424 | return; | ||
| 1425 | } | ||
| 1426 | 1420 | ||
| 1427 | /* | 1421 | /* |
| 1428 | * This is a strange one. Windows issues a set address to the device | 1422 | * This is a strange one. Windows issues a set address to the device |
| 1429 | * on the receive control pipe and expect a certain value pair back | 1423 | * on the receive control pipe and expect a certain value pair back |
| 1430 | */ | 1424 | */ |
| 1431 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | 1425 | ret = usb_control_msg_recv(ir->usbdev, 0, USB_REQ_SET_ADDRESS, |
| 1432 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, | 1426 | USB_DIR_IN | USB_TYPE_VENDOR, |
| 1433 | data, USB_CTRL_MSG_SZ, 3000); | 1427 | 0, 0, data, USB_CTRL_MSG_SZ, 3000, |
| 1428 | GFP_KERNEL); | ||
| 1434 | dev_dbg(dev, "set address - ret = %d", ret); | 1429 | dev_dbg(dev, "set address - ret = %d", ret); |
| 1435 | dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", | 1430 | dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", |
| 1436 | data[0], data[1]); | 1431 | data[0], data[1]); |
| 1437 | 1432 | ||
| 1438 | /* set feature: bit rate 38400 bps */ | 1433 | /* set feature: bit rate 38400 bps */ |
| 1439 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1434 | ret = usb_control_msg_send(ir->usbdev, 0, |
| 1440 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, | 1435 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
| 1441 | 0xc04e, 0x0000, NULL, 0, 3000); | 1436 | 0xc04e, 0x0000, NULL, 0, 3000, GFP_KERNEL); |
| 1442 | 1437 | ||
| 1443 | dev_dbg(dev, "set feature - ret = %d", ret); | 1438 | dev_dbg(dev, "set feature - ret = %d", ret); |
| 1444 | 1439 | ||
| 1445 | /* bRequest 4: set char length to 8 bits */ | 1440 | /* bRequest 4: set char length to 8 bits */ |
| 1446 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1441 | ret = usb_control_msg_send(ir->usbdev, 0, |
| 1447 | 4, USB_TYPE_VENDOR, | 1442 | 4, USB_TYPE_VENDOR, |
| 1448 | 0x0808, 0x0000, NULL, 0, 3000); | 1443 | 0x0808, 0x0000, NULL, 0, 3000, GFP_KERNEL); |
| 1449 | dev_dbg(dev, "set char length - retB = %d", ret); | 1444 | dev_dbg(dev, "set char length - retB = %d", ret); |
| 1450 | 1445 | ||
| 1451 | /* bRequest 2: set handshaking to use DTR/DSR */ | 1446 | /* bRequest 2: set handshaking to use DTR/DSR */ |
| 1452 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1447 | ret = usb_control_msg_send(ir->usbdev, 0, |
| 1453 | 2, USB_TYPE_VENDOR, | 1448 | 2, USB_TYPE_VENDOR, |
| 1454 | 0x0000, 0x0100, NULL, 0, 3000); | 1449 | 0x0000, 0x0100, NULL, 0, 3000, GFP_KERNEL); |
| 1455 | dev_dbg(dev, "set handshake - retC = %d", ret); | 1450 | dev_dbg(dev, "set handshake - retC = %d", ret); |
| 1456 | 1451 | ||
| 1457 | /* device resume */ | 1452 | /* device resume */ |
| @@ -1459,8 +1454,6 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) · 1 unmodified line | |||
| 1459 | 1454 | ||
| 1460 | /* get hw/sw revision? */ | 1455 | /* get hw/sw revision? */ |
| 1461 | mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION)); | 1456 | mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
| 1462 | |||
| 1463 | kfree(data); | ||
| 1464 | } | 1457 | } |
| 1465 | 1458 | ||
| 1466 | static void mceusb_gen2_init(struct mceusb_dev *ir) | 1459 | static void mceusb_gen2_init(struct mceusb_dev *ir) |
| @@ -407,7 +407,7 @@ static void tb_ctl_rx_submit(struct ctl_pkg *pkg) · 406 unmodified lines | |||
| 407 | 407 | ||
| 408 | static int tb_async_error(const struct ctl_pkg *pkg) | 408 | static int tb_async_error(const struct ctl_pkg *pkg) |
| 409 | { | 409 | { |
| 410 | const struct cfg_error_pkg *error = (const struct cfg_error_pkg *)pkg; | 410 | const struct cfg_error_pkg *error = pkg->buffer; |
| 411 | 411 | ||
| 412 | if (pkg->frame.eof != TB_CFG_PKG_ERROR) | 412 | if (pkg->frame.eof != TB_CFG_PKG_ERROR) |
| 413 | return false; | 413 | return false; |
| @@ -3786,14 +3786,18 @@ int tb_switch_pcie_l1_enable(struct tb_switch *sw) · 3785 unmodified lines | |||
| 3786 | */ | 3786 | */ |
| 3787 | int tb_switch_xhci_connect(struct tb_switch *sw) | 3787 | int tb_switch_xhci_connect(struct tb_switch *sw) |
| 3788 | { | 3788 | { |
| 3789 | bool usb_port1, usb_port3, xhci_port1, xhci_port3; | ||
| 3790 | struct tb_port *port1, *port3; | 3789 | struct tb_port *port1, *port3; |
| 3791 | int ret; | 3790 | int ret; |
| 3792 | 3791 | ||
| 3792 | if (sw->generation != 3) | ||
| 3793 | return 0; | ||
| 3794 | |||
| 3793 | port1 = &sw->ports[1]; | 3795 | port1 = &sw->ports[1]; |
| 3794 | port3 = &sw->ports[3]; | 3796 | port3 = &sw->ports[3]; |
| 3795 | 3797 | ||
| 3796 | if (tb_switch_is_alpine_ridge(sw)) { | 3798 | if (tb_switch_is_alpine_ridge(sw)) { |
| 3799 | bool usb_port1, usb_port3, xhci_port1, xhci_port3; | ||
| 3800 | |||
| 3797 | usb_port1 = tb_lc_is_usb_plugged(port1); | 3801 | usb_port1 = tb_lc_is_usb_plugged(port1); |
| 3798 | usb_port3 = tb_lc_is_usb_plugged(port3); | 3802 | usb_port3 = tb_lc_is_usb_plugged(port3); |
| 3799 | xhci_port1 = tb_lc_is_xhci_connected(port1); | 3803 | xhci_port1 = tb_lc_is_xhci_connected(port1); |
| @@ -1530,7 +1530,8 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev, · 1529 unmodified lines | |||
| 1530 | TRB_LEN(le32_to_cpu(trb->length)); | 1530 | TRB_LEN(le32_to_cpu(trb->length)); |
| 1531 | 1531 | ||
| 1532 | if (priv_req->num_of_trb > 1 && | 1532 | if (priv_req->num_of_trb > 1 && |
| 1533 | le32_to_cpu(trb->control) & TRB_SMM) | 1533 | le32_to_cpu(trb->control) & TRB_SMM && |
| 1534 | le32_to_cpu(trb->control) & TRB_CHAIN) | ||
| 1534 | transfer_end = true; | 1535 | transfer_end = true; |
| 1535 | 1536 | ||
| 1536 | cdns3_ep_inc_deq(priv_ep); | 1537 | cdns3_ep_inc_deq(priv_ep); |
| @@ -1690,6 +1691,7 @@ static int cdns3_check_ep_interrupt_proceed(struct cdns3_endpoint *priv_ep) · 153 unmodified lines | |||
| 1690 | ep_cfg &= ~EP_CFG_ENABLE; | 1691 | ep_cfg &= ~EP_CFG_ENABLE; |
| 1691 | writel(ep_cfg, &priv_dev->regs->ep_cfg); | 1692 | writel(ep_cfg, &priv_dev->regs->ep_cfg); |
| 1692 | priv_ep->flags &= ~EP_QUIRK_ISO_OUT_EN; | 1693 | priv_ep->flags &= ~EP_QUIRK_ISO_OUT_EN; |
| 1694 | priv_ep->flags |= EP_UPDATE_EP_TRBADDR; | ||
| 1693 | } | 1695 | } |
| 1694 | cdns3_transfer_completed(priv_dev, priv_ep); | 1696 | cdns3_transfer_completed(priv_dev, priv_ep); |
| 1695 | } else if (!(priv_ep->flags & EP_STALLED) && | 1697 | } else if (!(priv_ep->flags & EP_STALLED) && |
| @@ -1810,6 +1810,9 @@ static const struct usb_device_id acm_ids[] = { · 1809 unmodified lines | |||
| 1810 | { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ | 1810 | { USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */ |
| 1811 | .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ | 1811 | .driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */ |
| 1812 | }, | 1812 | }, |
| 1813 | { USB_DEVICE(0x0c26, 0x0020), /* Icom ICF3400 Serie */ | ||
| 1814 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ | ||
| 1815 | }, | ||
| 1813 | { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ | 1816 | { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */ |
| 1814 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ | 1817 | .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */ |
| 1815 | }, | 1818 | }, |
| @@ -6038,6 +6038,11 @@ re_enumerate: · 6037 unmodified lines | |||
| 6038 | * the reset is over (using their post_reset method). | 6038 | * the reset is over (using their post_reset method). |
| 6039 | * | 6039 | * |
| 6040 | * Return: The same as for usb_reset_and_verify_device(). | 6040 | * Return: The same as for usb_reset_and_verify_device(). |
| 6041 | * However, if a reset is already in progress (for instance, if a | ||
| 6042 | * driver doesn't have pre_ or post_reset() callbacks, and while | ||
| 6043 | * being unbound or re-bound during the ongoing reset its disconnect() | ||
| 6044 | * or probe() routine tries to perform a second, nested reset), the | ||
| 6045 | * routine returns -EINPROGRESS. | ||
| 6041 | * | 6046 | * |
| 6042 | * Note: | 6047 | * Note: |
| 6043 | * The caller must own the device lock. For example, it's safe to use | 6048 | * The caller must own the device lock. For example, it's safe to use |
| @@ -6071,6 +6076,10 @@ int usb_reset_device(struct usb_device *udev) · 27 unmodified lines | |||
| 6071 | return -EISDIR; | 6076 | return -EISDIR; |
| 6072 | } | 6077 | } |
| 6073 | 6078 | ||
| 6079 | if (udev->reset_in_progress) | ||
| 6080 | return -EINPROGRESS; | ||
| 6081 | udev->reset_in_progress = 1; | ||
| 6082 | |||
| 6074 | port_dev = hub->ports[udev->portnum - 1]; | 6083 | port_dev = hub->ports[udev->portnum - 1]; |
| 6075 | 6084 | ||
| 6076 | /* | 6085 | /* |
| @@ -6135,6 +6144,7 @@ int usb_reset_device(struct usb_device *udev) · 58 unmodified lines | |||
| 6135 | 6144 | ||
| 6136 | usb_autosuspend_device(udev); | 6145 | usb_autosuspend_device(udev); |
| 6137 | memalloc_noio_restore(noio_flag); | 6146 | memalloc_noio_restore(noio_flag); |
| 6147 | udev->reset_in_progress = 0; | ||
| 6138 | return ret; | 6148 | return ret; |
| 6139 | } | 6149 | } |
| 6140 | EXPORT_SYMBOL_GPL(usb_reset_device); | 6150 | EXPORT_SYMBOL_GPL(usb_reset_device); |
| @@ -154,9 +154,9 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) · 153 unmodified lines | |||
| 154 | } else if (hsotg->plat && hsotg->plat->phy_init) { | 154 | } else if (hsotg->plat && hsotg->plat->phy_init) { |
| 155 | ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); | 155 | ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); |
| 156 | } else { | 156 | } else { |
| 157 | ret = phy_power_on(hsotg->phy); | 157 | ret = phy_init(hsotg->phy); |
| 158 | if (ret == 0) | 158 | if (ret == 0) |
| 159 | ret = phy_init(hsotg->phy); | 159 | ret = phy_power_on(hsotg->phy); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | return ret; | 162 | return ret; |
| @@ -188,9 +188,9 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) · 25 unmodified lines | |||
| 188 | } else if (hsotg->plat && hsotg->plat->phy_exit) { | 188 | } else if (hsotg->plat && hsotg->plat->phy_exit) { |
| 189 | ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); | 189 | ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); |
| 190 | } else { | 190 | } else { |
| 191 | ret = phy_exit(hsotg->phy); | 191 | ret = phy_power_off(hsotg->phy); |
| 192 | if (ret == 0) | 192 | if (ret == 0) |
| 193 | ret = phy_power_off(hsotg->phy); | 193 | ret = phy_exit(hsotg->phy); |
| 194 | } | 194 | } |
| 195 | if (ret) | 195 | if (ret) |
| 196 | return ret; | 196 | return ret; |
| @@ -833,15 +833,16 @@ static void dwc3_core_exit(struct dwc3 *dwc) · 832 unmodified lines | |||
| 833 | { | 833 | { |
| 834 | dwc3_event_buffers_cleanup(dwc); | 834 | dwc3_event_buffers_cleanup(dwc); |
| 835 | 835 | ||
| 836 | usb_phy_set_suspend(dwc->usb2_phy, 1); | ||
| 837 | usb_phy_set_suspend(dwc->usb3_phy, 1); | ||
| 838 | phy_power_off(dwc->usb2_generic_phy); | ||
| 839 | phy_power_off(dwc->usb3_generic_phy); | ||
| 840 | |||
| 836 | usb_phy_shutdown(dwc->usb2_phy); | 841 | usb_phy_shutdown(dwc->usb2_phy); |
| 837 | usb_phy_shutdown(dwc->usb3_phy); | 842 | usb_phy_shutdown(dwc->usb3_phy); |
| 838 | phy_exit(dwc->usb2_generic_phy); | 843 | phy_exit(dwc->usb2_generic_phy); |
| 839 | phy_exit(dwc->usb3_generic_phy); | 844 | phy_exit(dwc->usb3_generic_phy); |
| 840 | 845 | ||
| 841 | usb_phy_set_suspend(dwc->usb2_phy, 1); | ||
| 842 | usb_phy_set_suspend(dwc->usb3_phy, 1); | ||
| 843 | phy_power_off(dwc->usb2_generic_phy); | ||
| 844 | phy_power_off(dwc->usb3_generic_phy); | ||
| 845 | dwc3_clk_disable(dwc); | 846 | dwc3_clk_disable(dwc); |
| 846 | reset_control_assert(dwc->reset); | 847 | reset_control_assert(dwc->reset); |
| 847 | } | 848 | } |
| @@ -1821,7 +1822,6 @@ static int dwc3_probe(struct platform_device *pdev) · 973 unmodified lines | |||
| 1821 | 1822 | ||
| 1822 | platform_set_drvdata(pdev, dwc); | 1823 | platform_set_drvdata(pdev, dwc); |
| 1823 | dwc3_cache_hwparams(dwc); | 1824 | dwc3_cache_hwparams(dwc); |
| 1824 | device_init_wakeup(&pdev->dev, of_property_read_bool(dev->of_node, "wakeup-source")); | ||
| 1825 | 1825 | ||
| 1826 | spin_lock_init(&dwc->lock); | 1826 | spin_lock_init(&dwc->lock); |
| 1827 | mutex_init(&dwc->mutex); | 1827 | mutex_init(&dwc->mutex); |
| @@ -1879,16 +1879,16 @@ err5: · 51 unmodified lines | |||
| 1879 | dwc3_debugfs_exit(dwc); | 1879 | dwc3_debugfs_exit(dwc); |
| 1880 | dwc3_event_buffers_cleanup(dwc); | 1880 | dwc3_event_buffers_cleanup(dwc); |
| 1881 | 1881 | ||
| 1882 | usb_phy_shutdown(dwc->usb2_phy); | ||
| 1883 | usb_phy_shutdown(dwc->usb3_phy); | ||
| 1884 | phy_exit(dwc->usb2_generic_phy); | ||
| 1885 | phy_exit(dwc->usb3_generic_phy); | ||
| 1886 | |||
| 1887 | usb_phy_set_suspend(dwc->usb2_phy, 1); | 1882 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
| 1888 | usb_phy_set_suspend(dwc->usb3_phy, 1); | 1883 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
| 1889 | phy_power_off(dwc->usb2_generic_phy); | 1884 | phy_power_off(dwc->usb2_generic_phy); |
| 1890 | phy_power_off(dwc->usb3_generic_phy); | 1885 | phy_power_off(dwc->usb3_generic_phy); |
| 1891 | 1886 | ||
| 1887 | usb_phy_shutdown(dwc->usb2_phy); | ||
| 1888 | usb_phy_shutdown(dwc->usb3_phy); | ||
| 1889 | phy_exit(dwc->usb2_generic_phy); | ||
| 1890 | phy_exit(dwc->usb3_generic_phy); | ||
| 1891 | |||
| 1892 | dwc3_ulpi_exit(dwc); | 1892 | dwc3_ulpi_exit(dwc); |
| 1893 | 1893 | ||
| 1894 | err4: | 1894 | err4: |
| @@ -1983,7 +1983,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 88 unmodified lines | |||
| 1983 | dwc3_core_exit(dwc); | 1983 | dwc3_core_exit(dwc); |
| 1984 | break; | 1984 | break; |
| 1985 | case DWC3_GCTL_PRTCAP_HOST: | 1985 | case DWC3_GCTL_PRTCAP_HOST: |
| 1986 | if (!PMSG_IS_AUTO(msg) && !device_can_wakeup(dwc->dev)) { | 1986 | if (!PMSG_IS_AUTO(msg) && !device_may_wakeup(dwc->dev)) { |
| 1987 | dwc3_core_exit(dwc); | 1987 | dwc3_core_exit(dwc); |
| 1988 | break; | 1988 | break; |
| 1989 | } | 1989 | } |
| @@ -2044,7 +2044,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) · 54 unmodified lines | |||
| 2044 | spin_unlock_irqrestore(&dwc->lock, flags); | 2044 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2045 | break; | 2045 | break; |
| 2046 | case DWC3_GCTL_PRTCAP_HOST: | 2046 | case DWC3_GCTL_PRTCAP_HOST: |
| 2047 | if (!PMSG_IS_AUTO(msg) && !device_can_wakeup(dwc->dev)) { | 2047 | if (!PMSG_IS_AUTO(msg) && !device_may_wakeup(dwc->dev)) { |
| 2048 | ret = dwc3_core_init_for_resume(dwc); | 2048 | ret = dwc3_core_init_for_resume(dwc); |
| 2049 | if (ret) | 2049 | if (ret) |
| 2050 | return ret; | 2050 | return ret; |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | |||
| 44 | #define PCI_DEVICE_ID_INTEL_ADLP 0x51ee | 44 | #define PCI_DEVICE_ID_INTEL_ADLP 0x51ee |
| 45 | #define PCI_DEVICE_ID_INTEL_ADLM 0x54ee | 45 | #define PCI_DEVICE_ID_INTEL_ADLM 0x54ee |
| 46 | #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 | 46 | #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 |
| 47 | #define PCI_DEVICE_ID_INTEL_RPL 0x460e | ||
| 47 | #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 | 48 | #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 |
| 48 | #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 | 49 | #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 |
| 49 | #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e | 50 | #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e |
| @@ -456,6 +457,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = { · 406 unmodified lines | |||
| 456 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS), | 457 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ADLS), |
| 457 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | 458 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, |
| 458 | 459 | ||
| 460 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPL), | ||
| 461 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | ||
| 462 | |||
| 459 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS), | 463 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS), |
| 460 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | 464 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, |
| 461 | 465 | ||
| @@ -17,7 +17,6 @@ · 16 unmodified lines | |||
| 17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/phy/phy.h> | 19 | #include <linux/phy/phy.h> |
| 20 | #include <linux/pm_domain.h> | ||
| 21 | #include <linux/usb/of.h> | 20 | #include <linux/usb/of.h> |
| 22 | #include <linux/reset.h> | 21 | #include <linux/reset.h> |
| 23 | #include <linux/iopoll.h> | 22 | #include <linux/iopoll.h> |
| @@ -299,11 +298,24 @@ static void dwc3_qcom_interconnect_exit(struct dwc3_qcom *qcom) · 275 unmodified lines | |||
| 299 | icc_put(qcom->icc_path_apps); | 298 | icc_put(qcom->icc_path_apps); |
| 300 | } | 299 | } |
| 301 | 300 | ||
| 301 | /* Only usable in contexts where the role can not change. */ | ||
| 302 | static bool dwc3_qcom_is_host(struct dwc3_qcom *qcom) | ||
| 303 | { | ||
| 304 | struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); | ||
| 305 | |||
| 306 | return dwc->xhci; | ||
| 307 | } | ||
| 308 | |||
| 302 | static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom) | 309 | static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom) |
| 303 | { | 310 | { |
| 304 | struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); | 311 | struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); |
| 305 | struct usb_hcd *hcd = platform_get_drvdata(dwc->xhci); | ||
| 306 | struct usb_device *udev; | 312 | struct usb_device *udev; |
| 313 | struct usb_hcd __maybe_unused *hcd; | ||
| 314 | |||
| 315 | /* | ||
| 316 | * FIXME: Fix this layering violation. | ||
| 317 | */ | ||
| 318 | hcd = platform_get_drvdata(dwc->xhci); | ||
| 307 | 319 | ||
| 308 | /* | 320 | /* |
| 309 | * It is possible to query the speed of all children of | 321 | * It is possible to query the speed of all children of |
| @@ -311,8 +323,11 @@ static enum usb_device_speed dwc3_qcom_read_usb2_speed(struct dwc3_qcom *qcom) · 1 unmodified line | |||
| 311 | * currently supports only 1 port per controller. So | 323 | * currently supports only 1 port per controller. So |
| 312 | * this is sufficient. | 324 | * this is sufficient. |
| 313 | */ | 325 | */ |
| 326 | #ifdef CONFIG_USB | ||
| 314 | udev = usb_hub_find_child(hcd->self.root_hub, 1); | 327 | udev = usb_hub_find_child(hcd->self.root_hub, 1); |
| 315 | 328 | #else | |
| 329 | udev = NULL; | ||
| 330 | #endif | ||
| 316 | if (!udev) | 331 | if (!udev) |
| 317 | return USB_SPEED_UNKNOWN; | 332 | return USB_SPEED_UNKNOWN; |
| 318 | 333 | ||
| @@ -387,7 +402,7 @@ static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) · 68 unmodified lines | |||
| 387 | dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq, 0); | 402 | dwc3_qcom_enable_wakeup_irq(qcom->ss_phy_irq, 0); |
| 388 | } | 403 | } |
| 389 | 404 | ||
| 390 | static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) | 405 | static int dwc3_qcom_suspend(struct dwc3_qcom *qcom, bool wakeup) |
| 391 | { | 406 | { |
| 392 | u32 val; | 407 | u32 val; |
| 393 | int i, ret; | 408 | int i, ret; |
| @@ -406,7 +421,11 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) · 12 unmodified lines | |||
| 406 | if (ret) | 421 | if (ret) |
| 407 | dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); | 422 | dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); |
| 408 | 423 | ||
| 409 | if (device_may_wakeup(qcom->dev)) { | 424 | /* |
| 425 | * The role is stable during suspend as role switching is done from a | ||
| 426 | * freezable workqueue. | ||
| 427 | */ | ||
| 428 | if (dwc3_qcom_is_host(qcom) && wakeup) { | ||
| 410 | qcom->usb2_speed = dwc3_qcom_read_usb2_speed(qcom); | 429 | qcom->usb2_speed = dwc3_qcom_read_usb2_speed(qcom); |
| 411 | dwc3_qcom_enable_interrupts(qcom); | 430 | dwc3_qcom_enable_interrupts(qcom); |
| 412 | } | 431 | } |
| @@ -416,7 +435,7 @@ static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) · 3 unmodified lines | |||
| 416 | return 0; | 435 | return 0; |
| 417 | } | 436 | } |
| 418 | 437 | ||
| 419 | static int dwc3_qcom_resume(struct dwc3_qcom *qcom) | 438 | static int dwc3_qcom_resume(struct dwc3_qcom *qcom, bool wakeup) |
| 420 | { | 439 | { |
| 421 | int ret; | 440 | int ret; |
| 422 | int i; | 441 | int i; |
| @@ -424,7 +443,7 @@ static int dwc3_qcom_resume(struct dwc3_qcom *qcom) · 1 unmodified line | |||
| 424 | if (!qcom->is_suspended) | 443 | if (!qcom->is_suspended) |
| 425 | return 0; | 444 | return 0; |
| 426 | 445 | ||
| 427 | if (device_may_wakeup(qcom->dev)) | 446 | if (dwc3_qcom_is_host(qcom) && wakeup) |
| 428 | dwc3_qcom_disable_interrupts(qcom); | 447 | dwc3_qcom_disable_interrupts(qcom); |
| 429 | 448 | ||
| 430 | for (i = 0; i < qcom->num_clocks; i++) { | 449 | for (i = 0; i < qcom->num_clocks; i++) { |
| @@ -458,7 +477,11 @@ static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data) · 27 unmodified lines | |||
| 458 | if (qcom->pm_suspended) | 477 | if (qcom->pm_suspended) |
| 459 | return IRQ_HANDLED; | 478 | return IRQ_HANDLED; |
| 460 | 479 | ||
| 461 | if (dwc->xhci) | 480 | /* |
| 481 | * This is safe as role switching is done from a freezable workqueue | ||
| 482 | * and the wakeup interrupts are disabled as part of resume. | ||
| 483 | */ | ||
| 484 | if (dwc3_qcom_is_host(qcom)) | ||
| 462 | pm_runtime_resume(&dwc->xhci->dev); | 485 | pm_runtime_resume(&dwc->xhci->dev); |
| 463 | 486 | ||
| 464 | return IRQ_HANDLED; | 487 | return IRQ_HANDLED; |
| @@ -757,13 +780,13 @@ dwc3_qcom_create_urs_usb_platdev(struct device *dev) · 292 unmodified lines | |||
| 757 | 780 | ||
| 758 | static int dwc3_qcom_probe(struct platform_device *pdev) | 781 | static int dwc3_qcom_probe(struct platform_device *pdev) |
| 759 | { | 782 | { |
| 760 | struct device_node *np = pdev->dev.of_node; | 783 | struct device_node *np = pdev->dev.of_node; |
| 761 | struct device *dev = &pdev->dev; | 784 | struct device *dev = &pdev->dev; |
| 762 | struct dwc3_qcom *qcom; | 785 | struct dwc3_qcom *qcom; |
| 763 | struct resource *res, *parent_res = NULL; | 786 | struct resource *res, *parent_res = NULL; |
| 764 | int ret, i; | 787 | int ret, i; |
| 765 | bool ignore_pipe_clk; | 788 | bool ignore_pipe_clk; |
| 766 | struct generic_pm_domain *genpd; | 789 | bool wakeup_source; |
| 767 | 790 | ||
| 768 | qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); | 791 | qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); |
| 769 | if (!qcom) | 792 | if (!qcom) |
| @@ -772,8 +795,6 @@ static int dwc3_qcom_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 772 | platform_set_drvdata(pdev, qcom); | 795 | platform_set_drvdata(pdev, qcom); |
| 773 | qcom->dev = &pdev->dev; | 796 | qcom->dev = &pdev->dev; |
| 774 | 797 | ||
| 775 | genpd = pd_to_genpd(qcom->dev->pm_domain); | ||
| 776 | |||
| 777 | if (has_acpi_companion(dev)) { | 798 | if (has_acpi_companion(dev)) { |
| 778 | qcom->acpi_pdata = acpi_device_get_match_data(dev); | 799 | qcom->acpi_pdata = acpi_device_get_match_data(dev); |
| 779 | if (!qcom->acpi_pdata) { | 800 | if (!qcom->acpi_pdata) { |
| @@ -881,16 +902,9 @@ static int dwc3_qcom_probe(struct platform_device *pdev) · 101 unmodified lines | |||
| 881 | if (ret) | 902 | if (ret) |
| 882 | goto interconnect_exit; | 903 | goto interconnect_exit; |
| 883 | 904 | ||
| 884 | if (device_can_wakeup(&qcom->dwc3->dev)) { | 905 | wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source"); |
| 885 | /* | 906 | device_init_wakeup(&pdev->dev, wakeup_source); |
| 886 | * Setting GENPD_FLAG_ALWAYS_ON flag takes care of keeping | 907 | device_init_wakeup(&qcom->dwc3->dev, wakeup_source); |
| 887 | * genpd on in both runtime suspend and system suspend cases. | ||
| 888 | */ | ||
| 889 | genpd->flags |= GENPD_FLAG_ALWAYS_ON; | ||
| 890 | device_init_wakeup(&pdev->dev, true); | ||
| 891 | } else { | ||
| 892 | genpd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; | ||
| 893 | } | ||
| 894 | 908 | ||
| 895 | qcom->is_suspended = false; | 909 | qcom->is_suspended = false; |
| 896 | pm_runtime_set_active(dev); | 910 | pm_runtime_set_active(dev); |
| @@ -944,39 +958,45 @@ static int dwc3_qcom_remove(struct platform_device *pdev) · 47 unmodified lines | |||
| 944 | static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev) | 958 | static int __maybe_unused dwc3_qcom_pm_suspend(struct device *dev) |
| 945 | { | 959 | { |
| 946 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); | 960 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); |
| 947 | int ret = 0; | 961 | bool wakeup = device_may_wakeup(dev); |
| 962 | int ret; | ||
| 948 | 963 | ||
| 949 | ret = dwc3_qcom_suspend(qcom); | 964 | ret = dwc3_qcom_suspend(qcom, wakeup); |
| 950 | if (!ret) | 965 | if (ret) |
| 951 | qcom->pm_suspended = true; | 966 | return ret; |
| 952 | 967 | ||
| 953 | return ret; | 968 | qcom->pm_suspended = true; |
| 969 | |||
| 970 | return 0; | ||
| 954 | } | 971 | } |
| 955 | 972 | ||
| 956 | static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev) | 973 | static int __maybe_unused dwc3_qcom_pm_resume(struct device *dev) |
| 957 | { | 974 | { |
| 958 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); | 975 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); |
| 976 | bool wakeup = device_may_wakeup(dev); | ||
| 959 | int ret; | 977 | int ret; |
| 960 | 978 | ||
| 961 | ret = dwc3_qcom_resume(qcom); | 979 | ret = dwc3_qcom_resume(qcom, wakeup); |
| 962 | if (!ret) | 980 | if (ret) |
| 963 | qcom->pm_suspended = false; | 981 | return ret; |
| 964 | 982 | ||
| 965 | return ret; | 983 | qcom->pm_suspended = false; |
| 984 | |||
| 985 | return 0; | ||
| 966 | } | 986 | } |
| 967 | 987 | ||
| 968 | static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev) | 988 | static int __maybe_unused dwc3_qcom_runtime_suspend(struct device *dev) |
| 969 | { | 989 | { |
| 970 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); | 990 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); |
| 971 | 991 | ||
| 972 | return dwc3_qcom_suspend(qcom); | 992 | return dwc3_qcom_suspend(qcom, true); |
| 973 | } | 993 | } |
| 974 | 994 | ||
| 975 | static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev) | 995 | static int __maybe_unused dwc3_qcom_runtime_resume(struct device *dev) |
| 976 | { | 996 | { |
| 977 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); | 997 | struct dwc3_qcom *qcom = dev_get_drvdata(dev); |
| 978 | 998 | ||
| 979 | return dwc3_qcom_resume(qcom); | 999 | return dwc3_qcom_resume(qcom, true); |
| 980 | } | 1000 | } |
| 981 | 1001 | ||
| 982 | static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { | 1002 | static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { |
| @@ -2539,9 +2539,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 2538 unmodified lines | |||
| 2539 | 2539 | ||
| 2540 | is_on = !!is_on; | 2540 | is_on = !!is_on; |
| 2541 | 2541 | ||
| 2542 | if (dwc->pullups_connected == is_on) | ||
| 2543 | return 0; | ||
| 2544 | |||
| 2545 | dwc->softconnect = is_on; | 2542 | dwc->softconnect = is_on; |
| 2546 | 2543 | ||
| 2547 | /* | 2544 | /* |
| @@ -2566,6 +2563,11 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 18 unmodified lines | |||
| 2566 | return 0; | 2563 | return 0; |
| 2567 | } | 2564 | } |
| 2568 | 2565 | ||
| 2566 | if (dwc->pullups_connected == is_on) { | ||
| 2567 | pm_runtime_put(dwc->dev); | ||
| 2568 | return 0; | ||
| 2569 | } | ||
| 2570 | |||
| 2569 | if (!is_on) { | 2571 | if (!is_on) { |
| 2570 | ret = dwc3_gadget_soft_disconnect(dwc); | 2572 | ret = dwc3_gadget_soft_disconnect(dwc); |
| 2571 | } else { | 2573 | } else { |
| @@ -11,8 +11,13 @@ · 10 unmodified lines | |||
| 11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
| 12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| 13 | 13 | ||
| 14 | #include "../host/xhci-plat.h" | ||
| 14 | #include "core.h" | 15 | #include "core.h" |
| 15 | 16 | ||
| 17 | static const struct xhci_plat_priv dwc3_xhci_plat_priv = { | ||
| 18 | .quirks = XHCI_SKIP_PHY_INIT, | ||
| 19 | }; | ||
| 20 | |||
| 16 | static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc, | 21 | static void dwc3_host_fill_xhci_irq_res(struct dwc3 *dwc, |
| 17 | int irq, char *name) | 22 | int irq, char *name) |
| 18 | { | 23 | { |
| @@ -92,6 +97,11 @@ int dwc3_host_init(struct dwc3 *dwc) · 73 unmodified lines | |||
| 92 | goto err; | 97 | goto err; |
| 93 | } | 98 | } |
| 94 | 99 | ||
| 100 | ret = platform_device_add_data(xhci, &dwc3_xhci_plat_priv, | ||
| 101 | sizeof(dwc3_xhci_plat_priv)); | ||
| 102 | if (ret) | ||
| 103 | goto err; | ||
| 104 | |||
| 95 | memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); | 105 | memset(props, 0, sizeof(struct property_entry) * ARRAY_SIZE(props)); |
| 96 | 106 | ||
| 97 | if (dwc->usb3_lpm_capable) | 107 | if (dwc->usb3_lpm_capable) |
| @@ -135,4 +145,5 @@ err: · 37 unmodified lines | |||
| 135 | void dwc3_host_exit(struct dwc3 *dwc) | 145 | void dwc3_host_exit(struct dwc3 *dwc) |
| 136 | { | 146 | { |
| 137 | platform_device_unregister(dwc->xhci); | 147 | platform_device_unregister(dwc->xhci); |
| 148 | dwc->xhci = NULL; | ||
| 138 | } | 149 | } |
| @@ -291,6 +291,12 @@ static struct usb_endpoint_descriptor ss_ep_int_desc = { · 290 unmodified lines | |||
| 291 | .bInterval = 4, | 291 | .bInterval = 4, |
| 292 | }; | 292 | }; |
| 293 | 293 | ||
| 294 | static struct usb_ss_ep_comp_descriptor ss_ep_int_desc_comp = { | ||
| 295 | .bLength = sizeof(ss_ep_int_desc_comp), | ||
| 296 | .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, | ||
| 297 | .wBytesPerInterval = cpu_to_le16(6), | ||
| 298 | }; | ||
| 299 | |||
| 294 | /* Audio Streaming OUT Interface - Alt0 */ | 300 | /* Audio Streaming OUT Interface - Alt0 */ |
| 295 | static struct usb_interface_descriptor std_as_out_if0_desc = { | 301 | static struct usb_interface_descriptor std_as_out_if0_desc = { |
| 296 | .bLength = sizeof std_as_out_if0_desc, | 302 | .bLength = sizeof std_as_out_if0_desc, |
| @@ -604,7 +610,8 @@ static struct usb_descriptor_header *ss_audio_desc[] = { · 307 unmodified lines | |||
| 604 | (struct usb_descriptor_header *)&in_feature_unit_desc, | 610 | (struct usb_descriptor_header *)&in_feature_unit_desc, |
| 605 | (struct usb_descriptor_header *)&io_out_ot_desc, | 611 | (struct usb_descriptor_header *)&io_out_ot_desc, |
| 606 | 612 | ||
| 607 | (struct usb_descriptor_header *)&ss_ep_int_desc, | 613 | (struct usb_descriptor_header *)&ss_ep_int_desc, |
| 614 | (struct usb_descriptor_header *)&ss_ep_int_desc_comp, | ||
| 608 | 615 | ||
| 609 | (struct usb_descriptor_header *)&std_as_out_if0_desc, | 616 | (struct usb_descriptor_header *)&std_as_out_if0_desc, |
| 610 | (struct usb_descriptor_header *)&std_as_out_if1_desc, | 617 | (struct usb_descriptor_header *)&std_as_out_if1_desc, |
| @@ -800,6 +807,7 @@ static void setup_headers(struct f_uac2_opts *opts, · 189 unmodified lines | |||
| 800 | struct usb_ss_ep_comp_descriptor *epout_desc_comp = NULL; | 807 | struct usb_ss_ep_comp_descriptor *epout_desc_comp = NULL; |
| 801 | struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL; | 808 | struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL; |
| 802 | struct usb_ss_ep_comp_descriptor *epin_fback_desc_comp = NULL; | 809 | struct usb_ss_ep_comp_descriptor *epin_fback_desc_comp = NULL; |
| 810 | struct usb_ss_ep_comp_descriptor *ep_int_desc_comp = NULL; | ||
| 803 | struct usb_endpoint_descriptor *epout_desc; | 811 | struct usb_endpoint_descriptor *epout_desc; |
| 804 | struct usb_endpoint_descriptor *epin_desc; | 812 | struct usb_endpoint_descriptor *epin_desc; |
| 805 | struct usb_endpoint_descriptor *epin_fback_desc; | 813 | struct usb_endpoint_descriptor *epin_fback_desc; |
| @@ -827,6 +835,7 @@ static void setup_headers(struct f_uac2_opts *opts, · 21 unmodified lines | |||
| 827 | epin_fback_desc = &ss_epin_fback_desc; | 835 | epin_fback_desc = &ss_epin_fback_desc; |
| 828 | epin_fback_desc_comp = &ss_epin_fback_desc_comp; | 836 | epin_fback_desc_comp = &ss_epin_fback_desc_comp; |
| 829 | ep_int_desc = &ss_ep_int_desc; | 837 | ep_int_desc = &ss_ep_int_desc; |
| 838 | ep_int_desc_comp = &ss_ep_int_desc_comp; | ||
| 830 | } | 839 | } |
| 831 | 840 | ||
| 832 | i = 0; | 841 | i = 0; |
| @@ -855,8 +864,11 @@ static void setup_headers(struct f_uac2_opts *opts, · 22 unmodified lines | |||
| 855 | if (EPOUT_EN(opts)) | 864 | if (EPOUT_EN(opts)) |
| 856 | headers[i++] = USBDHDR(&io_out_ot_desc); | 865 | headers[i++] = USBDHDR(&io_out_ot_desc); |
| 857 | 866 | ||
| 858 | if (FUOUT_EN(opts) || FUIN_EN(opts)) | 867 | if (FUOUT_EN(opts) || FUIN_EN(opts)) { |
| 859 | headers[i++] = USBDHDR(ep_int_desc); | 868 | headers[i++] = USBDHDR(ep_int_desc); |
| 869 | if (ep_int_desc_comp) | ||
| 870 | headers[i++] = USBDHDR(ep_int_desc_comp); | ||
| 871 | } | ||
| 860 | 872 | ||
| 861 | if (EPOUT_EN(opts)) { | 873 | if (EPOUT_EN(opts)) { |
| 862 | headers[i++] = USBDHDR(&std_as_out_if0_desc); | 874 | headers[i++] = USBDHDR(&std_as_out_if0_desc); |
| @@ -294,8 +294,10 @@ EXPORT_SYMBOL_GPL(fsg_lun_fsync_sub); · 293 unmodified lines | |||
| 294 | void store_cdrom_address(u8 *dest, int msf, u32 addr) | 294 | void store_cdrom_address(u8 *dest, int msf, u32 addr) |
| 295 | { | 295 | { |
| 296 | if (msf) { | 296 | if (msf) { |
| 297 | /* Convert to Minutes-Seconds-Frames */ | 297 | /* |
| 298 | addr >>= 2; /* Convert to 2048-byte frames */ | 298 | * Convert to Minutes-Seconds-Frames. |
| 299 | * Sector size is already set to 2048 bytes. | ||
| 300 | */ | ||
| 299 | addr += 2*75; /* Lead-in occupies 2 seconds */ | 301 | addr += 2*75; /* Lead-in occupies 2 seconds */ |
| 300 | dest[3] = addr % 75; /* Frames */ | 302 | dest[3] = addr % 75; /* Frames */ |
| 301 | addr /= 75; | 303 | addr /= 75; |
| @@ -736,7 +736,10 @@ int usb_gadget_disconnect(struct usb_gadget *gadget) · 735 unmodified lines | |||
| 736 | ret = gadget->ops->pullup(gadget, 0); | 736 | ret = gadget->ops->pullup(gadget, 0); |
| 737 | if (!ret) { | 737 | if (!ret) { |
| 738 | gadget->connected = 0; | 738 | gadget->connected = 0; |
| 739 | gadget->udc->driver->disconnect(gadget); | 739 | mutex_lock(&udc_lock); |
| 740 | if (gadget->udc->driver) | ||
| 741 | gadget->udc->driver->disconnect(gadget); | ||
| 742 | mutex_unlock(&udc_lock); | ||
| 740 | } | 743 | } |
| 741 | 744 | ||
| 742 | out: | 745 | out: |
| @@ -1489,7 +1492,6 @@ static int gadget_bind_driver(struct device *dev) · 746 unmodified lines | |||
| 1489 | 1492 | ||
| 1490 | usb_gadget_udc_set_speed(udc, driver->max_speed); | 1493 | usb_gadget_udc_set_speed(udc, driver->max_speed); |
| 1491 | 1494 | ||
| 1492 | mutex_lock(&udc_lock); | ||
| 1493 | ret = driver->bind(udc->gadget, driver); | 1495 | ret = driver->bind(udc->gadget, driver); |
| 1494 | if (ret) | 1496 | if (ret) |
| 1495 | goto err_bind; | 1497 | goto err_bind; |
| @@ -1499,7 +1501,6 @@ static int gadget_bind_driver(struct device *dev) · 3 unmodified lines | |||
| 1499 | goto err_start; | 1501 | goto err_start; |
| 1500 | usb_gadget_enable_async_callbacks(udc); | 1502 | usb_gadget_enable_async_callbacks(udc); |
| 1501 | usb_udc_connect_control(udc); | 1503 | usb_udc_connect_control(udc); |
| 1502 | mutex_unlock(&udc_lock); | ||
| 1503 | 1504 | ||
| 1504 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | 1505 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); |
| 1505 | return 0; | 1506 | return 0; |
| @@ -1512,6 +1513,7 @@ static int gadget_bind_driver(struct device *dev) · 6 unmodified lines | |||
| 1512 | dev_err(&udc->dev, "failed to start %s: %d\n", | 1513 | dev_err(&udc->dev, "failed to start %s: %d\n", |
| 1513 | driver->function, ret); | 1514 | driver->function, ret); |
| 1514 | 1515 | ||
| 1516 | mutex_lock(&udc_lock); | ||
| 1515 | udc->driver = NULL; | 1517 | udc->driver = NULL; |
| 1516 | driver->is_bound = false; | 1518 | driver->is_bound = false; |
| 1517 | mutex_unlock(&udc_lock); | 1519 | mutex_unlock(&udc_lock); |
| @@ -1529,7 +1531,6 @@ static void gadget_unbind_driver(struct device *dev) · 11 unmodified lines | |||
| 1529 | 1531 | ||
| 1530 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); | 1532 | kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); |
| 1531 | 1533 | ||
| 1532 | mutex_lock(&udc_lock); | ||
| 1533 | usb_gadget_disconnect(gadget); | 1534 | usb_gadget_disconnect(gadget); |
| 1534 | usb_gadget_disable_async_callbacks(udc); | 1535 | usb_gadget_disable_async_callbacks(udc); |
| 1535 | if (gadget->irq) | 1536 | if (gadget->irq) |
| @@ -1537,6 +1538,7 @@ static void gadget_unbind_driver(struct device *dev) · 1 unmodified line | |||
| 1537 | udc->driver->unbind(gadget); | 1538 | udc->driver->unbind(gadget); |
| 1538 | usb_gadget_udc_stop(udc); | 1539 | usb_gadget_udc_stop(udc); |
| 1539 | 1540 | ||
| 1541 | mutex_lock(&udc_lock); | ||
| 1540 | driver->is_bound = false; | 1542 | driver->is_bound = false; |
| 1541 | udc->driver = NULL; | 1543 | udc->driver = NULL; |
| 1542 | mutex_unlock(&udc_lock); | 1544 | mutex_unlock(&udc_lock); |
| @@ -1612,7 +1614,7 @@ static ssize_t soft_connect_store(struct device *dev, · 69 unmodified lines | |||
| 1612 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 1614 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
| 1613 | ssize_t ret; | 1615 | ssize_t ret; |
| 1614 | 1616 | ||
| 1615 | mutex_lock(&udc_lock); | 1617 | device_lock(&udc->gadget->dev); |
| 1616 | if (!udc->driver) { | 1618 | if (!udc->driver) { |
| 1617 | dev_err(dev, "soft-connect without a gadget driver\n"); | 1619 | dev_err(dev, "soft-connect without a gadget driver\n"); |
| 1618 | ret = -EOPNOTSUPP; | 1620 | ret = -EOPNOTSUPP; |
| @@ -1633,7 +1635,7 @@ static ssize_t soft_connect_store(struct device *dev, · 14 unmodified lines | |||
| 1633 | 1635 | ||
| 1634 | ret = n; | 1636 | ret = n; |
| 1635 | out: | 1637 | out: |
| 1636 | mutex_unlock(&udc_lock); | 1638 | device_unlock(&udc->gadget->dev); |
| 1637 | return ret; | 1639 | return ret; |
| 1638 | } | 1640 | } |
| 1639 | static DEVICE_ATTR_WO(soft_connect); | 1641 | static DEVICE_ATTR_WO(soft_connect); |
| @@ -1652,11 +1654,15 @@ static ssize_t function_show(struct device *dev, struct device_attribute *attr, · 12 unmodified lines | |||
| 1652 | char *buf) | 1654 | char *buf) |
| 1653 | { | 1655 | { |
| 1654 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 1656 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
| 1655 | struct usb_gadget_driver *drv = udc->driver; | 1657 | struct usb_gadget_driver *drv; |
| 1658 | int rc = 0; | ||
| 1656 | 1659 | ||
| 1657 | if (!drv || !drv->function) | 1660 | mutex_lock(&udc_lock); |
| 1658 | return 0; | 1661 | drv = udc->driver; |
| 1659 | return scnprintf(buf, PAGE_SIZE, "%s\n", drv->function); | 1662 | if (drv && drv->function) |
| 1663 | rc = scnprintf(buf, PAGE_SIZE, "%s\n", drv->function); | ||
| 1664 | mutex_unlock(&udc_lock); | ||
| 1665 | return rc; | ||
| 1660 | } | 1666 | } |
| 1661 | static DEVICE_ATTR_RO(function); | 1667 | static DEVICE_ATTR_RO(function); |
| 1662 | 1668 | ||
| @@ -652,7 +652,7 @@ struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd) · 651 unmodified lines | |||
| 652 | * It will release and re-aquire the lock while calling ACPI | 652 | * It will release and re-aquire the lock while calling ACPI |
| 653 | * method. | 653 | * method. |
| 654 | */ | 654 | */ |
| 655 | void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, | 655 | static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, |
| 656 | u16 index, bool on, unsigned long *flags) | 656 | u16 index, bool on, unsigned long *flags) |
| 657 | __must_hold(&xhci->lock) | 657 | __must_hold(&xhci->lock) |
| 658 | { | 658 | { |
| @@ -1648,6 +1648,17 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) · 989 unmodified lines | |||
| 1648 | 1648 | ||
| 1649 | status = bus_state->resuming_ports; | 1649 | status = bus_state->resuming_ports; |
| 1650 | 1650 | ||
| 1651 | /* | ||
| 1652 | * SS devices are only visible to roothub after link training completes. | ||
| 1653 | * Keep polling roothubs for a grace period after xHC start | ||
| 1654 | */ | ||
| 1655 | if (xhci->run_graceperiod) { | ||
| 1656 | if (time_before(jiffies, xhci->run_graceperiod)) | ||
| 1657 | status = 1; | ||
| 1658 | else | ||
| 1659 | xhci->run_graceperiod = 0; | ||
| 1660 | } | ||
| 1661 | |||
| 1651 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; | 1662 | mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC; |
| 1652 | 1663 | ||
| 1653 | /* For each port, did anything change? If so, set that bit in buf. */ | 1664 | /* For each port, did anything change? If so, set that bit in buf. */ |
| @@ -425,7 +425,6 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) · 424 unmodified lines | |||
| 425 | 425 | ||
| 426 | static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) | 426 | static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) |
| 427 | { | 427 | { |
| 428 | u32 extra_cs_count; | ||
| 429 | u32 start_ss, last_ss; | 428 | u32 start_ss, last_ss; |
| 430 | u32 start_cs, last_cs; | 429 | u32 start_cs, last_cs; |
| 431 | 430 | ||
| @@ -461,18 +460,12 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) · 29 unmodified lines | |||
| 461 | if (last_cs > 7) | 460 | if (last_cs > 7) |
| 462 | return -ESCH_CS_OVERFLOW; | 461 | return -ESCH_CS_OVERFLOW; |
| 463 | 462 | ||
| 464 | if (sch_ep->ep_type == ISOC_IN_EP) | ||
| 465 | extra_cs_count = (last_cs == 7) ? 1 : 2; | ||
| 466 | else /* ep_type : INTR IN / INTR OUT */ | ||
| 467 | extra_cs_count = 1; | ||
| 468 | |||
| 469 | cs_count += extra_cs_count; | ||
| 470 | if (cs_count > 7) | 463 | if (cs_count > 7) |
| 471 | cs_count = 7; /* HW limit */ | 464 | cs_count = 7; /* HW limit */ |
| 472 | 465 | ||
| 473 | sch_ep->cs_count = cs_count; | 466 | sch_ep->cs_count = cs_count; |
| 474 | /* one for ss, the other for idle */ | 467 | /* ss, idle are ignored */ |
| 475 | sch_ep->num_budget_microframes = cs_count + 2; | 468 | sch_ep->num_budget_microframes = cs_count; |
| 476 | 469 | ||
| 477 | /* | 470 | /* |
| 478 | * if interval=1, maxp >752, num_budge_micoframe is larger | 471 | * if interval=1, maxp >752, num_budge_micoframe is larger |
| @@ -771,8 +764,8 @@ int xhci_mtk_drop_ep(struct usb_hcd *hcd, struct usb_device *udev, · 292 unmodified lines | |||
| 771 | if (ret) | 764 | if (ret) |
| 772 | return ret; | 765 | return ret; |
| 773 | 766 | ||
| 774 | if (ep->hcpriv) | 767 | /* needn't check @ep->hcpriv, xhci_endpoint_disable set it NULL */ |
| 775 | drop_ep_quirk(hcd, udev, ep); | 768 | drop_ep_quirk(hcd, udev, ep); |
| 776 | 769 | ||
| 777 | return 0; | 770 | return 0; |
| 778 | } | 771 | } |
| @@ -398,12 +398,17 @@ static int xhci_plat_remove(struct platform_device *dev) · 397 unmodified lines | |||
| 398 | pm_runtime_get_sync(&dev->dev); | 398 | pm_runtime_get_sync(&dev->dev); |
| 399 | xhci->xhc_state |= XHCI_STATE_REMOVING; | 399 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
| 400 | 400 | ||
| 401 | usb_remove_hcd(shared_hcd); | 401 | if (shared_hcd) { |
| 402 | xhci->shared_hcd = NULL; | 402 | usb_remove_hcd(shared_hcd); |
| 403 | xhci->shared_hcd = NULL; | ||
| 404 | } | ||
| 405 | |||
| 403 | usb_phy_shutdown(hcd->usb_phy); | 406 | usb_phy_shutdown(hcd->usb_phy); |
| 404 | 407 | ||
| 405 | usb_remove_hcd(hcd); | 408 | usb_remove_hcd(hcd); |
| 406 | usb_put_hcd(shared_hcd); | 409 | |
| 410 | if (shared_hcd) | ||
| 411 | usb_put_hcd(shared_hcd); | ||
| 407 | 412 | ||
| 408 | clk_disable_unprepare(clk); | 413 | clk_disable_unprepare(clk); |
| 409 | clk_disable_unprepare(reg_clk); | 414 | clk_disable_unprepare(reg_clk); |
| @@ -151,9 +151,11 @@ int xhci_start(struct xhci_hcd *xhci) · 150 unmodified lines | |||
| 151 | xhci_err(xhci, "Host took too long to start, " | 151 | xhci_err(xhci, "Host took too long to start, " |
| 152 | "waited %u microseconds.\n", | 152 | "waited %u microseconds.\n", |
| 153 | XHCI_MAX_HALT_USEC); | 153 | XHCI_MAX_HALT_USEC); |
| 154 | if (!ret) | 154 | if (!ret) { |
| 155 | /* clear state flags. Including dying, halted or removing */ | 155 | /* clear state flags. Including dying, halted or removing */ |
| 156 | xhci->xhc_state = 0; | 156 | xhci->xhc_state = 0; |
| 157 | xhci->run_graceperiod = jiffies + msecs_to_jiffies(500); | ||
| 158 | } | ||
| 157 | 159 | ||
| 158 | return ret; | 160 | return ret; |
| 159 | } | 161 | } |
| @@ -791,8 +793,6 @@ static void xhci_stop(struct usb_hcd *hcd) · 631 unmodified lines | |||
| 791 | void xhci_shutdown(struct usb_hcd *hcd) | 793 | void xhci_shutdown(struct usb_hcd *hcd) |
| 792 | { | 794 | { |
| 793 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 795 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
| 794 | unsigned long flags; | ||
| 795 | int i; | ||
| 796 | 796 | ||
| 797 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) | 797 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
| 798 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); | 798 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); |
| @@ -808,21 +808,12 @@ void xhci_shutdown(struct usb_hcd *hcd) · 9 unmodified lines | |||
| 808 | del_timer_sync(&xhci->shared_hcd->rh_timer); | 808 | del_timer_sync(&xhci->shared_hcd->rh_timer); |
| 809 | } | 809 | } |
| 810 | 810 | ||
| 811 | spin_lock_irqsave(&xhci->lock, flags); | 811 | spin_lock_irq(&xhci->lock); |
| 812 | xhci_halt(xhci); | 812 | xhci_halt(xhci); |
| 813 | |||
| 814 | /* Power off USB2 ports*/ | ||
| 815 | for (i = 0; i < xhci->usb2_rhub.num_ports; i++) | ||
| 816 | xhci_set_port_power(xhci, xhci->main_hcd, i, false, &flags); | ||
| 817 | |||
| 818 | /* Power off USB3 ports*/ | ||
| 819 | for (i = 0; i < xhci->usb3_rhub.num_ports; i++) | ||
| 820 | xhci_set_port_power(xhci, xhci->shared_hcd, i, false, &flags); | ||
| 821 | |||
| 822 | /* Workaround for spurious wakeups at shutdown with HSW */ | 813 | /* Workaround for spurious wakeups at shutdown with HSW */ |
| 823 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | 814 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) |
| 824 | xhci_reset(xhci, XHCI_RESET_SHORT_USEC); | 815 | xhci_reset(xhci, XHCI_RESET_SHORT_USEC); |
| 825 | spin_unlock_irqrestore(&xhci->lock, flags); | 816 | spin_unlock_irq(&xhci->lock); |
| 826 | 817 | ||
| 827 | xhci_cleanup_msix(xhci); | 818 | xhci_cleanup_msix(xhci); |
| 828 | 819 | ||
| @@ -1826,7 +1826,7 @@ struct xhci_hcd { · 1825 unmodified lines | |||
| 1826 | 1826 | ||
| 1827 | /* Host controller watchdog timer structures */ | 1827 | /* Host controller watchdog timer structures */ |
| 1828 | unsigned int xhc_state; | 1828 | unsigned int xhc_state; |
| 1829 | 1829 | unsigned long run_graceperiod; | |
| 1830 | u32 command; | 1830 | u32 command; |
| 1831 | struct s3_save s3; | 1831 | struct s3_save s3; |
| 1832 | /* Host controller is dying - not responding to commands. "I'm not dead yet!" | 1832 | /* Host controller is dying - not responding to commands. "I'm not dead yet!" |
| @@ -2196,8 +2196,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, · 363 unmodified lines | |||
| 2196 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); | 2196 | int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); |
| 2197 | int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); | 2197 | int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1); |
| 2198 | struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); | 2198 | struct xhci_hub *xhci_get_rhub(struct usb_hcd *hcd); |
| 2199 | void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, u16 index, | ||
| 2200 | bool on, unsigned long *flags); | ||
| 2201 | 2199 | ||
| 2202 | void xhci_hc_died(struct xhci_hcd *xhci); | 2200 | void xhci_hc_died(struct xhci_hcd *xhci); |
| 2203 | 2201 | ||
| @@ -71,10 +71,7 @@ static int onboard_hub_power_off(struct onboard_hub *hub) · 70 unmodified lines | |||
| 71 | { | 71 | { |
| 72 | int err; | 72 | int err; |
| 73 | 73 | ||
| 74 | if (hub->reset_gpio) { | 74 | gpiod_set_value_cansleep(hub->reset_gpio, 1); |
| 75 | gpiod_set_value_cansleep(hub->reset_gpio, 1); | ||
| 76 | fsleep(hub->pdata->reset_us); | ||
| 77 | } | ||
| 78 | 75 | ||
| 79 | err = regulator_disable(hub->vdd); | 76 | err = regulator_disable(hub->vdd); |
| 80 | if (err) { | 77 | if (err) { |
| @@ -86,7 +86,7 @@ config USB_MUSB_TUSB6010 · 85 unmodified lines | |||
| 86 | tristate "TUSB6010" | 86 | tristate "TUSB6010" |
| 87 | depends on HAS_IOMEM | 87 | depends on HAS_IOMEM |
| 88 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | 88 | depends on ARCH_OMAP2PLUS || COMPILE_TEST |
| 89 | depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules | 89 | depends on NOP_USB_XCEIV!=m || USB_MUSB_HDRC=m |
| 90 | 90 | ||
| 91 | config USB_MUSB_OMAP2PLUS | 91 | config USB_MUSB_OMAP2PLUS |
| 92 | tristate "OMAP2430 and onwards" | 92 | tristate "OMAP2430 and onwards" |
| @@ -97,7 +97,10 @@ struct ch341_private { · 96 unmodified lines | |||
| 97 | u8 mcr; | 97 | u8 mcr; |
| 98 | u8 msr; | 98 | u8 msr; |
| 99 | u8 lcr; | 99 | u8 lcr; |
| 100 | |||
| 100 | unsigned long quirks; | 101 | unsigned long quirks; |
| 102 | u8 version; | ||
| 103 | |||
| 101 | unsigned long break_end; | 104 | unsigned long break_end; |
| 102 | }; | 105 | }; |
| 103 | 106 | ||
| @@ -250,8 +253,12 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev, · 146 unmodified lines | |||
| 250 | /* | 253 | /* |
| 251 | * CH341A buffers data until a full endpoint-size packet (32 bytes) | 254 | * CH341A buffers data until a full endpoint-size packet (32 bytes) |
| 252 | * has been received unless bit 7 is set. | 255 | * has been received unless bit 7 is set. |
| 256 | * | ||
| 257 | * At least one device with version 0x27 appears to have this bit | ||
| 258 | * inverted. | ||
| 253 | */ | 259 | */ |
| 254 | val |= BIT(7); | 260 | if (priv->version > 0x27) |
| 261 | val |= BIT(7); | ||
| 255 | 262 | ||
| 256 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, | 263 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
| 257 | CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, | 264 | CH341_REG_DIVISOR << 8 | CH341_REG_PRESCALER, |
| @@ -265,6 +272,9 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev, · 7 unmodified lines | |||
| 265 | * (stop bits, parity and word length). Version 0x30 and above use | 272 | * (stop bits, parity and word length). Version 0x30 and above use |
| 266 | * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. | 273 | * CH341_REG_LCR only and CH341_REG_LCR2 is always set to zero. |
| 267 | */ | 274 | */ |
| 275 | if (priv->version < 0x30) | ||
| 276 | return 0; | ||
| 277 | |||
| 268 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, | 278 | r = ch341_control_out(dev, CH341_REQ_WRITE_REG, |
| 269 | CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr); | 279 | CH341_REG_LCR2 << 8 | CH341_REG_LCR, lcr); |
| 270 | if (r) | 280 | if (r) |
| @@ -308,7 +318,9 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) · 37 unmodified lines | |||
| 308 | r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size); | 318 | r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size); |
| 309 | if (r) | 319 | if (r) |
| 310 | return r; | 320 | return r; |
| 311 | dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]); | 321 | |
| 322 | priv->version = buffer[0]; | ||
| 323 | dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version); | ||
| 312 | 324 | ||
| 313 | r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0); | 325 | r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0); |
| 314 | if (r < 0) | 326 | if (r < 0) |
| @@ -130,6 +130,7 @@ static const struct usb_device_id id_table[] = { · 129 unmodified lines | |||
| 130 | { USB_DEVICE(0x10C4, 0x83AA) }, /* Mark-10 Digital Force Gauge */ | 130 | { USB_DEVICE(0x10C4, 0x83AA) }, /* Mark-10 Digital Force Gauge */ |
| 131 | { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */ | 131 | { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */ |
| 132 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ | 132 | { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ |
| 133 | { USB_DEVICE(0x10C4, 0x8414) }, /* Decagon USB Cable Adapter */ | ||
| 133 | { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ | 134 | { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ |
| 134 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | 135 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ |
| 135 | { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ | 136 | { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ |
| @@ -1045,6 +1045,8 @@ static const struct usb_device_id id_table_combined[] = { · 1044 unmodified lines | |||
| 1045 | /* IDS GmbH devices */ | 1045 | /* IDS GmbH devices */ |
| 1046 | { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, | 1046 | { USB_DEVICE(IDS_VID, IDS_SI31A_PID) }, |
| 1047 | { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, | 1047 | { USB_DEVICE(IDS_VID, IDS_CM31A_PID) }, |
| 1048 | /* Omron devices */ | ||
| 1049 | { USB_DEVICE(OMRON_VID, OMRON_CS1W_CIF31_PID) }, | ||
| 1048 | /* U-Blox devices */ | 1050 | /* U-Blox devices */ |
| 1049 | { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, | 1051 | { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ZED_PID) }, |
| 1050 | { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, | 1052 | { USB_DEVICE(UBLOX_VID, UBLOX_C099F9P_ODIN_PID) }, |
| @@ -661,6 +661,12 @@ · 660 unmodified lines | |||
| 661 | #define INFINEON_TRIBOARD_TC1798_PID 0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */ | 661 | #define INFINEON_TRIBOARD_TC1798_PID 0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */ |
| 662 | #define INFINEON_TRIBOARD_TC2X7_PID 0x0043 /* DAS JTAG TriBoard TC2X7 V1.0 */ | 662 | #define INFINEON_TRIBOARD_TC2X7_PID 0x0043 /* DAS JTAG TriBoard TC2X7 V1.0 */ |
| 663 | 663 | ||
| 664 | /* | ||
| 665 | * Omron corporation (https://www.omron.com) | ||
| 666 | */ | ||
| 667 | #define OMRON_VID 0x0590 | ||
| 668 | #define OMRON_CS1W_CIF31_PID 0x00b2 | ||
| 669 | |||
| 664 | /* | 670 | /* |
| 665 | * Acton Research Corp. | 671 | * Acton Research Corp. |
| 666 | */ | 672 | */ |
| @@ -253,6 +253,7 @@ static void option_instat_callback(struct urb *urb); · 252 unmodified lines | |||
| 253 | #define QUECTEL_PRODUCT_BG96 0x0296 | 253 | #define QUECTEL_PRODUCT_BG96 0x0296 |
| 254 | #define QUECTEL_PRODUCT_EP06 0x0306 | 254 | #define QUECTEL_PRODUCT_EP06 0x0306 |
| 255 | #define QUECTEL_PRODUCT_EM05G 0x030a | 255 | #define QUECTEL_PRODUCT_EM05G 0x030a |
| 256 | #define QUECTEL_PRODUCT_EM060K 0x030b | ||
| 256 | #define QUECTEL_PRODUCT_EM12 0x0512 | 257 | #define QUECTEL_PRODUCT_EM12 0x0512 |
| 257 | #define QUECTEL_PRODUCT_RM500Q 0x0800 | 258 | #define QUECTEL_PRODUCT_RM500Q 0x0800 |
| 258 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 | 259 | #define QUECTEL_PRODUCT_EC200S_CN 0x6002 |
| @@ -438,6 +439,8 @@ static void option_instat_callback(struct urb *urb); · 179 unmodified lines | |||
| 438 | #define CINTERION_PRODUCT_MV31_2_RMNET 0x00b9 | 439 | #define CINTERION_PRODUCT_MV31_2_RMNET 0x00b9 |
| 439 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 | 440 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 |
| 440 | #define CINTERION_PRODUCT_MV32_WB 0x00f2 | 441 | #define CINTERION_PRODUCT_MV32_WB 0x00f2 |
| 442 | #define CINTERION_PRODUCT_MV32_WA_RMNET 0x00f3 | ||
| 443 | #define CINTERION_PRODUCT_MV32_WB_RMNET 0x00f4 | ||
| 441 | 444 | ||
| 442 | /* Olivetti products */ | 445 | /* Olivetti products */ |
| 443 | #define OLIVETTI_VENDOR_ID 0x0b3c | 446 | #define OLIVETTI_VENDOR_ID 0x0b3c |
| @@ -573,6 +576,10 @@ static void option_instat_callback(struct urb *urb); · 129 unmodified lines | |||
| 573 | #define WETELECOM_PRODUCT_6802 0x6802 | 576 | #define WETELECOM_PRODUCT_6802 0x6802 |
| 574 | #define WETELECOM_PRODUCT_WMD300 0x6803 | 577 | #define WETELECOM_PRODUCT_WMD300 0x6803 |
| 575 | 578 | ||
| 579 | /* OPPO products */ | ||
| 580 | #define OPPO_VENDOR_ID 0x22d9 | ||
| 581 | #define OPPO_PRODUCT_R11 0x276c | ||
| 582 | |||
| 576 | 583 | ||
| 577 | /* Device flags */ | 584 | /* Device flags */ |
| 578 | 585 | ||
| @@ -1138,6 +1145,9 @@ static const struct usb_device_id option_ids[] = { · 559 unmodified lines | |||
| 1138 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, | 1145 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, |
| 1139 | { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), | 1146 | { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), |
| 1140 | .driver_info = RSVD(6) | ZLP }, | 1147 | .driver_info = RSVD(6) | ZLP }, |
| 1148 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, | ||
| 1149 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, | ||
| 1150 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, | ||
| 1141 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), | 1151 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1142 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, | 1152 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1143 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, | 1153 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, |
| @@ -1993,8 +2003,12 @@ static const struct usb_device_id option_ids[] = { · 849 unmodified lines | |||
| 1993 | .driver_info = RSVD(0)}, | 2003 | .driver_info = RSVD(0)}, |
| 1994 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), | 2004 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), |
| 1995 | .driver_info = RSVD(3)}, | 2005 | .driver_info = RSVD(3)}, |
| 2006 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA_RMNET, 0xff), | ||
| 2007 | .driver_info = RSVD(0) }, | ||
| 1996 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), | 2008 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), |
| 1997 | .driver_info = RSVD(3)}, | 2009 | .driver_info = RSVD(3)}, |
| 2010 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB_RMNET, 0xff), | ||
| 2011 | .driver_info = RSVD(0) }, | ||
| 1998 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), | 2012 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), |
| 1999 | .driver_info = RSVD(4) }, | 2013 | .driver_info = RSVD(4) }, |
| 2000 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), | 2014 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), |
| @@ -2155,6 +2169,7 @@ static const struct usb_device_id option_ids[] = { · 154 unmodified lines | |||
| 2155 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ | 2169 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
| 2156 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ | 2170 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ |
| 2157 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ | 2171 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ |
| 2172 | { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) }, | ||
| 2158 | { } /* Terminating entry */ | 2173 | { } /* Terminating entry */ |
| 2159 | }; | 2174 | }; |
| 2160 | MODULE_DEVICE_TABLE(usb, option_ids); | 2175 | MODULE_DEVICE_TABLE(usb, option_ids); |
| @@ -2294,6 +2294,13 @@ UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0000, · 2293 unmodified lines | |||
| 2294 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 2294 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 2295 | US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), | 2295 | US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), |
| 2296 | 2296 | ||
| 2297 | /* Reported by Witold Lipieta <witold.lipieta@thaumatec.com> */ | ||
| 2298 | UNUSUAL_DEV( 0x1fc9, 0x0117, 0x0100, 0x0100, | ||
| 2299 | "NXP Semiconductors", | ||
| 2300 | "PN7462AU", | ||
| 2301 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 2302 | US_FL_IGNORE_RESIDUE ), | ||
| 2303 | |||
| 2297 | /* Supplied with some Castlewood ORB removable drives */ | 2304 | /* Supplied with some Castlewood ORB removable drives */ |
| 2298 | UNUSUAL_DEV( 0x2027, 0xa001, 0x0000, 0x9999, | 2305 | UNUSUAL_DEV( 0x2027, 0xa001, 0x0000, 0x9999, |
| 2299 | "Double-H Technology", | 2306 | "Double-H Technology", |
| @@ -62,6 +62,13 @@ UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, · 61 unmodified lines | |||
| 62 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 62 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 63 | US_FL_IGNORE_UAS), | 63 | US_FL_IGNORE_UAS), |
| 64 | 64 | ||
| 65 | /* Reported-by: Tom Hu <huxiaoying@kylinos.cn> */ | ||
| 66 | UNUSUAL_DEV(0x0b05, 0x1932, 0x0000, 0x9999, | ||
| 67 | "ASUS", | ||
| 68 | "External HDD", | ||
| 69 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 70 | US_FL_IGNORE_UAS), | ||
| 71 | |||
| 65 | /* Reported-by: David Webb <djw@noc.ac.uk> */ | 72 | /* Reported-by: David Webb <djw@noc.ac.uk> */ |
| 66 | UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, | 73 | UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, |
| 67 | "Seagate", | 74 | "Seagate", |
| @@ -99,8 +99,8 @@ static int dp_altmode_configure(struct dp_altmode *dp, u8 con) · 98 unmodified lines | |||
| 99 | case DP_STATUS_CON_UFP_D: | 99 | case DP_STATUS_CON_UFP_D: |
| 100 | case DP_STATUS_CON_BOTH: /* NOTE: First acting as DP source */ | 100 | case DP_STATUS_CON_BOTH: /* NOTE: First acting as DP source */ |
| 101 | conf |= DP_CONF_UFP_U_AS_UFP_D; | 101 | conf |= DP_CONF_UFP_U_AS_UFP_D; |
| 102 | pin_assign = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo) & | 102 | pin_assign = DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo) & |
| 103 | DP_CAP_UFP_D_PIN_ASSIGN(dp->port->vdo); | 103 | DP_CAP_PIN_ASSIGN_DFP_D(dp->port->vdo); |
| 104 | break; | 104 | break; |
| 105 | default: | 105 | default: |
| 106 | break; | 106 | break; |
| @@ -2346,6 +2346,7 @@ static void __exit typec_exit(void) · 2345 unmodified lines | |||
| 2346 | ida_destroy(&typec_index_ida); | 2346 | ida_destroy(&typec_index_ida); |
| 2347 | bus_unregister(&typec_bus); | 2347 | bus_unregister(&typec_bus); |
| 2348 | class_unregister(&typec_mux_class); | 2348 | class_unregister(&typec_mux_class); |
| 2349 | class_unregister(&retimer_class); | ||
| 2349 | } | 2350 | } |
| 2350 | module_exit(typec_exit); | 2351 | module_exit(typec_exit); |
| 2351 | 2352 | ||
| @@ -571,9 +571,11 @@ err_unregister_switch: · 570 unmodified lines | |||
| 571 | 571 | ||
| 572 | static int is_memory(struct acpi_resource *res, void *data) | 572 | static int is_memory(struct acpi_resource *res, void *data) |
| 573 | { | 573 | { |
| 574 | struct resource r; | 574 | struct resource_win win = {}; |
| 575 | struct resource *r = &win.res; | ||
| 575 | 576 | ||
| 576 | return !acpi_dev_resource_memory(res, &r); | 577 | return !(acpi_dev_resource_memory(res, r) || |
| 578 | acpi_dev_resource_address_space(res, &win)); | ||
| 577 | } | 579 | } |
| 578 | 580 | ||
| 579 | /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */ | 581 | /* IOM ACPI IDs and IOM_PORT_STATUS_OFFSET */ |
| @@ -583,6 +585,9 @@ static const struct acpi_device_id iom_acpi_ids[] = { · 3 unmodified lines | |||
| 583 | 585 | ||
| 584 | /* AlderLake */ | 586 | /* AlderLake */ |
| 585 | { "INTC1079", 0x160, }, | 587 | { "INTC1079", 0x160, }, |
| 588 | |||
| 589 | /* Meteor Lake */ | ||
| 590 | { "INTC107A", 0x160, }, | ||
| 586 | {} | 591 | {} |
| 587 | }; | 592 | }; |
| 588 | 593 | ||
| @@ -6320,6 +6320,13 @@ static int tcpm_psy_set_prop(struct power_supply *psy, · 6319 unmodified lines | |||
| 6320 | struct tcpm_port *port = power_supply_get_drvdata(psy); | 6320 | struct tcpm_port *port = power_supply_get_drvdata(psy); |
| 6321 | int ret; | 6321 | int ret; |
| 6322 | 6322 | ||
| 6323 | /* | ||
| 6324 | * All the properties below are related to USB PD. The check needs to be | ||
| 6325 | * property specific when a non-pd related property is added. | ||
| 6326 | */ | ||
| 6327 | if (!port->pd_supported) | ||
| 6328 | return -EOPNOTSUPP; | ||
| 6329 | |||
| 6323 | switch (psp) { | 6330 | switch (psp) { |
| 6324 | case POWER_SUPPLY_PROP_ONLINE: | 6331 | case POWER_SUPPLY_PROP_ONLINE: |
| 6325 | ret = tcpm_psy_set_online(port, val); | 6332 | ret = tcpm_psy_set_online(port, val); |
| @@ -1200,32 +1200,6 @@ out_unlock: · 1199 unmodified lines | |||
| 1200 | return ret; | 1200 | return ret; |
| 1201 | } | 1201 | } |
| 1202 | 1202 | ||
| 1203 | static void ucsi_unregister_connectors(struct ucsi *ucsi) | ||
| 1204 | { | ||
| 1205 | struct ucsi_connector *con; | ||
| 1206 | int i; | ||
| 1207 | |||
| 1208 | if (!ucsi->connector) | ||
| 1209 | return; | ||
| 1210 | |||
| 1211 | for (i = 0; i < ucsi->cap.num_connectors; i++) { | ||
| 1212 | con = &ucsi->connector[i]; | ||
| 1213 | |||
| 1214 | if (!con->wq) | ||
| 1215 | break; | ||
| 1216 | |||
| 1217 | cancel_work_sync(&con->work); | ||
| 1218 | ucsi_unregister_partner(con); | ||
| 1219 | ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); | ||
| 1220 | ucsi_unregister_port_psy(con); | ||
| 1221 | destroy_workqueue(con->wq); | ||
| 1222 | typec_unregister_port(con->port); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | kfree(ucsi->connector); | ||
| 1226 | ucsi->connector = NULL; | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | /** | 1203 | /** |
| 1230 | * ucsi_init - Initialize UCSI interface | 1204 | * ucsi_init - Initialize UCSI interface |
| 1231 | * @ucsi: UCSI to be initialized | 1205 | * @ucsi: UCSI to be initialized |
| @@ -1234,6 +1208,7 @@ static void ucsi_unregister_connectors(struct ucsi *ucsi) · 2 unmodified lines | |||
| 1234 | */ | 1208 | */ |
| 1235 | static int ucsi_init(struct ucsi *ucsi) | 1209 | static int ucsi_init(struct ucsi *ucsi) |
| 1236 | { | 1210 | { |
| 1211 | struct ucsi_connector *con; | ||
| 1237 | u64 command; | 1212 | u64 command; |
| 1238 | int ret; | 1213 | int ret; |
| 1239 | int i; | 1214 | int i; |
| @@ -1264,7 +1239,7 @@ static int ucsi_init(struct ucsi *ucsi) · 24 unmodified lines | |||
| 1264 | } | 1239 | } |
| 1265 | 1240 | ||
| 1266 | /* Allocate the connectors. Released in ucsi_unregister() */ | 1241 | /* Allocate the connectors. Released in ucsi_unregister() */ |
| 1267 | ucsi->connector = kcalloc(ucsi->cap.num_connectors, | 1242 | ucsi->connector = kcalloc(ucsi->cap.num_connectors + 1, |
| 1268 | sizeof(*ucsi->connector), GFP_KERNEL); | 1243 | sizeof(*ucsi->connector), GFP_KERNEL); |
| 1269 | if (!ucsi->connector) { | 1244 | if (!ucsi->connector) { |
| 1270 | ret = -ENOMEM; | 1245 | ret = -ENOMEM; |
| @@ -1288,7 +1263,15 @@ static int ucsi_init(struct ucsi *ucsi) · 17 unmodified lines | |||
| 1288 | return 0; | 1263 | return 0; |
| 1289 | 1264 | ||
| 1290 | err_unregister: | 1265 | err_unregister: |
| 1291 | ucsi_unregister_connectors(ucsi); | 1266 | for (con = ucsi->connector; con->port; con++) { |
| 1267 | ucsi_unregister_partner(con); | ||
| 1268 | ucsi_unregister_altmodes(con, UCSI_RECIPIENT_CON); | ||
| 1269 | ucsi_unregister_port_psy(con); | ||
| 1270 | if (con->wq) | ||
| 1271 | destroy_workqueue(con->wq); | ||
| 1272 | typec_unregister_port(con->port); | ||
| 1273 | con->port = NULL; | ||
| 1274 | } | ||
| 1292 | 1275 | ||
| 1293 | err_reset: | 1276 | err_reset: |
| 1294 | memset(&ucsi->cap, 0, sizeof(ucsi->cap)); | 1277 | memset(&ucsi->cap, 0, sizeof(ucsi->cap)); |
| @@ -1402,6 +1385,7 @@ EXPORT_SYMBOL_GPL(ucsi_register); · 107 unmodified lines | |||
| 1402 | void ucsi_unregister(struct ucsi *ucsi) | 1385 | void ucsi_unregister(struct ucsi *ucsi) |
| 1403 | { | 1386 | { |
| 1404 | u64 cmd = UCSI_SET_NOTIFICATION_ENABLE; | 1387 | u64 cmd = UCSI_SET_NOTIFICATION_ENABLE; |
| 1388 | int i; | ||
| 1405 | 1389 | ||
| 1406 | /* Make sure that we are not in the middle of driver initialization */ | 1390 | /* Make sure that we are not in the middle of driver initialization */ |
| 1407 | cancel_delayed_work_sync(&ucsi->work); | 1391 | cancel_delayed_work_sync(&ucsi->work); |
| @@ -1409,7 +1393,18 @@ void ucsi_unregister(struct ucsi *ucsi) · 1 unmodified line | |||
| 1409 | /* Disable notifications */ | 1393 | /* Disable notifications */ |
| 1410 | ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); | 1394 | ucsi->ops->async_write(ucsi, UCSI_CONTROL, &cmd, sizeof(cmd)); |
| 1411 | 1395 | ||
| 1412 | ucsi_unregister_connectors(ucsi); | 1396 | for (i = 0; i < ucsi->cap.num_connectors; i++) { |
| 1397 | cancel_work_sync(&ucsi->connector[i].work); | ||
| 1398 | ucsi_unregister_partner(&ucsi->connector[i]); | ||
| 1399 | ucsi_unregister_altmodes(&ucsi->connector[i], | ||
| 1400 | UCSI_RECIPIENT_CON); | ||
| 1401 | ucsi_unregister_port_psy(&ucsi->connector[i]); | ||
| 1402 | if (ucsi->connector[i].wq) | ||
| 1403 | destroy_workqueue(ucsi->connector[i].wq); | ||
| 1404 | typec_unregister_port(ucsi->connector[i].port); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | kfree(ucsi->connector); | ||
| 1413 | } | 1408 | } |
| 1414 | EXPORT_SYMBOL_GPL(ucsi_unregister); | 1409 | EXPORT_SYMBOL_GPL(ucsi_unregister); |
| 1415 | 1410 | ||
| @@ -575,6 +575,7 @@ struct usb3_lpm_parameters { · 574 unmodified lines | |||
| 575 | * @devaddr: device address, XHCI: assigned by HW, others: same as devnum | 575 | * @devaddr: device address, XHCI: assigned by HW, others: same as devnum |
| 576 | * @can_submit: URBs may be submitted | 576 | * @can_submit: URBs may be submitted |
| 577 | * @persist_enabled: USB_PERSIST enabled for this device | 577 | * @persist_enabled: USB_PERSIST enabled for this device |
| 578 | * @reset_in_progress: the device is being reset | ||
| 578 | * @have_langid: whether string_langid is valid | 579 | * @have_langid: whether string_langid is valid |
| 579 | * @authorized: policy has said we can use it; | 580 | * @authorized: policy has said we can use it; |
| 580 | * (user space) policy determines if we authorize this device to be | 581 | * (user space) policy determines if we authorize this device to be |
| @@ -662,6 +663,7 @@ struct usb_device { · 81 unmodified lines | |||
| 662 | 663 | ||
| 663 | unsigned can_submit:1; | 664 | unsigned can_submit:1; |
| 664 | unsigned persist_enabled:1; | 665 | unsigned persist_enabled:1; |
| 666 | unsigned reset_in_progress:1; | ||
| 665 | unsigned have_langid:1; | 667 | unsigned have_langid:1; |
| 666 | unsigned authorized:1; | 668 | unsigned authorized:1; |
| 667 | unsigned authenticated:1; | 669 | unsigned authenticated:1; |
| @@ -73,6 +73,11 @@ enum { · 72 unmodified lines | |||
| 73 | #define DP_CAP_USB BIT(7) | 73 | #define DP_CAP_USB BIT(7) |
| 74 | #define DP_CAP_DFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(15, 8)) >> 8) | 74 | #define DP_CAP_DFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(15, 8)) >> 8) |
| 75 | #define DP_CAP_UFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(23, 16)) >> 16) | 75 | #define DP_CAP_UFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(23, 16)) >> 16) |
| 76 | /* Get pin assignment taking plug & receptacle into consideration */ | ||
| 77 | #define DP_CAP_PIN_ASSIGN_UFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \ | ||
| 78 | DP_CAP_UFP_D_PIN_ASSIGN(_cap_) : DP_CAP_DFP_D_PIN_ASSIGN(_cap_)) | ||
| 79 | #define DP_CAP_PIN_ASSIGN_DFP_D(_cap_) ((_cap_ & DP_CAP_RECEPTACLE) ? \ | ||
| 80 | DP_CAP_DFP_D_PIN_ASSIGN(_cap_) : DP_CAP_UFP_D_PIN_ASSIGN(_cap_)) | ||
| 76 | 81 | ||
| 77 | /* DisplayPort Status Update VDO bits */ | 82 | /* DisplayPort Status Update VDO bits */ |
| 78 | #define DP_STATUS_CONNECTION(_status_) ((_status_) & 3) | 83 | #define DP_STATUS_CONNECTION(_status_) ((_status_) & 3) |