[PATCH] Add Prolific new chip: PL2303TB & PL2303N(G)
Add new PID to support PL2303TB (TYPE_HX) Add new PID to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new flow control to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Down/Up Stream reset to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Pull-Up Mode to support PL2303HXD (TYPE_HX) Signed-off-by: Charles Yeh --- drivers/usb/serial/pl2303.c | 116 +--- drivers/usb/serial/pl2303.h | 11 2 files changed, 106 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a4e0d13fc121..dde112f06601 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -46,6 +46,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_TB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GC) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GT) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GL) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GE) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GS) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID), @@ -123,9 +130,11 @@ MODULE_DEVICE_TABLE(usb, id_table); #define VENDOR_WRITE_REQUEST_TYPE 0x40 #define VENDOR_WRITE_REQUEST 0x01 +#define VENDOR_WRITE_NREQUEST 0x80 #define VENDOR_READ_REQUEST_TYPE 0xc0 #define VENDOR_READ_REQUEST0x01 +#define VENDOR_READ_NREQUEST 0x81 #define UART_STATE_INDEX 8 #define UART_STATE_MSR_MASK0x8b @@ -139,11 +148,21 @@ MODULE_DEVICE_TABLE(usb, id_table); #define UART_OVERRUN_ERROR 0x40 #define UART_CTS 0x80 +#define TYPE_HX_READ_OTP_STATUS_REGISTER 0x8484 +#define TYPE_HX_EXTERNAL_PULLUP_MODE 0x08 +#define TYPE_HX_PULLUP_MODE_REG0x09 +#define TYPE_HXN_UART_FLOWCONTROL 0x0A +#define TYPE_HXN_HARDWAREFLOW 0xFA +#define TYPE_HXN_SOFTWAREFLOW 0xEE +#define TYPE_HXN_NOFLOW0xFF +#define TYPE_HXN_RESET_DOWN_UPSTREAM 0x07 + static void pl2303_set_break(struct usb_serial_port *port, bool enable); enum pl2303_type { TYPE_01,/* Type 0 and 1 (difference unknown) */ TYPE_HX,/* HX version of the pl2303 chip */ + TYPE_HXN, /* HXN version of the pl2303 chip */ TYPE_COUNT }; @@ -173,16 +192,26 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = { [TYPE_HX] = { .max_baud_rate =1200, }, + [TYPE_HXN] = { + .max_baud_rate =1200, + }, }; static int pl2303_vendor_read(struct usb_serial *serial, u16 value, unsigned char buf[1]) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; + + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_READ_NREQUEST; + else + request = VENDOR_READ_REQUEST; res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, + request, VENDOR_READ_REQUEST_TYPE, value, 0, buf, 1, 100); if (res != 1) { dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__, @@ -201,12 +230,19 @@ static int pl2303_vendor_read(struct usb_serial *serial, u16 value, static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_WRITE_NREQUEST; + else + request = VENDOR_WRITE_REQUEST; + res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, + request, VENDOR_WRITE_REQUEST_TYPE, value, index, NULL, 0, 100); if (res) { dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__, @@ -286,6 +322,7 @@ static int pl2303_startup(struct usb_serial *serial) struct pl2303_serial_
Re: [PATCH] Add Prolific new chip: PL2303TB & PL2303N(G)
Hi Charles, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on usb-serial/usb-next] [also build test WARNING on v4.20 next-20181224] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Charles-Yeh/Add-Prolific-new-chip-PL2303TB-PL2303N-G/20181225-220256 base: https://git.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial.git usb-next config: x86_64-allmodconfig (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): include/linux/slab.h:332:43: warning: dubious: x & !y include/linux/slab.h:332:43: warning: dubious: x & !y >> drivers/usb/serial/pl2303.c:352:36: warning: restricted __le16 degrades to >> integer include/linux/slab.h:332:43: warning: dubious: x & !y include/linux/slab.h:332:43: warning: dubious: x & !y vim +352 drivers/usb/serial/pl2303.c 324 325 static int pl2303_startup(struct usb_serial *serial) 326 { 327 struct pl2303_serial_private *spriv; 328 enum pl2303_type type = TYPE_01; 329 unsigned char *buf; 330 int res; 331 332 spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); 333 if (!spriv) 334 return -ENOMEM; 335 336 buf = kmalloc(1, GFP_KERNEL); 337 if (!buf) { 338 kfree(spriv); 339 return -ENOMEM; 340 } 341 342 if (serial->dev->descriptor.bDeviceClass == 0x02) 343 type = TYPE_01; /* type 0 */ 344 else if (serial->dev->descriptor.bMaxPacketSize0 == 0x40) 345 type = TYPE_HX; 346 else if (serial->dev->descriptor.bDeviceClass == 0x00) 347 type = TYPE_01; /* type 1 */ 348 else if (serial->dev->descriptor.bDeviceClass == 0xFF) 349 type = TYPE_01; /* type 1 */ 350 dev_dbg(&serial->interface->dev, "device type: %d\n", type); 351 > 352 if (serial->dev->descriptor.bcdUSB == 0x0200) { 353 res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 354 VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, 355 TYPE_HX_READ_OTP_STATUS_REGISTER, 0, buf, 1, 100); 356 if (res != 1) 357 type = TYPE_HXN; 358 } 359 360 spriv->type = &pl2303_type_data[type]; 361 spriv->quirks = (unsigned long)usb_get_serial_data(serial); 362 spriv->quirks |= spriv->type->quirks; 363 364 usb_set_serial_data(serial, spriv); 365 366 if (type != TYPE_HXN) { 367 pl2303_vendor_read(serial, 0x8484, buf); 368 pl2303_vendor_write(serial, 0x0404, 0); 369 pl2303_vendor_read(serial, 0x8484, buf); 370 pl2303_vendor_read(serial, 0x8383, buf); 371 pl2303_vendor_read(serial, 0x8484, buf); 372 pl2303_vendor_write(serial, 0x0404, 1); 373 pl2303_vendor_read(serial, 0x8484, buf); 374 pl2303_vendor_read(serial, 0x8383, buf); 375 pl2303_vendor_write(serial, 0, 1); 376 pl2303_vendor_write(serial, 1, 0); 377 if (spriv->quirks & PL2303_QUIRK_LEGACY) 378 pl2303_vendor_write(serial, 2, 0x24); 379 else 380 pl2303_vendor_write(serial, 2, 0x44); 381 } 382 383 kfree(buf); 384 385 return 0; 386 } 387 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[RFC PATCH v1] leds: fix regression in usbport led trigger
The patch "usb: simplify usbport trigger" together with "leds: triggers: add device attribute support" caused an regression for the usbport trigger. it will no longer enumerate any active usb hub ports under the "ports" directory in the sysfs class directory, if the usb host drivers are fully initialized before the usbport trigger was loaded. The reason is that the usbport driver tries to register the sysfs entries during the activate() callback. And this will fail with -2 / ENOENT because the patch "leds: triggers: add device attribute support" made it so that the sysfs "ports" group was only being added after the activate() callback succeeded. This version of the patch moves the device_add_groups() in front of the call to the trigger's activate() function in order to solve the problem. Cc: Greg Kroah-Hartman Cc: Uwe Kleine-König Cc: Rafał Miłecki Fixes: 6f7b0bad8839 ("usb: simplify usbport trigger") Signed-off-by: Christian Lamparter --- This version of the patch ... of which will be many more?! yeah, device_add_groups() in front of activate() works for the usbport driver since it dynamically registers the entries in "ports". However, if a trigger has a static list of entities this can get more complicated, since I think the sysfs entries will now be available before the activate() call even started and this can end up badly. So, is there any better approach? Introduce a "post_activate()" callback? Or use the event system and make usbport trigger on the KOBJ_CHANGE? use a (delayed) work_struct in usbport to register the ports at a slightly later time? etc... (Note: I'm hitting this on 4.19 too, so whatever the real fix will look like it should be backported) --- drivers/leds/led-triggers.c | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 17d73db1456e..08e7c724a9dc 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -134,6 +134,12 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) led_set_brightness(led_cdev, LED_OFF); } if (trig) { + ret = device_add_groups(led_cdev->dev, trig->groups); + if (ret) { + dev_err(led_cdev->dev, "Failed to add trigger attributes\n"); + goto err_add_groups; + } + write_lock_irqsave(&trig->leddev_list_lock, flags); list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); write_unlock_irqrestore(&trig->leddev_list_lock, flags); @@ -146,12 +152,6 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) if (ret) goto err_activate; - - ret = device_add_groups(led_cdev->dev, trig->groups); - if (ret) { - dev_err(led_cdev->dev, "Failed to add trigger attributes\n"); - goto err_add_groups; - } } if (event) { @@ -165,17 +165,18 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) return 0; -err_add_groups: - +err_activate: + device_remove_groups(led_cdev->dev, trig->groups); if (trig->deactivate) trig->deactivate(led_cdev); -err_activate: led_cdev->trigger = NULL; led_cdev->trigger_data = NULL; write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); list_del(&led_cdev->trig_list); write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); + +err_add_groups: led_set_brightness(led_cdev, LED_OFF); return ret; -- 2.20.1
[PATCH] usb: chipidea: add a check for the availability of next child
of_get_next_available_child returns NULL when no child nodes are found. The fix checks its return value instead of assuming a child is found. Signed-off-by: Kangjie Lu --- drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 880009987460..7dc987b4036a 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -250,6 +250,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); if (ulpi_node) { phy_node = of_get_next_available_child(ulpi_node, NULL); + if (!phy_node) + dev_err(&pdev->dev, "no child nodes found\n"); ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); of_node_put(phy_node); } -- 2.17.2 (Apple Git-113)
[PATCH] usb: dwc3: gadget: Fix the uninitialized link_state when udc starts
Currently the link_state is uninitialized and the default value is 0(U0) before the first time we start the udc, and after we start the udc then stop the udc, the link_state will be undefined. We may have the following warnings if we start the udc again with an undefined link_state: WARNING: CPU: 0 PID: 327 at drivers/usb/dwc3/gadget.c:294 dwc3_send_gadget_ep_cmd+0x304/0x308 dwc3 100e.hidwc3_0: wakeup failed --> -22 [...] Call Trace: [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x84/0x98) [] (dump_stack) from [] (__warn+0xe8/0x100) [] (__warn) from [](warn_slowpath_fmt+0x38/0x48) [] (warn_slowpath_fmt) from [](dwc3_send_gadget_ep_cmd+0x304/0x308) [] (dwc3_send_gadget_ep_cmd) from [](dwc3_ep0_start_trans+0x48/0xf4) [] (dwc3_ep0_start_trans) from [](dwc3_ep0_out_start+0x64/0x80) [] (dwc3_ep0_out_start) from [](__dwc3_gadget_start+0x1e0/0x278) [] (__dwc3_gadget_start) from [](dwc3_gadget_start+0x88/0x10c) [] (dwc3_gadget_start) from [](udc_bind_to_driver+0x88/0xbc) [] (udc_bind_to_driver) from [](usb_gadget_probe_driver+0xf8/0x140) [] (usb_gadget_probe_driver) from [](gadget_dev_desc_UDC_store+0xac/0xc4 [libcomposite]) [] (gadget_dev_desc_UDC_store [libcomposite]) from[] (configfs_write_file+0xd4/0x160) [] (configfs_write_file) from [] (__vfs_write+0x1c/0x114) [] (__vfs_write) from [] (vfs_write+0xa4/0x168) [] (vfs_write) from [] (SyS_write+0x3c/0x90) [] (SyS_write) from [] (ret_fast_syscall+0x0/0x3c) Signed-off-by: Zeng Tao --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 16a6e3c..e18c2a2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1988,6 +1988,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) /* begin to receive SETUP packets */ dwc->ep0state = EP0_SETUP_PHASE; + dwc->link_state = DWC3_LINK_STATE_SS_DIS; dwc3_ep0_out_start(dwc); dwc3_gadget_enable_irq(dwc); -- 2.7.4
RE: [PATCH] usb: chipidea: add a check for the availability of next child
> Signed-off-by: Kangjie Lu > --- > drivers/usb/chipidea/ci_hdrc_msm.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c > b/drivers/usb/chipidea/ci_hdrc_msm.c > index 880009987460..7dc987b4036a 100644 > --- a/drivers/usb/chipidea/ci_hdrc_msm.c > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c > @@ -250,6 +250,8 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) > ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); > if (ulpi_node) { > phy_node = of_get_next_available_child(ulpi_node, NULL); > + if (!phy_node) > + dev_err(&pdev->dev, "no child nodes found\n"); > ci->hsic = of_device_is_compatible(phy_node, > "qcom,usb-hsic-phy"); > of_node_put(phy_node); > } With "ulpi" node, but phy node is not found, I assume the controller can't work properly, we may need to return error value. Add loic to confirm. Peter