From f2fd71db12f8269a0384321c3c71a9312c66b415 Mon Sep 17 00:00:00 2001 From: Suwan Kim Date: Mon, 7 Jan 2019 23:21:11 +0900 Subject: usb: core: Simplify return value of usb_get_configuration() It is better to initialize the return value "result" to -ENOMEM than to 0. And because "result" takes the return value of usb_parse_configuration() which returns 0 for success, setting "result" to 0 at before and after of the for loop is unnecessary. Signed-off-by: Suwan Kim Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 7b5cb28ffb35..4a0945c04b4c 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -800,13 +800,12 @@ int usb_get_configuration(struct usb_device *dev) { struct device *ddev = &dev->dev; int ncfg = dev->descriptor.bNumConfigurations; - int result = 0; + int result = -ENOMEM; unsigned int cfgno, length; unsigned char *bigbuffer; struct usb_config_descriptor *desc; cfgno = 0; - result = -ENOMEM; if (ncfg > USB_MAXCONFIG) { dev_warn(ddev, "too many configurations: %d, " "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); @@ -832,7 +831,6 @@ int usb_get_configuration(struct usb_device *dev) if (!desc) goto err2; - result = 0; for (; cfgno < ncfg; cfgno++) { /* We grab just the first descriptor so we know how long * the whole configuration is */ @@ -889,7 +887,6 @@ int usb_get_configuration(struct usb_device *dev) goto err; } } - result = 0; err: kfree(desc); -- cgit v1.2.3-58-ga151 From d1ab1b842073b148a61e65c747826379e9c3e08e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 4 Jan 2019 17:43:49 +0000 Subject: usb: host: u132-hcd: fix a couple of indentation issues There are two statements that are indented incorrectly and need to be moved to a new line. Fix these. Signed-off-by: Colin Ian King Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 5b8a3d9530c4..934584f0a20a 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2477,7 +2477,8 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); - } urb->error_count = 0; + } + urb->error_count = 0; usb_hcd_giveback_urb(hcd, urb, status); return 0; } else if (list_empty(&endp->urb_more)) { @@ -2982,7 +2983,8 @@ static int u132_remove(struct platform_device *pdev) while (rings-- > 0) { struct u132_ring *ring = &u132->ring[rings]; u132_ring_cancel_work(u132, ring); - } while (endps-- > 0) { + } + while (endps-- > 0) { struct u132_endp *endp = u132->endp[endps]; if (endp) u132_endp_cancel_work(u132, endp); -- cgit v1.2.3-58-ga151 From 8a1dbc8d91d3d1602282c7e6b4222c7759c916fa Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Wed, 2 Jan 2019 09:33:56 +0800 Subject: usb: devio: update max count of DPs per interval for ISOC The failure happened when I tried to send up to 96DPs per an interval for SSP ISOC transations by libusb, this is used to verify SSP ISOC function of USB3 GEN2 controller, so update it as 96DPs. (refer usb3.1r1.0 section 8.12.6 Isochronous Transactions) Signed-off-by: Chunfeng Yun Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index d65566341dd1..a12f2ce8df90 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1564,12 +1564,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb } for (totlen = u = 0; u < number_of_packets; u++) { /* - * arbitrary limit need for USB 3.0 - * bMaxBurst (0~15 allowed, 1~16 packets) - * bmAttributes (bit 1:0, mult 0~2, 1~3 packets) - * sizemax: 1024 * 16 * 3 = 49152 + * arbitrary limit need for USB 3.1 Gen2 + * sizemax: 96 DPs at SSP, 96 * 1024 = 98304 */ - if (isopkt[u].length > 49152) { + if (isopkt[u].length > 98304) { ret = -EINVAL; goto error; } -- cgit v1.2.3-58-ga151 From 00553f322b7ac2a4e774e36fb633265f43651a7c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 30 Dec 2018 16:53:08 +0100 Subject: usb: gadget: udc: reduce indentation Delete tab aligning a statement with the right hand side of a preceding assignment rather than the left hand side. Found with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/snps_udc_core.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index d4da47f4f6f4..3fcded31405a 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -947,15 +947,14 @@ static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) UDC_DMA_STP_STS_BS_HOST_READY, UDC_DMA_STP_STS_BS); - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } + /* clear NAK by writing CNAK */ + if (ep->naking) { + tmp = readl(&ep->regs->ctl); + tmp |= AMD_BIT(UDC_EPCTL_CNAK); + writel(tmp, &ep->regs->ctl); + ep->naking = 0; + UDC_QUEUE_CNAK(ep, ep->num); + } } -- cgit v1.2.3-58-ga151 From 6756f4c375db11af7039985636bddde676615a94 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Jan 2019 09:22:25 -0600 Subject: USB: core: urb: Use struct_size() in kmalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kmalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kmalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index f51750bcd152..0eab79f82ce4 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -70,9 +70,8 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; - urb = kmalloc(sizeof(struct urb) + - iso_packets * sizeof(struct usb_iso_packet_descriptor), - mem_flags); + urb = kmalloc(struct_size(urb, iso_frame_desc, iso_packets), + mem_flags); if (!urb) return NULL; usb_init_urb(urb); -- cgit v1.2.3-58-ga151 From 8eb58994dd96da7055721c68e46b732febe671ae Mon Sep 17 00:00:00 2001 From: Nicolas Saenz Julienne Date: Tue, 8 Jan 2019 16:45:22 +0100 Subject: usb: hub: add retry routine after intr URB submit error The hub sends hot-plug events to the host trough it's interrupt URB. The driver takes care of completing the URB and re-submitting it. Completion errors are handled in the hub_event() work, yet submission errors are ignored, rendering the device unresponsive. All further events are lost. It is fairly hard to find this issue in the wild, since you have to time the USB hot-plug event with the URB submission failure. For instance it could be the system running out of memory or some malfunction in the USB controller driver. Nevertheless, it's pretty reasonable to think it'll happen sometime. One can trigger this issue using eBPF's function override feature (see BCC's inject.py script). This patch adds a retry routine to the event of a submission error. The HUB driver will try to re-submit the URB once every second until it's successful or the HUB is disconnected. As some USB subsystems already take care of this issue, the implementation was inspired from usbhid/hid_core.c's. Signed-off-by: Nicolas Saenz Julienne Reviewed-by: Oliver Neukum Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 43 +++++++++++++++++++++++++++++++++++++------ drivers/usb/core/hub.h | 2 ++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 1d1e61e980f3..713ab85332f8 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -607,6 +607,36 @@ static int hub_port_status(struct usb_hub *hub, int port1, status, change, NULL); } +static void hub_resubmit_irq_urb(struct usb_hub *hub) +{ + unsigned long flags; + int status; + + spin_lock_irqsave(&hub->irq_urb_lock, flags); + + if (hub->quiescing) { + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); + return; + } + + status = usb_submit_urb(hub->urb, GFP_ATOMIC); + if (status && status != -ENODEV && status != -EPERM && + status != -ESHUTDOWN) { + dev_err(hub->intfdev, "resubmit --> %d\n", status); + mod_timer(&hub->irq_urb_retry, jiffies + HZ); + } + + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); +} + +static void hub_retry_irq_urb(struct timer_list *t) +{ + struct usb_hub *hub = from_timer(hub, t, irq_urb_retry); + + hub_resubmit_irq_urb(hub); +} + + static void kick_hub_wq(struct usb_hub *hub) { struct usb_interface *intf; @@ -709,12 +739,7 @@ static void hub_irq(struct urb *urb) kick_hub_wq(hub); resubmit: - if (hub->quiescing) - return; - - status = usb_submit_urb(hub->urb, GFP_ATOMIC); - if (status != 0 && status != -ENODEV && status != -EPERM) - dev_err(hub->intfdev, "resubmit --> %d\n", status); + hub_resubmit_irq_urb(hub); } /* USB 2.0 spec Section 11.24.2.3 */ @@ -1264,10 +1289,13 @@ enum hub_quiescing_type { static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) { struct usb_device *hdev = hub->hdev; + unsigned long flags; int i; /* hub_wq and related activity won't re-trigger */ + spin_lock_irqsave(&hub->irq_urb_lock, flags); hub->quiescing = 1; + spin_unlock_irqrestore(&hub->irq_urb_lock, flags); if (type != HUB_SUSPEND) { /* Disconnect all the children */ @@ -1278,6 +1306,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) } /* Stop hub_wq and related activity */ + del_timer_sync(&hub->irq_urb_retry); usb_kill_urb(hub->urb); if (hub->has_indicators) cancel_delayed_work_sync(&hub->leds); @@ -1810,6 +1839,8 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) INIT_DELAYED_WORK(&hub->leds, led_work); INIT_DELAYED_WORK(&hub->init_work, NULL); INIT_WORK(&hub->events, hub_event); + spin_lock_init(&hub->irq_urb_lock); + timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0); usb_get_intf(intf); usb_get_dev(hdev); diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 4accfb63f7dc..a9e24e4b8df1 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h @@ -69,6 +69,8 @@ struct usb_hub { struct delayed_work leds; struct delayed_work init_work; struct work_struct events; + spinlock_t irq_urb_lock; + struct timer_list irq_urb_retry; struct usb_port **ports; }; -- cgit v1.2.3-58-ga151 From da79ff6e586bd5aaa3bd9c73e56ae9d9183c3263 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Jan 2019 09:40:46 -0600 Subject: xhci: Use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 005e65922608..7fa58c99f126 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1455,8 +1455,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag else num_tds = 1; - urb_priv = kzalloc(sizeof(struct urb_priv) + - num_tds * sizeof(struct xhci_td), mem_flags); + urb_priv = kzalloc(struct_size(urb_priv, td, num_tds), mem_flags); if (!urb_priv) return -ENOMEM; -- cgit v1.2.3-58-ga151 From 6041828fdae09b973d3eed4e2c1ae82ddcf28c58 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Tue, 8 Jan 2019 10:27:00 -0600 Subject: uwb: use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/drp-ie.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c index 1d2a939cfcf8..ed993e363472 100644 --- a/drivers/uwb/drp-ie.c +++ b/drivers/uwb/drp-ie.c @@ -125,9 +125,8 @@ static struct uwb_ie_drp *uwb_drp_ie_alloc(void) { struct uwb_ie_drp *drp_ie; - drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + - UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), - GFP_KERNEL); + drp_ie = kzalloc(struct_size(drp_ie, allocs, UWB_NUM_ZONES), + GFP_KERNEL); if (drp_ie) drp_ie->hdr.element_id = UWB_IE_DRP; return drp_ie; -- cgit v1.2.3-58-ga151 From fecb28291404786b921c3f116aedb17a04fa4884 Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Wed, 16 Jan 2019 10:57:43 +0100 Subject: USB: host: ohci-at91: add sam9x60-sfr definition for ohci Add this SFR compatible definition for the sam9x60 SoC and manage its use in ohci-at91.c driver. Signed-off-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ec6739ef3129..fc35a7993b7b 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -141,8 +141,11 @@ static struct regmap *at91_dt_syscon_sfr(void) struct regmap *regmap; regmap = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); - if (IS_ERR(regmap)) - regmap = NULL; + if (IS_ERR(regmap)) { + regmap = syscon_regmap_lookup_by_compatible("microchip,sam9x60-sfr"); + if (IS_ERR(regmap)) + regmap = NULL; + } return regmap; } -- cgit v1.2.3-58-ga151 From bb09779f879371fcf0b8f07d932451966cd3b3f3 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 17 Jan 2019 16:24:15 +0900 Subject: usb: renesas_usbhs: replace udelay() with usleep_range() According to Documentation/timers/timers-howto.txt, a driver should use usleep_range() instead of udelay() on NON-ATOMIC CONTEXT if "SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms)". Since the .hardware_init() and .power_ctrl() will run on NON-ATOMIC CONTEXT, this patch replaces udelay() with usleep_range(). Signed-off-by: Yoshihiro Shimoda Reviewed-by: Simon Horman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/renesas_usbhs/rcar3.c | 2 +- drivers/usb/renesas_usbhs/rza.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/rcar3.c b/drivers/usb/renesas_usbhs/rcar3.c index aa3820448286..5e730e9b40ef 100644 --- a/drivers/usb/renesas_usbhs/rcar3.c +++ b/drivers/usb/renesas_usbhs/rcar3.c @@ -59,7 +59,7 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev, if (enable) { usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); /* The controller on R-Car Gen3 needs to wait up to 45 usec */ - udelay(45); + usleep_range(45, 90); } else { usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0); } diff --git a/drivers/usb/renesas_usbhs/rza.c b/drivers/usb/renesas_usbhs/rza.c index 5b287257ec11..8c739bd24acd 100644 --- a/drivers/usb/renesas_usbhs/rza.c +++ b/drivers/usb/renesas_usbhs/rza.c @@ -35,7 +35,7 @@ static int usbhs_rza1_hardware_init(struct platform_device *pdev) /* Enable USB PLL (NOTE: ch0 controls both ch0 and ch1) */ usbhs_bset(priv, SYSCFG, UPLLE, UPLLE); - udelay(1000); + usleep_range(1000, 2000); usbhs_bset(priv, SUSPMODE, SUSPM, SUSPM); return 0; -- cgit v1.2.3-58-ga151 From 5d6353fe6984e7c3c41dae47aa38ee9c8ddaebd8 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 16 Jan 2019 15:20:36 +0100 Subject: dt-bindings: usb: usb251xb: add documentation for data lane swapping Add optional binding to allow USB differential-pair (D+/D-) data lane swapping. The swapping can be specified for each port separately, default is no swapping. Signed-off-by: Marco Felsch Reviewed-by: Richard Leitner Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/usb/usb251xb.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/usb251xb.txt b/Documentation/devicetree/bindings/usb/usb251xb.txt index 168ff819e827..17915f64b8ee 100644 --- a/Documentation/devicetree/bindings/usb/usb251xb.txt +++ b/Documentation/devicetree/bindings/usb/usb251xb.txt @@ -64,6 +64,8 @@ Optional properties : - power-on-time-ms : Specifies the time it takes from the time the host initiates the power-on sequence to a port until the port has adequate power. The value is given in ms in a 0 - 510 range (default is 100ms). + - swap-dx-lanes : Specifies the ports which will swap the differential-pair + (D+/D-), default is not-swapped. Examples: usb2512b@2c { @@ -81,4 +83,6 @@ Examples: manufacturer = "Foo"; product = "Foo-Bar"; serial = "1234567890A"; + /* correct misplaced usb connectors on port 1,2 */ + swap-dx-lanes = <1 2>; }; -- cgit v1.2.3-58-ga151 From 02a50b8750464fd1b9b8a80e0539fe469741b370 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Wed, 16 Jan 2019 15:20:37 +0100 Subject: usb: usb251xb: add usb data lane port swap feature The HW can swap the USB differential-pair (D+/D-) for each port separately. So the USB signals can be re-aligned with a misplaced USB connector on the PCB. Signed-off-by: Marco Felsch Reviewed-by: Richard Leitner Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb251xb.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c index a6efb9a72939..4d72b7d1d383 100644 --- a/drivers/usb/misc/usb251xb.c +++ b/drivers/usb/misc/usb251xb.c @@ -337,10 +337,12 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, struct device *dev = hub->dev; struct device_node *np = dev->of_node; int len, err, i; - u32 property_u32 = 0; + u32 port, property_u32 = 0; const u32 *cproperty_u32; const char *cproperty_char; char str[USB251XB_STRING_BUFSIZE / 2]; + struct property *prop; + const __be32 *p; if (!np) { dev_err(dev, "failed to get ofdata\n"); @@ -539,6 +541,16 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, (wchar_t *)hub->serial, USB251XB_STRING_BUFSIZE); + /* + * The datasheet documents the register as 'Port Swap' but in real the + * register controls the USB DP/DM signal swapping for each port. + */ + hub->port_swap = USB251XB_DEF_PORT_SWAP; + of_property_for_each_u32(np, "swap-dx-lanes", prop, p, port) { + if ((port >= 0) && (port <= data->port_cnt)) + hub->port_swap |= BIT(port); + } + /* The following parameters are currently not exposed to devicetree, but * may be as soon as needed. */ @@ -546,7 +558,6 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, hub->boost_up = USB251XB_DEF_BOOST_UP; hub->boost_57 = USB251XB_DEF_BOOST_57; hub->boost_14 = USB251XB_DEF_BOOST_14; - hub->port_swap = USB251XB_DEF_PORT_SWAP; hub->port_map12 = USB251XB_DEF_PORT_MAP_12; hub->port_map34 = USB251XB_DEF_PORT_MAP_34; hub->port_map56 = USB251XB_DEF_PORT_MAP_56; -- cgit v1.2.3-58-ga151 From 972a34e1c7c7ebf39a76f918166e6ee3a9f0aaa2 Mon Sep 17 00:00:00 2001 From: Ran Wang Date: Thu, 17 Jan 2019 09:10:50 +0000 Subject: usb: ehci: fsl: Update register accessing for arm/arm64 platforms arm/arm64's io.h doesn't define clrbits32() and clrsetbits_be32(), which causing compile failure on some Layerscape Platforms (such as LS1021A and LS2012A which also integrates FSL EHCI controller). So use ioread32be()/iowrite32be() instead to make it workable on both powerpc and arm. Signed-off-by: Ran Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 62 ++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0a9fd2022acf..0a867d96c126 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ehci.h" #include "ehci-fsl.h" @@ -50,6 +51,7 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) struct resource *res; int irq; int retval; + u32 tmp; pr_debug("initializing FSL-SOC USB Controller\n"); @@ -114,17 +116,22 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev) } /* Enable USB controller, 83xx or 8536 */ - if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) - clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, 0x4); - + if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) { + tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= 0x4; + iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); + } /* * Enable UTMI phy and program PTS field in UTMI mode before asserting * controller reset for USB Controller version 2.5 */ if (pdata->has_fsl_erratum_a007792) { - clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, CTRL_UTMI_PHY_EN); + tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= CTRL_UTMI_PHY_EN; + iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); + writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1); } @@ -174,7 +181,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, enum fsl_usb2_phy_modes phy_mode, unsigned int port_offset) { - u32 portsc; + u32 portsc, tmp; struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd->regs; struct device *dev = hcd->self.controller; @@ -192,11 +199,16 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, case FSL_USB2_PHY_ULPI: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ - clrbits32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, - ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); + /* turn off UTMI PHY first */ + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~(CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + + /* then turn on ULPI and enable USB controller */ + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); } portsc |= PORT_PTS_ULPI; break; @@ -210,16 +222,21 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, case FSL_USB2_PHY_UTMI_DUAL: if (pdata->have_sysif_regs && pdata->controller_ver) { /* controller version 1.6 or above */ - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, UTMI_PHY_EN); + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= UTMI_PHY_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + mdelay(FSL_UTMI_PHY_DLY); /* Delay for UTMI PHY CLK to become stable - 10ms*/ } /* enable UTMI PHY */ - if (pdata->have_sysif_regs) - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, - CTRL_UTMI_PHY_EN); + if (pdata->have_sysif_regs) { + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= CTRL_UTMI_PHY_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + } portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: @@ -241,9 +258,12 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); - if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) - clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, - CONTROL_REGISTER_W1C_MASK, USB_CTRL_USB_EN); + if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) { + tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); + tmp &= ~CONTROL_REGISTER_W1C_MASK; + tmp |= USB_CTRL_USB_EN; + iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); + } return 0; } -- cgit v1.2.3-58-ga151 From 73855109a92c72e41c424aff15c23a289dde032b Mon Sep 17 00:00:00 2001 From: Ran Wang Date: Thu, 17 Jan 2019 09:10:53 +0000 Subject: usb: kconfig: remove dependency FSL_SOC for ehci fsl driver CONFIG_USB_EHCI_FSL is not dependent on FSL_SOC, it can be built on non-PPC platforms. Signed-off-by: Rajesh Bhagat Signed-off-by: Ran Wang Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 16758b12a5e9..11db5b2a30f2 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -179,8 +179,7 @@ config XPS_USB_HCD_XILINX devices only. config USB_EHCI_FSL - tristate "Support for Freescale PPC on-chip EHCI USB controller" - depends on FSL_SOC + tristate "Support for Freescale on-chip EHCI USB controller" select USB_EHCI_ROOT_HUB_TT ---help--- Variation of ARC USB block used in some Freescale chips. -- cgit v1.2.3-58-ga151 From 5f620bb6439ea8f354cfe4c7d47887df9d3acaf0 Mon Sep 17 00:00:00 2001 From: Ran Wang Date: Thu, 17 Jan 2019 09:10:55 +0000 Subject: drivers: usb :fsl: Remove USB Errata checking code Remove USB errata checking code from driver. Applicability of erratum is retrieved by reading corresponding property in device tree. This property is written during device tree fixup. Besides, replace spaces with tabs to make code aligned. Signed-off-by: Ramneek Mehresh Signed-off-by: Nikhil Badola Signed-off-by: Yinbo Zhu Signed-off-by: Ran Wang Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 7 +------ drivers/usb/host/fsl-mph-dr-of.c | 6 ++++++ include/linux/fsl_devices.h | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0a867d96c126..e3d0c1c25160 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -304,14 +304,9 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) return -EINVAL; if (pdata->operating_mode == FSL_USB2_MPH_HOST) { - unsigned int chip, rev, svr; - - svr = mfspr(SPRN_SVR); - chip = svr >> 16; - rev = (svr >> 4) & 0xf; /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ - if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) + if (pdata->has_fsl_erratum_14 == 1) ehci->has_fsl_port_bug = 1; if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 677f9d592109..4f8b8a08c914 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -225,6 +225,12 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) pdata->has_fsl_erratum_a005697 = of_property_read_bool(np, "fsl,usb_erratum-a005697"); + if (of_get_property(np, "fsl,usb_erratum_14", NULL)) + pdata->has_fsl_erratum_14 = 1; + else + pdata->has_fsl_erratum_14 = 0; + + /* * Determine whether phy_clk_valid needs to be checked * by reading property in device tree diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 60cef8227534..5da56a674f2f 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -98,10 +98,11 @@ struct fsl_usb2_platform_data { unsigned suspended:1; unsigned already_suspended:1; - unsigned has_fsl_erratum_a007792:1; - unsigned has_fsl_erratum_a005275:1; + unsigned has_fsl_erratum_a007792:1; + unsigned has_fsl_erratum_14:1; + unsigned has_fsl_erratum_a005275:1; unsigned has_fsl_erratum_a005697:1; - unsigned check_phy_clk_valid:1; + unsigned check_phy_clk_valid:1; /* register save area for suspend/resume */ u32 pm_command; -- cgit v1.2.3-58-ga151 From 7529b2574a7aaf902f1f8159fbc2a7caa74be559 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sat, 12 Jan 2019 03:54:24 +0800 Subject: USB: Add new USB LPM helpers Use new helpers to make LPM enabling/disabling more clear. This is a preparation to subsequent patch. Signed-off-by: Kai-Heng Feng Cc: stable # after much soaking Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 12 +++++++++++- drivers/usb/core/hub.c | 12 ++++++------ drivers/usb/core/message.c | 2 +- drivers/usb/core/sysfs.c | 5 ++++- drivers/usb/core/usb.h | 10 ++++++++-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 53564386ed57..c276ffc5561f 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1896,7 +1896,7 @@ int usb_runtime_idle(struct device *dev) return -EBUSY; } -int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) { struct usb_hcd *hcd = bus_to_hcd(udev->bus); int ret = -EPERM; @@ -1913,6 +1913,16 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) return ret; } +int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + return usb_set_usb2_hardware_lpm(udev, 1); +} + +int usb_disable_usb2_hardware_lpm(struct usb_device *udev) +{ + return usb_set_usb2_hardware_lpm(udev, 0); +} + #endif /* CONFIG_PM */ struct bus_type usb_bus_type = { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 713ab85332f8..7337e942e9b0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3252,7 +3252,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) /* disable USB2 hardware LPM */ if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); if (usb_disable_ltm(udev)) { dev_err(&udev->dev, "Failed to disable LTM before suspend\n"); @@ -3291,7 +3291,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) err_ltm: /* Try to enable USB2 hardware LPM again */ if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); if (udev->do_remote_wakeup) (void) usb_disable_remote_wakeup(udev); @@ -3575,7 +3575,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) } else { /* Try to enable USB2 hardware LPM */ if (udev->usb2_hw_lpm_capable == 1) - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); /* Try to enable USB3 LTM */ usb_enable_ltm(udev); @@ -4466,7 +4466,7 @@ static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev) if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) || connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) { udev->usb2_hw_lpm_allowed = 1; - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); } } @@ -5681,7 +5681,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) * It will be re-enabled by the enumeration process. */ if (udev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(udev, 0); + usb_disable_usb2_hardware_lpm(udev); /* Disable LPM while we reset the device and reinstall the alt settings. * Device-initiated LPM, and system exit latency settings are cleared @@ -5784,7 +5784,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) done: /* Now that the alt settings are re-installed, enable LTM and LPM. */ - usb_set_usb2_hardware_lpm(udev, 1); + usb_enable_usb2_hardware_lpm(udev); usb_unlocked_enable_lpm(udev); usb_enable_ltm(udev); usb_release_bos_descriptor(udev); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index bfa5eda0cc26..35951aea7f50 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1244,7 +1244,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) } if (dev->usb2_hw_lpm_enabled == 1) - usb_set_usb2_hardware_lpm(dev, 0); + usb_disable_usb2_hardware_lpm(dev); usb_unlocked_disable_lpm(dev); usb_disable_ltm(dev); diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index ea18284dfa9a..7e88fdfe3cf5 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -528,7 +528,10 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev, if (!ret) { udev->usb2_hw_lpm_allowed = value; - ret = usb_set_usb2_hardware_lpm(udev, value); + if (value) + ret = usb_enable_usb2_hardware_lpm(udev); + else + ret = usb_disable_usb2_hardware_lpm(udev); } usb_unlock_device(udev); diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 546a2219454b..d95a5358f73d 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -92,7 +92,8 @@ extern int usb_remote_wakeup(struct usb_device *dev); extern int usb_runtime_suspend(struct device *dev); extern int usb_runtime_resume(struct device *dev); extern int usb_runtime_idle(struct device *dev); -extern int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable); +extern int usb_enable_usb2_hardware_lpm(struct usb_device *udev); +extern int usb_disable_usb2_hardware_lpm(struct usb_device *udev); #else @@ -112,7 +113,12 @@ static inline int usb_autoresume_device(struct usb_device *udev) return 0; } -static inline int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) +static inline int usb_enable_usb2_hardware_lpm(struct usb_device *udev) +{ + return 0; +} + +static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev) { return 0; } -- cgit v1.2.3-58-ga151 From d7a6c0ce8d26412903c7981503bad9e1cc7c45d2 Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Sat, 12 Jan 2019 03:54:25 +0800 Subject: USB: Consolidate LPM checks to avoid enabling LPM twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit USB Bluetooth controller QCA ROME (0cf3:e007) sometimes stops working after S3: [ 165.110742] Bluetooth: hci0: using NVM file: qca/nvm_usb_00000302.bin [ 168.432065] Bluetooth: hci0: Failed to send body at 4 of 1953 (-110) After some experiments, I found that disabling LPM can workaround the issue. On some platforms, the USB power is cut during S3, so the driver uses reset-resume to resume the device. During port resume, LPM gets enabled twice, by usb_reset_and_verify_device() and usb_port_resume(). Consolidate all checks into new LPM helpers to make sure LPM only gets enabled once. Fixes: de68bab4fa96 ("usb: Don't enable USB 2.0 Link PM by default.”) Signed-off-by: Kai-Heng Feng Cc: stable # after much soaking Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 11 ++++++++--- drivers/usb/core/hub.c | 12 ++++-------- drivers/usb/core/message.c | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c276ffc5561f..8987cec9549d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1901,9 +1901,6 @@ static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) struct usb_hcd *hcd = bus_to_hcd(udev->bus); int ret = -EPERM; - if (enable && !udev->usb2_hw_lpm_allowed) - return 0; - if (hcd->driver->set_usb2_hw_lpm) { ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable); if (!ret) @@ -1915,11 +1912,19 @@ static int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable) int usb_enable_usb2_hardware_lpm(struct usb_device *udev) { + if (!udev->usb2_hw_lpm_capable || + !udev->usb2_hw_lpm_allowed || + udev->usb2_hw_lpm_enabled) + return 0; + return usb_set_usb2_hardware_lpm(udev, 1); } int usb_disable_usb2_hardware_lpm(struct usb_device *udev) { + if (!udev->usb2_hw_lpm_enabled) + return 0; + return usb_set_usb2_hardware_lpm(udev, 0); } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 7337e942e9b0..bb0830c72286 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3251,8 +3251,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) } /* disable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(udev); + usb_disable_usb2_hardware_lpm(udev); if (usb_disable_ltm(udev)) { dev_err(&udev->dev, "Failed to disable LTM before suspend\n"); @@ -3290,8 +3289,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) usb_enable_ltm(udev); err_ltm: /* Try to enable USB2 hardware LPM again */ - if (udev->usb2_hw_lpm_capable == 1) - usb_enable_usb2_hardware_lpm(udev); + usb_enable_usb2_hardware_lpm(udev); if (udev->do_remote_wakeup) (void) usb_disable_remote_wakeup(udev); @@ -3574,8 +3572,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) hub_port_logical_disconnect(hub, port1); } else { /* Try to enable USB2 hardware LPM */ - if (udev->usb2_hw_lpm_capable == 1) - usb_enable_usb2_hardware_lpm(udev); + usb_enable_usb2_hardware_lpm(udev); /* Try to enable USB3 LTM */ usb_enable_ltm(udev); @@ -5680,8 +5677,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) /* Disable USB2 hardware LPM. * It will be re-enabled by the enumeration process. */ - if (udev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(udev); + usb_disable_usb2_hardware_lpm(udev); /* Disable LPM while we reset the device and reinstall the alt settings. * Device-initiated LPM, and system exit latency settings are cleared diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 35951aea7f50..4f33eb632a88 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1243,8 +1243,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev->actconfig->interface[i] = NULL; } - if (dev->usb2_hw_lpm_enabled == 1) - usb_disable_usb2_hardware_lpm(dev); + usb_disable_usb2_hardware_lpm(dev); usb_unlocked_disable_lpm(dev); usb_disable_ltm(dev); -- cgit v1.2.3-58-ga151 From 9812de4fb87439427c9b8cf1f3b839731f898afd Mon Sep 17 00:00:00 2001 From: Bharath Vedartham Date: Mon, 21 Jan 2019 16:34:55 +0530 Subject: USB: storage: karma: add whitespace after declarations fixed the checkpatch.pl warning: WARNING: Missing a blank line after declarations Added space after declarations to conform to coding style. Signed-off-by: Bharath Vedartham Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/karma.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index edcf2be0e0eb..395cf8fb5870 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -167,6 +167,7 @@ static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) static void rio_karma_destructor(void *extra) { struct karma_data *data = (struct karma_data *) extra; + kfree(data->recv); } @@ -174,6 +175,7 @@ static int rio_karma_init(struct us_data *us) { int ret = 0; struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); + if (!data) goto out; -- cgit v1.2.3-58-ga151 From cae8dc3b685fb24f61f09b7197c6a383a66cff2c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Jan 2019 09:23:50 +0100 Subject: USB: add missing SPDX lines to Kconfig and Makefiles There are a few remaining drivers/usb/ files that do not have SPDX identifiers in them, all of these are either Kconfig or Makefiles. Add the correct GPL-2.0 identifier to them to make scanning tools happy. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + drivers/usb/atm/Kconfig | 1 + drivers/usb/chipidea/Kconfig | 2 ++ drivers/usb/class/Kconfig | 1 + drivers/usb/core/Kconfig | 1 + drivers/usb/dwc2/Kconfig | 2 ++ drivers/usb/dwc3/Kconfig | 2 ++ drivers/usb/gadget/Kconfig | 1 + drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/udc/Kconfig | 1 + drivers/usb/gadget/udc/bdc/Kconfig | 2 ++ drivers/usb/host/Kconfig | 1 + drivers/usb/image/Kconfig | 1 + drivers/usb/isp1760/Kconfig | 2 ++ drivers/usb/misc/Kconfig | 1 + drivers/usb/misc/sisusbvga/Kconfig | 1 + drivers/usb/mon/Kconfig | 1 + drivers/usb/mtu3/Kconfig | 2 ++ drivers/usb/musb/Kconfig | 1 + drivers/usb/phy/Kconfig | 1 + drivers/usb/roles/Kconfig | 2 ++ drivers/usb/roles/Makefile | 2 ++ drivers/usb/serial/Kconfig | 1 + drivers/usb/storage/Kconfig | 1 + drivers/usb/typec/Kconfig | 1 + drivers/usb/typec/altmodes/Kconfig | 1 + drivers/usb/typec/altmodes/Makefile | 2 ++ drivers/usb/typec/mux/Kconfig | 2 ++ drivers/usb/typec/tcpm/Kconfig | 2 ++ drivers/usb/typec/ucsi/Kconfig | 2 ++ drivers/usb/usbip/Kconfig | 2 ++ drivers/usb/wusbcore/Kconfig | 1 + 32 files changed, 45 insertions(+) diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 70e6c956c23c..e4b27413f528 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB device configuration # diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig index 0f922942a07a..989aaa3b080d 100644 --- a/drivers/usb/atm/Kconfig +++ b/drivers/usb/atm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB/ATM DSL configuration # diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index ee34e9046f7e..eb37ebfcb123 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_CHIPIDEA tristate "ChipIdea Highspeed Dual Role Controller" depends on ((USB_EHCI_HCD && USB_GADGET) || (USB_EHCI_HCD && !USB_GADGET) || (!USB_EHCI_HCD && USB_GADGET)) && HAS_DMA diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig index 971385fe9abc..52f3a531a82f 100644 --- a/drivers/usb/class/Kconfig +++ b/drivers/usb/class/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Class driver configuration # diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 4d75d9a80001..4453e10b9dbb 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Core configuration # diff --git a/drivers/usb/dwc2/Kconfig b/drivers/usb/dwc2/Kconfig index b6a495e98fd8..68d095ae2865 100644 --- a/drivers/usb/dwc2/Kconfig +++ b/drivers/usb/dwc2/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_DWC2 tristate "DesignWare USB2 DRD Core Support" depends on HAS_DMA diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 1a0404fda596..d7e4cab8cdd7 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB || USB_GADGET) && HAS_DMA diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 31cce7805eb2..ec189d7855a0 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 784bf86dad4f..d7c9e4fca895 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 0a16cbd4e528..ef0259a950ba 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Gadget support on a system involves # (a) a peripheral controller, and diff --git a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig index c74ac25dddcd..3e88c7670b2e 100644 --- a/drivers/usb/gadget/udc/bdc/Kconfig +++ b/drivers/usb/gadget/udc/bdc/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_BDC_UDC tristate "Broadcom USB3.0 device controller IP driver(BDC)" depends on USB_GADGET && HAS_DMA diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 11db5b2a30f2..29e8a56d8d82 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Host Controller Drivers # diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig index 320d368c8dac..26c75f309da9 100644 --- a/drivers/usb/image/Kconfig +++ b/drivers/usb/image/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Imaging devices configuration # diff --git a/drivers/usb/isp1760/Kconfig b/drivers/usb/isp1760/Kconfig index c94b7d953399..b1022cc490a2 100644 --- a/drivers/usb/isp1760/Kconfig +++ b/drivers/usb/isp1760/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_ISP1760 tristate "NXP ISP 1760/1761 support" depends on USB || USB_GADGET diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 68d2f2cd17dd..be04c117fe80 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Miscellaneous driver configuration # diff --git a/drivers/usb/misc/sisusbvga/Kconfig b/drivers/usb/misc/sisusbvga/Kconfig index 36bc28c884ad..9b632ab24f03 100644 --- a/drivers/usb/misc/sisusbvga/Kconfig +++ b/drivers/usb/misc/sisusbvga/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config USB_SISUSBVGA tristate "USB 2.0 SVGA dongle support (Net2280/SiS315)" diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 5c6ffa2a612e..48f1b2dadb24 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Monitor configuration # diff --git a/drivers/usb/mtu3/Kconfig b/drivers/usb/mtu3/Kconfig index 40bbf1f53337..bcc23486c4ed 100644 --- a/drivers/usb/mtu3/Kconfig +++ b/drivers/usb/mtu3/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# # For MTK USB3.0 IP config USB_MTU3 diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ad08895e78f9..38ff15da8ac8 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Dual Role (OTG-ready) Controller Drivers # for silicon based on Mentor Graphics INVENTRA designs diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index d7312eed6088..8efeb9699679 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Physical Layer USB driver configuration # diff --git a/drivers/usb/roles/Kconfig b/drivers/usb/roles/Kconfig index e4194ac94510..f8b31aa67526 100644 --- a/drivers/usb/roles/Kconfig +++ b/drivers/usb/roles/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USB_ROLE_SWITCH tristate "USB Role Switch Support" help diff --git a/drivers/usb/roles/Makefile b/drivers/usb/roles/Makefile index c02873206fc1..757a7d2797eb 100644 --- a/drivers/usb/roles/Makefile +++ b/drivers/usb/roles/Makefile @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_USB_ROLE_SWITCH) += roles.o roles-y := class.o obj-$(CONFIG_USB_ROLES_INTEL_XHCI) += intel-xhci-usb-role-switch.o diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 533f127c30ad..7d031911d04e 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Serial device configuration # diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 6fd427284b12..59aad38b490a 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # USB Storage driver configuration # diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 30a847c2089d..89d9193bd1cf 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menuconfig TYPEC tristate "USB Type-C Support" diff --git a/drivers/usb/typec/altmodes/Kconfig b/drivers/usb/typec/altmodes/Kconfig index efef2a64bc51..ef2226eb7a33 100644 --- a/drivers/usb/typec/altmodes/Kconfig +++ b/drivers/usb/typec/altmodes/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 menu "USB Type-C Alternate Mode drivers" diff --git a/drivers/usb/typec/altmodes/Makefile b/drivers/usb/typec/altmodes/Makefile index 5caf094ef71a..eda8456f1c92 100644 --- a/drivers/usb/typec/altmodes/Makefile +++ b/drivers/usb/typec/altmodes/Makefile @@ -1,2 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_TYPEC_DP_ALTMODE) += typec_displayport.o typec_displayport-y := displayport.o diff --git a/drivers/usb/typec/mux/Kconfig b/drivers/usb/typec/mux/Kconfig index 9a954d2b8d8f..01ed0d5e10e8 100644 --- a/drivers/usb/typec/mux/Kconfig +++ b/drivers/usb/typec/mux/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + menu "USB Type-C Multiplexer/DeMultiplexer Switch support" config TYPEC_MUX_PI3USB30532 diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig index f03ea8a61768..72481bbb2af3 100644 --- a/drivers/usb/typec/tcpm/Kconfig +++ b/drivers/usb/typec/tcpm/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config TYPEC_TCPM tristate "USB Type-C Port Controller Manager" depends on USB diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig index 78118883f96c..15c2ac7db02d 100644 --- a/drivers/usb/typec/ucsi/Kconfig +++ b/drivers/usb/typec/ucsi/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config TYPEC_UCSI tristate "USB Type-C Connector System Software Interface driver" depends on !CPU_BIG_ENDIAN diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index a20b65cb6678..2f86b28fa3da 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config USBIP_CORE tristate "USB/IP support" depends on NET diff --git a/drivers/usb/wusbcore/Kconfig b/drivers/usb/wusbcore/Kconfig index 348de1d6726e..12e89189ca7d 100644 --- a/drivers/usb/wusbcore/Kconfig +++ b/drivers/usb/wusbcore/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # Wireless USB Core configuration # -- cgit v1.2.3-58-ga151 From 0b8c0cbc17b90a7c6979c12f8579989724625655 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Jan 2019 09:23:49 +0100 Subject: USB: remove README file This file is really really old, and doesn't make any sense to keep around anymore, so just drop it. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/README | 54 ------------------------------------------------------ 1 file changed, 54 deletions(-) delete mode 100644 drivers/usb/README diff --git a/drivers/usb/README b/drivers/usb/README deleted file mode 100644 index 2144e7dbfa41..000000000000 --- a/drivers/usb/README +++ /dev/null @@ -1,54 +0,0 @@ -To understand all the Linux-USB framework, you'll use these resources: - - * This source code. This is necessarily an evolving work, and - includes kerneldoc that should help you get a current overview. - ("make pdfdocs", and then look at "usb.pdf" for host side and - "gadget.pdf" for peripheral side.) Also, Documentation/usb has - more information. - - * The USB 2.0 specification (from www.usb.org), with supplements - such as those for USB OTG and the various device classes. - The USB specification has a good overview chapter, and USB - peripherals conform to the widely known "Chapter 9". - - * Chip specifications for USB controllers. Examples include - host controllers (on PCs, servers, and more); peripheral - controllers (in devices with Linux firmware, like printers or - cell phones); and hard-wired peripherals like Ethernet adapters. - - * Specifications for other protocols implemented by USB peripheral - functions. Some are vendor-specific; others are vendor-neutral - but just standardized outside of the www.usb.org team. - -Here is a list of what each subdirectory here is, and what is contained in -them. - -core/ - This is for the core USB host code, including the - usbfs files and the hub class driver ("hub_wq"). - -host/ - This is for USB host controller drivers. This - includes UHCI, OHCI, EHCI, and others that might - be used with more specialized "embedded" systems. - -gadget/ - This is for USB peripheral controller drivers and - the various gadget drivers which talk to them. - - -Individual USB driver directories. A new driver should be added to the -first subdirectory in the list below that it fits into. - -image/ - This is for still image drivers, like scanners or - digital cameras. -../input/ - This is for any driver that uses the input subsystem, - like keyboard, mice, touchscreens, tablets, etc. -../media/ - This is for multimedia drivers, like video cameras, - radios, and any other drivers that talk to the v4l - subsystem. -../net/ - This is for network drivers. -serial/ - This is for USB to serial drivers. -storage/ - This is for USB mass-storage drivers. -class/ - This is for all USB device drivers that do not fit - into any of the above categories, and work for a range - of USB Class specified devices. -misc/ - This is for all USB device drivers that do not fit - into any of the above categories. -- cgit v1.2.3-58-ga151 From e36f8b7b7d2a93622c2e17a738e0fda59f64a71c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Jan 2019 09:23:47 +0100 Subject: USB: host: whci: rename Kbuild file We have been using Makefile for well over a decade now, use that name instead of Kbuild. Also, while moving the file, add the proper SPDX identifier at the top of it. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/whci/Kbuild | 12 ------------ drivers/usb/host/whci/Makefile | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) delete mode 100644 drivers/usb/host/whci/Kbuild create mode 100644 drivers/usb/host/whci/Makefile diff --git a/drivers/usb/host/whci/Kbuild b/drivers/usb/host/whci/Kbuild deleted file mode 100644 index 26df0138079e..000000000000 --- a/drivers/usb/host/whci/Kbuild +++ /dev/null @@ -1,12 +0,0 @@ -obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o - -whci-hcd-y := \ - asl.o \ - debug.o \ - hcd.o \ - hw.o \ - init.o \ - int.o \ - pzl.o \ - qset.o \ - wusb.o diff --git a/drivers/usb/host/whci/Makefile b/drivers/usb/host/whci/Makefile new file mode 100644 index 000000000000..859d20079df6 --- /dev/null +++ b/drivers/usb/host/whci/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_USB_WHCI_HCD) += whci-hcd.o + +whci-hcd-y := \ + asl.o \ + debug.o \ + hcd.o \ + hw.o \ + init.o \ + int.o \ + pzl.o \ + qset.o \ + wusb.o -- cgit v1.2.3-58-ga151 From 04389af74d9129703c22609315ee7648d831dca0 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 23 Jan 2019 22:16:56 +0800 Subject: usb: ftdi-elan: remove a unnecessary variable 'empty_packets' The variable 'empty_packets' does not used in any other places except for self increment, so it can be removed. Signed-off-by: YueHaibing Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 76c718ac8c78..b2b05c99e668 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -915,7 +915,6 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi) int bytes_read = 0; int retry_on_empty = 1; int retry_on_timeout = 3; - int empty_packets = 0; read:{ int packet_bytes = 0; int retval = usb_bulk_msg(ftdi->udev, @@ -963,7 +962,6 @@ read:{ } else if (packet_bytes == 2) { unsigned char s0 = ftdi->bulk_in_buffer[0]; unsigned char s1 = ftdi->bulk_in_buffer[1]; - empty_packets += 1; if (s0 == 0x31 && s1 == 0x60) { if (retry_on_empty-- > 0) { goto more; -- cgit v1.2.3-58-ga151 From 3af5d01c29c3285241d45739a945465e4a2b9740 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 22 Jan 2019 16:11:59 +0100 Subject: usb: sisusb_con, convert addr macros to functions Convert SISUSB_VADDR and SISUSB_HADDR to inline functions. Now, there are no more hidden accesses to local variables (vc_data and sisusb_usb_data). sisusb_haddr returns unsigned long from now on, not u16 *, as ulong is what every caller expects -- we can remove some casts. Call sites were aligned to be readable too. Use sisusb_haddr on 4 more places in sisusbcon_blank and sisusbcon_scroll. It was open coded there with [x, y] being [0, 0]. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb_con.c | 78 ++++++++++++++++----------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index c4f017e1d17a..28faf566b8fb 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -356,15 +356,22 @@ sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count) } } -#define SISUSB_VADDR(x,y) \ - ((u16 *)c->vc_origin + \ - (y) * sisusb->sisusb_num_columns + \ - (x)) +static inline void *sisusb_vaddr(const struct sisusb_usb_data *sisusb, + const struct vc_data *c, unsigned int x, unsigned int y) +{ + return (u16 *)c->vc_origin + y * sisusb->sisusb_num_columns + x; +} + +static inline unsigned long sisusb_haddr(const struct sisusb_usb_data *sisusb, + const struct vc_data *c, unsigned int x, unsigned int y) +{ + unsigned long offset = c->vc_origin - sisusb->scrbuf; + + /* 2 bytes per each character */ + offset += 2 * (y * sisusb->sisusb_num_columns + x); -#define SISUSB_HADDR(x,y) \ - ((u16 *)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)) + \ - (y) * sisusb->sisusb_num_columns + \ - (x)) + return sisusb->vrambase + offset; +} /* Interface routine */ static void @@ -382,9 +389,8 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) return; } - - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), 2); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), 2); mutex_unlock(&sisusb->lock); } @@ -408,7 +414,7 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, * because the vt does this AFTER calling us. */ - dest = SISUSB_VADDR(x, y); + dest = sisusb_vaddr(sisusb, c, x, y); for (i = count; i > 0; i--) sisusbcon_writew(sisusbcon_readw(s++), dest++); @@ -418,8 +424,8 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, return; } - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), count * 2); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), count * 2); mutex_unlock(&sisusb->lock); } @@ -446,7 +452,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) * this AFTER calling us. */ - dest = SISUSB_VADDR(x, y); + dest = sisusb_vaddr(sisusb, c, x, y); cols = sisusb->sisusb_num_columns; @@ -472,8 +478,8 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) length = ((height * cols) - x - (cols - width - x)) * 2; - sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), - (long)SISUSB_HADDR(x, y), length); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, x, y), + sisusb_haddr(sisusb, c, x, y), length); mutex_unlock(&sisusb->lock); } @@ -520,9 +526,8 @@ sisusbcon_switch(struct vc_data *c) sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); - sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, - (long)SISUSB_HADDR(0, 0), - length); + sisusb_copy_memory(sisusb, (char *)c->vc_origin, + sisusb_haddr(sisusb, c, 0, 0), length); mutex_unlock(&sisusb->lock); @@ -628,10 +633,8 @@ sisusbcon_blank(struct vc_data *c, int blank, int mode_switch) sisusbcon_memsetw((u16 *)c->vc_origin, c->vc_video_erase_char, c->vc_screenbuf_size); - sisusb_copy_memory(sisusb, - (unsigned char *)c->vc_origin, - (u32)(sisusb->vrambase + - (c->vc_origin - sisusb->scrbuf)), + sisusb_copy_memory(sisusb, (char *)c->vc_origin, + sisusb_haddr(sisusb, c, 0, 0), c->vc_screenbuf_size); sisusb->con_blanked = 1; ret = 1; @@ -796,24 +799,24 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, switch (dir) { case SM_UP: - sisusbcon_memmovew(SISUSB_VADDR(0, t), - SISUSB_VADDR(0, t + lines), + sisusbcon_memmovew(sisusb_vaddr(sisusb, c, 0, t), + sisusb_vaddr(sisusb, c, 0, t + lines), (b - t - lines) * cols * 2); - sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr, - lines * cols * 2); + sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, b - lines), + eattr, lines * cols * 2); break; case SM_DOWN: - sisusbcon_memmovew(SISUSB_VADDR(0, t + lines), - SISUSB_VADDR(0, t), + sisusbcon_memmovew(sisusb_vaddr(sisusb, c, 0, t + lines), + sisusb_vaddr(sisusb, c, 0, t), (b - t - lines) * cols * 2); - sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr, + sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, t), eattr, lines * cols * 2); break; } - sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), - (long)SISUSB_HADDR(0, t), length); + sisusb_copy_memory(sisusb, sisusb_vaddr(sisusb, c, 0, t), + sisusb_haddr(sisusb, c, 0, t), length); mutex_unlock(&sisusb->lock); @@ -830,7 +833,6 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, int copyall = 0; unsigned long oldorigin; unsigned int delta = lines * c->vc_size_row; - u32 originoffset; /* Returning != 0 means we have done the scrolling successfully. * Returning 0 makes vt do the scrolling on its own. @@ -913,23 +915,21 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, break; } - originoffset = (u32)(c->vc_origin - sisusb->scrbuf); - if (copyall) sisusb_copy_memory(sisusb, (char *)c->vc_origin, - (u32)(sisusb->vrambase + originoffset), + sisusb_haddr(sisusb, c, 0, 0), c->vc_screenbuf_size); else if (dir == SM_UP) sisusb_copy_memory(sisusb, (char *)c->vc_origin + c->vc_screenbuf_size - delta, - (u32)sisusb->vrambase + originoffset + + sisusb_haddr(sisusb, c, 0, 0) + c->vc_screenbuf_size - delta, delta); else sisusb_copy_memory(sisusb, (char *)c->vc_origin, - (u32)(sisusb->vrambase + originoffset), + sisusb_haddr(sisusb, c, 0, 0), delta); c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size; -- cgit v1.2.3-58-ga151 From 022e468e1395737e26a54e11e956eb3e29106087 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 22 Jan 2019 16:12:00 +0100 Subject: usb: sisusb_con, cleanup configs There are two macros defined: 1) ifdef CONFIG_COMPAT => define SISUSB_NEW_CONFIG_COMPAT 2) ifdef CONFIG_USB_SISUSBVGA_CON => define INCL_SISUSB_CON Remove the latter and make use only of the former. This removes one layer of obfuscation. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb.c | 32 ++++++++++++++++---------------- drivers/usb/misc/sisusbvga/sisusb.h | 15 +-------------- drivers/usb/misc/sisusbvga/sisusb_con.c | 2 +- drivers/usb/misc/sisusbvga/sisusb_init.c | 4 ++-- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 3198d0477cf8..9560fde621ee 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -53,7 +53,7 @@ #include "sisusb.h" #include "sisusb_init.h" -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON #include #endif @@ -61,7 +61,7 @@ /* Forward declarations / clean-up routines */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON static int sisusb_first_vc; static int sisusb_last_vc; module_param_named(first, sisusb_first_vc, int, 0); @@ -1198,7 +1198,7 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, /* High level: Gfx (indexed) register access */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data) { return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_IO, port, data); @@ -1272,7 +1272,7 @@ int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, /* Write/read video ram */ -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data) { return sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data); @@ -2255,7 +2255,7 @@ static int sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen) } -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Set up default text mode: * - Set text mode (0x03) @@ -2448,7 +2448,7 @@ void sisusb_delete(struct kref *kref) sisusb->sisusb_dev = NULL; sisusb_free_buffers(sisusb); sisusb_free_urbs(sisusb); -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON kfree(sisusb->SiS_Pr); #endif kfree(sisusb); @@ -2844,7 +2844,7 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, case SUCMD_HANDLETEXTMODE: retval = 0; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Gfx core must be initialized, SiS_Pr must exist */ if (!sisusb->gfxinit || !sisusb->SiS_Pr) return -ENODEV; @@ -2860,7 +2860,7 @@ static int sisusb_handle_command(struct sisusb_usb_data *sisusb, #endif break; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON case SUCMD_SETMODE: /* Gfx core must be initialized, SiS_Pr must exist */ if (!sisusb->gfxinit || !sisusb->SiS_Pr) @@ -2944,7 +2944,7 @@ static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) x.sisusb_vramsize = sisusb->vramsize; x.sisusb_minor = sisusb->minor; x.sisusb_fbdevactive = 0; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON x.sisusb_conactive = sisusb->haveconsole ? 1 : 0; #else x.sisusb_conactive = 0; @@ -2975,7 +2975,7 @@ err_out: return retval; } -#ifdef SISUSB_NEW_CONFIG_COMPAT +#ifdef CONFIG_COMPAT static long sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { @@ -2998,7 +2998,7 @@ static const struct file_operations usb_sisusb_fops = { .read = sisusb_read, .write = sisusb_write, .llseek = sisusb_lseek, -#ifdef SISUSB_NEW_CONFIG_COMPAT +#ifdef CONFIG_COMPAT .compat_ioctl = sisusb_compat_ioctl, #endif .unlocked_ioctl = sisusb_ioctl @@ -3091,7 +3091,7 @@ static int sisusb_probe(struct usb_interface *intf, dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs); -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON /* Allocate our SiS_Pr */ sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL); if (!sisusb->SiS_Pr) { @@ -3112,7 +3112,7 @@ static int sisusb_probe(struct usb_interface *intf, if (dev->speed == USB_SPEED_HIGH || dev->speed >= USB_SPEED_SUPER) { int initscreen = 1; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON if (sisusb_first_vc > 0 && sisusb_last_vc > 0 && sisusb_first_vc <= sisusb_last_vc && sisusb_last_vc <= MAX_NR_CONSOLES) @@ -3134,7 +3134,7 @@ static int sisusb_probe(struct usb_interface *intf, dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); #endif -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_console_init(sisusb, sisusb_first_vc, sisusb_last_vc); #endif @@ -3160,7 +3160,7 @@ static void sisusb_disconnect(struct usb_interface *intf) if (!sisusb) return; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_console_exit(sisusb); #endif @@ -3210,7 +3210,7 @@ static struct usb_driver sisusb_driver = { static int __init usb_sisusb_init(void) { -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON sisusb_init_concode(); #endif diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index 20f03ad0ea16..8a5e6bb07d05 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h @@ -38,17 +38,8 @@ #ifndef _SISUSB_H_ #define _SISUSB_H_ -#ifdef CONFIG_COMPAT -#define SISUSB_NEW_CONFIG_COMPAT -#endif - #include -/* For older kernels, support for text consoles is by default - * off. To enable text console support, change the following: - */ -/* #define CONFIG_USB_SISUSBVGA_CON */ - /* Version Information */ #define SISUSB_VERSION 0 @@ -57,10 +48,6 @@ /* Include console and mode switching code? */ -#ifdef CONFIG_USB_SISUSBVGA_CON -#define INCL_SISUSB_CON 1 -#endif - #include #include #include "sisusb_struct.h" @@ -139,7 +126,7 @@ struct sisusb_usb_data { unsigned char gfxinit; /* graphics core initialized? */ unsigned short chipid, chipvendor; unsigned short chiprevision; -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON struct SiS_Private *SiS_Pr; unsigned long scrbuf; unsigned int scrbuf_size; diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 28faf566b8fb..10c15723a7c5 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -70,7 +70,7 @@ #include "sisusb.h" #include "sisusb_init.h" -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON #define sisusbcon_writew(val, addr) (*(addr) = (val)) #define sisusbcon_readw(addr) (*(addr)) diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 6a30e8bd9221..0f7170f5b53f 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -45,7 +45,7 @@ #include "sisusb.h" -#ifdef INCL_SISUSB_CON +#ifdef CONFIG_USB_SISUSBVGA_CON #include "sisusb_init.h" @@ -956,4 +956,4 @@ int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) return SiSUSBSetMode(SiS_Pr, ModeNo); } -#endif /* INCL_SISUSB_CON */ +#endif /* CONFIG_USB_SISUSBVGA_CON */ -- cgit v1.2.3-58-ga151 From 0277531df26ff75f010882ad820ca83e35935a2f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 22 Jan 2019 16:12:01 +0100 Subject: usb: sisusb: let files build only when needed After the previous patch we see, that whole files are ifdeffed depending on CONFIG options. So do not build the files at all if the CONFIG is not enabled. (I.e. move the check from .c to Makefile.) Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/Makefile | 3 ++- drivers/usb/misc/sisusbvga/sisusb_con.c | 7 ------- drivers/usb/misc/sisusbvga/sisusb_init.c | 5 ----- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/Makefile b/drivers/usb/misc/sisusbvga/Makefile index 6ed3a638261a..6551bce68ac5 100644 --- a/drivers/usb/misc/sisusbvga/Makefile +++ b/drivers/usb/misc/sisusbvga/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga.o -sisusbvga-y := sisusb.o sisusb_init.o sisusb_con.o +sisusbvga-y := sisusb.o +sisusbvga-$(CONFIG_USB_SISUSBVGA_CON) += sisusb_con.o sisusb_init.o diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 10c15723a7c5..8e6d1b02e7c2 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -70,8 +70,6 @@ #include "sisusb.h" #include "sisusb_init.h" -#ifdef CONFIG_USB_SISUSBVGA_CON - #define sisusbcon_writew(val, addr) (*(addr) = (val)) #define sisusbcon_readw(addr) (*(addr)) #define sisusbcon_memmovew(d, s, c) memmove(d, s, c) @@ -1534,8 +1532,3 @@ void __init sisusb_init_concode(void) for (i = 0; i < MAX_NR_CONSOLES; i++) mysisusbs[i] = NULL; } - -#endif /* INCL_CON */ - - - diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 0f7170f5b53f..66f6ab5acd97 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c @@ -44,9 +44,6 @@ #include #include "sisusb.h" - -#ifdef CONFIG_USB_SISUSBVGA_CON - #include "sisusb_init.h" /*********************************************/ @@ -955,5 +952,3 @@ int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) return SiSUSBSetMode(SiS_Pr, ModeNo); } - -#endif /* CONFIG_USB_SISUSBVGA_CON */ -- cgit v1.2.3-58-ga151 From 5b25536954bf8761704e05baa05e993d323bff8a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 22 Jan 2019 16:12:02 +0100 Subject: usb: sisusb: remove useless macros and compact the code Remove macros which are only wrappers around standard operations. When we expand them into code, we see that sisusbcon_memsetw can simply use memset16 and sisusbcon_putcs can just call memcpy. So make the code compact. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb_con.c | 48 +++++++++++---------------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 8e6d1b02e7c2..cd0155310fea 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -70,11 +70,6 @@ #include "sisusb.h" #include "sisusb_init.h" -#define sisusbcon_writew(val, addr) (*(addr) = (val)) -#define sisusbcon_readw(addr) (*(addr)) -#define sisusbcon_memmovew(d, s, c) memmove(d, s, c) -#define sisusbcon_memcpyw(d, s, c) memcpy(d, s, c) - /* vc_data -> sisusb conversion table */ static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES]; @@ -84,9 +79,7 @@ static const struct consw sisusb_con; static inline void sisusbcon_memsetw(u16 *s, u16 c, unsigned int count) { - count /= 2; - while (count--) - sisusbcon_writew(c, s++); + memset16(s, c, count / 2); } static inline void @@ -344,13 +337,11 @@ sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count) */ while (count--) { - u16 a = sisusbcon_readw(p); - - a = ((a) & 0x88ff) | - (((a) & 0x7000) >> 4) | - (((a) & 0x0700) << 4); + u16 a = *p; - sisusbcon_writew(a, p++); + *p++ = ((a) & 0x88ff) | + (((a) & 0x7000) >> 4) | + (((a) & 0x0700) << 4); } } @@ -399,8 +390,6 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, int count, int y, int x) { struct sisusb_usb_data *sisusb; - u16 *dest; - int i; sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num); if (!sisusb) @@ -412,10 +401,7 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, * because the vt does this AFTER calling us. */ - dest = sisusb_vaddr(sisusb, c, x, y); - - for (i = count; i > 0; i--) - sisusbcon_writew(sisusbcon_readw(s++), dest++); + memcpy(sisusb_vaddr(sisusb, c, x, y), s, count * 2); if (sisusb_is_inactive(c, sisusb)) { mutex_unlock(&sisusb->lock); @@ -521,8 +507,7 @@ sisusbcon_switch(struct vc_data *c) (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Restore the screen contents */ - sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, - length); + memcpy((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf, length); sisusb_copy_memory(sisusb, (char *)c->vc_origin, sisusb_haddr(sisusb, c, 0, 0), length); @@ -559,8 +544,7 @@ sisusbcon_save_screen(struct vc_data *c) (int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin)); /* Save the screen contents to vc's private buffer */ - sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, - length); + memcpy((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin, length); mutex_unlock(&sisusb->lock); } @@ -797,7 +781,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, switch (dir) { case SM_UP: - sisusbcon_memmovew(sisusb_vaddr(sisusb, c, 0, t), + memmove(sisusb_vaddr(sisusb, c, 0, t), sisusb_vaddr(sisusb, c, 0, t + lines), (b - t - lines) * cols * 2); sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, b - lines), @@ -805,7 +789,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, break; case SM_DOWN: - sisusbcon_memmovew(sisusb_vaddr(sisusb, c, 0, t + lines), + memmove(sisusb_vaddr(sisusb, c, 0, t + lines), sisusb_vaddr(sisusb, c, 0, t), (b - t - lines) * cols * 2); sisusbcon_memsetw(sisusb_vaddr(sisusb, c, 0, t), eattr, @@ -874,7 +858,7 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, if (c->vc_scr_end + delta >= sisusb->scrbuf + sisusb->scrbuf_size) { - sisusbcon_memcpyw((u16 *)sisusb->scrbuf, + memcpy((u16 *)sisusb->scrbuf, (u16 *)(oldorigin + delta), c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf; @@ -892,12 +876,10 @@ sisusbcon_scroll(struct vc_data *c, unsigned int t, unsigned int b, case SM_DOWN: if (oldorigin - delta < sisusb->scrbuf) { - sisusbcon_memmovew((u16 *)(sisusb->scrbuf + - sisusb->scrbuf_size - - c->vc_screenbuf_size + - delta), - (u16 *)oldorigin, - c->vc_screenbuf_size - delta); + memmove((void *)sisusb->scrbuf + sisusb->scrbuf_size - + c->vc_screenbuf_size + delta, + (u16 *)oldorigin, + c->vc_screenbuf_size - delta); c->vc_origin = sisusb->scrbuf + sisusb->scrbuf_size - c->vc_screenbuf_size; -- cgit v1.2.3-58-ga151 From 2c904963b1dd2acd4bc785b6c72e10a6283c2081 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Thu, 24 Jan 2019 14:46:42 -0700 Subject: usbip: Fix vhci_urb_enqueue() URB null transfer buffer error path Fix vhci_urb_enqueue() to print debug msg and return error instead of failing with BUG_ON. Signed-off-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vhci_hcd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 1e592ec94ba4..f46ee1fefe02 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -702,8 +702,10 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag } vdev = &vhci_hcd->vdev[portnum-1]; - /* patch to usb_sg_init() is in 2.5.60 */ - BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); + if (!urb->transfer_buffer && urb->transfer_buffer_length) { + dev_dbg(dev, "Null URB transfer buffer\n"); + return -EINVAL; + } spin_lock_irqsave(&vhci->lock, flags); -- cgit v1.2.3-58-ga151 From f84f9ae32fbf026ecc6d7a5e546cac0963ae994e Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 21 Jan 2019 15:33:35 +0100 Subject: usb: misc: usb3503: Add system sleep support in non-I2C mode USB3503 chip can be used without any I2C connection, what is handled by a simple platform device driver. Add support for resetting the chip (via GPIO lines) during system suspend/resume cycle by adding calls to existing suspend/resume functions used for E2C device. Signed-off-by: Marek Szyprowski Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usb3503.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/usb/misc/usb3503.c b/drivers/usb/misc/usb3503.c index f723f7b8c9ac..d5141aa79dd4 100644 --- a/drivers/usb/misc/usb3503.c +++ b/drivers/usb/misc/usb3503.c @@ -355,11 +355,8 @@ static int usb3503_platform_remove(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP -static int usb3503_i2c_suspend(struct device *dev) +static int usb3503_suspend(struct usb3503 *hub) { - struct i2c_client *client = to_i2c_client(dev); - struct usb3503 *hub = i2c_get_clientdata(client); - usb3503_switch_mode(hub, USB3503_MODE_STANDBY); if (hub->clk) @@ -368,11 +365,8 @@ static int usb3503_i2c_suspend(struct device *dev) return 0; } -static int usb3503_i2c_resume(struct device *dev) +static int usb3503_resume(struct usb3503 *hub) { - struct i2c_client *client = to_i2c_client(dev); - struct usb3503 *hub = i2c_get_clientdata(client); - if (hub->clk) clk_prepare_enable(hub->clk); @@ -380,11 +374,38 @@ static int usb3503_i2c_resume(struct device *dev) return 0; } + +static int usb3503_i2c_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return usb3503_suspend(i2c_get_clientdata(client)); +} + +static int usb3503_i2c_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + + return usb3503_resume(i2c_get_clientdata(client)); +} + +static int usb3503_platform_suspend(struct device *dev) +{ + return usb3503_suspend(dev_get_drvdata(dev)); +} + +static int usb3503_platform_resume(struct device *dev) +{ + return usb3503_resume(dev_get_drvdata(dev)); +} #endif static SIMPLE_DEV_PM_OPS(usb3503_i2c_pm_ops, usb3503_i2c_suspend, usb3503_i2c_resume); +static SIMPLE_DEV_PM_OPS(usb3503_platform_pm_ops, usb3503_platform_suspend, + usb3503_platform_resume); + static const struct i2c_device_id usb3503_id[] = { { USB3503_I2C_NAME, 0 }, { } @@ -415,6 +436,7 @@ static struct platform_driver usb3503_platform_driver = { .driver = { .name = USB3503_I2C_NAME, .of_match_table = of_match_ptr(usb3503_of_match), + .pm = &usb3503_platform_pm_ops, }, .probe = usb3503_platform_probe, .remove = usb3503_platform_remove, -- cgit v1.2.3-58-ga151 From 9997ab35f4284ea5bd07768797929d1d646064c8 Mon Sep 17 00:00:00 2001 From: Jun Li Date: Tue, 22 Jan 2019 09:00:24 +0000 Subject: usb: typec: tpcm: improve error handling of tcpm_register_port Remove debugfs if tcpm register port fails. Signed-off-by: Li Jun Reviewed-by: Guenter Roeck Reviewed-by: Heikki Krogerus Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 4bc29b586698..f1d3e54210df 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -4810,12 +4810,12 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) err = devm_tcpm_psy_register(port); if (err) - goto out_destroy_wq; + goto out_role_sw_put; port->typec_port = typec_register_port(port->dev, &port->typec_caps); if (IS_ERR(port->typec_port)) { err = PTR_ERR(port->typec_port); - goto out_destroy_wq; + goto out_role_sw_put; } if (tcpc->config && tcpc->config->alt_modes) { @@ -4848,8 +4848,10 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) tcpm_log(port, "%s: registered", dev_name(dev)); return port; -out_destroy_wq: +out_role_sw_put: usb_role_switch_put(port->role_sw); +out_destroy_wq: + tcpm_debugfs_exit(port); destroy_workqueue(port->wq); return ERR_PTR(err); } -- cgit v1.2.3-58-ga151 From ac626ff960624d81442a3ec4a3e71a9e929e98ae Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 23 Jan 2019 22:16:57 +0800 Subject: usb: ftdi-elan: Fix if == else warnings in ftdi_elan_respond_engine Fixes the following coccinelle warning: ./drivers/usb/misc/ftdi-elan.c:972:10-12: WARNING: possible condition with no effect (if == else) ./drivers/usb/misc/ftdi-elan.c:983:9-11: WARNING: possible condition with no effect (if == else) ./drivers/usb/misc/ftdi-elan.c:2052:11-13: WARNING: possible condition with no effect (if == else) All these else/if branches just do the same thing actually as the last else branch, So it can be merged into the last branch. Signed-off-by: YueHaibing Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ftdi-elan.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index b2b05c99e668..257efacf3551 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c @@ -959,30 +959,6 @@ read:{ dev_err(&ftdi->udev->dev, "error = %d with packet_bytes = %d with total %d bytes%s\n", retval, packet_bytes, bytes_read, diag); return retval; - } else if (packet_bytes == 2) { - unsigned char s0 = ftdi->bulk_in_buffer[0]; - unsigned char s1 = ftdi->bulk_in_buffer[1]; - if (s0 == 0x31 && s1 == 0x60) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } else if (s0 == 0x31 && s1 == 0x00) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } else { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; - } - } else if (packet_bytes == 1) { - if (retry_on_empty-- > 0) { - goto more; - } else - return 0; } else { if (retry_on_empty-- > 0) { goto more; -- cgit v1.2.3-58-ga151 From a49e1abf07701600ad5ef990e56d676cbab91bf5 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 24 Jan 2019 13:48:39 +0000 Subject: USB: serial: cp210x: support all gpios on CP2102N QFN28 package The QFN28 package version of the CP2102N has three additional gpio pins. Add support for these. Signed-off-by: Mans Rullgard Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index c0777a374a88..336a3c0f9f2c 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -1574,12 +1574,6 @@ static int cp2102n_gpioconf_init(struct usb_serial *serial) if (config_version != 0x01) return -ENOTSUPP; - /* - * We only support 4 GPIOs even on the QFN28 package, because - * config locations of GPIOs 4-6 determined using reverse - * engineering revealed conflicting offsets with other - * documented functions. So we'll just play it safe for now. - */ priv->gc.ngpio = 4; /* @@ -1594,6 +1588,19 @@ static int cp2102n_gpioconf_init(struct usb_serial *serial) /* 0 indicates GPIO mode, 1 is alternate function */ priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f; + if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN28) { + /* + * For the QFN28 package, GPIO4-6 are controlled by + * the low three bits of the mode/latch fields. + * Contrary to the document linked above, the bits for + * the SUSPEND pins are elsewhere. No alternate + * function is available for these pins. + */ + priv->gc.ngpio = 7; + gpio_latch |= (gpio_rst_latch & 7) << 4; + priv->gpio_pushpull |= (gpio_pushpull & 7) << 4; + } + /* * The CP2102N does not strictly has input and output pin modes, * it only knows open-drain and push-pull modes which is set at -- cgit v1.2.3-58-ga151 From d7c3eeffbc55ad462e6447902ffa752c7e9d6aae Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Wed, 23 Jan 2019 22:31:36 +0800 Subject: usb: gadget: Remove dead branch code 'num' is a u8 variable, it never greater than 255, So the if branch is dead code and can be removed. Signed-off-by: YueHaibing Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc_configfs.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index bc1e2af566c3..8fe85cb4e87e 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -1570,10 +1570,6 @@ uvcg_uncompressed_##cname##_store(struct config_item *item, \ if (ret) \ goto end; \ \ - if (num > 255) { \ - ret = -EINVAL; \ - goto end; \ - } \ u->desc.aname = num; \ ret = len; \ end: \ @@ -1767,10 +1763,6 @@ uvcg_mjpeg_##cname##_store(struct config_item *item, \ if (ret) \ goto end; \ \ - if (num > 255) { \ - ret = -EINVAL; \ - goto end; \ - } \ u->desc.aname = num; \ ret = len; \ end: \ -- cgit v1.2.3-58-ga151 From b266d6e496a8c61a2d120960678b1bd97803a0ad Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 21 Jan 2019 14:32:46 -0700 Subject: dt-bindings: usb: Add support for msm8998 msm8998 USB has a dwc3 controller just like the existing sdm845 support. Signed-off-by: Jeffrey Hugo Reviewed-by: Bjorn Andersson Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/qcom,dwc3.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt index 95afdcf3c337..cb695aa3fba4 100644 --- a/Documentation/devicetree/bindings/usb/qcom,dwc3.txt +++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.txt @@ -4,6 +4,7 @@ Required properties: - compatible: Compatible list, contains "qcom,dwc3" "qcom,msm8996-dwc3" for msm8996 SOC. + "qcom,msm8998-dwc3" for msm8998 SOC. "qcom,sdm845-dwc3" for sdm845 SOC. - reg: Offset and length of register set for QSCRATCH wrapper - power-domains: specifies a phandle to PM domain provider node -- cgit v1.2.3-58-ga151 From 54c9da1bcec44d234a2c6f55c2935d0980a50286 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 21 Jan 2019 14:33:08 -0700 Subject: usb: dwc3: qcom: Add support for MSM8998 Add a MSM8998 specific DT compatible so that we can properly bind to the device and enable the USB controller. Reviewed-by: Andy Gross Reviewed-by: Bjorn Andersson Signed-off-by: Jeffrey Hugo Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-qcom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index a6d0203e40b6..184df4daa590 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -595,6 +595,7 @@ static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { static const struct of_device_id dwc3_qcom_of_match[] = { { .compatible = "qcom,dwc3" }, { .compatible = "qcom,msm8996-dwc3" }, + { .compatible = "qcom,msm8998-dwc3" }, { .compatible = "qcom,sdm845-dwc3" }, { } }; -- cgit v1.2.3-58-ga151 From 1c1a3ddae9782ba748f5ceb775ed13ef554e8994 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 17 Jan 2019 16:24:15 +0900 Subject: usb: renesas_usbhs: replace udelay() with usleep_range() According to Documentation/timers/timers-howto.txt, a driver should use usleep_range() instead of udelay() on NON-ATOMIC CONTEXT if "SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms)". Since the .hardware_init() and .power_ctrl() will run on NON-ATOMIC CONTEXT, this patch replaces udelay() with usleep_range(). Reviewed-by: Simon Horman Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/rcar3.c | 2 +- drivers/usb/renesas_usbhs/rza.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/rcar3.c b/drivers/usb/renesas_usbhs/rcar3.c index aa3820448286..5e730e9b40ef 100644 --- a/drivers/usb/renesas_usbhs/rcar3.c +++ b/drivers/usb/renesas_usbhs/rcar3.c @@ -59,7 +59,7 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev, if (enable) { usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); /* The controller on R-Car Gen3 needs to wait up to 45 usec */ - udelay(45); + usleep_range(45, 90); } else { usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0); } diff --git a/drivers/usb/renesas_usbhs/rza.c b/drivers/usb/renesas_usbhs/rza.c index 5b287257ec11..8c739bd24acd 100644 --- a/drivers/usb/renesas_usbhs/rza.c +++ b/drivers/usb/renesas_usbhs/rza.c @@ -35,7 +35,7 @@ static int usbhs_rza1_hardware_init(struct platform_device *pdev) /* Enable USB PLL (NOTE: ch0 controls both ch0 and ch1) */ usbhs_bset(priv, SYSCFG, UPLLE, UPLLE); - udelay(1000); + usleep_range(1000, 2000); usbhs_bset(priv, SUSPMODE, SUSPM, SUSPM); return 0; -- cgit v1.2.3-58-ga151 From 169e3b68cadb5775daca009ced4faf01ffd97dcf Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Jan 2019 17:04:28 +0200 Subject: usb: dwc3: gadget: Fix OTG events when gadget driver isn't loaded On v3.10a in dual-role mode, if port is in device mode and gadget driver isn't loaded, the OTG event interrupts don't come through. It seems that if the core is configured to be OTG2.0 only, then we can't leave the DCFG.DEVSPD at Super-speed (default) if we expect OTG to work properly. It must be set to High-speed. Fix this issue by configuring DCFG.DEVSPD to the supported maximum speed at gadget init. Device tree still needs to provide correct supported maximum speed for this to work. This issue wasn't present on v2.40a but is seen on v3.10a. It doesn't cause any side effects on v2.40a. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index bed2ff42780b..d478d46847b6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3339,6 +3339,8 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err4; } + dwc3_gadget_set_speed(&dwc->gadget, dwc->maximum_speed); + return 0; err4: -- cgit v1.2.3-58-ga151 From d26c05781e08472861dcad4764d4f1585051638c Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Jan 2019 17:04:29 +0200 Subject: dt-bindings: usb: keystone-usb: Add ti,am654-dwc3 support The AM654 SoC from TI contains a DWC3 controller. Add support for it. Reviewed-by: Rob Herring Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/keystone-usb.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/keystone-usb.txt b/Documentation/devicetree/bindings/usb/keystone-usb.txt index f96e09f784cc..77df82e36138 100644 --- a/Documentation/devicetree/bindings/usb/keystone-usb.txt +++ b/Documentation/devicetree/bindings/usb/keystone-usb.txt @@ -3,7 +3,9 @@ TI Keystone Soc USB Controller DWC3 GLUE Required properties: - - compatible: should be "ti,keystone-dwc3". + - compatible: should be + "ti,keystone-dwc3" for Keystone 2 SoCs + "ti,am654-dwc3" for AM654 SoC - #address-cells, #size-cells : should be '1' if the device has sub-nodes with 'reg' property. - reg : Address and length of the register set for the USB subsystem on @@ -21,7 +23,7 @@ SoCs only: - clock-names: Must be "usb". -The following are mandatory properties for Keystone 2 66AK2G SoCs only: +The following are mandatory properties for 66AK2G and AM654: - power-domains: Should contain a phandle to a PM domain provider node and an args specifier containing the USB device id -- cgit v1.2.3-58-ga151 From eca6b49430c69742e511eb99516e86557d99ae70 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Jan 2019 17:04:30 +0200 Subject: usb: dwc3: keystone: Add support for ti,am654-dwc3 The AM654 SoC contains a DWC3 controller with TI specific wrapper. Add support for that. Unlike the Keystone 2 case, for AM654 We don't need to process any IRQs for basic USB operation. Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Kconfig | 6 +++--- drivers/usb/dwc3/dwc3-keystone.c | 11 ++++++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 1a0404fda596..34d9ce20532c 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -86,11 +86,11 @@ config USB_DWC3_HAPS platform, please say 'Y' or 'M' here. config USB_DWC3_KEYSTONE - tristate "Texas Instruments Keystone2 Platforms" - depends on ARCH_KEYSTONE || COMPILE_TEST + tristate "Texas Instruments Keystone2/AM654 Platforms" + depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST default USB_DWC3 help - Support of USB2/3 functionality in TI Keystone2 platforms. + Support of USB2/3 functionality in TI Keystone2 and AM654 platforms. Say 'Y' or 'M' here if you have one such device config USB_DWC3_OF_SIMPLE diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c index 193a9a88222a..cbee5fb9b9fb 100644 --- a/drivers/usb/dwc3/dwc3-keystone.c +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -106,6 +106,10 @@ static int kdwc3_probe(struct platform_device *pdev) goto err_irq; } + /* IRQ processing not required currently for AM65 */ + if (of_device_is_compatible(node, "ti,am654-dwc3")) + goto skip_irq; + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "missing irq\n"); @@ -123,6 +127,7 @@ static int kdwc3_probe(struct platform_device *pdev) kdwc3_enable_irqs(kdwc); +skip_irq: error = of_platform_populate(node, NULL, NULL, dev); if (error) { dev_err(&pdev->dev, "failed to create dwc3 core\n"); @@ -152,8 +157,11 @@ static int kdwc3_remove_core(struct device *dev, void *c) static int kdwc3_remove(struct platform_device *pdev) { struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); + struct device_node *node = pdev->dev.of_node; + + if (!of_device_is_compatible(node, "ti,am654-dwc3")) + kdwc3_disable_irqs(kdwc); - kdwc3_disable_irqs(kdwc); device_for_each_child(&pdev->dev, NULL, kdwc3_remove_core); pm_runtime_put_sync(kdwc->dev); pm_runtime_disable(kdwc->dev); @@ -165,6 +173,7 @@ static int kdwc3_remove(struct platform_device *pdev) static const struct of_device_id kdwc3_of_match[] = { { .compatible = "ti,keystone-dwc3", }, + { .compatible = "ti,am654-dwc3" }, {}, }; MODULE_DEVICE_TABLE(of, kdwc3_of_match); -- cgit v1.2.3-58-ga151 From 4d8cd61609200dbeb179649e90235d8ab6d66ef5 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Fri, 4 Jan 2019 22:44:43 +0100 Subject: usb: gadget: aspeed: fix typo Fix spelling mistake: "lenght" -> "length" Signed-off-by: Matteo Croce Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/aspeed-vhub/epn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/aspeed-vhub/epn.c b/drivers/usb/gadget/udc/aspeed-vhub/epn.c index 4a28e3fbeb0b..83340f4fdc6e 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/epn.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/epn.c @@ -120,7 +120,7 @@ static void ast_vhub_epn_handle_ack(struct ast_vhub_ep *ep) /* No current DMA ongoing */ req->active = false; - /* Grab lenght out of HW */ + /* Grab length out of HW */ len = VHUB_EP_DMA_TX_SIZE(stat); /* If not using DMA, copy data out if needed */ -- cgit v1.2.3-58-ga151 From 488e3b5fcd1d5c838b0b845a9d99b545ce46d84e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 30 Dec 2018 16:53:08 +0100 Subject: usb: gadget: udc: reduce indentation Delete tab aligning a statement with the right hand side of a preceding assignment rather than the left hand side. Found with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/snps_udc_core.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index d4da47f4f6f4..3fcded31405a 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -947,15 +947,14 @@ static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) UDC_DMA_STP_STS_BS_HOST_READY, UDC_DMA_STP_STS_BS); - - /* clear NAK by writing CNAK */ - if (ep->naking) { - tmp = readl(&ep->regs->ctl); - tmp |= AMD_BIT(UDC_EPCTL_CNAK); - writel(tmp, &ep->regs->ctl); - ep->naking = 0; - UDC_QUEUE_CNAK(ep, ep->num); - } + /* clear NAK by writing CNAK */ + if (ep->naking) { + tmp = readl(&ep->regs->ctl); + tmp |= AMD_BIT(UDC_EPCTL_CNAK); + writel(tmp, &ep->regs->ctl); + ep->naking = 0; + UDC_QUEUE_CNAK(ep, ep->num); + } } -- cgit v1.2.3-58-ga151 From 35ed6229c0f0d079f28b22b60b0af3114f9226fb Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:22:18 +0000 Subject: usb: gadget: udc: renesas_usb3: Add bindings for r8a774c0 Document RZ/G2E (R8A774C0) SoC bindings. Reviewed-by: Rob Herring Reviewed-by: Simon Horman Reviewed-by: Yoshihiro Shimoda Signed-off-by: Fabrizio Castro Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/renesas_usb3.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt b/Documentation/devicetree/bindings/usb/renesas_usb3.txt index d366555166d0..35039e720515 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt @@ -3,6 +3,7 @@ Renesas Electronics USB3.0 Peripheral driver Required properties: - compatible: Must contain one of the following: - "renesas,r8a774a1-usb3-peri" + - "renesas,r8a774c0-usb3-peri" - "renesas,r8a7795-usb3-peri" - "renesas,r8a7796-usb3-peri" - "renesas,r8a77965-usb3-peri" -- cgit v1.2.3-58-ga151 From 539cf1039165ac59d217d916bc8f88bde8be73bd Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:21:03 +0000 Subject: dt-bindings: usb: renesas_usbhs: Add r8a774c0 support Document RZ/G2E (R8A774C0) SoC bindings. Reviewed-by: Rob Herring Reviewed-by: Simon Horman Reviewed-by: Yoshihiro Shimoda Signed-off-by: Fabrizio Castro Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index 90719f501852..d93b6a1504f2 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -7,6 +7,7 @@ Required properties: - "renesas,usbhs-r8a7744" for r8a7744 (RZ/G1N) compatible device - "renesas,usbhs-r8a7745" for r8a7745 (RZ/G1E) compatible device - "renesas,usbhs-r8a774a1" for r8a774a1 (RZ/G2M) compatible device + - "renesas,usbhs-r8a774c0" for r8a774c0 (RZ/G2E) compatible device - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device - "renesas,usbhs-r8a7792" for r8a7792 (R-Car V2H) compatible device -- cgit v1.2.3-58-ga151 From 8b4c62aef6f611dcfcf0ce27731f0e439be17b05 Mon Sep 17 00:00:00 2001 From: Michał Mirosław Date: Sun, 16 Dec 2018 21:23:47 +0100 Subject: usb: gadget: u_serial: process RX in workqueue instead of tasklet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch RX processing from tasklet to (delayed) work queue. This allows receiver more room to process incoming data and prevents flood of "ttyGS0: RX not scheduled?" messages on HS receive on slow CPU. A side effect is 2.4MB/s zmodem transfer speed (up from 1.8MB/s) on my test board. Signed-off-by: Michał Mirosław Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_serial.c | 35 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 29436f75bbe0..65f634ec7fc2 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include #include "u_serial.h" @@ -110,7 +110,7 @@ struct gs_port { int read_allocated; struct list_head read_queue; unsigned n_read; - struct tasklet_struct push; + struct delayed_work push; struct list_head write_pool; int write_started; @@ -352,9 +352,10 @@ __acquires(&port->port_lock) * So QUEUE_SIZE packets plus however many the FIFO holds (usually two) * can be buffered before the TTY layer's buffers (currently 64 KB). */ -static void gs_rx_push(unsigned long _port) +static void gs_rx_push(struct work_struct *work) { - struct gs_port *port = (void *)_port; + struct delayed_work *w = to_delayed_work(work); + struct gs_port *port = container_of(w, struct gs_port, push); struct tty_struct *tty; struct list_head *queue = &port->read_queue; bool disconnect = false; @@ -429,21 +430,13 @@ static void gs_rx_push(unsigned long _port) /* We want our data queue to become empty ASAP, keeping data * in the tty and ldisc (not here). If we couldn't push any - * this time around, there may be trouble unless there's an - * implicit tty_unthrottle() call on its way... + * this time around, RX may be starved, so wait until next jiffy. * - * REVISIT we should probably add a timer to keep the tasklet - * from starving ... but it's not clear that case ever happens. + * We may leave non-empty queue only when there is a tty, and + * either it is throttled or there is no more room in flip buffer. */ - if (!list_empty(queue) && tty) { - if (!tty_throttled(tty)) { - if (do_push) - tasklet_schedule(&port->push); - else - pr_warn("ttyGS%d: RX not scheduled?\n", - port->port_num); - } - } + if (!list_empty(queue) && !tty_throttled(tty)) + schedule_delayed_work(&port->push, 1); /* If we're still connected, refill the USB RX queue. */ if (!disconnect && port->port_usb) @@ -459,7 +452,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) /* Queue all received data until the tty layer is ready for it. */ spin_lock(&port->port_lock); list_add_tail(&req->list, &port->read_queue); - tasklet_schedule(&port->push); + schedule_delayed_work(&port->push, 0); spin_unlock(&port->port_lock); } @@ -854,8 +847,8 @@ static void gs_unthrottle(struct tty_struct *tty) * rts/cts, or other handshaking with the host, but if the * read queue backs up enough we'll be NAKing OUT packets. */ - tasklet_schedule(&port->push); pr_vdebug("ttyGS%d: unthrottle\n", port->port_num); + schedule_delayed_work(&port->push, 0); } spin_unlock_irqrestore(&port->port_lock, flags); } @@ -1159,7 +1152,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) init_waitqueue_head(&port->drain_wait); init_waitqueue_head(&port->close_wait); - tasklet_init(&port->push, gs_rx_push, (unsigned long) port); + INIT_DELAYED_WORK(&port->push, gs_rx_push); INIT_LIST_HEAD(&port->read_pool); INIT_LIST_HEAD(&port->read_queue); @@ -1186,7 +1179,7 @@ static int gs_closed(struct gs_port *port) static void gserial_free_port(struct gs_port *port) { - tasklet_kill(&port->push); + cancel_delayed_work_sync(&port->push); /* wait for old opens to finish */ wait_event(port->close_wait, gs_closed(port)); WARN_ON(port->port_usb != NULL); -- cgit v1.2.3-58-ga151 From e49107d8acfee263b2bd8831d4833c4ead152784 Mon Sep 17 00:00:00 2001 From: Paul Elder Date: Mon, 17 Dec 2018 01:03:40 -0500 Subject: usb: gadget: uvc: add uvcg_warn macro We only have uvcg_dbg, uvcg_info, and uvcg_err, so add uvcg_warn macro to print gadget device name and function name along with format. Signed-off-by: Paul Elder Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 099d650082e5..1473d25ff17a 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -56,6 +56,8 @@ extern unsigned int uvc_gadget_trace_param; dev_dbg(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args) #define uvcg_info(f, fmt, args...) \ dev_info(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args) +#define uvcg_warn(f, fmt, args...) \ + dev_warn(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args) #define uvcg_err(f, fmt, args...) \ dev_err(&(f)->config->cdev->gadget->dev, "%s: " fmt, (f)->name, ##args) -- cgit v1.2.3-58-ga151 From 546970fdab1da5fead4f0f5c8cbf4b1c68213707 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:23:55 +0000 Subject: usb: gadget: udc: renesas_usb3: add support for r8a774c0 RZ/G2E USB 3.0 implementation is like the one found on R-Car E3, therefore add the same quirk. Reviewed-by: Simon Horman Reviewed-by: Yoshihiro Shimoda Signed-off-by: Fabrizio Castro Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/renesas_usb3.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 6e34f9594159..7dc248546fd4 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2629,6 +2629,10 @@ static const struct of_device_id usb3_of_match[] = { MODULE_DEVICE_TABLE(of, usb3_of_match); static const struct soc_device_attribute renesas_usb3_quirks_match[] = { + { + .soc_id = "r8a774c0", + .data = &renesas_usb3_priv_r8a77990, + }, { .soc_id = "r8a7795", .revision = "ES1.*", .data = &renesas_usb3_priv_r8a7795_es1, -- cgit v1.2.3-58-ga151 From a3af5e3ad3f11a0001317da9e9fb78b371c5f603 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Jan 2019 12:57:09 +0200 Subject: usb: dwc3: gadget: add dwc3_request status tracking This patch starts tracking dwc3_request status. A following patch will build on top of this to prevent a request from being queued twice. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 9 +++++++++ drivers/usb/dwc3/gadget.c | 3 +++ drivers/usb/dwc3/gadget.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index df876418cb78..5c3ee741541f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -863,6 +863,7 @@ struct dwc3_hwparams { * @num_pending_sgs: counter to pending sgs * @num_queued_sgs: counter to the number of sgs which already got queued * @remaining: amount of data remaining + * @status: internal dwc3 request status tracking * @epnum: endpoint number to which this request refers * @trb: pointer to struct dwc3_trb * @trb_dma: DMA address of @trb @@ -883,6 +884,14 @@ struct dwc3_request { unsigned num_pending_sgs; unsigned int num_queued_sgs; unsigned remaining; + + unsigned int status; +#define DWC3_REQUEST_STATUS_QUEUED 0 +#define DWC3_REQUEST_STATUS_STARTED 1 +#define DWC3_REQUEST_STATUS_CANCELLED 2 +#define DWC3_REQUEST_STATUS_COMPLETED 3 +#define DWC3_REQUEST_STATUS_UNKNOWN -1 + u8 epnum; struct dwc3_trb *trb; dma_addr_t trb_dma; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index d478d46847b6..9fde48656044 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -209,6 +209,7 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, struct dwc3 *dwc = dep->dwc; dwc3_gadget_del_and_unmap_request(dep, req, status); + req->status = DWC3_REQUEST_STATUS_COMPLETED; spin_unlock(&dwc->lock); usb_gadget_giveback_request(&dep->endpoint, &req->request); @@ -847,6 +848,7 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, req->direction = dep->direction; req->epnum = dep->number; req->dep = dep; + req->status = DWC3_REQUEST_STATUS_UNKNOWN; trace_dwc3_alloc_request(req); @@ -1443,6 +1445,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) trace_dwc3_ep_queue(req); list_add_tail(&req->list, &dep->pending_list); + req->status = DWC3_REQUEST_STATUS_QUEUED; /* * NOTICE: Isochronous endpoints should NEVER be prestarted. We must diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 023a473648eb..6aebe8c0eae1 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -76,6 +76,7 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) struct dwc3_ep *dep = req->dep; req->started = true; + req->status = DWC3_REQUEST_STATUS_STARTED; list_move_tail(&req->list, &dep->started_list); } @@ -91,6 +92,7 @@ static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req) struct dwc3_ep *dep = req->dep; req->started = false; + req->status = DWC3_REQUEST_STATUS_CANCELLED; list_move_tail(&req->list, &dep->cancelled_list); } -- cgit v1.2.3-58-ga151 From b2b6d601365a1acb90b87c85197d797447bc9a2c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Jan 2019 12:58:52 +0200 Subject: usb: dwc3: gadget: prevent dwc3_request from being queued twice Queueing the same request twice can introduce hard-to-debug problems. At least one function driver - Android's f_mtp.c - is known to cause this problem. While that function is out-of-tree, this is a problem that's easy enough to avoid. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 9fde48656044..064d5161c483 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1437,6 +1437,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) &req->request, req->dep->name)) return -EINVAL; + if (WARN(req->status < DWC3_REQUEST_STATUS_COMPLETED, + "%s: request %pK already in flight\n", + dep->name, &req->request)) + return -EINVAL; + pm_runtime_get(dwc->dev); req->request.actual = 0; -- cgit v1.2.3-58-ga151 From 7c3d7dc89e57a1d43acea935882dd8713c9e639f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 11 Jan 2019 13:03:27 +0200 Subject: usb: dwc3: gadget: remove req->started flag Now that we have req->status, we don't need this extra flag anymore. It's safe to remove it. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 2 -- drivers/usb/dwc3/gadget.c | 1 - drivers/usb/dwc3/gadget.h | 2 -- 3 files changed, 5 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 5c3ee741541f..96794c301a6b 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -872,7 +872,6 @@ struct dwc3_hwparams { * or unaligned OUT) * @direction: IN or OUT direction flag * @mapped: true when request has been dma-mapped - * @started: request is started */ struct dwc3_request { struct usb_request request; @@ -901,7 +900,6 @@ struct dwc3_request { unsigned needs_extra_trb:1; unsigned direction:1; unsigned mapped:1; - unsigned started:1; }; /* diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 064d5161c483..189605df6bd2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -174,7 +174,6 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, { struct dwc3 *dwc = dep->dwc; - req->started = false; list_del(&req->list); req->remaining = 0; req->needs_extra_trb = false; diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 6aebe8c0eae1..3ed738e86ea7 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -75,7 +75,6 @@ static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; - req->started = true; req->status = DWC3_REQUEST_STATUS_STARTED; list_move_tail(&req->list, &dep->started_list); } @@ -91,7 +90,6 @@ static inline void dwc3_gadget_move_cancelled_request(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; - req->started = false; req->status = DWC3_REQUEST_STATUS_CANCELLED; list_move_tail(&req->list, &dep->cancelled_list); } -- cgit v1.2.3-58-ga151 From b97a31348379f7beed7664a8d4eab491e227c165 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:23:40 +0100 Subject: usb: core: comply to PHY framework Current implementation of the USB core does not take into account the new PHY framework. Correct the situation by adding a call to phy_set_mode() before phy_power_on(). Signed-off-by: Miquel Raynal Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 5 +++++ drivers/usb/core/phy.c | 28 ++++++++++++++++++++++++++++ drivers/usb/core/phy.h | 2 ++ 3 files changed, 35 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 015b126ce455..86f39e44f98a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2736,6 +2736,11 @@ int usb_add_hcd(struct usb_hcd *hcd, if (retval) return retval; + retval = usb_phy_roothub_set_mode(hcd->phy_roothub, + PHY_MODE_USB_HOST_SS); + if (retval) + goto err_usb_phy_roothub_power_on; + retval = usb_phy_roothub_power_on(hcd->phy_roothub); if (retval) goto err_usb_phy_roothub_power_on; diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index 38b2c776c4b4..7580493b867a 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -123,6 +123,34 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub) } EXPORT_SYMBOL_GPL(usb_phy_roothub_exit); +int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, + enum phy_mode mode) +{ + struct usb_phy_roothub *roothub_entry; + struct list_head *head; + int err; + + if (!phy_roothub) + return 0; + + head = &phy_roothub->list; + + list_for_each_entry(roothub_entry, head, list) { + err = phy_set_mode(roothub_entry->phy, mode); + if (err) + goto err_out; + } + + return 0; + +err_out: + list_for_each_entry_continue_reverse(roothub_entry, head, list) + phy_power_off(roothub_entry->phy); + + return err; +} +EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode); + int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub) { struct usb_phy_roothub *roothub_entry; diff --git a/drivers/usb/core/phy.h b/drivers/usb/core/phy.h index 88a3c037e9df..dad564e2d2d4 100644 --- a/drivers/usb/core/phy.h +++ b/drivers/usb/core/phy.h @@ -16,6 +16,8 @@ struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev); int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub); int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub); +int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, + enum phy_mode mode); int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub); void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub); -- cgit v1.2.3-58-ga151 From 12453a897e36665d75f1d7b722159ae1eeadf81c Mon Sep 17 00:00:00 2001 From: Ofer Heifetz Date: Tue, 29 Jan 2019 10:23:41 +0100 Subject: usb: host: xhci: mvebu: add reset on resume quirk The mvebu xHCI host driver does not have suspend/resume support. Use of the XHCI_RESET_ON_RESUME quirk is mandatory in order to avoid failures after resume. This will work only if no USB device is plugged-in. While at it, mention in the Kconfig file that this IP is also present on the A3700 SoC. Signed-off-by: Ofer Heifetz [miquel.raynal@bootlin.com: Reword the commit message] Signed-off-by: Miquel Raynal Reviewed-by: Gregory CLEMENT Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 4 ++-- drivers/usb/host/xhci-mvebu.c | 11 +++++++++++ drivers/usb/host/xhci-mvebu.h | 6 ++++++ drivers/usb/host/xhci-plat.c | 7 +++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 29e8a56d8d82..d809671c5fea 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -70,13 +70,13 @@ config USB_XHCI_MTK If unsure, say N. config USB_XHCI_MVEBU - tristate "xHCI support for Marvell Armada 375/38x" + tristate "xHCI support for Marvell Armada 375/38x/37xx" select USB_XHCI_PLATFORM depends on HAS_IOMEM depends on ARCH_MVEBU || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller - found in Marvell Armada 375/38x ARM SOCs. + found in Marvell Armada 375/38x/37xx ARM SOCs. config USB_XHCI_RCAR tristate "xHCI support for Renesas R-Car SoCs" diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 32e158568788..60651a50770f 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -13,6 +13,7 @@ #include #include "xhci-mvebu.h" +#include "xhci.h" #define USB3_MAX_WINDOWS 4 #define USB3_WIN_CTRL(w) (0x0 + ((w) * 8)) @@ -72,3 +73,13 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) return 0; } + +int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + /* Without reset on resume, the HC won't work at all */ + xhci->quirks |= XHCI_RESET_ON_RESUME; + + return 0; +} diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index 09791df2cec0..ca0a3a5721dd 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -12,10 +12,16 @@ struct usb_hcd; #if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); +int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); #else static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) { return 0; } + +static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) +{ + return 0; +} #endif #endif /* __LINUX_XHCI_MVEBU_H */ diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ef09cb06212f..0ac4ec975547 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -98,6 +98,10 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { .init_quirk = xhci_mvebu_mbus_init_quirk, }; +static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { + .init_quirk = xhci_mvebu_a3700_init_quirk, +}; + static const struct xhci_plat_priv xhci_plat_renesas_rcar_gen2 = { .firmware_name = XHCI_RCAR_FIRMWARE_NAME_V1, .init_quirk = xhci_rcar_init_quirk, @@ -123,6 +127,9 @@ static const struct of_device_id usb_xhci_of_match[] = { }, { .compatible = "marvell,armada-380-xhci", .data = &xhci_plat_marvell_armada, + }, { + .compatible = "marvell,armada3700-xhci", + .data = &xhci_plat_marvell_armada3700, }, { .compatible = "renesas,xhci-r8a7790", .data = &xhci_plat_renesas_rcar_gen2, -- cgit v1.2.3-58-ga151 From e04585184dcf792cd053d6ce84091201e45c2225 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:23:42 +0100 Subject: usb: ehci-orion: avoid double PHY initialization No need to initialize the PHY from the driver's probe. It is done by the core automatically and doing it twice would increment the phy->powercount counter to 2 instead of 1. During later suspend operation, the counter will be decremented to one, no phy->power_off() will occur and worse than that, the following phy->power_on() at resume time will also be skipped, failing the whole S2RAM operation. Signed-off-by: Miquel Raynal Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-orion.c | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 1ad72647a069..3109f082949e 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -257,15 +257,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) if (IS_ERR(priv->phy)) { err = PTR_ERR(priv->phy); if (err != -ENOSYS) - goto err_phy_get; - } else { - err = phy_init(priv->phy); - if (err) - goto err_phy_init; - - err = phy_power_on(priv->phy); - if (err) - goto err_phy_power_on; + goto err_dis_clk; } /* @@ -297,19 +289,12 @@ static int ehci_orion_drv_probe(struct platform_device *pdev) err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) - goto err_add_hcd; + goto err_dis_clk; device_wakeup_enable(hcd->self.controller); return 0; -err_add_hcd: - if (!IS_ERR(priv->phy)) - phy_power_off(priv->phy); -err_phy_power_on: - if (!IS_ERR(priv->phy)) - phy_exit(priv->phy); -err_phy_init: -err_phy_get: +err_dis_clk: if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); usb_put_hcd(hcd); @@ -327,11 +312,6 @@ static int ehci_orion_drv_remove(struct platform_device *pdev) usb_remove_hcd(hcd); - if (!IS_ERR(priv->phy)) { - phy_power_off(priv->phy); - phy_exit(priv->phy); - } - if (!IS_ERR(priv->clk)) clk_disable_unprepare(priv->clk); -- cgit v1.2.3-58-ga151 From f91649c525880006c78e62f6bae4d802a590c3ba Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:23:43 +0100 Subject: usb: ehci-orion: add S2RAM support Add suspend/resume callbacks to reset the host controller properly during S2RAM operation. Signed-off-by: Miquel Raynal Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-orion.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 3109f082949e..790acf3633e8 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -182,6 +182,23 @@ static int ehci_orion_drv_reset(struct usb_hcd *hcd) return ret; } +static int __maybe_unused ehci_orion_drv_suspend(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + return ehci_suspend(hcd, device_may_wakeup(dev)); +} + +static int __maybe_unused ehci_orion_drv_resume(struct device *dev) +{ + struct usb_hcd *hcd = dev_get_drvdata(dev); + + return ehci_resume(hcd, false); +} + +static SIMPLE_DEV_PM_OPS(ehci_orion_pm_ops, ehci_orion_drv_suspend, + ehci_orion_drv_resume); + static const struct ehci_driver_overrides orion_overrides __initconst = { .extra_priv_size = sizeof(struct orion_ehci_hcd), .reset = ehci_orion_drv_reset, @@ -334,6 +351,7 @@ static struct platform_driver ehci_orion_driver = { .driver = { .name = "orion-ehci", .of_match_table = ehci_orion_dt_ids, + .pm = &ehci_orion_pm_ops, }, }; -- cgit v1.2.3-58-ga151 From a2fd23b93733bf604870eb8a15ccaa74c9b23889 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 25 Jan 2019 09:05:42 -0700 Subject: usbip: Fix vep_free_request() null pointer checks on input args Fix vep_free_request() to return when usb_ep and usb_request are null instead of calling WARN_ON. Signed-off-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usbip/vudc_dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vudc_dev.c b/drivers/usb/usbip/vudc_dev.c index 1634d8698e15..a72c17ff1c6a 100644 --- a/drivers/usb/usbip/vudc_dev.c +++ b/drivers/usb/usbip/vudc_dev.c @@ -297,7 +297,8 @@ static void vep_free_request(struct usb_ep *_ep, struct usb_request *_req) { struct vrequest *req; - if (WARN_ON(!_ep || !_req)) + /* ep is always valid here - see usb_ep_free_request() */ + if (!_req) return; req = to_vrequest(_req); -- cgit v1.2.3-58-ga151 From acbfa6c26f21a18830ee064b588c92334305b6af Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Jan 2019 12:58:27 +0200 Subject: usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete We must wait until End Transfer completes in order to clear DWC3_EP_TRANSFER_STARTED, otherwise we may confuse the driver. This patch is in preparation to fix a rare race condition that happens upon Disconnect Interrupt. Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 189605df6bd2..f9b44302199a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -384,19 +384,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd, trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status); - if (ret == 0) { - switch (DWC3_DEPCMD_CMD(cmd)) { - case DWC3_DEPCMD_STARTTRANSFER: - dep->flags |= DWC3_EP_TRANSFER_STARTED; - dwc3_gadget_ep_get_transfer_index(dep); - break; - case DWC3_DEPCMD_ENDTRANSFER: - dep->flags &= ~DWC3_EP_TRANSFER_STARTED; - break; - default: - /* nothing */ - break; - } + if (ret == 0 && DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) { + dep->flags |= DWC3_EP_TRANSFER_STARTED; + dwc3_gadget_ep_get_transfer_index(dep); } if (saved_config) { @@ -2578,7 +2568,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, cmd = DEPEVT_PARAMETER_CMD(event->parameters); if (cmd == DWC3_DEPCMD_ENDTRANSFER) { - dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; + dep->flags &= ~(DWC3_EP_END_TRANSFER_PENDING | + DWC3_EP_TRANSFER_STARTED); dwc3_gadget_ep_cleanup_cancelled_requests(dep); } break; -- cgit v1.2.3-58-ga151 From 974a1368c33ebb09c94c9ec1b523908cc7ca068f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Jan 2019 13:00:03 +0200 Subject: usb: dwc3: gadget: don't use resource_index as a flag We have a proper flag for testing that we have a valid transfer in flight, let's use that instead. This patch is in preparation to fix a rare race condition that happens upon Disconnect Interrupt. Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f9b44302199a..eaeea8ff5191 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2626,8 +2626,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force) u32 cmd; int ret; - if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) || - !dep->resource_index) + if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) + || !(dep->flags & DWC3_EP_TRANSFER_STARTED)) return; /* -- cgit v1.2.3-58-ga151 From 9f45581f5eec6786c6eded2b3c85345d82a910c9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Jan 2019 13:01:16 +0200 Subject: usb: dwc3: gadget: early giveback if End Transfer already completed There is a rare race condition that may happen during a Disconnect Interrupt if we have a started request that happens to be dequeued *after* completion of End Transfer command. If that happens, that request will be left waiting for completion of an End Transfer command that will never happen. If End Transfer command has already completed before, we are safe to giveback the request straight away. Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index eaeea8ff5191..b82a8885747d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1550,7 +1550,10 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; dwc3_gadget_move_cancelled_request(req); - goto out0; + if (dep->flags & DWC3_EP_TRANSFER_STARTED) + goto out0; + else + goto out1; } dev_err(dwc->dev, "request %pK was not queued to %s\n", request, ep->name); @@ -1558,6 +1561,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } +out1: dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: -- cgit v1.2.3-58-ga151 From 3aec99154db3a95572bb92aa470589585e37df06 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Jan 2019 13:08:44 +0200 Subject: usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING Now that we modified the code to fix a race condition, it's clear that DWC3_EP_END_TRANSFER_PENDING is unnecessary, considering that DWC3_EP_TRANSFER_STARTED will remain set until End Transfer completes. Tested-by: Thinh Nguyen Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.h | 1 - drivers/usb/dwc3/gadget.c | 15 +++++---------- drivers/usb/dwc3/trace.h | 3 +-- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 96794c301a6b..1528d395b156 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -692,7 +692,6 @@ struct dwc3_ep { #define DWC3_EP_WEDGE BIT(2) #define DWC3_EP_TRANSFER_STARTED BIT(3) #define DWC3_EP_PENDING_REQUEST BIT(5) -#define DWC3_EP_END_TRANSFER_PENDING BIT(7) /* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN BIT(31) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index b82a8885747d..8425b6dab875 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -632,7 +632,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) dep->type = usb_endpoint_type(desc); dep->flags |= DWC3_EP_ENABLED; - dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING; reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); reg |= DWC3_DALEPENA_EP(dep->number); @@ -738,7 +737,7 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) dep->stream_capable = false; dep->type = 0; - dep->flags &= DWC3_EP_END_TRANSFER_PENDING; + dep->flags = 0; /* Clear out the ep descriptors for non-ep0 */ if (dep->number > 1) { @@ -2548,7 +2547,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, dep = dwc->eps[epnum]; if (!(dep->flags & DWC3_EP_ENABLED)) { - if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) + if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) return; /* Handle only EPCMDCMPLT when EP disabled */ @@ -2572,8 +2571,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, cmd = DEPEVT_PARAMETER_CMD(event->parameters); if (cmd == DWC3_DEPCMD_ENDTRANSFER) { - dep->flags &= ~(DWC3_EP_END_TRANSFER_PENDING | - DWC3_EP_TRANSFER_STARTED); + dep->flags &= ~DWC3_EP_TRANSFER_STARTED; dwc3_gadget_ep_cleanup_cancelled_requests(dep); } break; @@ -2630,8 +2628,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force) u32 cmd; int ret; - if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) - || !(dep->flags & DWC3_EP_TRANSFER_STARTED)) + if (!(dep->flags & DWC3_EP_TRANSFER_STARTED)) return; /* @@ -2674,10 +2671,8 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force) WARN_ON_ONCE(ret); dep->resource_index = 0; - if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) { - dep->flags |= DWC3_EP_END_TRANSFER_PENDING; + if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A) udelay(100); - } } static void dwc3_clear_stall_all_ep(struct dwc3 *dwc) diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index e97a00593dda..3a2f2c319c9a 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -305,7 +305,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep, __entry->trb_enqueue = dep->trb_enqueue; __entry->trb_dequeue = dep->trb_dequeue; ), - TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c:%c", + TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c", __get_str(name), __entry->maxpacket, __entry->maxpacket_limit, __entry->max_streams, __entry->maxburst, __entry->trb_enqueue, @@ -315,7 +315,6 @@ DECLARE_EVENT_CLASS(dwc3_log_ep, __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w', __entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b', __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p', - __entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e', __entry->direction ? '<' : '>' ) ); -- cgit v1.2.3-58-ga151 From 1760435d613c9ee536eaf40ffa97958c3e1973fe Mon Sep 17 00:00:00 2001 From: Suwan Kim Date: Wed, 30 Jan 2019 23:48:28 +0900 Subject: usb: core: Move variable initialization to appropriate place It is better to initialize the variable 'cfgno' in the for loop than at the current place. Signed-off-by: Suwan Kim Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 4a0945c04b4c..7bb6b1bd06c8 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -805,7 +805,6 @@ int usb_get_configuration(struct usb_device *dev) unsigned char *bigbuffer; struct usb_config_descriptor *desc; - cfgno = 0; if (ncfg > USB_MAXCONFIG) { dev_warn(ddev, "too many configurations: %d, " "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); @@ -831,7 +830,7 @@ int usb_get_configuration(struct usb_device *dev) if (!desc) goto err2; - for (; cfgno < ncfg; cfgno++) { + for (cfgno = 0; cfgno < ncfg; cfgno++) { /* We grab just the first descriptor so we know how long * the whole configuration is */ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, -- cgit v1.2.3-58-ga151 From 68f1ec8ea14f5dcb91df6258e482afcb41610b2e Mon Sep 17 00:00:00 2001 From: Jon Flatley Date: Fri, 1 Feb 2019 13:55:07 -0800 Subject: usb: Change "wired" to "hardwired" for connect_type The sysfs documentation for /sys/bus/usb/.../portX/connect_type has one of the possible values listed as "wired" when the actual value should be "hardwired". Changes the ABI documentation for connect_type to match the strings in port.c. Signed-off-by: Jon Flatley Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 559baa5c418c..614d216dff1d 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -186,7 +186,7 @@ Contact: Lan Tianyu Description: Some platforms provide usb port connect types through ACPI. This attribute is to expose these information to user space. - The file will read "hotplug", "wired" and "not used" if the + The file will read "hotplug", "hardwired" and "not used" if the information is available, and "unknown" otherwise. What: /sys/bus/usb/devices/.../(hub interface)/portX/location -- cgit v1.2.3-58-ga151 From 7790b3556fccc555ae422f1576e97bf34c8ab8b6 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 4 Feb 2019 15:43:38 +0200 Subject: usb: dwc3: trace: pass trace buffer size to decoding functions Instead of assuming that our buffer is big enough, let's pass the buffer size around so printing functions can make sure they won't overflow the buffer. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debug.h | 142 +++++++++++++++++++++++++---------------------- drivers/usb/dwc3/trace.h | 7 ++- 2 files changed, 80 insertions(+), 69 deletions(-) diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h index 4f75ab3505b7..e925a6b73005 100644 --- a/drivers/usb/dwc3/debug.h +++ b/drivers/usb/dwc3/debug.h @@ -193,65 +193,69 @@ static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) * dwc3_gadget_event_string - returns event name * @event: the event code */ -static inline const char * -dwc3_gadget_event_string(char *str, const struct dwc3_event_devt *event) +static inline const char *dwc3_gadget_event_string(char *str, size_t size, + const struct dwc3_event_devt *event) { enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; switch (event->type) { case DWC3_DEVICE_EVENT_DISCONNECT: - sprintf(str, "Disconnect: [%s]", + snprintf(str, size, "Disconnect: [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_RESET: - sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); + snprintf(str, size, "Reset [%s]", + dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_CONNECT_DONE: - sprintf(str, "Connection Done [%s]", + snprintf(str, size, "Connection Done [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: - sprintf(str, "Link Change [%s]", + snprintf(str, size, "Link Change [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_WAKEUP: - sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); + snprintf(str, size, "WakeUp [%s]", + dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_EOPF: - sprintf(str, "End-Of-Frame [%s]", + snprintf(str, size, "End-Of-Frame [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_SOF: - sprintf(str, "Start-Of-Frame [%s]", + snprintf(str, size, "Start-Of-Frame [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_ERRATIC_ERROR: - sprintf(str, "Erratic Error [%s]", + snprintf(str, size, "Erratic Error [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_CMD_CMPL: - sprintf(str, "Command Complete [%s]", + snprintf(str, size, "Command Complete [%s]", dwc3_gadget_link_string(state)); break; case DWC3_DEVICE_EVENT_OVERFLOW: - sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); + snprintf(str, size, "Overflow [%s]", + dwc3_gadget_link_string(state)); break; default: - sprintf(str, "UNKNOWN"); + snprintf(str, size, "UNKNOWN"); } return str; } -static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str) +static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str, + size_t size) { switch (t & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: - sprintf(str, "Get Interface Status(Intf = %d, Length = %d)", - i, l); + snprintf(str, size, "Get Interface Status(Intf = %d, Length = %d)", + i, l); break; case USB_RECIP_ENDPOINT: - sprintf(str, "Get Endpoint Status(ep%d%s)", + snprintf(str, size, "Get Endpoint Status(ep%d%s)", i & ~USB_DIR_IN, i & USB_DIR_IN ? "in" : "out"); break; @@ -259,11 +263,11 @@ static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str) } static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, - __u16 i, char *str) + __u16 i, char *str, size_t size) { switch (t & USB_RECIP_MASK) { case USB_RECIP_DEVICE: - sprintf(str, "%s Device Feature(%s%s)", + snprintf(str, size, "%s Device Feature(%s%s)", b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", ({char *s; switch (v) { @@ -311,13 +315,13 @@ static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, } s; }) : ""); break; case USB_RECIP_INTERFACE: - sprintf(str, "%s Interface Feature(%s)", + snprintf(str, size, "%s Interface Feature(%s)", b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", v == USB_INTRF_FUNC_SUSPEND ? "Function Suspend" : "UNKNOWN"); break; case USB_RECIP_ENDPOINT: - sprintf(str, "%s Endpoint Feature(%s ep%d%s)", + snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)", b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", i & ~USB_DIR_IN, @@ -326,15 +330,15 @@ static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, } } -static inline void dwc3_decode_set_address(__u16 v, char *str) +static inline void dwc3_decode_set_address(__u16 v, char *str, size_t size) { - sprintf(str, "Set Address(Addr = %02x)", v); + snprintf(str, size, "Set Address(Addr = %02x)", v); } static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, - __u16 i, __u16 l, char *str) + __u16 i, __u16 l, char *str, size_t size) { - sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)", + snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)", b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", ({ char *s; switch (v >> 8) { @@ -393,87 +397,92 @@ static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, } -static inline void dwc3_decode_get_configuration(__u16 l, char *str) +static inline void dwc3_decode_get_configuration(__u16 l, char *str, + size_t size) { - sprintf(str, "Get Configuration(Length = %d)", l); + snprintf(str, size, "Get Configuration(Length = %d)", l); } -static inline void dwc3_decode_set_configuration(__u8 v, char *str) +static inline void dwc3_decode_set_configuration(__u8 v, char *str, size_t size) { - sprintf(str, "Set Configuration(Config = %d)", v); + snprintf(str, size, "Set Configuration(Config = %d)", v); } -static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str) +static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str, + size_t size) { - sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l); + snprintf(str, size, "Get Interface(Intf = %d, Length = %d)", i, l); } -static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str) +static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str, size_t size) { - sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); + snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); } -static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str) +static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str, + size_t size) { - sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l); + snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)", i, l); } -static inline void dwc3_decode_set_sel(__u16 l, char *str) +static inline void dwc3_decode_set_sel(__u16 l, char *str, size_t size) { - sprintf(str, "Set SEL(Length = %d)", l); + snprintf(str, size, "Set SEL(Length = %d)", l); } -static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str) +static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str, size_t size) { - sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v); + snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", v); } /** * dwc3_decode_ctrl - returns a string represetion of ctrl request */ -static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType, - __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength) +static inline const char *dwc3_decode_ctrl(char *str, size_t size, + __u8 bRequestType, __u8 bRequest, __u16 wValue, __u16 wIndex, + __u16 wLength) { switch (bRequest) { case USB_REQ_GET_STATUS: - dwc3_decode_get_status(bRequestType, wIndex, wLength, str); + dwc3_decode_get_status(bRequestType, wIndex, wLength, str, + size); break; case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, - wIndex, str); + wIndex, str, size); break; case USB_REQ_SET_ADDRESS: - dwc3_decode_set_address(wValue, str); + dwc3_decode_set_address(wValue, str, size); break; case USB_REQ_GET_DESCRIPTOR: case USB_REQ_SET_DESCRIPTOR: dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, - wIndex, wLength, str); + wIndex, wLength, str, size); break; case USB_REQ_GET_CONFIGURATION: - dwc3_decode_get_configuration(wLength, str); + dwc3_decode_get_configuration(wLength, str, size); break; case USB_REQ_SET_CONFIGURATION: - dwc3_decode_set_configuration(wValue, str); + dwc3_decode_set_configuration(wValue, str, size); break; case USB_REQ_GET_INTERFACE: - dwc3_decode_get_intf(wIndex, wLength, str); + dwc3_decode_get_intf(wIndex, wLength, str, size); break; case USB_REQ_SET_INTERFACE: - dwc3_decode_set_intf(wValue, wIndex, str); + dwc3_decode_set_intf(wValue, wIndex, str, size); break; case USB_REQ_SYNCH_FRAME: - dwc3_decode_synch_frame(wIndex, wLength, str); + dwc3_decode_synch_frame(wIndex, wLength, str, size); break; case USB_REQ_SET_SEL: - dwc3_decode_set_sel(wLength, str); + dwc3_decode_set_sel(wLength, str, size); break; case USB_REQ_SET_ISOCH_DELAY: - dwc3_decode_set_isoch_delay(wValue, str); + dwc3_decode_set_isoch_delay(wValue, str, size); break; default: - sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x", + snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x", bRequestType, bRequest, cpu_to_le16(wValue) & 0xff, cpu_to_le16(wValue) >> 8, @@ -490,16 +499,15 @@ static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType, * dwc3_ep_event_string - returns event name * @event: then event code */ -static inline const char * -dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, - u32 ep0state) +static inline const char *dwc3_ep_event_string(char *str, size_t size, + const struct dwc3_event_depevt *event, u32 ep0state) { u8 epnum = event->endpoint_number; size_t len; int status; int ret; - ret = sprintf(str, "ep%d%s: ", epnum >> 1, + ret = snprintf(str, size, "ep%d%s: ", epnum >> 1, (epnum & 1) ? "in" : "out"); if (ret < 0) return "UNKNOWN"; @@ -509,7 +517,7 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, switch (event->endpoint_event) { case DWC3_DEPEVT_XFERCOMPLETE: len = strlen(str); - sprintf(str + len, "Transfer Complete (%c%c%c)", + snprintf(str + len, size - len, "Transfer Complete (%c%c%c)", status & DEPEVT_STATUS_SHORT ? 'S' : 's', status & DEPEVT_STATUS_IOC ? 'I' : 'i', status & DEPEVT_STATUS_LST ? 'L' : 'l'); @@ -517,12 +525,13 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, len = strlen(str); if (epnum <= 1) - sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state)); + snprintf(str + len, size - len, " [%s]", + dwc3_ep0_state_string(ep0state)); break; case DWC3_DEPEVT_XFERINPROGRESS: len = strlen(str); - sprintf(str + len, "Transfer In Progress [%d] (%c%c%c)", + snprintf(str + len, size - len, "Transfer In Progress [%d] (%c%c%c)", event->parameters, status & DEPEVT_STATUS_SHORT ? 'S' : 's', status & DEPEVT_STATUS_IOC ? 'I' : 'i', @@ -531,7 +540,7 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, case DWC3_DEPEVT_XFERNOTREADY: len = strlen(str); - sprintf(str + len, "Transfer Not Ready [%d]%s", + snprintf(str + len, size - len, "Transfer Not Ready [%d]%s", event->parameters, status & DEPEVT_STATUS_TRANSFER_ACTIVE ? " (Active)" : " (Not Active)"); @@ -557,7 +566,7 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, switch (status) { case DEPEVT_STREAMEVT_FOUND: - sprintf(str + ret, " Stream %d Found", + snprintf(str + ret, size - ret, " Stream %d Found", event->parameters); break; case DEPEVT_STREAMEVT_NOTFOUND: @@ -571,7 +580,7 @@ dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, strcat(str, "Endpoint Command Complete"); break; default: - sprintf(str, "UNKNOWN"); + snprintf(str, size, "UNKNOWN"); } return str; @@ -611,14 +620,15 @@ static inline const char *dwc3_gadget_event_type_string(u8 event) } } -static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state) +static inline const char *dwc3_decode_event(char *str, size_t size, u32 event, + u32 ep0state) { const union dwc3_event evt = (union dwc3_event) event; if (evt.type.is_devspec) - return dwc3_gadget_event_string(str, &evt.devt); + return dwc3_gadget_event_string(str, size, &evt.devt); else - return dwc3_ep_event_string(str, &evt.depevt, ep0state); + return dwc3_ep_event_string(str, size, &evt.depevt, ep0state); } static inline const char *dwc3_ep_cmd_status_string(int status) diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index 3a2f2c319c9a..818a63da1a44 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -59,8 +59,8 @@ DECLARE_EVENT_CLASS(dwc3_log_event, __entry->ep0state = dwc->ep0state; ), TP_printk("event (%08x): %s", __entry->event, - dwc3_decode_event(__get_str(str), __entry->event, - __entry->ep0state)) + dwc3_decode_event(__get_str(str), DWC3_MSG_MAX, + __entry->event, __entry->ep0state)) ); DEFINE_EVENT(dwc3_log_event, dwc3_event, @@ -86,7 +86,8 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl, __entry->wIndex = le16_to_cpu(ctrl->wIndex); __entry->wLength = le16_to_cpu(ctrl->wLength); ), - TP_printk("%s", dwc3_decode_ctrl(__get_str(str), __entry->bRequestType, + TP_printk("%s", dwc3_decode_ctrl(__get_str(str), DWC3_MSG_MAX, + __entry->bRequestType, __entry->bRequest, __entry->wValue, __entry->wIndex, __entry->wLength) ) -- cgit v1.2.3-58-ga151 From 15fb84b741966c8a08e02e145ec5932d51b6c4ad Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Mon, 28 Jan 2019 13:57:17 +0800 Subject: USB: serial: cp210x: add GPIO support for CP2104 The CP2104 chips feature 4 controllable GPIO pins, which are similar to the ones on CP2102N chip (output-only when push-pull, output or simulated input mode when open-drain). Add support for the GPIO pins for cp210x driver. The pin get/set routine is shared with CP2102N, but the pinconf initialization code is not shared because the acquisition of GPIO configuration in OTP ROM is similar to CP2105, not CP2102N. Signed-off-by: Icenowy Zheng Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 82 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 336a3c0f9f2c..260c875dd263 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -443,10 +443,10 @@ struct cp210x_pin_mode { #define CP210X_PIN_MODE_GPIO BIT(0) /* - * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xf bytes. - * Structure needs padding due to unused/unspecified bytes. + * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xf bytes + * on a CP2105 chip. Structure needs padding due to unused/unspecified bytes. */ -struct cp210x_config { +struct cp210x_dual_port_config { __le16 gpio_mode; u8 __pad0[2]; __le16 reset_state; @@ -457,6 +457,19 @@ struct cp210x_config { u8 device_cfg; } __packed; +/* + * CP210X_VENDOR_SPECIFIC, CP210X_GET_PORTCONFIG call reads these 0xd bytes + * on a CP2104 chip. Structure needs padding due to unused/unspecified bytes. + */ +struct cp210x_single_port_config { + __le16 gpio_mode; + u8 __pad0[2]; + __le16 reset_state; + u8 __pad1[4]; + __le16 suspend_state; + u8 device_cfg; +} __packed; + /* GPIO modes */ #define CP210X_SCI_GPIO_MODE_OFFSET 9 #define CP210X_SCI_GPIO_MODE_MASK GENMASK(11, 9) @@ -464,11 +477,19 @@ struct cp210x_config { #define CP210X_ECI_GPIO_MODE_OFFSET 2 #define CP210X_ECI_GPIO_MODE_MASK GENMASK(3, 2) +#define CP210X_GPIO_MODE_OFFSET 8 +#define CP210X_GPIO_MODE_MASK GENMASK(11, 8) + /* CP2105 port configuration values */ #define CP2105_GPIO0_TXLED_MODE BIT(0) #define CP2105_GPIO1_RXLED_MODE BIT(1) #define CP2105_GPIO1_RS485_MODE BIT(2) +/* CP2104 port configuration values */ +#define CP2104_GPIO0_TXLED_MODE BIT(0) +#define CP2104_GPIO1_RXLED_MODE BIT(1) +#define CP2104_GPIO2_RS485_MODE BIT(2) + /* CP2102N configuration array indices */ #define CP210X_2NCONFIG_CONFIG_VERSION_IDX 2 #define CP210X_2NCONFIG_GPIO_MODE_IDX 581 @@ -1470,7 +1491,7 @@ static int cp2105_gpioconf_init(struct usb_serial *serial) { struct cp210x_serial_private *priv = usb_get_serial_data(serial); struct cp210x_pin_mode mode; - struct cp210x_config config; + struct cp210x_dual_port_config config; u8 intf_num = cp210x_interface_num(serial); u8 iface_config; int result; @@ -1529,6 +1550,56 @@ static int cp2105_gpioconf_init(struct usb_serial *serial) return 0; } +static int cp2104_gpioconf_init(struct usb_serial *serial) +{ + struct cp210x_serial_private *priv = usb_get_serial_data(serial); + struct cp210x_single_port_config config; + u8 iface_config; + u8 gpio_latch; + int result; + u8 i; + + result = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, + CP210X_GET_PORTCONFIG, &config, + sizeof(config)); + if (result < 0) + return result; + + priv->gc.ngpio = 4; + + iface_config = config.device_cfg; + priv->gpio_pushpull = (u8)((le16_to_cpu(config.gpio_mode) & + CP210X_GPIO_MODE_MASK) >> + CP210X_GPIO_MODE_OFFSET); + gpio_latch = (u8)((le16_to_cpu(config.reset_state) & + CP210X_GPIO_MODE_MASK) >> + CP210X_GPIO_MODE_OFFSET); + + /* mark all pins which are not in GPIO mode */ + if (iface_config & CP2104_GPIO0_TXLED_MODE) /* GPIO 0 */ + priv->gpio_altfunc |= BIT(0); + if (iface_config & CP2104_GPIO1_RXLED_MODE) /* GPIO 1 */ + priv->gpio_altfunc |= BIT(1); + if (iface_config & CP2104_GPIO2_RS485_MODE) /* GPIO 2 */ + priv->gpio_altfunc |= BIT(2); + + /* + * Like CP2102N, CP2104 has also no strict input and output pin + * modes. + * Do the same input mode emulation as CP2102N. + */ + for (i = 0; i < priv->gc.ngpio; ++i) { + /* + * Set direction to "input" iff pin is open-drain and reset + * value is 1. + */ + if (!(priv->gpio_pushpull & BIT(i)) && (gpio_latch & BIT(i))) + priv->gpio_input |= BIT(i); + } + + return 0; +} + static int cp2102n_gpioconf_init(struct usb_serial *serial) { struct cp210x_serial_private *priv = usb_get_serial_data(serial); @@ -1627,6 +1698,9 @@ static int cp210x_gpio_init(struct usb_serial *serial) int result; switch (priv->partnum) { + case CP210X_PARTNUM_CP2104: + result = cp2104_gpioconf_init(serial); + break; case CP210X_PARTNUM_CP2105: result = cp2105_gpioconf_init(serial); break; -- cgit v1.2.3-58-ga151 From 1381a5113caf764f090b912b478663275e7b999e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 5 Feb 2019 09:00:14 +0200 Subject: usb: dwc3: debug: purge usage of strcat Now that buffer size is always passed around, we don't need to rely on strcat anymore. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/debug.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h index e925a6b73005..6759a7efd8d5 100644 --- a/drivers/usb/dwc3/debug.h +++ b/drivers/usb/dwc3/debug.h @@ -545,21 +545,25 @@ static inline const char *dwc3_ep_event_string(char *str, size_t size, status & DEPEVT_STATUS_TRANSFER_ACTIVE ? " (Active)" : " (Not Active)"); + len = strlen(str); + /* Control Endpoints */ if (epnum <= 1) { int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); switch (phase) { case DEPEVT_STATUS_CONTROL_DATA: - strcat(str, " [Data Phase]"); + snprintf(str + ret, size - ret, + " [Data Phase]"); break; case DEPEVT_STATUS_CONTROL_STATUS: - strcat(str, " [Status Phase]"); + snprintf(str + ret, size - ret, + " [Status Phase]"); } } break; case DWC3_DEPEVT_RXTXFIFOEVT: - strcat(str, "FIFO"); + snprintf(str + ret, size - ret, "FIFO"); break; case DWC3_DEPEVT_STREAMEVT: status = event->status; @@ -571,13 +575,13 @@ static inline const char *dwc3_ep_event_string(char *str, size_t size, break; case DEPEVT_STREAMEVT_NOTFOUND: default: - strcat(str, " Stream Not Found"); + snprintf(str + ret, size - ret, " Stream Not Found"); break; } break; case DWC3_DEPEVT_EPCMDCMPLT: - strcat(str, "Endpoint Command Complete"); + snprintf(str + ret, size - ret, "Endpoint Command Complete"); break; default: snprintf(str, size, "UNKNOWN"); -- cgit v1.2.3-58-ga151 From 1e19a520a9258f3c7286826e7172e56bf6da86dc Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 5 Feb 2019 14:33:02 -0500 Subject: USB: gadget: Improve kerneldoc for usb_ep_dequeue() Commit bf594c1070f5 ("USB: gadget: Document that certain ep operations can be called in interrupt context") documented that usb_ep_dequeue() may be called in a non-process context. It follows that the routine must not sleep or wait for events. However, the routine's existing kerneldoc seems to imply that it will wait until the request being cancelled has fully completed. This is not so, and thus the comment needs to be improved. Misunderstanding this point may very well have been responsible for a bug recently uncovered in the f_fs function. The updated comment explicitly says that the routine may return before the request's completion handler is called. Signed-off-by: Alan Stern CC: John Stultz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 87d6b12779f2..7cf34beb50df 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -281,10 +281,10 @@ EXPORT_SYMBOL_GPL(usb_ep_queue); * @ep:the endpoint associated with the request * @req:the request being canceled * - * If the request is still active on the endpoint, it is dequeued and its - * completion routine is called (with status -ECONNRESET); else a negative - * error code is returned. This is guaranteed to happen before the call to - * usb_ep_dequeue() returns. + * If the request is still active on the endpoint, it is dequeued and + * eventually its completion routine is called (with status -ECONNRESET); + * else a negative error code is returned. This routine is asynchronous, + * that is, it may return before the completion routine runs. * * Note that some hardware can't clear out write fifos (to unlink the request * at the head of the queue) except as part of disconnecting from usb. Such -- cgit v1.2.3-58-ga151 From 836bcab50624d728abeab3766f356d54c48ea1b1 Mon Sep 17 00:00:00 2001 From: Guido Kiener Date: Mon, 4 Feb 2019 19:04:20 +0100 Subject: udc: net2280: Fix net2280_disable A reset e.g. calling ep_reset_338x() can happen while endpoints are enabled. The ep_reset_338x() sets ep->desc = NULL to mark endpoint being invalid. A subsequent call of net2280_disable will fail and return -EINVAL to parent function usb_ep_disable(), which will fail, too, and do not set the member ep->enabled = false. See: https://elixir.bootlin.com/linux/v5.0-rc5/source/drivers/usb/gadget/udc/core.c#L139 This fix ignores dp->desc and allows net2280_disable() to succeed. Subsequent calls to usb_ep_enable()/usb_ep_disable() succeeds. Acked-by: Alan Stern Signed-off-by: Guido Kiener Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index e7dae5379e04..7154f00dea40 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -516,8 +516,8 @@ static int net2280_disable(struct usb_ep *_ep) unsigned long flags; ep = container_of(_ep, struct net2280_ep, ep); - if (!_ep || !ep->desc || _ep->name == ep0name) { - pr_err("%s: Invalid ep=%p or ep->desc\n", __func__, _ep); + if (!_ep || _ep->name == ep0name) { + pr_err("%s: Invalid ep=%p\n", __func__, _ep); return -EINVAL; } spin_lock_irqsave(&ep->dev->lock, flags); -- cgit v1.2.3-58-ga151 From e4e2c343a82d286e5e6f042e3ffbae950eb30369 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Sun, 23 Dec 2018 07:03:30 +0000 Subject: phy: freescale: Break dependency on SOC_IMX8MQ for USB PHY Since this is going to be used on more SoCs than just i.MX8MQ, make the dependency here more generic. Signed-off-by: Abel Vesa Reviewed-by: Dong Aisheng Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/freescale/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig index f050bd4e97e0..832670b4952b 100644 --- a/drivers/phy/freescale/Kconfig +++ b/drivers/phy/freescale/Kconfig @@ -2,4 +2,4 @@ config PHY_FSL_IMX8MQ_USB tristate "Freescale i.MX8M USB3 PHY" depends on OF && HAS_IOMEM select GENERIC_PHY - default SOC_IMX8MQ + default ARCH_MXC && ARM64 -- cgit v1.2.3-58-ga151 From 4f0960ba7a6aedee18d5749e13ac74afe939bf2e Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Thu, 13 Dec 2018 20:21:21 +0000 Subject: dt-bindings: rcar-gen3-phy-usb2: Add r8a774c0 support Document RZ/G2E (R8A774C0) SoC bindings. Signed-off-by: Fabrizio Castro Reviewed-by: Yoshihiro Shimoda Reviewed-by: Simon Horman Reviewed-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt index de7b5393c163..ad9c290d8f15 100644 --- a/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt +++ b/Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb2.txt @@ -5,6 +5,8 @@ This file provides information on what the device node for the R-Car generation Required properties: - compatible: "renesas,usb2-phy-r8a774a1" if the device is a part of an R8A774A1 + SoC. + "renesas,usb2-phy-r8a774c0" if the device is a part of an R8A774C0 SoC. "renesas,usb2-phy-r8a7795" if the device is a part of an R8A7795 SoC. -- cgit v1.2.3-58-ga151 From 32fcf6fc6c71ffb29f31cffe6e93f4389757cb19 Mon Sep 17 00:00:00 2001 From: Marc Gonzalez Date: Fri, 21 Dec 2018 11:13:18 +0100 Subject: phy: qcom-ufs: Use iopoll.h readl_poll_timeout macro The private copy of readl_poll_timeout is no longer needed. Use the implementation in iopoll.h instead. Signed-off-by: Marc Gonzalez Reviewed-by: Bjorn Andersson Reviewed-by: Andy Gross Reviewed-by: Vivek Gautam Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/qualcomm/phy-qcom-ufs-i.h | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index 681644e43248..f798fb64de94 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -23,24 +23,7 @@ #include #include #include - -#define readl_poll_timeout(addr, val, cond, sleep_us, timeout_us) \ -({ \ - ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ - might_sleep_if(timeout_us); \ - for (;;) { \ - (val) = readl(addr); \ - if (cond) \ - break; \ - if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ - (val) = readl(addr); \ - break; \ - } \ - if (sleep_us) \ - usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \ - } \ - (cond) ? 0 : -ETIMEDOUT; \ -}) +#include #define UFS_QCOM_PHY_CAL_ENTRY(reg, val) \ { \ -- cgit v1.2.3-58-ga151 From ed31ee7cf1fea2463d9600ac91ed74691b88131f Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 5 Dec 2018 17:03:23 +0200 Subject: phy: ti: usb2: Fix logic on -EPROBE_DEFER If clk_get() returns -EPROBE_DEFER then we should just return instead of falling back to old clock name. Use clk_prepare_enable() and clk_disable_unprepare() instead of splitting up prepare/unprepare from enable/disable. Signed-off-by: Roger Quadros Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/ti/phy-omap-usb2.c | 88 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index fe909fd8144f..418e7f1a113b 100644 --- a/drivers/phy/ti/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c @@ -135,9 +135,9 @@ static int omap_usb_power_on(struct phy *x) static int omap_usb2_disable_clocks(struct omap_usb *phy) { - clk_disable(phy->wkupclk); + clk_disable_unprepare(phy->wkupclk); if (!IS_ERR(phy->optclk)) - clk_disable(phy->optclk); + clk_disable_unprepare(phy->optclk); return 0; } @@ -146,14 +146,14 @@ static int omap_usb2_enable_clocks(struct omap_usb *phy) { int ret; - ret = clk_enable(phy->wkupclk); + ret = clk_prepare_enable(phy->wkupclk); if (ret < 0) { dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); goto err0; } if (!IS_ERR(phy->optclk)) { - ret = clk_enable(phy->optclk); + ret = clk_prepare_enable(phy->optclk); if (ret < 0) { dev_err(phy->dev, "Failed to enable optclk %d\n", ret); goto err1; @@ -346,63 +346,72 @@ static int omap_usb2_probe(struct platform_device *pdev) } } - otg->set_host = omap_usb_set_host; - otg->set_peripheral = omap_usb_set_peripheral; - if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) - otg->set_vbus = omap_usb_set_vbus; - if (phy_data->flags & OMAP_USB2_HAS_START_SRP) - otg->start_srp = omap_usb_start_srp; - otg->usb_phy = &phy->phy; - - platform_set_drvdata(pdev, phy); - pm_runtime_enable(phy->dev); - - generic_phy = devm_phy_create(phy->dev, NULL, &ops); - if (IS_ERR(generic_phy)) { - pm_runtime_disable(phy->dev); - return PTR_ERR(generic_phy); - } - - phy_set_drvdata(generic_phy, phy); - omap_usb_power_off(generic_phy); - - phy_provider = devm_of_phy_provider_register(phy->dev, - of_phy_simple_xlate); - if (IS_ERR(phy_provider)) { - pm_runtime_disable(phy->dev); - return PTR_ERR(phy_provider); - } phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); if (IS_ERR(phy->wkupclk)) { - dev_warn(&pdev->dev, "unable to get wkupclk, trying old name\n"); + if (PTR_ERR(phy->wkupclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + dev_warn(&pdev->dev, "unable to get wkupclk %ld, trying old name\n", + PTR_ERR(phy->wkupclk)); phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); + if (IS_ERR(phy->wkupclk)) { - dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); - pm_runtime_disable(phy->dev); + if (PTR_ERR(phy->wkupclk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); return PTR_ERR(phy->wkupclk); } else { dev_warn(&pdev->dev, "found usb_phy_cm_clk32k, please fix DTS\n"); } } - clk_prepare(phy->wkupclk); phy->optclk = devm_clk_get(phy->dev, "refclk"); if (IS_ERR(phy->optclk)) { + if (PTR_ERR(phy->optclk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_dbg(&pdev->dev, "unable to get refclk, trying old name\n"); phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m"); + if (IS_ERR(phy->optclk)) { - dev_dbg(&pdev->dev, - "unable to get usb_otg_ss_refclk960m\n"); + if (PTR_ERR(phy->optclk) != -EPROBE_DEFER) { + dev_dbg(&pdev->dev, + "unable to get usb_otg_ss_refclk960m\n"); + } } else { dev_warn(&pdev->dev, "found usb_otg_ss_refclk960m, please fix DTS\n"); } } - if (!IS_ERR(phy->optclk)) - clk_prepare(phy->optclk); + otg->set_host = omap_usb_set_host; + otg->set_peripheral = omap_usb_set_peripheral; + if (phy_data->flags & OMAP_USB2_HAS_SET_VBUS) + otg->set_vbus = omap_usb_set_vbus; + if (phy_data->flags & OMAP_USB2_HAS_START_SRP) + otg->start_srp = omap_usb_start_srp; + otg->usb_phy = &phy->phy; + + platform_set_drvdata(pdev, phy); + pm_runtime_enable(phy->dev); + + generic_phy = devm_phy_create(phy->dev, NULL, &ops); + if (IS_ERR(generic_phy)) { + pm_runtime_disable(phy->dev); + return PTR_ERR(generic_phy); + } + + phy_set_drvdata(generic_phy, phy); + omap_usb_power_off(generic_phy); + + phy_provider = devm_of_phy_provider_register(phy->dev, + of_phy_simple_xlate); + if (IS_ERR(phy_provider)) { + pm_runtime_disable(phy->dev); + return PTR_ERR(phy_provider); + } + usb_add_phy_dev(&phy->phy); @@ -413,9 +422,6 @@ static int omap_usb2_remove(struct platform_device *pdev) { struct omap_usb *phy = platform_get_drvdata(pdev); - clk_unprepare(phy->wkupclk); - if (!IS_ERR(phy->optclk)) - clk_unprepare(phy->optclk); usb_remove_phy(&phy->phy); pm_runtime_disable(phy->dev); -- cgit v1.2.3-58-ga151 From 266744faec8c197dcc86ba2f24951a69dc4d3671 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 5 Dec 2018 17:03:24 +0200 Subject: phy: ti: Don't depend on OMAP_OCP2SCP TI_PIPE3 and OMAP_USB2 don't depend on OMAP_OCP2SCP for build. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/ti/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig index f137e0107764..2388b1b65fc5 100644 --- a/drivers/phy/ti/Kconfig +++ b/drivers/phy/ti/Kconfig @@ -38,7 +38,6 @@ config OMAP_USB2 select GENERIC_PHY select USB_PHY select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP help Enable this to support the transceiver that is part of SOC. This driver takes care of all the PHY functionality apart from comparator. @@ -50,7 +49,6 @@ config TI_PIPE3 depends on ARCH_OMAP2PLUS || COMPILE_TEST select GENERIC_PHY select OMAP_CONTROL_PHY - depends on OMAP_OCP2SCP help Enable this to support the PIPE3 PHY that is part of TI SOCs. This driver takes care of all the PHY functionality apart from comparator. -- cgit v1.2.3-58-ga151 From e712792ec0dd90124e7d943a782372679350488d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 5 Dec 2018 17:03:25 +0200 Subject: dt-bindings: phy: ti: Add support for AM654x USB2 PHY Add support for USB2 PHY on AM654x SoC. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Reviewed-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/ti-phy.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt index 57dfda8a7a1d..8f93c3b694a7 100644 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt @@ -35,6 +35,7 @@ Required properties: DRA7x Should be "ti,dra7x-usb2-phy2" for the 2nd instance of USB2 PHY in DRA7x + Should be "ti,am654-usb2" for the USB2 PHYs on AM654. - reg : Address and length of the register set for the device. - #phy-cells: determine the number of cells that should be given in the phandle while referencing this phy. -- cgit v1.2.3-58-ga151 From 6777cee3a872f8aedc41b95532f4177a5678cb31 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 5 Dec 2018 17:03:26 +0200 Subject: phy: ti: usb2: Add support for AM654 USB2 PHY Add support for the USB2 PHY on the AM654 SoC. Signed-off-by: Roger Quadros Signed-off-by: Sekhar Nori Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/ti/Kconfig | 4 ++-- drivers/phy/ti/phy-omap-usb2.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig index 2388b1b65fc5..bf3d23a6d469 100644 --- a/drivers/phy/ti/Kconfig +++ b/drivers/phy/ti/Kconfig @@ -33,11 +33,11 @@ config OMAP_CONTROL_PHY config OMAP_USB2 tristate "OMAP USB2 PHY Driver" - depends on ARCH_OMAP2PLUS + depends on ARCH_OMAP2PLUS || ARCH_K3 depends on USB_SUPPORT select GENERIC_PHY select USB_PHY - select OMAP_CONTROL_PHY + select OMAP_CONTROL_PHY if ARCH_OMAP2PLUS help Enable this to support the transceiver that is part of SOC. This driver takes care of all the PHY functionality apart from comparator. diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index 418e7f1a113b..e871f2983a0e 100644 --- a/drivers/phy/ti/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c @@ -36,6 +36,10 @@ #define USB2PHY_DISCON_BYP_LATCH (1 << 31) #define USB2PHY_ANA_CONFIG1 0x4c +#define AM654_USB2_OTG_PD BIT(8) +#define AM654_USB2_VBUS_DET_EN BIT(5) +#define AM654_USB2_VBUSVALID_DET_EN BIT(4) + /** * omap_usb2_set_comparator - links the comparator present in the sytem with * this phy @@ -245,6 +249,15 @@ static const struct usb_phy_data am437x_usb2_data = { .power_off = AM437X_USB2_PHY_PD | AM437X_USB2_OTG_PD, }; +static const struct usb_phy_data am654_usb2_data = { + .label = "am654_usb2", + .flags = OMAP_USB2_CALIBRATE_FALSE_DISCONNECT, + .mask = AM654_USB2_OTG_PD | AM654_USB2_VBUS_DET_EN | + AM654_USB2_VBUSVALID_DET_EN, + .power_on = AM654_USB2_VBUS_DET_EN | AM654_USB2_VBUSVALID_DET_EN, + .power_off = AM654_USB2_OTG_PD, +}; + static const struct of_device_id omap_usb2_id_table[] = { { .compatible = "ti,omap-usb2", @@ -266,6 +279,10 @@ static const struct of_device_id omap_usb2_id_table[] = { .compatible = "ti,am437x-usb2", .data = &am437x_usb2_data, }, + { + .compatible = "ti,am654-usb2", + .data = &am654_usb2_data, + }, {}, }; MODULE_DEVICE_TABLE(of, omap_usb2_id_table); -- cgit v1.2.3-58-ga151 From 8fa0402ba33677fb084f37e96be3e57aecf8abaf Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 9 Jan 2019 11:32:06 +0100 Subject: phy: rockchip-inno-usb2: fix misspelling and kernel-doc documentation Fix the typo flase -> false and clean up the kernel-doc documentation in phy-rockchip-inno.usb2.c and fix the following warnings when documentation is built. :58: warning: missing initial short description :69: warning: cannot understand function prototype: 'enum usb_chg_state ' :97: warning: missing initial short description :136: warning: cannot understand function prototype: 'struct rockchip_usb2phy_port_cfg ' :157: warning: cannot understand function prototype: 'struct rockchip_usb2phy_cfg ' :163: warning: Function parameter or member 'port_cfgs' not described in 'rockchip_usb2phy_cfg' :187: warning: cannot understand function prototype: 'struct rockchip_usb2phy_port ' :204: warning: Function parameter or member 'port_cfg' not described in 'rockchip_usb2phy_port' :207: warning: missing initial short description :234: warning: Function parameter or member 'dev' not described in 'rockchip_usb2phy' :234: warning: Function parameter or member 'clk480m_hw' not described in 'rockchip_usb2phy' Signed-off-by: Enric Balletbo i Serra Reviewed-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 91fba60267a0..a1f2253d60c1 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -55,16 +55,16 @@ enum rockchip_usb2phy_host_state { }; /** - * Different states involved in USB charger detection. - * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection + * enum usb_chg_state - Different states involved in USB charger detection. + * @USB_CHG_STATE_UNDEFINED: USB charger is not connected or detection * process is not yet started. - * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact. - * USB_CHG_STATE_DCD_DONE Data pin contact is detected. - * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects + * @USB_CHG_STATE_WAIT_FOR_DCD: Waiting for Data pins contact. + * @USB_CHG_STATE_DCD_DONE: Data pin contact is detected. + * @USB_CHG_STATE_PRIMARY_DONE: Primary detection is completed (Detects * between SDP and DCP/CDP). - * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects - * between DCP and CDP). - * USB_CHG_STATE_DETECTED USB charger type is determined. + * @USB_CHG_STATE_SECONDARY_DONE: Secondary detection is completed (Detects + * between DCP and CDP). + * @USB_CHG_STATE_DETECTED: USB charger type is determined. */ enum usb_chg_state { USB_CHG_STATE_UNDEFINED = 0, @@ -94,7 +94,7 @@ struct usb2phy_reg { }; /** - * struct rockchip_chg_det_reg: usb charger detect registers + * struct rockchip_chg_det_reg - usb charger detect registers * @cp_det: charging port detected successfully. * @dcp_det: dedicated charging port detected successfully. * @dp_det: assert data pin connect successfully. @@ -120,7 +120,7 @@ struct rockchip_chg_det_reg { }; /** - * struct rockchip_usb2phy_port_cfg: usb-phy port configuration. + * struct rockchip_usb2phy_port_cfg - usb-phy port configuration. * @phy_sus: phy suspend register. * @bvalid_det_en: vbus valid rise detection enable register. * @bvalid_det_st: vbus valid rise detection status register. @@ -148,10 +148,11 @@ struct rockchip_usb2phy_port_cfg { }; /** - * struct rockchip_usb2phy_cfg: usb-phy configuration. + * struct rockchip_usb2phy_cfg - usb-phy configuration. * @reg: the address offset of grf for usb-phy config. * @num_ports: specify how many ports that the phy has. * @clkout_ctl: keep on/turn off output clk of phy. + * @port_cfgs: usb-phy port configurations. * @chg_det: charger detection registers. */ struct rockchip_usb2phy_cfg { @@ -163,12 +164,13 @@ struct rockchip_usb2phy_cfg { }; /** - * struct rockchip_usb2phy_port: usb-phy port data. + * struct rockchip_usb2phy_port - usb-phy port data. + * @phy: generic phy. * @port_id: flag for otg port or host port. * @suspended: phy suspended flag. * @utmi_avalid: utmi avalid status usage flag. * true - use avalid to get vbus status - * flase - use bvalid to get vbus status + * false - use bvalid to get vbus status * @vbus_attached: otg device vbus status. * @bvalid_irq: IRQ number assigned for vbus valid rise detection. * @ls_irq: IRQ number assigned for linestate detection. @@ -178,7 +180,7 @@ struct rockchip_usb2phy_cfg { * @chg_work: charge detect work. * @otg_sm_work: OTG state machine work. * @sm_work: HOST state machine work. - * @phy_cfg: port register configuration, assigned by driver data. + * @port_cfg: port register configuration, assigned by driver data. * @event_nb: hold event notification callback. * @state: define OTG enumeration states before device reset. * @mode: the dr_mode of the controller. @@ -203,12 +205,13 @@ struct rockchip_usb2phy_port { }; /** - * struct rockchip_usb2phy: usb2.0 phy driver data. + * struct rockchip_usb2phy - usb2.0 phy driver data. + * @dev: pointer to device. * @grf: General Register Files regmap. * @usbgrf: USB General Register Files regmap. * @clk: clock struct of phy input clk. * @clk480m: clock struct of phy output clk. - * @clk_hw: clock struct of phy output clk management. + * @clk480m_hw: clock struct of phy output clk management. * @chg_state: states involved in USB charger detection. * @chg_type: USB charger types. * @dcd_retries: The retry count used to track Data contact -- cgit v1.2.3-58-ga151 From 68eab01c2179b6ea5132b069cc89b18ca6ef5cb3 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 9 Jan 2019 18:17:39 +0100 Subject: dt-bindings: phy-rockchip-inno-usb2: add documentation for extcon property Commit 98898f3bc83c8 ("phy: rockchip-inno-usb2: support otg-port for rk3399") introduces the extcon property that is used to detect the cable-state. Document this property in the documentation binding. Fixes: 98898f3bc83c8 ("phy: rockchip-inno-usb2: support otg-port for rk3399") Signed-off-by: Enric Balletbo i Serra Reviewed-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt index 074a7b3b0425..00639baae74a 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.txt @@ -23,6 +23,8 @@ Optional properties: register files". When set driver will request its phandle as one companion-grf for some special SoCs (e.g RV1108). + - extcon : phandle to the extcon device providing the cable state for + the otg phy. Required nodes : a sub-node is required for each port the phy provides. The sub-node name is used to identify host or otg port, -- cgit v1.2.3-58-ga151 From 0ade2930fccf6fbd1e03832b654bf603f6d1afab Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 14 Jan 2019 09:36:11 -0700 Subject: dt-bindings: phy-qcom: Add support for msm8998 usb USB on msm8998 utilizes the QUSB2 and QMP phys, similar to sdm845. Signed-off-by: Jeffrey Hugo Reviewed-by: Bjorn Andersson Signed-off-by: Kishon Vijay Abraham I --- Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt | 5 +++++ Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt | 1 + 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt index 41a1074228ba..4ff26dbf4310 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt @@ -9,6 +9,7 @@ Required properties: "qcom,ipq8074-qmp-pcie-phy" for PCIe phy on IPQ8074 "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996, "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996, + "qcom,msm8998-qmp-usb3-phy" for USB3 QMP V3 phy on msm8998, "qcom,sdm845-qmp-usb3-phy" for USB3 QMP V3 phy on sdm845, "qcom,sdm845-qmp-usb3-uni-phy" for USB3 QMP V3 UNI phy on sdm845, "qcom,sdm845-qmp-ufs-phy" for UFS QMP phy on sdm845. @@ -42,6 +43,8 @@ Required properties: "aux", "cfg_ahb", "ref". For "qcom,msm8996-qmp-usb3-phy" must contain: "aux", "cfg_ahb", "ref". + For "qcom,msm8998-qmp-usb3-phy" must contain: + "aux", "cfg_ahb", "ref". For "qcom,sdm845-qmp-usb3-phy" must contain: "aux", "cfg_ahb", "ref", "com_aux". For "qcom,sdm845-qmp-usb3-uni-phy" must contain: @@ -61,6 +64,8 @@ Required properties: "phy", "common", "cfg". For "qcom,msm8996-qmp-usb3-phy" must contain "phy", "common". + For "qcom,msm8998-qmp-usb3-phy" must contain + "phy", "common". For "qcom,sdm845-qmp-usb3-phy" must contain: "phy", "common". For "qcom,sdm845-qmp-usb3-uni-phy" must contain: diff --git a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt index 03025d97998b..fe29f9e0af6d 100644 --- a/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt +++ b/Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt @@ -6,6 +6,7 @@ QUSB2 controller supports LS/FS/HS usb connectivity on Qualcomm chipsets. Required properties: - compatible: compatible list, contains "qcom,msm8996-qusb2-phy" for 14nm PHY on msm8996, + "qcom,msm8998-qusb2-phy" for 10nm PHY on msm8998, "qcom,sdm845-qusb2-phy" for 10nm PHY on sdm845. - reg: offset and length of the PHY register set. -- cgit v1.2.3-58-ga151 From a51969fafc824037234fc67ce1acc4617c488c76 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 14 Jan 2019 09:36:59 -0700 Subject: phy: qcom-qmp: Add QMP V3 USB3 PHY support for msm8998 MSM8998 contains a single QMP v3 USB3 phy similar to the existing sdm845 support. Signed-off-by: Jeffrey Hugo Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/qualcomm/phy-qcom-qmp.c | 140 ++++++++++++++++++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-qmp.h | 4 ++ 2 files changed, 144 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c index b4006818e1b6..daf751500232 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -687,6 +687,116 @@ static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V3_PCS_MULTI_LANE_CTRL1, 0x02), }; +static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85), + QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05), +}; + +static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TX_LARGE_AMP_DRV_LVL, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13), +}; + + /* struct qmp_phy_cfg - per-PHY initialization config */ struct qmp_phy_cfg { /* phy-type - PCIE/UFS/USB */ @@ -1036,6 +1146,33 @@ static const struct qmp_phy_cfg sdm845_ufsphy_cfg = { .no_pcs_sw_reset = true, }; +static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { + .type = PHY_TYPE_USB3, + .nlanes = 1, + + .serdes_tbl = msm8998_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(msm8998_usb3_serdes_tbl), + .tx_tbl = msm8998_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(msm8998_usb3_tx_tbl), + .rx_tbl = msm8998_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), + .pcs_tbl = msm8998_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), + .clk_list = msm8996_phy_clk_l, + .num_clks = ARRAY_SIZE(msm8996_phy_clk_l), + .reset_list = msm8996_usb3phy_reset_l, + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = qmp_v3_usb3phy_regs_layout, + + .start_ctrl = SERDES_START | PCS_START, + .pwrdn_ctrl = SW_PWRDN, + .mask_pcs_ready = PHYSTATUS, + + .is_dual_lane_phy = true, +}; + static void qcom_qmp_phy_configure(void __iomem *base, const unsigned int *regs, const struct qmp_phy_init_tbl tbl[], @@ -1747,6 +1884,9 @@ static const struct of_device_id qcom_qmp_phy_of_match_table[] = { }, { .compatible = "qcom,sdm845-qmp-ufs-phy", .data = &sdm845_ufsphy_cfg, + }, { + .compatible = "qcom,msm8998-qmp-usb3-phy", + .data = &msm8998_usb3phy_cfg, }, { }, }; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index d201cc307151..a1b6cdee9a08 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -174,6 +174,7 @@ #define QSERDES_V3_COM_DIV_FRAC_START1_MODE1 0x0c4 #define QSERDES_V3_COM_DIV_FRAC_START2_MODE1 0x0c8 #define QSERDES_V3_COM_DIV_FRAC_START3_MODE1 0x0cc +#define QSERDES_V3_COM_INTEGLOOP_INITVAL 0x0d0 #define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0 0x0d8 #define QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0 0x0dc #define QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1 0x0e0 @@ -201,6 +202,7 @@ #define QSERDES_V3_COM_DEBUG_BUS2 0x170 #define QSERDES_V3_COM_DEBUG_BUS3 0x174 #define QSERDES_V3_COM_DEBUG_BUS_SEL 0x178 +#define QSERDES_V3_COM_CMN_MODE 0x184 /* Only for QMP V3 PHY - TX registers */ #define QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX 0x044 @@ -211,6 +213,7 @@ #define QSERDES_V3_TX_RCV_DETECT_LVL_2 0x0a4 /* Only for QMP V3 PHY - RX registers */ +#define QSERDES_V3_RX_UCDR_FO_GAIN 0x008 #define QSERDES_V3_RX_UCDR_SO_GAIN_HALF 0x00c #define QSERDES_V3_RX_UCDR_SO_GAIN 0x014 #define QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF 0x024 @@ -219,6 +222,7 @@ #define QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN 0x030 #define QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 #define QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c +#define QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040 #define QSERDES_V3_RX_UCDR_PI_CONTROLS 0x044 #define QSERDES_V3_RX_RX_TERM_BW 0x07c #define QSERDES_V3_RX_VGA_CAL_CNTRL1 0x0bc -- cgit v1.2.3-58-ga151 From 31926c217b5a7a5c2014c89f686b51ce9d1df2df Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 16 Jan 2019 11:08:23 +0100 Subject: phy: phy-rockchip-inno-usb2: drop reading the utmi-avalid property That property is no used in mainline and is not documented. The only board using that property is the rk33-99-evb-rev1 and -rev2 in the vendor kernel. The existence of a further -rev3 (which also looks way better cared for compared rev1+2) indicates that the older ones are probably some sort of preproduction models, where some wiring (on the soc or board) may have gone wrong. It is also not clear why this is a hardware-description or a DT property, so, as noboby seems to care of this just drop reading that property. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Heiko Stuebner Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index a1f2253d60c1..ba07121c3eff 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -168,9 +168,6 @@ struct rockchip_usb2phy_cfg { * @phy: generic phy. * @port_id: flag for otg port or host port. * @suspended: phy suspended flag. - * @utmi_avalid: utmi avalid status usage flag. - * true - use avalid to get vbus status - * false - use bvalid to get vbus status * @vbus_attached: otg device vbus status. * @bvalid_irq: IRQ number assigned for vbus valid rise detection. * @ls_irq: IRQ number assigned for linestate detection. @@ -189,7 +186,6 @@ struct rockchip_usb2phy_port { struct phy *phy; unsigned int port_id; bool suspended; - bool utmi_avalid; bool vbus_attached; int bvalid_irq; int ls_irq; @@ -545,12 +541,8 @@ static void rockchip_usb2phy_otg_sm_work(struct work_struct *work) unsigned long delay; bool vbus_attach, sch_work, notify_charger; - if (rport->utmi_avalid) - vbus_attach = property_enabled(rphy->grf, - &rport->port_cfg->utmi_avalid); - else - vbus_attach = property_enabled(rphy->grf, - &rport->port_cfg->utmi_bvalid); + vbus_attach = property_enabled(rphy->grf, + &rport->port_cfg->utmi_bvalid); sch_work = false; notify_charger = false; @@ -1024,9 +1016,6 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy, INIT_DELAYED_WORK(&rport->chg_work, rockchip_chg_detect_work); INIT_DELAYED_WORK(&rport->otg_sm_work, rockchip_usb2phy_otg_sm_work); - rport->utmi_avalid = - of_property_read_bool(child_np, "rockchip,utmi-avalid"); - /* * Some SoCs use one interrupt with otg-id/otg-bvalid/linestate * interrupts muxed together, so probe the otg-mux interrupt first, -- cgit v1.2.3-58-ga151 From e74f0f8a170fd6113f28bfa8482d8808f8e30112 Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Mon, 14 Jan 2019 09:36:42 -0700 Subject: phy: qcom-qusb2: Add QUSB2 PHY support for msm8998 MSM8998 contains one QUSB2 PHY which is very similar to the existing sdm845 support. Signed-off-by: Jeffrey Hugo Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/qualcomm/phy-qcom-qusb2.c | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-qusb2.c b/drivers/phy/qualcomm/phy-qcom-qusb2.c index 9177989f22d1..8fd7ce139772 100644 --- a/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -152,6 +152,31 @@ static const struct qusb2_phy_init_tbl msm8996_init_tbl[] = { QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00), }; +static const unsigned int msm8998_regs_layout[] = { + [QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8, + [QUSB2PHY_PLL_STATUS] = 0x1a0, + [QUSB2PHY_PORT_TUNE1] = 0x23c, + [QUSB2PHY_PORT_TUNE2] = 0x240, + [QUSB2PHY_PORT_TUNE3] = 0x244, + [QUSB2PHY_PORT_TUNE4] = 0x248, + [QUSB2PHY_PORT_TEST1] = 0x24c, + [QUSB2PHY_PORT_TEST2] = 0x250, + [QUSB2PHY_PORT_POWERDOWN] = 0x210, + [QUSB2PHY_INTR_CTRL] = 0x22c, +}; + +static const struct qusb2_phy_init_tbl msm8998_init_tbl[] = { + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_ANALOG_CONTROLS_TWO, 0x13), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CLOCK_INVERTERS, 0x7c), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_CMODE, 0x80), + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_LOCK_DELAY, 0x0a), + + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0xa5), + QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x09), + + QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_DIGITAL_TIMERS_TWO, 0x19), +}; + static const unsigned int sdm845_regs_layout[] = { [QUSB2PHY_PLL_CORE_INPUT_OVERRIDE] = 0xa8, [QUSB2PHY_PLL_STATUS] = 0x1a0, @@ -221,6 +246,18 @@ static const struct qusb2_phy_cfg msm8996_phy_cfg = { .autoresume_en = BIT(3), }; +static const struct qusb2_phy_cfg msm8998_phy_cfg = { + .tbl = msm8998_init_tbl, + .tbl_num = ARRAY_SIZE(msm8998_init_tbl), + .regs = msm8998_regs_layout, + + .disable_ctrl = POWER_DOWN, + .mask_core_ready = CORE_READY_STATUS, + .has_pll_override = true, + .autoresume_en = BIT(0), + .update_tune1_with_efuse = true, +}; + static const struct qusb2_phy_cfg sdm845_phy_cfg = { .tbl = sdm845_init_tbl, .tbl_num = ARRAY_SIZE(sdm845_init_tbl), @@ -733,6 +770,9 @@ static const struct of_device_id qusb2_phy_of_match_table[] = { { .compatible = "qcom,msm8996-qusb2-phy", .data = &msm8996_phy_cfg, + }, { + .compatible = "qcom,msm8998-qusb2-phy", + .data = &msm8998_phy_cfg, }, { .compatible = "qcom,sdm845-qusb2-phy", .data = &sdm845_phy_cfg, -- cgit v1.2.3-58-ga151 From cc013c285e3f6c3b7d8b15d39fa53848f9013990 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 9 Dec 2018 19:34:48 -0500 Subject: phy: make phy-core explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/phy/Kconfig:config GENERIC_PHY drivers/phy/Kconfig: bool "PHY Core" ...meaning that it currently is not being built as a module by anyone. Lets remove the modular code that is essentially orphaned, so that when reading the driver there is no doubt it is builtin-only. Since module_init translates to device_initcall in the non-modular case, the init ordering remains unchanged with this commit. We don't remove module.h since the file is using other modular fcns (to load other phy modules) even though the core support itself is non-modular. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Cc: Kishon Vijay Abraham I Signed-off-by: Paul Gortmaker Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/phy-core.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 19b05e824ee4..cb38f6e8614c 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -1112,14 +1112,4 @@ static int __init phy_core_init(void) return 0; } -module_init(phy_core_init); - -static void __exit phy_core_exit(void) -{ - class_destroy(phy_class); -} -module_exit(phy_core_exit); - -MODULE_DESCRIPTION("Generic PHY Framework"); -MODULE_AUTHOR("Kishon Vijay Abraham I "); -MODULE_LICENSE("GPL v2"); +device_initcall(phy_core_init); -- cgit v1.2.3-58-ga151 From a211034a0d3752bce6968f6cae3857c79ac0f998 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 9 Dec 2018 19:34:49 -0500 Subject: phy: make phy-mvebu-sata explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/phy/Kconfig:config PHY_MVEBU_SATA drivers/phy/Kconfig: def_bool y ...meaning that it currently is not being built as a module by anyone. Lets remove the couple of traces of modular infrastructure, so that when reading the driver there is no doubt it is builtin-only. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Cc: Kishon Vijay Abraham I Cc: Andrew Lunn Signed-off-by: Paul Gortmaker Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-sata.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/phy/marvell/phy-mvebu-sata.c b/drivers/phy/marvell/phy-mvebu-sata.c index 768ce92e81ce..369fece2be7a 100644 --- a/drivers/phy/marvell/phy-mvebu-sata.c +++ b/drivers/phy/marvell/phy-mvebu-sata.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include @@ -122,7 +122,6 @@ static const struct of_device_id phy_mvebu_sata_of_match[] = { { .compatible = "marvell,mvebu-sata-phy" }, { }, }; -MODULE_DEVICE_TABLE(of, phy_mvebu_sata_of_match); static struct platform_driver phy_mvebu_sata_driver = { .probe = phy_mvebu_sata_probe, @@ -131,8 +130,4 @@ static struct platform_driver phy_mvebu_sata_driver = { .of_match_table = phy_mvebu_sata_of_match, } }; -module_platform_driver(phy_mvebu_sata_driver); - -MODULE_AUTHOR("Andrew Lunn "); -MODULE_DESCRIPTION("Marvell MVEBU SATA PHY driver"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver(phy_mvebu_sata_driver); -- cgit v1.2.3-58-ga151 From 4a72dcbee944a70843458692c6b7fa13045c1232 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 9 Dec 2018 19:34:50 -0500 Subject: phy: make phy-armada375-usb2 explicitly non-modular The Kconfig currently controlling compilation of this code is: drivers/phy/marvell/Kconfig:config ARMADA375_USBCLUSTER_PHY drivers/phy/marvell/Kconfig: def_bool y ...meaning that it currently is not being built as a module by anyone. Lets remove the couple of traces of modular infrastructure, so that when reading the driver there is no doubt it is builtin-only. Since module_platform_driver() uses the same init level priority as builtin_platform_driver() the init ordering remains unchanged with this commit. Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code. We also delete the MODULE_LICENSE tag etc. since all that information is already contained at the top of the file in the comments. Cc: Kishon Vijay Abraham I Cc: Gregory CLEMENT Signed-off-by: Paul Gortmaker Reviewed-by: Gregory CLEMENT Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-armada375-usb2.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c index 1a3db288c0a9..4f0295992500 100644 --- a/drivers/phy/marvell/phy-armada375-usb2.c +++ b/drivers/phy/marvell/phy-armada375-usb2.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -142,7 +141,6 @@ static const struct of_device_id of_usb_cluster_table[] = { { .compatible = "marvell,armada-375-usb-cluster", }, { /* end of list */ }, }; -MODULE_DEVICE_TABLE(of, of_usb_cluster_table); static struct platform_driver armada375_usb_phy_driver = { .probe = armada375_usb_phy_probe, @@ -151,8 +149,4 @@ static struct platform_driver armada375_usb_phy_driver = { .name = "armada-375-usb-cluster", } }; -module_platform_driver(armada375_usb_phy_driver); - -MODULE_DESCRIPTION("Armada 375 USB cluster driver"); -MODULE_AUTHOR("Gregory CLEMENT "); -MODULE_LICENSE("GPL"); +builtin_platform_driver(armada375_usb_phy_driver); -- cgit v1.2.3-58-ga151 From 65f04fea91cf8e271cae2077cf0c5a73a630aef6 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 18 Jan 2019 16:01:46 +0100 Subject: phy: armada375-usb2: switch to SPDX license identifier Adopt the SPDX license identifier headers to ease license compliance management. Signed-off-by: Gregory CLEMENT Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-armada375-usb2.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/phy/marvell/phy-armada375-usb2.c b/drivers/phy/marvell/phy-armada375-usb2.c index 4f0295992500..fa5dc9462d09 100644 --- a/drivers/phy/marvell/phy-armada375-usb2.c +++ b/drivers/phy/marvell/phy-armada375-usb2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * USB cluster support for Armada 375 platform. * @@ -5,10 +6,6 @@ * * Gregory CLEMENT * - * This file is licensed under the terms of the GNU General Public - * License version 2 or later. This program is licensed "as is" - * without any warranty of any kind, whether express or implied. - * * Armada 375 comes with an USB2 host and device controller and an * USB3 controller. The USB cluster control register allows to manage * common features of both USB controllers. -- cgit v1.2.3-58-ga151 From ae4c5d69acc012ba40680cf8b63a2845622cc7c7 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 8 Jan 2019 17:31:18 +0100 Subject: phy: mvebu-cp110-comphy: fix port check in ->xlate() So far the PHY ->xlate() callback was checking if the port was "invalid" before continuing, meaning that the port has not been used yet. This check is not correct as there is no opposite call to ->xlate() once the PHY is released by the user and the port will remain "valid" after the first phy_get()/phy_put() calls. Hence, if this driver is built as a module, inserted, removed and inserted again, the PHY will appear busy and the second probe will fail. To fix this, just drop the faulty check and instead verify that the port number is valid (ie. in the possible range). Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/phy-mvebu-cp110-comphy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c index 187cccde53b5..d98e0451f6a1 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -580,8 +580,6 @@ static struct phy *mvebu_comphy_xlate(struct device *dev, return phy; lane = phy_get_drvdata(phy); - if (lane->port >= 0) - return ERR_PTR(-EBUSY); lane->port = args->args[0]; return phy; -- cgit v1.2.3-58-ga151 From 9695375a3f4a604406f2e61f2b735eca1de931ed Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 8 Jan 2019 17:31:20 +0100 Subject: phy: add A3700 COMPHY support Add a driver to support COMPHY, a hardware block providing shared serdes PHYs on Marvell Armada 3700. This driver uses SMC calls and rely on having an up-to-date firmware. SATA, PCie and USB3 host mode have been tested successfully with an ESPRESSObin. (HS)SGMII mode cannot be tested with this platform. Evan worked on the original driver structure and Grzegorz on the SMC calls rework. The structure of this driver has been copied from Antoine Tenart work on CP110 COMPHY driver. Signed-off-by: Miquel Raynal Co-developed-by: Evan Wang Signed-off-by: Evan Wang Co-developed-by: Grzegorz Jaszczyk Signed-off-by: Grzegorz Jaszczyk Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/Kconfig | 12 + drivers/phy/marvell/Makefile | 1 + drivers/phy/marvell/phy-mvebu-a3700-comphy.c | 318 +++++++++++++++++++++++++++ 3 files changed, 331 insertions(+) create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-comphy.c diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig index 6fb4b56e4c14..9c90c0408ea3 100644 --- a/drivers/phy/marvell/Kconfig +++ b/drivers/phy/marvell/Kconfig @@ -21,6 +21,18 @@ config PHY_BERLIN_USB help Enable this to support the USB PHY on Marvell Berlin SoCs. +config PHY_MVEBU_A3700_COMPHY + tristate "Marvell A3700 comphy driver" + depends on ARCH_MVEBU || COMPILE_TEST + depends on OF + depends on HAVE_ARM_SMCCC + default y + select GENERIC_PHY + help + This driver allows to control the comphy, a hardware block providing + shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be + used by various controllers: Ethernet, SATA, USB3, PCIe. + config PHY_MVEBU_CP110_COMPHY tristate "Marvell CP110 comphy driver" depends on ARCH_MVEBU || COMPILE_TEST diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile index 3975b144f8ec..c13a0c8ab6f0 100644 --- a/drivers/phy/marvell/Makefile +++ b/drivers/phy/marvell/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o +obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o diff --git a/drivers/phy/marvell/phy-mvebu-a3700-comphy.c b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c new file mode 100644 index 000000000000..8812a104c233 --- /dev/null +++ b/drivers/phy/marvell/phy-mvebu-a3700-comphy.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Marvell + * + * Authors: + * Evan Wang + * Miquèl Raynal + * + * Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart. + * SMC call initial support done by Grzegorz Jaszczyk. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MVEBU_A3700_COMPHY_LANES 3 +#define MVEBU_A3700_COMPHY_PORTS 2 + +/* COMPHY Fast SMC function identifiers */ +#define COMPHY_SIP_POWER_ON 0x82000001 +#define COMPHY_SIP_POWER_OFF 0x82000002 +#define COMPHY_SIP_PLL_LOCK 0x82000003 + +#define COMPHY_FW_MODE_SATA 0x1 +#define COMPHY_FW_MODE_SGMII 0x2 +#define COMPHY_FW_MODE_HS_SGMII 0x3 +#define COMPHY_FW_MODE_USB3H 0x4 +#define COMPHY_FW_MODE_USB3D 0x5 +#define COMPHY_FW_MODE_PCIE 0x6 +#define COMPHY_FW_MODE_RXAUI 0x7 +#define COMPHY_FW_MODE_XFI 0x8 +#define COMPHY_FW_MODE_SFI 0x9 +#define COMPHY_FW_MODE_USB3 0xa + +#define COMPHY_FW_SPEED_1_25G 0 /* SGMII 1G */ +#define COMPHY_FW_SPEED_2_5G 1 +#define COMPHY_FW_SPEED_3_125G 2 /* SGMII 2.5G */ +#define COMPHY_FW_SPEED_5G 3 +#define COMPHY_FW_SPEED_5_15625G 4 /* XFI 5G */ +#define COMPHY_FW_SPEED_6G 5 +#define COMPHY_FW_SPEED_10_3125G 6 /* XFI 10G */ +#define COMPHY_FW_SPEED_MAX 0x3F + +#define COMPHY_FW_MODE(mode) ((mode) << 12) +#define COMPHY_FW_NET(mode, idx, speed) (COMPHY_FW_MODE(mode) | \ + ((idx) << 8) | \ + ((speed) << 2)) +#define COMPHY_FW_PCIE(mode, idx, speed, width) (COMPHY_FW_NET(mode, idx, speed) | \ + ((width) << 18)) + +struct mvebu_a3700_comphy_conf { + unsigned int lane; + enum phy_mode mode; + int submode; + unsigned int port; + u32 fw_mode; +}; + +#define MVEBU_A3700_COMPHY_CONF(_lane, _mode, _smode, _port, _fw) \ + { \ + .lane = _lane, \ + .mode = _mode, \ + .submode = _smode, \ + .port = _port, \ + .fw_mode = _fw, \ + } + +#define MVEBU_A3700_COMPHY_CONF_GEN(_lane, _mode, _port, _fw) \ + MVEBU_A3700_COMPHY_CONF(_lane, _mode, PHY_INTERFACE_MODE_NA, _port, _fw) + +#define MVEBU_A3700_COMPHY_CONF_ETH(_lane, _smode, _port, _fw) \ + MVEBU_A3700_COMPHY_CONF(_lane, PHY_MODE_ETHERNET, _smode, _port, _fw) + +static const struct mvebu_a3700_comphy_conf mvebu_a3700_comphy_modes[] = { + /* lane 0 */ + MVEBU_A3700_COMPHY_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0, + COMPHY_FW_MODE_USB3H), + MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_SGMII, 1, + COMPHY_FW_MODE_SGMII), + MVEBU_A3700_COMPHY_CONF_ETH(0, PHY_INTERFACE_MODE_2500BASEX, 1, + COMPHY_FW_MODE_HS_SGMII), + /* lane 1 */ + MVEBU_A3700_COMPHY_CONF_GEN(1, PHY_MODE_PCIE, 0, + COMPHY_FW_MODE_PCIE), + MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0, + COMPHY_FW_MODE_SGMII), + MVEBU_A3700_COMPHY_CONF_ETH(1, PHY_INTERFACE_MODE_2500BASEX, 0, + COMPHY_FW_MODE_HS_SGMII), + /* lane 2 */ + MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_SATA, 0, + COMPHY_FW_MODE_SATA), + MVEBU_A3700_COMPHY_CONF_GEN(2, PHY_MODE_USB_HOST_SS, 0, + COMPHY_FW_MODE_USB3H), +}; + +struct mvebu_a3700_comphy_lane { + struct device *dev; + unsigned int id; + enum phy_mode mode; + int submode; + int port; +}; + +static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane, + unsigned long mode) +{ + struct arm_smccc_res res; + + arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); + + return res.a0; +} + +static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, + enum phy_mode mode, + int submode) +{ + int i, n = ARRAY_SIZE(mvebu_a3700_comphy_modes); + + /* Unused PHY mux value is 0x0 */ + if (mode == PHY_MODE_INVALID) + return -EINVAL; + + for (i = 0; i < n; i++) { + if (mvebu_a3700_comphy_modes[i].lane == lane && + mvebu_a3700_comphy_modes[i].port == port && + mvebu_a3700_comphy_modes[i].mode == mode && + mvebu_a3700_comphy_modes[i].submode == submode) + break; + } + + if (i == n) + return -EINVAL; + + return mvebu_a3700_comphy_modes[i].fw_mode; +} + +static int mvebu_a3700_comphy_set_mode(struct phy *phy, enum phy_mode mode, + int submode) +{ + struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); + int fw_mode; + + if (submode == PHY_INTERFACE_MODE_1000BASEX) + submode = PHY_INTERFACE_MODE_SGMII; + + fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, mode, + submode); + if (fw_mode < 0) { + dev_err(lane->dev, "invalid COMPHY mode\n"); + return fw_mode; + } + + /* Just remember the mode, ->power_on() will do the real setup */ + lane->mode = mode; + lane->submode = submode; + + return 0; +} + +static int mvebu_a3700_comphy_power_on(struct phy *phy) +{ + struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); + u32 fw_param; + int fw_mode; + + fw_mode = mvebu_a3700_comphy_get_fw_mode(lane->id, lane->port, + lane->mode, lane->submode); + if (fw_mode < 0) { + dev_err(lane->dev, "invalid COMPHY mode\n"); + return fw_mode; + } + + switch (lane->mode) { + case PHY_MODE_USB_HOST_SS: + dev_dbg(lane->dev, "set lane %d to USB3 host mode\n", lane->id); + fw_param = COMPHY_FW_MODE(fw_mode); + break; + case PHY_MODE_SATA: + dev_dbg(lane->dev, "set lane %d to SATA mode\n", lane->id); + fw_param = COMPHY_FW_MODE(fw_mode); + break; + case PHY_MODE_ETHERNET: + switch (lane->submode) { + case PHY_INTERFACE_MODE_SGMII: + dev_dbg(lane->dev, "set lane %d to SGMII mode\n", + lane->id); + fw_param = COMPHY_FW_NET(fw_mode, lane->port, + COMPHY_FW_SPEED_1_25G); + break; + case PHY_INTERFACE_MODE_2500BASEX: + dev_dbg(lane->dev, "set lane %d to HS SGMII mode\n", + lane->id); + fw_param = COMPHY_FW_NET(fw_mode, lane->port, + COMPHY_FW_SPEED_3_125G); + break; + default: + dev_err(lane->dev, "unsupported PHY submode (%d)\n", + lane->submode); + return -ENOTSUPP; + } + break; + case PHY_MODE_PCIE: + dev_dbg(lane->dev, "set lane %d to PCIe mode\n", lane->id); + fw_param = COMPHY_FW_PCIE(fw_mode, lane->port, + COMPHY_FW_SPEED_5G, + phy->attrs.bus_width); + break; + default: + dev_err(lane->dev, "unsupported PHY mode (%d)\n", lane->mode); + return -ENOTSUPP; + } + + return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); +} + +static int mvebu_a3700_comphy_power_off(struct phy *phy) +{ + struct mvebu_a3700_comphy_lane *lane = phy_get_drvdata(phy); + + return mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_OFF, lane->id, 0); +} + +static const struct phy_ops mvebu_a3700_comphy_ops = { + .power_on = mvebu_a3700_comphy_power_on, + .power_off = mvebu_a3700_comphy_power_off, + .set_mode = mvebu_a3700_comphy_set_mode, + .owner = THIS_MODULE, +}; + +static struct phy *mvebu_a3700_comphy_xlate(struct device *dev, + struct of_phandle_args *args) +{ + struct mvebu_a3700_comphy_lane *lane; + struct phy *phy; + + if (WARN_ON(args->args[0] >= MVEBU_A3700_COMPHY_PORTS)) + return ERR_PTR(-EINVAL); + + phy = of_phy_simple_xlate(dev, args); + if (IS_ERR(phy)) + return phy; + + lane = phy_get_drvdata(phy); + lane->port = args->args[0]; + + return phy; +} + +static int mvebu_a3700_comphy_probe(struct platform_device *pdev) +{ + struct phy_provider *provider; + struct device_node *child; + + for_each_available_child_of_node(pdev->dev.of_node, child) { + struct mvebu_a3700_comphy_lane *lane; + struct phy *phy; + int ret; + u32 lane_id; + + ret = of_property_read_u32(child, "reg", &lane_id); + if (ret < 0) { + dev_err(&pdev->dev, "missing 'reg' property (%d)\n", + ret); + continue; + } + + if (lane_id >= MVEBU_A3700_COMPHY_LANES) { + dev_err(&pdev->dev, "invalid 'reg' property\n"); + continue; + } + + lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL); + if (!lane) + return -ENOMEM; + + phy = devm_phy_create(&pdev->dev, child, + &mvebu_a3700_comphy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + lane->dev = &pdev->dev; + lane->mode = PHY_MODE_INVALID; + lane->submode = PHY_INTERFACE_MODE_NA; + lane->id = lane_id; + lane->port = -1; + phy_set_drvdata(phy, lane); + } + + provider = devm_of_phy_provider_register(&pdev->dev, + mvebu_a3700_comphy_xlate); + return PTR_ERR_OR_ZERO(provider); +} + +static const struct of_device_id mvebu_a3700_comphy_of_match_table[] = { + { .compatible = "marvell,comphy-a3700" }, + { }, +}; +MODULE_DEVICE_TABLE(of, mvebu_a3700_comphy_of_match_table); + +static struct platform_driver mvebu_a3700_comphy_driver = { + .probe = mvebu_a3700_comphy_probe, + .driver = { + .name = "mvebu-a3700-comphy", + .of_match_table = mvebu_a3700_comphy_of_match_table, + }, +}; +module_platform_driver(mvebu_a3700_comphy_driver); + +MODULE_AUTHOR("Miquèl Raynal "); +MODULE_DESCRIPTION("Common PHY driver for A3700"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-58-ga151 From 6362f0a68d244bc54610ce8238ec46726bb4019f Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 8 Jan 2019 17:31:21 +0100 Subject: dt-bindings: phy: mvebu-comphy: extend the file to describe a3700 bindings Current file describe COMPHY bindings for the IP available on the CP110 of Armada 7k/8k. Bindings are very close (and serve the same purpose) as the new Armada 3700 COMPHY driver so update this file to describe both. Also add an example of how to use this second compatible (same as for the ESPRESSObin). While doing so, enhance a bit the file by adding upper case where needed. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/phy-mvebu-comphy.txt | 65 ++++++++++++++++++---- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt index bfcf80341657..cf2cd86db267 100644 --- a/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt +++ b/Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt @@ -1,16 +1,27 @@ -mvebu comphy driver -------------------- +MVEBU comphy drivers +-------------------- -A comphy controller can be found on Marvell Armada 7k/8k on the CP110. It -provides a number of shared PHYs used by various interfaces (network, sata, -usb, PCIe...). +COMPHY controllers can be found on the following Marvell MVEBU SoCs: +* Armada 7k/8k (on the CP110) +* Armada 3700 +It provides a number of shared PHYs used by various interfaces (network, SATA, +USB, PCIe...). Required properties: -- compatible: should be "marvell,comphy-cp110" -- reg: should contain the comphy register location and length. -- marvell,system-controller: should contain a phandle to the - system controller node. +- compatible: should be one of: + * "marvell,comphy-cp110" for Armada 7k/8k + * "marvell,comphy-a3700" for Armada 3700 +- reg: should contain the COMPHY register(s) location(s) and length(s). + * 1 entry for Armada 7k/8k + * 4 entries for Armada 3700 along with the corresponding reg-names + properties, memory areas are: + * Generic COMPHY registers + * Lane 1 (PCIe/GbE) + * Lane 0 (USB3/GbE) + * Lane 2 (SATA/USB3) +- marvell,system-controller: should contain a phandle to the system + controller node (only for Armada 7k/8k) - #address-cells: should be 1. - #size-cells: should be 0. @@ -18,11 +29,11 @@ A sub-node is required for each comphy lane provided by the comphy. Required properties (child nodes): -- reg: comphy lane number. -- #phy-cells : from the generic phy bindings, must be 1. Defines the +- reg: COMPHY lane number. +- #phy-cells : from the generic PHY bindings, must be 1. Defines the input port to use for a given comphy lane. -Example: +Examples: cpm_comphy: phy@120000 { compatible = "marvell,comphy-cp110"; @@ -41,3 +52,33 @@ Example: #phy-cells = <1>; }; }; + + comphy: phy@18300 { + compatible = "marvell,comphy-a3700"; + reg = <0x18300 0x300>, + <0x1F000 0x400>, + <0x5C000 0x400>, + <0xe0178 0x8>; + reg-names = "comphy", + "lane1_pcie_gbe", + "lane0_usb3_gbe", + "lane2_sata_usb3"; + #address-cells = <1>; + #size-cells = <0>; + + + comphy0: phy@0 { + reg = <0>; + #phy-cells = <1>; + }; + + comphy1: phy@1 { + reg = <1>; + #phy-cells = <1>; + }; + + comphy2: phy@2 { + reg = <2>; + #phy-cells = <1>; + }; + }; -- cgit v1.2.3-58-ga151 From e25909f9b7feb58e6ba976d404e9bb53349b67bf Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 8 Jan 2019 17:31:22 +0100 Subject: MAINTAINERS: phy: add entry for Armada 3700 COMPHY driver Add myself as Armada 3700 COMPHY driver/bindings maintainer. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 32d444476a90..abfd80f21b24 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9080,6 +9080,12 @@ F: drivers/gpu/drm/armada/ F: include/uapi/drm/armada_drm.h F: Documentation/devicetree/bindings/display/armada/ +MARVELL ARMADA 3700 COMPHY DRIVER +M: Miquel Raynal +S: Maintained +F: drivers/phy/marvell/phy-mvebu-a3700-comphy.c +F: Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt + MARVELL CRYPTO DRIVER M: Boris Brezillon M: Arnaud Ebalard -- cgit v1.2.3-58-ga151 From cc8b7a0ae866bb2ac8e4d089173a5e676105c8cb Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:36:30 +0100 Subject: phy: add A3700 UTMI PHY driver Marvell Armada 3700 SoC has two USB controllers, each of them being wired to an internal UTMI PHY. Add a driver to control them. Igal Liberman worked on supporting the PHY, I took the while 'register configuration' from his work and rewrote almost entirely the driver/bindings around it. Co-developed-by: Igal Liberman Signed-off-by: Miquel Raynal Signed-off-by: Igal Liberman Signed-off-by: Kishon Vijay Abraham I --- drivers/phy/marvell/Kconfig | 9 + drivers/phy/marvell/Makefile | 1 + drivers/phy/marvell/phy-mvebu-a3700-utmi.c | 278 +++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+) create mode 100644 drivers/phy/marvell/phy-mvebu-a3700-utmi.c diff --git a/drivers/phy/marvell/Kconfig b/drivers/phy/marvell/Kconfig index 9c90c0408ea3..b8e9dd38ad0d 100644 --- a/drivers/phy/marvell/Kconfig +++ b/drivers/phy/marvell/Kconfig @@ -33,6 +33,15 @@ config PHY_MVEBU_A3700_COMPHY shared serdes PHYs on Marvell Armada 3700. Its serdes lanes can be used by various controllers: Ethernet, SATA, USB3, PCIe. +config PHY_MVEBU_A3700_UTMI + tristate "Marvell A3700 UTMI driver" + depends on ARCH_MVEBU || COMPILE_TEST + depends on OF + default y + select GENERIC_PHY + help + Enable this to support Marvell A3700 UTMI PHY driver. + config PHY_MVEBU_CP110_COMPHY tristate "Marvell CP110 comphy driver" depends on ARCH_MVEBU || COMPILE_TEST diff --git a/drivers/phy/marvell/Makefile b/drivers/phy/marvell/Makefile index c13a0c8ab6f0..82f291cf59ee 100644 --- a/drivers/phy/marvell/Makefile +++ b/drivers/phy/marvell/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_MVEBU_A3700_COMPHY) += phy-mvebu-a3700-comphy.o +obj-$(CONFIG_PHY_MVEBU_A3700_UTMI) += phy-mvebu-a3700-utmi.o obj-$(CONFIG_PHY_MVEBU_CP110_COMPHY) += phy-mvebu-cp110-comphy.o obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o diff --git a/drivers/phy/marvell/phy-mvebu-a3700-utmi.c b/drivers/phy/marvell/phy-mvebu-a3700-utmi.c new file mode 100644 index 000000000000..94a29dea57af --- /dev/null +++ b/drivers/phy/marvell/phy-mvebu-a3700-utmi.c @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Marvell + * + * Authors: + * Igal Liberman + * Miquèl Raynal + * + * Marvell A3700 UTMI PHY driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Armada 3700 UTMI PHY registers */ +#define USB2_PHY_PLL_CTRL_REG0 0x0 +#define PLL_REF_DIV_OFF 0 +#define PLL_REF_DIV_MASK GENMASK(6, 0) +#define PLL_REF_DIV_5 5 +#define PLL_FB_DIV_OFF 16 +#define PLL_FB_DIV_MASK GENMASK(24, 16) +#define PLL_FB_DIV_96 96 +#define PLL_SEL_LPFR_OFF 28 +#define PLL_SEL_LPFR_MASK GENMASK(29, 28) +#define PLL_READY BIT(31) +#define USB2_PHY_CAL_CTRL 0x8 +#define PHY_PLLCAL_DONE BIT(31) +#define PHY_IMPCAL_DONE BIT(23) +#define USB2_RX_CHAN_CTRL1 0x18 +#define USB2PHY_SQCAL_DONE BIT(31) +#define USB2_PHY_OTG_CTRL 0x34 +#define PHY_PU_OTG BIT(4) +#define USB2_PHY_CHRGR_DETECT 0x38 +#define PHY_CDP_EN BIT(2) +#define PHY_DCP_EN BIT(3) +#define PHY_PD_EN BIT(4) +#define PHY_PU_CHRG_DTC BIT(5) +#define PHY_CDP_DM_AUTO BIT(7) +#define PHY_ENSWITCH_DP BIT(12) +#define PHY_ENSWITCH_DM BIT(13) + +/* Armada 3700 USB miscellaneous registers */ +#define USB2_PHY_CTRL(usb32) (usb32 ? 0x20 : 0x4) +#define RB_USB2PHY_PU BIT(0) +#define USB2_DP_PULLDN_DEV_MODE BIT(5) +#define USB2_DM_PULLDN_DEV_MODE BIT(6) +#define RB_USB2PHY_SUSPM(usb32) (usb32 ? BIT(14) : BIT(7)) + +#define PLL_LOCK_DELAY_US 10000 +#define PLL_LOCK_TIMEOUT_US 1000000 + +/** + * struct mvebu_a3700_utmi_caps - PHY capabilities + * + * @usb32: Flag indicating which PHY is in use (impacts the register map): + * - The UTMI PHY wired to the USB3/USB2 controller (otg) + * - The UTMI PHY wired to the USB2 controller (host only) + * @ops: PHY operations + */ +struct mvebu_a3700_utmi_caps { + int usb32; + const struct phy_ops *ops; +}; + +/** + * struct mvebu_a3700_utmi - PHY driver data + * + * @regs: PHY registers + * @usb_mis: Regmap with USB miscellaneous registers including PHY ones + * @caps: PHY capabilities + * @phy: PHY handle + */ +struct mvebu_a3700_utmi { + void __iomem *regs; + struct regmap *usb_misc; + const struct mvebu_a3700_utmi_caps *caps; + struct phy *phy; +}; + +static int mvebu_a3700_utmi_phy_power_on(struct phy *phy) +{ + struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy); + struct device *dev = &phy->dev; + int usb32 = utmi->caps->usb32; + int ret = 0; + u32 reg; + + /* + * Setup PLL. 40MHz clock used to be the default, being 25MHz now. + * See "PLL Settings for Typical REFCLK" table. + */ + reg = readl(utmi->regs + USB2_PHY_PLL_CTRL_REG0); + reg &= ~(PLL_REF_DIV_MASK | PLL_FB_DIV_MASK | PLL_SEL_LPFR_MASK); + reg |= (PLL_REF_DIV_5 << PLL_REF_DIV_OFF) | + (PLL_FB_DIV_96 << PLL_FB_DIV_OFF); + writel(reg, utmi->regs + USB2_PHY_PLL_CTRL_REG0); + + /* Enable PHY pull up and disable USB2 suspend */ + regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32), + RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU, + RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU); + + if (usb32) { + /* Power up OTG module */ + reg = readl(utmi->regs + USB2_PHY_OTG_CTRL); + reg |= PHY_PU_OTG; + writel(reg, utmi->regs + USB2_PHY_OTG_CTRL); + + /* Disable PHY charger detection */ + reg = readl(utmi->regs + USB2_PHY_CHRGR_DETECT); + reg &= ~(PHY_CDP_EN | PHY_DCP_EN | PHY_PD_EN | PHY_PU_CHRG_DTC | + PHY_CDP_DM_AUTO | PHY_ENSWITCH_DP | PHY_ENSWITCH_DM); + writel(reg, utmi->regs + USB2_PHY_CHRGR_DETECT); + + /* Disable PHY DP/DM pull-down (used for device mode) */ + regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32), + USB2_DP_PULLDN_DEV_MODE | + USB2_DM_PULLDN_DEV_MODE, 0); + } + + /* Wait for PLL calibration */ + ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg, + reg & PHY_PLLCAL_DONE, + PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US); + if (ret) { + dev_err(dev, "Failed to end USB2 PLL calibration\n"); + return ret; + } + + /* Wait for impedance calibration */ + ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg, + reg & PHY_IMPCAL_DONE, + PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US); + if (ret) { + dev_err(dev, "Failed to end USB2 impedance calibration\n"); + return ret; + } + + /* Wait for squelch calibration */ + ret = readl_poll_timeout(utmi->regs + USB2_RX_CHAN_CTRL1, reg, + reg & USB2PHY_SQCAL_DONE, + PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US); + if (ret) { + dev_err(dev, "Failed to end USB2 unknown calibration\n"); + return ret; + } + + /* Wait for PLL to be locked */ + ret = readl_poll_timeout(utmi->regs + USB2_PHY_PLL_CTRL_REG0, reg, + reg & PLL_READY, + PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US); + if (ret) + dev_err(dev, "Failed to lock USB2 PLL\n"); + + return ret; +} + +static int mvebu_a3700_utmi_phy_power_off(struct phy *phy) +{ + struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy); + int usb32 = utmi->caps->usb32; + u32 reg; + + /* Disable PHY pull-up and enable USB2 suspend */ + reg = readl(utmi->regs + USB2_PHY_CTRL(usb32)); + reg &= ~(RB_USB2PHY_PU | RB_USB2PHY_SUSPM(usb32)); + writel(reg, utmi->regs + USB2_PHY_CTRL(usb32)); + + /* Power down OTG module */ + if (usb32) { + reg = readl(utmi->regs + USB2_PHY_OTG_CTRL); + reg &= ~PHY_PU_OTG; + writel(reg, utmi->regs + USB2_PHY_OTG_CTRL); + } + + return 0; +} + +static const struct phy_ops mvebu_a3700_utmi_phy_ops = { + .power_on = mvebu_a3700_utmi_phy_power_on, + .power_off = mvebu_a3700_utmi_phy_power_off, + .owner = THIS_MODULE, +}; + +static const struct mvebu_a3700_utmi_caps mvebu_a3700_utmi_otg_phy_caps = { + .usb32 = true, + .ops = &mvebu_a3700_utmi_phy_ops, +}; + +static const struct mvebu_a3700_utmi_caps mvebu_a3700_utmi_host_phy_caps = { + .usb32 = false, + .ops = &mvebu_a3700_utmi_phy_ops, +}; + +static const struct of_device_id mvebu_a3700_utmi_of_match[] = { + { + .compatible = "marvell,a3700-utmi-otg-phy", + .data = &mvebu_a3700_utmi_otg_phy_caps, + }, + { + .compatible = "marvell,a3700-utmi-host-phy", + .data = &mvebu_a3700_utmi_host_phy_caps, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, mvebu_a3700_utmi_of_match); + +static int mvebu_a3700_utmi_phy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mvebu_a3700_utmi *utmi; + struct phy_provider *provider; + struct resource *res; + + utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL); + if (!utmi) + return -ENOMEM; + + /* Get UTMI memory region */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "Missing UTMI PHY memory resource\n"); + return -ENODEV; + } + + utmi->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(utmi->regs)) + return PTR_ERR(utmi->regs); + + /* Get miscellaneous Host/PHY region */ + utmi->usb_misc = syscon_regmap_lookup_by_phandle(dev->of_node, + "marvell,usb-misc-reg"); + if (IS_ERR(utmi->usb_misc)) { + dev_err(dev, + "Missing USB misc purpose system controller\n"); + return PTR_ERR(utmi->usb_misc); + } + + /* Retrieve PHY capabilities */ + utmi->caps = of_device_get_match_data(dev); + + /* Instantiate the PHY */ + utmi->phy = devm_phy_create(dev, NULL, utmi->caps->ops); + if (IS_ERR(utmi->phy)) { + dev_err(dev, "Failed to create the UTMI PHY\n"); + return PTR_ERR(utmi->phy); + } + + phy_set_drvdata(utmi->phy, utmi); + + /* Ensure the PHY is powered off */ + utmi->caps->ops->power_off(utmi->phy); + + provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(provider); +} + +static struct platform_driver mvebu_a3700_utmi_driver = { + .probe = mvebu_a3700_utmi_phy_probe, + .driver = { + .name = "mvebu-a3700-utmi-phy", + .owner = THIS_MODULE, + .of_match_table = mvebu_a3700_utmi_of_match, + }, +}; +module_platform_driver(mvebu_a3700_utmi_driver); + +MODULE_AUTHOR("Igal Liberman "); +MODULE_AUTHOR("Miquel Raynal "); +MODULE_DESCRIPTION("Marvell EBU A3700 UTMI PHY driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-58-ga151 From e60958699afa3468cfe36fdd3c2eefdcb5326176 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:36:31 +0100 Subject: dt-bindings: phy: mvebu-utmi: add UTMI PHY bindings Add bindings for Marvell Armada 3700 USB2 UTMI+ PHY. Signed-off-by: Miquel Raynal Reviewed-by: Rob Herring Signed-off-by: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/phy-mvebu-utmi.txt | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt diff --git a/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt b/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt new file mode 100644 index 000000000000..aa99ceec73b0 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt @@ -0,0 +1,38 @@ +MVEBU A3700 UTMI PHY +-------------------- + +USB2 UTMI+ PHY controllers can be found on the following Marvell MVEBU SoCs: +* Armada 3700 + +On Armada 3700, there are two USB controllers, one is compatible with the USB2 +and USB3 specifications and supports OTG. The other one is USB2 compliant and +only supports host mode. Both of these controllers come with a slightly +different UTMI PHY. + +Required Properties: + +- compatible: Should be one of: + * "marvell,a3700-utmi-host-phy" for the PHY connected to + the USB2 host-only controller. + * "marvell,a3700-utmi-otg-phy" for the PHY connected to + the USB3 and USB2 OTG capable controller. +- reg: PHY IP register range. +- marvell,usb-misc-reg: handle on the "USB miscellaneous registers" shared + region covering registers related to both the host + controller and the PHY. +- #phy-cells: Standard property (Documentation: phy-bindings.txt) Should be 0. + + +Example: + + usb2_utmi_host_phy: phy@5f000 { + compatible = "marvell,armada-3700-utmi-host-phy"; + reg = <0x5f000 0x800>; + marvell,usb-misc-reg = <&usb2_syscon>; + #phy-cells = <0>; + }; + + usb2_syscon: system-controller@5f800 { + compatible = "marvell,armada-3700-usb2-host-misc", "syscon"; + reg = <0x5f800 0x800>; + }; -- cgit v1.2.3-58-ga151 From 07830a2a9af4965f642aeb1269dcbce2bc4502bc Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Tue, 29 Jan 2019 10:36:32 +0100 Subject: MAINTAINERS: phy: fill Armada 3700 PHY drivers entry Update the Armada 3700 PHY drivers entry with the recently added UTMI PHY driver. Signed-off-by: Miquel Raynal Signed-off-by: Kishon Vijay Abraham I --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index abfd80f21b24..2a08a097e107 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9080,11 +9080,13 @@ F: drivers/gpu/drm/armada/ F: include/uapi/drm/armada_drm.h F: Documentation/devicetree/bindings/display/armada/ -MARVELL ARMADA 3700 COMPHY DRIVER +MARVELL ARMADA 3700 PHY DRIVERS M: Miquel Raynal S: Maintained F: drivers/phy/marvell/phy-mvebu-a3700-comphy.c +F: drivers/phy/marvell/phy-mvebu-a3700-utmi.c F: Documentation/devicetree/bindings/phy/phy-mvebu-comphy.txt +F: Documentation/devicetree/bindings/phy/phy-mvebu-utmi.txt MARVELL CRYPTO DRIVER M: Boris Brezillon -- cgit v1.2.3-58-ga151 From 752b5da2359fee342d5264e2c10352daf5b9a199 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 21 Jan 2019 16:45:46 +0100 Subject: phy: dphy: Remove unused header The videomode.h header inclusion is an artifact from the patches development, remove it. Suggested-by: Sakari Ailus Acked-by: Sakari Ailus Signed-off-by: Maxime Ripard Signed-off-by: Kishon Vijay Abraham I --- include/linux/phy/phy-mipi-dphy.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h index c08aacc0ac35..9cf97cd1d303 100644 --- a/include/linux/phy/phy-mipi-dphy.h +++ b/include/linux/phy/phy-mipi-dphy.h @@ -6,8 +6,6 @@ #ifndef __PHY_MIPI_DPHY_H_ #define __PHY_MIPI_DPHY_H_ -#include