From fe84f522ed6d27ed0a48e202e04327c2f4891e23 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 1 Sep 2015 09:01:38 -0500 Subject: usb: dwc3: gadget: move trace_dwc3_ep_queue() by moving trace_dwc3_ep_queue() from dwc3_gadget_ep_queue() to __dwc3_gadget_ep_queue() after usb_request is properly initialized, makes for a better output always showing a request with 0 actual and -115 (-EINPROGRESS) status. 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 1e8bdf817811..0429820152f9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1050,6 +1050,8 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) req->direction = dep->direction; req->epnum = dep->number; + trace_dwc3_ep_queue(req); + /* * We only add to our list of requests now and * start consuming the list once we get XferNotReady @@ -1159,8 +1161,6 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, goto out; } - trace_dwc3_ep_queue(req); - ret = __dwc3_gadget_ep_queue(dep, req); out: -- cgit v1.2.3 From 1d6a39186b37b6f5097f9cdee8fcbfc24d231428 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 14 Sep 2015 11:27:46 -0500 Subject: usb: dwc3: gadget: start requests as soon as they come In an attempt to make dwc3 slightly faster, let's start usb_requests as soon as they come as that will let us avoid a XFER_NOT_READY event and save a little bit of time. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0429820152f9..2d0dc2d5c3c6 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1071,6 +1071,22 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) list_add_tail(&req->list, &dep->request_list); + /* + * If there are no pending requests and the endpoint isn't already + * busy, we will just start the request straight away. + * + * This will save one IRQ (XFER_NOT_READY) and possibly make it a + * little bit faster. + */ + if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && + !(dep->flags & DWC3_EP_BUSY)) { + ret = __dwc3_gadget_kick_transfer(dep, 0, true); + if (ret && ret != -EBUSY) + dev_dbg(dwc->dev, "%s: failed to kick transfers\n", + dep->name); + return ret; + } + /* * There are a few special cases: * -- cgit v1.2.3 From 89185916d2295f7c4bc3a05adae25380b3e08e58 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Sep 2015 09:49:14 -0500 Subject: usb: dwc3: gadget: clear DWC3_PENDING_REQUEST when request is queued Instead of clearing DWC3_PENDING_REQUEST when we start transfer, let's do it when the request is actually queued, that way we know for sure that we're clearing in the right time. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 2d0dc2d5c3c6..13ed16a96e37 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -948,7 +948,6 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, dwc3_trace(trace_dwc3_gadget, "%s: endpoint busy", dep->name); return -EBUSY; } - dep->flags &= ~DWC3_EP_PENDING_REQUEST; /* * If we are getting here after a short-out-packet we don't enqueue any @@ -1117,6 +1116,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) if (ret && ret != -EBUSY) dev_dbg(dwc->dev, "%s: failed to kick transfers\n", dep->name); + + if (!ret) + dep->flags &= ~DWC3_EP_PENDING_REQUEST; + return ret; } -- cgit v1.2.3 From a8f32817eeb0ada6367d812de5cd2ee91a532a48 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 16 Sep 2015 10:40:07 -0500 Subject: usb: dwc3: gadget: improve ep_queue's error reporting We shouldn't return -EBUSY, that's used only internally when the core still has transfers in flight on a given endpoint. Also, combine the error reporting so that we don't have to duplicate it. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 13ed16a96e37..201e12342447 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1080,10 +1080,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && !(dep->flags & DWC3_EP_BUSY)) { ret = __dwc3_gadget_kick_transfer(dep, 0, true); - if (ret && ret != -EBUSY) - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", - dep->name); - return ret; + goto out; } /* @@ -1113,14 +1110,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) } ret = __dwc3_gadget_kick_transfer(dep, 0, true); - if (ret && ret != -EBUSY) - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", - dep->name); - if (!ret) dep->flags &= ~DWC3_EP_PENDING_REQUEST; - return ret; + goto out; } /* @@ -1134,10 +1127,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) WARN_ON_ONCE(!dep->resource_index); ret = __dwc3_gadget_kick_transfer(dep, dep->resource_index, false); - if (ret && ret != -EBUSY) - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", - dep->name); - return ret; + goto out; } /* @@ -1145,14 +1135,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) * right away, otherwise host will not know we have streams to be * handled. */ - if (dep->stream_capable) { + if (dep->stream_capable) ret = __dwc3_gadget_kick_transfer(dep, 0, true); - if (ret && ret != -EBUSY) - dev_dbg(dwc->dev, "%s: failed to kick transfers\n", - dep->name); - } - return 0; +out: + if (ret && ret != -EBUSY) + dev_dbg(dwc->dev, "%s: failed to kick transfers\n", + dep->name); + if (ret == -EBUSY) + ret = 0; + + return ret; } static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request, -- cgit v1.2.3 From 2e6c72b61b9a0a7787e8cfa3fff3b34a0c2548ce Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 15 Sep 2015 09:39:45 -0500 Subject: usb: gadget: mass_storage: allow for deeper queue lengths Instead of allowing a range of 2 to 4 requests, let's allow the user choose up to 32 requests as that will give us a better chance of keeping controller busy. We still maintain default of 2 so users shouldn't be affected. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Kconfig | 2 +- drivers/usb/gadget/function/f_mass_storage.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bcf83c0a6e62..33834aa09ed4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -113,7 +113,7 @@ config USB_GADGET_VBUS_DRAW config USB_GADGET_STORAGE_NUM_BUFFERS int "Number of storage pipeline buffers" - range 2 4 + range 2 32 default 2 help Usually 2 buffers are enough to establish a good buffering diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index a6eb537d7768..5277e7c4a82a 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2662,10 +2662,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put); /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) { - if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) +#define FSG_MAX_NUM_BUFFERS 32 + + if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS) return 0; pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", - fsg_num_buffers, 2, 4); + fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS); return -EINVAL; } -- cgit v1.2.3 From f35fe4beb03d4e3203a2bd734d2253060694d98f Mon Sep 17 00:00:00 2001 From: "Felipe F. Tonello" Date: Fri, 18 Sep 2015 18:36:28 +0100 Subject: usb: gadget: f_midi: check for error on usb_ep_queue f_midi is not checking whether there is an error on usb_ep_queue request, ignoring potential problems, such as memory leaks. Signed-off-by: Felipe F. Tonello Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a287a4829273..9fc86d90c7bd 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -547,10 +547,16 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) } } - if (req->length > 0) - usb_ep_queue(ep, req, GFP_ATOMIC); - else + if (req->length > 0) { + int err; + + err = usb_ep_queue(ep, req, GFP_ATOMIC); + if (err < 0) + ERROR(midi, "%s queue req: %d\n", + midi->in_ep->name, err); + } else { free_ep_req(ep, req); + } } static void f_midi_in_tasklet(unsigned long data) -- cgit v1.2.3 From 9b7537642cb6ad400ee4a95114582ba758b3009c Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 9 Sep 2015 13:17:23 -0500 Subject: usb: musb: set the controller speed based on the config setting Set the Power register HSENAB bit based on musb->config->maximum_speed, so that the glue layer can control MUSB to work in high- or full-speed. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 16 ++++++++++------ include/linux/usb/musb.h | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 4a518ff12310..e0e10dd424e0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1028,18 +1028,22 @@ void musb_start(struct musb *musb) { void __iomem *regs = musb->mregs; u8 devctl = musb_readb(regs, MUSB_DEVCTL); + u8 power; dev_dbg(musb->controller, "<== devctl %02x\n", devctl); musb_enable_interrupts(musb); musb_writeb(regs, MUSB_TESTMODE, 0); - /* put into basic highspeed mode and start session */ - musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE - | MUSB_POWER_HSENAB - /* ENSUSPEND wedges tusb */ - /* | MUSB_POWER_ENSUSPEND */ - ); + power = MUSB_POWER_ISOUPDATE; + /* + * treating UNKNOWN as unspecified maximum speed, in which case + * we will default to high-speed. + */ + if (musb->config->maximum_speed == USB_SPEED_HIGH || + musb->config->maximum_speed == USB_SPEED_UNKNOWN) + power |= MUSB_POWER_HSENAB; + musb_writeb(regs, MUSB_POWER, power); musb->is_active = 0; devctl = musb_readb(regs, MUSB_DEVCTL); diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index a4ee1b582183..fa6dc132bd1b 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -95,7 +95,7 @@ struct musb_hdrc_config { /* musb CLKIN in Blackfin in MHZ */ unsigned char clkin; #endif - + u32 maximum_speed; }; struct musb_hdrc_platform_data { -- cgit v1.2.3 From 41932b9b8adc14b5650e8909f66d5bd08619b81c Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 9 Sep 2015 11:56:18 -0500 Subject: usb: musb: dsps: control musb speed based on dts setting Set musb config->maximum_speed based on the dts setting to control musb speed. By default musb works in high-speed mode. Adding maximum-speed = "full-speed"; to dts usb node will force musb to full-speed mode. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 84512d1d5eee..c8b2ec9a79d6 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -747,6 +747,19 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, if (!ret && val) config->multipoint = true; + config->maximum_speed = of_usb_get_maximum_speed(dn); + switch (config->maximum_speed) { + case USB_SPEED_LOW: + case USB_SPEED_FULL: + break; + case USB_SPEED_SUPER: + dev_warn(dev, "ignore incorrect maximum_speed " + "(super-speed) setting in dts"); + /* fall through */ + default: + config->maximum_speed = USB_SPEED_HIGH; + } + ret = platform_device_add_data(musb, &pdata, sizeof(pdata)); if (ret) { dev_err(dev, "failed to add platform_data\n"); -- cgit v1.2.3 From 7ed855e65b4f9ecd8658ddda5d50d0e7399419f3 Mon Sep 17 00:00:00 2001 From: "Ivan T. Ivanov" Date: Mon, 7 Sep 2015 14:24:36 +0300 Subject: usb: phy: qcom: Switch to new extcon framework API [un]register_interest and reading cable state by name have been deprecated. Switch to new API. Signed-off-by: Ivan T. Ivanov Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-qcom-8x16-usb.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/usb/phy/phy-qcom-8x16-usb.c b/drivers/usb/phy/phy-qcom-8x16-usb.c index 5d357a94599e..579587d97217 100644 --- a/drivers/usb/phy/phy-qcom-8x16-usb.c +++ b/drivers/usb/phy/phy-qcom-8x16-usb.c @@ -71,7 +71,7 @@ struct phy_8x16 { struct reset_control *phy_reset; - struct extcon_specific_cable_nb vbus_cable; + struct extcon_dev *vbus_edev; struct notifier_block vbus_notify; struct gpio_desc *switch_gpio; @@ -234,7 +234,7 @@ static int phy_8x16_init(struct usb_phy *phy) val = ULPI_PWR_OTG_COMP_DISABLE; usb_phy_io_write(phy, val, ULPI_SET(ULPI_PWR_CLK_MNG_REG)); - state = extcon_get_cable_state(qphy->vbus_cable.edev, "USB"); + state = extcon_get_cable_state_(qphy->vbus_edev, EXTCON_USB); if (state) phy_8x16_vbus_on(qphy); else @@ -314,7 +314,6 @@ static int phy_8x16_reboot_notify(struct notifier_block *this, static int phy_8x16_probe(struct platform_device *pdev) { - struct extcon_dev *edev; struct phy_8x16 *qphy; struct resource *res; struct usb_phy *phy; @@ -349,9 +348,9 @@ static int phy_8x16_probe(struct platform_device *pdev) if (ret < 0) return ret; - edev = extcon_get_edev_by_phandle(phy->dev, 0); - if (IS_ERR(edev)) - return PTR_ERR(edev); + qphy->vbus_edev = extcon_get_edev_by_phandle(phy->dev, 0); + if (IS_ERR(qphy->vbus_edev)) + return PTR_ERR(qphy->vbus_edev); ret = clk_set_rate(qphy->core_clk, INT_MAX); if (ret < 0) @@ -370,8 +369,8 @@ static int phy_8x16_probe(struct platform_device *pdev) goto off_clks; qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify; - ret = extcon_register_interest(&qphy->vbus_cable, edev->name, - "USB", &qphy->vbus_notify); + ret = extcon_register_notifier(qphy->vbus_edev, EXTCON_USB, + &qphy->vbus_notify); if (ret < 0) goto off_power; @@ -385,7 +384,8 @@ static int phy_8x16_probe(struct platform_device *pdev) return 0; off_extcon: - extcon_unregister_interest(&qphy->vbus_cable); + extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB, + &qphy->vbus_notify); off_power: phy_8x16_regulators_disable(qphy); off_clks: @@ -400,7 +400,8 @@ static int phy_8x16_remove(struct platform_device *pdev) struct phy_8x16 *qphy = platform_get_drvdata(pdev); unregister_reboot_notifier(&qphy->reboot_notify); - extcon_unregister_interest(&qphy->vbus_cable); + extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB, + &qphy->vbus_notify); /* * Ensure that D+/D- lines are routed to uB connector, so -- cgit v1.2.3 From 3737c54418c35034127bf2837e9b27a3c3c67940 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Fri, 4 Sep 2015 10:14:54 +0530 Subject: Documentation: dt: dwc3: Add snps,quirk-frame-length-adjustment property Add snps,quirk-frame-length-adjustment property which provides value for post silicon frame length adjustment Signed-off-by: Nikhil Badola Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 0815eac5b185..8c7d58553681 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -40,6 +40,9 @@ Optional properties: - snps,hird-threshold: HIRD threshold - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3. + - snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ + register for post-silicon frame length adjustment when the + fladj_30mhz_sdbnd signal is invalid or incorrect. This is usually a subnode to DWC3 glue to which it is connected. -- cgit v1.2.3 From db2be4e9e30c6e43e48c5749d3fc74cee0a6bbb3 Mon Sep 17 00:00:00 2001 From: Nikhil Badola Date: Fri, 4 Sep 2015 10:15:58 +0530 Subject: usb: dwc3: Add frame length adjustment quirk Add adjust_frame_length_quirk for writing to fladj register which adjusts (micro)frame length to value provided by "snps,quirk-frame-length-adjustment" property thus avoiding USB 2.0 devices to time-out over a longer run Signed-off-by: Nikhil Badola Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 34 ++++++++++++++++++++++++++++++++++ drivers/usb/dwc3/core.h | 5 +++++ drivers/usb/dwc3/platform_data.h | 2 ++ 3 files changed, 41 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 064123e44566..6270581fc7a9 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -143,6 +143,32 @@ static int dwc3_soft_reset(struct dwc3 *dwc) return 0; } +/* + * dwc3_frame_length_adjustment - Adjusts frame length if required + * @dwc3: Pointer to our controller context structure + * @fladj: Value of GFLADJ_30MHZ to adjust frame length + */ +static void dwc3_frame_length_adjustment(struct dwc3 *dwc, u32 fladj) +{ + u32 reg; + u32 dft; + + if (dwc->revision < DWC3_REVISION_250A) + return; + + if (fladj == 0) + return; + + reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + dft = reg & DWC3_GFLADJ_30MHZ_MASK; + if (!dev_WARN_ONCE(dwc->dev, dft == fladj, + "request value same as default, ignoring\n")) { + reg &= ~DWC3_GFLADJ_30MHZ_MASK; + reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | fladj; + dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + } +} + /** * dwc3_free_one_event_buffer - Frees one event buffer * @dwc: Pointer to our controller context structure @@ -779,6 +805,7 @@ static int dwc3_probe(struct platform_device *pdev) u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; + u32 fladj = 0; int ret; @@ -886,6 +913,9 @@ static int dwc3_probe(struct platform_device *pdev) &tx_de_emphasis); of_property_read_string(node, "snps,hsphy_interface", &dwc->hsphy_interface); + of_property_read_u32(node, + "snps,quirk-frame-length-adjustment", + &fladj); } else if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; @@ -915,6 +945,7 @@ static int dwc3_probe(struct platform_device *pdev) tx_de_emphasis = pdata->tx_de_emphasis; dwc->hsphy_interface = pdata->hsphy_interface; + fladj = pdata->fladj_value; } /* default to superspeed if no maximum_speed passed */ @@ -971,6 +1002,9 @@ static int dwc3_probe(struct platform_device *pdev) goto err1; } + /* Adjust Frame Length */ + dwc3_frame_length_adjustment(dwc, fladj); + usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 044778884585..91887455133a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -124,6 +124,7 @@ #define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10)) #define DWC3_GHWPARAMS8 0xc600 +#define DWC3_GFLADJ 0xc630 /* Device Registers */ #define DWC3_DCFG 0xc700 @@ -234,6 +235,10 @@ /* Global HWPARAMS6 Register */ #define DWC3_GHWPARAMS6_EN_FPGA (1 << 7) +/* Global Frame Length Adjustment Register */ +#define DWC3_GFLADJ_30MHZ_SDBND_SEL (1 << 7) +#define DWC3_GFLADJ_30MHZ_MASK 0x3f + /* Device Configuration Register */ #define DWC3_DCFG_DEVADDR(addr) ((addr) << 3) #define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f) diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index d3614ecbb9ca..400b197d9985 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -46,5 +46,7 @@ struct dwc3_platform_data { unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; + u32 fladj_value; + const char *hsphy_interface; }; -- cgit v1.2.3 From 1f91b4cc03556ba0d43ac80621dac8263cda3880 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 6 Aug 2015 18:11:54 -0500 Subject: usb: dwc2: rename all s3c_* to dwc2_* this driver has long ago became dwc2.ko with both peripheral and host roles, there's no point in keeping the old function names. Acked-by: John Youn Tested-by: John Youn Signed-off-by: Felipe Balbi --- arch/arm/mach-s3c64xx/mach-crag6410.c | 4 +- arch/arm/mach-s3c64xx/mach-smartq.c | 4 +- arch/arm/mach-s3c64xx/mach-smdk6410.c | 4 +- arch/arm/plat-samsung/devs.c | 6 +- drivers/usb/dwc2/core.h | 52 +-- drivers/usb/dwc2/core_intr.c | 4 +- drivers/usb/dwc2/debugfs.c | 20 +- drivers/usb/dwc2/gadget.c | 696 ++++++++++++++++---------------- drivers/usb/dwc2/hcd.c | 4 +- drivers/usb/dwc2/platform.c | 8 +- include/linux/platform_data/s3c-hsotg.h | 10 +- 11 files changed, 406 insertions(+), 406 deletions(-) diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index 65c426bc45f7..14bd9ae3f476 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -809,7 +809,7 @@ static const struct gpio_led_platform_data gpio_leds_pdata = { .num_leds = ARRAY_SIZE(gpio_leds), }; -static struct s3c_hsotg_plat crag6410_hsotg_pdata; +static struct dwc2_hsotg_plat crag6410_hsotg_pdata; static void __init crag6410_machine_init(void) { @@ -835,7 +835,7 @@ static void __init crag6410_machine_init(void) s3c_i2c0_set_platdata(&i2c0_pdata); s3c_i2c1_set_platdata(&i2c1_pdata); s3c_fb_set_platdata(&crag6410_lcd_pdata); - s3c_hsotg_set_platdata(&crag6410_hsotg_pdata); + dwc2_hsotg_set_platdata(&crag6410_hsotg_pdata); i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0)); i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index b3d13537a7f0..719843dca510 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -189,7 +189,7 @@ static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = { }, }; -static struct s3c_hsotg_plat smartq_hsotg_pdata; +static struct dwc2_hsotg_plat smartq_hsotg_pdata; static int __init smartq_lcd_setup_gpio(void) { @@ -382,7 +382,7 @@ void __init smartq_map_io(void) void __init smartq_machine_init(void) { s3c_i2c0_set_platdata(NULL); - s3c_hsotg_set_platdata(&smartq_hsotg_pdata); + dwc2_hsotg_set_platdata(&smartq_hsotg_pdata); s3c_hwmon_set_platdata(&smartq_hwmon_pdata); s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata); s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata); diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index d590b88bd8a8..286c9bd676e1 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -628,7 +628,7 @@ static struct platform_pwm_backlight_data smdk6410_bl_data = { .enable_gpio = -1, }; -static struct s3c_hsotg_plat smdk6410_hsotg_pdata; +static struct dwc2_hsotg_plat smdk6410_hsotg_pdata; static void __init smdk6410_map_io(void) { @@ -659,7 +659,7 @@ static void __init smdk6410_machine_init(void) s3c_i2c0_set_platdata(NULL); s3c_i2c1_set_platdata(NULL); s3c_fb_set_platdata(&smdk6410_lcd_pdata); - s3c_hsotg_set_platdata(&smdk6410_hsotg_pdata); + dwc2_hsotg_set_platdata(&smdk6410_hsotg_pdata); samsung_keypad_set_platdata(&smdk6410_keypad_data); diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 83c7d154bde0..82074625de5c 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -1042,11 +1042,11 @@ struct platform_device s3c_device_usb_hsotg = { }, }; -void __init s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd) +void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd) { - struct s3c_hsotg_plat *npd; + struct dwc2_hsotg_plat *npd; - npd = s3c_set_platdata(pd, sizeof(struct s3c_hsotg_plat), + npd = s3c_set_platdata(pd, sizeof(struct dwc2_hsotg_plat), &s3c_device_usb_hsotg); if (!npd->phy_init) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 0ed87620941b..9655b1ec4f34 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -58,8 +58,8 @@ static inline void do_write(u32 value, void *addr) /* Maximum number of Endpoints/HostChannels */ #define MAX_EPS_CHANNELS 16 -/* s3c-hsotg declarations */ -static const char * const s3c_hsotg_supply_names[] = { +/* dwc2-hsotg declarations */ +static const char * const dwc2_hsotg_supply_names[] = { "vusb_d", /* digital USB supply, 1.2V */ "vusb_a", /* analog USB supply, 1.1V */ }; @@ -85,10 +85,10 @@ static const char * const s3c_hsotg_supply_names[] = { #define EP0_MPS_LIMIT 64 struct dwc2_hsotg; -struct s3c_hsotg_req; +struct dwc2_hsotg_req; /** - * struct s3c_hsotg_ep - driver endpoint definition. + * struct dwc2_hsotg_ep - driver endpoint definition. * @ep: The gadget layer representation of the endpoint. * @name: The driver generated name for the endpoint. * @queue: Queue of requests for this endpoint. @@ -127,11 +127,11 @@ struct s3c_hsotg_req; * as in shared-fifo mode periodic in acts like a single-frame packet * buffer than a fifo) */ -struct s3c_hsotg_ep { +struct dwc2_hsotg_ep { struct usb_ep ep; struct list_head queue; struct dwc2_hsotg *parent; - struct s3c_hsotg_req *req; + struct dwc2_hsotg_req *req; struct dentry *debugfs; unsigned long total_data; @@ -155,12 +155,12 @@ struct s3c_hsotg_ep { }; /** - * struct s3c_hsotg_req - data transfer request + * struct dwc2_hsotg_req - data transfer request * @req: The USB gadget request * @queue: The list of requests for the endpoint this is queued for. * @saved_req_buf: variable to save req.buf when bounce buffers are used. */ -struct s3c_hsotg_req { +struct dwc2_hsotg_req { struct usb_request req; struct list_head queue; void *saved_req_buf; @@ -693,7 +693,7 @@ struct dwc2_hsotg { struct phy *phy; struct usb_phy *uphy; - struct regulator_bulk_data supplies[ARRAY_SIZE(s3c_hsotg_supply_names)]; + struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)]; spinlock_t lock; struct mutex init_mutex; @@ -796,7 +796,7 @@ struct dwc2_hsotg { #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) /* Gadget structures */ struct usb_gadget_driver *driver; - struct s3c_hsotg_plat *plat; + struct dwc2_hsotg_plat *plat; u32 phyif; int fifo_mem; @@ -815,8 +815,8 @@ struct dwc2_hsotg { unsigned int enabled:1; unsigned int connected:1; unsigned long last_rst; - struct s3c_hsotg_ep *eps_in[MAX_EPS_CHANNELS]; - struct s3c_hsotg_ep *eps_out[MAX_EPS_CHANNELS]; + struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS]; + struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS]; u32 g_using_dma; u32 g_rx_fifo_sz; u32 g_np_g_tx_fifo_sz; @@ -1104,30 +1104,30 @@ extern u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg); /* Gadget defines */ #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) -extern int s3c_hsotg_remove(struct dwc2_hsotg *hsotg); -extern int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2); -extern int s3c_hsotg_resume(struct dwc2_hsotg *dwc2); +extern int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg); +extern int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2); +extern int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2); extern int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq); -extern void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, +extern void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, bool reset); -extern void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg); -extern void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2); -extern int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); +extern void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg); +extern void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2); +extern int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode); #define dwc2_is_device_connected(hsotg) (hsotg->connected) #else -static inline int s3c_hsotg_remove(struct dwc2_hsotg *dwc2) +static inline int dwc2_hsotg_remove(struct dwc2_hsotg *dwc2) { return 0; } -static inline int s3c_hsotg_suspend(struct dwc2_hsotg *dwc2) +static inline int dwc2_hsotg_suspend(struct dwc2_hsotg *dwc2) { return 0; } -static inline int s3c_hsotg_resume(struct dwc2_hsotg *dwc2) +static inline int dwc2_hsotg_resume(struct dwc2_hsotg *dwc2) { return 0; } static inline int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { return 0; } -static inline void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, +static inline void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *dwc2, bool reset) {} -static inline void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} -static inline void s3c_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} -static inline int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, +static inline void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hsotg_disconnect(struct dwc2_hsotg *dwc2) {} +static inline int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) { return 0; } #define dwc2_is_device_connected(hsotg) (0) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 927be1e8b3dc..344a859c2153 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -129,7 +129,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) gotgctl = readl(hsotg->regs + GOTGCTL); if (dwc2_is_device_mode(hsotg)) - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); if (hsotg->op_state == OTG_STATE_B_HOST) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; @@ -322,7 +322,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) * Report disconnect if there is any previous session established */ if (dwc2_is_device_mode(hsotg)) - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); } /* diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c index ef2ee3d9a25d..cee3d771b75e 100644 --- a/drivers/usb/dwc2/debugfs.c +++ b/drivers/usb/dwc2/debugfs.c @@ -57,7 +57,7 @@ static ssize_t testmode_write(struct file *file, const char __user *ubuf, size_t testmode = 0; spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_set_test_mode(hsotg, testmode); + dwc2_hsotg_set_test_mode(hsotg, testmode); spin_unlock_irqrestore(&hsotg->lock, flags); return count; } @@ -256,9 +256,9 @@ static const char *decode_direction(int is_in) */ static int ep_show(struct seq_file *seq, void *v) { - struct s3c_hsotg_ep *ep = seq->private; + struct dwc2_hsotg_ep *ep = seq->private; struct dwc2_hsotg *hsotg = ep->parent; - struct s3c_hsotg_req *req; + struct dwc2_hsotg_req *req; void __iomem *regs = hsotg->regs; int index = ep->index; int show_limit = 15; @@ -326,7 +326,7 @@ static const struct file_operations ep_fops = { }; /** - * s3c_hsotg_create_debug - create debugfs directory and files + * dwc2_hsotg_create_debug - create debugfs directory and files * @hsotg: The driver state * * Create the debugfs files to allow the user to get information @@ -334,7 +334,7 @@ static const struct file_operations ep_fops = { * with the same name as the device itself, in case we end up * with multiple blocks in future systems. */ -static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) { struct dentry *root; struct dentry *file; @@ -360,7 +360,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) /* Create one file for each out endpoint */ for (epidx = 0; epidx < hsotg->num_of_eps; epidx++) { - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep; ep = hsotg->eps_out[epidx]; if (ep) { @@ -373,7 +373,7 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) } /* Create one file for each in endpoint. EP0 is handled with out eps */ for (epidx = 1; epidx < hsotg->num_of_eps; epidx++) { - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep; ep = hsotg->eps_in[epidx]; if (ep) { @@ -386,10 +386,10 @@ static void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) } } #else -static inline void s3c_hsotg_create_debug(struct dwc2_hsotg *hsotg) {} +static inline void dwc2_hsotg_create_debug(struct dwc2_hsotg *hsotg) {} #endif -/* s3c_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */ +/* dwc2_hsotg_delete_debug is removed as cleanup in done in dwc2_debugfs_exit */ #define dump_register(nm) \ { \ @@ -737,7 +737,7 @@ int dwc2_debugfs_init(struct dwc2_hsotg *hsotg) } /* Add gadget debugfs nodes */ - s3c_hsotg_create_debug(hsotg); + dwc2_hsotg_create_debug(hsotg); hsotg->regset = devm_kzalloc(hsotg->dev, sizeof(*hsotg->regset), GFP_KERNEL); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 3ee5b4c77a1f..2ed9ad84d979 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -39,14 +39,14 @@ #include "hw.h" /* conversion functions */ -static inline struct s3c_hsotg_req *our_req(struct usb_request *req) +static inline struct dwc2_hsotg_req *our_req(struct usb_request *req) { - return container_of(req, struct s3c_hsotg_req, req); + return container_of(req, struct dwc2_hsotg_req, req); } -static inline struct s3c_hsotg_ep *our_ep(struct usb_ep *ep) +static inline struct dwc2_hsotg_ep *our_ep(struct usb_ep *ep) { - return container_of(ep, struct s3c_hsotg_ep, ep); + return container_of(ep, struct dwc2_hsotg_ep, ep); } static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget) @@ -64,7 +64,7 @@ static inline void __bic32(void __iomem *ptr, u32 val) writel(readl(ptr) & ~val, ptr); } -static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg, +static inline struct dwc2_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg, u32 ep_index, u32 dir_in) { if (dir_in) @@ -74,7 +74,7 @@ static inline struct s3c_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg, } /* forward declaration of functions */ -static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg); +static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg); /** * using_dma - return the DMA status of the driver. @@ -101,11 +101,11 @@ static inline bool using_dma(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_en_gsint - enable one or more of the general interrupt + * dwc2_hsotg_en_gsint - enable one or more of the general interrupt * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) +static void dwc2_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; @@ -119,11 +119,11 @@ static void s3c_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) } /** - * s3c_hsotg_disable_gsint - disable one or more of the general interrupt + * dwc2_hsotg_disable_gsint - disable one or more of the general interrupt * @hsotg: The device state * @ints: A bitmask of the interrupts to enable */ -static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) +static void dwc2_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) { u32 gsintmsk = readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; @@ -135,7 +135,7 @@ static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) } /** - * s3c_hsotg_ctrl_epint - enable/disable an endpoint irq + * dwc2_hsotg_ctrl_epint - enable/disable an endpoint irq * @hsotg: The device state * @ep: The endpoint index * @dir_in: True if direction is in. @@ -144,7 +144,7 @@ static void s3c_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) * Set or clear the mask for an individual endpoint's interrupt * request. */ -static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, +static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, unsigned int ep, unsigned int dir_in, unsigned int en) { @@ -166,10 +166,10 @@ static void s3c_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_init_fifo - initialise non-periodic FIFOs + * dwc2_hsotg_init_fifo - initialise non-periodic FIFOs * @hsotg: The device instance. */ -static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) { unsigned int ep; unsigned int addr; @@ -248,12 +248,12 @@ static void s3c_hsotg_init_fifo(struct dwc2_hsotg *hsotg) * * Allocate a new USB request structure appropriate for the specified endpoint */ -static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, +static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep, gfp_t flags) { - struct s3c_hsotg_req *req; + struct dwc2_hsotg_req *req; - req = kzalloc(sizeof(struct s3c_hsotg_req), flags); + req = kzalloc(sizeof(struct dwc2_hsotg_req), flags); if (!req) return NULL; @@ -269,23 +269,23 @@ static struct usb_request *s3c_hsotg_ep_alloc_request(struct usb_ep *ep, * Returns true if the endpoint is in periodic mode, meaning it is being * used for an Interrupt or ISO transfer. */ -static inline int is_ep_periodic(struct s3c_hsotg_ep *hs_ep) +static inline int is_ep_periodic(struct dwc2_hsotg_ep *hs_ep) { return hs_ep->periodic; } /** - * s3c_hsotg_unmap_dma - unmap the DMA memory being used for the request + * dwc2_hsotg_unmap_dma - unmap the DMA memory being used for the request * @hsotg: The device state. * @hs_ep: The endpoint for the request * @hs_req: The request being processed. * - * This is the reverse of s3c_hsotg_map_dma(), called for the completion + * This is the reverse of dwc2_hsotg_map_dma(), called for the completion * of a request to ensure the buffer is ready for access by the caller. */ -static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, - struct s3c_hsotg_req *hs_req) +static void dwc2_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, + struct dwc2_hsotg_req *hs_req) { struct usb_request *req = &hs_req->req; @@ -297,7 +297,7 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_write_fifo - write packet Data to the TxFIFO + * dwc2_hsotg_write_fifo - write packet Data to the TxFIFO * @hsotg: The controller state. * @hs_ep: The endpoint we're going to write for. * @hs_req: The request to write data for. @@ -312,9 +312,9 @@ static void s3c_hsotg_unmap_dma(struct dwc2_hsotg *hsotg, * * This routine is only needed for PIO */ -static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, - struct s3c_hsotg_req *hs_req) +static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, + struct dwc2_hsotg_req *hs_req) { bool periodic = is_ep_periodic(hs_ep); u32 gnptxsts = readl(hsotg->regs + GNPTXSTS); @@ -348,7 +348,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, * previous data has been completely sent. */ if (hs_ep->fifo_load != 0) { - s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP); + dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP); return -ENOSPC; } @@ -369,7 +369,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, __func__, can_write); if (can_write <= 0) { - s3c_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP); + dwc2_hsotg_en_gsint(hsotg, GINTSTS_PTXFEMP); return -ENOSPC; } } else if (hsotg->dedicated_fifos && hs_ep->index != 0) { @@ -383,7 +383,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, "%s: no queue slots available (0x%08x)\n", __func__, gnptxsts); - s3c_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP); + dwc2_hsotg_en_gsint(hsotg, GINTSTS_NPTXFEMP); return -ENOSPC; } @@ -414,7 +414,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, /* it's needed only when we do not use dedicated fifos */ if (!hsotg->dedicated_fifos) - s3c_hsotg_en_gsint(hsotg, + dwc2_hsotg_en_gsint(hsotg, periodic ? GINTSTS_PTXFEMP : GINTSTS_NPTXFEMP); } @@ -443,7 +443,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, /* it's needed only when we do not use dedicated fifos */ if (!hsotg->dedicated_fifos) - s3c_hsotg_en_gsint(hsotg, + dwc2_hsotg_en_gsint(hsotg, periodic ? GINTSTS_PTXFEMP : GINTSTS_NPTXFEMP); } @@ -475,7 +475,7 @@ static int s3c_hsotg_write_fifo(struct dwc2_hsotg *hsotg, * Return the maximum data that can be queued in one go on a given endpoint * so that transfers that are too long can be split. */ -static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) +static unsigned get_ep_limit(struct dwc2_hsotg_ep *hs_ep) { int index = hs_ep->index; unsigned maxsize; @@ -508,7 +508,7 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) } /** - * s3c_hsotg_start_req - start a USB request from an endpoint's queue + * dwc2_hsotg_start_req - start a USB request from an endpoint's queue * @hsotg: The controller state. * @hs_ep: The endpoint to process a request for * @hs_req: The request to start. @@ -517,9 +517,9 @@ static unsigned get_ep_limit(struct s3c_hsotg_ep *hs_ep) * Start the given request running by setting the endpoint registers * appropriately, and writing any data to the FIFOs. */ -static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, - struct s3c_hsotg_req *hs_req, +static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, + struct dwc2_hsotg_req *hs_req, bool continuing) { struct usb_request *ureq = &hs_req->req; @@ -625,7 +625,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, /* * write DMA address to control register, buffer already - * synced by s3c_hsotg_ep_queue(). + * synced by dwc2_hsotg_ep_queue(). */ dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index); @@ -659,7 +659,7 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, /* set these anyway, we may need them for non-periodic in */ hs_ep->fifo_load = 0; - s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req); + dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req); } /* @@ -685,11 +685,11 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, __func__, readl(hsotg->regs + epctrl_reg)); /* enable ep interrupts */ - s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1); + dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1); } /** - * s3c_hsotg_map_dma - map the DMA memory being used for the request + * dwc2_hsotg_map_dma - map the DMA memory being used for the request * @hsotg: The device state. * @hs_ep: The endpoint the request is on. * @req: The request being processed. @@ -700,11 +700,11 @@ static void s3c_hsotg_start_req(struct dwc2_hsotg *hsotg, * DMA memory, then we map the memory and mark our request to allow us to * cleanup on completion. */ -static int s3c_hsotg_map_dma(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, +static int dwc2_hsotg_map_dma(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, struct usb_request *req) { - struct s3c_hsotg_req *hs_req = our_req(req); + struct dwc2_hsotg_req *hs_req = our_req(req); int ret; /* if the length is zero, ignore the DMA data */ @@ -724,8 +724,8 @@ dma_error: return -EIO; } -static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) +static int dwc2_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req) { void *req_buf = hs_req->req.buf; @@ -755,8 +755,8 @@ static int s3c_hsotg_handle_unaligned_buf_start(struct dwc2_hsotg *hsotg, return 0; } -static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, struct s3c_hsotg_req *hs_req) +static void dwc2_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, struct dwc2_hsotg_req *hs_req) { /* If dma is not being used or buffer was aligned */ if (!using_dma(hsotg) || !hs_req->saved_req_buf) @@ -777,11 +777,11 @@ static void s3c_hsotg_handle_unaligned_buf_complete(struct dwc2_hsotg *hsotg, hs_req->saved_req_buf = NULL; } -static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, +static int dwc2_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { - struct s3c_hsotg_req *hs_req = our_req(req); - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_req *hs_req = our_req(req); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hs = hs_ep->parent; bool first; int ret; @@ -802,13 +802,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, req->actual = 0; req->status = -EINPROGRESS; - ret = s3c_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req); + ret = dwc2_hsotg_handle_unaligned_buf_start(hs, hs_ep, hs_req); if (ret) return ret; /* if we're using DMA, sync the buffers as necessary */ if (using_dma(hs)) { - ret = s3c_hsotg_map_dma(hs, hs_ep, req); + ret = dwc2_hsotg_map_dma(hs, hs_ep, req); if (ret) return ret; } @@ -817,51 +817,51 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, list_add_tail(&hs_req->queue, &hs_ep->queue); if (first) - s3c_hsotg_start_req(hs, hs_ep, hs_req, false); + dwc2_hsotg_start_req(hs, hs_ep, hs_req, false); return 0; } -static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, +static int dwc2_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags = 0; int ret = 0; spin_lock_irqsave(&hs->lock, flags); - ret = s3c_hsotg_ep_queue(ep, req, gfp_flags); + ret = dwc2_hsotg_ep_queue(ep, req, gfp_flags); spin_unlock_irqrestore(&hs->lock, flags); return ret; } -static void s3c_hsotg_ep_free_request(struct usb_ep *ep, +static void dwc2_hsotg_ep_free_request(struct usb_ep *ep, struct usb_request *req) { - struct s3c_hsotg_req *hs_req = our_req(req); + struct dwc2_hsotg_req *hs_req = our_req(req); kfree(hs_req); } /** - * s3c_hsotg_complete_oursetup - setup completion callback + * dwc2_hsotg_complete_oursetup - setup completion callback * @ep: The endpoint the request was on. * @req: The request completed. * * Called on completion of any requests the driver itself * submitted that need cleaning up. */ -static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, +static void dwc2_hsotg_complete_oursetup(struct usb_ep *ep, struct usb_request *req) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; dev_dbg(hsotg->dev, "%s: ep %p, req %p\n", __func__, ep, req); - s3c_hsotg_ep_free_request(ep, req); + dwc2_hsotg_ep_free_request(ep, req); } /** @@ -872,10 +872,10 @@ static void s3c_hsotg_complete_oursetup(struct usb_ep *ep, * Convert the given wIndex into a pointer to an driver endpoint * structure, or return NULL if it is not a valid endpoint. */ -static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, +static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, u32 windex) { - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep; int dir = (windex & USB_DIR_IN) ? 1 : 0; int idx = windex & 0x7F; @@ -894,12 +894,12 @@ static struct s3c_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_set_test_mode - Enable usb Test Modes + * dwc2_hsotg_set_test_mode - Enable usb Test Modes * @hsotg: The driver state. * @testmode: requested usb test mode * Enable usb Test Mode requested by the Host. */ -int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) +int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) { int dctl = readl(hsotg->regs + DCTL); @@ -920,7 +920,7 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) } /** - * s3c_hsotg_send_reply - send reply to control request + * dwc2_hsotg_send_reply - send reply to control request * @hsotg: The device state * @ep: Endpoint 0 * @buff: Buffer for request @@ -929,8 +929,8 @@ int s3c_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) * Create a request and queue it on the given endpoint. This is useful as * an internal method of sending replies to certain control requests, etc. */ -static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *ep, +static int dwc2_hsotg_send_reply(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *ep, void *buff, int length) { @@ -939,7 +939,7 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, dev_dbg(hsotg->dev, "%s: buff %p, len %d\n", __func__, buff, length); - req = s3c_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC); + req = dwc2_hsotg_ep_alloc_request(&ep->ep, GFP_ATOMIC); hsotg->ep0_reply = req; if (!req) { dev_warn(hsotg->dev, "%s: cannot alloc req\n", __func__); @@ -953,12 +953,12 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, * STATUS stage. */ req->zero = 0; - req->complete = s3c_hsotg_complete_oursetup; + req->complete = dwc2_hsotg_complete_oursetup; if (length) memcpy(req->buf, buff, length); - ret = s3c_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC); + ret = dwc2_hsotg_ep_queue(&ep->ep, req, GFP_ATOMIC); if (ret) { dev_warn(hsotg->dev, "%s: cannot queue req\n", __func__); return ret; @@ -968,15 +968,15 @@ static int s3c_hsotg_send_reply(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_process_req_status - process request GET_STATUS + * dwc2_hsotg_process_req_status - process request GET_STATUS * @hsotg: The device state * @ctrl: USB control request */ -static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, +static int dwc2_hsotg_process_req_status(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { - struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; + struct dwc2_hsotg_ep *ep; __le16 reply; int ret; @@ -1013,7 +1013,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, if (le16_to_cpu(ctrl->wLength) != 2) return -EINVAL; - ret = s3c_hsotg_send_reply(hsotg, ep0, &reply, 2); + ret = dwc2_hsotg_send_reply(hsotg, ep0, &reply, 2); if (ret) { dev_err(hsotg->dev, "%s: failed to send reply\n", __func__); return ret; @@ -1022,7 +1022,7 @@ static int s3c_hsotg_process_req_status(struct dwc2_hsotg *hsotg, return 1; } -static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); +static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value); /** * get_ep_head - return the first request on the endpoint @@ -1030,27 +1030,27 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value); * * Get the first request on the endpoint. */ -static struct s3c_hsotg_req *get_ep_head(struct s3c_hsotg_ep *hs_ep) +static struct dwc2_hsotg_req *get_ep_head(struct dwc2_hsotg_ep *hs_ep) { if (list_empty(&hs_ep->queue)) return NULL; - return list_first_entry(&hs_ep->queue, struct s3c_hsotg_req, queue); + return list_first_entry(&hs_ep->queue, struct dwc2_hsotg_req, queue); } /** - * s3c_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE + * dwc2_hsotg_process_req_feature - process request {SET,CLEAR}_FEATURE * @hsotg: The device state * @ctrl: USB control request */ -static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, +static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { - struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; - struct s3c_hsotg_req *hs_req; + struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; + struct dwc2_hsotg_req *hs_req; bool restart; bool set = (ctrl->bRequest == USB_REQ_SET_FEATURE); - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep; int ret; bool halted; u32 recip; @@ -1074,7 +1074,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, return -EINVAL; hsotg->test_mode = wIndex >> 8; - ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); + ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0); if (ret) { dev_err(hsotg->dev, "%s: failed to send reply\n", __func__); @@ -1098,9 +1098,9 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, case USB_ENDPOINT_HALT: halted = ep->halted; - s3c_hsotg_ep_sethalt(&ep->ep, set); + dwc2_hsotg_ep_sethalt(&ep->ep, set); - ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); + ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0); if (ret) { dev_err(hsotg->dev, "%s: failed to send reply\n", __func__); @@ -1134,7 +1134,7 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, restart = !list_empty(&ep->queue); if (restart) { hs_req = get_ep_head(ep); - s3c_hsotg_start_req(hsotg, ep, + dwc2_hsotg_start_req(hsotg, ep, hs_req, false); } } @@ -1152,17 +1152,17 @@ static int s3c_hsotg_process_req_feature(struct dwc2_hsotg *hsotg, return 1; } -static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); +static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg); /** - * s3c_hsotg_stall_ep0 - stall ep0 + * dwc2_hsotg_stall_ep0 - stall ep0 * @hsotg: The device state * * Set stall for ep0 as response for setup request. */ -static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) { - struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; + struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; u32 reg; u32 ctrl; @@ -1187,11 +1187,11 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) * complete won't be called, so we enqueue * setup request here */ - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); } /** - * s3c_hsotg_process_control - process a control request + * dwc2_hsotg_process_control - process a control request * @hsotg: The device state * @ctrl: The control request received * @@ -1199,10 +1199,10 @@ static void s3c_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) * needs to work out what to do next (and whether to pass it on to the * gadget driver). */ -static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, +static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg, struct usb_ctrlrequest *ctrl) { - struct s3c_hsotg_ep *ep0 = hsotg->eps_out[0]; + struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; int ret = 0; u32 dcfg; @@ -1233,16 +1233,16 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, dev_info(hsotg->dev, "new address %d\n", ctrl->wValue); - ret = s3c_hsotg_send_reply(hsotg, ep0, NULL, 0); + ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0); return; case USB_REQ_GET_STATUS: - ret = s3c_hsotg_process_req_status(hsotg, ctrl); + ret = dwc2_hsotg_process_req_status(hsotg, ctrl); break; case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: - ret = s3c_hsotg_process_req_feature(hsotg, ctrl); + ret = dwc2_hsotg_process_req_feature(hsotg, ctrl); break; } } @@ -1263,21 +1263,21 @@ static void s3c_hsotg_process_control(struct dwc2_hsotg *hsotg, */ if (ret < 0) - s3c_hsotg_stall_ep0(hsotg); + dwc2_hsotg_stall_ep0(hsotg); } /** - * s3c_hsotg_complete_setup - completion of a setup transfer + * dwc2_hsotg_complete_setup - completion of a setup transfer * @ep: The endpoint the request was on. * @req: The request completed. * * Called on completion of any requests the driver itself submitted for * EP0 setup packets */ -static void s3c_hsotg_complete_setup(struct usb_ep *ep, +static void dwc2_hsotg_complete_setup(struct usb_ep *ep, struct usb_request *req) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; if (req->status < 0) { @@ -1287,23 +1287,23 @@ static void s3c_hsotg_complete_setup(struct usb_ep *ep, spin_lock(&hsotg->lock); if (req->actual == 0) - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); else - s3c_hsotg_process_control(hsotg, req->buf); + dwc2_hsotg_process_control(hsotg, req->buf); spin_unlock(&hsotg->lock); } /** - * s3c_hsotg_enqueue_setup - start a request for EP0 packets + * dwc2_hsotg_enqueue_setup - start a request for EP0 packets * @hsotg: The device state. * * Enqueue a request on EP0 if necessary to received any SETUP packets * received from the host. */ -static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) { struct usb_request *req = hsotg->ctrl_req; - struct s3c_hsotg_req *hs_req = our_req(req); + struct dwc2_hsotg_req *hs_req = our_req(req); int ret; dev_dbg(hsotg->dev, "%s: queueing setup request\n", __func__); @@ -1311,7 +1311,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) req->zero = 0; req->length = 8; req->buf = hsotg->ctrl_buff; - req->complete = s3c_hsotg_complete_setup; + req->complete = dwc2_hsotg_complete_setup; if (!list_empty(&hs_req->queue)) { dev_dbg(hsotg->dev, "%s already queued???\n", __func__); @@ -1322,7 +1322,7 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) hsotg->eps_out[0]->send_zlp = 0; hsotg->ep0_state = DWC2_EP0_SETUP; - ret = s3c_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC); + ret = dwc2_hsotg_ep_queue(&hsotg->eps_out[0]->ep, req, GFP_ATOMIC); if (ret < 0) { dev_err(hsotg->dev, "%s: failed queue (%d)\n", __func__, ret); /* @@ -1332,8 +1332,8 @@ static void s3c_hsotg_enqueue_setup(struct dwc2_hsotg *hsotg) } } -static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep) +static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep) { u32 ctrl; u8 index = hs_ep->index; @@ -1359,7 +1359,7 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_complete_request - complete a request given to us + * dwc2_hsotg_complete_request - complete a request given to us * @hsotg: The device state. * @hs_ep: The endpoint the request was on. * @hs_req: The request to complete. @@ -1371,9 +1371,9 @@ static void s3c_hsotg_program_zlp(struct dwc2_hsotg *hsotg, * * Note, expects the ep to already be locked as appropriate. */ -static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, - struct s3c_hsotg_req *hs_req, +static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, + struct dwc2_hsotg_req *hs_req, int result) { bool restart; @@ -1394,13 +1394,13 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, if (hs_req->req.status == -EINPROGRESS) hs_req->req.status = result; - s3c_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req); + dwc2_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req); hs_ep->req = NULL; list_del_init(&hs_req->queue); if (using_dma(hsotg)) - s3c_hsotg_unmap_dma(hsotg, hs_ep, hs_req); + dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req); /* * call the complete request with the locks off, just in case the @@ -1423,13 +1423,13 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, restart = !list_empty(&hs_ep->queue); if (restart) { hs_req = get_ep_head(hs_ep); - s3c_hsotg_start_req(hsotg, hs_ep, hs_req, false); + dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, false); } } } /** - * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint + * dwc2_hsotg_rx_data - receive data from the FIFO for an endpoint * @hsotg: The device state. * @ep_idx: The endpoint index for the data * @size: The size of data in the fifo, in bytes @@ -1438,10 +1438,10 @@ static void s3c_hsotg_complete_request(struct dwc2_hsotg *hsotg, * endpoint, so sort out whether we need to read the data into a request * that has been made for that endpoint. */ -static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) +static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) { - struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx]; - struct s3c_hsotg_req *hs_req = hs_ep->req; + struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[ep_idx]; + struct dwc2_hsotg_req *hs_req = hs_ep->req; void __iomem *fifo = hsotg->regs + EPFIFO(ep_idx); int to_read; int max_req; @@ -1492,7 +1492,7 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) } /** - * s3c_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint + * dwc2_hsotg_ep0_zlp - send/receive zero-length packet on control endpoint * @hsotg: The device instance * @dir_in: If IN zlp * @@ -1503,17 +1503,17 @@ static void s3c_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) * currently believed that we do not need to wait for any space in * the TxFIFO. */ -static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) +static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) { /* eps_out[0] is used in both directions */ hsotg->eps_out[0]->dir_in = dir_in; hsotg->ep0_state = dir_in ? DWC2_EP0_STATUS_IN : DWC2_EP0_STATUS_OUT; - s3c_hsotg_program_zlp(hsotg, hsotg->eps_out[0]); + dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]); } /** - * s3c_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO + * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO * @hsotg: The device instance * @epnum: The endpoint received from * @@ -1521,11 +1521,11 @@ static void s3c_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) * transfer for an OUT endpoint has been completed, either by a short * packet or by the finish of a transfer. */ -static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) +static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) { u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); - struct s3c_hsotg_ep *hs_ep = hsotg->eps_out[epnum]; - struct s3c_hsotg_req *hs_req = hs_ep->req; + struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum]; + struct dwc2_hsotg_req *hs_req = hs_ep->req; struct usb_request *req = &hs_req->req; unsigned size_left = DXEPTSIZ_XFERSIZE_GET(epsize); int result = 0; @@ -1537,8 +1537,8 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_OUT) { dev_dbg(hsotg->dev, "zlp packet received\n"); - s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); + dwc2_hsotg_enqueue_setup(hsotg); return; } @@ -1562,7 +1562,7 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) /* if there is more request to do, schedule new transfer */ if (req->actual < req->length && size_left == 0) { - s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); + dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true); return; } @@ -1578,20 +1578,20 @@ static void s3c_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) if (epnum == 0 && hsotg->ep0_state == DWC2_EP0_DATA_OUT) { /* Move to STATUS IN */ - s3c_hsotg_ep0_zlp(hsotg, true); + dwc2_hsotg_ep0_zlp(hsotg, true); return; } - s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result); } /** - * s3c_hsotg_read_frameno - read current frame number + * dwc2_hsotg_read_frameno - read current frame number * @hsotg: The device instance * * Return the current frame number */ -static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg) +static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) { u32 dsts; @@ -1603,7 +1603,7 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_handle_rx - RX FIFO has data + * dwc2_hsotg_handle_rx - RX FIFO has data * @hsotg: The device instance * * The IRQ handler has detected that the RX FIFO has some data in it @@ -1618,7 +1618,7 @@ static u32 s3c_hsotg_read_frameno(struct dwc2_hsotg *hsotg) * as the actual data should be sent to the memory directly and we turn * on the completion interrupts to get notifications of transfer completion. */ -static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg) { u32 grxstsr = readl(hsotg->regs + GRXSTSP); u32 epnum, status, size; @@ -1641,55 +1641,55 @@ static void s3c_hsotg_handle_rx(struct dwc2_hsotg *hsotg) case GRXSTS_PKTSTS_OUTDONE: dev_dbg(hsotg->dev, "OutDone (Frame=0x%08x)\n", - s3c_hsotg_read_frameno(hsotg)); + dwc2_hsotg_read_frameno(hsotg)); if (!using_dma(hsotg)) - s3c_hsotg_handle_outdone(hsotg, epnum); + dwc2_hsotg_handle_outdone(hsotg, epnum); break; case GRXSTS_PKTSTS_SETUPDONE: dev_dbg(hsotg->dev, "SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n", - s3c_hsotg_read_frameno(hsotg), + dwc2_hsotg_read_frameno(hsotg), readl(hsotg->regs + DOEPCTL(0))); /* - * Call s3c_hsotg_handle_outdone here if it was not called from + * Call dwc2_hsotg_handle_outdone here if it was not called from * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't * generate GRXSTS_PKTSTS_OUTDONE for setup packet. */ if (hsotg->ep0_state == DWC2_EP0_SETUP) - s3c_hsotg_handle_outdone(hsotg, epnum); + dwc2_hsotg_handle_outdone(hsotg, epnum); break; case GRXSTS_PKTSTS_OUTRX: - s3c_hsotg_rx_data(hsotg, epnum, size); + dwc2_hsotg_rx_data(hsotg, epnum, size); break; case GRXSTS_PKTSTS_SETUPRX: dev_dbg(hsotg->dev, "SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n", - s3c_hsotg_read_frameno(hsotg), + dwc2_hsotg_read_frameno(hsotg), readl(hsotg->regs + DOEPCTL(0))); WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP); - s3c_hsotg_rx_data(hsotg, epnum, size); + dwc2_hsotg_rx_data(hsotg, epnum, size); break; default: dev_warn(hsotg->dev, "%s: unknown status %08x\n", __func__, grxstsr); - s3c_hsotg_dump(hsotg); + dwc2_hsotg_dump(hsotg); break; } } /** - * s3c_hsotg_ep0_mps - turn max packet size into register setting + * dwc2_hsotg_ep0_mps - turn max packet size into register setting * @mps: The maximum packet size in bytes. */ -static u32 s3c_hsotg_ep0_mps(unsigned int mps) +static u32 dwc2_hsotg_ep0_mps(unsigned int mps) { switch (mps) { case 64: @@ -1708,7 +1708,7 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps) } /** - * s3c_hsotg_set_ep_maxpacket - set endpoint's max-packet field + * dwc2_hsotg_set_ep_maxpacket - set endpoint's max-packet field * @hsotg: The driver state. * @ep: The index number of the endpoint * @mps: The maximum packet size in bytes @@ -1716,10 +1716,10 @@ static u32 s3c_hsotg_ep0_mps(unsigned int mps) * Configure the maximum packet size for the given endpoint, updating * the hardware control registers to reflect this. */ -static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, +static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, unsigned int ep, unsigned int mps, unsigned int dir_in) { - struct s3c_hsotg_ep *hs_ep; + struct dwc2_hsotg_ep *hs_ep; void __iomem *regs = hsotg->regs; u32 mpsval; u32 mcval; @@ -1731,7 +1731,7 @@ static void s3c_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, if (ep == 0) { /* EP0 is a special case */ - mpsval = s3c_hsotg_ep0_mps(mps); + mpsval = dwc2_hsotg_ep0_mps(mps); if (mpsval > 3) goto bad_mps; hs_ep->ep.maxpacket = mps; @@ -1766,11 +1766,11 @@ bad_mps: } /** - * s3c_hsotg_txfifo_flush - flush Tx FIFO + * dwc2_hsotg_txfifo_flush - flush Tx FIFO * @hsotg: The driver state * @idx: The index for the endpoint (0..15) */ -static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) +static void dwc2_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) { int timeout; int val; @@ -1799,17 +1799,17 @@ static void s3c_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) } /** - * s3c_hsotg_trytx - check to see if anything needs transmitting + * dwc2_hsotg_trytx - check to see if anything needs transmitting * @hsotg: The driver state * @hs_ep: The driver endpoint to check. * * Check to see if there is a request that has data to send, and if so * make an attempt to write data into the FIFO. */ -static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep) +static int dwc2_hsotg_trytx(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep) { - struct s3c_hsotg_req *hs_req = hs_ep->req; + struct dwc2_hsotg_req *hs_req = hs_ep->req; if (!hs_ep->dir_in || !hs_req) { /** @@ -1817,7 +1817,7 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg, * for endpoints, excepting ep0 */ if (hs_ep->index != 0) - s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, + dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); return 0; } @@ -1825,24 +1825,24 @@ static int s3c_hsotg_trytx(struct dwc2_hsotg *hsotg, if (hs_req->req.actual < hs_req->req.length) { dev_dbg(hsotg->dev, "trying to write more for ep%d\n", hs_ep->index); - return s3c_hsotg_write_fifo(hsotg, hs_ep, hs_req); + return dwc2_hsotg_write_fifo(hsotg, hs_ep, hs_req); } return 0; } /** - * s3c_hsotg_complete_in - complete IN transfer + * dwc2_hsotg_complete_in - complete IN transfer * @hsotg: The device state. * @hs_ep: The endpoint that has just completed. * * An IN transfer has been completed, update the transfer's state and then * call the relevant completion routines. */ -static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep) +static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep) { - struct s3c_hsotg_req *hs_req = hs_ep->req; + struct dwc2_hsotg_req *hs_req = hs_ep->req; u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index)); int size_left, size_done; @@ -1854,19 +1854,19 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, /* Finish ZLP handling for IN EP0 transactions */ if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_STATUS_IN) { dev_dbg(hsotg->dev, "zlp packet sent\n"); - s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); if (hsotg->test_mode) { int ret; - ret = s3c_hsotg_set_test_mode(hsotg, hsotg->test_mode); + ret = dwc2_hsotg_set_test_mode(hsotg, hsotg->test_mode); if (ret < 0) { dev_dbg(hsotg->dev, "Invalid Test #%d\n", hsotg->test_mode); - s3c_hsotg_stall_ep0(hsotg); + dwc2_hsotg_stall_ep0(hsotg); return; } } - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); return; } @@ -1895,13 +1895,13 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, if (!size_left && hs_req->req.actual < hs_req->req.length) { dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); - s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); + dwc2_hsotg_start_req(hsotg, hs_ep, hs_req, true); return; } /* Zlp for all endpoints, for ep0 only in DATA IN stage */ if (hs_ep->send_zlp) { - s3c_hsotg_program_zlp(hsotg, hs_ep); + dwc2_hsotg_program_zlp(hsotg, hs_ep); hs_ep->send_zlp = 0; /* transfer will be completed on next complete interrupt */ return; @@ -1909,25 +1909,25 @@ static void s3c_hsotg_complete_in(struct dwc2_hsotg *hsotg, if (hs_ep->index == 0 && hsotg->ep0_state == DWC2_EP0_DATA_IN) { /* Move to STATUS OUT */ - s3c_hsotg_ep0_zlp(hsotg, false); + dwc2_hsotg_ep0_zlp(hsotg, false); return; } - s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); } /** - * s3c_hsotg_epint - handle an in/out endpoint interrupt + * dwc2_hsotg_epint - handle an in/out endpoint interrupt * @hsotg: The driver state * @idx: The index for the endpoint (0..15) * @dir_in: Set if this is an IN endpoint * * Process and clear any interrupt pending for an individual endpoint */ -static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, +static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, int dir_in) { - struct s3c_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in); + struct dwc2_hsotg_ep *hs_ep = index_to_ep(hsotg, idx, dir_in); u32 epint_reg = dir_in ? DIEPINT(idx) : DOEPINT(idx); u32 epctl_reg = dir_in ? DIEPCTL(idx) : DOEPCTL(idx); u32 epsiz_reg = dir_in ? DIEPTSIZ(idx) : DOEPTSIZ(idx); @@ -1972,17 +1972,17 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, * at completing IN requests here */ if (dir_in) { - s3c_hsotg_complete_in(hsotg, hs_ep); + dwc2_hsotg_complete_in(hsotg, hs_ep); if (idx == 0 && !hs_ep->req) - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); } else if (using_dma(hsotg)) { /* * We're using DMA, we need to fire an OutDone here * as we ignore the RXFIFO. */ - s3c_hsotg_handle_outdone(hsotg, idx); + dwc2_hsotg_handle_outdone(hsotg, idx); } } @@ -1992,7 +1992,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, if (dir_in) { int epctl = readl(hsotg->regs + epctl_reg); - s3c_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index); + dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index); if ((epctl & DXEPCTL_STALL) && (epctl & DXEPCTL_EPTYPE_BULK)) { @@ -2021,7 +2021,7 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, if (dir_in) WARN_ON_ONCE(1); else - s3c_hsotg_handle_outdone(hsotg, 0); + dwc2_hsotg_handle_outdone(hsotg, 0); } } @@ -2047,19 +2047,19 @@ static void s3c_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); if (!using_dma(hsotg)) - s3c_hsotg_trytx(hsotg, hs_ep); + dwc2_hsotg_trytx(hsotg, hs_ep); } } } /** - * s3c_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done) + * dwc2_hsotg_irq_enumdone - Handle EnumDone interrupt (enumeration done) * @hsotg: The device state. * * Handle updating the device settings after the enumeration phase has * been completed. */ -static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) { u32 dsts = readl(hsotg->regs + DSTS); int ep0_mps = 0, ep_mps = 8; @@ -2113,19 +2113,19 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) if (ep0_mps) { int i; /* Initialize ep0 for both in and out directions */ - s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1); - s3c_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0); + dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1); + dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0); for (i = 1; i < hsotg->num_of_eps; i++) { if (hsotg->eps_in[i]) - s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1); + dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1); if (hsotg->eps_out[i]) - s3c_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0); + dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0); } } /* ensure after enumeration our EP0 is active */ - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", readl(hsotg->regs + DIEPCTL0), @@ -2142,34 +2142,34 @@ static void s3c_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) * completed with the given result code. */ static void kill_all_requests(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *ep, + struct dwc2_hsotg_ep *ep, int result) { - struct s3c_hsotg_req *req, *treq; + struct dwc2_hsotg_req *req, *treq; unsigned size; ep->req = NULL; list_for_each_entry_safe(req, treq, &ep->queue, queue) - s3c_hsotg_complete_request(hsotg, ep, req, + dwc2_hsotg_complete_request(hsotg, ep, req, result); if (!hsotg->dedicated_fifos) return; size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; if (size < ep->fifo_size) - s3c_hsotg_txfifo_flush(hsotg, ep->fifo_index); + dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); } /** - * s3c_hsotg_disconnect - disconnect service + * dwc2_hsotg_disconnect - disconnect service * @hsotg: The device state. * * The device has been disconnected. Remove all current * transactions and signal the gadget driver that this * has happened. */ -void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) +void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg) { unsigned ep; @@ -2192,13 +2192,13 @@ void s3c_hsotg_disconnect(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_irq_fifoempty - TX FIFO empty interrupt handler + * dwc2_hsotg_irq_fifoempty - TX FIFO empty interrupt handler * @hsotg: The device state: * @periodic: True if this is a periodic FIFO interrupt */ -static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) +static void dwc2_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) { - struct s3c_hsotg_ep *ep; + struct dwc2_hsotg_ep *ep; int epno, ret; /* look through for any more data to transmit */ @@ -2215,7 +2215,7 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) (!periodic && ep->periodic)) continue; - ret = s3c_hsotg_trytx(hsotg, ep); + ret = dwc2_hsotg_trytx(hsotg, ep); if (ret < 0) break; } @@ -2227,12 +2227,12 @@ static void s3c_hsotg_irq_fifoempty(struct dwc2_hsotg *hsotg, bool periodic) GINTSTS_RXFLVL) /** - * s3c_hsotg_corereset - issue softreset to the core + * dwc2_hsotg_corereset - issue softreset to the core * @hsotg: The device state * * Issue a soft reset to the core, and await the core finishing it. */ -static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) +static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg) { int timeout; u32 grstctl; @@ -2275,18 +2275,18 @@ static int s3c_hsotg_corereset(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_core_init - issue softreset to the core + * dwc2_hsotg_core_init - issue softreset to the core * @hsotg: The device state * * Issue a soft reset to the core, and await the core finishing it. */ -void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, +void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, bool is_usb_reset) { u32 val; if (!is_usb_reset) - s3c_hsotg_corereset(hsotg); + dwc2_hsotg_corereset(hsotg); /* * we must now enable ep0 ready for host detection and then @@ -2298,7 +2298,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); - s3c_hsotg_init_fifo(hsotg); + dwc2_hsotg_init_fifo(hsotg); if (!is_usb_reset) __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); @@ -2359,7 +2359,7 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, readl(hsotg->regs + DOEPCTL0)); /* enable in and out endpoint interrupts */ - s3c_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT); + dwc2_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT); /* * Enable the RXFIFO when in slave mode, as this is how we collect @@ -2367,11 +2367,11 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, * things we cannot process, so do not use it. */ if (!using_dma(hsotg)) - s3c_hsotg_en_gsint(hsotg, GINTSTS_RXFLVL); + dwc2_hsotg_en_gsint(hsotg, GINTSTS_RXFLVL); /* Enable interrupts for EP0 in and out */ - s3c_hsotg_ctrl_epint(hsotg, 0, 0, 1); - s3c_hsotg_ctrl_epint(hsotg, 0, 1, 1); + dwc2_hsotg_ctrl_epint(hsotg, 0, 0, 1); + dwc2_hsotg_ctrl_epint(hsotg, 0, 1, 1); if (!is_usb_reset) { __orr32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); @@ -2390,16 +2390,16 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0); - writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | + writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | DXEPCTL_CNAK | DXEPCTL_EPENA | DXEPCTL_USBACTEP, hsotg->regs + DOEPCTL0); /* enable, but don't activate EP0in */ - writel(s3c_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | + writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); - s3c_hsotg_enqueue_setup(hsotg); + dwc2_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", readl(hsotg->regs + DIEPCTL0), @@ -2417,24 +2417,24 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, hsotg->last_rst = jiffies; } -static void s3c_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) { /* set the soft-disconnect bit */ __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); } -void s3c_hsotg_core_connect(struct dwc2_hsotg *hsotg) +void dwc2_hsotg_core_connect(struct dwc2_hsotg *hsotg) { /* remove the soft-disconnect and let's go */ __bic32(hsotg->regs + DCTL, DCTL_SFTDISCON); } /** - * s3c_hsotg_irq - handle device interrupt + * dwc2_hsotg_irq - handle device interrupt * @irq: The IRQ number triggered * @pw: The pw value when registered the handler. */ -static irqreturn_t s3c_hsotg_irq(int irq, void *pw) +static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) { struct dwc2_hsotg *hsotg = pw; int retry_count = 8; @@ -2454,7 +2454,7 @@ irq_retry: if (gintsts & GINTSTS_ENUMDONE) { writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); - s3c_hsotg_irq_enumdone(hsotg); + dwc2_hsotg_irq_enumdone(hsotg); } if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { @@ -2472,13 +2472,13 @@ irq_retry: for (ep = 0; ep < hsotg->num_of_eps && daint_out; ep++, daint_out >>= 1) { if (daint_out & 1) - s3c_hsotg_epint(hsotg, ep, 0); + dwc2_hsotg_epint(hsotg, ep, 0); } for (ep = 0; ep < hsotg->num_of_eps && daint_in; ep++, daint_in >>= 1) { if (daint_in & 1) - s3c_hsotg_epint(hsotg, ep, 1); + dwc2_hsotg_epint(hsotg, ep, 1); } } @@ -2505,7 +2505,7 @@ irq_retry: writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); /* Report disconnection if it is not already done. */ - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); if (usb_status & GOTGCTL_BSESVLD) { if (time_after(jiffies, hsotg->last_rst + @@ -2515,7 +2515,7 @@ irq_retry: -ECONNRESET); hsotg->lx_state = DWC2_L0; - s3c_hsotg_core_init_disconnected(hsotg, true); + dwc2_hsotg_core_init_disconnected(hsotg, true); } } } @@ -2531,8 +2531,8 @@ irq_retry: * it needs re-enabling */ - s3c_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP); - s3c_hsotg_irq_fifoempty(hsotg, false); + dwc2_hsotg_disable_gsint(hsotg, GINTSTS_NPTXFEMP); + dwc2_hsotg_irq_fifoempty(hsotg, false); } if (gintsts & GINTSTS_PTXFEMP) { @@ -2540,18 +2540,18 @@ irq_retry: /* See note in GINTSTS_NPTxFEmp */ - s3c_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP); - s3c_hsotg_irq_fifoempty(hsotg, true); + dwc2_hsotg_disable_gsint(hsotg, GINTSTS_PTXFEMP); + dwc2_hsotg_irq_fifoempty(hsotg, true); } if (gintsts & GINTSTS_RXFLVL) { /* * note, since GINTSTS_RxFLvl doubles as FIFO-not-empty, - * we need to retry s3c_hsotg_handle_rx if this is still + * we need to retry dwc2_hsotg_handle_rx if this is still * set. */ - s3c_hsotg_handle_rx(hsotg); + dwc2_hsotg_handle_rx(hsotg); } if (gintsts & GINTSTS_ERLYSUSP) { @@ -2570,7 +2570,7 @@ irq_retry: writel(DCTL_CGOUTNAK, hsotg->regs + DCTL); - s3c_hsotg_dump(hsotg); + dwc2_hsotg_dump(hsotg); } if (gintsts & GINTSTS_GINNAKEFF) { @@ -2578,7 +2578,7 @@ irq_retry: writel(DCTL_CGNPINNAK, hsotg->regs + DCTL); - s3c_hsotg_dump(hsotg); + dwc2_hsotg_dump(hsotg); } /* @@ -2595,16 +2595,16 @@ irq_retry: } /** - * s3c_hsotg_ep_enable - enable the given endpoint + * dwc2_hsotg_ep_enable - enable the given endpoint * @ep: The USB endpint to configure * @desc: The USB endpoint descriptor to configure with. * * This is called from the USB gadget code's usb_ep_enable(). */ -static int s3c_hsotg_ep_enable(struct usb_ep *ep, +static int dwc2_hsotg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; unsigned long flags; unsigned int index = hs_ep->index; @@ -2631,7 +2631,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, mps = usb_endpoint_maxp(desc); - /* note, we handle this here instead of s3c_hsotg_set_ep_maxpacket */ + /* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */ epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); epctrl = readl(hsotg->regs + epctrl_reg); @@ -2660,7 +2660,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, epctrl |= DXEPCTL_SNAK; /* update the endpoint state */ - s3c_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in); + dwc2_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in); /* default, set to non-periodic */ hs_ep->isochronous = 0; @@ -2752,7 +2752,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, __func__, readl(hsotg->regs + epctrl_reg)); /* enable the endpoint interrupt */ - s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); + dwc2_hsotg_ctrl_epint(hsotg, index, dir_in, 1); error: spin_unlock_irqrestore(&hsotg->lock, flags); @@ -2760,12 +2760,12 @@ error: } /** - * s3c_hsotg_ep_disable - disable given endpoint + * dwc2_hsotg_ep_disable - disable given endpoint * @ep: The endpoint to disable. */ -static int s3c_hsotg_ep_disable(struct usb_ep *ep) +static int dwc2_hsotg_ep_disable(struct usb_ep *ep) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hsotg = hs_ep->parent; int dir_in = hs_ep->dir_in; int index = hs_ep->index; @@ -2797,7 +2797,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) writel(ctrl, hsotg->regs + epctrl_reg); /* disable endpoint interrupts */ - s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); + dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); /* terminate all requests with shutdown */ kill_all_requests(hsotg, hs_ep, -ESHUTDOWN); @@ -2811,9 +2811,9 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) * @ep: The endpoint to check. * @test: The request to test if it is on the endpoint. */ -static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test) +static bool on_list(struct dwc2_hsotg_ep *ep, struct dwc2_hsotg_req *test) { - struct s3c_hsotg_req *req, *treq; + struct dwc2_hsotg_req *req, *treq; list_for_each_entry_safe(req, treq, &ep->queue, queue) { if (req == test) @@ -2824,14 +2824,14 @@ static bool on_list(struct s3c_hsotg_ep *ep, struct s3c_hsotg_req *test) } /** - * s3c_hsotg_ep_dequeue - dequeue given endpoint + * dwc2_hsotg_ep_dequeue - dequeue given endpoint * @ep: The endpoint to dequeue. * @req: The request to be removed from a queue. */ -static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) +static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { - struct s3c_hsotg_req *hs_req = our_req(req); - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_req *hs_req = our_req(req); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags; @@ -2844,20 +2844,20 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) return -EINVAL; } - s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); + dwc2_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); spin_unlock_irqrestore(&hs->lock, flags); return 0; } /** - * s3c_hsotg_ep_sethalt - set halt on a given endpoint + * dwc2_hsotg_ep_sethalt - set halt on a given endpoint * @ep: The endpoint to set halt. * @value: Set or unset the halt. */ -static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) +static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hs = hs_ep->parent; int index = hs_ep->index; u32 epreg; @@ -2868,7 +2868,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) if (index == 0) { if (value) - s3c_hsotg_stall_ep0(hs); + dwc2_hsotg_stall_ep0(hs); else dev_warn(hs->dev, "%s: can't clear halt on ep0\n", __func__); @@ -2914,43 +2914,43 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) } /** - * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held + * dwc2_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held * @ep: The endpoint to set halt. * @value: Set or unset the halt. */ -static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) +static int dwc2_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) { - struct s3c_hsotg_ep *hs_ep = our_ep(ep); + struct dwc2_hsotg_ep *hs_ep = our_ep(ep); struct dwc2_hsotg *hs = hs_ep->parent; unsigned long flags = 0; int ret = 0; spin_lock_irqsave(&hs->lock, flags); - ret = s3c_hsotg_ep_sethalt(ep, value); + ret = dwc2_hsotg_ep_sethalt(ep, value); spin_unlock_irqrestore(&hs->lock, flags); return ret; } -static struct usb_ep_ops s3c_hsotg_ep_ops = { - .enable = s3c_hsotg_ep_enable, - .disable = s3c_hsotg_ep_disable, - .alloc_request = s3c_hsotg_ep_alloc_request, - .free_request = s3c_hsotg_ep_free_request, - .queue = s3c_hsotg_ep_queue_lock, - .dequeue = s3c_hsotg_ep_dequeue, - .set_halt = s3c_hsotg_ep_sethalt_lock, +static struct usb_ep_ops dwc2_hsotg_ep_ops = { + .enable = dwc2_hsotg_ep_enable, + .disable = dwc2_hsotg_ep_disable, + .alloc_request = dwc2_hsotg_ep_alloc_request, + .free_request = dwc2_hsotg_ep_free_request, + .queue = dwc2_hsotg_ep_queue_lock, + .dequeue = dwc2_hsotg_ep_dequeue, + .set_halt = dwc2_hsotg_ep_sethalt_lock, /* note, don't believe we have any call for the fifo routines */ }; /** - * s3c_hsotg_phy_enable - enable platform phy dev + * dwc2_hsotg_phy_enable - enable platform phy dev * @hsotg: The driver state * * A wrapper for platform code responsible for controlling * low-level USB code */ -static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_phy_enable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -2967,13 +2967,13 @@ static void s3c_hsotg_phy_enable(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_phy_disable - disable platform phy dev + * dwc2_hsotg_phy_disable - disable platform phy dev * @hsotg: The driver state * * A wrapper for platform code responsible for controlling * low-level USB code */ -static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_phy_disable(struct dwc2_hsotg *hsotg) { struct platform_device *pdev = to_platform_device(hsotg->dev); @@ -2988,10 +2988,10 @@ static void s3c_hsotg_phy_disable(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_init - initalize the usb core + * dwc2_hsotg_init - initalize the usb core * @hsotg: The driver state */ -static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) { u32 trdtim; /* unmask subset of endpoint interrupts */ @@ -3015,7 +3015,7 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) readl(hsotg->regs + GRXFSIZ), readl(hsotg->regs + GNPTXFSIZ)); - s3c_hsotg_init_fifo(hsotg); + dwc2_hsotg_init_fifo(hsotg); /* set the PLL on, remove the HNP/SRP and set the PHY */ trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; @@ -3028,14 +3028,14 @@ static void s3c_hsotg_init(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_udc_start - prepare the udc for work + * dwc2_hsotg_udc_start - prepare the udc for work * @gadget: The usb gadget state * @driver: The usb gadget driver * * Perform initialization to prepare udc device and driver * to work. */ -static int s3c_hsotg_udc_start(struct usb_gadget *gadget, +static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); @@ -3077,13 +3077,13 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, goto err; } - s3c_hsotg_phy_enable(hsotg); + dwc2_hsotg_phy_enable(hsotg); if (!IS_ERR_OR_NULL(hsotg->uphy)) otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget); spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_init(hsotg); - s3c_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_init(hsotg); + dwc2_hsotg_core_init_disconnected(hsotg, false); hsotg->enabled = 0; spin_unlock_irqrestore(&hsotg->lock, flags); @@ -3100,13 +3100,13 @@ err: } /** - * s3c_hsotg_udc_stop - stop the udc + * dwc2_hsotg_udc_stop - stop the udc * @gadget: The usb gadget state * @driver: The usb gadget driver * * Stop udc hw block and stay tunned for future transmissions */ -static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) +static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; @@ -3120,9 +3120,9 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) { if (hsotg->eps_in[ep]) - s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); + dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); if (hsotg->eps_out[ep]) - s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); + dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); } spin_lock_irqsave(&hsotg->lock, flags); @@ -3135,7 +3135,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) if (!IS_ERR_OR_NULL(hsotg->uphy)) otg_set_peripheral(hsotg->uphy->otg, NULL); - s3c_hsotg_phy_disable(hsotg); + dwc2_hsotg_phy_disable(hsotg); regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3147,24 +3147,24 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) } /** - * s3c_hsotg_gadget_getframe - read the frame number + * dwc2_hsotg_gadget_getframe - read the frame number * @gadget: The usb gadget state * * Read the {micro} frame number */ -static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) +static int dwc2_hsotg_gadget_getframe(struct usb_gadget *gadget) { - return s3c_hsotg_read_frameno(to_hsotg(gadget)); + return dwc2_hsotg_read_frameno(to_hsotg(gadget)); } /** - * s3c_hsotg_pullup - connect/disconnect the USB PHY + * dwc2_hsotg_pullup - connect/disconnect the USB PHY * @gadget: The usb gadget state * @is_on: Current state of the USB PHY * * Connect/Disconnect the USB PHY pullup */ -static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) +static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; @@ -3176,11 +3176,11 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) if (is_on) { clk_enable(hsotg->clk); hsotg->enabled = 1; - s3c_hsotg_core_init_disconnected(hsotg, false); - s3c_hsotg_core_connect(hsotg); + dwc2_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_core_connect(hsotg); } else { - s3c_hsotg_core_disconnect(hsotg); - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_core_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); hsotg->enabled = 0; clk_disable(hsotg->clk); } @@ -3192,7 +3192,7 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) return 0; } -static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) +static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags; @@ -3211,12 +3211,12 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) } /* Kill any ep0 requests as controller will be reinitialized */ kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); - s3c_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) - s3c_hsotg_core_connect(hsotg); + dwc2_hsotg_core_connect(hsotg); } else { - s3c_hsotg_core_disconnect(hsotg); - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_core_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); } spin_unlock_irqrestore(&hsotg->lock, flags); @@ -3224,13 +3224,13 @@ static int s3c_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) } /** - * s3c_hsotg_vbus_draw - report bMaxPower field + * dwc2_hsotg_vbus_draw - report bMaxPower field * @gadget: The usb gadget state * @mA: Amount of current * * Report how much power the device may consume to the phy. */ -static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA) +static int dwc2_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA) { struct dwc2_hsotg *hsotg = to_hsotg(gadget); @@ -3239,17 +3239,17 @@ static int s3c_hsotg_vbus_draw(struct usb_gadget *gadget, unsigned mA) return usb_phy_set_power(hsotg->uphy, mA); } -static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { - .get_frame = s3c_hsotg_gadget_getframe, - .udc_start = s3c_hsotg_udc_start, - .udc_stop = s3c_hsotg_udc_stop, - .pullup = s3c_hsotg_pullup, - .vbus_session = s3c_hsotg_vbus_session, - .vbus_draw = s3c_hsotg_vbus_draw, +static const struct usb_gadget_ops dwc2_hsotg_gadget_ops = { + .get_frame = dwc2_hsotg_gadget_getframe, + .udc_start = dwc2_hsotg_udc_start, + .udc_stop = dwc2_hsotg_udc_stop, + .pullup = dwc2_hsotg_pullup, + .vbus_session = dwc2_hsotg_vbus_session, + .vbus_draw = dwc2_hsotg_vbus_draw, }; /** - * s3c_hsotg_initep - initialise a single endpoint + * dwc2_hsotg_initep - initialise a single endpoint * @hsotg: The device state. * @hs_ep: The endpoint to be initialised. * @epnum: The endpoint number @@ -3258,8 +3258,8 @@ static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { * creation) to give to the gadget driver. Setup the endpoint name, any * direction information and other state that may be required. */ -static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, - struct s3c_hsotg_ep *hs_ep, +static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep, int epnum, bool dir_in) { @@ -3287,7 +3287,7 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, hs_ep->parent = hsotg; hs_ep->ep.name = hs_ep->name; usb_ep_set_maxpacket_limit(&hs_ep->ep, epnum ? 1024 : EP0_MPS_LIMIT); - hs_ep->ep.ops = &s3c_hsotg_ep_ops; + hs_ep->ep.ops = &dwc2_hsotg_ep_ops; if (epnum == 0) { hs_ep->ep.caps.type_control = true; @@ -3317,12 +3317,12 @@ static void s3c_hsotg_initep(struct dwc2_hsotg *hsotg, } /** - * s3c_hsotg_hw_cfg - read HW configuration registers + * dwc2_hsotg_hw_cfg - read HW configuration registers * @param: The device state * * Read the USB core HW configuration registers */ -static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) +static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) { u32 cfg; u32 ep_type; @@ -3335,11 +3335,11 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* Add ep0 */ hsotg->num_of_eps++; - hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct s3c_hsotg_ep), + hsotg->eps_in[0] = devm_kzalloc(hsotg->dev, sizeof(struct dwc2_hsotg_ep), GFP_KERNEL); if (!hsotg->eps_in[0]) return -ENOMEM; - /* Same s3c_hsotg_ep is used in both directions for ep0 */ + /* Same dwc2_hsotg_ep is used in both directions for ep0 */ hsotg->eps_out[0] = hsotg->eps_in[0]; cfg = readl(hsotg->regs + GHWCFG1); @@ -3348,14 +3348,14 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* Direction in or both */ if (!(ep_type & 2)) { hsotg->eps_in[i] = devm_kzalloc(hsotg->dev, - sizeof(struct s3c_hsotg_ep), GFP_KERNEL); + sizeof(struct dwc2_hsotg_ep), GFP_KERNEL); if (!hsotg->eps_in[i]) return -ENOMEM; } /* Direction out or both */ if (!(ep_type & 1)) { hsotg->eps_out[i] = devm_kzalloc(hsotg->dev, - sizeof(struct s3c_hsotg_ep), GFP_KERNEL); + sizeof(struct dwc2_hsotg_ep), GFP_KERNEL); if (!hsotg->eps_out[i]) return -ENOMEM; } @@ -3375,10 +3375,10 @@ static int s3c_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) } /** - * s3c_hsotg_dump - dump state of the udc + * dwc2_hsotg_dump - dump state of the udc * @param: The device state */ -static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg) { #ifdef DEBUG struct device *dev = hsotg->dev; @@ -3427,7 +3427,7 @@ static void s3c_hsotg_dump(struct dwc2_hsotg *hsotg) } #ifdef CONFIG_OF -static void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) +static void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { struct device_node *np = hsotg->dev->of_node; u32 len = 0; @@ -3468,7 +3468,7 @@ rx_fifo: &hsotg->g_np_g_tx_fifo_sz); } #else -static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { } +static inline void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { } #endif /** @@ -3479,7 +3479,7 @@ static inline void s3c_hsotg_of_probe(struct dwc2_hsotg *hsotg) { } int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { struct device *dev = hsotg->dev; - struct s3c_hsotg_plat *plat = dev->platform_data; + struct dwc2_hsotg_plat *plat = dev->platform_data; int epnum; int ret; int i; @@ -3488,14 +3488,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; - s3c_hsotg_of_probe(hsotg); + dwc2_hsotg_of_probe(hsotg); /* Initialize to legacy fifo configuration values */ hsotg->g_rx_fifo_sz = 2048; hsotg->g_np_g_tx_fifo_sz = 1024; memcpy(&hsotg->g_tx_fifo_sz[1], p_tx_fifo, sizeof(p_tx_fifo)); /* Device tree specific probe */ - s3c_hsotg_of_probe(hsotg); + dwc2_hsotg_of_probe(hsotg); /* Dump fifo information */ dev_dbg(dev, "NonPeriodic TXFIFO size: %d\n", hsotg->g_np_g_tx_fifo_sz); @@ -3531,7 +3531,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) } hsotg->gadget.max_speed = USB_SPEED_HIGH; - hsotg->gadget.ops = &s3c_hsotg_gadget_ops; + hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; hsotg->gadget.name = dev_name(dev); if (hsotg->dr_mode == USB_DR_MODE_OTG) hsotg->gadget.is_otg = 1; @@ -3548,7 +3548,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* regulators */ for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) - hsotg->supplies[i].supply = s3c_hsotg_supply_names[i]; + hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3566,7 +3566,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) } /* usb phy enable */ - s3c_hsotg_phy_enable(hsotg); + dwc2_hsotg_phy_enable(hsotg); /* * Force Device mode before initialization. @@ -3581,14 +3581,14 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) */ msleep(25); - s3c_hsotg_corereset(hsotg); - ret = s3c_hsotg_hw_cfg(hsotg); + dwc2_hsotg_corereset(hsotg); + ret = dwc2_hsotg_hw_cfg(hsotg); if (ret) { dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret); goto err_clk; } - s3c_hsotg_init(hsotg); + dwc2_hsotg_init(hsotg); /* Switch back to default configuration */ __bic32(hsotg->regs + GUSBCFG, GUSBCFG_FORCEDEVMODE); @@ -3609,10 +3609,10 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) goto err_supplies; } - ret = devm_request_irq(hsotg->dev, irq, s3c_hsotg_irq, IRQF_SHARED, + ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED, dev_name(hsotg->dev), hsotg); if (ret < 0) { - s3c_hsotg_phy_disable(hsotg); + dwc2_hsotg_phy_disable(hsotg); clk_disable_unprepare(hsotg->clk); regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3635,7 +3635,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* allocate EP0 request */ - hsotg->ctrl_req = s3c_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep, + hsotg->ctrl_req = dwc2_hsotg_ep_alloc_request(&hsotg->eps_out[0]->ep, GFP_KERNEL); if (!hsotg->ctrl_req) { dev_err(dev, "failed to allocate ctrl req\n"); @@ -3646,15 +3646,15 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* initialise the endpoints now the core has been initialised */ for (epnum = 0; epnum < hsotg->num_of_eps; epnum++) { if (hsotg->eps_in[epnum]) - s3c_hsotg_initep(hsotg, hsotg->eps_in[epnum], + dwc2_hsotg_initep(hsotg, hsotg->eps_in[epnum], epnum, 1); if (hsotg->eps_out[epnum]) - s3c_hsotg_initep(hsotg, hsotg->eps_out[epnum], + dwc2_hsotg_initep(hsotg, hsotg->eps_out[epnum], epnum, 0); } /* disable power and clock */ - s3c_hsotg_phy_disable(hsotg); + dwc2_hsotg_phy_disable(hsotg); ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); @@ -3667,12 +3667,12 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) if (ret) goto err_supplies; - s3c_hsotg_dump(hsotg); + dwc2_hsotg_dump(hsotg); return 0; err_supplies: - s3c_hsotg_phy_disable(hsotg); + dwc2_hsotg_phy_disable(hsotg); err_clk: clk_disable_unprepare(hsotg->clk); @@ -3680,10 +3680,10 @@ err_clk: } /** - * s3c_hsotg_remove - remove function for hsotg driver + * dwc2_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) +int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(&hsotg->gadget); clk_disable_unprepare(hsotg->clk); @@ -3691,7 +3691,7 @@ int s3c_hsotg_remove(struct dwc2_hsotg *hsotg) return 0; } -int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) +int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; @@ -3709,18 +3709,18 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) spin_lock_irqsave(&hsotg->lock, flags); if (hsotg->enabled) - s3c_hsotg_core_disconnect(hsotg); - s3c_hsotg_disconnect(hsotg); + dwc2_hsotg_core_disconnect(hsotg); + dwc2_hsotg_disconnect(hsotg); hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); - s3c_hsotg_phy_disable(hsotg); + dwc2_hsotg_phy_disable(hsotg); for (ep = 0; ep < hsotg->num_of_eps; ep++) { if (hsotg->eps_in[ep]) - s3c_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); + dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); if (hsotg->eps_out[ep]) - s3c_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); + dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); } ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), @@ -3733,7 +3733,7 @@ int s3c_hsotg_suspend(struct dwc2_hsotg *hsotg) return ret; } -int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) +int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; int ret = 0; @@ -3751,12 +3751,12 @@ int s3c_hsotg_resume(struct dwc2_hsotg *hsotg) ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - s3c_hsotg_phy_enable(hsotg); + dwc2_hsotg_phy_enable(hsotg); spin_lock_irqsave(&hsotg->lock, flags); - s3c_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) - s3c_hsotg_core_connect(hsotg); + dwc2_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); } mutex_unlock(&hsotg->init_mutex); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index f845c41fe9e5..007a3d5a0642 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1382,8 +1382,8 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); - s3c_hsotg_core_init_disconnected(hsotg, false); - s3c_hsotg_core_connect(hsotg); + dwc2_hsotg_core_init_disconnected(hsotg, false); + dwc2_hsotg_core_connect(hsotg); } else { /* A-Device connector (Host Mode) */ dev_dbg(hsotg->dev, "connId A\n"); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 90935304185a..3d1f82def2f3 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -130,7 +130,7 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->hcd_enabled) dwc2_hcd_remove(hsotg); if (hsotg->gadget_enabled) - s3c_hsotg_remove(hsotg); + dwc2_hsotg_remove(hsotg); return 0; } @@ -269,7 +269,7 @@ static int dwc2_driver_probe(struct platform_device *dev) retval = dwc2_hcd_init(hsotg, irq); if (retval) { if (hsotg->gadget_enabled) - s3c_hsotg_remove(hsotg); + dwc2_hsotg_remove(hsotg); return retval; } hsotg->hcd_enabled = 1; @@ -288,7 +288,7 @@ static int __maybe_unused dwc2_suspend(struct device *dev) int ret = 0; if (dwc2_is_device_mode(dwc2)) { - ret = s3c_hsotg_suspend(dwc2); + ret = dwc2_hsotg_suspend(dwc2); } else { if (dwc2->lx_state == DWC2_L0) return 0; @@ -305,7 +305,7 @@ static int __maybe_unused dwc2_resume(struct device *dev) int ret = 0; if (dwc2_is_device_mode(dwc2)) { - ret = s3c_hsotg_resume(dwc2); + ret = dwc2_hsotg_resume(dwc2); } else { phy_power_on(dwc2->phy); phy_init(dwc2->phy); diff --git a/include/linux/platform_data/s3c-hsotg.h b/include/linux/platform_data/s3c-hsotg.h index 3f1cbf95ec3b..3982586ba6df 100644 --- a/include/linux/platform_data/s3c-hsotg.h +++ b/include/linux/platform_data/s3c-hsotg.h @@ -17,19 +17,19 @@ struct platform_device; -enum s3c_hsotg_dmamode { +enum dwc2_hsotg_dmamode { S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */ S3C_HSOTG_DMA_ONLY, /* always use DMA */ S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */ }; /** - * struct s3c_hsotg_plat - platform data for high-speed otg/udc + * struct dwc2_hsotg_plat - platform data for high-speed otg/udc * @dma: Whether to use DMA or not. * @is_osc: The clock source is an oscillator, not a crystal */ -struct s3c_hsotg_plat { - enum s3c_hsotg_dmamode dma; +struct dwc2_hsotg_plat { + enum dwc2_hsotg_dmamode dma; unsigned int is_osc:1; int phy_type; @@ -37,6 +37,6 @@ struct s3c_hsotg_plat { int (*phy_exit)(struct platform_device *pdev, int type); }; -extern void s3c_hsotg_set_platdata(struct s3c_hsotg_plat *pd); +extern void dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd); #endif /* __LINUX_USB_S3C_HSOTG_H */ -- cgit v1.2.3 From 428163d703712d11cacfddaf30f40b18ccc50042 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 10 Aug 2015 16:46:19 +0200 Subject: usb: gadget: at91_udc: move at91_udc_data in at91_udc.h struct at91_udc_data is now only used inside the driver, move it to its include. Acked-by: Nicolas Ferre Signed-off-by: Alexandre Belloni Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/at91_udc.h | 8 ++++++++ include/linux/platform_data/atmel.h | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 2679c8b217cc..0a433e6b346b 100644 --- a/drivers/usb/gadget/udc/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h @@ -112,6 +112,14 @@ struct at91_udc_caps { void (*pullup)(struct at91_udc *udc, int is_on); }; +struct at91_udc_data { + int vbus_pin; /* high == host powering us */ + u8 vbus_active_low; /* vbus polarity */ + u8 vbus_polled; /* Use polling, not interrupt */ + int pullup_pin; /* active == D+ pulled up */ + u8 pullup_active_low; /* true == pullup_pin is active low */ +}; + /* * driver is non-SMP, and just blocks IRQs whenever it needs * access protection for chip registers or driver state diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index 527a85c61924..9127ebbaa487 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -25,15 +25,6 @@ */ #define ATMEL_MAX_UART 7 - /* USB Device */ -struct at91_udc_data { - int vbus_pin; /* high == host powering us */ - u8 vbus_active_low; /* vbus polarity */ - u8 vbus_polled; /* Use polling, not interrupt */ - int pullup_pin; /* active == D+ pulled up */ - u8 pullup_active_low; /* true == pullup_pin is active low */ -}; - /* Compact Flash */ struct at91_cf_data { int irq_pin; /* I/O IRQ */ -- cgit v1.2.3 From bba787a860fa8c7b4ab3cefbfcb2b214b2aed30c Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Wed, 5 Aug 2015 08:54:55 +0200 Subject: usb: gadget: ether: Allow jumbo frames USB network adapters support Jumbo frames. The only thing blocking that feature is the code in the gadget driver that disposes of packets larger than 1518 bytes, and the limit on the ioctl to set the mtu. This patch relaxes these limits, and allows up to 15k frames sizes. The 15k value was chosen because 16k does not work on all platforms, and usingclose to 16k will result in allocating 5 or 8 4k pages to store the skb, wasting pages at no measurable performance gain. On a topic-miami board (Zynq-7000), iperf3 performance reports: MTU= 1500, PC-to-gadget: 139 Mbps, Gadget-to-PC: 116 Mbps MTU=15000, PC-to-gadget: 239 Mbps, Gadget-to-PC: 361 Mbps On boards with slower CPUs the performance improvement will be relatively much larger, e.g. an OMAP-L138 increased from 40 to 220 Mbps using a similar patch on an 2.6.37 kernel. Signed-off-by: Mike Looijmans Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_ether.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index f1fd777ef4ec..6828ea294024 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -48,6 +48,11 @@ #define UETH__VERSION "29-May-2008" +/* Experiments show that both Linux and Windows hosts allow up to 16k + * frame sizes. Set the max size to 15k+52 to prevent allocating 32k + * blocks and still have efficient handling. */ +#define GETHER_MAX_ETH_FRAME_LEN 15412 + struct eth_dev { /* lock is held while accessing port_usb */ @@ -146,7 +151,7 @@ static int ueth_change_mtu(struct net_device *net, int new_mtu) spin_lock_irqsave(&dev->lock, flags); if (dev->port_usb) status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN) + else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) status = -ERANGE; else net->mtu = new_mtu; @@ -294,7 +299,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > GETHER_MAX_ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); -- cgit v1.2.3 From 95c8bc3609440af5e4a4f760b8680caea7424396 Mon Sep 17 00:00:00 2001 From: Antti Seppälä Date: Thu, 20 Aug 2015 21:41:07 +0300 Subject: usb: dwc2: Use platform endianness when accessing registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch switches calls to readl/writel to their dwc2_readl/dwc2_writel equivalents which preserve platform endianness. This patch is necessary to access dwc2 registers correctly on big-endian systems such as the mips based SoCs made by Lantiq. Then dwc2 can be used to replace ifx-hcd driver for Lantiq platforms found e.g. in OpenWrt. The patch was autogenerated with the following commands: $EDITOR core.h sed -i "s/\/dwc2_readl/g" *.c hcd.h hw.h sed -i "s/\/dwc2_writel/g" *.c hcd.h hw.h Some files were then hand-edited to fix checkpatch.pl warnings about too long lines. Signed-off-by: Antti Seppälä Signed-off-by: Vincent Pelletier Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 469 ++++++++++++++++++++++--------------------- drivers/usb/dwc2/core.h | 28 ++- drivers/usb/dwc2/core_intr.c | 73 +++---- drivers/usb/dwc2/debugfs.c | 52 ++--- drivers/usb/dwc2/gadget.c | 284 +++++++++++++------------- drivers/usb/dwc2/hcd.c | 140 ++++++------- drivers/usb/dwc2/hcd.h | 15 +- drivers/usb/dwc2/hcd_ddma.c | 10 +- drivers/usb/dwc2/hcd_intr.c | 82 ++++---- drivers/usb/dwc2/hcd_queue.c | 10 +- 10 files changed, 591 insertions(+), 572 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index b00fe9539184..fc0521aeed77 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -73,13 +73,13 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) /* Backup Host regs */ hr = &hsotg->hr_backup; - hr->hcfg = readl(hsotg->regs + HCFG); - hr->haintmsk = readl(hsotg->regs + HAINTMSK); + hr->hcfg = dwc2_readl(hsotg->regs + HCFG); + hr->haintmsk = dwc2_readl(hsotg->regs + HAINTMSK); for (i = 0; i < hsotg->core_params->host_channels; ++i) - hr->hcintmsk[i] = readl(hsotg->regs + HCINTMSK(i)); + hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i)); - hr->hprt0 = readl(hsotg->regs + HPRT0); - hr->hfir = readl(hsotg->regs + HFIR); + hr->hprt0 = dwc2_readl(hsotg->regs + HPRT0); + hr->hfir = dwc2_readl(hsotg->regs + HFIR); hr->valid = true; return 0; @@ -108,14 +108,14 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) } hr->valid = false; - writel(hr->hcfg, hsotg->regs + HCFG); - writel(hr->haintmsk, hsotg->regs + HAINTMSK); + dwc2_writel(hr->hcfg, hsotg->regs + HCFG); + dwc2_writel(hr->haintmsk, hsotg->regs + HAINTMSK); for (i = 0; i < hsotg->core_params->host_channels; ++i) - writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i)); + dwc2_writel(hr->hcintmsk[i], hsotg->regs + HCINTMSK(i)); - writel(hr->hprt0, hsotg->regs + HPRT0); - writel(hr->hfir, hsotg->regs + HFIR); + dwc2_writel(hr->hprt0, hsotg->regs + HPRT0); + dwc2_writel(hr->hfir, hsotg->regs + HFIR); return 0; } @@ -146,15 +146,15 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) /* Backup dev regs */ dr = &hsotg->dr_backup; - dr->dcfg = readl(hsotg->regs + DCFG); - dr->dctl = readl(hsotg->regs + DCTL); - dr->daintmsk = readl(hsotg->regs + DAINTMSK); - dr->diepmsk = readl(hsotg->regs + DIEPMSK); - dr->doepmsk = readl(hsotg->regs + DOEPMSK); + dr->dcfg = dwc2_readl(hsotg->regs + DCFG); + dr->dctl = dwc2_readl(hsotg->regs + DCTL); + dr->daintmsk = dwc2_readl(hsotg->regs + DAINTMSK); + dr->diepmsk = dwc2_readl(hsotg->regs + DIEPMSK); + dr->doepmsk = dwc2_readl(hsotg->regs + DOEPMSK); for (i = 0; i < hsotg->num_of_eps; i++) { /* Backup IN EPs */ - dr->diepctl[i] = readl(hsotg->regs + DIEPCTL(i)); + dr->diepctl[i] = dwc2_readl(hsotg->regs + DIEPCTL(i)); /* Ensure DATA PID is correctly configured */ if (dr->diepctl[i] & DXEPCTL_DPID) @@ -162,11 +162,11 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) else dr->diepctl[i] |= DXEPCTL_SETD0PID; - dr->dieptsiz[i] = readl(hsotg->regs + DIEPTSIZ(i)); - dr->diepdma[i] = readl(hsotg->regs + DIEPDMA(i)); + dr->dieptsiz[i] = dwc2_readl(hsotg->regs + DIEPTSIZ(i)); + dr->diepdma[i] = dwc2_readl(hsotg->regs + DIEPDMA(i)); /* Backup OUT EPs */ - dr->doepctl[i] = readl(hsotg->regs + DOEPCTL(i)); + dr->doepctl[i] = dwc2_readl(hsotg->regs + DOEPCTL(i)); /* Ensure DATA PID is correctly configured */ if (dr->doepctl[i] & DXEPCTL_DPID) @@ -174,8 +174,8 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) else dr->doepctl[i] |= DXEPCTL_SETD0PID; - dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i)); - dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i)); + dr->doeptsiz[i] = dwc2_readl(hsotg->regs + DOEPTSIZ(i)); + dr->doepdma[i] = dwc2_readl(hsotg->regs + DOEPDMA(i)); } dr->valid = true; return 0; @@ -205,28 +205,28 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) } dr->valid = false; - writel(dr->dcfg, hsotg->regs + DCFG); - writel(dr->dctl, hsotg->regs + DCTL); - writel(dr->daintmsk, hsotg->regs + DAINTMSK); - writel(dr->diepmsk, hsotg->regs + DIEPMSK); - writel(dr->doepmsk, hsotg->regs + DOEPMSK); + dwc2_writel(dr->dcfg, hsotg->regs + DCFG); + dwc2_writel(dr->dctl, hsotg->regs + DCTL); + dwc2_writel(dr->daintmsk, hsotg->regs + DAINTMSK); + dwc2_writel(dr->diepmsk, hsotg->regs + DIEPMSK); + dwc2_writel(dr->doepmsk, hsotg->regs + DOEPMSK); for (i = 0; i < hsotg->num_of_eps; i++) { /* Restore IN EPs */ - writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i)); - writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i)); - writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i)); + dwc2_writel(dr->diepctl[i], hsotg->regs + DIEPCTL(i)); + dwc2_writel(dr->dieptsiz[i], hsotg->regs + DIEPTSIZ(i)); + dwc2_writel(dr->diepdma[i], hsotg->regs + DIEPDMA(i)); /* Restore OUT EPs */ - writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i)); - writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i)); - writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i)); + dwc2_writel(dr->doepctl[i], hsotg->regs + DOEPCTL(i)); + dwc2_writel(dr->doeptsiz[i], hsotg->regs + DOEPTSIZ(i)); + dwc2_writel(dr->doepdma[i], hsotg->regs + DOEPDMA(i)); } /* Set the Power-On Programming done bit */ - dctl = readl(hsotg->regs + DCTL); + dctl = dwc2_readl(hsotg->regs + DCTL); dctl |= DCTL_PWRONPRGDONE; - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); return 0; } @@ -253,16 +253,16 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) /* Backup global regs */ gr = &hsotg->gr_backup; - gr->gotgctl = readl(hsotg->regs + GOTGCTL); - gr->gintmsk = readl(hsotg->regs + GINTMSK); - gr->gahbcfg = readl(hsotg->regs + GAHBCFG); - gr->gusbcfg = readl(hsotg->regs + GUSBCFG); - gr->grxfsiz = readl(hsotg->regs + GRXFSIZ); - gr->gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); - gr->hptxfsiz = readl(hsotg->regs + HPTXFSIZ); - gr->gdfifocfg = readl(hsotg->regs + GDFIFOCFG); + gr->gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); + gr->gintmsk = dwc2_readl(hsotg->regs + GINTMSK); + gr->gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); + gr->gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + gr->grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); + gr->gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); + gr->hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); + gr->gdfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG); for (i = 0; i < MAX_EPS_CHANNELS; i++) - gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i)); + gr->dtxfsiz[i] = dwc2_readl(hsotg->regs + DPTXFSIZN(i)); gr->valid = true; return 0; @@ -291,17 +291,17 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg) } gr->valid = false; - writel(0xffffffff, hsotg->regs + GINTSTS); - writel(gr->gotgctl, hsotg->regs + GOTGCTL); - writel(gr->gintmsk, hsotg->regs + GINTMSK); - writel(gr->gusbcfg, hsotg->regs + GUSBCFG); - writel(gr->gahbcfg, hsotg->regs + GAHBCFG); - writel(gr->grxfsiz, hsotg->regs + GRXFSIZ); - writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ); - writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ); - writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG); + dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); + dwc2_writel(gr->gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gr->gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gr->gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gr->gahbcfg, hsotg->regs + GAHBCFG); + dwc2_writel(gr->grxfsiz, hsotg->regs + GRXFSIZ); + dwc2_writel(gr->gnptxfsiz, hsotg->regs + GNPTXFSIZ); + dwc2_writel(gr->hptxfsiz, hsotg->regs + HPTXFSIZ); + dwc2_writel(gr->gdfifocfg, hsotg->regs + GDFIFOCFG); for (i = 0; i < MAX_EPS_CHANNELS; i++) - writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i)); + dwc2_writel(gr->dtxfsiz[i], hsotg->regs + DPTXFSIZN(i)); return 0; } @@ -320,17 +320,17 @@ int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore) if (!hsotg->core_params->hibernation) return -ENOTSUPP; - pcgcctl = readl(hsotg->regs + PCGCTL); + pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); pcgcctl &= ~PCGCTL_STOPPCLK; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); - pcgcctl = readl(hsotg->regs + PCGCTL); + pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); pcgcctl &= ~PCGCTL_PWRCLMP; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); - pcgcctl = readl(hsotg->regs + PCGCTL); + pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); pcgcctl &= ~PCGCTL_RSTPDWNMODULE; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); udelay(100); if (restore) { @@ -398,18 +398,18 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg) } /* Put the controller in low power state */ - pcgcctl = readl(hsotg->regs + PCGCTL); + pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); pcgcctl |= PCGCTL_PWRCLMP; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); ndelay(20); pcgcctl |= PCGCTL_RSTPDWNMODULE; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); ndelay(20); pcgcctl |= PCGCTL_STOPPCLK; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); return ret; } @@ -425,10 +425,10 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) u32 intmsk; /* Clear any pending OTG Interrupts */ - writel(0xffffffff, hsotg->regs + GOTGINT); + dwc2_writel(0xffffffff, hsotg->regs + GOTGINT); /* Clear any pending interrupts */ - writel(0xffffffff, hsotg->regs + GINTSTS); + dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); /* Enable the interrupts in the GINTMSK */ intmsk = GINTSTS_MODEMIS | GINTSTS_OTGINT; @@ -441,7 +441,7 @@ static void dwc2_enable_common_interrupts(struct dwc2_hsotg *hsotg) intmsk |= GINTSTS_WKUPINT | GINTSTS_USBSUSP | GINTSTS_SESSREQINT; - writel(intmsk, hsotg->regs + GINTMSK); + dwc2_writel(intmsk, hsotg->regs + GINTMSK); } /* @@ -464,10 +464,10 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) } dev_dbg(hsotg->dev, "Initializing HCFG.FSLSPClkSel to %08x\n", val); - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); hcfg &= ~HCFG_FSLSPCLKSEL_MASK; hcfg |= val << HCFG_FSLSPCLKSEL_SHIFT; - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); } /* @@ -485,7 +485,7 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) /* Wait for AHB master IDLE state */ do { usleep_range(20000, 40000); - greset = readl(hsotg->regs + GRSTCTL); + greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, "%s() HANG! AHB Idle GRSTCTL=%0x\n", @@ -497,10 +497,10 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) /* Core Soft Reset */ count = 0; greset |= GRSTCTL_CSFTRST; - writel(greset, hsotg->regs + GRSTCTL); + dwc2_writel(greset, hsotg->regs + GRSTCTL); do { usleep_range(20000, 40000); - greset = readl(hsotg->regs + GRSTCTL); + greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 50) { dev_warn(hsotg->dev, "%s() HANG! Soft Reset GRSTCTL=%0x\n", @@ -510,20 +510,20 @@ static int dwc2_core_reset(struct dwc2_hsotg *hsotg) } while (greset & GRSTCTL_CSFTRST); if (hsotg->dr_mode == USB_DR_MODE_HOST) { - gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEDEVMODE; gusbcfg |= GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); } else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { - gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; gusbcfg |= GUSBCFG_FORCEDEVMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); } else if (hsotg->dr_mode == USB_DR_MODE_OTG) { - gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; gusbcfg &= ~GUSBCFG_FORCEDEVMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); } /* @@ -546,9 +546,9 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) */ if (select_phy) { dev_dbg(hsotg->dev, "FS PHY selected\n"); - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); usbcfg |= GUSBCFG_PHYSEL; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after a PHY select */ retval = dwc2_core_reset(hsotg); @@ -571,18 +571,18 @@ static int dwc2_fs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) dev_dbg(hsotg->dev, "FS PHY enabling I2C\n"); /* Program GUSBCFG.OtgUtmiFsSel to I2C */ - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); usbcfg |= GUSBCFG_OTG_UTMI_FS_SEL; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Program GI2CCTL.I2CEn */ - i2cctl = readl(hsotg->regs + GI2CCTL); + i2cctl = dwc2_readl(hsotg->regs + GI2CCTL); i2cctl &= ~GI2CCTL_I2CDEVADDR_MASK; i2cctl |= 1 << GI2CCTL_I2CDEVADDR_SHIFT; i2cctl &= ~GI2CCTL_I2CEN; - writel(i2cctl, hsotg->regs + GI2CCTL); + dwc2_writel(i2cctl, hsotg->regs + GI2CCTL); i2cctl |= GI2CCTL_I2CEN; - writel(i2cctl, hsotg->regs + GI2CCTL); + dwc2_writel(i2cctl, hsotg->regs + GI2CCTL); } return retval; @@ -596,7 +596,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) if (!select_phy) return 0; - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); /* * HS PHY parameters. These parameters are preserved during soft reset @@ -624,7 +624,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) break; } - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset after setting the PHY parameters */ retval = dwc2_core_reset(hsotg); @@ -659,15 +659,15 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED && hsotg->core_params->ulpi_fs_ls > 0) { dev_dbg(hsotg->dev, "Setting ULPI FSLS\n"); - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); usbcfg |= GUSBCFG_ULPI_FS_LS; usbcfg |= GUSBCFG_ULPI_CLK_SUSP_M; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); } else { - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); usbcfg &= ~GUSBCFG_ULPI_FS_LS; usbcfg &= ~GUSBCFG_ULPI_CLK_SUSP_M; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); } return retval; @@ -675,7 +675,7 @@ static int dwc2_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) { - u32 ahbcfg = readl(hsotg->regs + GAHBCFG); + u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); switch (hsotg->hw_params.arch) { case GHWCFG2_EXT_DMA_ARCH: @@ -714,7 +714,7 @@ static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) if (hsotg->core_params->dma_enable > 0) ahbcfg |= GAHBCFG_DMA_EN; - writel(ahbcfg, hsotg->regs + GAHBCFG); + dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); return 0; } @@ -723,7 +723,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) { u32 usbcfg; - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); usbcfg &= ~(GUSBCFG_HNPCAP | GUSBCFG_SRPCAP); switch (hsotg->hw_params.op_mode) { @@ -751,7 +751,7 @@ static void dwc2_gusbcfg_init(struct dwc2_hsotg *hsotg) break; } - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); } /** @@ -769,7 +769,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); /* Set ULPI External VBUS bit if needed */ usbcfg &= ~GUSBCFG_ULPI_EXT_VBUS_DRV; @@ -782,7 +782,7 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) if (hsotg->core_params->ts_dline > 0) usbcfg |= GUSBCFG_TERMSELDLPULSE; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); /* Reset the Controller */ retval = dwc2_core_reset(hsotg); @@ -808,11 +808,11 @@ int dwc2_core_init(struct dwc2_hsotg *hsotg, bool select_phy, int irq) dwc2_gusbcfg_init(hsotg); /* Program the GOTGCTL register */ - otgctl = readl(hsotg->regs + GOTGCTL); + otgctl = dwc2_readl(hsotg->regs + GOTGCTL); otgctl &= ~GOTGCTL_OTGVER; if (hsotg->core_params->otg_ver > 0) otgctl |= GOTGCTL_OTGVER; - writel(otgctl, hsotg->regs + GOTGCTL); + dwc2_writel(otgctl, hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "OTG VER PARAM: %d\n", hsotg->core_params->otg_ver); /* Clear the SRP success bit for FS-I2c */ @@ -848,16 +848,16 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "%s()\n", __func__); /* Disable all interrupts */ - writel(0, hsotg->regs + GINTMSK); - writel(0, hsotg->regs + HAINTMSK); + dwc2_writel(0, hsotg->regs + GINTMSK); + dwc2_writel(0, hsotg->regs + HAINTMSK); /* Enable the common interrupts */ dwc2_enable_common_interrupts(hsotg); /* Enable host mode interrupts without disturbing common interrupts */ - intmsk = readl(hsotg->regs + GINTMSK); + intmsk = dwc2_readl(hsotg->regs + GINTMSK); intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT; - writel(intmsk, hsotg->regs + GINTMSK); + dwc2_writel(intmsk, hsotg->regs + GINTMSK); } /** @@ -867,12 +867,12 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) */ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg) { - u32 intmsk = readl(hsotg->regs + GINTMSK); + u32 intmsk = dwc2_readl(hsotg->regs + GINTMSK); /* Disable host mode interrupts without disturbing common interrupts */ intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT | GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP); - writel(intmsk, hsotg->regs + GINTMSK); + dwc2_writel(intmsk, hsotg->regs + GINTMSK); } /* @@ -952,36 +952,37 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) dwc2_calculate_dynamic_fifo(hsotg); /* Rx FIFO */ - grxfsiz = readl(hsotg->regs + GRXFSIZ); + grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); dev_dbg(hsotg->dev, "initial grxfsiz=%08x\n", grxfsiz); grxfsiz &= ~GRXFSIZ_DEPTH_MASK; grxfsiz |= params->host_rx_fifo_size << GRXFSIZ_DEPTH_SHIFT & GRXFSIZ_DEPTH_MASK; - writel(grxfsiz, hsotg->regs + GRXFSIZ); - dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", readl(hsotg->regs + GRXFSIZ)); + dwc2_writel(grxfsiz, hsotg->regs + GRXFSIZ); + dev_dbg(hsotg->dev, "new grxfsiz=%08x\n", + dwc2_readl(hsotg->regs + GRXFSIZ)); /* Non-periodic Tx FIFO */ dev_dbg(hsotg->dev, "initial gnptxfsiz=%08x\n", - readl(hsotg->regs + GNPTXFSIZ)); + dwc2_readl(hsotg->regs + GNPTXFSIZ)); nptxfsiz = params->host_nperio_tx_fifo_size << FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; nptxfsiz |= params->host_rx_fifo_size << FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; - writel(nptxfsiz, hsotg->regs + GNPTXFSIZ); + dwc2_writel(nptxfsiz, hsotg->regs + GNPTXFSIZ); dev_dbg(hsotg->dev, "new gnptxfsiz=%08x\n", - readl(hsotg->regs + GNPTXFSIZ)); + dwc2_readl(hsotg->regs + GNPTXFSIZ)); /* Periodic Tx FIFO */ dev_dbg(hsotg->dev, "initial hptxfsiz=%08x\n", - readl(hsotg->regs + HPTXFSIZ)); + dwc2_readl(hsotg->regs + HPTXFSIZ)); hptxfsiz = params->host_perio_tx_fifo_size << FIFOSIZE_DEPTH_SHIFT & FIFOSIZE_DEPTH_MASK; hptxfsiz |= (params->host_rx_fifo_size + params->host_nperio_tx_fifo_size) << FIFOSIZE_STARTADDR_SHIFT & FIFOSIZE_STARTADDR_MASK; - writel(hptxfsiz, hsotg->regs + HPTXFSIZ); + dwc2_writel(hptxfsiz, hsotg->regs + HPTXFSIZ); dev_dbg(hsotg->dev, "new hptxfsiz=%08x\n", - readl(hsotg->regs + HPTXFSIZ)); + dwc2_readl(hsotg->regs + HPTXFSIZ)); if (hsotg->core_params->en_multiple_tx_fifo > 0 && hsotg->hw_params.snpsid <= DWC2_CORE_REV_2_94a) { @@ -989,14 +990,14 @@ static void dwc2_config_fifos(struct dwc2_hsotg *hsotg) * Global DFIFOCFG calculation for Host mode - * include RxFIFO, NPTXFIFO and HPTXFIFO */ - dfifocfg = readl(hsotg->regs + GDFIFOCFG); + dfifocfg = dwc2_readl(hsotg->regs + GDFIFOCFG); dfifocfg &= ~GDFIFOCFG_EPINFOBASE_MASK; dfifocfg |= (params->host_rx_fifo_size + params->host_nperio_tx_fifo_size + params->host_perio_tx_fifo_size) << GDFIFOCFG_EPINFOBASE_SHIFT & GDFIFOCFG_EPINFOBASE_MASK; - writel(dfifocfg, hsotg->regs + GDFIFOCFG); + dwc2_writel(dfifocfg, hsotg->regs + GDFIFOCFG); } } @@ -1017,14 +1018,14 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); /* Restart the Phy Clock */ - writel(0, hsotg->regs + PCGCTL); + dwc2_writel(0, hsotg->regs + PCGCTL); /* Initialize Host Configuration Register */ dwc2_init_fs_ls_pclk_sel(hsotg); if (hsotg->core_params->speed == DWC2_SPEED_PARAM_FULL) { - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); hcfg |= HCFG_FSLSSUPP; - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); } /* @@ -1033,9 +1034,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) * and its value must not be changed during runtime. */ if (hsotg->core_params->reload_ctl > 0) { - hfir = readl(hsotg->regs + HFIR); + hfir = dwc2_readl(hsotg->regs + HFIR); hfir |= HFIR_RLDCTRL; - writel(hfir, hsotg->regs + HFIR); + dwc2_writel(hfir, hsotg->regs + HFIR); } if (hsotg->core_params->dma_desc_enable > 0) { @@ -1051,9 +1052,9 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) "falling back to buffer DMA mode.\n"); hsotg->core_params->dma_desc_enable = 0; } else { - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); hcfg |= HCFG_DESCDMA; - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); } } @@ -1062,18 +1063,18 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) /* TODO - check this */ /* Clear Host Set HNP Enable in the OTG Control Register */ - otgctl = readl(hsotg->regs + GOTGCTL); + otgctl = dwc2_readl(hsotg->regs + GOTGCTL); otgctl &= ~GOTGCTL_HSTSETHNPEN; - writel(otgctl, hsotg->regs + GOTGCTL); + dwc2_writel(otgctl, hsotg->regs + GOTGCTL); /* Make sure the FIFOs are flushed */ dwc2_flush_tx_fifo(hsotg, 0x10 /* all TX FIFOs */); dwc2_flush_rx_fifo(hsotg); /* Clear Host Set HNP Enable in the OTG Control Register */ - otgctl = readl(hsotg->regs + GOTGCTL); + otgctl = dwc2_readl(hsotg->regs + GOTGCTL); otgctl &= ~GOTGCTL_HSTSETHNPEN; - writel(otgctl, hsotg->regs + GOTGCTL); + dwc2_writel(otgctl, hsotg->regs + GOTGCTL); if (hsotg->core_params->dma_desc_enable <= 0) { int num_channels, i; @@ -1082,25 +1083,25 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) /* Flush out any leftover queued requests */ num_channels = hsotg->core_params->host_channels; for (i = 0; i < num_channels; i++) { - hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); hcchar &= ~HCCHAR_CHENA; hcchar |= HCCHAR_CHDIS; hcchar &= ~HCCHAR_EPDIR; - writel(hcchar, hsotg->regs + HCCHAR(i)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); } /* Halt all channels to put them into a known state */ for (i = 0; i < num_channels; i++) { int count = 0; - hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); hcchar |= HCCHAR_CHENA | HCCHAR_CHDIS; hcchar &= ~HCCHAR_EPDIR; - writel(hcchar, hsotg->regs + HCCHAR(i)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); dev_dbg(hsotg->dev, "%s: Halt channel %d\n", __func__, i); do { - hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); if (++count > 1000) { dev_err(hsotg->dev, "Unable to clear enable on channel %d\n", @@ -1121,7 +1122,7 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg) !!(hprt0 & HPRT0_PWR)); if (!(hprt0 & HPRT0_PWR)) { hprt0 |= HPRT0_PWR; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); } } @@ -1201,7 +1202,7 @@ static void dwc2_hc_enable_slave_ints(struct dwc2_hsotg *hsotg, break; } - writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); } @@ -1238,7 +1239,7 @@ static void dwc2_hc_enable_dma_ints(struct dwc2_hsotg *hsotg, } } - writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "set HCINTMSK to %08x\n", hcintmsk); } @@ -1259,16 +1260,16 @@ static void dwc2_hc_enable_ints(struct dwc2_hsotg *hsotg, } /* Enable the top level host channel interrupt */ - intmsk = readl(hsotg->regs + HAINTMSK); + intmsk = dwc2_readl(hsotg->regs + HAINTMSK); intmsk |= 1 << chan->hc_num; - writel(intmsk, hsotg->regs + HAINTMSK); + dwc2_writel(intmsk, hsotg->regs + HAINTMSK); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "set HAINTMSK to %08x\n", intmsk); /* Make sure host channel interrupts are enabled */ - intmsk = readl(hsotg->regs + GINTMSK); + intmsk = dwc2_readl(hsotg->regs + GINTMSK); intmsk |= GINTSTS_HCHINT; - writel(intmsk, hsotg->regs + GINTMSK); + dwc2_writel(intmsk, hsotg->regs + GINTMSK); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "set GINTMSK to %08x\n", intmsk); } @@ -1297,7 +1298,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) /* Clear old interrupt conditions for this host channel */ hcintmsk = 0xffffffff; hcintmsk &= ~HCINTMSK_RESERVED14_31; - writel(hcintmsk, hsotg->regs + HCINT(hc_num)); + dwc2_writel(hcintmsk, hsotg->regs + HCINT(hc_num)); /* Enable channel interrupts required for this transfer */ dwc2_hc_enable_ints(hsotg, chan); @@ -1314,7 +1315,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) hcchar |= HCCHAR_LSPDDEV; hcchar |= chan->ep_type << HCCHAR_EPTYPE_SHIFT & HCCHAR_EPTYPE_MASK; hcchar |= chan->max_packet << HCCHAR_MPS_SHIFT & HCCHAR_MPS_MASK; - writel(hcchar, hsotg->regs + HCCHAR(hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(hc_num)); if (dbg_hc(chan)) { dev_vdbg(hsotg->dev, "set HCCHAR(%d) to %08x\n", hc_num, hcchar); @@ -1368,7 +1369,7 @@ void dwc2_hc_init(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) } } - writel(hcsplt, hsotg->regs + HCSPLT(hc_num)); + dwc2_writel(hcsplt, hsotg->regs + HCSPLT(hc_num)); } /** @@ -1420,14 +1421,14 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, u32 hcintmsk = HCINTMSK_CHHLTD; dev_vdbg(hsotg->dev, "dequeue/error\n"); - writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); + dwc2_writel(hcintmsk, hsotg->regs + HCINTMSK(chan->hc_num)); /* * Make sure no other interrupts besides halt are currently * pending. Handling another interrupt could cause a crash due * to the QTD and QH state. */ - writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num)); + dwc2_writel(~hcintmsk, hsotg->regs + HCINT(chan->hc_num)); /* * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR @@ -1436,7 +1437,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, */ chan->halt_status = halt_status; - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); if (!(hcchar & HCCHAR_CHENA)) { /* * The channel is either already halted or it hasn't @@ -1464,7 +1465,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, return; } - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); /* No need to set the bit in DDMA for disabling the channel */ /* TODO check it everywhere channel is disabled */ @@ -1487,7 +1488,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL || chan->ep_type == USB_ENDPOINT_XFER_BULK) { dev_vdbg(hsotg->dev, "control/bulk\n"); - nptxsts = readl(hsotg->regs + GNPTXSTS); + nptxsts = dwc2_readl(hsotg->regs + GNPTXSTS); if ((nptxsts & TXSTS_QSPCAVAIL_MASK) == 0) { dev_vdbg(hsotg->dev, "Disabling channel\n"); hcchar &= ~HCCHAR_CHENA; @@ -1495,7 +1496,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, } else { if (dbg_perio()) dev_vdbg(hsotg->dev, "isoc/intr\n"); - hptxsts = readl(hsotg->regs + HPTXSTS); + hptxsts = dwc2_readl(hsotg->regs + HPTXSTS); if ((hptxsts & TXSTS_QSPCAVAIL_MASK) == 0 || hsotg->queuing_high_bandwidth) { if (dbg_perio()) @@ -1508,7 +1509,7 @@ void dwc2_hc_halt(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, dev_vdbg(hsotg->dev, "DMA enabled\n"); } - writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); chan->halt_status = halt_status; if (hcchar & HCCHAR_CHENA) { @@ -1555,10 +1556,10 @@ void dwc2_hc_cleanup(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) * Clear channel interrupt enables and any unhandled channel interrupt * conditions */ - writel(0, hsotg->regs + HCINTMSK(chan->hc_num)); + dwc2_writel(0, hsotg->regs + HCINTMSK(chan->hc_num)); hcintmsk = 0xffffffff; hcintmsk &= ~HCINTMSK_RESERVED14_31; - writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num)); + dwc2_writel(hcintmsk, hsotg->regs + HCINT(chan->hc_num)); } /** @@ -1644,13 +1645,13 @@ static void dwc2_hc_write_packet(struct dwc2_hsotg *hsotg, if (((unsigned long)data_buf & 0x3) == 0) { /* xfer_buf is DWORD aligned */ for (i = 0; i < dword_count; i++, data_buf++) - writel(*data_buf, data_fifo); + dwc2_writel(*data_buf, data_fifo); } else { /* xfer_buf is not DWORD aligned */ for (i = 0; i < dword_count; i++, data_buf++) { u32 data = data_buf[0] | data_buf[1] << 8 | data_buf[2] << 16 | data_buf[3] << 24; - writel(data, data_fifo); + dwc2_writel(data, data_fifo); } } @@ -1803,7 +1804,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, hctsiz |= num_packets << TSIZ_PKTCNT_SHIFT & TSIZ_PKTCNT_MASK; hctsiz |= chan->data_pid_start << TSIZ_SC_MC_PID_SHIFT & TSIZ_SC_MC_PID_MASK; - writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); if (dbg_hc(chan)) { dev_vdbg(hsotg->dev, "Wrote %08x to HCTSIZ(%d)\n", hctsiz, chan->hc_num); @@ -1831,7 +1832,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, } else { dma_addr = chan->xfer_dma; } - writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num)); + dwc2_writel((u32)dma_addr, hsotg->regs + HCDMA(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "Wrote %08lx to HCDMA(%d)\n", (unsigned long)dma_addr, chan->hc_num); @@ -1839,13 +1840,13 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, /* Start the split */ if (chan->do_split) { - u32 hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num)); + u32 hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num)); hcsplt |= HCSPLT_SPLTENA; - writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num)); + dwc2_writel(hcsplt, hsotg->regs + HCSPLT(chan->hc_num)); } - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); hcchar &= ~HCCHAR_MULTICNT_MASK; hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & HCCHAR_MULTICNT_MASK; @@ -1865,7 +1866,7 @@ void dwc2_hc_start_transfer(struct dwc2_hsotg *hsotg, (hcchar & HCCHAR_MULTICNT_MASK) >> HCCHAR_MULTICNT_SHIFT); - writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, chan->hc_num); @@ -1924,18 +1925,18 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, dev_vdbg(hsotg->dev, " NTD: %d\n", chan->ntd - 1); } - writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); hc_dma = (u32)chan->desc_list_addr & HCDMA_DMA_ADDR_MASK; /* Always start from first descriptor */ hc_dma &= ~HCDMA_CTD_MASK; - writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num)); + dwc2_writel(hc_dma, hsotg->regs + HCDMA(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "Wrote %08x to HCDMA(%d)\n", hc_dma, chan->hc_num); - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); hcchar &= ~HCCHAR_MULTICNT_MASK; hcchar |= chan->multi_count << HCCHAR_MULTICNT_SHIFT & HCCHAR_MULTICNT_MASK; @@ -1954,7 +1955,7 @@ void dwc2_hc_start_transfer_ddma(struct dwc2_hsotg *hsotg, (hcchar & HCCHAR_MULTICNT_MASK) >> HCCHAR_MULTICNT_SHIFT); - writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); if (dbg_hc(chan)) dev_vdbg(hsotg->dev, "Wrote %08x to HCCHAR(%d)\n", hcchar, chan->hc_num); @@ -2011,7 +2012,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, * transfer completes, the extra requests for the channel will * be flushed. */ - u32 hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + u32 hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); hcchar |= HCCHAR_CHENA; @@ -2019,7 +2020,7 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, if (dbg_hc(chan)) dev_vdbg(hsotg->dev, " IN xfer: hcchar = 0x%08x\n", hcchar); - writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); chan->requests++; return 1; } @@ -2029,8 +2030,8 @@ int dwc2_hc_continue_transfer(struct dwc2_hsotg *hsotg, if (chan->xfer_count < chan->xfer_len) { if (chan->ep_type == USB_ENDPOINT_XFER_INT || chan->ep_type == USB_ENDPOINT_XFER_ISOC) { - u32 hcchar = readl(hsotg->regs + - HCCHAR(chan->hc_num)); + u32 hcchar = dwc2_readl(hsotg->regs + + HCCHAR(chan->hc_num)); dwc2_hc_set_even_odd_frame(hsotg, chan, &hcchar); @@ -2066,12 +2067,12 @@ void dwc2_hc_do_ping(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan) hctsiz = TSIZ_DOPNG; hctsiz |= 1 << TSIZ_PKTCNT_SHIFT; - writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); + dwc2_writel(hctsiz, hsotg->regs + HCTSIZ(chan->hc_num)); - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); hcchar |= HCCHAR_CHENA; hcchar &= ~HCCHAR_CHDIS; - writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(chan->hc_num)); } /** @@ -2090,8 +2091,8 @@ u32 dwc2_calc_frame_interval(struct dwc2_hsotg *hsotg) u32 hprt0; int clock = 60; /* default value */ - usbcfg = readl(hsotg->regs + GUSBCFG); - hprt0 = readl(hsotg->regs + HPRT0); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); + hprt0 = dwc2_readl(hsotg->regs + HPRT0); if (!(usbcfg & GUSBCFG_PHYSEL) && (usbcfg & GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & GUSBCFG_PHYIF16)) @@ -2147,7 +2148,7 @@ void dwc2_read_packet(struct dwc2_hsotg *hsotg, u8 *dest, u16 bytes) dev_vdbg(hsotg->dev, "%s(%p,%p,%d)\n", __func__, hsotg, dest, bytes); for (i = 0; i < word_count; i++, data_buf++) - *data_buf = readl(fifo); + *data_buf = dwc2_readl(fifo); } /** @@ -2167,56 +2168,56 @@ void dwc2_dump_host_registers(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "Host Global Registers\n"); addr = hsotg->regs + HCFG; dev_dbg(hsotg->dev, "HCFG @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HFIR; dev_dbg(hsotg->dev, "HFIR @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HFNUM; dev_dbg(hsotg->dev, "HFNUM @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HPTXSTS; dev_dbg(hsotg->dev, "HPTXSTS @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HAINT; dev_dbg(hsotg->dev, "HAINT @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HAINTMSK; dev_dbg(hsotg->dev, "HAINTMSK @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); if (hsotg->core_params->dma_desc_enable > 0) { addr = hsotg->regs + HFLBADDR; dev_dbg(hsotg->dev, "HFLBADDR @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); } addr = hsotg->regs + HPRT0; dev_dbg(hsotg->dev, "HPRT0 @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); for (i = 0; i < hsotg->core_params->host_channels; i++) { dev_dbg(hsotg->dev, "Host Channel %d Specific Registers\n", i); addr = hsotg->regs + HCCHAR(i); dev_dbg(hsotg->dev, "HCCHAR @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HCSPLT(i); dev_dbg(hsotg->dev, "HCSPLT @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HCINT(i); dev_dbg(hsotg->dev, "HCINT @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HCINTMSK(i); dev_dbg(hsotg->dev, "HCINTMSK @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HCTSIZ(i); dev_dbg(hsotg->dev, "HCTSIZ @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HCDMA(i); dev_dbg(hsotg->dev, "HCDMA @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); if (hsotg->core_params->dma_desc_enable > 0) { addr = hsotg->regs + HCDMAB(i); dev_dbg(hsotg->dev, "HCDMAB @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); } } #endif @@ -2238,80 +2239,80 @@ void dwc2_dump_global_registers(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "Core Global Registers\n"); addr = hsotg->regs + GOTGCTL; dev_dbg(hsotg->dev, "GOTGCTL @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GOTGINT; dev_dbg(hsotg->dev, "GOTGINT @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GAHBCFG; dev_dbg(hsotg->dev, "GAHBCFG @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GUSBCFG; dev_dbg(hsotg->dev, "GUSBCFG @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GRSTCTL; dev_dbg(hsotg->dev, "GRSTCTL @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GINTSTS; dev_dbg(hsotg->dev, "GINTSTS @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GINTMSK; dev_dbg(hsotg->dev, "GINTMSK @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GRXSTSR; dev_dbg(hsotg->dev, "GRXSTSR @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GRXFSIZ; dev_dbg(hsotg->dev, "GRXFSIZ @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GNPTXFSIZ; dev_dbg(hsotg->dev, "GNPTXFSIZ @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GNPTXSTS; dev_dbg(hsotg->dev, "GNPTXSTS @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GI2CCTL; dev_dbg(hsotg->dev, "GI2CCTL @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GPVNDCTL; dev_dbg(hsotg->dev, "GPVNDCTL @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GGPIO; dev_dbg(hsotg->dev, "GGPIO @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GUID; dev_dbg(hsotg->dev, "GUID @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GSNPSID; dev_dbg(hsotg->dev, "GSNPSID @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GHWCFG1; dev_dbg(hsotg->dev, "GHWCFG1 @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GHWCFG2; dev_dbg(hsotg->dev, "GHWCFG2 @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GHWCFG3; dev_dbg(hsotg->dev, "GHWCFG3 @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GHWCFG4; dev_dbg(hsotg->dev, "GHWCFG4 @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GLPMCFG; dev_dbg(hsotg->dev, "GLPMCFG @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GPWRDN; dev_dbg(hsotg->dev, "GPWRDN @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + GDFIFOCFG; dev_dbg(hsotg->dev, "GDFIFOCFG @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + HPTXFSIZ; dev_dbg(hsotg->dev, "HPTXFSIZ @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); addr = hsotg->regs + PCGCTL; dev_dbg(hsotg->dev, "PCGCTL @0x%08lX : 0x%08X\n", - (unsigned long)addr, readl(addr)); + (unsigned long)addr, dwc2_readl(addr)); #endif } @@ -2330,15 +2331,15 @@ void dwc2_flush_tx_fifo(struct dwc2_hsotg *hsotg, const int num) greset = GRSTCTL_TXFFLSH; greset |= num << GRSTCTL_TXFNUM_SHIFT & GRSTCTL_TXFNUM_MASK; - writel(greset, hsotg->regs + GRSTCTL); + dwc2_writel(greset, hsotg->regs + GRSTCTL); do { - greset = readl(hsotg->regs + GRSTCTL); + greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 10000) { dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n", __func__, greset, - readl(hsotg->regs + GNPTXSTS)); + dwc2_readl(hsotg->regs + GNPTXSTS)); break; } udelay(1); @@ -2361,10 +2362,10 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "%s()\n", __func__); greset = GRSTCTL_RXFFLSH; - writel(greset, hsotg->regs + GRSTCTL); + dwc2_writel(greset, hsotg->regs + GRSTCTL); do { - greset = readl(hsotg->regs + GRSTCTL); + greset = dwc2_readl(hsotg->regs + GRSTCTL); if (++count > 10000) { dev_warn(hsotg->dev, "%s() HANG! GRSTCTL=%0x\n", __func__, greset); @@ -3062,7 +3063,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) * 0x45f42xxx or 0x45f43xxx, which corresponds to either "OT2" or "OT3", * as in "OTG version 2.xx" or "OTG version 3.xx". */ - hw->snpsid = readl(hsotg->regs + GSNPSID); + hw->snpsid = dwc2_readl(hsotg->regs + GSNPSID); if ((hw->snpsid & 0xfffff000) != 0x4f542000 && (hw->snpsid & 0xfffff000) != 0x4f543000) { dev_err(hsotg->dev, "Bad value for GSNPSID: 0x%08x\n", @@ -3074,11 +3075,11 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); - hwcfg1 = readl(hsotg->regs + GHWCFG1); - hwcfg2 = readl(hsotg->regs + GHWCFG2); - hwcfg3 = readl(hsotg->regs + GHWCFG3); - hwcfg4 = readl(hsotg->regs + GHWCFG4); - grxfsiz = readl(hsotg->regs + GRXFSIZ); + hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1); + hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2); + hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3); + hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4); + grxfsiz = dwc2_readl(hsotg->regs + GRXFSIZ); dev_dbg(hsotg->dev, "hwcfg1=%08x\n", hwcfg1); dev_dbg(hsotg->dev, "hwcfg2=%08x\n", hwcfg2); @@ -3087,18 +3088,18 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "grxfsiz=%08x\n", grxfsiz); /* Force host mode to get HPTXFSIZ / GNPTXFSIZ exact power on value */ - gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg |= GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); usleep_range(100000, 150000); - gnptxfsiz = readl(hsotg->regs + GNPTXFSIZ); - hptxfsiz = readl(hsotg->regs + HPTXFSIZ); + gnptxfsiz = dwc2_readl(hsotg->regs + GNPTXFSIZ); + hptxfsiz = dwc2_readl(hsotg->regs + HPTXFSIZ); dev_dbg(hsotg->dev, "gnptxfsiz=%08x\n", gnptxfsiz); dev_dbg(hsotg->dev, "hptxfsiz=%08x\n", hptxfsiz); - gusbcfg = readl(hsotg->regs + GUSBCFG); + gusbcfg = dwc2_readl(hsotg->regs + GUSBCFG); gusbcfg &= ~GUSBCFG_FORCEHOSTMODE; - writel(gusbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); usleep_range(100000, 150000); /* hwcfg2 */ @@ -3233,7 +3234,7 @@ u16 dwc2_get_otg_version(struct dwc2_hsotg *hsotg) bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg) { - if (readl(hsotg->regs + GSNPSID) == 0xffffffff) + if (dwc2_readl(hsotg->regs + GSNPSID) == 0xffffffff) return false; else return true; @@ -3247,10 +3248,10 @@ bool dwc2_is_controller_alive(struct dwc2_hsotg *hsotg) */ void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg) { - u32 ahbcfg = readl(hsotg->regs + GAHBCFG); + u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); ahbcfg |= GAHBCFG_GLBL_INTR_EN; - writel(ahbcfg, hsotg->regs + GAHBCFG); + dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); } /** @@ -3261,10 +3262,10 @@ void dwc2_enable_global_interrupts(struct dwc2_hsotg *hsotg) */ void dwc2_disable_global_interrupts(struct dwc2_hsotg *hsotg) { - u32 ahbcfg = readl(hsotg->regs + GAHBCFG); + u32 ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); ahbcfg &= ~GAHBCFG_GLBL_INTR_EN; - writel(ahbcfg, hsotg->regs + GAHBCFG); + dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); } MODULE_DESCRIPTION("DESIGNWARE HS OTG Core"); diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 9655b1ec4f34..1a7982dbdad5 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -44,16 +44,32 @@ #include #include "hw.h" -#ifdef DWC2_LOG_WRITES -static inline void do_write(u32 value, void *addr) +static inline u32 dwc2_readl(const void __iomem *addr) { - writel(value, addr); - pr_info("INFO:: wrote %08x to %p\n", value, addr); + u32 value = __raw_readl(addr); + + /* In order to preserve endianness __raw_* operation is used. Therefore + * a barrier is needed to ensure IO access is not re-ordered across + * reads or writes + */ + mb(); + return value; } -#undef writel -#define writel(v, a) do_write(v, a) +static inline void dwc2_writel(u32 value, void __iomem *addr) +{ + __raw_writel(value, addr); + + /* + * In order to preserve endianness __raw_* operation is used. Therefore + * a barrier is needed to ensure IO access is not re-ordered across + * reads or writes + */ + mb(); +#ifdef DWC2_LOG_WRITES + pr_info("INFO:: wrote %08x to %p\n", value, addr); #endif +} /* Maximum number of Endpoints/HostChannels */ #define MAX_EPS_CHANNELS 16 diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 344a859c2153..a6b16139850d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -80,15 +80,15 @@ static const char *dwc2_op_state_str(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_usb_port_intr(struct dwc2_hsotg *hsotg) { - u32 hprt0 = readl(hsotg->regs + HPRT0); + u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0); if (hprt0 & HPRT0_ENACHG) { hprt0 &= ~HPRT0_ENA; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); } /* Clear interrupt */ - writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_PRTINT, hsotg->regs + GINTSTS); } /** @@ -102,7 +102,7 @@ static void dwc2_handle_mode_mismatch_intr(struct dwc2_hsotg *hsotg) dwc2_is_host_mode(hsotg) ? "Host" : "Device"); /* Clear interrupt */ - writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_MODEMIS, hsotg->regs + GINTSTS); } /** @@ -117,8 +117,8 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) u32 gotgctl; u32 gintmsk; - gotgint = readl(hsotg->regs + GOTGINT); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgint = dwc2_readl(hsotg->regs + GOTGINT); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "++OTG Interrupt gotgint=%0x [%s]\n", gotgint, dwc2_op_state_str(hsotg)); @@ -126,7 +126,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " ++OTG Interrupt: Session End Detected++ (%s)\n", dwc2_op_state_str(hsotg)); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); if (dwc2_is_device_mode(hsotg)) dwc2_hsotg_disconnect(hsotg); @@ -152,15 +152,15 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state = DWC2_L0; } - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~GOTGCTL_DEVHNPEN; - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); } if (gotgint & GOTGINT_SES_REQ_SUC_STS_CHNG) { dev_dbg(hsotg->dev, " ++OTG Interrupt: Session Request Success Status Change++\n"); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); if (gotgctl & GOTGCTL_SESREQSCS) { if (hsotg->core_params->phy_type == DWC2_PHY_TYPE_PARAM_FS @@ -168,9 +168,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->srp_success = 1; } else { /* Clear Session Request */ - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~GOTGCTL_SESREQ; - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); } } } @@ -180,7 +180,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) * Print statements during the HNP interrupt handling * can cause it to fail */ - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); /* * WA for 3.00a- HW is not setting cur_mode, even sometimes * this does not help @@ -200,9 +200,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) * interrupt does not get handled and Linux * complains loudly. */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); /* * Call callback function with spin lock @@ -216,9 +216,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->op_state = OTG_STATE_B_HOST; } } else { - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl &= ~(GOTGCTL_HNPREQ | GOTGCTL_DEVHNPEN); - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "HNP Failed\n"); dev_err(hsotg->dev, "Device Not Connected/Responding\n"); @@ -244,9 +244,9 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) hsotg->op_state = OTG_STATE_A_PERIPHERAL; } else { /* Need to disable SOF interrupt immediately */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); spin_unlock(&hsotg->lock); dwc2_hcd_start(hsotg); spin_lock(&hsotg->lock); @@ -261,7 +261,7 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " ++OTG Interrupt: Debounce Done++\n"); /* Clear GOTGINT */ - writel(gotgint, hsotg->regs + GOTGINT); + dwc2_writel(gotgint, hsotg->regs + GOTGINT); } /** @@ -276,11 +276,11 @@ static void dwc2_handle_otg_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) { - u32 gintmsk = readl(hsotg->regs + GINTMSK); + u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK); /* Need to disable SOF interrupt immediately */ gintmsk &= ~GINTSTS_SOF; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); dev_dbg(hsotg->dev, " ++Connector ID Status Change Interrupt++ (%s)\n", dwc2_is_host_mode(hsotg) ? "Host" : "Device"); @@ -297,7 +297,7 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) } /* Clear interrupt */ - writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_CONIDSTSCHNG, hsotg->regs + GINTSTS); } /** @@ -316,7 +316,7 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "++Session Request Interrupt++\n"); /* Clear interrupt */ - writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); /* * Report disconnect if there is any previous session established @@ -339,13 +339,14 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "%s lxstate = %d\n", __func__, hsotg->lx_state); if (dwc2_is_device_mode(hsotg)) { - dev_dbg(hsotg->dev, "DSTS=0x%0x\n", readl(hsotg->regs + DSTS)); + dev_dbg(hsotg->dev, "DSTS=0x%0x\n", + dwc2_readl(hsotg->regs + DSTS)); if (hsotg->lx_state == DWC2_L2) { - u32 dctl = readl(hsotg->regs + DCTL); + u32 dctl = dwc2_readl(hsotg->regs + DCTL); /* Clear Remote Wakeup Signaling */ dctl &= ~DCTL_RMTWKUPSIG; - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); ret = dwc2_exit_hibernation(hsotg, true); if (ret && (ret != -ENOTSUPP)) dev_err(hsotg->dev, "exit hibernation failed\n"); @@ -356,11 +357,11 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) hsotg->lx_state = DWC2_L0; } else { if (hsotg->lx_state != DWC2_L1) { - u32 pcgcctl = readl(hsotg->regs + PCGCTL); + u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); /* Restart the Phy Clock */ pcgcctl &= ~PCGCTL_STOPPCLK; - writel(pcgcctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgcctl, hsotg->regs + PCGCTL); mod_timer(&hsotg->wkp_timer, jiffies + msecs_to_jiffies(71)); } else { @@ -370,7 +371,7 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) } /* Clear interrupt */ - writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); } /* @@ -389,7 +390,7 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) /* Change to L3 (OFF) state */ hsotg->lx_state = DWC2_L3; - writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); } /* @@ -412,7 +413,7 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg) * Check the Device status register to determine if the Suspend * state is active */ - dsts = readl(hsotg->regs + DSTS); + dsts = dwc2_readl(hsotg->regs + DSTS); dev_dbg(hsotg->dev, "DSTS=0x%0x\n", dsts); dev_dbg(hsotg->dev, "DSTS.Suspend Status=%d HWCFG4.Power Optimize=%d\n", @@ -465,7 +466,7 @@ skip_power_saving: clear_int: /* Clear interrupt */ - writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_USBSUSP, hsotg->regs + GINTSTS); } #define GINTMSK_COMMON (GINTSTS_WKUPINT | GINTSTS_SESSREQINT | \ @@ -483,9 +484,9 @@ static u32 dwc2_read_common_intr(struct dwc2_hsotg *hsotg) u32 gahbcfg; u32 gintmsk_common = GINTMSK_COMMON; - gintsts = readl(hsotg->regs + GINTSTS); - gintmsk = readl(hsotg->regs + GINTMSK); - gahbcfg = readl(hsotg->regs + GAHBCFG); + gintsts = dwc2_readl(hsotg->regs + GINTSTS); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); + gahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); /* If any common interrupts set */ if (gintsts & gintmsk_common) diff --git a/drivers/usb/dwc2/debugfs.c b/drivers/usb/dwc2/debugfs.c index cee3d771b75e..55d91f24f94a 100644 --- a/drivers/usb/dwc2/debugfs.c +++ b/drivers/usb/dwc2/debugfs.c @@ -76,7 +76,7 @@ static int testmode_show(struct seq_file *s, void *unused) int dctl; spin_lock_irqsave(&hsotg->lock, flags); - dctl = readl(hsotg->regs + DCTL); + dctl = dwc2_readl(hsotg->regs + DCTL); dctl &= DCTL_TSTCTL_MASK; dctl >>= DCTL_TSTCTL_SHIFT; spin_unlock_irqrestore(&hsotg->lock, flags); @@ -137,38 +137,38 @@ static int state_show(struct seq_file *seq, void *v) int idx; seq_printf(seq, "DCFG=0x%08x, DCTL=0x%08x, DSTS=0x%08x\n", - readl(regs + DCFG), - readl(regs + DCTL), - readl(regs + DSTS)); + dwc2_readl(regs + DCFG), + dwc2_readl(regs + DCTL), + dwc2_readl(regs + DSTS)); seq_printf(seq, "DIEPMSK=0x%08x, DOEPMASK=0x%08x\n", - readl(regs + DIEPMSK), readl(regs + DOEPMSK)); + dwc2_readl(regs + DIEPMSK), dwc2_readl(regs + DOEPMSK)); seq_printf(seq, "GINTMSK=0x%08x, GINTSTS=0x%08x\n", - readl(regs + GINTMSK), - readl(regs + GINTSTS)); + dwc2_readl(regs + GINTMSK), + dwc2_readl(regs + GINTSTS)); seq_printf(seq, "DAINTMSK=0x%08x, DAINT=0x%08x\n", - readl(regs + DAINTMSK), - readl(regs + DAINT)); + dwc2_readl(regs + DAINTMSK), + dwc2_readl(regs + DAINT)); seq_printf(seq, "GNPTXSTS=0x%08x, GRXSTSR=%08x\n", - readl(regs + GNPTXSTS), - readl(regs + GRXSTSR)); + dwc2_readl(regs + GNPTXSTS), + dwc2_readl(regs + GRXSTSR)); seq_puts(seq, "\nEndpoint status:\n"); for (idx = 0; idx < hsotg->num_of_eps; idx++) { u32 in, out; - in = readl(regs + DIEPCTL(idx)); - out = readl(regs + DOEPCTL(idx)); + in = dwc2_readl(regs + DIEPCTL(idx)); + out = dwc2_readl(regs + DOEPCTL(idx)); seq_printf(seq, "ep%d: DIEPCTL=0x%08x, DOEPCTL=0x%08x", idx, in, out); - in = readl(regs + DIEPTSIZ(idx)); - out = readl(regs + DOEPTSIZ(idx)); + in = dwc2_readl(regs + DIEPTSIZ(idx)); + out = dwc2_readl(regs + DOEPTSIZ(idx)); seq_printf(seq, ", DIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x", in, out); @@ -208,9 +208,9 @@ static int fifo_show(struct seq_file *seq, void *v) int idx; seq_puts(seq, "Non-periodic FIFOs:\n"); - seq_printf(seq, "RXFIFO: Size %d\n", readl(regs + GRXFSIZ)); + seq_printf(seq, "RXFIFO: Size %d\n", dwc2_readl(regs + GRXFSIZ)); - val = readl(regs + GNPTXFSIZ); + val = dwc2_readl(regs + GNPTXFSIZ); seq_printf(seq, "NPTXFIFO: Size %d, Start 0x%08x\n", val >> FIFOSIZE_DEPTH_SHIFT, val & FIFOSIZE_DEPTH_MASK); @@ -218,7 +218,7 @@ static int fifo_show(struct seq_file *seq, void *v) seq_puts(seq, "\nPeriodic TXFIFOs:\n"); for (idx = 1; idx < hsotg->num_of_eps; idx++) { - val = readl(regs + DPTXFSIZN(idx)); + val = dwc2_readl(regs + DPTXFSIZN(idx)); seq_printf(seq, "\tDPTXFIFO%2d: Size %d, Start 0x%08x\n", idx, val >> FIFOSIZE_DEPTH_SHIFT, @@ -270,20 +270,20 @@ static int ep_show(struct seq_file *seq, void *v) /* first show the register state */ seq_printf(seq, "\tDIEPCTL=0x%08x, DOEPCTL=0x%08x\n", - readl(regs + DIEPCTL(index)), - readl(regs + DOEPCTL(index))); + dwc2_readl(regs + DIEPCTL(index)), + dwc2_readl(regs + DOEPCTL(index))); seq_printf(seq, "\tDIEPDMA=0x%08x, DOEPDMA=0x%08x\n", - readl(regs + DIEPDMA(index)), - readl(regs + DOEPDMA(index))); + dwc2_readl(regs + DIEPDMA(index)), + dwc2_readl(regs + DOEPDMA(index))); seq_printf(seq, "\tDIEPINT=0x%08x, DOEPINT=0x%08x\n", - readl(regs + DIEPINT(index)), - readl(regs + DOEPINT(index))); + dwc2_readl(regs + DIEPINT(index)), + dwc2_readl(regs + DOEPINT(index))); seq_printf(seq, "\tDIEPTSIZ=0x%08x, DOEPTSIZ=0x%08x\n", - readl(regs + DIEPTSIZ(index)), - readl(regs + DOEPTSIZ(index))); + dwc2_readl(regs + DIEPTSIZ(index)), + dwc2_readl(regs + DOEPTSIZ(index))); seq_puts(seq, "\n"); seq_printf(seq, "mps %d\n", ep->ep.maxpacket); diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 2ed9ad84d979..ddd14a725760 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -56,12 +56,12 @@ static inline struct dwc2_hsotg *to_hsotg(struct usb_gadget *gadget) static inline void __orr32(void __iomem *ptr, u32 val) { - writel(readl(ptr) | val, ptr); + dwc2_writel(dwc2_readl(ptr) | val, ptr); } static inline void __bic32(void __iomem *ptr, u32 val) { - writel(readl(ptr) & ~val, ptr); + dwc2_writel(dwc2_readl(ptr) & ~val, ptr); } static inline struct dwc2_hsotg_ep *index_to_ep(struct dwc2_hsotg *hsotg, @@ -107,14 +107,14 @@ static inline bool using_dma(struct dwc2_hsotg *hsotg) */ static void dwc2_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) { - u32 gsintmsk = readl(hsotg->regs + GINTMSK); + u32 gsintmsk = dwc2_readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; new_gsintmsk = gsintmsk | ints; if (new_gsintmsk != gsintmsk) { dev_dbg(hsotg->dev, "gsintmsk now 0x%08x\n", new_gsintmsk); - writel(new_gsintmsk, hsotg->regs + GINTMSK); + dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK); } } @@ -125,13 +125,13 @@ static void dwc2_hsotg_en_gsint(struct dwc2_hsotg *hsotg, u32 ints) */ static void dwc2_hsotg_disable_gsint(struct dwc2_hsotg *hsotg, u32 ints) { - u32 gsintmsk = readl(hsotg->regs + GINTMSK); + u32 gsintmsk = dwc2_readl(hsotg->regs + GINTMSK); u32 new_gsintmsk; new_gsintmsk = gsintmsk & ~ints; if (new_gsintmsk != gsintmsk) - writel(new_gsintmsk, hsotg->regs + GINTMSK); + dwc2_writel(new_gsintmsk, hsotg->regs + GINTMSK); } /** @@ -156,12 +156,12 @@ static void dwc2_hsotg_ctrl_epint(struct dwc2_hsotg *hsotg, bit <<= 16; local_irq_save(flags); - daint = readl(hsotg->regs + DAINTMSK); + daint = dwc2_readl(hsotg->regs + DAINTMSK); if (en) daint |= bit; else daint &= ~bit; - writel(daint, hsotg->regs + DAINTMSK); + dwc2_writel(daint, hsotg->regs + DAINTMSK); local_irq_restore(flags); } @@ -181,8 +181,8 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) hsotg->fifo_map = 0; /* set RX/NPTX FIFO sizes */ - writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ); - writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) | + dwc2_writel(hsotg->g_rx_fifo_sz, hsotg->regs + GRXFSIZ); + dwc2_writel((hsotg->g_rx_fifo_sz << FIFOSIZE_STARTADDR_SHIFT) | (hsotg->g_np_g_tx_fifo_sz << FIFOSIZE_DEPTH_SHIFT), hsotg->regs + GNPTXFSIZ); @@ -210,7 +210,7 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) "insufficient fifo memory"); addr += hsotg->g_tx_fifo_sz[ep]; - writel(val, hsotg->regs + DPTXFSIZN(ep)); + dwc2_writel(val, hsotg->regs + DPTXFSIZN(ep)); } /* @@ -218,13 +218,13 @@ static void dwc2_hsotg_init_fifo(struct dwc2_hsotg *hsotg) * all fifos are flushed before continuing */ - writel(GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH | + dwc2_writel(GRSTCTL_TXFNUM(0x10) | GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH, hsotg->regs + GRSTCTL); /* wait until the fifos are both flushed */ timeout = 100; while (1) { - val = readl(hsotg->regs + GRSTCTL); + val = dwc2_readl(hsotg->regs + GRSTCTL); if ((val & (GRSTCTL_TXFFLSH | GRSTCTL_RXFFLSH)) == 0) break; @@ -317,7 +317,7 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, struct dwc2_hsotg_req *hs_req) { bool periodic = is_ep_periodic(hs_ep); - u32 gnptxsts = readl(hsotg->regs + GNPTXSTS); + u32 gnptxsts = dwc2_readl(hsotg->regs + GNPTXSTS); int buf_pos = hs_req->req.actual; int to_write = hs_ep->size_loaded; void *data; @@ -332,7 +332,7 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, return 0; if (periodic && !hsotg->dedicated_fifos) { - u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index)); + u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index)); int size_left; int size_done; @@ -373,7 +373,7 @@ static int dwc2_hsotg_write_fifo(struct dwc2_hsotg *hsotg, return -ENOSPC; } } else if (hsotg->dedicated_fifos && hs_ep->index != 0) { - can_write = readl(hsotg->regs + DTXFSTS(hs_ep->index)); + can_write = dwc2_readl(hsotg->regs + DTXFSTS(hs_ep->index)); can_write &= 0xffff; can_write *= 4; @@ -550,11 +550,11 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, epsize_reg = dir_in ? DIEPTSIZ(index) : DOEPTSIZ(index); dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x, ep %d, dir %s\n", - __func__, readl(hsotg->regs + epctrl_reg), index, + __func__, dwc2_readl(hsotg->regs + epctrl_reg), index, hs_ep->dir_in ? "in" : "out"); /* If endpoint is stalled, we will restart request later */ - ctrl = readl(hsotg->regs + epctrl_reg); + ctrl = dwc2_readl(hsotg->regs + epctrl_reg); if (ctrl & DXEPCTL_STALL) { dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index); @@ -618,7 +618,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, hs_ep->req = hs_req; /* write size / packets */ - writel(epsize, hsotg->regs + epsize_reg); + dwc2_writel(epsize, hsotg->regs + epsize_reg); if (using_dma(hsotg) && !continuing) { unsigned int dma_reg; @@ -629,7 +629,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, */ dma_reg = dir_in ? DIEPDMA(index) : DOEPDMA(index); - writel(ureq->dma, hsotg->regs + dma_reg); + dwc2_writel(ureq->dma, hsotg->regs + dma_reg); dev_dbg(hsotg->dev, "%s: %pad => 0x%08x\n", __func__, &ureq->dma, dma_reg); @@ -645,7 +645,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); - writel(ctrl, hsotg->regs + epctrl_reg); + dwc2_writel(ctrl, hsotg->regs + epctrl_reg); /* * set these, it seems that DMA support increments past the end @@ -667,7 +667,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, * to debugging to see what is going on. */ if (dir_in) - writel(DIEPMSK_INTKNTXFEMPMSK, + dwc2_writel(DIEPMSK_INTKNTXFEMPMSK, hsotg->regs + DIEPINT(index)); /* @@ -676,13 +676,13 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, */ /* check ep is enabled */ - if (!(readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA)) + if (!(dwc2_readl(hsotg->regs + epctrl_reg) & DXEPCTL_EPENA)) dev_dbg(hsotg->dev, "ep%d: failed to become enabled (DXEPCTL=0x%08x)?\n", - index, readl(hsotg->regs + epctrl_reg)); + index, dwc2_readl(hsotg->regs + epctrl_reg)); dev_dbg(hsotg->dev, "%s: DXEPCTL=0x%08x\n", - __func__, readl(hsotg->regs + epctrl_reg)); + __func__, dwc2_readl(hsotg->regs + epctrl_reg)); /* enable ep interrupts */ dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 1); @@ -901,7 +901,7 @@ static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, */ int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) { - int dctl = readl(hsotg->regs + DCTL); + int dctl = dwc2_readl(hsotg->regs + DCTL); dctl &= ~DCTL_TSTCTL_MASK; switch (testmode) { @@ -915,7 +915,7 @@ int dwc2_hsotg_set_test_mode(struct dwc2_hsotg *hsotg, int testmode) default: return -EINVAL; } - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); return 0; } @@ -1174,14 +1174,14 @@ static void dwc2_hsotg_stall_ep0(struct dwc2_hsotg *hsotg) * taken effect, so no need to clear later. */ - ctrl = readl(hsotg->regs + reg); + ctrl = dwc2_readl(hsotg->regs + reg); ctrl |= DXEPCTL_STALL; ctrl |= DXEPCTL_CNAK; - writel(ctrl, hsotg->regs + reg); + dwc2_writel(ctrl, hsotg->regs + reg); dev_dbg(hsotg->dev, "written DXEPCTL=0x%08x to %08x (DXEPCTL=0x%08x)\n", - ctrl, reg, readl(hsotg->regs + reg)); + ctrl, reg, dwc2_readl(hsotg->regs + reg)); /* * complete won't be called, so we enqueue @@ -1225,11 +1225,11 @@ static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg, switch (ctrl->bRequest) { case USB_REQ_SET_ADDRESS: hsotg->connected = 1; - dcfg = readl(hsotg->regs + DCFG); + dcfg = dwc2_readl(hsotg->regs + DCFG); dcfg &= ~DCFG_DEVADDR_MASK; dcfg |= (le16_to_cpu(ctrl->wValue) << DCFG_DEVADDR_SHIFT) & DCFG_DEVADDR_MASK; - writel(dcfg, hsotg->regs + DCFG); + dwc2_writel(dcfg, hsotg->regs + DCFG); dev_info(hsotg->dev, "new address %d\n", ctrl->wValue); @@ -1347,15 +1347,15 @@ static void dwc2_hsotg_program_zlp(struct dwc2_hsotg *hsotg, dev_dbg(hsotg->dev, "Receiving zero-length packet on ep%d\n", index); - writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | - DXEPTSIZ_XFERSIZE(0), hsotg->regs + - epsiz_reg); + dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | + DXEPTSIZ_XFERSIZE(0), hsotg->regs + + epsiz_reg); - ctrl = readl(hsotg->regs + epctl_reg); + ctrl = dwc2_readl(hsotg->regs + epctl_reg); ctrl |= DXEPCTL_CNAK; /* clear NAK set by core */ ctrl |= DXEPCTL_EPENA; /* ensure ep enabled */ ctrl |= DXEPCTL_USBACTEP; - writel(ctrl, hsotg->regs + epctl_reg); + dwc2_writel(ctrl, hsotg->regs + epctl_reg); } /** @@ -1449,7 +1449,7 @@ static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) if (!hs_req) { - u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); + u32 epctl = dwc2_readl(hsotg->regs + DOEPCTL(ep_idx)); int ptr; dev_dbg(hsotg->dev, @@ -1458,7 +1458,7 @@ static void dwc2_hsotg_rx_data(struct dwc2_hsotg *hsotg, int ep_idx, int size) /* dump the data from the FIFO, we've nothing we can do */ for (ptr = 0; ptr < size; ptr += 4) - (void)readl(fifo); + (void)dwc2_readl(fifo); return; } @@ -1523,7 +1523,7 @@ static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) */ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) { - u32 epsize = readl(hsotg->regs + DOEPTSIZ(epnum)); + u32 epsize = dwc2_readl(hsotg->regs + DOEPTSIZ(epnum)); struct dwc2_hsotg_ep *hs_ep = hsotg->eps_out[epnum]; struct dwc2_hsotg_req *hs_req = hs_ep->req; struct usb_request *req = &hs_req->req; @@ -1595,7 +1595,7 @@ static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) { u32 dsts; - dsts = readl(hsotg->regs + DSTS); + dsts = dwc2_readl(hsotg->regs + DSTS); dsts &= DSTS_SOFFN_MASK; dsts >>= DSTS_SOFFN_SHIFT; @@ -1620,7 +1620,7 @@ static u32 dwc2_hsotg_read_frameno(struct dwc2_hsotg *hsotg) */ static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg) { - u32 grxstsr = readl(hsotg->regs + GRXSTSP); + u32 grxstsr = dwc2_readl(hsotg->regs + GRXSTSP); u32 epnum, status, size; WARN_ON(using_dma(hsotg)); @@ -1651,7 +1651,7 @@ static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "SetupDone (Frame=0x%08x, DOPEPCTL=0x%08x)\n", dwc2_hsotg_read_frameno(hsotg), - readl(hsotg->regs + DOEPCTL(0))); + dwc2_readl(hsotg->regs + DOEPCTL(0))); /* * Call dwc2_hsotg_handle_outdone here if it was not called from * GRXSTS_PKTSTS_OUTDONE. That is, if the core didn't @@ -1669,7 +1669,7 @@ static void dwc2_hsotg_handle_rx(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "SetupRX (Frame=0x%08x, DOPEPCTL=0x%08x)\n", dwc2_hsotg_read_frameno(hsotg), - readl(hsotg->regs + DOEPCTL(0))); + dwc2_readl(hsotg->regs + DOEPCTL(0))); WARN_ON(hsotg->ep0_state != DWC2_EP0_SETUP); @@ -1748,15 +1748,15 @@ static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg, } if (dir_in) { - reg = readl(regs + DIEPCTL(ep)); + reg = dwc2_readl(regs + DIEPCTL(ep)); reg &= ~DXEPCTL_MPS_MASK; reg |= mpsval; - writel(reg, regs + DIEPCTL(ep)); + dwc2_writel(reg, regs + DIEPCTL(ep)); } else { - reg = readl(regs + DOEPCTL(ep)); + reg = dwc2_readl(regs + DOEPCTL(ep)); reg &= ~DXEPCTL_MPS_MASK; reg |= mpsval; - writel(reg, regs + DOEPCTL(ep)); + dwc2_writel(reg, regs + DOEPCTL(ep)); } return; @@ -1775,14 +1775,14 @@ static void dwc2_hsotg_txfifo_flush(struct dwc2_hsotg *hsotg, unsigned int idx) int timeout; int val; - writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH, - hsotg->regs + GRSTCTL); + dwc2_writel(GRSTCTL_TXFNUM(idx) | GRSTCTL_TXFFLSH, + hsotg->regs + GRSTCTL); /* wait until the fifo is flushed */ timeout = 100; while (1) { - val = readl(hsotg->regs + GRSTCTL); + val = dwc2_readl(hsotg->regs + GRSTCTL); if ((val & (GRSTCTL_TXFFLSH)) == 0) break; @@ -1843,7 +1843,7 @@ static void dwc2_hsotg_complete_in(struct dwc2_hsotg *hsotg, struct dwc2_hsotg_ep *hs_ep) { struct dwc2_hsotg_req *hs_req = hs_ep->req; - u32 epsize = readl(hsotg->regs + DIEPTSIZ(hs_ep->index)); + u32 epsize = dwc2_readl(hsotg->regs + DIEPTSIZ(hs_ep->index)); int size_left, size_done; if (!hs_req) { @@ -1934,11 +1934,11 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, u32 ints; u32 ctrl; - ints = readl(hsotg->regs + epint_reg); - ctrl = readl(hsotg->regs + epctl_reg); + ints = dwc2_readl(hsotg->regs + epint_reg); + ctrl = dwc2_readl(hsotg->regs + epctl_reg); /* Clear endpoint interrupts */ - writel(ints, hsotg->regs + epint_reg); + dwc2_writel(ints, hsotg->regs + epint_reg); if (!hs_ep) { dev_err(hsotg->dev, "%s:Interrupt for unconfigured ep%d(%s)\n", @@ -1959,13 +1959,13 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, ctrl |= DXEPCTL_SETEVENFR; else ctrl |= DXEPCTL_SETODDFR; - writel(ctrl, hsotg->regs + epctl_reg); + dwc2_writel(ctrl, hsotg->regs + epctl_reg); } dev_dbg(hsotg->dev, "%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n", - __func__, readl(hsotg->regs + epctl_reg), - readl(hsotg->regs + epsiz_reg)); + __func__, dwc2_readl(hsotg->regs + epctl_reg), + dwc2_readl(hsotg->regs + epsiz_reg)); /* * we get OutDone from the FIFO, so we only need to look @@ -1990,16 +1990,16 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, dev_dbg(hsotg->dev, "%s: EPDisbld\n", __func__); if (dir_in) { - int epctl = readl(hsotg->regs + epctl_reg); + int epctl = dwc2_readl(hsotg->regs + epctl_reg); dwc2_hsotg_txfifo_flush(hsotg, hs_ep->fifo_index); if ((epctl & DXEPCTL_STALL) && (epctl & DXEPCTL_EPTYPE_BULK)) { - int dctl = readl(hsotg->regs + DCTL); + int dctl = dwc2_readl(hsotg->regs + DCTL); dctl |= DCTL_CGNPINNAK; - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); } } } @@ -2061,7 +2061,7 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, */ static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) { - u32 dsts = readl(hsotg->regs + DSTS); + u32 dsts = dwc2_readl(hsotg->regs + DSTS); int ep0_mps = 0, ep_mps = 8; /* @@ -2128,8 +2128,8 @@ static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg) dwc2_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", - readl(hsotg->regs + DIEPCTL0), - readl(hsotg->regs + DOEPCTL0)); + dwc2_readl(hsotg->regs + DIEPCTL0), + dwc2_readl(hsotg->regs + DOEPCTL0)); } /** @@ -2156,7 +2156,7 @@ static void kill_all_requests(struct dwc2_hsotg *hsotg, if (!hsotg->dedicated_fifos) return; - size = (readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; + size = (dwc2_readl(hsotg->regs + DTXFSTS(ep->index)) & 0xffff) * 4; if (size < ep->fifo_size) dwc2_hsotg_txfifo_flush(hsotg, ep->fifo_index); } @@ -2240,11 +2240,11 @@ static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, "resetting core\n"); /* issue soft reset */ - writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL); + dwc2_writel(GRSTCTL_CSFTRST, hsotg->regs + GRSTCTL); timeout = 10000; do { - grstctl = readl(hsotg->regs + GRSTCTL); + grstctl = dwc2_readl(hsotg->regs + GRSTCTL); } while ((grstctl & GRSTCTL_CSFTRST) && timeout-- > 0); if (grstctl & GRSTCTL_CSFTRST) { @@ -2255,7 +2255,7 @@ static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg) timeout = 10000; while (1) { - u32 grstctl = readl(hsotg->regs + GRSTCTL); + u32 grstctl = dwc2_readl(hsotg->regs + GRSTCTL); if (timeout-- < 0) { dev_info(hsotg->dev, @@ -2295,7 +2295,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, /* set the PLL on, remove the HNP/SRP and set the PHY */ val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | + dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); dwc2_hsotg_init_fifo(hsotg); @@ -2303,15 +2303,15 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, if (!is_usb_reset) __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); - writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS, hsotg->regs + DCFG); + dwc2_writel(DCFG_EPMISCNT(1) | DCFG_DEVSPD_HS, hsotg->regs + DCFG); /* Clear any pending OTG interrupts */ - writel(0xffffffff, hsotg->regs + GOTGINT); + dwc2_writel(0xffffffff, hsotg->regs + GOTGINT); /* Clear any pending interrupts */ - writel(0xffffffff, hsotg->regs + GINTSTS); + dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); - writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | + dwc2_writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF | GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST | GINTSTS_RESETDET | GINTSTS_ENUMDONE | @@ -2320,14 +2320,14 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, hsotg->regs + GINTMSK); if (using_dma(hsotg)) - writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | - (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT), - hsotg->regs + GAHBCFG); + dwc2_writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | + (GAHBCFG_HBSTLEN_INCR4 << GAHBCFG_HBSTLEN_SHIFT), + hsotg->regs + GAHBCFG); else - writel(((hsotg->dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | - GAHBCFG_P_TXF_EMP_LVL) : 0) | - GAHBCFG_GLBL_INTR_EN, - hsotg->regs + GAHBCFG); + dwc2_writel(((hsotg->dedicated_fifos) ? + (GAHBCFG_NP_TXF_EMP_LVL | + GAHBCFG_P_TXF_EMP_LVL) : 0) | + GAHBCFG_GLBL_INTR_EN, hsotg->regs + GAHBCFG); /* * If INTknTXFEmpMsk is enabled, it's important to disable ep interrupts @@ -2335,7 +2335,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, * interrupts. */ - writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ? + dwc2_writel(((hsotg->dedicated_fifos && !using_dma(hsotg)) ? DIEPMSK_TXFIFOEMPTY | DIEPMSK_INTKNTXFEMPMSK : 0) | DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK | DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | @@ -2346,17 +2346,17 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, * don't need XferCompl, we get that from RXFIFO in slave mode. In * DMA mode we may need this. */ - writel((using_dma(hsotg) ? (DIEPMSK_XFERCOMPLMSK | + dwc2_writel((using_dma(hsotg) ? (DIEPMSK_XFERCOMPLMSK | DIEPMSK_TIMEOUTMSK) : 0) | DOEPMSK_EPDISBLDMSK | DOEPMSK_AHBERRMSK | DOEPMSK_SETUPMSK, hsotg->regs + DOEPMSK); - writel(0, hsotg->regs + DAINTMSK); + dwc2_writel(0, hsotg->regs + DAINTMSK); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", - readl(hsotg->regs + DIEPCTL0), - readl(hsotg->regs + DOEPCTL0)); + dwc2_readl(hsotg->regs + DIEPCTL0), + dwc2_readl(hsotg->regs + DOEPCTL0)); /* enable in and out endpoint interrupts */ dwc2_hsotg_en_gsint(hsotg, GINTSTS_OEPINT | GINTSTS_IEPINT); @@ -2379,7 +2379,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, __bic32(hsotg->regs + DCTL, DCTL_PWRONPRGDONE); } - dev_dbg(hsotg->dev, "DCTL=0x%08x\n", readl(hsotg->regs + DCTL)); + dev_dbg(hsotg->dev, "DCTL=0x%08x\n", dwc2_readl(hsotg->regs + DCTL)); /* * DxEPCTL_USBActEp says RO in manual, but seems to be set by @@ -2387,23 +2387,23 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, */ /* set to read 1 8byte packet */ - writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | + dwc2_writel(DXEPTSIZ_MC(1) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(8), hsotg->regs + DOEPTSIZ0); - writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | + dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | DXEPCTL_CNAK | DXEPCTL_EPENA | DXEPCTL_USBACTEP, hsotg->regs + DOEPCTL0); /* enable, but don't activate EP0in */ - writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | + dwc2_writel(dwc2_hsotg_ep0_mps(hsotg->eps_out[0]->ep.maxpacket) | DXEPCTL_USBACTEP, hsotg->regs + DIEPCTL0); dwc2_hsotg_enqueue_setup(hsotg); dev_dbg(hsotg->dev, "EP0: DIEPCTL0=0x%08x, DOEPCTL0=0x%08x\n", - readl(hsotg->regs + DIEPCTL0), - readl(hsotg->regs + DOEPCTL0)); + dwc2_readl(hsotg->regs + DIEPCTL0), + dwc2_readl(hsotg->regs + DOEPCTL0)); /* clear global NAKs */ val = DCTL_CGOUTNAK | DCTL_CGNPINNAK; @@ -2443,8 +2443,8 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw) spin_lock(&hsotg->lock); irq_retry: - gintsts = readl(hsotg->regs + GINTSTS); - gintmsk = readl(hsotg->regs + GINTMSK); + gintsts = dwc2_readl(hsotg->regs + GINTSTS); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); dev_dbg(hsotg->dev, "%s: %08x %08x (%08x) retry %d\n", __func__, gintsts, gintsts & gintmsk, gintmsk, retry_count); @@ -2452,14 +2452,14 @@ irq_retry: gintsts &= gintmsk; if (gintsts & GINTSTS_ENUMDONE) { - writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); dwc2_hsotg_irq_enumdone(hsotg); } if (gintsts & (GINTSTS_OEPINT | GINTSTS_IEPINT)) { - u32 daint = readl(hsotg->regs + DAINT); - u32 daintmsk = readl(hsotg->regs + DAINTMSK); + u32 daint = dwc2_readl(hsotg->regs + DAINT); + u32 daintmsk = dwc2_readl(hsotg->regs + DAINTMSK); u32 daint_out, daint_in; int ep; @@ -2485,7 +2485,7 @@ irq_retry: if (gintsts & GINTSTS_RESETDET) { dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__); - writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS); /* This event must be used only if controller is suspended */ if (hsotg->lx_state == DWC2_L2) { @@ -2496,13 +2496,13 @@ irq_retry: if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { - u32 usb_status = readl(hsotg->regs + GOTGCTL); + u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "%s: USBRst\n", __func__); dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", - readl(hsotg->regs + GNPTXSTS)); + dwc2_readl(hsotg->regs + GNPTXSTS)); - writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); /* Report disconnection if it is not already done. */ dwc2_hsotg_disconnect(hsotg); @@ -2556,7 +2556,7 @@ irq_retry: if (gintsts & GINTSTS_ERLYSUSP) { dev_dbg(hsotg->dev, "GINTSTS_ErlySusp\n"); - writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_ERLYSUSP, hsotg->regs + GINTSTS); } /* @@ -2568,7 +2568,7 @@ irq_retry: if (gintsts & GINTSTS_GOUTNAKEFF) { dev_info(hsotg->dev, "GOUTNakEff triggered\n"); - writel(DCTL_CGOUTNAK, hsotg->regs + DCTL); + dwc2_writel(DCTL_CGOUTNAK, hsotg->regs + DCTL); dwc2_hsotg_dump(hsotg); } @@ -2576,7 +2576,7 @@ irq_retry: if (gintsts & GINTSTS_GINNAKEFF) { dev_info(hsotg->dev, "GINNakEff triggered\n"); - writel(DCTL_CGNPINNAK, hsotg->regs + DCTL); + dwc2_writel(DCTL_CGNPINNAK, hsotg->regs + DCTL); dwc2_hsotg_dump(hsotg); } @@ -2634,7 +2634,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, /* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */ epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); - epctrl = readl(hsotg->regs + epctrl_reg); + epctrl = dwc2_readl(hsotg->regs + epctrl_reg); dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", __func__, epctrl, epctrl_reg); @@ -2718,7 +2718,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, for (i = 1; i < hsotg->num_of_eps; ++i) { if (hsotg->fifo_map & (1<regs + DPTXFSIZN(i)); + val = dwc2_readl(hsotg->regs + DPTXFSIZN(i)); val = (val >> FIFOSIZE_DEPTH_SHIFT)*4; if (val < size) continue; @@ -2747,9 +2747,9 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, dev_dbg(hsotg->dev, "%s: write DxEPCTL=0x%08x\n", __func__, epctrl); - writel(epctrl, hsotg->regs + epctrl_reg); + dwc2_writel(epctrl, hsotg->regs + epctrl_reg); dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x\n", - __func__, readl(hsotg->regs + epctrl_reg)); + __func__, dwc2_readl(hsotg->regs + epctrl_reg)); /* enable the endpoint interrupt */ dwc2_hsotg_ctrl_epint(hsotg, index, dir_in, 1); @@ -2788,13 +2788,13 @@ static int dwc2_hsotg_ep_disable(struct usb_ep *ep) hs_ep->fifo_index = 0; hs_ep->fifo_size = 0; - ctrl = readl(hsotg->regs + epctrl_reg); + ctrl = dwc2_readl(hsotg->regs + epctrl_reg); ctrl &= ~DXEPCTL_EPENA; ctrl &= ~DXEPCTL_USBACTEP; ctrl |= DXEPCTL_SNAK; dev_dbg(hsotg->dev, "%s: DxEPCTL=0x%08x\n", __func__, ctrl); - writel(ctrl, hsotg->regs + epctrl_reg); + dwc2_writel(ctrl, hsotg->regs + epctrl_reg); /* disable endpoint interrupts */ dwc2_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); @@ -2877,7 +2877,7 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value) if (hs_ep->dir_in) { epreg = DIEPCTL(index); - epctl = readl(hs->regs + epreg); + epctl = dwc2_readl(hs->regs + epreg); if (value) { epctl |= DXEPCTL_STALL | DXEPCTL_SNAK; @@ -2890,11 +2890,11 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value) xfertype == DXEPCTL_EPTYPE_INTERRUPT) epctl |= DXEPCTL_SETD0PID; } - writel(epctl, hs->regs + epreg); + dwc2_writel(epctl, hs->regs + epreg); } else { epreg = DOEPCTL(index); - epctl = readl(hs->regs + epreg); + epctl = dwc2_readl(hs->regs + epreg); if (value) epctl |= DXEPCTL_STALL; @@ -2905,7 +2905,7 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value) xfertype == DXEPCTL_EPTYPE_INTERRUPT) epctl |= DXEPCTL_SETD0PID; } - writel(epctl, hs->regs + epreg); + dwc2_writel(epctl, hs->regs + epreg); } hs_ep->halted = value; @@ -2996,15 +2996,15 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) u32 trdtim; /* unmask subset of endpoint interrupts */ - writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | - DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK, - hsotg->regs + DIEPMSK); + dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | + DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK, + hsotg->regs + DIEPMSK); - writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK | - DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK, - hsotg->regs + DOEPMSK); + dwc2_writel(DOEPMSK_SETUPMSK | DOEPMSK_AHBERRMSK | + DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK, + hsotg->regs + DOEPMSK); - writel(0, hsotg->regs + DAINTMSK); + dwc2_writel(0, hsotg->regs + DAINTMSK); /* Be in disconnected state until gadget is registered */ __orr32(hsotg->regs + DCTL, DCTL_SFTDISCON); @@ -3012,14 +3012,14 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) /* setup fifos */ dev_dbg(hsotg->dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", - readl(hsotg->regs + GRXFSIZ), - readl(hsotg->regs + GNPTXFSIZ)); + dwc2_readl(hsotg->regs + GRXFSIZ), + dwc2_readl(hsotg->regs + GNPTXFSIZ)); dwc2_hsotg_init_fifo(hsotg); /* set the PLL on, remove the HNP/SRP and set the PHY */ trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; - writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | + dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | (trdtim << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); @@ -3310,9 +3310,9 @@ static void dwc2_hsotg_initep(struct dwc2_hsotg *hsotg, if (using_dma(hsotg)) { u32 next = DXEPCTL_NEXTEP((epnum + 1) % 15); if (dir_in) - writel(next, hsotg->regs + DIEPCTL(epnum)); + dwc2_writel(next, hsotg->regs + DIEPCTL(epnum)); else - writel(next, hsotg->regs + DOEPCTL(epnum)); + dwc2_writel(next, hsotg->regs + DOEPCTL(epnum)); } } @@ -3330,7 +3330,7 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* check hardware configuration */ - cfg = readl(hsotg->regs + GHWCFG2); + cfg = dwc2_readl(hsotg->regs + GHWCFG2); hsotg->num_of_eps = (cfg >> GHWCFG2_NUM_DEV_EP_SHIFT) & 0xF; /* Add ep0 */ hsotg->num_of_eps++; @@ -3342,7 +3342,7 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) /* Same dwc2_hsotg_ep is used in both directions for ep0 */ hsotg->eps_out[0] = hsotg->eps_in[0]; - cfg = readl(hsotg->regs + GHWCFG1); + cfg = dwc2_readl(hsotg->regs + GHWCFG1); for (i = 1, cfg >>= 2; i < hsotg->num_of_eps; i++, cfg >>= 2) { ep_type = cfg & 3; /* Direction in or both */ @@ -3361,10 +3361,10 @@ static int dwc2_hsotg_hw_cfg(struct dwc2_hsotg *hsotg) } } - cfg = readl(hsotg->regs + GHWCFG3); + cfg = dwc2_readl(hsotg->regs + GHWCFG3); hsotg->fifo_mem = (cfg >> GHWCFG3_DFIFO_DEPTH_SHIFT); - cfg = readl(hsotg->regs + GHWCFG4); + cfg = dwc2_readl(hsotg->regs + GHWCFG4); hsotg->dedicated_fifos = (cfg >> GHWCFG4_DED_FIFO_SHIFT) & 1; dev_info(hsotg->dev, "EPs: %d, %s fifos, %d entries in SPRAM\n", @@ -3387,19 +3387,19 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg) int idx; dev_info(dev, "DCFG=0x%08x, DCTL=0x%08x, DIEPMSK=%08x\n", - readl(regs + DCFG), readl(regs + DCTL), - readl(regs + DIEPMSK)); + dwc2_readl(regs + DCFG), dwc2_readl(regs + DCTL), + dwc2_readl(regs + DIEPMSK)); dev_info(dev, "GAHBCFG=0x%08x, GHWCFG1=0x%08x\n", - readl(regs + GAHBCFG), readl(regs + GHWCFG1)); + dwc2_readl(regs + GAHBCFG), dwc2_readl(regs + GHWCFG1)); dev_info(dev, "GRXFSIZ=0x%08x, GNPTXFSIZ=0x%08x\n", - readl(regs + GRXFSIZ), readl(regs + GNPTXFSIZ)); + dwc2_readl(regs + GRXFSIZ), dwc2_readl(regs + GNPTXFSIZ)); /* show periodic fifo settings */ for (idx = 1; idx < hsotg->num_of_eps; idx++) { - val = readl(regs + DPTXFSIZN(idx)); + val = dwc2_readl(regs + DPTXFSIZN(idx)); dev_info(dev, "DPTx[%d] FSize=%d, StAddr=0x%08x\n", idx, val >> FIFOSIZE_DEPTH_SHIFT, val & FIFOSIZE_STARTADDR_MASK); @@ -3408,21 +3408,21 @@ static void dwc2_hsotg_dump(struct dwc2_hsotg *hsotg) for (idx = 0; idx < hsotg->num_of_eps; idx++) { dev_info(dev, "ep%d-in: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", idx, - readl(regs + DIEPCTL(idx)), - readl(regs + DIEPTSIZ(idx)), - readl(regs + DIEPDMA(idx))); + dwc2_readl(regs + DIEPCTL(idx)), + dwc2_readl(regs + DIEPTSIZ(idx)), + dwc2_readl(regs + DIEPDMA(idx))); - val = readl(regs + DOEPCTL(idx)); + val = dwc2_readl(regs + DOEPCTL(idx)); dev_info(dev, "ep%d-out: EPCTL=0x%08x, SIZ=0x%08x, DMA=0x%08x\n", - idx, readl(regs + DOEPCTL(idx)), - readl(regs + DOEPTSIZ(idx)), - readl(regs + DOEPDMA(idx))); + idx, dwc2_readl(regs + DOEPCTL(idx)), + dwc2_readl(regs + DOEPTSIZ(idx)), + dwc2_readl(regs + DOEPDMA(idx))); } dev_info(dev, "DVBUSDIS=0x%08x, DVBUSPULSE=%08x\n", - readl(regs + DVBUSDIS), readl(regs + DVBUSPULSE)); + dwc2_readl(regs + DVBUSDIS), dwc2_readl(regs + DVBUSPULSE)); #endif } diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 007a3d5a0642..1595d7061f2c 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -80,10 +80,10 @@ static void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg, if (chan == NULL) return; - hcchar = readl(hsotg->regs + HCCHAR(chan->hc_num)); - hcsplt = readl(hsotg->regs + HCSPLT(chan->hc_num)); - hctsiz = readl(hsotg->regs + HCTSIZ(chan->hc_num)); - hc_dma = readl(hsotg->regs + HCDMA(chan->hc_num)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chan->hc_num)); + hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chan->hc_num)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chan->hc_num)); + hc_dma = dwc2_readl(hsotg->regs + HCDMA(chan->hc_num)); dev_dbg(hsotg->dev, " Assigned to channel %p:\n", chan); dev_dbg(hsotg->dev, " hcchar 0x%08x, hcsplt 0x%08x\n", @@ -207,7 +207,7 @@ void dwc2_hcd_start(struct dwc2_hsotg *hsotg) */ hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_RST; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); } queue_delayed_work(hsotg->wq_otg, &hsotg->start_work, @@ -228,11 +228,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) channel = hsotg->hc_ptr_array[i]; if (!list_empty(&channel->hc_list_entry)) continue; - hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); if (hcchar & HCCHAR_CHENA) { hcchar &= ~(HCCHAR_CHENA | HCCHAR_EPDIR); hcchar |= HCCHAR_CHDIS; - writel(hcchar, hsotg->regs + HCCHAR(i)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); } } } @@ -241,11 +241,11 @@ static void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) channel = hsotg->hc_ptr_array[i]; if (!list_empty(&channel->hc_list_entry)) continue; - hcchar = readl(hsotg->regs + HCCHAR(i)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); if (hcchar & HCCHAR_CHENA) { /* Halt the channel */ hcchar |= HCCHAR_CHDIS; - writel(hcchar, hsotg->regs + HCCHAR(i)); + dwc2_writel(hcchar, hsotg->regs + HCCHAR(i)); } dwc2_hc_cleanup(hsotg, channel); @@ -287,11 +287,11 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) * interrupt mask and status bits and disabling subsequent host * channel interrupts. */ - intr = readl(hsotg->regs + GINTMSK); + intr = dwc2_readl(hsotg->regs + GINTMSK); intr &= ~(GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT); - writel(intr, hsotg->regs + GINTMSK); + dwc2_writel(intr, hsotg->regs + GINTMSK); intr = GINTSTS_NPTXFEMP | GINTSTS_PTXFEMP | GINTSTS_HCHINT; - writel(intr, hsotg->regs + GINTSTS); + dwc2_writel(intr, hsotg->regs + GINTSTS); /* * Turn off the vbus power only if the core has transitioned to device @@ -301,7 +301,7 @@ void dwc2_hcd_disconnect(struct dwc2_hsotg *hsotg) if (dwc2_is_device_mode(hsotg)) { if (hsotg->op_state != OTG_STATE_A_SUSPEND) { dev_dbg(hsotg->dev, "Disconnect: PortPower off\n"); - writel(0, hsotg->regs + HPRT0); + dwc2_writel(0, hsotg->regs + HPRT0); } dwc2_disable_host_interrupts(hsotg); @@ -354,7 +354,7 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) /* Turn off the vbus power */ dev_dbg(hsotg->dev, "PortPower off\n"); - writel(0, hsotg->regs + HPRT0); + dwc2_writel(0, hsotg->regs + HPRT0); } /* Caller must hold driver lock */ @@ -378,7 +378,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, if ((dev_speed == USB_SPEED_LOW) && (hsotg->hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED) && (hsotg->hw_params.hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI)) { - u32 hprt0 = readl(hsotg->regs + HPRT0); + u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0); u32 prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; if (prtspd == HPRT0_SPD_FULL_SPEED) @@ -397,7 +397,7 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, return retval; } - intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask = dwc2_readl(hsotg->regs + GINTMSK); if (!(intr_mask & GINTSTS_SOF)) { enum dwc2_transaction_type tr_type; @@ -1070,7 +1070,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) if (dbg_perio()) dev_vdbg(hsotg->dev, "Queue periodic transactions\n"); - tx_status = readl(hsotg->regs + HPTXSTS); + tx_status = dwc2_readl(hsotg->regs + HPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> @@ -1085,7 +1085,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) qh_ptr = hsotg->periodic_sched_assigned.next; while (qh_ptr != &hsotg->periodic_sched_assigned) { - tx_status = readl(hsotg->regs + HPTXSTS); + tx_status = dwc2_readl(hsotg->regs + HPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; if (qspcavail == 0) { @@ -1145,7 +1145,7 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) } if (hsotg->core_params->dma_enable <= 0) { - tx_status = readl(hsotg->regs + HPTXSTS); + tx_status = dwc2_readl(hsotg->regs + HPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> @@ -1168,9 +1168,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) * level to ensure that new requests are loaded as * soon as possible.) */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk |= GINTSTS_PTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } else { /* * Disable the Tx FIFO empty interrupt since there are @@ -1179,9 +1179,9 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) * handlers to queue more transactions as transfer * states change. */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_PTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } } } @@ -1210,7 +1210,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "Queue non-periodic transactions\n"); - tx_status = readl(hsotg->regs + GNPTXSTS); + tx_status = dwc2_readl(hsotg->regs + GNPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> @@ -1233,7 +1233,7 @@ static void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) * available in the request queue or the Tx FIFO */ do { - tx_status = readl(hsotg->regs + GNPTXSTS); + tx_status = dwc2_readl(hsotg->regs + GNPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; if (hsotg->core_params->dma_enable <= 0 && qspcavail == 0) { @@ -1270,7 +1270,7 @@ next: } while (hsotg->non_periodic_qh_ptr != orig_qh_ptr); if (hsotg->core_params->dma_enable <= 0) { - tx_status = readl(hsotg->regs + GNPTXSTS); + tx_status = dwc2_readl(hsotg->regs + GNPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; fspcavail = (tx_status & TXSTS_FSPCAVAIL_MASK) >> @@ -1290,9 +1290,9 @@ next: * level to ensure that new requests are loaded as * soon as possible.) */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk |= GINTSTS_NPTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } else { /* * Disable the Tx FIFO empty interrupt since there are @@ -1301,9 +1301,9 @@ next: * handlers to queue more transactions as transfer * states change. */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_NPTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } } } @@ -1341,10 +1341,10 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, * Ensure NP Tx FIFO empty interrupt is disabled when * there are no non-periodic transfers to process */ - u32 gintmsk = readl(hsotg->regs + GINTMSK); + u32 gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk &= ~GINTSTS_NPTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } } } @@ -1358,7 +1358,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) dev_dbg(hsotg->dev, "%s()\n", __func__); - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); dev_dbg(hsotg->dev, "gotgctl=%0x\n", gotgctl); dev_dbg(hsotg->dev, "gotgctl.b.conidsts=%d\n", !!(gotgctl & GOTGCTL_CONID_B)); @@ -1421,9 +1421,9 @@ static void dwc2_wakeup_detected(unsigned long data) hprt0 = dwc2_read_hprt0(hsotg); dev_dbg(hsotg->dev, "Resume: HPRT0=%0x\n", hprt0); hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n", - readl(hsotg->regs + HPRT0)); + dwc2_readl(hsotg->regs + HPRT0)); dwc2_hcd_rem_wakeup(hsotg); @@ -1451,30 +1451,30 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) spin_lock_irqsave(&hsotg->lock, flags); if (windex == hsotg->otg_port && dwc2_host_is_b_hnp_enabled(hsotg)) { - gotgctl = readl(hsotg->regs + GOTGCTL); + gotgctl = dwc2_readl(hsotg->regs + GOTGCTL); gotgctl |= GOTGCTL_HSTSETHNPEN; - writel(gotgctl, hsotg->regs + GOTGCTL); + dwc2_writel(gotgctl, hsotg->regs + GOTGCTL); hsotg->op_state = OTG_STATE_A_SUSPEND; } hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_SUSP; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); /* Update lx_state */ hsotg->lx_state = DWC2_L2; /* Suspend the Phy Clock */ - pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); pcgctl |= PCGCTL_STOPPCLK; - writel(pcgctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); udelay(10); /* For HNP the bus must be suspended for at least 200ms */ if (dwc2_host_is_b_hnp_enabled(hsotg)) { - pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); pcgctl &= ~PCGCTL_STOPPCLK; - writel(pcgctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); spin_unlock_irqrestore(&hsotg->lock, flags); @@ -1523,23 +1523,23 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, "ClearPortFeature USB_PORT_FEAT_ENABLE\n"); hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_ENA; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); break; case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - writel(0, hsotg->regs + PCGCTL); + dwc2_writel(0, hsotg->regs + PCGCTL); usleep_range(20000, 40000); hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); hprt0 &= ~HPRT0_SUSP; msleep(USB_RESUME_TIMEOUT); hprt0 &= ~HPRT0_RES; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); break; case USB_PORT_FEAT_POWER: @@ -1547,7 +1547,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, "ClearPortFeature USB_PORT_FEAT_POWER\n"); hprt0 = dwc2_read_hprt0(hsotg); hprt0 &= ~HPRT0_PWR; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); break; case USB_PORT_FEAT_INDICATOR: @@ -1668,7 +1668,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, break; } - hprt0 = readl(hsotg->regs + HPRT0); + hprt0 = dwc2_readl(hsotg->regs + HPRT0); dev_vdbg(hsotg->dev, " HPRT0: 0x%08x\n", hprt0); if (hprt0 & HPRT0_CONNSTS) @@ -1733,18 +1733,18 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, "SetPortFeature - USB_PORT_FEAT_POWER\n"); hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_PWR; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); break; case USB_PORT_FEAT_RESET: hprt0 = dwc2_read_hprt0(hsotg); dev_dbg(hsotg->dev, "SetPortFeature - USB_PORT_FEAT_RESET\n"); - pcgctl = readl(hsotg->regs + PCGCTL); + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); pcgctl &= ~(PCGCTL_ENBL_SLEEP_GATING | PCGCTL_STOPPCLK); - writel(pcgctl, hsotg->regs + PCGCTL); + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); /* ??? Original driver does this */ - writel(0, hsotg->regs + PCGCTL); + dwc2_writel(0, hsotg->regs + PCGCTL); hprt0 = dwc2_read_hprt0(hsotg); /* Clear suspend bit if resetting from suspend state */ @@ -1759,13 +1759,13 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, hprt0 |= HPRT0_PWR | HPRT0_RST; dev_dbg(hsotg->dev, "In host mode, hprt0=%08x\n", hprt0); - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); } /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */ usleep_range(50000, 70000); hprt0 &= ~HPRT0_RST; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); hsotg->lx_state = DWC2_L0; /* Now back to On state */ break; @@ -1781,7 +1781,7 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, "SetPortFeature - USB_PORT_FEAT_TEST\n"); hprt0 &= ~HPRT0_TSTCTL_MASK; hprt0 |= (windex >> 8) << HPRT0_TSTCTL_SHIFT; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); break; default: @@ -1838,7 +1838,7 @@ static int dwc2_hcd_is_status_changed(struct dwc2_hsotg *hsotg, int port) int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg) { - u32 hfnum = readl(hsotg->regs + HFNUM); + u32 hfnum = dwc2_readl(hsotg->regs + HFNUM); #ifdef DWC2_DEBUG_SOF dev_vdbg(hsotg->dev, "DWC OTG HCD GET FRAME NUMBER %d\n", @@ -1941,11 +1941,11 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) if (chan->xfer_started) { u32 hfnum, hcchar, hctsiz, hcint, hcintmsk; - hfnum = readl(hsotg->regs + HFNUM); - hcchar = readl(hsotg->regs + HCCHAR(i)); - hctsiz = readl(hsotg->regs + HCTSIZ(i)); - hcint = readl(hsotg->regs + HCINT(i)); - hcintmsk = readl(hsotg->regs + HCINTMSK(i)); + hfnum = dwc2_readl(hsotg->regs + HFNUM); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(i)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(i)); + hcint = dwc2_readl(hsotg->regs + HCINT(i)); + hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(i)); dev_dbg(hsotg->dev, " hfnum: 0x%08x\n", hfnum); dev_dbg(hsotg->dev, " hcchar: 0x%08x\n", hcchar); dev_dbg(hsotg->dev, " hctsiz: 0x%08x\n", hctsiz); @@ -1993,12 +1993,12 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) dev_dbg(hsotg->dev, " periodic_channels: %d\n", hsotg->periodic_channels); dev_dbg(hsotg->dev, " periodic_usecs: %d\n", hsotg->periodic_usecs); - np_tx_status = readl(hsotg->regs + GNPTXSTS); + np_tx_status = dwc2_readl(hsotg->regs + GNPTXSTS); dev_dbg(hsotg->dev, " NP Tx Req Queue Space Avail: %d\n", (np_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT); dev_dbg(hsotg->dev, " NP Tx FIFO Space Avail: %d\n", (np_tx_status & TXSTS_FSPCAVAIL_MASK) >> TXSTS_FSPCAVAIL_SHIFT); - p_tx_status = readl(hsotg->regs + HPTXSTS); + p_tx_status = dwc2_readl(hsotg->regs + HPTXSTS); dev_dbg(hsotg->dev, " P Tx Req Queue Space Avail: %d\n", (p_tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT); dev_dbg(hsotg->dev, " P Tx FIFO Space Avail: %d\n", @@ -2262,7 +2262,7 @@ static void dwc2_hcd_reset_func(struct work_struct *work) dev_dbg(hsotg->dev, "USB RESET function called\n"); hprt0 = dwc2_read_hprt0(hsotg); hprt0 &= ~HPRT0_RST; - writel(hprt0, hsotg->regs + HPRT0); + dwc2_writel(hprt0, hsotg->regs + HPRT0); hsotg->flags.b.port_reset_change = 1; } @@ -2790,17 +2790,17 @@ static void dwc2_hcd_free(struct dwc2_hsotg *hsotg) hsotg->status_buf = NULL; } - ahbcfg = readl(hsotg->regs + GAHBCFG); + ahbcfg = dwc2_readl(hsotg->regs + GAHBCFG); /* Disable all interrupts */ ahbcfg &= ~GAHBCFG_GLBL_INTR_EN; - writel(ahbcfg, hsotg->regs + GAHBCFG); - writel(0, hsotg->regs + GINTMSK); + dwc2_writel(ahbcfg, hsotg->regs + GAHBCFG); + dwc2_writel(0, hsotg->regs + GINTMSK); if (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a) { - dctl = readl(hsotg->regs + DCTL); + dctl = dwc2_readl(hsotg->regs + DCTL); dctl |= DCTL_SFTDISCON; - writel(dctl, hsotg->regs + DCTL); + dwc2_writel(dctl, hsotg->regs + DCTL); } if (hsotg->wq_otg) { @@ -2841,7 +2841,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq) retval = -ENOMEM; - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); dev_dbg(hsotg->dev, "hcfg=%08x\n", hcfg); #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h index fc1054965552..f105bada2fd1 100644 --- a/drivers/usb/dwc2/hcd.h +++ b/drivers/usb/dwc2/hcd.h @@ -371,10 +371,10 @@ static inline struct usb_hcd *dwc2_hsotg_to_hcd(struct dwc2_hsotg *hsotg) */ static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr) { - u32 mask = readl(hsotg->regs + HCINTMSK(chnum)); + u32 mask = dwc2_readl(hsotg->regs + HCINTMSK(chnum)); mask &= ~intr; - writel(mask, hsotg->regs + HCINTMSK(chnum)); + dwc2_writel(mask, hsotg->regs + HCINTMSK(chnum)); } /* @@ -382,11 +382,11 @@ static inline void disable_hc_int(struct dwc2_hsotg *hsotg, int chnum, u32 intr) */ static inline int dwc2_is_host_mode(struct dwc2_hsotg *hsotg) { - return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; + return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) != 0; } static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) { - return (readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; + return (dwc2_readl(hsotg->regs + GINTSTS) & GINTSTS_CURMODE_HOST) == 0; } /* @@ -395,7 +395,7 @@ static inline int dwc2_is_device_mode(struct dwc2_hsotg *hsotg) */ static inline u32 dwc2_read_hprt0(struct dwc2_hsotg *hsotg) { - u32 hprt0 = readl(hsotg->regs + HPRT0); + u32 hprt0 = dwc2_readl(hsotg->regs + HPRT0); hprt0 &= ~(HPRT0_ENA | HPRT0_CONNDET | HPRT0_ENACHG | HPRT0_OVRCURRCHG); return hprt0; @@ -580,7 +580,8 @@ static inline u16 dwc2_micro_frame_num(u16 frame) */ static inline u32 dwc2_read_core_intr(struct dwc2_hsotg *hsotg) { - return readl(hsotg->regs + GINTSTS) & readl(hsotg->regs + GINTMSK); + return dwc2_readl(hsotg->regs + GINTSTS) & + dwc2_readl(hsotg->regs + GINTMSK); } static inline u32 dwc2_hcd_urb_get_status(struct dwc2_hcd_urb *dwc2_urb) @@ -732,7 +733,7 @@ do { \ qtd_list_entry); \ if (usb_pipeint(_qtd_->urb->pipe) && \ (_qh_)->start_split_frame != 0 && !_qtd_->complete_split) { \ - _hfnum_.d32 = readl((_hcd_)->regs + HFNUM); \ + _hfnum_.d32 = dwc2_readl((_hcd_)->regs + HFNUM); \ switch (_hfnum_.b.frnum & 0x7) { \ case 7: \ (_hcd_)->hfnum_7_samples_##_letter_++; \ diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c index 3376177e4d3c..78993aba9335 100644 --- a/drivers/usb/dwc2/hcd_ddma.c +++ b/drivers/usb/dwc2/hcd_ddma.c @@ -169,19 +169,19 @@ static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en) spin_lock_irqsave(&hsotg->lock, flags); - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); if (hcfg & HCFG_PERSCHEDENA) { /* already enabled */ spin_unlock_irqrestore(&hsotg->lock, flags); return; } - writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR); + dwc2_writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR); hcfg &= ~HCFG_FRLISTEN_MASK; hcfg |= fr_list_en | HCFG_PERSCHEDENA; dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n"); - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); spin_unlock_irqrestore(&hsotg->lock, flags); } @@ -193,7 +193,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg) spin_lock_irqsave(&hsotg->lock, flags); - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); if (!(hcfg & HCFG_PERSCHEDENA)) { /* already disabled */ spin_unlock_irqrestore(&hsotg->lock, flags); @@ -202,7 +202,7 @@ static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg) hcfg &= ~HCFG_PERSCHEDENA; dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n"); - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); spin_unlock_irqrestore(&hsotg->lock, flags); } diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index 4cc95df4262d..f70c970707a0 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -148,7 +148,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg) dwc2_hcd_queue_transactions(hsotg, tr_type); /* Clear interrupt */ - writel(GINTSTS_SOF, hsotg->regs + GINTSTS); + dwc2_writel(GINTSTS_SOF, hsotg->regs + GINTSTS); } /* @@ -164,7 +164,7 @@ static void dwc2_rx_fifo_level_intr(struct dwc2_hsotg *hsotg) if (dbg_perio()) dev_vdbg(hsotg->dev, "--RxFIFO Level Interrupt--\n"); - grxsts = readl(hsotg->regs + GRXSTSP); + grxsts = dwc2_readl(hsotg->regs + GRXSTSP); chnum = (grxsts & GRXSTS_HCHNUM_MASK) >> GRXSTS_HCHNUM_SHIFT; chan = hsotg->hc_ptr_array[chnum]; if (!chan) { @@ -247,11 +247,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, dev_vdbg(hsotg->dev, "%s(%p)\n", __func__, hsotg); /* Every time when port enables calculate HFIR.FrInterval */ - hfir = readl(hsotg->regs + HFIR); + hfir = dwc2_readl(hsotg->regs + HFIR); hfir &= ~HFIR_FRINT_MASK; hfir |= dwc2_calc_frame_interval(hsotg) << HFIR_FRINT_SHIFT & HFIR_FRINT_MASK; - writel(hfir, hsotg->regs + HFIR); + dwc2_writel(hfir, hsotg->regs + HFIR); /* Check if we need to adjust the PHY clock speed for low power */ if (!params->host_support_fs_ls_low_power) { @@ -260,7 +260,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, return; } - usbcfg = readl(hsotg->regs + GUSBCFG); + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); prtspd = (hprt0 & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; if (prtspd == HPRT0_SPD_LOW_SPEED || prtspd == HPRT0_SPD_FULL_SPEED) { @@ -268,11 +268,11 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, if (!(usbcfg & GUSBCFG_PHY_LP_CLK_SEL)) { /* Set PHY low power clock select for FS/LS devices */ usbcfg |= GUSBCFG_PHY_LP_CLK_SEL; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); do_reset = 1; } - hcfg = readl(hsotg->regs + HCFG); + hcfg = dwc2_readl(hsotg->regs + HCFG); fslspclksel = (hcfg & HCFG_FSLSPCLKSEL_MASK) >> HCFG_FSLSPCLKSEL_SHIFT; @@ -286,7 +286,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, fslspclksel = HCFG_FSLSPCLKSEL_6_MHZ; hcfg &= ~HCFG_FSLSPCLKSEL_MASK; hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT; - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); do_reset = 1; } } else { @@ -297,7 +297,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, fslspclksel = HCFG_FSLSPCLKSEL_48_MHZ; hcfg &= ~HCFG_FSLSPCLKSEL_MASK; hcfg |= fslspclksel << HCFG_FSLSPCLKSEL_SHIFT; - writel(hcfg, hsotg->regs + HCFG); + dwc2_writel(hcfg, hsotg->regs + HCFG); do_reset = 1; } } @@ -305,7 +305,7 @@ static void dwc2_hprt0_enable(struct dwc2_hsotg *hsotg, u32 hprt0, /* Not low power */ if (usbcfg & GUSBCFG_PHY_LP_CLK_SEL) { usbcfg &= ~GUSBCFG_PHY_LP_CLK_SEL; - writel(usbcfg, hsotg->regs + GUSBCFG); + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); do_reset = 1; } } @@ -332,7 +332,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) dev_vdbg(hsotg->dev, "--Port Interrupt--\n"); - hprt0 = readl(hsotg->regs + HPRT0); + hprt0 = dwc2_readl(hsotg->regs + HPRT0); hprt0_modify = hprt0; /* @@ -388,7 +388,7 @@ static void dwc2_port_intr(struct dwc2_hsotg *hsotg) } /* Clear Port Interrupts */ - writel(hprt0_modify, hsotg->regs + HPRT0); + dwc2_writel(hprt0_modify, hsotg->regs + HPRT0); } /* @@ -408,7 +408,7 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg, { u32 hctsiz, count, length; - hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); if (halt_status == DWC2_HC_XFER_COMPLETE) { if (chan->ep_is_in) { @@ -491,7 +491,7 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg, urb->status = 0; } - hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n", __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum); dev_vdbg(hsotg->dev, " chan->xfer_len %d\n", chan->xfer_len); @@ -514,7 +514,7 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg, struct dwc2_host_chan *chan, int chnum, struct dwc2_qtd *qtd) { - u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); u32 pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT; if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) { @@ -771,9 +771,9 @@ cleanup: } } - haintmsk = readl(hsotg->regs + HAINTMSK); + haintmsk = dwc2_readl(hsotg->regs + HAINTMSK); haintmsk &= ~(1 << chan->hc_num); - writel(haintmsk, hsotg->regs + HAINTMSK); + dwc2_writel(haintmsk, hsotg->regs + HAINTMSK); /* Try to queue more transfers now that there's a free channel */ tr_type = dwc2_hcd_select_transactions(hsotg); @@ -820,9 +820,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg, * is enabled so that the non-periodic schedule will * be processed */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk |= GINTSTS_NPTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } else { dev_vdbg(hsotg->dev, "isoc/intr\n"); /* @@ -839,9 +839,9 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg, * enabled so that the periodic schedule will be * processed */ - gintmsk = readl(hsotg->regs + GINTMSK); + gintmsk = dwc2_readl(hsotg->regs + GINTMSK); gintmsk |= GINTSTS_PTXFEMP; - writel(gintmsk, hsotg->regs + GINTMSK); + dwc2_writel(gintmsk, hsotg->regs + GINTMSK); } } } @@ -906,7 +906,7 @@ static void dwc2_complete_periodic_xfer(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, enum dwc2_halt_status halt_status) { - u32 hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + u32 hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); qtd->error_count = 0; @@ -1184,7 +1184,7 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg, urb->actual_length += xfer_length; - hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); dev_vdbg(hsotg->dev, "DWC_otg: %s: %s, channel %d\n", __func__, (chan->ep_is_in ? "IN" : "OUT"), chnum); dev_vdbg(hsotg->dev, " chan->start_pkt_count %d\n", @@ -1505,10 +1505,10 @@ static void dwc2_hc_ahberr_intr(struct dwc2_hsotg *hsotg, dwc2_hc_handle_tt_clear(hsotg, chan, qtd); - hcchar = readl(hsotg->regs + HCCHAR(chnum)); - hcsplt = readl(hsotg->regs + HCSPLT(chnum)); - hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); - hc_dma = readl(hsotg->regs + HCDMA(chnum)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum)); + hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); + hc_dma = dwc2_readl(hsotg->regs + HCDMA(chnum)); dev_err(hsotg->dev, "AHB ERROR, Channel %d\n", chnum); dev_err(hsotg->dev, " hcchar 0x%08x, hcsplt 0x%08x\n", hcchar, hcsplt); @@ -1721,10 +1721,10 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg, * This code is here only as a check. This condition should * never happen. Ignore the halt if it does occur. */ - hcchar = readl(hsotg->regs + HCCHAR(chnum)); - hctsiz = readl(hsotg->regs + HCTSIZ(chnum)); - hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); - hcsplt = readl(hsotg->regs + HCSPLT(chnum)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum)); + hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum)); + hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum)); + hcsplt = dwc2_readl(hsotg->regs + HCSPLT(chnum)); dev_dbg(hsotg->dev, "%s: chan->halt_status DWC2_HC_XFER_NO_HALT_STATUS,\n", __func__); @@ -1748,7 +1748,7 @@ static bool dwc2_halt_status_ok(struct dwc2_hsotg *hsotg, * when the halt interrupt occurs. Halt the channel again if it does * occur. */ - hcchar = readl(hsotg->regs + HCCHAR(chnum)); + hcchar = dwc2_readl(hsotg->regs + HCCHAR(chnum)); if (hcchar & HCCHAR_CHDIS) { dev_warn(hsotg->dev, "%s: hcchar.chdis set unexpectedly, hcchar 0x%08x, trying to halt again\n", @@ -1808,7 +1808,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, return; } - hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); + hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum)); if (chan->hcint & HCINTMSK_XFERCOMPL) { /* @@ -1903,7 +1903,7 @@ static void dwc2_hc_chhltd_intr_dma(struct dwc2_hsotg *hsotg, dev_err(hsotg->dev, "hcint 0x%08x, intsts 0x%08x\n", chan->hcint, - readl(hsotg->regs + GINTSTS)); + dwc2_readl(hsotg->regs + GINTSTS)); goto error; } } @@ -1958,11 +1958,11 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) chan = hsotg->hc_ptr_array[chnum]; - hcint = readl(hsotg->regs + HCINT(chnum)); - hcintmsk = readl(hsotg->regs + HCINTMSK(chnum)); + hcint = dwc2_readl(hsotg->regs + HCINT(chnum)); + hcintmsk = dwc2_readl(hsotg->regs + HCINTMSK(chnum)); if (!chan) { dev_err(hsotg->dev, "## hc_ptr_array for channel is NULL ##\n"); - writel(hcint, hsotg->regs + HCINT(chnum)); + dwc2_writel(hcint, hsotg->regs + HCINT(chnum)); return; } @@ -1974,7 +1974,7 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) hcint, hcintmsk, hcint & hcintmsk); } - writel(hcint, hsotg->regs + HCINT(chnum)); + dwc2_writel(hcint, hsotg->regs + HCINT(chnum)); chan->hcint = hcint; hcint &= hcintmsk; @@ -2066,7 +2066,7 @@ static void dwc2_hc_intr(struct dwc2_hsotg *hsotg) u32 haint; int i; - haint = readl(hsotg->regs + HAINT); + haint = dwc2_readl(hsotg->regs + HAINT); if (dbg_perio()) { dev_vdbg(hsotg->dev, "%s()\n", __func__); @@ -2134,8 +2134,8 @@ irqreturn_t dwc2_handle_hcd_intr(struct dwc2_hsotg *hsotg) "DWC OTG HCD Finished Servicing Interrupts\n"); dev_vdbg(hsotg->dev, "DWC OTG HCD gintsts=0x%08x gintmsk=0x%08x\n", - readl(hsotg->regs + GINTSTS), - readl(hsotg->regs + GINTMSK)); + dwc2_readl(hsotg->regs + GINTSTS), + dwc2_readl(hsotg->regs + GINTMSK)); } } diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 3ad63d392e13..712977fd67d1 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -115,7 +115,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, if (qh->ep_type == USB_ENDPOINT_XFER_INT) qh->interval = 8; #endif - hprt = readl(hsotg->regs + HPRT0); + hprt = dwc2_readl(hsotg->regs + HPRT0); prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; if (prtspd == HPRT0_SPD_HIGH_SPEED && (dev_speed == USB_SPEED_LOW || @@ -595,9 +595,9 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) if (status) return status; if (!hsotg->periodic_qh_count) { - intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask = dwc2_readl(hsotg->regs + GINTMSK); intr_mask |= GINTSTS_SOF; - writel(intr_mask, hsotg->regs + GINTMSK); + dwc2_writel(intr_mask, hsotg->regs + GINTMSK); } hsotg->periodic_qh_count++; @@ -632,9 +632,9 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) dwc2_deschedule_periodic(hsotg, qh); hsotg->periodic_qh_count--; if (!hsotg->periodic_qh_count) { - intr_mask = readl(hsotg->regs + GINTMSK); + intr_mask = dwc2_readl(hsotg->regs + GINTMSK); intr_mask &= ~GINTSTS_SOF; - writel(intr_mask, hsotg->regs + GINTMSK); + dwc2_writel(intr_mask, hsotg->regs + GINTMSK); } } -- cgit v1.2.3 From 41d3c0b84d6e084865c429b1b6825256c0169319 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:47:58 +0800 Subject: usb: misc: usbtest: allocate size of urb array according to user parameter Allocate the size of urb pointer array according to testusb's parameter sglen, and limits the length of sglen as MAX_SGLEN (128 currently). Acked-by: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 9517812a50e2..8f294d716369 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -95,6 +95,7 @@ static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test) dev_warn(&(tdev)->intf->dev , fmt , ## args) #define GUARD_BYTE 0xA5 +#define MAX_SGLEN 128 /*-------------------------------------------------------------------------*/ @@ -1911,10 +1912,7 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, unsigned i; unsigned long packets = 0; int status = 0; - struct urb *urbs[10]; /* FIXME no limit */ - - if (param->sglen > 10) - return -EDOM; + struct urb *urbs[param->sglen]; memset(&context, 0, sizeof(context)); context.count = param->iterations * param->sglen; @@ -2061,6 +2059,9 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) if (param->iterations <= 0) return -EINVAL; + if (param->sglen > MAX_SGLEN) + return -EINVAL; + if (mutex_lock_interruptible(&dev->lock)) return -ERESTARTSYS; -- cgit v1.2.3 From a724ddfb17e0519d2c2b6e09a96b1b94eff6b801 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:47:59 +0800 Subject: usb: misc: usbtest: delete useless memset for urbs array The element of urbs array will be initialized at below code at once. for (i = 0; i < param->sglen; i++) { urbs[i] = iso_alloc_urb(udev, pipe, desc, param->length, offset); Acked-by: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 8f294d716369..819b4b1f327b 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1920,7 +1920,6 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, init_completion(&context.done); spin_lock_init(&context.lock); - memset(urbs, 0, sizeof(urbs)); udev = testdev_to_usbdev(dev); dev_info(&dev->intf->dev, "iso period %d %sframes, wMaxPacket %d, transactions: %d\n", -- cgit v1.2.3 From 169900f96792c11a5435773dd379046bc8036704 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:48:00 +0800 Subject: usb: misc: usbtest: using the same data format among write/compare/output Using the same data format "buf[j] = (u8)(i + j)" among write, compare buf, and console output stage. Acked-by: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 819b4b1f327b..cac93b77f9a7 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1720,7 +1720,7 @@ static int ctrl_out(struct usbtest_dev *dev, for (i = 0; i < count; i++) { /* write patterned data */ for (j = 0; j < len; j++) - buf[j] = i + j; + buf[j] = (u8)(i + j); retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x5b, USB_DIR_OUT|USB_TYPE_VENDOR, 0, 0, buf, len, USB_CTRL_SET_TIMEOUT); @@ -1750,9 +1750,9 @@ static int ctrl_out(struct usbtest_dev *dev, /* fail if we can't verify */ for (j = 0; j < len; j++) { - if (buf[j] != (u8) (i + j)) { + if (buf[j] != (u8)(i + j)) { ERROR(dev, "ctrl_out, byte %d is %d not %d\n", - j, buf[j], (u8) i + j); + j, buf[j], (u8)(i + j)); retval = -EBADMSG; break; } -- cgit v1.2.3 From b9a6e8e1001e28fecbd74c073f5503dac2790563 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 1 Sep 2015 09:48:01 +0800 Subject: usb: misc: usbtest: format the data pattern according to max packet size With this change, the host and gadget doesn't need to agree with transfer length for comparing the data, since they doesn't know each other's transfer size, but know max packet size. Signed-off-by: Peter Chen Acked-by: Michal Nazarewicz (Fixed the 'line over 80 characters warning' by Peter Chen) Tested-by: Peter Chen Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index cac93b77f9a7..ad6dd4a1de6c 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -304,11 +304,20 @@ static unsigned mod_pattern; module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(mod_pattern, "i/o pattern (0 == zeroes)"); -static inline void simple_fill_buf(struct urb *urb) +static unsigned get_maxpacket(struct usb_device *udev, int pipe) +{ + struct usb_host_endpoint *ep; + + ep = usb_pipe_endpoint(udev, pipe); + return le16_to_cpup(&ep->desc.wMaxPacketSize); +} + +static void simple_fill_buf(struct urb *urb) { unsigned i; u8 *buf = urb->transfer_buffer; unsigned len = urb->transfer_buffer_length; + unsigned maxpacket; switch (pattern) { default: @@ -317,8 +326,9 @@ static inline void simple_fill_buf(struct urb *urb) memset(buf, 0, len); break; case 1: /* mod63 */ + maxpacket = get_maxpacket(urb->dev, urb->pipe); for (i = 0; i < len; i++) - *buf++ = (u8) (i % 63); + *buf++ = (u8) ((i % maxpacket) % 63); break; } } @@ -350,6 +360,7 @@ static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) u8 expected; u8 *buf = urb->transfer_buffer; unsigned len = urb->actual_length; + unsigned maxpacket = get_maxpacket(urb->dev, urb->pipe); int ret = check_guard_bytes(tdev, urb); if (ret) @@ -367,7 +378,7 @@ static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb) * with set_interface or set_config. */ case 1: /* mod63 */ - expected = i % 63; + expected = (i % maxpacket) % 63; break; /* always fail unsupported patterns */ default: @@ -479,11 +490,13 @@ static void free_sglist(struct scatterlist *sg, int nents) } static struct scatterlist * -alloc_sglist(int nents, int max, int vary) +alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe) { struct scatterlist *sg; unsigned i; unsigned size = max; + unsigned maxpacket = + get_maxpacket(interface_to_usbdev(dev->intf), pipe); if (max == 0) return NULL; @@ -512,7 +525,7 @@ alloc_sglist(int nents, int max, int vary) break; case 1: for (j = 0; j < size; j++) - *buf++ = (u8) (j % 63); + *buf++ = (u8) ((j % maxpacket) % 63); break; } @@ -2176,7 +2189,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 5: write %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); - sg = alloc_sglist(param->sglen, param->length, 0); + sg = alloc_sglist(param->sglen, param->length, + 0, dev, dev->out_pipe); if (!sg) { retval = -ENOMEM; break; @@ -2194,7 +2208,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 6: read %d sglists %d entries of %d bytes\n", param->iterations, param->sglen, param->length); - sg = alloc_sglist(param->sglen, param->length, 0); + sg = alloc_sglist(param->sglen, param->length, + 0, dev, dev->in_pipe); if (!sg) { retval = -ENOMEM; break; @@ -2211,7 +2226,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 7: write/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); - sg = alloc_sglist(param->sglen, param->length, param->vary); + sg = alloc_sglist(param->sglen, param->length, + param->vary, dev, dev->out_pipe); if (!sg) { retval = -ENOMEM; break; @@ -2228,7 +2244,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 8: read/%d %d sglists %d entries 0..%d bytes\n", param->vary, param->iterations, param->sglen, param->length); - sg = alloc_sglist(param->sglen, param->length, param->vary); + sg = alloc_sglist(param->sglen, param->length, + param->vary, dev, dev->in_pipe); if (!sg) { retval = -ENOMEM; break; -- cgit v1.2.3 From 046839098c34f0ade17b7060e7385bd581151b3b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:48:02 +0800 Subject: usb: gadget: f_sourcesink: format data pattern according to max packet size Since the host and gadget can't agree with transfer length before each transfer, but they agree with max packet size for each endpoint, we use max packet size to format data pattern. Acked-by: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index cbfaf86fe456..37c7a51bd898 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -489,6 +489,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) unsigned i; u8 *buf = req->buf; struct usb_composite_dev *cdev = ss->function.config->cdev; + int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize); if (pattern == 2) return 0; @@ -510,7 +511,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) * stutter for any reason, including buffer duplication...) */ case 1: - if (*buf == (u8)(i % 63)) + if (*buf == (u8)((i % max_packet_size) % 63)) continue; break; } @@ -525,6 +526,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) { unsigned i; u8 *buf = req->buf; + int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize); switch (pattern) { case 0: @@ -532,7 +534,7 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) break; case 1: for (i = 0; i < req->length; i++) - *buf++ = (u8) (i % 63); + *buf++ = (u8) ((i % max_packet_size) % 63); break; case 2: break; -- cgit v1.2.3 From 0f286379ed72cfc2f9e9a4fd52e79b92d4edaa01 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:48:03 +0800 Subject: tools: usb: testusb: change the help text The 'length' is the transfer length, not the packet size, so change the help text. Acked-by: Michal Nazarewicz Cc: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- tools/usb/testusb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index 879f9870a6bc..863d9e2b3424 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c @@ -454,10 +454,10 @@ usage: "\t-t testnum only run specified case\n" "\t-n no test running, show devices to be tested\n" "Case arguments:\n" - "\t-c iterations default 1000\n" - "\t-s packetsize default 512\n" - "\t-g sglen default 32\n" - "\t-v vary default 512\n", + "\t-c iterations default 1000\n" + "\t-s transfer length default 512\n" + "\t-g sglen default 32\n" + "\t-v vary default 512\n", argv[0]); return 1; } -- cgit v1.2.3 From 9e44d194b90b2d9e6e26cd0381db856fa7cd7e19 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 1 Sep 2015 09:48:04 +0800 Subject: tools: usb: testusb: change the default value for length from 512 to 1024 For ctrl out test, it needs length > vary, so in order to run it with default parameters, we do this change. Acked-by: Michal Nazarewicz Cc: Michal Nazarewicz Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- tools/usb/testusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index 863d9e2b3424..0692d99b6d8f 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c @@ -394,7 +394,7 @@ int main (int argc, char **argv) * low speed, interrupt 8 * 1 = 8 */ param.iterations = 1000; - param.length = 512; + param.length = 1024; param.vary = 512; param.sglen = 32; @@ -455,7 +455,7 @@ usage: "\t-n no test running, show devices to be tested\n" "Case arguments:\n" "\t-c iterations default 1000\n" - "\t-s transfer length default 512\n" + "\t-s transfer length default 1024\n" "\t-g sglen default 32\n" "\t-v vary default 512\n", argv[0]); -- cgit v1.2.3 From 6344475f53977d329ec50f49805fd4ab83df4011 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Mon, 31 Aug 2015 21:09:08 +0530 Subject: usb: dwc3: support for pinctrl state change during system sleep Add support for USB DRVVBUS pinctrl state change during suspend/resume. This helps is conserving power during system sleep. Signed-off-by: Sekhar Nori Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 6270581fc7a9..cfbcebe2cf8f 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1125,6 +1126,8 @@ static int dwc3_suspend(struct device *dev) phy_exit(dwc->usb2_generic_phy); phy_exit(dwc->usb3_generic_phy); + pinctrl_pm_select_sleep_state(dev); + return 0; } @@ -1134,6 +1137,8 @@ static int dwc3_resume(struct device *dev) unsigned long flags; int ret; + pinctrl_pm_select_default_state(dev); + usb_phy_init(dwc->usb3_phy); usb_phy_init(dwc->usb2_phy); ret = phy_init(dwc->usb2_generic_phy); -- cgit v1.2.3 From 04c4d8d4d556256ca8131dd780427e2fbfbd0270 Mon Sep 17 00:00:00 2001 From: WEN Pingbo Date: Fri, 18 Sep 2015 10:51:26 +0800 Subject: usb: gadget: dummy_hcd: replace timeval with timespec64 The millisecond of the last second will be normal if tv_sec is overflowed. But for y2038 consistency and demonstration purpose, and avoiding further risks, we need to remove 'timeval' in this driver, to avoid similair problems. Signed-off-by: Pingbo Wen Reviewed-by: Arnd Bergmann Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/dummy_hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 27af0f008b57..dde44450dfa9 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -833,10 +833,10 @@ static const struct usb_ep_ops dummy_ep_ops = { /* there are both host and device side versions of this call ... */ static int dummy_g_get_frame(struct usb_gadget *_gadget) { - struct timeval tv; + struct timespec64 ts64; - do_gettimeofday(&tv); - return tv.tv_usec / 1000; + ktime_get_ts64(&ts64); + return ts64.tv_nsec / NSEC_PER_MSEC; } static int dummy_wakeup(struct usb_gadget *_gadget) -- cgit v1.2.3 From f871cb9b2e178667a351a6fae9d930826ec10e95 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:39 +0200 Subject: usb: gadget: fix few outdated comments Fix comments in code to make them up to date. composite: claiming endpoint is now done by setting ep->claimed flag, not ep->driver_data. epautoconf: usb_ep_autoconfig() and usb_ep_autoconfig_ss() return claimed endpoint with ep->claimed flag already set. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 4 +--- drivers/usb/gadget/epautoconf.c | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index b474499839d3..3e95c0e88b8b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -839,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev, } } - /* set_alt(), or next bind(), sets up - * ep->driver_data as needed. - */ + /* set_alt(), or next bind(), sets up ep->claimed as needed */ usb_ep_autoconfig_reset(cdev->gadget); done: diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6399c106a3a5..0f4ece44d703 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -53,13 +53,13 @@ * the restrictions that may apply. Some combinations of driver * and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed and * the bmAttribute field in the ep companion descriptor is * updated with the assigned number of streams if it is * different from the original value. To prevent the endpoint - * from being returned by a later autoconfig call, claim it by + * from being returned by a later autoconfig call, claims it by * assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. @@ -154,10 +154,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss); * USB controller, and it can't know all the restrictions that may apply. * Some combinations of driver and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed. To prevent - * the endpoint from being returned by a later autoconfig call, claim it + * the endpoint from being returned by a later autoconfig call, claims it * by assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. -- cgit v1.2.3 From 35bfde36872607b1de87288f9798af79820a910f Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:40 +0200 Subject: usb: gadget: f_ncm: obtain cdev from function instead of driver_data The 'driver_data' field in ep0 is never set to pointer to cdev, so we have to obtain it from another source as in this context ep->driver_data contains invalid data. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_ncm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 3f05c6bd57f0..394cdbfc40f1 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -586,7 +586,7 @@ static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req) unsigned in_size; struct usb_function *f = req->context; struct f_ncm *ncm = func_to_ncm(f); - struct usb_composite_dev *cdev = ep->driver_data; + struct usb_composite_dev *cdev = f->config->cdev; req->context = NULL; if (req->status || req->actual != req->length) { -- cgit v1.2.3 From b67f628c84329a9ce82dbff5fde196dc4624e7c2 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:41 +0200 Subject: usb: gadget: epautoconf: add usb_ep_autoconfig_release() function This patch introduces usb_ep_autoconfig_release() function which allows to release endpoint previously obtained from usb_ep_autoconfig() during USB function bind. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/epautoconf.c | 17 +++++++++++++++++ include/linux/usb/gadget.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 0f4ece44d703..30fdab0ae383 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -171,6 +171,23 @@ struct usb_ep *usb_ep_autoconfig( } EXPORT_SYMBOL_GPL(usb_ep_autoconfig); +/** + * usb_ep_autoconfig_release - releases endpoint and set it to initial state + * @ep: endpoint which should be released + * + * This function can be used during function bind for endpoints obtained + * from usb_ep_autoconfig(). It unclaims endpoint claimed by + * usb_ep_autoconfig() to make it available for other functions. Endpoint + * which was released is no longer invalid and shouldn't be used in + * context of function which released it. + */ +void usb_ep_autoconfig_release(struct usb_ep *ep) +{ + ep->claimed = false; + ep->driver_data = NULL; +} +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release); + /** * usb_ep_autoconfig_reset - reset endpoint autoconfig state * @gadget: device for which autoconfig state will be reset diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index c14a69b36d27..3f299e2b6942 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1233,6 +1233,8 @@ extern struct usb_ep *usb_ep_autoconfig_ss(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); +extern void usb_ep_autoconfig_release(struct usb_ep *); + extern void usb_ep_autoconfig_reset(struct usb_gadget *); #endif /* __LINUX_USB_GADGET_H */ -- cgit v1.2.3 From b0bac2581c1918cc4ab0aca01977ad69f0bc127a Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:42 +0200 Subject: usb: gadget: introduce 'enabled' flag in struct usb_ep This patch introduces 'enabled' flag in struct usb_ep, and modifies usb_ep_enable() and usb_ep_disable() functions to encapsulate endpoint enabled/disabled state. It helps to avoid enabling endpoints which are already enabled, and disabling endpoints which are already disables. From now USB functions don't have to remember current endpoint enable/disable state, as this state is now handled automatically which makes this API less bug-prone. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 3f299e2b6942..3d583a10b926 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -215,6 +215,7 @@ struct usb_ep { struct list_head ep_list; struct usb_ep_caps caps; bool claimed; + bool enabled; unsigned maxpacket:16; unsigned maxpacket_limit:16; unsigned max_streams:16; @@ -264,7 +265,18 @@ static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep, */ static inline int usb_ep_enable(struct usb_ep *ep) { - return ep->ops->enable(ep, ep->desc); + int ret; + + if (ep->enabled) + return 0; + + ret = ep->ops->enable(ep, ep->desc); + if (ret) + return ret; + + ep->enabled = true; + + return 0; } /** @@ -281,7 +293,18 @@ static inline int usb_ep_enable(struct usb_ep *ep) */ static inline int usb_ep_disable(struct usb_ep *ep) { - return ep->ops->disable(ep); + int ret; + + if (!ep->enabled) + return 0; + + ret = ep->ops->disable(ep); + if (ret) + return ret; + + ep->enabled = false; + + return 0; } /** -- cgit v1.2.3 From 92fbfc3884733a4deae313169ef4eca20c0e6e72 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:43 +0200 Subject: usb: gadget: f_ecm: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_ecm, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_ecm.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 7b7424f10ddd..4abca70cdaab 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -541,24 +541,21 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ecm->notify->driver_data) { - VDBG(cdev, "reset ecm control %d\n", intf); - usb_ep_disable(ecm->notify); - } + VDBG(cdev, "reset ecm control %d\n", intf); + usb_ep_disable(ecm->notify); if (!(ecm->notify->desc)) { VDBG(cdev, "init ecm ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, ecm->notify)) goto fail; } usb_ep_enable(ecm->notify); - ecm->notify->driver_data = ecm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ecm->data_id) { if (alt > 1) goto fail; - if (ecm->port.in_ep->driver_data) { + if (ecm->port.in_ep->enabled) { DBG(cdev, "reset ecm\n"); gether_disconnect(&ecm->port); } @@ -618,7 +615,7 @@ static int ecm_get_alt(struct usb_function *f, unsigned intf) if (intf == ecm->ctrl_id) return 0; - return ecm->port.in_ep->driver_data ? 1 : 0; + return ecm->port.in_ep->enabled ? 1 : 0; } static void ecm_disable(struct usb_function *f) @@ -628,14 +625,11 @@ static void ecm_disable(struct usb_function *f) DBG(cdev, "ecm deactivated\n"); - if (ecm->port.in_ep->driver_data) + if (ecm->port.in_ep->enabled) gether_disconnect(&ecm->port); - if (ecm->notify->driver_data) { - usb_ep_disable(ecm->notify); - ecm->notify->driver_data = NULL; - ecm->notify->desc = NULL; - } + usb_ep_disable(ecm->notify); + ecm->notify->desc = NULL; } /*-------------------------------------------------------------------------*/ @@ -750,13 +744,11 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); if (!ep) goto fail; ecm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is *OPTIONAL* but we * don't treat it that way. It's simpler, and some newer CDC @@ -766,7 +758,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -820,14 +811,6 @@ fail: usb_ep_free_request(ecm->notify, ecm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ecm->notify) - ecm->notify->driver_data = NULL; - if (ecm->port.out_ep) - ecm->port.out_ep->driver_data = NULL; - if (ecm->port.in_ep) - ecm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From 4aab757ca44ad8f9d629c4bf5a513e94cff9aeb1 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:44 +0200 Subject: usb: gadget: f_acm: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_acm we only need to store in ep->driver_data pointer to struct f_acm, as it's used in acm_complete_set_line_coding() callback. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_acm.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index be9df09fde26..22e723d12d36 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -428,21 +428,18 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ if (intf == acm->ctrl_id) { - if (acm->notify->driver_data) { - dev_vdbg(&cdev->gadget->dev, - "reset acm control interface %d\n", intf); - usb_ep_disable(acm->notify); - } + dev_vdbg(&cdev->gadget->dev, + "reset acm control interface %d\n", intf); + usb_ep_disable(acm->notify); if (!acm->notify->desc) if (config_ep_by_speed(cdev->gadget, f, acm->notify)) return -EINVAL; usb_ep_enable(acm->notify); - acm->notify->driver_data = acm; } else if (intf == acm->data_id) { - if (acm->port.in->driver_data) { + if (acm->notify->enabled) { dev_dbg(&cdev->gadget->dev, "reset acm ttyGS%d\n", acm->port_num); gserial_disconnect(&acm->port); @@ -475,7 +472,6 @@ static void acm_disable(struct usb_function *f) dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num); gserial_disconnect(&acm->port); usb_ep_disable(acm->notify); - acm->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -655,19 +651,16 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; acm->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); if (!ep) goto fail; acm->port.out = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); if (!ep) goto fail; acm->notify = ep; - ep->driver_data = cdev; /* claim */ /* allocate notification */ acm->notify_req = gs_alloc_req(ep, @@ -709,14 +702,6 @@ fail: if (acm->notify_req) gs_free_req(acm->notify, acm->notify_req); - /* we might as well release our claims on endpoints */ - if (acm->notify) - acm->notify->driver_data = NULL; - if (acm->port.out) - acm->port.out->driver_data = NULL; - if (acm->port.in) - acm->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; -- cgit v1.2.3 From 34422a5e5a884c8680ce9144cf270ae08b1472be Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:45 +0200 Subject: usb: gadget: f_eem: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_ecm, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_eem.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index c9e90de5bdd9..9a55757c729b 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -195,11 +195,8 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; if (intf == eem->ctrl_id) { - - if (eem->port.in_ep->driver_data) { - DBG(cdev, "reset eem\n"); - gether_disconnect(&eem->port); - } + DBG(cdev, "reset eem\n"); + gether_disconnect(&eem->port); if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) { DBG(cdev, "init eem\n"); @@ -237,7 +234,7 @@ static void eem_disable(struct usb_function *f) DBG(cdev, "eem deactivated\n"); - if (eem->port.in_ep->driver_data) + if (eem->port.in_ep->enabled) gether_disconnect(&eem->port); } @@ -293,13 +290,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; eem->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc); if (!ep) goto fail; eem->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -325,11 +320,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (eem->port.out_ep) - eem->port.out_ep->driver_data = NULL; - if (eem->port.in_ep) - eem->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From 2516a680c4202aa587858e94ce7b721dfb9363a3 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:46 +0200 Subject: usb: gadget: f_hid: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_hid we only need to store in ep->driver_data pointer to struct f_hidg, as it's used in f_hidg_req_complete() callback. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6df9715a4bcd..21fcf18f53a0 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -492,10 +492,7 @@ static void hidg_disable(struct usb_function *f) struct f_hidg_req_list *list, *next; usb_ep_disable(hidg->in_ep); - hidg->in_ep->driver_data = NULL; - usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { list_del(&list->list); @@ -513,8 +510,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->in_ep != NULL) { /* restart endpoint */ - if (hidg->in_ep->driver_data != NULL) - usb_ep_disable(hidg->in_ep); + usb_ep_disable(hidg->in_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->in_ep); @@ -533,8 +529,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->out_ep != NULL) { /* restart endpoint */ - if (hidg->out_ep->driver_data != NULL) - usb_ep_disable(hidg->out_ep); + usb_ep_disable(hidg->out_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->out_ep); @@ -566,7 +561,6 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) hidg->out_ep->name, status); } else { usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; status = -ENOMEM; goto fail; } @@ -614,13 +608,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->in_ep = ep; ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->out_ep = ep; /* preallocate request and buffer */ -- cgit v1.2.3 From 0523ca4e485f9273975103c5fe2397b2a8abfae8 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:47 +0200 Subject: usb: gadget: f_loopback: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_hid we only need to store in ep->driver_data pointer to struct f_loopback, as it's used in loopback_complete() callback. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_loopback.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 6e2fe63b9267..300e6011ae67 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -195,12 +195,10 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - loop->in_ep->driver_data = cdev; /* claim */ loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc); if (!loop->out_ep) goto autoconf_fail; - loop->out_ep->driver_data = cdev; /* claim */ /* support high speed hardware */ hs_loop_source_desc.bEndpointAddress = @@ -364,8 +362,7 @@ static int loopback_set_alt(struct usb_function *f, struct usb_composite_dev *cdev = f->config->cdev; /* we know alt is zero */ - if (loop->in_ep->driver_data) - disable_loopback(loop); + disable_loopback(loop); return enable_loopback(cdev, loop); } -- cgit v1.2.3 From 1cecd54f327fdddbeefa15126f2f58b26b6c39e2 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:48 +0200 Subject: usb: gadget: f_mass_storage: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_mass_storage we only need to store in ep->driver_data pointer to struct fsg_common, which is used in bulk_in_complete() and bulk_out_complete() callbacks. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_mass_storage.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 5277e7c4a82a..cd54e72a6c50 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2258,12 +2258,10 @@ reset: /* Disable the endpoints */ if (fsg->bulk_in_enabled) { usb_ep_disable(fsg->bulk_in); - fsg->bulk_in->driver_data = NULL; fsg->bulk_in_enabled = 0; } if (fsg->bulk_out_enabled) { usb_ep_disable(fsg->bulk_out); - fsg->bulk_out->driver_data = NULL; fsg->bulk_out_enabled = 0; } @@ -3072,13 +3070,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_in = ep; ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; /* Assume endpoint addresses are the same for both speeds */ -- cgit v1.2.3 From ce723951a5093a47b312d828c2b975c4cf3d5a5b Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:49 +0200 Subject: usb: gadget: f_midi: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_midi we only need to store in ep->driver_data pointer to struct f_midi, as it's used in f_midi_complete() callback and related functions. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_midi.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index 9fc86d90c7bd..ce3c8a629266 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -302,8 +302,7 @@ static int f_midi_start_ep(struct f_midi *midi, int err; struct usb_composite_dev *cdev = f->config->cdev; - if (ep->driver_data) - usb_ep_disable(ep); + usb_ep_disable(ep); err = config_ep_by_speed(midi->gadget, f, ep); if (err) { @@ -341,8 +340,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) return err; - if (midi->out_ep->driver_data) - usb_ep_disable(midi->out_ep); + usb_ep_disable(midi->out_ep); err = config_ep_by_speed(midi->gadget, f, midi->out_ep); if (err) { @@ -763,12 +761,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); if (!midi->in_ep) goto fail; - midi->in_ep->driver_data = cdev; /* claim */ midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc); if (!midi->out_ep) goto fail; - midi->out_ep->driver_data = cdev; /* claim */ /* allocate temporary function list */ midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), @@ -895,12 +891,6 @@ fail_f_midi: fail: f_midi_unregister_card(midi); fail_register: - /* we might as well release our claims on endpoints */ - if (midi->out_ep) - midi->out_ep->driver_data = NULL; - if (midi->in_ep) - midi->in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From 6b4012a2e4d4702f8fb0ee1db1c0f0b17ab7d41b Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:50 +0200 Subject: usb: gadget: f_ncm: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_ncm, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_ncm.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 394cdbfc40f1..b6f7ed7d48a7 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -803,10 +803,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ncm->notify->driver_data) { - DBG(cdev, "reset ncm control %d\n", intf); - usb_ep_disable(ncm->notify); - } + DBG(cdev, "reset ncm control %d\n", intf); + usb_ep_disable(ncm->notify); if (!(ncm->notify->desc)) { DBG(cdev, "init ncm ctrl %d\n", intf); @@ -814,14 +812,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; } usb_ep_enable(ncm->notify); - ncm->notify->driver_data = ncm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ncm->data_id) { if (alt > 1) goto fail; - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { DBG(cdev, "reset ncm\n"); ncm->timer_stopping = true; ncm->netdev = NULL; @@ -885,7 +882,7 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf) if (intf == ncm->ctrl_id) return 0; - return ncm->port.in_ep->driver_data ? 1 : 0; + return ncm->port.in_ep->enabled ? 1 : 0; } static struct sk_buff *package_for_tx(struct f_ncm *ncm) @@ -1276,15 +1273,14 @@ static void ncm_disable(struct usb_function *f) DBG(cdev, "ncm deactivated\n"); - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { ncm->timer_stopping = true; ncm->netdev = NULL; gether_disconnect(&ncm->port); } - if (ncm->notify->driver_data) { + if (ncm->notify->enabled) { usb_ep_disable(ncm->notify); - ncm->notify->driver_data = NULL; ncm->notify->desc = NULL; } } @@ -1402,19 +1398,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ncm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); if (!ep) goto fail; ncm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); if (!ep) goto fail; ncm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -1468,14 +1461,6 @@ fail: usb_ep_free_request(ncm->notify, ncm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ncm->notify) - ncm->notify->driver_data = NULL; - if (ncm->port.out_ep) - ncm->port.out_ep->driver_data = NULL; - if (ncm->port.in_ep) - ncm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From d277e1a30305bbef4ce38477771dc1594dc1e8fb Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:51 +0200 Subject: usb: gadget: f_obex: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_obex, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_obex.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index 5460426057eb..1c3d30ad2f92 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -206,7 +206,7 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt > 1) goto fail; - if (obex->port.in->driver_data) { + if (obex->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset obex ttyGS%d\n", obex->port_num); gserial_disconnect(&obex->port); @@ -348,13 +348,11 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; obex->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc); if (!ep) goto fail; obex->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -378,12 +376,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (obex->port.out) - obex->port.out->driver_data = NULL; - if (obex->port.in) - obex->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; -- cgit v1.2.3 From 101382ffb3838d68bf6d6d675c66a2f84ed3cb90 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:52 +0200 Subject: usb: gadget: f_phonet: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_phonet we only need to store in ep->driver_data pointer to struct f_phonet, as it's used in pn_tx_complete() and pn_rx_complete() callbacks. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_phonet.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index c0c3ef272714..62a198754029 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -418,7 +418,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) spin_lock(&port->lock); - if (fp->in_ep->driver_data) + if (fp->in_ep->enabled) __pn_reset(f); if (alt == 1) { @@ -530,13 +530,11 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto err; fp->out_ep = ep; - ep->driver_data = fp; /* Claim */ ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc); if (!ep) goto err; fp->in_ep = ep; - ep->driver_data = fp; /* Claim */ pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress; pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress; @@ -575,10 +573,6 @@ err_req: usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); usb_free_all_descriptors(f); err: - if (fp->out_ep) - fp->out_ep->driver_data = NULL; - if (fp->in_ep) - fp->in_ep->driver_data = NULL; ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n"); return status; } -- cgit v1.2.3 From ce21a9894208bf6fc3444837bb286f876d675205 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:53 +0200 Subject: usb: gadget: f_printer: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_printer we only need to store in ep->driver_data pointer to struct printer_dev, as it's used in rx_complete() and tx_complete() callbacks. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_printer.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8e2b6bea07bc..7fb3209ed52c 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1039,12 +1039,10 @@ autoconf_fail: cdev->gadget->name); return -ENODEV; } - in_ep->driver_data = in_ep; /* claim */ out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); if (!out_ep) goto autoconf_fail; - out_ep->driver_data = out_ep; /* claim */ /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; -- cgit v1.2.3 From bbc474f7882b815e616a57adcc49c977ad53fb7f Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:54 +0200 Subject: usb: gadget: f_rndis: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_rndis, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_rndis.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 32985dade838..fd301ed9e294 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -543,22 +543,20 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0 */ if (intf == rndis->ctrl_id) { - if (rndis->notify->driver_data) { - VDBG(cdev, "reset rndis control %d\n", intf); - usb_ep_disable(rndis->notify); - } + VDBG(cdev, "reset rndis control %d\n", intf); + usb_ep_disable(rndis->notify); + if (!rndis->notify->desc) { VDBG(cdev, "init rndis ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) goto fail; } usb_ep_enable(rndis->notify); - rndis->notify->driver_data = rndis; } else if (intf == rndis->data_id) { struct net_device *net; - if (rndis->port.in_ep->driver_data) { + if (rndis->port.in_ep->enabled) { DBG(cdev, "reset rndis\n"); gether_disconnect(&rndis->port); } @@ -612,7 +610,7 @@ static void rndis_disable(struct usb_function *f) struct f_rndis *rndis = func_to_rndis(f); struct usb_composite_dev *cdev = f->config->cdev; - if (!rndis->notify->driver_data) + if (!rndis->notify->enabled) return; DBG(cdev, "rndis deactivated\n"); @@ -621,7 +619,6 @@ static void rndis_disable(struct usb_function *f) gether_disconnect(&rndis->port); usb_ep_disable(rndis->notify); - rndis->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -745,13 +742,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); if (!ep) goto fail; rndis->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is, strictly speaking, * optional. We don't treat it that way though! It's simpler, @@ -761,7 +756,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -829,14 +823,6 @@ fail: usb_ep_free_request(rndis->notify, rndis->notify_req); } - /* we might as well release our claims on endpoints */ - if (rndis->notify) - rndis->notify->driver_data = NULL; - if (rndis->port.out_ep) - rndis->port.out_ep->driver_data = NULL; - if (rndis->port.in_ep) - rndis->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From 885d22eb84a5f634e3776676e5d42f9931899d06 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:55 +0200 Subject: usb: gadget: f_serial: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_serial, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_serial.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 1d162e200e83..ba705e047d7e 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -153,7 +153,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (gser->port.in->driver_data) { + if (gser->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset generic ttyGS%d\n", gser->port_num); gserial_disconnect(&gser->port); @@ -219,13 +219,11 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; gser->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc); if (!ep) goto fail; gser->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -249,12 +247,6 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (gser->port.out) - gser->port.out->driver_data = NULL; - if (gser->port.in) - gser->port.in->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From dbd2badfa6b40de6baf81b7c1911794cdb4c1c90 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:56 +0200 Subject: usb: gadget: f_sourcesink: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_sourcesink we only need to store in ep->driver_data pointer to struct f_sourcesink, as it's used in source_sink_complete() callback. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 37c7a51bd898..1353465ca599 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -311,13 +311,9 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) { int value; - if (ep->driver_data) { - value = usb_ep_disable(ep); - if (value < 0) - DBG(cdev, "disable %s --> %d\n", - ep->name, value); - ep->driver_data = NULL; - } + value = usb_ep_disable(ep); + if (value < 0) + DBG(cdev, "disable %s --> %d\n", ep->name, value); } void disable_endpoints(struct usb_composite_dev *cdev, @@ -355,12 +351,10 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - ss->in_ep->driver_data = cdev; /* claim */ ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc); if (!ss->out_ep) goto autoconf_fail; - ss->out_ep->driver_data = cdev; /* claim */ /* sanity check the isoc module parameters */ if (isoc_interval < 1) @@ -384,13 +378,10 @@ autoconf_fail: ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc); if (!ss->iso_in_ep) goto no_iso; - ss->iso_in_ep->driver_data = cdev; /* claim */ ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc); - if (ss->iso_out_ep) { - ss->iso_out_ep->driver_data = cdev; /* claim */ - } else { - ss->iso_in_ep->driver_data = NULL; + if (!ss->iso_out_ep) { + usb_ep_autoconfig_release(ss->iso_in_ep); ss->iso_in_ep = NULL; no_iso: /* @@ -685,7 +676,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss, fail: ep = ss->in_ep; usb_ep_disable(ep); - ep->driver_data = NULL; return result; } @@ -704,7 +694,6 @@ fail: fail2: ep = ss->out_ep; usb_ep_disable(ep); - ep->driver_data = NULL; goto fail; } @@ -726,10 +715,8 @@ fail2: if (result < 0) { fail3: ep = ss->iso_in_ep; - if (ep) { + if (ep) usb_ep_disable(ep); - ep->driver_data = NULL; - } goto fail2; } } @@ -748,7 +735,6 @@ fail3: result = source_sink_start_ep(ss, false, true, speed); if (result < 0) { usb_ep_disable(ep); - ep->driver_data = NULL; goto fail3; } } @@ -765,8 +751,7 @@ static int sourcesink_set_alt(struct usb_function *f, struct f_sourcesink *ss = func_to_ss(f); struct usb_composite_dev *cdev = f->config->cdev; - if (ss->in_ep->driver_data) - disable_source_sink(ss); + disable_source_sink(ss); return enable_source_sink(cdev, ss, alt); } -- cgit v1.2.3 From bb38c18adb872714d5b27b0fe2d87c6489cb6275 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:57 +0200 Subject: usb: gadget: f_subset: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_subset, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_subset.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index e3dfa675ff06..2e66e624e6e1 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -262,7 +262,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (geth->port.in_ep->driver_data) { + if (geth->port.in_ep->enabled) { DBG(cdev, "reset cdc subset\n"); gether_disconnect(&geth->port); } @@ -343,13 +343,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; geth->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc); if (!ep) goto fail; geth->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -380,12 +378,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (geth->port.out_ep) - geth->port.out_ep->driver_data = NULL; - if (geth->port.in_ep) - geth->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; -- cgit v1.2.3 From 6ae6e1a241c1d7a5c5800d035d195a66911d96f1 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:58 +0200 Subject: usb: gadget: f_uac1: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_uac1, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7856b3394494..8ee701924d29 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -593,7 +593,6 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return err; usb_ep_enable(out_ep); - out_ep->driver_data = audio; audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(audio->copy_buf)) return -ENOMEM; @@ -718,7 +717,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) goto fail; audio->out_ep = ep; audio->out_ep->desc = &as_out_ep_desc; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -730,8 +728,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) fail: gaudio_cleanup(&audio->card); - if (ep) - ep->driver_data = NULL; return status; } -- cgit v1.2.3 From 887d8206c5c50f06241688f3ab807e1e2568f5c6 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:10:59 +0200 Subject: usb: gadget: f_uac2: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_uac2, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac2.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f8de7ea2a0c1..63336e269898 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1081,14 +1081,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->out_ep->driver_data = agdev; agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); if (!agdev->in_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->in_ep->driver_data = agdev; uac2->p_prm.uac2 = uac2; uac2->c_prm.uac2 = uac2; @@ -1132,10 +1130,6 @@ err_free_descs: err: kfree(agdev->uac2.p_prm.rbuf); kfree(agdev->uac2.c_prm.rbuf); - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; return -EINVAL; } @@ -1583,11 +1577,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) prm = &agdev->uac2.c_prm; kfree(prm->rbuf); usb_free_all_descriptors(f); - - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; } static struct usb_function *afunc_alloc(struct usb_function_instance *fi) -- cgit v1.2.3 From d62bf8c16570eb44e2ea3fc5c1f6a8ab83e52778 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:11:00 +0200 Subject: usb: gadget: f_uvc: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of f_uvc, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uvc.c | 42 +++++++------------------------------ 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 743be34605dc..29b41b5dee04 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -280,7 +280,7 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface) else if (interface != uvc->streaming_intf) return -EINVAL; else - return uvc->video.ep->driver_data ? 1 : 0; + return uvc->video.ep->enabled ? 1 : 0; } static int @@ -298,18 +298,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (alt) return -EINVAL; - if (uvc->control_ep->driver_data) { - INFO(cdev, "reset UVC Control\n"); - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + INFO(cdev, "reset UVC Control\n"); + usb_ep_disable(uvc->control_ep); if (!uvc->control_ep->desc) if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep)) return -EINVAL; usb_ep_enable(uvc->control_ep); - uvc->control_ep->driver_data = uvc; if (uvc->state == UVC_STATE_DISCONNECTED) { memset(&v4l2_event, 0, sizeof(v4l2_event)); @@ -336,10 +332,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (uvc->state != UVC_STATE_STREAMING) return 0; - if (uvc->video.ep) { + if (uvc->video.ep) usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMOFF; @@ -355,18 +349,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (!uvc->video.ep) return -EINVAL; - if (uvc->video.ep->driver_data) { - INFO(cdev, "reset UVC\n"); - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } + INFO(cdev, "reset UVC\n"); + usb_ep_disable(uvc->video.ep); ret = config_ep_by_speed(f->config->cdev->gadget, &(uvc->func), uvc->video.ep); if (ret) return ret; usb_ep_enable(uvc->video.ep); - uvc->video.ep->driver_data = uvc; memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; @@ -392,15 +382,8 @@ uvc_function_disable(struct usb_function *f) uvc->state = UVC_STATE_DISCONNECTED; - if (uvc->video.ep->driver_data) { - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } - - if (uvc->control_ep->driver_data) { - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + usb_ep_disable(uvc->video.ep); + usb_ep_disable(uvc->control_ep); } /* -------------------------------------------------------------------------- @@ -651,7 +634,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->control_ep = ep; - ep->driver_data = uvc; if (gadget_is_superspeed(c->cdev->gadget)) ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, @@ -666,7 +648,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->video.ep = ep; - ep->driver_data = uvc; uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; @@ -755,11 +736,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) error: v4l2_device_unregister(&uvc->v4l2_dev); - if (uvc->control_ep) - uvc->control_ep->driver_data = NULL; - if (uvc->video.ep) - uvc->video.ep->driver_data = NULL; - if (uvc->control_req) usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); @@ -886,8 +862,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); - uvc->control_ep->driver_data = NULL; - uvc->video.ep->driver_data = NULL; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); -- cgit v1.2.3 From 6e4bfc54083b2b0eff45ad2001f2a3bee9074dcc Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:11:01 +0200 Subject: usb: gadget: u_ether: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of u_ether we only need to store in ep->driver_data pointer to struct eth_dev, as it's used in rx_complete() and tx_complete() callbacks. All other uses of ep->driver_data are now meaningless and can be safely removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_ether.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 6828ea294024..6554322af2c1 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -1149,7 +1149,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->in_ep->driver_data = NULL; link->in_ep->desc = NULL; usb_ep_disable(link->out_ep); @@ -1164,7 +1163,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->out_ep->driver_data = NULL; link->out_ep->desc = NULL; /* finish forgetting about this USB link episode */ -- cgit v1.2.3 From 18411c0f94716ec225a4f7e1d7735c80f5ec0dab Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:11:02 +0200 Subject: usb: gadget: u_serial: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of u_serial ep->driver_data stores pointer to struct gs_port, which is referenced in many places in code. Code using ep->driver_data to mark endpoint as enabled/disabled has been removed. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_serial.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 7ee057930ae7..9cc6a13d5e5b 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -876,7 +876,6 @@ static void gs_close(struct tty_struct *tty, struct file *file) else gs_buf_clear(&port->port_write_buf); - tty->driver_data = NULL; port->port.tty = NULL; port->openclose = false; @@ -1224,7 +1223,6 @@ int gserial_connect(struct gserial *gser, u8 port_num) fail_out: usb_ep_disable(gser->in); - gser->in->driver_data = NULL; return status; } EXPORT_SYMBOL_GPL(gserial_connect); @@ -1264,10 +1262,7 @@ void gserial_disconnect(struct gserial *gser) /* disable endpoints, aborting down any active I/O */ usb_ep_disable(gser->out); - gser->out->driver_data = NULL; - usb_ep_disable(gser->in); - gser->in->driver_data = NULL; /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); -- cgit v1.2.3 From 4ce86bfaa62f7f044701b796f1ee84e80308457f Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:11:03 +0200 Subject: usb: gadget: legacy: dbgp: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of dbgp, ep->driver_data was used only for endpoint claiming and marking endpoints as enabled, so we can simplify code by reducing it. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/dbgp.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 5231a32aef55..99ca3dabc4f3 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -79,10 +79,7 @@ static int dbgp_consume(char *buf, unsigned len) static void __disable_ep(struct usb_ep *ep) { - if (ep && ep->driver_data == dbgp.gadget) { - usb_ep_disable(ep); - ep->driver_data = NULL; - } + usb_ep_disable(ep); } static void dbgp_disable_ep(void) @@ -171,7 +168,6 @@ static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc) int err; ep->desc = desc; err = usb_ep_enable(ep); - ep->driver_data = dbgp.gadget; return err; } @@ -229,8 +225,6 @@ static void dbgp_unbind(struct usb_gadget *gadget) usb_ep_free_request(gadget->ep0, dbgp.req); dbgp.req = NULL; } - - gadget->ep0->driver_data = NULL; } #ifdef CONFIG_USB_G_DBGP_SERIAL @@ -249,18 +243,15 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) goto fail_1; } - dbgp.i_ep->driver_data = gadget; i_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc); if (!dbgp.o_ep) { - dbgp.i_ep->driver_data = NULL; stp = 2; - goto fail_2; + goto fail_1; } - dbgp.o_ep->driver_data = gadget; o_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); @@ -277,8 +268,6 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) return 0; -fail_2: - dbgp.i_ep->driver_data = NULL; fail_1: dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp); return -ENODEV; @@ -306,7 +295,6 @@ static int dbgp_bind(struct usb_gadget *gadget, } dbgp.req->length = DBGP_REQ_EP0_LEN; - gadget->ep0->driver_data = gadget; #ifdef CONFIG_USB_G_DBGP_SERIAL dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); @@ -356,8 +344,6 @@ static int dbgp_setup(struct usb_gadget *gadget, void *data = NULL; u16 len = 0; - gadget->ep0->driver_data = gadget; - if (request == USB_REQ_GET_DESCRIPTOR) { switch (value>>8) { case USB_DT_DEVICE: -- cgit v1.2.3 From 5cd22f80bc0c10e3005dad5e2903504b431bbe0e Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 16 Sep 2015 12:11:04 +0200 Subject: usb: gadget: legacy: tcm: eliminate abuse of ep->driver data Since ep->driver_data is not used for endpoint claiming, neither for enabled/disabled state storing, we can reduce number of places where we read or modify it's value, as now it has no particular meaning for function or framework logic. In case of tcm, ep->driver_data was used only for endpoint claiming so we can simplify code by reducing it. We also remove give_back_ep() function which is not needed after all - when error code is returned from bind() function, composite will release all endpoints anyway. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index c3c48088fced..778e42abb3cb 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -2018,14 +2018,6 @@ static struct usb_configuration usbg_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; -static void give_back_ep(struct usb_ep **pep) -{ - struct usb_ep *ep = *pep; - if (!ep) - return; - ep->driver_data = NULL; -} - static int usbg_bind(struct usb_configuration *c, struct usb_function *f) { struct f_uas *fu = to_f_uas(f); @@ -2045,29 +2037,24 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) &uasp_bi_ep_comp_desc); if (!ep) goto ep_fail; - - ep->driver_data = fu; fu->ep_in = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, &uasp_bo_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_out = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, &uasp_status_in_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_status = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, &uasp_cmd_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_cmd = ep; /* Assume endpoint addresses are the same for both speeds */ @@ -2091,11 +2078,6 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) return 0; ep_fail: pr_err("Can't claim all required eps\n"); - - give_back_ep(&fu->ep_in); - give_back_ep(&fu->ep_out); - give_back_ep(&fu->ep_status); - give_back_ep(&fu->ep_cmd); return -ENOTSUPP; } -- cgit v1.2.3 From 58efd4b06df4a421652cb2c8a850a9697a37915c Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 22 Sep 2015 15:31:34 +0800 Subject: usb: phy: change some comments - Replace all "transceiver" with "phy" - Replace one "OTG controller" with "phy" Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi --- include/linux/usb/phy.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index e39f251cf861..31a8068c42a5 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -63,7 +63,7 @@ enum usb_otg_state { struct usb_phy; struct usb_otg; -/* for transceivers connected thru an ULPI interface, the user must +/* for phys connected thru an ULPI interface, the user must * provide access ops */ struct usb_phy_io_ops { @@ -92,10 +92,10 @@ struct usb_phy { u16 port_status; u16 port_change; - /* to support controllers that have multiple transceivers */ + /* to support controllers that have multiple phys */ struct list_head head; - /* initialize/shutdown the OTG controller */ + /* initialize/shutdown the phy */ int (*init)(struct usb_phy *x); void (*shutdown)(struct usb_phy *x); @@ -106,7 +106,7 @@ struct usb_phy { int (*set_power)(struct usb_phy *x, unsigned mA); - /* Set transceiver into suspend mode */ + /* Set phy into suspend mode */ int (*set_suspend)(struct usb_phy *x, int suspend); -- cgit v1.2.3 From 63863b988eeca2823ce76b28b104e0b8366cafec Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 11:14:32 +0300 Subject: usb: common: of_usb_get_maximum_speed to usb_get_maximum_speed By using the unified device property interface, the function can be made available for all platforms and not just the ones using DT. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/common/common.c | 44 ++++++++++++++++++-------------------------- drivers/usb/dwc3/core.c | 3 ++- drivers/usb/musb/musb_dsps.c | 2 +- include/linux/usb/ch9.h | 11 ++++++++++- include/linux/usb/of.h | 6 ------ 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 3feebf7f31f0..ce7153232425 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -648,7 +648,7 @@ static int ci_get_platdata(struct device *dev, return ret; } - if (of_usb_get_maximum_speed(dev->of_node) == USB_SPEED_FULL) + if (usb_get_maximum_speed(dev) == USB_SPEED_FULL) platdata->flags |= CI_HDRC_FORCE_FULLSPEED; platdata->itc_setting = 1; diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 9e39286a4e5a..b25a111903ab 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -60,6 +60,24 @@ const char *usb_speed_string(enum usb_device_speed speed) } EXPORT_SYMBOL_GPL(usb_speed_string); +enum usb_device_speed usb_get_maximum_speed(struct device *dev) +{ + const char *maximum_speed; + int err; + int i; + + err = device_property_read_string(dev, "maximum-speed", &maximum_speed); + if (err < 0) + return USB_SPEED_UNKNOWN; + + for (i = 0; i < ARRAY_SIZE(speed_names); i++) + if (strcmp(maximum_speed, speed_names[i]) == 0) + return i; + + return USB_SPEED_UNKNOWN; +} +EXPORT_SYMBOL_GPL(usb_get_maximum_speed); + const char *usb_state_string(enum usb_device_state state) { static const char *const names[] = { @@ -113,32 +131,6 @@ enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) } EXPORT_SYMBOL_GPL(of_usb_get_dr_mode); -/** - * of_usb_get_maximum_speed - Get maximum requested speed for a given USB - * controller. - * @np: Pointer to the given device_node - * - * The function gets the maximum speed string from property "maximum-speed", - * and returns the corresponding enum usb_device_speed. - */ -enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np) -{ - const char *maximum_speed; - int err; - int i; - - err = of_property_read_string(np, "maximum-speed", &maximum_speed); - if (err < 0) - return USB_SPEED_UNKNOWN; - - for (i = 0; i < ARRAY_SIZE(speed_names); i++) - if (strcmp(maximum_speed, speed_names[i]) == 0) - return i; - - return USB_SPEED_UNKNOWN; -} -EXPORT_SYMBOL_GPL(of_usb_get_maximum_speed); - /** * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported * for given targeted hosts (non-PC hosts) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index cfbcebe2cf8f..61a56357baf0 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -870,8 +870,9 @@ static int dwc3_probe(struct platform_device *pdev) */ hird_threshold = 12; + dwc->maximum_speed = usb_get_maximum_speed(dev); + if (node) { - dwc->maximum_speed = of_usb_get_maximum_speed(node); dwc->has_lpm_erratum = of_property_read_bool(node, "snps,has-lpm-erratum"); of_property_read_u8(node, "snps,lpm-nyet-threshold", diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index c8b2ec9a79d6..c6a69eaf280f 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -747,7 +747,7 @@ static int dsps_create_musb_pdev(struct dsps_glue *glue, if (!ret && val) config->multipoint = true; - config->maximum_speed = of_usb_get_maximum_speed(dn); + config->maximum_speed = usb_get_maximum_speed(&parent->dev); switch (config->maximum_speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index 27603bcbb9b9..6cc96bb12ddc 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h @@ -32,9 +32,9 @@ #ifndef __LINUX_USB_CH9_H #define __LINUX_USB_CH9_H +#include #include - /** * usb_speed_string() - Returns human readable-name of the speed. * @speed: The speed to return human-readable name for. If it's not @@ -43,6 +43,15 @@ */ extern const char *usb_speed_string(enum usb_device_speed speed); +/** + * usb_get_maximum_speed - Get maximum requested speed for a given USB + * controller. + * @dev: Pointer to the given USB controller device + * + * The function gets the maximum speed string from property "maximum-speed", + * and returns the corresponding enum usb_device_speed. + */ +extern enum usb_device_speed usb_get_maximum_speed(struct device *dev); /** * usb_state_string - Returns human readable name for the state. diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index 8c5a818ec244..ff23fea49fca 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -13,7 +13,6 @@ #if IS_ENABLED(CONFIG_OF) enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np); -enum usb_device_speed of_usb_get_maximum_speed(struct device_node *np); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); @@ -23,11 +22,6 @@ static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) return USB_DR_MODE_UNKNOWN; } -static inline enum usb_device_speed -of_usb_get_maximum_speed(struct device_node *np) -{ - return USB_SPEED_UNKNOWN; -} static inline bool of_usb_host_tpl_support(struct device_node *np) { return false; -- cgit v1.2.3 From 666472733b8ce20716037c0d866395db54aa8c1d Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 11:14:33 +0300 Subject: usb: dwc3: st: prepare the driver for generic usb_get_dr_mode function of_usb_get_dr_mode will be converted into more generic usb_get_dr_mode function that will take struct device instead of struct device_node as its parameter. To make the conversion possible later, waiting for the platform device for dwc3 to be populated before calling of_usb_get_dr_mode. Signed-off-by: Heikki Krogerus CC: Giuseppe Cavallaro CC: Peter Griffin Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-st.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index de4d52f62517..02d47d50905b 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -195,6 +195,7 @@ static int st_dwc3_probe(struct platform_device *pdev) struct resource *res; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node, *child; + struct platform_device *child_pdev; struct regmap *regmap; int ret; @@ -253,8 +254,6 @@ static int st_dwc3_probe(struct platform_device *pdev) goto undo_softreset; } - dwc3_data->dr_mode = of_usb_get_dr_mode(child); - /* Allocate and initialize the core */ ret = of_platform_populate(node, NULL, NULL, dev); if (ret) { @@ -262,6 +261,15 @@ static int st_dwc3_probe(struct platform_device *pdev) goto undo_softreset; } + child_pdev = of_find_device_by_node(child); + if (!child_pdev) { + dev_err(dev, "failed to find dwc3 core device\n"); + ret = -ENODEV; + goto undo_softreset; + } + + dwc3_data->dr_mode = of_usb_get_dr_mode(child_pdev->dev.of_node); + /* * Configure the USB port as device or host according to the static * configuration passed from DT. -- cgit v1.2.3 From 06e7114f0d8297278eb24f4e9bee3393a94bd8ce Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 11:14:34 +0300 Subject: usb: common: of_usb_get_dr_mode to usb_get_dr_mode By using the unified device property interface, the function can be made available for all platforms and not just the ones using DT. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/core.c | 2 +- drivers/usb/common/common.c | 15 ++++----------- drivers/usb/dwc2/platform.c | 2 +- drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/dwc3-st.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/sunxi.c | 2 +- drivers/usb/phy/phy-msm-usb.c | 2 +- drivers/usb/phy/phy-tegra-usb.c | 2 +- include/linux/usb/of.h | 6 ------ include/linux/usb/otg.h | 9 +++++++++ 11 files changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ce7153232425..bf2599757f55 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -611,7 +611,7 @@ static int ci_get_platdata(struct device *dev, platdata->phy_mode = of_usb_get_phy_mode(dev->of_node); if (!platdata->dr_mode) - platdata->dr_mode = of_usb_get_dr_mode(dev->of_node); + platdata->dr_mode = usb_get_dr_mode(dev); if (platdata->dr_mode == USB_DR_MODE_UNKNOWN) platdata->dr_mode = USB_DR_MODE_OTG; diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index b25a111903ab..673d53038ed2 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -99,7 +99,6 @@ const char *usb_state_string(enum usb_device_state state) } EXPORT_SYMBOL_GPL(usb_state_string); -#ifdef CONFIG_OF static const char *const usb_dr_modes[] = { [USB_DR_MODE_UNKNOWN] = "", [USB_DR_MODE_HOST] = "host", @@ -107,19 +106,12 @@ static const char *const usb_dr_modes[] = { [USB_DR_MODE_OTG] = "otg", }; -/** - * of_usb_get_dr_mode - Get dual role mode for given device_node - * @np: Pointer to the given device_node - * - * The function gets phy interface string from property 'dr_mode', - * and returns the correspondig enum usb_dr_mode - */ -enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) +enum usb_dr_mode usb_get_dr_mode(struct device *dev) { const char *dr_mode; int err, i; - err = of_property_read_string(np, "dr_mode", &dr_mode); + err = device_property_read_string(dev, "dr_mode", &dr_mode); if (err < 0) return USB_DR_MODE_UNKNOWN; @@ -129,8 +121,9 @@ enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) return USB_DR_MODE_UNKNOWN; } -EXPORT_SYMBOL_GPL(of_usb_get_dr_mode); +EXPORT_SYMBOL_GPL(usb_get_dr_mode); +#ifdef CONFIG_OF /** * of_usb_host_tpl_support - to get if Targeted Peripheral List is supported * for given targeted hosts (non-PC hosts) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 3d1f82def2f3..28abd1f90900 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -220,7 +220,7 @@ static int dwc2_driver_probe(struct platform_device *dev) dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", (unsigned long)res->start, hsotg->regs); - hsotg->dr_mode = of_usb_get_dr_mode(dev->dev.of_node); + hsotg->dr_mode = usb_get_dr_mode(&dev->dev); /* * Attempt to find a generic PHY, then look for an old style diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 61a56357baf0..407151465645 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -871,6 +871,7 @@ static int dwc3_probe(struct platform_device *pdev) hird_threshold = 12; dwc->maximum_speed = usb_get_maximum_speed(dev); + dwc->dr_mode = usb_get_dr_mode(dev); if (node) { dwc->has_lpm_erratum = of_property_read_bool(node, @@ -886,7 +887,6 @@ static int dwc3_probe(struct platform_device *pdev) dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize"); - dwc->dr_mode = of_usb_get_dr_mode(node); dwc->disable_scramble_quirk = of_property_read_bool(node, "snps,disable_scramble_quirk"); diff --git a/drivers/usb/dwc3/dwc3-st.c b/drivers/usb/dwc3/dwc3-st.c index 02d47d50905b..5c0adb9c6fb2 100644 --- a/drivers/usb/dwc3/dwc3-st.c +++ b/drivers/usb/dwc3/dwc3-st.c @@ -268,7 +268,7 @@ static int st_dwc3_probe(struct platform_device *pdev) goto undo_softreset; } - dwc3_data->dr_mode = of_usb_get_dr_mode(child_pdev->dev.of_node); + dwc3_data->dr_mode = usb_get_dr_mode(&child_pdev->dev); /* * Configure the USB port as device or host according to the static diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index c6a69eaf280f..eeb7d9ecf7df 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -666,7 +666,7 @@ static int get_musb_port_mode(struct device *dev) { enum usb_dr_mode mode; - mode = of_usb_get_dr_mode(dev->of_node); + mode = usb_get_dr_mode(dev); switch (mode) { case USB_DR_MODE_HOST: return MUSB_PORT_MODE_HOST; diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index f9f6304ad854..f11b8f681b30 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -617,7 +617,7 @@ static int sunxi_musb_probe(struct platform_device *pdev) return -ENOMEM; memset(&pdata, 0, sizeof(pdata)); - switch (of_usb_get_dr_mode(np)) { + switch (usb_get_dr_mode(&pdev->dev)) { #if defined CONFIG_USB_MUSB_DUAL_ROLE || defined CONFIG_USB_MUSB_HOST case USB_DR_MODE_HOST: pdata.mode = MUSB_PORT_MODE_HOST; diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index c58c3c0dbe35..80eb991c2506 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1529,7 +1529,7 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) if (IS_ERR(motg->phy_rst)) motg->phy_rst = NULL; - pdata->mode = of_usb_get_dr_mode(node); + pdata->mode = usb_get_dr_mode(&pdev->dev); if (pdata->mode == USB_DR_MODE_UNKNOWN) pdata->mode = USB_DR_MODE_OTG; diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index ab025b00964c..5fe4a5704bde 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -1029,7 +1029,7 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) } if (of_find_property(np, "dr_mode", NULL)) - tegra_phy->mode = of_usb_get_dr_mode(np); + tegra_phy->mode = usb_get_dr_mode(&pdev->dev); else tegra_phy->mode = USB_DR_MODE_HOST; diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index ff23fea49fca..c3fe9e48ce27 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -12,16 +12,10 @@ #include #if IS_ENABLED(CONFIG_OF) -enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); #else -static inline enum usb_dr_mode of_usb_get_dr_mode(struct device_node *np) -{ - return USB_DR_MODE_UNKNOWN; -} - static inline bool of_usb_host_tpl_support(struct device_node *np) { return false; diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index bd1dcf816100..67929df86df5 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -119,4 +119,13 @@ enum usb_dr_mode { USB_DR_MODE_OTG, }; +/** + * usb_get_dr_mode - Get dual role mode for given device + * @dev: Pointer to the given device + * + * The function gets phy interface string from property 'dr_mode', + * and returns the correspondig enum usb_dr_mode + */ +extern enum usb_dr_mode usb_get_dr_mode(struct device *dev); + #endif /* __LINUX_USB_OTG_H */ -- cgit v1.2.3 From 3d128919b7e514f0e489ab863c572a1e7032276a Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 11:14:35 +0300 Subject: usb: dwc3: core: convert to unified device property interface No functional affect on existing platforms, but the driver is now ready to extract the properties also from ACPI tables as well as from DT. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 50 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 407151465645..c72c8c5c1c5a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -800,7 +800,6 @@ static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dwc3_platform_data *pdata = dev_get_platdata(dev); - struct device_node *node = dev->of_node; struct resource *res; struct dwc3 *dwc; u8 lpm_nyet_threshold; @@ -873,52 +872,51 @@ static int dwc3_probe(struct platform_device *pdev) dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->dr_mode = usb_get_dr_mode(dev); - if (node) { - dwc->has_lpm_erratum = of_property_read_bool(node, + dwc->has_lpm_erratum = device_property_read_bool(dev, "snps,has-lpm-erratum"); - of_property_read_u8(node, "snps,lpm-nyet-threshold", + device_property_read_u8(dev, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); - dwc->is_utmi_l1_suspend = of_property_read_bool(node, + dwc->is_utmi_l1_suspend = device_property_read_bool(dev, "snps,is-utmi-l1-suspend"); - of_property_read_u8(node, "snps,hird-threshold", + device_property_read_u8(dev, "snps,hird-threshold", &hird_threshold); - dwc->usb3_lpm_capable = of_property_read_bool(node, + dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); - dwc->needs_fifo_resize = of_property_read_bool(node, + dwc->needs_fifo_resize = device_property_read_bool(dev, "tx-fifo-resize"); - dwc->disable_scramble_quirk = of_property_read_bool(node, + dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); - dwc->u2exit_lfps_quirk = of_property_read_bool(node, + dwc->u2exit_lfps_quirk = device_property_read_bool(dev, "snps,u2exit_lfps_quirk"); - dwc->u2ss_inp3_quirk = of_property_read_bool(node, + dwc->u2ss_inp3_quirk = device_property_read_bool(dev, "snps,u2ss_inp3_quirk"); - dwc->req_p1p2p3_quirk = of_property_read_bool(node, + dwc->req_p1p2p3_quirk = device_property_read_bool(dev, "snps,req_p1p2p3_quirk"); - dwc->del_p1p2p3_quirk = of_property_read_bool(node, + dwc->del_p1p2p3_quirk = device_property_read_bool(dev, "snps,del_p1p2p3_quirk"); - dwc->del_phy_power_chg_quirk = of_property_read_bool(node, + dwc->del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,del_phy_power_chg_quirk"); - dwc->lfps_filter_quirk = of_property_read_bool(node, + dwc->lfps_filter_quirk = device_property_read_bool(dev, "snps,lfps_filter_quirk"); - dwc->rx_detect_poll_quirk = of_property_read_bool(node, + dwc->rx_detect_poll_quirk = device_property_read_bool(dev, "snps,rx_detect_poll_quirk"); - dwc->dis_u3_susphy_quirk = of_property_read_bool(node, + dwc->dis_u3_susphy_quirk = device_property_read_bool(dev, "snps,dis_u3_susphy_quirk"); - dwc->dis_u2_susphy_quirk = of_property_read_bool(node, + dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); - dwc->tx_de_emphasis_quirk = of_property_read_bool(node, + dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); - of_property_read_u8(node, "snps,tx_de_emphasis", + device_property_read_u8(dev, "snps,tx_de_emphasis", &tx_de_emphasis); - of_property_read_string(node, "snps,hsphy_interface", - &dwc->hsphy_interface); - of_property_read_u32(node, - "snps,quirk-frame-length-adjustment", - &fladj); - } else if (pdata) { + device_property_read_string(dev, "snps,hsphy_interface", + &dwc->hsphy_interface); + device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", + &fladj); + + if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; if (pdata->lpm_nyet_threshold) -- cgit v1.2.3 From 9caeb06ebd4687bc40a67d94facabb2d31c702ce Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 11:14:36 +0300 Subject: usb: dwc3: pci: passing forward the ACPI companion Sharing the ACPI companion with dwc3 core so it has access to the properties defined for DWC3 in ACPI tables. Signed-off-by: Heikki Krogerus Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index f62617999f3c..89eb3642a78e 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -154,6 +154,7 @@ static int dwc3_pci_probe(struct pci_dev *pci, goto err; dwc3->dev.parent = dev; + ACPI_COMPANION_SET(&dwc3->dev, ACPI_COMPANION(dev)); ret = platform_device_add(dwc3); if (ret) { -- cgit v1.2.3 From 9903b6bedd389a033a3da0308f220571c7f68e7a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Sep 2015 10:45:47 -0500 Subject: usb: gadget: pch-udc: fix lock gadget methods should be called without spinlocks held. Reported-by: Alexey Khoroshilov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pch_udc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index e5f4c5274298..3181fc9c1c49 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_US) { if (dev->driver && dev->driver->suspend) { - spin_lock(&dev->lock); - dev->driver->suspend(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); } vbus = pch_vbus_gpio_get_value(dev); if ((dev->vbus_session == 0) && (vbus != 1)) { if (dev->driver && dev->driver->disconnect) { - spin_lock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); } pch_udc_reconnect(dev); } else if ((dev->vbus_session == 0) -- cgit v1.2.3 From 8a1a9c9e4503f246b1d4339c5be3485e14c31858 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Sep 2015 14:32:00 -0500 Subject: usb: dwc3: gadget: start transfer on XFER_COMPLETE if by the time we get to XFER_COMPLETE we have pending requests to be processed, instead of waiting for a following XFER_NOT_READY, let's start the request right away and, maybe, save the time of a few NAKs due to lack of started transfers. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 201e12342447..c57e2002bcff 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1967,6 +1967,14 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, dwc->u1u2 = 0; } + + if (is_xfer_complete && !usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + int ret; + + ret = __dwc3_gadget_kick_transfer(dep, 0, 1); + if (!ret || ret == -EBUSY) + return; + } } static void dwc3_endpoint_interrupt(struct dwc3 *dwc, -- cgit v1.2.3 From 6bb4fe12ea089da98b89dc2630d2273d60fe0c29 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Sep 2015 14:49:02 -0500 Subject: usb: dwc3: gadget: use update transfer command If we get a Xfer Not Ready event with reason "Transfer Active" it means endpoint is still transferring data and we can use that to issue update transfer for this particular endpoint in case we have pending requests in our queue. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c57e2002bcff..ee3d05fa674d 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2012,15 +2012,16 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { dwc3_gadget_start_isoc(dwc, dep, event); } else { + int active; int ret; + active = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; + dwc3_trace(trace_dwc3_gadget, "%s: reason %s", - dep->name, event->status & - DEPEVT_STATUS_TRANSFER_ACTIVE - ? "Transfer Active" + dep->name, active ? "Transfer Active" : "Transfer Not Active"); - ret = __dwc3_gadget_kick_transfer(dep, 0, 1); + ret = __dwc3_gadget_kick_transfer(dep, 0, !active); if (!ret || ret == -EBUSY) return; -- cgit v1.2.3 From e6e709b7ab89a0d9ec0d803cb2f3b66902145ba0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Sep 2015 15:16:56 -0500 Subject: usb: dwc3: gadget: use Update Transfer from Xfer In Progress Instead of limiting __dwc3_gadget_kick_transfer() to Xfer Complete, we can try to issue Update Transfer command from Xfer In Progress too. 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 ee3d05fa674d..81bfb9ad1e2e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1968,10 +1968,10 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc, dwc->u1u2 = 0; } - if (is_xfer_complete && !usb_endpoint_xfer_isoc(dep->endpoint.desc)) { + if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) { int ret; - ret = __dwc3_gadget_kick_transfer(dep, 0, 1); + ret = __dwc3_gadget_kick_transfer(dep, 0, is_xfer_complete); if (!ret || ret == -EBUSY) return; } -- cgit v1.2.3 From 70f3a9caa11665e9f9aace581d85d8483716a4c8 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 28 Sep 2015 15:18:33 -0500 Subject: usb: dwc3: gadget: remove unnecessary _irqsave() We *know* our threads executes with our IRQs disabled. We really don't need to use the _irqsave() variant of spin_lock(). Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 81bfb9ad1e2e..cca806e09e5b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2642,16 +2642,15 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) { struct dwc3 *dwc = _dwc; - unsigned long flags; irqreturn_t ret = IRQ_NONE; int i; - spin_lock_irqsave(&dwc->lock, flags); + spin_lock(&dwc->lock); for (i = 0; i < dwc->num_event_buffers; i++) ret |= dwc3_process_event_buf(dwc, i); - spin_unlock_irqrestore(&dwc->lock, flags); + spin_unlock(&dwc->lock); return ret; } -- cgit v1.2.3 From cc047ce4be6188d3bd3997b44ec724ce390fbdcb Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:37 +0200 Subject: usb: dwc2: host: don't clear hprt0 status bits when exiting hibernation When entering hibernation hprt0 must be read using dwc2_read_hprt0(). Otherwise, any set hprt0 status bits will be cleared when restoring hprt0 on exit from hibernation. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index fc0521aeed77..0bfc987dd373 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -78,7 +78,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) for (i = 0; i < hsotg->core_params->host_channels; ++i) hr->hcintmsk[i] = dwc2_readl(hsotg->regs + HCINTMSK(i)); - hr->hprt0 = dwc2_readl(hsotg->regs + HPRT0); + hr->hprt0 = dwc2_read_hprt0(hsotg); hr->hfir = dwc2_readl(hsotg->regs + HFIR); hr->valid = true; -- cgit v1.2.3 From 30db103c3ddeb0b616eedb8fd030b88efb1af96f Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:38 +0200 Subject: usb: dwc2: host: create a function to handle port_resume port resume sequence may be used in different places. Create a function to handle it. Make hprt0 read-modify-write atomic and clear HPRT0_SUSP for both writes as it is a "read, write-set, and self-clear (R_WS_SC)" bit. Since the lock is released between the writes, read hprt0 again. Since the phy clock is stopped in dwc2_port_suspend(), enable it here and remove the PCGCTL write from dwc2_hcd_hub_control() Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1595d7061f2c..b929087f26f2 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1484,6 +1484,35 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) } } +/* Must NOT be called with interrupt disabled or spinlock held */ +static void dwc2_port_resume(struct dwc2_hsotg *hsotg) +{ + unsigned long flags; + u32 hprt0; + u32 pcgctl; + + /* Resume the Phy Clock */ + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); + pcgctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); + usleep_range(20000, 40000); + + spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_RES; + hprt0 &= ~HPRT0_SUSP; + dwc2_writel(hprt0, hsotg->regs + HPRT0); + spin_unlock_irqrestore(&hsotg->lock, flags); + + msleep(USB_RESUME_TIMEOUT); + + spin_lock_irqsave(&hsotg->lock, flags); + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 &= ~(HPRT0_RES | HPRT0_SUSP); + dwc2_writel(hprt0, hsotg->regs + HPRT0); + spin_unlock_irqrestore(&hsotg->lock, flags); +} + /* Handles hub class-specific requests */ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, u16 wvalue, u16 windex, char *buf, u16 wlength) @@ -1529,17 +1558,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, case USB_PORT_FEAT_SUSPEND: dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - dwc2_writel(0, hsotg->regs + PCGCTL); - usleep_range(20000, 40000); - hprt0 = dwc2_read_hprt0(hsotg); - hprt0 |= HPRT0_RES; - dwc2_writel(hprt0, hsotg->regs + HPRT0); - hprt0 &= ~HPRT0_SUSP; - msleep(USB_RESUME_TIMEOUT); - - hprt0 &= ~HPRT0_RES; - dwc2_writel(hprt0, hsotg->regs + HPRT0); + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: -- cgit v1.2.3 From 734643dfbdde7dd881b2c16404a86f444287414e Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:39 +0200 Subject: usb: dwc2: host: add flag to reflect bus state lx_state must be used to reflect controller power state only and not bus state. Thus add a flag to track state during bus suspend. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/hcd.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 1a7982dbdad5..d2115d2a3db2 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -764,6 +764,7 @@ struct dwc2_hsotg { u16 frame_usecs[8]; u16 frame_number; u16 periodic_qh_count; + bool bus_suspended; #ifdef CONFIG_USB_DWC2_TRACK_MISSED_SOFS #define FRAME_NUM_ARRAY_SIZE 1000 diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index b929087f26f2..490ecb74382c 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1425,6 +1425,7 @@ static void dwc2_wakeup_detected(unsigned long data) dev_dbg(hsotg->dev, "Clear Resume: HPRT0=%0x\n", dwc2_readl(hsotg->regs + HPRT0)); + hsotg->bus_suspended = 0; dwc2_hcd_rem_wakeup(hsotg); /* Change to L0 state */ @@ -1461,8 +1462,7 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) hprt0 |= HPRT0_SUSP; dwc2_writel(hprt0, hsotg->regs + HPRT0); - /* Update lx_state */ - hsotg->lx_state = DWC2_L2; + hsotg->bus_suspended = 1; /* Suspend the Phy Clock */ pcgctl = dwc2_readl(hsotg->regs + PCGCTL); @@ -1510,6 +1510,7 @@ static void dwc2_port_resume(struct dwc2_hsotg *hsotg) hprt0 = dwc2_read_hprt0(hsotg); hprt0 &= ~(HPRT0_RES | HPRT0_SUSP); dwc2_writel(hprt0, hsotg->regs + HPRT0); + hsotg->bus_suspended = 0; spin_unlock_irqrestore(&hsotg->lock, flags); } -- cgit v1.2.3 From a2a23d3f9e6f44f900e4c4b4cd58f22490c3c200 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:40 +0200 Subject: usb: dwc2: host: enter hibernation during bus suspend Disable controller power and enter hibernation when usb bus is suspended. A phy driver is required to disable the power of the controller and detect remote-wakeup or disconnection since the controller will not be able to detect these in this state. Once the phy driver detects bus activity, it must call usb_hcd_resume_root_hub. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 140 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 128 insertions(+), 12 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 490ecb74382c..459b441e4838 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1464,11 +1464,17 @@ static void dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex) hsotg->bus_suspended = 1; - /* Suspend the Phy Clock */ - pcgctl = dwc2_readl(hsotg->regs + PCGCTL); - pcgctl |= PCGCTL_STOPPCLK; - dwc2_writel(pcgctl, hsotg->regs + PCGCTL); - udelay(10); + /* + * If hibernation is supported, Phy clock will be suspended + * after registers are backuped. + */ + if (!hsotg->core_params->hibernation) { + /* Suspend the Phy Clock */ + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); + pcgctl |= PCGCTL_STOPPCLK; + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); + udelay(10); + } /* For HNP the bus must be suspended for at least 200ms */ if (dwc2_host_is_b_hnp_enabled(hsotg)) { @@ -1491,11 +1497,16 @@ static void dwc2_port_resume(struct dwc2_hsotg *hsotg) u32 hprt0; u32 pcgctl; - /* Resume the Phy Clock */ - pcgctl = dwc2_readl(hsotg->regs + PCGCTL); - pcgctl &= ~PCGCTL_STOPPCLK; - dwc2_writel(pcgctl, hsotg->regs + PCGCTL); - usleep_range(20000, 40000); + /* + * If hibernation is supported, Phy clock is already resumed + * after registers restore. + */ + if (!hsotg->core_params->hibernation) { + pcgctl = dwc2_readl(hsotg->regs + PCGCTL); + pcgctl &= ~PCGCTL_STOPPCLK; + dwc2_writel(pcgctl, hsotg->regs + PCGCTL); + usleep_range(20000, 40000); + } spin_lock_irqsave(&hsotg->lock, flags); hprt0 = dwc2_read_hprt0(hsotg); @@ -2347,17 +2358,122 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) static int _dwc2_hcd_suspend(struct usb_hcd *hcd) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + unsigned long flags; + int ret = 0; + u32 hprt0; + + spin_lock_irqsave(&hsotg->lock, flags); + + if (hsotg->lx_state != DWC2_L0) + goto unlock; + + if (!HCD_HW_ACCESSIBLE(hcd)) + goto unlock; + + if (!hsotg->core_params->hibernation) + goto skip_power_saving; + + /* + * Drive USB suspend and disable port Power + * if usb bus is not suspended. + */ + if (!hsotg->bus_suspended) { + hprt0 = dwc2_read_hprt0(hsotg); + hprt0 |= HPRT0_SUSP; + hprt0 &= ~HPRT0_PWR; + dwc2_writel(hprt0, hsotg->regs + HPRT0); + } + + /* Enter hibernation */ + ret = dwc2_enter_hibernation(hsotg); + if (ret) { + if (ret != -ENOTSUPP) + dev_err(hsotg->dev, + "enter hibernation failed\n"); + goto skip_power_saving; + } + + /* Ask phy to be suspended */ + if (!IS_ERR_OR_NULL(hsotg->uphy)) { + spin_unlock_irqrestore(&hsotg->lock, flags); + usb_phy_set_suspend(hsotg->uphy, true); + spin_lock_irqsave(&hsotg->lock, flags); + } + + /* After entering hibernation, hardware is no more accessible */ + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +skip_power_saving: hsotg->lx_state = DWC2_L2; - return 0; +unlock: + spin_unlock_irqrestore(&hsotg->lock, flags); + + return ret; } static int _dwc2_hcd_resume(struct usb_hcd *hcd) { struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hsotg->lock, flags); + + if (hsotg->lx_state != DWC2_L2) + goto unlock; + + if (!hsotg->core_params->hibernation) { + hsotg->lx_state = DWC2_L0; + goto unlock; + } + + /* + * Set HW accessible bit before powering on the controller + * since an interrupt may rise. + */ + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + /* + * Enable power if not already done. + * This must not be spinlocked since duration + * of this call is unknown. + */ + if (!IS_ERR_OR_NULL(hsotg->uphy)) { + spin_unlock_irqrestore(&hsotg->lock, flags); + usb_phy_set_suspend(hsotg->uphy, false); + spin_lock_irqsave(&hsotg->lock, flags); + } + + /* Exit hibernation */ + ret = dwc2_exit_hibernation(hsotg, true); + if (ret && (ret != -ENOTSUPP)) + dev_err(hsotg->dev, "exit hibernation failed\n"); hsotg->lx_state = DWC2_L0; - return 0; + + spin_unlock_irqrestore(&hsotg->lock, flags); + + if (hsotg->bus_suspended) { + spin_lock_irqsave(&hsotg->lock, flags); + hsotg->flags.b.port_suspend_change = 1; + spin_unlock_irqrestore(&hsotg->lock, flags); + dwc2_port_resume(hsotg); + } else { + /* + * Clear Port Enable and Port Status changes. + * Enable Port Power. + */ + dwc2_writel(HPRT0_PWR | HPRT0_CONNDET | + HPRT0_ENACHG, hsotg->regs + HPRT0); + /* Wait for controller to detect Port Connect */ + mdelay(5); + } + + return ret; +unlock: + spin_unlock_irqrestore(&hsotg->lock, flags); + + return ret; } /* Returns the current frame number */ -- cgit v1.2.3 From 31927b6b68acd21258b1f4ef24464acae60cfd36 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:41 +0200 Subject: usb: dwc2: host: update hcd and lx_state during start/stop callbacks During hcd initialization, hardware accessible flag and lx_state must be reset to the working state since controller is powered at this stage. Same logic applied for stop callback. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 459b441e4838..65ae0a390600 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2318,8 +2318,9 @@ static int _dwc2_hcd_start(struct usb_hcd *hcd) dev_dbg(hsotg->dev, "DWC OTG HCD START\n"); spin_lock_irqsave(&hsotg->lock, flags); - + hsotg->lx_state = DWC2_L0; hcd->state = HC_STATE_RUNNING; + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (dwc2_is_device_mode(hsotg)) { spin_unlock_irqrestore(&hsotg->lock, flags); @@ -2350,6 +2351,9 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) spin_lock_irqsave(&hsotg->lock, flags); dwc2_hcd_stop(hsotg); + hsotg->lx_state = DWC2_L3; + hcd->state = HC_STATE_HALT; + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); spin_unlock_irqrestore(&hsotg->lock, flags); usleep_range(1000, 3000); -- cgit v1.2.3 From 9afaf75508b0bec6ef38b83d97aa40701cc1b00c Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:42 +0200 Subject: usb: dwc2: host: avoid resetting lx_state to L3 during disconnect When a device is disconnected, lx_state must not be changed since the device may be disconnected whereas controller is still powered. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core_intr.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index a6b16139850d..3275310a8fb3 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -387,9 +387,6 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg) if (hsotg->op_state == OTG_STATE_A_HOST) dwc2_hcd_disconnect(hsotg); - /* Change to L3 (OFF) state */ - hsotg->lx_state = DWC2_L3; - dwc2_writel(GINTSTS_DISCONNINT, hsotg->regs + GINTSTS); } -- cgit v1.2.3 From 6e74162f69c7fb6f60941ea7e94f1264bd6225fb Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:43 +0200 Subject: usb: dwc2: host: ignore wakeup interrupt if hibernation supported If hibernation is supported, resume of devices will be handled in bus_resume callback. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core_intr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index 3275310a8fb3..d8a5400a2d2d 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -356,6 +356,10 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg) /* Change to L0 state */ hsotg->lx_state = DWC2_L0; } else { + if (hsotg->core_params->hibernation) { + dwc2_writel(GINTSTS_WKUPINT, hsotg->regs + GINTSTS); + return; + } if (hsotg->lx_state != DWC2_L1) { u32 pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); -- cgit v1.2.3 From bea78555f71e01196d0a4613ffefd4c8920ba439 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:44 +0200 Subject: usb: dwc2: host: resume only if bus is suspended Port can be resumed in bus_resume callback. In this case, there is no need to drive resume a second time when hcd ask for it. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 65ae0a390600..856e21cb6683 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1571,7 +1571,8 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq, dev_dbg(hsotg->dev, "ClearPortFeature USB_PORT_FEAT_SUSPEND\n"); - dwc2_port_resume(hsotg); + if (hsotg->bus_suspended) + dwc2_port_resume(hsotg); break; case USB_PORT_FEAT_POWER: -- cgit v1.2.3 From 08c4ffc24087d1949948002abdbac0d1e71ade5d Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:45 +0200 Subject: usb: dwc2: host: reset frame number after suspend Frame number is reset in hardware after exiting hibernation. Thus, reset frame_number and ensure qh are queued with correct sched_frame. Otherwise, qh->sched_frame may be too high compared to current frame number (which is 0). This can delay addition of qh in the list of transfers until frame number reaches qh->sched_frame. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 1 + drivers/usb/dwc2/hcd_queue.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 0bfc987dd373..f5c3120f4879 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -116,6 +116,7 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) dwc2_writel(hr->hprt0, hsotg->regs + HPRT0); dwc2_writel(hr->hfir, hsotg->regs + HFIR); + hsotg->frame_number = 0; return 0; } diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 712977fd67d1..801bd9d9c4bd 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -583,6 +583,14 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) /* QH already in a schedule */ return 0; + if (!dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number) && + !hsotg->frame_number) { + dev_dbg(hsotg->dev, + "reset frame number counter\n"); + qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number, + SCHEDULE_SLOP); + } + /* Add the new QH to the appropriate schedule */ if (dwc2_qh_is_non_per(qh)) { /* Always start in inactive schedule */ -- cgit v1.2.3 From 091473ad9b402f9e1b08a68a78b54e0d3c9affb6 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:46 +0200 Subject: usb: dwc2: host: disconnect hcd prior stopping it In case controller is asked to stop while devices are connected, disconnect all devices and clean up before stopping. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 856e21cb6683..257f9579705d 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2350,7 +2350,12 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); unsigned long flags; + /* Wait for interrupt processing to finish */ + synchronize_irq(hcd->irq); + spin_lock_irqsave(&hsotg->lock, flags); + /* Ensure hcd is disconnected */ + dwc2_hcd_disconnect(hsotg); dwc2_hcd_stop(hsotg); hsotg->lx_state = DWC2_L3; hcd->state = HC_STATE_HALT; -- cgit v1.2.3 From 77dbf7138d59994d50b7875deb24992f51b811b5 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 22 Sep 2015 15:16:47 +0200 Subject: usb: dwc2: host: add disconnect interrupt to host only interrupts GINTSTS.DisconnInt is host only interrupt and should be disable after dwc2_disable_host_interrupts is called. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index f5c3120f4879..c5e0a45c565d 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -857,7 +857,8 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) /* Enable host mode interrupts without disturbing common interrupts */ intmsk = dwc2_readl(hsotg->regs + GINTMSK); - intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT; + intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT | + GINTSTS_DISCONNINT; dwc2_writel(intmsk, hsotg->regs + GINTMSK); } @@ -872,7 +873,7 @@ void dwc2_disable_host_interrupts(struct dwc2_hsotg *hsotg) /* Disable host mode interrupts without disturbing common interrupts */ intmsk &= ~(GINTSTS_SOF | GINTSTS_PRTINT | GINTSTS_HCHINT | - GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP); + GINTSTS_PTXFEMP | GINTSTS_NPTXFEMP | GINTSTS_DISCONNINT); dwc2_writel(intmsk, hsotg->regs + GINTMSK); } -- cgit v1.2.3 From 5bbf6ce0a964c77d9522cf377fd7a4c4af030378 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:48 +0200 Subject: usb: dwc2: host: disable interrupt during stop Disable host interrupts before synchronising dwc2 irq. So that interrupts are not generated once controller is stopped. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 257f9579705d..de9d2e2bbf48 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2350,6 +2350,9 @@ static void _dwc2_hcd_stop(struct usb_hcd *hcd) struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); unsigned long flags; + /* Turn off all host-specific interrupts */ + dwc2_disable_host_interrupts(hsotg); + /* Wait for interrupt processing to finish */ synchronize_irq(hcd->irq); -- cgit v1.2.3 From cad73da26cb9392db3449ab35e506ea13efd1888 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:49 +0200 Subject: usb: dwc2: host: clear pending interrupts prior hibernation If an interrupt rises during hibernation process, dwc2 will assert interrupt line to interrupt controller. If interrupt is level sensitive, interrupt handler will be called in a loop because dwc2 will not be able to clear it while controller is hibernated. Thus, clear all controller interrupts before hibernation entry. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index c5e0a45c565d..bf5e951fbb7f 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -398,6 +398,12 @@ int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg) } } + /* + * Clear any pending interrupts since dwc2 will not be able to + * clear them after entering hibernation. + */ + dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); + /* Put the controller in low power state */ pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); -- cgit v1.2.3 From 5634e016cf6e2e0c9651081f5c554f59e1050fc5 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:50 +0200 Subject: usb: dwc2: host: wait 3ms for controller stabilization Some high speed mass storage devices fail to enumerate with following error: Cannot enable port %i. Maybe the USB cable is bad? This happens only when the device is plugged while the controller is in hibernation state. After exiting hibernation, the controller detects the device as a low speed device and fail to enumerate it. Problem occurs only if HPRT0.PWR bit is programmed in a too short delay after exiting hibernation. Dumping hprt register in _dwc2_hcd_resume() directly after dwc2_exit_hibernation() shows that HPRT0.LNSTS (D+/D- level) becomes valid approximately 2ms after exiting hibernation. Since dwc2_exit_hibernation() is called from atomic context, move the delay out of this function. Delay value is experimental and not mentioned in Synopsys documentation. To be on the safe side 3ms delay is used. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index de9d2e2bbf48..65044daddc13 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2472,6 +2472,9 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_port_resume(hsotg); } else { + /* Wait for controller to correctly update D+/D- level */ + usleep_range(3000, 5000); + /* * Clear Port Enable and Port Status changes. * Enable Port Power. @@ -2479,7 +2482,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) dwc2_writel(HPRT0_PWR | HPRT0_CONNDET | HPRT0_ENACHG, hsotg->regs + HPRT0); /* Wait for controller to detect Port Connect */ - mdelay(5); + usleep_range(5000, 7000); } return ret; -- cgit v1.2.3 From fe9b1773c989b261a9747940a6cf61f77b4e2685 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:51 +0200 Subject: usb: dwc2: host: correctly dump urb isochronous descriptors Print urb->iso_frame_desc.status after it has been updated using dwc2_hcd_urb_get_iso_desc_status(). Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 65044daddc13..397bb7d0d3c8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2227,11 +2227,6 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, usb_pipein(urb->pipe) ? "IN" : "OUT", status, urb->actual_length); - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) { - for (i = 0; i < urb->number_of_packets; i++) - dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n", - i, urb->iso_frame_desc[i].status); - } if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { urb->error_count = dwc2_hcd_urb_get_error_count(qtd->urb); @@ -2244,6 +2239,12 @@ void dwc2_host_complete(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, } } + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS && dbg_perio()) { + for (i = 0; i < urb->number_of_packets; i++) + dev_vdbg(hsotg->dev, " ISO Desc %d status %d\n", + i, urb->iso_frame_desc[i].status); + } + urb->status = status; if (!status) { if ((urb->transfer_flags & URB_SHORT_NOT_OK) && -- cgit v1.2.3 From dd81dd7c8178c430040dc98c8144d4998ba2f7fb Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:52 +0200 Subject: usb: dwc2: host: use correct frame number during qh init On first qh initialization, hsotg->frame_number is not corresponding to reality. So read it from host controller to get correct value. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_queue.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 801bd9d9c4bd..7d8d06cfe3c1 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -106,6 +106,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, USB_SPEED_HIGH : dev_speed, qh->ep_is_in, qh->ep_type == USB_ENDPOINT_XFER_ISOC, bytecount)); + + /* Ensure frame_number corresponds to the reality */ + hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); /* Start in a slightly future (micro)frame */ qh->sched_frame = dwc2_frame_num_inc(hsotg->frame_number, SCHEDULE_SLOP); -- cgit v1.2.3 From 2e84da6e340a652e942c3513703020976b28190b Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:53 +0200 Subject: usb: dwc2: host: kill remaining urbs using -ECONNRESET status On a disconnect, dwc2 will kill all remaining urbs from qh list. urbs are given back to hcd with -ETIMEDOUT status. Some usb device driver, like mass storage, will unlink all urbs using usb_hcd_unlink_urb when receiving a negative status different from -ECONNRESET. The following flow will then happen: dwc2_hcd_disconnect() -> dwc2_kill_all_urbs() try to kill first pending urb. -> dwc2_host_complete(-ETIMEDOUT) -> usb_hcd_giveback_urb(-ETIMEDOUT) -> sg_complete() -> usb_unlink_urb() -> usb_put_dev(urb->dev) -> dwc2_kill_all_urbs() try to kill next pending urb. -> dwc2_host_complete(-ETIMEDOUT) -> usb_hcd_giveback_urb(-ETIMEDOUT) -> NULL pointer dereferencing because urb->dev has been freed for all urbs of this device. The root cause of this NULL pointer is to call call usb_unlink_urb() while we are killing all urbs. To avoid this return urb with -ECONNRESET status This issue usually happens while removing mass storage device during transfer. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 397bb7d0d3c8..15a1e62ac902 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -134,7 +134,7 @@ static void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg, list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { - dwc2_host_complete(hsotg, qtd, -ETIMEDOUT); + dwc2_host_complete(hsotg, qtd, -ECONNRESET); dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); } } -- cgit v1.2.3 From 065d393124f06ef1f5a20a6f5f262fee2cfa873d Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 22 Sep 2015 15:16:54 +0200 Subject: usb: dwc2: gadget: ensure lx_state corresponds to current state Correctly update lx_state on gadget connection and disconnection. When usb cable is disconnected, lx_state must be updated to L3 as controller could be in power off state. When usb cable is connected, lx_state must be updated to L0 as controller is powered. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ddd14a725760..ddb54272478d 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2189,6 +2189,7 @@ void dwc2_hsotg_disconnect(struct dwc2_hsotg *hsotg) } call_gadget(hsotg, disconnect); + hsotg->lx_state = DWC2_L3; } /** @@ -2415,6 +2416,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, mdelay(3); hsotg->last_rst = jiffies; + hsotg->lx_state = DWC2_L0; } static void dwc2_hsotg_core_disconnect(struct dwc2_hsotg *hsotg) @@ -2514,7 +2516,6 @@ irq_retry: kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); - hsotg->lx_state = DWC2_L0; dwc2_hsotg_core_init_disconnected(hsotg, true); } } @@ -3205,10 +3206,9 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) * If controller is hibernated, it must exit from hibernation * before being initialized */ - if (hsotg->lx_state == DWC2_L2) { + if (hsotg->lx_state == DWC2_L2) dwc2_exit_hibernation(hsotg, false); - hsotg->lx_state = DWC2_L0; - } + /* Kill any ep0 requests as controller will be reinitialized */ kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); dwc2_hsotg_core_init_disconnected(hsotg, false); -- cgit v1.2.3 From ec4cc6579c7334fb334ba2f30214f5c41b16c6e8 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 22 Sep 2015 15:16:55 +0200 Subject: usb: dwc2: gadget: initialize op_state for peripheral only configuration ID status change interrupt will not be handled in peripheral only configuration. So initialize op_state during gadget init. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ddb54272478d..36345ab05f7e 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3535,6 +3535,8 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) hsotg->gadget.name = dev_name(dev); if (hsotg->dr_mode == USB_DR_MODE_OTG) hsotg->gadget.is_otg = 1; + else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + hsotg->op_state = OTG_STATE_B_PERIPHERAL; /* reset the system */ -- cgit v1.2.3 From 14a37ec6c181178a14ffb7d10a57b99ef8e6b3b3 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:26 +0530 Subject: usb: gadget: amd5536udc: rewrite init_dma_pools A rewrite of init_dma_pools() with proper error handling. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 175ca93fe5e2..38a68582dd6b 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3169,8 +3169,7 @@ static int init_dma_pools(struct udc *dev) sizeof(struct udc_data_dma), 0, 0); if (!dev->data_requests) { DBG(dev, "can't get request data pool\n"); - retval = -ENOMEM; - goto finished; + return -ENOMEM; } /* EP0 in dma regs = dev control regs */ @@ -3182,14 +3181,14 @@ static int init_dma_pools(struct udc *dev) if (!dev->stp_requests) { DBG(dev, "can't get stp request pool\n"); retval = -ENOMEM; - goto finished; + goto err_create_dma_pool; } /* setup */ td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_stp_dma); if (td_stp == NULL) { retval = -ENOMEM; - goto finished; + goto err_alloc_dma; } dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; @@ -3198,12 +3197,20 @@ static int init_dma_pools(struct udc *dev) &dev->ep[UDC_EP0OUT_IX].td_phys); if (td_data == NULL) { retval = -ENOMEM; - goto finished; + goto err_alloc_phys; } dev->ep[UDC_EP0OUT_IX].td = td_data; return 0; -finished: +err_alloc_phys: + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); +err_alloc_dma: + dma_pool_destroy(dev->stp_requests); + dev->stp_requests = NULL; +err_create_dma_pool: + dma_pool_destroy(dev->data_requests); + dev->data_requests = NULL; return retval; } -- cgit v1.2.3 From 580693bb3b66ce299f85f71dee60734438b1cd79 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:27 +0530 Subject: usb: gadget: amd5536udc: fix error path Handle the error properly instead of calling the pci remove function. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 38a68582dd6b..3f85044be196 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3107,6 +3107,17 @@ static void udc_remove(struct udc *dev) udc = NULL; } +/* free all the dma pools */ +static void free_dma_pools(struct udc *dev) +{ + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td, + dev->ep[UDC_EP0OUT_IX].td_phys); + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); + dma_pool_destroy(dev->stp_requests); + dma_pool_destroy(dev->data_requests); +} + /* Reset all pci context */ static void udc_pci_remove(struct pci_dev *pdev) { @@ -3297,7 +3308,7 @@ static int udc_pci_probe( if (use_dma) { retval = init_dma_pools(dev); if (retval != 0) - goto finished; + goto err_dma; } dev->phys_addr = resource; @@ -3305,13 +3316,17 @@ static int udc_pci_probe( dev->pdev = pdev; /* general probing */ - if (udc_probe(dev) == 0) - return 0; - -finished: - udc_pci_remove(pdev); - return retval; + if (udc_probe(dev)) { + retval = -ENODEV; + goto err_probe; + } + return 0; +err_probe: + if (use_dma) + free_dma_pools(dev); +err_dma: + free_irq(pdev->irq, dev); err_irq: iounmap(dev->virt_addr); err_ioremap: -- cgit v1.2.3 From 2e1b7d0c691c63c66d5bf5c097243f3b037adf32 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:28 +0530 Subject: usb: gadget: amd5536udc: use WARN_ON Use WARN_ON() instead of halting the kernel with BUG_ON() and also fix the checkpatch warning. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 3f85044be196..6223b1be029f 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3127,7 +3127,8 @@ static void udc_pci_remove(struct pci_dev *pdev) usb_del_gadget_udc(&udc->gadget); /* gadget driver must not be registered */ - BUG_ON(dev->driver != NULL); + if (WARN_ON(dev->driver)) + return; /* dma pool cleanup */ if (dev->data_requests) -- cgit v1.2.3 From f349dd3c76039a2b0bf03a11484dd2850868b7e3 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:29 +0530 Subject: usb: gadget: amd5536udc: use free_dma_pools We have the function free_dma_pools() which frees all the dma pools. Use it instead of calling all the functions separately. The if conditions for data_requests and stp_requests are also not required here as this is the remove function and we are here means probe has succeeded and dma has been successfully allocated, so they cannot be NULL here. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 6223b1be029f..7805b29bf101 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3131,20 +3131,7 @@ static void udc_pci_remove(struct pci_dev *pdev) return; /* dma pool cleanup */ - if (dev->data_requests) - pci_pool_destroy(dev->data_requests); - - if (dev->stp_requests) { - /* cleanup DMA desc's for ep0in */ - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td_stp, - dev->ep[UDC_EP0OUT_IX].td_stp_dma); - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td, - dev->ep[UDC_EP0OUT_IX].td_phys); - - pci_pool_destroy(dev->stp_requests); - } + free_dma_pools(dev); /* reset controller */ writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); -- cgit v1.2.3 From 76c3727da1e6e2bd5aa012841ea17c7664f0638b Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:30 +0530 Subject: usb: gadget: amd5536udc: remove unnecessary conditions The condition checking for irq_registered, regs, mem_region and active are not required as this is the remove function. And we are in the remove means that probe was successful and they can never be NULL at this point of code. It was required in the original code as the remove function was part of the error handler of probe function. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 17 +++++------------ drivers/usb/gadget/udc/amd5536udc.h | 5 +---- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 7805b29bf101..89e83e42fb97 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3135,15 +3135,11 @@ static void udc_pci_remove(struct pci_dev *pdev) /* reset controller */ writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - if (dev->irq_registered) - free_irq(pdev->irq, dev); - if (dev->virt_addr) - iounmap(dev->virt_addr); - if (dev->mem_region) - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (dev->active) - pci_disable_device(pdev); + free_irq(pdev->irq, dev); + iounmap(dev->virt_addr); + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + pci_disable_device(pdev); udc_remove(dev); } @@ -3240,7 +3236,6 @@ static int udc_pci_probe( retval = -ENODEV; goto err_pcidev; } - dev->active = 1; /* PCI resource allocation */ resource = pci_resource_start(pdev, 0); @@ -3251,7 +3246,6 @@ static int udc_pci_probe( retval = -EBUSY; goto err_memreg; } - dev->mem_region = 1; dev->virt_addr = ioremap_nocache(resource, len); if (dev->virt_addr == NULL) { @@ -3282,7 +3276,6 @@ static int udc_pci_probe( retval = -EBUSY; goto err_irq; } - dev->irq_registered = 1; pci_set_drvdata(pdev, dev); diff --git a/drivers/usb/gadget/udc/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h index 6744d3b83109..4638d707f169 100644 --- a/drivers/usb/gadget/udc/amd5536udc.h +++ b/drivers/usb/gadget/udc/amd5536udc.h @@ -526,14 +526,11 @@ struct udc { struct udc_ep ep[UDC_EP_NUM]; struct usb_gadget_driver *driver; /* operational flags */ - unsigned active : 1, - stall_ep0in : 1, + unsigned stall_ep0in : 1, waiting_zlp_ack_ep0in : 1, set_cfg_not_acked : 1, - irq_registered : 1, data_ep_enabled : 1, data_ep_queued : 1, - mem_region : 1, sys_suspended : 1, connected; -- cgit v1.2.3 From 4f06b6bb73be3fcdf728d7271ad05cd81df58f3d Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:31 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_probe Rearrange the udc_probe function to remove the forward declarations. While rearranging also fixed the relevant checkpatch warnings. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 133 ++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 89e83e42fb97..6c167370cd5a 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -65,7 +65,6 @@ static void udc_tasklet_disconnect(unsigned long); static void empty_req_queue(struct udc_ep *); -static int udc_probe(struct udc *dev); static void udc_basic_init(struct udc *dev); static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); @@ -3209,6 +3208,72 @@ err_create_dma_pool: return retval; } +/* general probe */ +static int udc_probe(struct udc *dev) +{ + char tmp[128]; + u32 reg; + int retval; + + /* mark timer as not initialized */ + udc_timer.data = 0; + udc_pollstall_timer.data = 0; + + /* device struct setup */ + dev->gadget.ops = &udc_ops; + + dev_set_name(&dev->gadget.dev, "gadget"); + dev->gadget.name = name; + dev->gadget.max_speed = USB_SPEED_HIGH; + + /* init registers, interrupts, ... */ + startup_registers(dev); + + dev_info(&dev->pdev->dev, "%s\n", mod_desc); + + snprintf(tmp, sizeof(tmp), "%d", dev->irq); + dev_info(&dev->pdev->dev, + "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", + tmp, dev->phys_addr, dev->chiprev, + (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); + strcpy(tmp, UDC_DRIVER_VERSION_STRING); + if (dev->chiprev == UDC_HSA0_REV) { + dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); + retval = -ENODEV; + goto finished; + } + dev_info(&dev->pdev->dev, + "driver version: %s(for Geode5536 B1)\n", tmp); + udc = dev; + + retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, + gadget_release); + if (retval) + goto finished; + + /* timer init */ + init_timer(&udc_timer); + udc_timer.function = udc_timer_function; + udc_timer.data = 1; + /* timer pollstall init */ + init_timer(&udc_pollstall_timer); + udc_pollstall_timer.function = udc_pollstall_timer_function; + udc_pollstall_timer.data = 1; + + /* set SD */ + reg = readl(&dev->regs->ctl); + reg |= AMD_BIT(UDC_DEVCTL_SD); + writel(reg, &dev->regs->ctl); + + /* print dev register info */ + print_regs(dev); + + return 0; + +finished: + return retval; +} + /* Called by pci bus driver to init pci context */ static int udc_pci_probe( struct pci_dev *pdev, @@ -3319,72 +3384,6 @@ err_pcidev: return retval; } -/* general probe */ -static int udc_probe(struct udc *dev) -{ - char tmp[128]; - u32 reg; - int retval; - - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - - /* device struct setup */ - dev->gadget.ops = &udc_ops; - - dev_set_name(&dev->gadget.dev, "gadget"); - dev->gadget.name = name; - dev->gadget.max_speed = USB_SPEED_HIGH; - - /* init registers, interrupts, ... */ - startup_registers(dev); - - dev_info(&dev->pdev->dev, "%s\n", mod_desc); - - snprintf(tmp, sizeof tmp, "%d", dev->irq); - dev_info(&dev->pdev->dev, - "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", - tmp, dev->phys_addr, dev->chiprev, - (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); - strcpy(tmp, UDC_DRIVER_VERSION_STRING); - if (dev->chiprev == UDC_HSA0_REV) { - dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); - retval = -ENODEV; - goto finished; - } - dev_info(&dev->pdev->dev, - "driver version: %s(for Geode5536 B1)\n", tmp); - udc = dev; - - retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, - gadget_release); - if (retval) - goto finished; - - /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; - - /* set SD */ - reg = readl(&dev->regs->ctl); - reg |= AMD_BIT(UDC_DEVCTL_SD); - writel(reg, &dev->regs->ctl); - - /* print dev register info */ - print_regs(dev); - - return 0; - -finished: - return retval; -} - /* Initiates a remote wakeup */ static int udc_remote_wakeup(struct udc *dev) { -- cgit v1.2.3 From 79a5b4aa3511f82e1398223062cd62051044288d Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:32 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_remote_wakeup Rearrange the udc_remote_wakeup function to remove the forward declaration. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 41 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 6c167370cd5a..f218520356ff 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -73,7 +73,6 @@ static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, unsigned long buf_len, gfp_t gfp_flags); -static int udc_remote_wakeup(struct udc *dev); static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void udc_pci_remove(struct pci_dev *pdev); @@ -1452,6 +1451,26 @@ static int udc_get_frame(struct usb_gadget *gadget) return -EOPNOTSUPP; } +/* Initiates a remote wakeup */ +static int udc_remote_wakeup(struct udc *dev) +{ + unsigned long flags; + u32 tmp; + + DBG(dev, "UDC initiates remote wakeup\n"); + + spin_lock_irqsave(&dev->lock, flags); + + tmp = readl(&dev->regs->ctl); + tmp |= AMD_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + + spin_unlock_irqrestore(&dev->lock, flags); + return 0; +} + /* Remote wakeup gadget interface */ static int udc_wakeup(struct usb_gadget *gadget) { @@ -3384,26 +3403,6 @@ err_pcidev: return retval; } -/* Initiates a remote wakeup */ -static int udc_remote_wakeup(struct udc *dev) -{ - unsigned long flags; - u32 tmp; - - DBG(dev, "UDC initiates remote wakeup\n"); - - spin_lock_irqsave(&dev->lock, flags); - - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} - /* PCI device parameters */ static const struct pci_device_id pci_id[] = { { -- cgit v1.2.3 From c9760ad817091b19fcbb86c8cb5e1ab9e90d913b Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:33 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_create_dma_chain Rearrange udc_create_dma_chain to remove the forward declaration. While rearranging fixed the relevant checkpatch warnings. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 238 ++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 121 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index f218520356ff..2602173d68d4 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -71,8 +71,6 @@ static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); -static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags); static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void udc_pci_remove(struct pci_dev *pdev); @@ -787,6 +785,123 @@ udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) return finished; } +/* Creates or re-inits a DMA chain */ +static int udc_create_dma_chain( + struct udc_ep *ep, + struct udc_request *req, + unsigned long buf_len, gfp_t gfp_flags +) +{ + unsigned long bytes = req->req.length; + unsigned int i; + dma_addr_t dma_addr; + struct udc_data_dma *td = NULL; + struct udc_data_dma *last = NULL; + unsigned long txbytes; + unsigned create_new_chain = 0; + unsigned len; + + VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", + bytes, buf_len); + dma_addr = DMA_DONT_USE; + + /* unset L bit in first desc for OUT */ + if (!ep->in) + req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); + + /* alloc only new desc's if not already available */ + len = req->req.length / ep->ep.maxpacket; + if (req->req.length % ep->ep.maxpacket) + len++; + + if (len > req->chain_len) { + /* shorter chain already allocated before */ + if (req->chain_len > 1) + udc_free_dma_chain(ep->dev, req); + req->chain_len = len; + create_new_chain = 1; + } + + td = req->td_data; + /* gen. required number of descriptors and buffers */ + for (i = buf_len; i < bytes; i += buf_len) { + /* create or determine next desc. */ + if (create_new_chain) { + td = pci_pool_alloc(ep->dev->data_requests, + gfp_flags, &dma_addr); + if (!td) + return -ENOMEM; + + td->status = 0; + } else if (i == buf_len) { + /* first td */ + td = (struct udc_data_dma *)phys_to_virt( + req->td_data->next); + td->status = 0; + } else { + td = (struct udc_data_dma *)phys_to_virt(last->next); + td->status = 0; + } + + if (td) + td->bufptr = req->req.dma + i; /* assign buffer */ + else + break; + + /* short packet ? */ + if ((bytes - i) >= buf_len) { + txbytes = buf_len; + } else { + /* short packet */ + txbytes = bytes - i; + } + + /* link td and assign tx bytes */ + if (i == buf_len) { + if (create_new_chain) + req->td_data->next = dma_addr; + /* + * else + * req->td_data->next = virt_to_phys(td); + */ + /* write tx bytes */ + if (ep->in) { + /* first desc */ + req->td_data->status = + AMD_ADDBITS(req->td_data->status, + ep->ep.maxpacket, + UDC_DMA_IN_STS_TXBYTES); + /* second desc */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } else { + if (create_new_chain) + last->next = dma_addr; + /* + * else + * last->next = virt_to_phys(td); + */ + if (ep->in) { + /* write tx bytes */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } + last = td; + } + /* set last bit */ + if (td) { + td->status |= AMD_BIT(UDC_DMA_IN_STS_L); + /* last desc. points to itself */ + req->td_data_last = td; + } + + return 0; +} + /* create/re-init a DMA descriptor or a DMA descriptor chain */ static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) { @@ -973,125 +1088,6 @@ static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) } -/* Creates or re-inits a DMA chain */ -static int udc_create_dma_chain( - struct udc_ep *ep, - struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags -) -{ - unsigned long bytes = req->req.length; - unsigned int i; - dma_addr_t dma_addr; - struct udc_data_dma *td = NULL; - struct udc_data_dma *last = NULL; - unsigned long txbytes; - unsigned create_new_chain = 0; - unsigned len; - - VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", - bytes, buf_len); - dma_addr = DMA_DONT_USE; - - /* unset L bit in first desc for OUT */ - if (!ep->in) - req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); - - /* alloc only new desc's if not already available */ - len = req->req.length / ep->ep.maxpacket; - if (req->req.length % ep->ep.maxpacket) - len++; - - if (len > req->chain_len) { - /* shorter chain already allocated before */ - if (req->chain_len > 1) - udc_free_dma_chain(ep->dev, req); - req->chain_len = len; - create_new_chain = 1; - } - - td = req->td_data; - /* gen. required number of descriptors and buffers */ - for (i = buf_len; i < bytes; i += buf_len) { - /* create or determine next desc. */ - if (create_new_chain) { - - td = pci_pool_alloc(ep->dev->data_requests, - gfp_flags, &dma_addr); - if (!td) - return -ENOMEM; - - td->status = 0; - } else if (i == buf_len) { - /* first td */ - td = (struct udc_data_dma *) phys_to_virt( - req->td_data->next); - td->status = 0; - } else { - td = (struct udc_data_dma *) phys_to_virt(last->next); - td->status = 0; - } - - - if (td) - td->bufptr = req->req.dma + i; /* assign buffer */ - else - break; - - /* short packet ? */ - if ((bytes - i) >= buf_len) { - txbytes = buf_len; - } else { - /* short packet */ - txbytes = bytes - i; - } - - /* link td and assign tx bytes */ - if (i == buf_len) { - if (create_new_chain) - req->td_data->next = dma_addr; - /* - else - req->td_data->next = virt_to_phys(td); - */ - /* write tx bytes */ - if (ep->in) { - /* first desc */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - /* second desc */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } else { - if (create_new_chain) - last->next = dma_addr; - /* - else - last->next = virt_to_phys(td); - */ - if (ep->in) { - /* write tx bytes */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } - last = td; - } - /* set last bit */ - if (td) { - td->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* last desc. points to itself */ - req->td_data_last = td; - } - - return 0; -} - /* Enabling RX DMA */ static void udc_set_rde(struct udc *dev) { -- cgit v1.2.3 From 3719b9bd66d29de3682b4daaf07748f915f7ac92 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:34 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_free_dma_chain Rearrange udc_free_dma_chain to remove the forward declaration. While at it fixed all the relevant checkpatch warnings. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 51 +++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 2602173d68d4..6d64129e3347 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -70,7 +70,6 @@ static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void udc_pci_remove(struct pci_dev *pdev); @@ -611,6 +610,30 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) return &req->req; } +/* frees pci pool descriptors of a DMA chain */ +static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) +{ + int ret_val = 0; + struct udc_data_dma *td; + struct udc_data_dma *td_last = NULL; + unsigned int i; + + DBG(dev, "free chain req = %p\n", req); + + /* do not free first desc., will be done by free for request */ + td_last = req->td_data; + td = phys_to_virt(td_last->next); + + for (i = 1; i < req->chain_len; i++) { + pci_pool_free(dev->data_requests, td, + (dma_addr_t)td_last->next); + td_last = td; + td = phys_to_virt(td_last->next); + } + + return ret_val; +} + /* Frees request packet, called by gadget driver */ static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) @@ -1026,32 +1049,6 @@ __acquires(ep->dev->lock) ep->halted = halted; } -/* frees pci pool descriptors of a DMA chain */ -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) -{ - - int ret_val = 0; - struct udc_data_dma *td; - struct udc_data_dma *td_last = NULL; - unsigned int i; - - DBG(dev, "free chain req = %p\n", req); - - /* do not free first desc., will be done by free for request */ - td_last = req->td_data; - td = phys_to_virt(td_last->next); - - for (i = 1; i < req->chain_len; i++) { - - pci_pool_free(dev->data_requests, td, - (dma_addr_t) td_last->next); - td_last = td; - td = phys_to_virt(td_last->next); - } - - return ret_val; -} - /* Iterates to the end of a DMA chain and returns last descriptor */ static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) { -- cgit v1.2.3 From 0e7734193a1fead4d966f3b3b64e54ae71b3d356 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:35 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_pci_* Remove the forward declarations of udc_pci_probe and udc_pci_remove. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 6d64129e3347..00ae0692aa67 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -70,8 +70,6 @@ static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void udc_pci_remove(struct pci_dev *pdev); /* description */ static const char mod_desc[] = UDC_MOD_DESCRIPTION; -- cgit v1.2.3 From 5d31a17b389870a8eb215ce7313144eb49c08838 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:36 +0530 Subject: usb: gadget: amd5536udc: remove forward declaration of udc_basic_init Rearrange the udc_basic_init function to remove the forward declaration. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 00ae0692aa67..157bff1ffa64 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -65,7 +65,6 @@ static void udc_tasklet_disconnect(unsigned long); static void empty_req_queue(struct udc_ep *); -static void udc_basic_init(struct udc *dev); static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); @@ -1507,33 +1506,6 @@ static void make_ep_lists(struct udc *dev) dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; } -/* init registers at driver load time */ -static int startup_registers(struct udc *dev) -{ - u32 tmp; - - /* init controller by soft reset */ - udc_soft_reset(dev); - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* put into initial config */ - udc_basic_init(dev); - /* link up all endpoints */ - udc_setup_endpoints(dev); - - /* program speed */ - tmp = readl(&dev->regs->cfg); - if (use_fullspeed) - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - else - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); - writel(tmp, &dev->regs->cfg); - - return 0; -} - /* Inits UDC context */ static void udc_basic_init(struct udc *dev) { @@ -1572,6 +1544,33 @@ static void udc_basic_init(struct udc *dev) dev->data_ep_queued = 0; } +/* init registers at driver load time */ +static int startup_registers(struct udc *dev) +{ + u32 tmp; + + /* init controller by soft reset */ + udc_soft_reset(dev); + + /* mask not needed interrupts */ + udc_mask_unused_interrupts(dev); + + /* put into initial config */ + udc_basic_init(dev); + /* link up all endpoints */ + udc_setup_endpoints(dev); + + /* program speed */ + tmp = readl(&dev->regs->cfg); + if (use_fullspeed) + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); + else + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); + writel(tmp, &dev->regs->cfg); + + return 0; +} + /* Sets initial endpoint parameters */ static void udc_setup_endpoints(struct udc *dev) { -- cgit v1.2.3 From 1b7015083486e0e5b919981c980980afca37507e Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 22 Sep 2015 18:54:37 +0530 Subject: usb: gadget: amd5536udc: NULL comparison A NULL comparison can be written as if (var) or if (!var). Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 157bff1ffa64..cd8764150861 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -2185,7 +2185,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) } /* DMA */ - } else if (!ep->cancel_transfer && req != NULL) { + } else if (!ep->cancel_transfer && req) { ret_val = IRQ_HANDLED; /* check for DMA done */ @@ -3189,7 +3189,7 @@ static int init_dma_pools(struct udc *dev) /* setup */ td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_stp_dma); - if (td_stp == NULL) { + if (!td_stp) { retval = -ENOMEM; goto err_alloc_dma; } @@ -3198,7 +3198,7 @@ static int init_dma_pools(struct udc *dev) /* data: 0 packets !? */ td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_phys); - if (td_data == NULL) { + if (!td_data) { retval = -ENOMEM; goto err_alloc_phys; } @@ -3322,7 +3322,7 @@ static int udc_pci_probe( } dev->virt_addr = ioremap_nocache(resource, len); - if (dev->virt_addr == NULL) { + if (!dev->virt_addr) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); retval = -EFAULT; goto err_ioremap; -- cgit v1.2.3 From 9af9195426685ffd7c81022002b0db3fd7040591 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Sat, 19 Sep 2015 22:42:58 +0530 Subject: usb: gadget: at91_udc: mention proper dependency While building allmodconfig on avr32 the build failed with the error: "at91_pmc_base" [drivers/usb/gadget/udc/atmel_usba_udc.ko] undefined! On checking the code it turned out that if CONFIG_OF is defined then it is using at91_pmc_read() which is using at91_pmc_base. And unless COMMON_CLK_AT91 is defined we donot have at91_pmc_base. And COMMON_CLK_AT91 is available with AT91 architecture. Mention the dependency such that this driver builds with avr32 only if OF is not enabled. Signed-off-by: Sudip Mukherjee Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 9a3a6b00391a..cdbff54e07ac 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -55,7 +55,7 @@ config USB_LPC32XX config USB_ATMEL_USBA tristate "Atmel USBA" - depends on AVR32 || ARCH_AT91 + depends on ((AVR32 && !OF) || ARCH_AT91) help USBA is the integrated high-speed USB Device controller on the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. -- cgit v1.2.3 From 902d03c7f3900b8a5d2997303b87dc12397bea71 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Mon, 21 Sep 2015 21:51:13 +0200 Subject: usb: gadget: loopback: Fix show methods for attributes Most of USB functions place new line after attribute value. Let's follow this convention also in loopback function as it improves readability. Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_loopback.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 300e6011ae67..abfdb92bde64 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -431,7 +431,7 @@ static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->qlen); + result = sprintf(page, "%d\n", opts->qlen); mutex_unlock(&opts->lock); return result; @@ -470,7 +470,7 @@ static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->bulk_buflen); + result = sprintf(page, "%d\n", opts->bulk_buflen); mutex_unlock(&opts->lock); return result; -- cgit v1.2.3 From fa50bff63689849175d65f4923691944556fbacc Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Mon, 21 Sep 2015 21:51:14 +0200 Subject: usb: gadget: SourceSink: Fix show methods for attributes Most of USB functions place new line after attribute value. Let's follow this convention also in source sink function as it improves readability. Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 1353465ca599..68efa01bdf4d 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -906,7 +906,7 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->pattern); + result = sprintf(page, "%u\n", opts->pattern); mutex_unlock(&opts->lock); return result; @@ -950,7 +950,7 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_interval); + result = sprintf(page, "%u\n", opts->isoc_interval); mutex_unlock(&opts->lock); return result; @@ -994,7 +994,7 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_maxpacket); + result = sprintf(page, "%u\n", opts->isoc_maxpacket); mutex_unlock(&opts->lock); return result; @@ -1038,7 +1038,7 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_mult); + result = sprintf(page, "%u\n", opts->isoc_mult); mutex_unlock(&opts->lock); return result; @@ -1082,7 +1082,7 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->isoc_maxburst); + result = sprintf(page, "%u\n", opts->isoc_maxburst); mutex_unlock(&opts->lock); return result; @@ -1126,7 +1126,7 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page) int result; mutex_lock(&opts->lock); - result = sprintf(page, "%u", opts->bulk_buflen); + result = sprintf(page, "%u\n", opts->bulk_buflen); mutex_unlock(&opts->lock); return result; -- cgit v1.2.3 From 857512d0ebf838d8a2b600234debdbfc1e97f919 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:18 +0200 Subject: usb: dwc2: force dr_mode in case of configuration mismatch If dual role configuration is not selected, check and force dr_mode based on the selected configuration. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 28abd1f90900..a013ea9f2c9c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -221,6 +221,17 @@ static int dwc2_driver_probe(struct platform_device *dev) (unsigned long)res->start, hsotg->regs); hsotg->dr_mode = usb_get_dr_mode(&dev->dev); + if (IS_ENABLED(CONFIG_USB_DWC2_HOST) && + hsotg->dr_mode != USB_DR_MODE_HOST) { + hsotg->dr_mode = USB_DR_MODE_HOST; + dev_warn(hsotg->dev, + "Configuration mismatch. Forcing host mode\n"); + } else if (IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) && + hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) { + hsotg->dr_mode = USB_DR_MODE_PERIPHERAL; + dev_warn(hsotg->dev, + "Configuration mismatch. Forcing peripheral mode\n"); + } /* * Attempt to find a generic PHY, then look for an old style -- cgit v1.2.3 From 77ba9119adc48a0bb890ca121f6b8f09162c9182 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 29 Sep 2015 12:08:19 +0200 Subject: usb: dwc2: gadget: don't modify pullup state in host mode Modifying the pullup state during host mode trig a new enumeration of attached device. Thus, avoid modifying pullup in host mode. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 36345ab05f7e..61d102185bf1 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3170,7 +3170,14 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) struct dwc2_hsotg *hsotg = to_hsotg(gadget); unsigned long flags = 0; - dev_dbg(hsotg->dev, "%s: is_on: %d\n", __func__, is_on); + dev_dbg(hsotg->dev, "%s: is_on: %d op_state: %d\n", __func__, is_on, + hsotg->op_state); + + /* Don't modify pullup state while in host mode */ + if (hsotg->op_state != OTG_STATE_B_PERIPHERAL) { + hsotg->enabled = is_on; + return 0; + } mutex_lock(&hsotg->init_mutex); spin_lock_irqsave(&hsotg->lock, flags); -- cgit v1.2.3 From cd0e641c8da3c763f1f4b838a9bc30f1297f68d0 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 29 Sep 2015 12:08:20 +0200 Subject: usb: dwc2: gadget: set op_state in vbus_session call Some device may have external id pin control enabled, so op_state will not be set on id pin interrupt change. Thus, ensure op_state is set to peripheral during vbus detection. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 61d102185bf1..1a216c51bbe4 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3209,6 +3209,7 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) spin_lock_irqsave(&hsotg->lock, flags); if (is_active) { + hsotg->op_state = OTG_STATE_B_PERIPHERAL; /* * If controller is hibernated, it must exit from hibernation * before being initialized -- cgit v1.2.3 From 86de48953653777fd6f918f5c0f2107bb873eae3 Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 29 Sep 2015 12:08:21 +0200 Subject: usb: dwc2: gadget: abort core init if core_reset fails No point of continue with initialization if core is not in a sane state. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 1a216c51bbe4..af4f0c165d05 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2287,7 +2287,8 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, u32 val; if (!is_usb_reset) - dwc2_hsotg_corereset(hsotg); + if (dwc2_hsotg_corereset(hsotg)) + return; /* * we must now enable ep0 ready for host detection and then -- cgit v1.2.3 From b2d4c54e51c4213d215520bab25efee74ddc8d3a Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:22 +0200 Subject: usb: dwc2: gadget: ignore stall check for ep0 dwc2_hsotg_start_req starts a request only if endpoint is not stalled. Ignore this check for ep0 as core will clear DOEPCTL0.Stall after sending stall handshake. Prepare instead for receiving next setup packet. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index af4f0c165d05..885b5b663a69 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -556,7 +556,7 @@ static void dwc2_hsotg_start_req(struct dwc2_hsotg *hsotg, /* If endpoint is stalled, we will restart request later */ ctrl = dwc2_readl(hsotg->regs + epctrl_reg); - if (ctrl & DXEPCTL_STALL) { + if (index && ctrl & DXEPCTL_STALL) { dev_warn(hsotg->dev, "%s: ep%d is stalled\n", __func__, index); return; } -- cgit v1.2.3 From e525e74339b1e94ade1c14640d5282dbcdb32526 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:23 +0200 Subject: usb: dwc2: gadget: print complete setup packet wIndex field was missing. Also print in natural order instead of Req first, so that its easier to compare for example against bus analyzer logs. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 885b5b663a69..9188991b9b72 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1206,9 +1206,10 @@ static void dwc2_hsotg_process_control(struct dwc2_hsotg *hsotg, int ret = 0; u32 dcfg; - dev_dbg(hsotg->dev, "ctrl Req=%02x, Type=%02x, V=%04x, L=%04x\n", - ctrl->bRequest, ctrl->bRequestType, - ctrl->wValue, ctrl->wLength); + dev_dbg(hsotg->dev, + "ctrl Type=%02x, Req=%02x, V=%04x, I=%04x, L=%04x\n", + ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, + ctrl->wIndex, ctrl->wLength); if (ctrl->wLength == 0) { ep0->dir_in = 1; -- cgit v1.2.3 From c524dd5f432a0690710b62e729a3673c557d8b58 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:24 +0200 Subject: usb: dwc2: gadget: stop current transfer on dequeue If the request being dequeued is already started, disable endpoint to stop the transfer and then call dwc2_hsotg_complete_request(). Endpoint will be re-enabled on next call to dwc2_hsotg_start_req(). Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 9188991b9b72..38c29a8bdd11 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2826,6 +2826,79 @@ static bool on_list(struct dwc2_hsotg_ep *ep, struct dwc2_hsotg_req *test) return false; } +static int dwc2_hsotg_wait_bit_set(struct dwc2_hsotg *hs_otg, u32 reg, + u32 bit, u32 timeout) +{ + u32 i; + + for (i = 0; i < timeout; i++) { + if (dwc2_readl(hs_otg->regs + reg) & bit) + return 0; + udelay(1); + } + + return -ETIMEDOUT; +} + +static void dwc2_hsotg_ep_stop_xfr(struct dwc2_hsotg *hsotg, + struct dwc2_hsotg_ep *hs_ep) +{ + u32 epctrl_reg; + u32 epint_reg; + + epctrl_reg = hs_ep->dir_in ? DIEPCTL(hs_ep->index) : + DOEPCTL(hs_ep->index); + epint_reg = hs_ep->dir_in ? DIEPINT(hs_ep->index) : + DOEPINT(hs_ep->index); + + dev_dbg(hsotg->dev, "%s: stopping transfer on %s\n", __func__, + hs_ep->name); + if (hs_ep->dir_in) { + __orr32(hsotg->regs + epctrl_reg, DXEPCTL_SNAK); + /* Wait for Nak effect */ + if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg, + DXEPINT_INEPNAKEFF, 100)) + dev_warn(hsotg->dev, + "%s: timeout DIEPINT.NAKEFF\n", __func__); + } else { + /* Clear any pending nak effect interrupt */ + dwc2_writel(GINTSTS_GINNAKEFF, hsotg->regs + GINTSTS); + + __orr32(hsotg->regs + DCTL, DCTL_SGNPINNAK); + + /* Wait for global nak to take effect */ + if (dwc2_hsotg_wait_bit_set(hsotg, GINTSTS, + GINTSTS_GINNAKEFF, 100)) + dev_warn(hsotg->dev, + "%s: timeout GINTSTS.GINNAKEFF\n", __func__); + } + + /* Disable ep */ + __orr32(hsotg->regs + epctrl_reg, DXEPCTL_EPDIS | DXEPCTL_SNAK); + + /* Wait for ep to be disabled */ + if (dwc2_hsotg_wait_bit_set(hsotg, epint_reg, DXEPINT_EPDISBLD, 100)) + dev_warn(hsotg->dev, + "%s: timeout DOEPCTL.EPDisable\n", __func__); + + if (hs_ep->dir_in) { + if (hsotg->dedicated_fifos) { + dwc2_writel(GRSTCTL_TXFNUM(hs_ep->fifo_index) | + GRSTCTL_TXFFLSH, hsotg->regs + GRSTCTL); + /* Wait for fifo flush */ + if (dwc2_hsotg_wait_bit_set(hsotg, GRSTCTL, + GRSTCTL_TXFFLSH, 100)) + dev_warn(hsotg->dev, + "%s: timeout flushing fifos\n", + __func__); + } + /* TODO: Flush shared tx fifo */ + } else { + /* Remove global NAKs */ + __bic32(hsotg->regs + DCTL, DCTL_SGNPINNAK); + } +} + /** * dwc2_hsotg_ep_dequeue - dequeue given endpoint * @ep: The endpoint to dequeue. @@ -2847,6 +2920,10 @@ static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) return -EINVAL; } + /* Dequeue already started request */ + if (req == &hs_ep->req->req) + dwc2_hsotg_ep_stop_xfr(hs, hs_ep); + dwc2_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); spin_unlock_irqrestore(&hs->lock, flags); -- cgit v1.2.3 From 5390d438e6f4aaf3555acc72aff155660a48cd28 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:25 +0200 Subject: usb: dwc2: gadget: kill ep0 requests before reinitializing core Make sure there are no requests pending on ep0 before reinitializing core. Otherwise, dwc2_hsotg_enqueue_setup will fail afterwards. Also, take hsotg->lock before calling dwc2_hsotg_core_init_disconnected() from dwc2_conn_id_status_change() as dwc2_hsotg_complete_request() expect lock to be held. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 8 +++----- drivers/usb/dwc2/hcd.c | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 38c29a8bdd11..2d81fc5f39e9 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2287,6 +2287,9 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, { u32 val; + /* Kill any ep0 requests as controller will be reinitialized */ + kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); + if (!is_usb_reset) if (dwc2_hsotg_corereset(hsotg)) return; @@ -2515,9 +2518,6 @@ irq_retry: if (time_after(jiffies, hsotg->last_rst + msecs_to_jiffies(200))) { - kill_all_requests(hsotg, hsotg->eps_out[0], - -ECONNRESET); - dwc2_hsotg_core_init_disconnected(hsotg, true); } } @@ -3296,8 +3296,6 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) if (hsotg->lx_state == DWC2_L2) dwc2_exit_hibernation(hsotg, false); - /* Kill any ep0 requests as controller will be reinitialized */ - kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) dwc2_hsotg_core_connect(hsotg); diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 15a1e62ac902..af4e4a27126f 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1355,6 +1355,7 @@ static void dwc2_conn_id_status_change(struct work_struct *work) wf_otg); u32 count = 0; u32 gotgctl; + unsigned long flags; dev_dbg(hsotg->dev, "%s()\n", __func__); @@ -1382,7 +1383,9 @@ static void dwc2_conn_id_status_change(struct work_struct *work) hsotg->op_state = OTG_STATE_B_PERIPHERAL; dwc2_core_init(hsotg, false, -1); dwc2_enable_global_interrupts(hsotg); + spin_lock_irqsave(&hsotg->lock, flags); dwc2_hsotg_core_init_disconnected(hsotg, false); + spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hsotg_core_connect(hsotg); } else { /* A-Device connector (Host Mode) */ -- cgit v1.2.3 From 2becdc62a98da6882d7457f7661f70255235ef88 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:26 +0200 Subject: usb: dwc2: gadget: only reset core after addressed state There is a 200ms guard period to avoid unnecessary resets of the dwc2 ip. This delay sometimes prove to be too large when usbcv is run with an ehci host. dwc2 only needs to be reset after addressed state. Change the logic to reset ip after addressed state. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 2 -- drivers/usb/dwc2/gadget.c | 11 +++-------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index d2115d2a3db2..305698109000 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -688,7 +688,6 @@ struct dwc2_hregs_backup { * @ctrl_req: Request for EP0 control packets. * @ep0_state: EP0 control transfers state * @test_mode: USB test mode requested by the host - * @last_rst: Time of last reset * @eps: The endpoints being supplied to the gadget framework * @g_using_dma: Indicate if dma usage is enabled * @g_rx_fifo_sz: Contains rx fifo size value @@ -831,7 +830,6 @@ struct dwc2_hsotg { struct usb_gadget gadget; unsigned int enabled:1; unsigned int connected:1; - unsigned long last_rst; struct dwc2_hsotg_ep *eps_in[MAX_EPS_CHANNELS]; struct dwc2_hsotg_ep *eps_out[MAX_EPS_CHANNELS]; u32 g_using_dma; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 2d81fc5f39e9..d6f552cc6a59 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2420,7 +2420,6 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, /* must be at-least 3ms to allow bus to see disconnect */ mdelay(3); - hsotg->last_rst = jiffies; hsotg->lx_state = DWC2_L0; } @@ -2504,6 +2503,7 @@ irq_retry: if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL); + u32 connected = hsotg->connected; dev_dbg(hsotg->dev, "%s: USBRst\n", __func__); dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", @@ -2514,13 +2514,8 @@ irq_retry: /* Report disconnection if it is not already done. */ dwc2_hsotg_disconnect(hsotg); - if (usb_status & GOTGCTL_BSESVLD) { - if (time_after(jiffies, hsotg->last_rst + - msecs_to_jiffies(200))) { - - dwc2_hsotg_core_init_disconnected(hsotg, true); - } - } + if (usb_status & GOTGCTL_BSESVLD && connected) + dwc2_hsotg_core_init_disconnected(hsotg, true); } /* check both FIFOs */ -- cgit v1.2.3 From 1ee6903b8f9bbcbeb7cf72e5127d7a0b8aeb267c Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 29 Sep 2015 12:08:27 +0200 Subject: usb: dwc2: gadget: unmask idstschng interrupt only if controller supports it idstschng interrupt should not be used when id pin control is external. This is already handled on dwc2 host part. Fix it on gadget part as well. Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index d6f552cc6a59..e87a7359e632 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2285,6 +2285,7 @@ static int dwc2_hsotg_corereset(struct dwc2_hsotg *hsotg) void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, bool is_usb_reset) { + u32 intmsk; u32 val; /* Kill any ep0 requests as controller will be reinitialized */ @@ -2316,14 +2317,16 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, /* Clear any pending interrupts */ dwc2_writel(0xffffffff, hsotg->regs + GINTSTS); - - dwc2_writel(GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | + intmsk = GINTSTS_ERLYSUSP | GINTSTS_SESSREQINT | GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF | - GINTSTS_CONIDSTSCHNG | GINTSTS_USBRST | - GINTSTS_RESETDET | GINTSTS_ENUMDONE | - GINTSTS_OTGINT | GINTSTS_USBSUSP | - GINTSTS_WKUPINT, - hsotg->regs + GINTMSK); + GINTSTS_USBRST | GINTSTS_RESETDET | + GINTSTS_ENUMDONE | GINTSTS_OTGINT | + GINTSTS_USBSUSP | GINTSTS_WKUPINT; + + if (hsotg->core_params->external_id_pin_ctl <= 0) + intmsk |= GINTSTS_CONIDSTSCHNG; + + dwc2_writel(intmsk, hsotg->regs + GINTMSK); if (using_dma(hsotg)) dwc2_writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | -- cgit v1.2.3 From 61f7223bf14689382fdf36b7580f206745c2409a Mon Sep 17 00:00:00 2001 From: Gregory Herrero Date: Tue, 29 Sep 2015 12:08:28 +0200 Subject: usb: dwc2: gadget: exit hibernation before power down When disconnecting cable, controller will detect a suspend condition and enter partial power down. If vbus_session is called by the phy driver during hibernation, make sure controller exit hibernation before it is accessed. Signed-off-by: Jianqiang Tang Signed-off-by: Gregory Herrero Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index e87a7359e632..ef964814b928 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3285,14 +3285,15 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active) dev_dbg(hsotg->dev, "%s: is_active: %d\n", __func__, is_active); spin_lock_irqsave(&hsotg->lock, flags); + /* + * If controller is hibernated, it must exit from hibernation + * before being initialized / de-initialized + */ + if (hsotg->lx_state == DWC2_L2) + dwc2_exit_hibernation(hsotg, false); + if (is_active) { hsotg->op_state = OTG_STATE_B_PERIPHERAL; - /* - * If controller is hibernated, it must exit from hibernation - * before being initialized - */ - if (hsotg->lx_state == DWC2_L2) - dwc2_exit_hibernation(hsotg, false); dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) -- cgit v1.2.3 From 8fc37b82a4a43f63e3464e5d02578ea988cb5c01 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:29 +0200 Subject: usb: dwc2: gadget: handle reset interrupt before endpoint interrupts If system is loaded, reset, enum-done and setup interrupts can occur at the same time. Current interrupt handling sequence will handle setup packet's interrupt before handling reset interrupt. Which will break the enumeration process. Correct sequence is to handle reset, enum-done and then any other endpoint interrupts. Signed-off-by: Mian Yousaf Kaukab Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index ef964814b928..bdda32cefeda 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2460,6 +2460,36 @@ irq_retry: gintsts &= gintmsk; + if (gintsts & GINTSTS_RESETDET) { + dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__); + + dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS); + + /* This event must be used only if controller is suspended */ + if (hsotg->lx_state == DWC2_L2) { + dwc2_exit_hibernation(hsotg, true); + hsotg->lx_state = DWC2_L0; + } + } + + if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { + + u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL); + u32 connected = hsotg->connected; + + dev_dbg(hsotg->dev, "%s: USBRst\n", __func__); + dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", + dwc2_readl(hsotg->regs + GNPTXSTS)); + + dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); + + /* Report disconnection if it is not already done. */ + dwc2_hsotg_disconnect(hsotg); + + if (usb_status & GOTGCTL_BSESVLD && connected) + dwc2_hsotg_core_init_disconnected(hsotg, true); + } + if (gintsts & GINTSTS_ENUMDONE) { dwc2_writel(GINTSTS_ENUMDONE, hsotg->regs + GINTSTS); @@ -2491,36 +2521,6 @@ irq_retry: } } - if (gintsts & GINTSTS_RESETDET) { - dev_dbg(hsotg->dev, "%s: USBRstDet\n", __func__); - - dwc2_writel(GINTSTS_RESETDET, hsotg->regs + GINTSTS); - - /* This event must be used only if controller is suspended */ - if (hsotg->lx_state == DWC2_L2) { - dwc2_exit_hibernation(hsotg, true); - hsotg->lx_state = DWC2_L0; - } - } - - if (gintsts & (GINTSTS_USBRST | GINTSTS_RESETDET)) { - - u32 usb_status = dwc2_readl(hsotg->regs + GOTGCTL); - u32 connected = hsotg->connected; - - dev_dbg(hsotg->dev, "%s: USBRst\n", __func__); - dev_dbg(hsotg->dev, "GNPTXSTS=%08x\n", - dwc2_readl(hsotg->regs + GNPTXSTS)); - - dwc2_writel(GINTSTS_USBRST, hsotg->regs + GINTSTS); - - /* Report disconnection if it is not already done. */ - dwc2_hsotg_disconnect(hsotg); - - if (usb_status & GOTGCTL_BSESVLD && connected) - dwc2_hsotg_core_init_disconnected(hsotg, true); - } - /* check both FIFOs */ if (gintsts & GINTSTS_NPTXFEMP) { -- cgit v1.2.3 From 21795c826a4525bd6b111acfe0db079545083c40 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Tue, 29 Sep 2015 12:08:30 +0200 Subject: usb: dwc2: exit hibernation on session request Controller enters hibernation through suspend interrupt on disconnection. On connection, session request interrupt is generated. dwc2 must exit hibernation and restore state from this interrupt before continuing. In host mode, exit from hibernation is handled by bus_resume function. Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Gregory Herrero Tested-by: Robert Baldyga Tested-by: Dinh Nguyen Tested-by: John Youn Acked-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core_intr.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index d8a5400a2d2d..27daa42788b1 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c @@ -313,16 +313,28 @@ static void dwc2_handle_conn_id_status_change_intr(struct dwc2_hsotg *hsotg) */ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg) { - dev_dbg(hsotg->dev, "++Session Request Interrupt++\n"); + int ret; + + dev_dbg(hsotg->dev, "Session request interrupt - lx_state=%d\n", + hsotg->lx_state); /* Clear interrupt */ dwc2_writel(GINTSTS_SESSREQINT, hsotg->regs + GINTSTS); - /* - * Report disconnect if there is any previous session established - */ - if (dwc2_is_device_mode(hsotg)) + if (dwc2_is_device_mode(hsotg)) { + if (hsotg->lx_state == DWC2_L2) { + ret = dwc2_exit_hibernation(hsotg, true); + if (ret && (ret != -ENOTSUPP)) + dev_err(hsotg->dev, + "exit hibernation failed\n"); + } + + /* + * Report disconnect if there is any previous session + * established + */ dwc2_hsotg_disconnect(hsotg); + } } /* -- cgit v1.2.3 From 44583fecfd85f33878a90ca9cad2eb533bfc39a1 Mon Sep 17 00:00:00 2001 From: Yunzhi Li Date: Tue, 29 Sep 2015 12:25:01 +0200 Subject: usb: dwc2: gadget: fix a memory use-after-free bug When dwc2_hsotg_handle_unaligned_buf_complete() hs_req->req.buf already destroyed, in dwc2_hsotg_unmap_dma(), it touches hs_req->req.dma again, so dwc2_hsotg_unmap_dma() should be called before dwc2_hsotg_handle_unaligned_buf_complete(). Otherwise, it will cause a bad_page BUG, when allocate this memory page next time. This bug led to the following crash: BUG: Bad page state in process swapper/0 pfn:2bdbc [ 26.820440] page:eed76780 count:0 mapcount:0 mapping: (null) index:0x0 [ 26.854710] page flags: 0x200(arch_1) [ 26.885836] page dumped because: PAGE_FLAGS_CHECK_AT_PREP flag set [ 26.919179] bad because of flags: [ 26.948917] page flags: 0x200(arch_1) [ 26.979100] Modules linked in: [ 27.008401] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W3.14.0 #17 [ 27.041816] [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [ 27.076108] [] (show_stack) from [] (dump_stack+0x70/0x8c) [ 27.110246] [] (dump_stack) from [] (bad_page+0xfc/0x12c) [ 27.143958] [] (bad_page) from [] (get_page_from_freelist+0x3e4/0x50c) [ 27.179298] [] (get_page_from_freelist) from [] (__alloc_pages_nodemask) [ 27.216296] [] (__alloc_pages_nodemask) from [] (__get_free_pages+0x20/) [ 27.252326] [] (__get_free_pages) from [] (kmalloc_order_trace+0x34/0xa) [ 27.288295] [] (kmalloc_order_trace) from [] (__kmalloc+0x40/0x1ac) [ 27.323751] [] (__kmalloc) from [] (dwc2_hsotg_ep_queue.isra.12+0x7c/0x1) [ 27.359937] [] (dwc2_hsotg_ep_queue.isra.12) from [] (dwc2_hsotg_ep_queue) [ 27.397478] [] (dwc2_hsotg_ep_queue_lock) from [] (rx_submit+0xfc/0x164) [ 27.433619] [] (rx_submit) from [] (rx_complete+0x22c/0x230) [ 27.468872] [] (rx_complete) from [] (dwc2_hsotg_complete_request+0xfc/0) [ 27.506240] [] (dwc2_hsotg_complete_request) from [] (dwc2_hsotg_handle_o) [ 27.545401] [] (dwc2_hsotg_handle_outdone) from [] (dwc2_hsotg_epint+0x2c) [ 27.583689] [] (dwc2_hsotg_epint) from [] (dwc2_hsotg_irq+0x1dc/0x4ac) [ 27.621041] [] (dwc2_hsotg_irq) from [] (handle_irq_event_percpu+0x70/0x) [ 27.659066] [] (handle_irq_event_percpu) from [] (handle_irq_event+0x4c) [ 27.697322] [] (handle_irq_event) from [] (handle_fasteoi_irq+0xc8/0x11) [ 27.735451] [] (handle_fasteoi_irq) from [] (generic_handle_irq+0x30/0x) [ 27.773918] [] (generic_handle_irq) from [] (__handle_domain_irq+0x84/0) [ 27.812018] [] (__handle_domain_irq) from [] (gic_handle_irq+0x48/0x6c) [ 27.849695] [] (gic_handle_irq) from [] (__irq_svc+0x40/0x50) [ 27.886907] Exception stack(0xc0d01ee0 to 0xc0d01f28) Acked-by: John Youn Tested-by: Heiko Stuebner Tested-by: Jeffy Chen Signed-off-by: Yunzhi Li Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index bdda32cefeda..6dc64e9d05f9 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1395,14 +1395,14 @@ static void dwc2_hsotg_complete_request(struct dwc2_hsotg *hsotg, if (hs_req->req.status == -EINPROGRESS) hs_req->req.status = result; + if (using_dma(hsotg)) + dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req); + dwc2_hsotg_handle_unaligned_buf_complete(hsotg, hs_ep, hs_req); hs_ep->req = NULL; list_del_init(&hs_req->queue); - if (using_dma(hsotg)) - dwc2_hsotg_unmap_dma(hsotg, hs_ep, hs_req); - /* * call the complete request with the locks off, just in case the * request tries to queue more work for this endpoint. -- cgit v1.2.3 From 19dadca58a16741b2eeb1c31021b577ffb4b88ee Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 21 Sep 2015 12:16:09 +0200 Subject: usb: dwc2: remove double call to dwc2_hsotg_of_probe This patch removes doubled call to dwc2_hsotg_of_probe() function. Tested-by: John Youn Acked-by: John Youn Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 6dc64e9d05f9..7afd04cf64b1 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3572,8 +3572,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) /* Set default UTMI width */ hsotg->phyif = GUSBCFG_PHYIF16; - dwc2_hsotg_of_probe(hsotg); - /* Initialize to legacy fifo configuration values */ hsotg->g_rx_fifo_sz = 2048; hsotg->g_np_g_tx_fifo_sz = 1024; -- cgit v1.2.3 From 4112905f90510fce7c8ccb1cdc05253a25595734 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 21 Sep 2015 12:16:10 +0200 Subject: usb: dwc2: remove non-functional clock gating During typical gadget operation, dwc2 clock was enabled 3 times: from dwc2_gadget_init(), dwc2_hsotg_udc_start() and dwc2_hsotg_pullup(), and then disabled in s3c_hsotg_pullup(), s3c_hsotg_udc_stop() and dwc2_hsotg_remove(). This really makes no sense, so leave clock control code only in dwc2_gadget_init/remove functions. Tested-by: John Youn Acked-by: John Youn Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/gadget.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 7afd04cf64b1..19202c1c79ff 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3146,8 +3146,6 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed = USB_SPEED_UNKNOWN; - clk_enable(hsotg->clk); - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); if (ret) { @@ -3217,8 +3215,6 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - clk_disable(hsotg->clk); - mutex_unlock(&hsotg->init_mutex); return 0; @@ -3259,7 +3255,6 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) mutex_lock(&hsotg->init_mutex); spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { - clk_enable(hsotg->clk); hsotg->enabled = 1; dwc2_hsotg_core_init_disconnected(hsotg, false); dwc2_hsotg_core_connect(hsotg); @@ -3267,7 +3262,6 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) dwc2_hsotg_core_disconnect(hsotg); dwc2_hsotg_disconnect(hsotg); hsotg->enabled = 0; - clk_disable(hsotg->clk); } hsotg->gadget.speed = USB_SPEED_UNKNOWN; -- cgit v1.2.3 From 5ee2a003e8622d51e865ffa5547a5708e592a1a5 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 21 Sep 2015 12:16:11 +0200 Subject: usb: dwc2: fix unbalanced phy control Even when DWC2 is in (internal) suspended state, it should disable PHY in suspend and then enable it in resume. This patch fixes unbalanced PHY control sequence. Tested-by: John Youn Acked-by: John Youn Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index a013ea9f2c9c..b920e438cd49 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -301,8 +301,6 @@ static int __maybe_unused dwc2_suspend(struct device *dev) if (dwc2_is_device_mode(dwc2)) { ret = dwc2_hsotg_suspend(dwc2); } else { - if (dwc2->lx_state == DWC2_L0) - return 0; phy_exit(dwc2->phy); phy_power_off(dwc2->phy); -- cgit v1.2.3 From ec1f9d9f01384fe656a6f92b90de274146fe35a1 Mon Sep 17 00:00:00 2001 From: Roman Bacik Date: Thu, 10 Sep 2015 18:13:43 -0700 Subject: usb: dwc2: gadget: parity fix in isochronous mode USB OTG driver in isochronous mode has to set the parity of the receiving microframe. The parity is set to even by default. This causes problems for an audio gadget, if the host starts transmitting on odd microframes. This fix uses Incomplete Periodic Transfer interrupt to toggle between even and odd parity until the Transfer Complete interrupt is received. Signed-off-by: Roman Bacik Reviewed-by: Abhinav Ratna Reviewed-by: Srinath Mannam Signed-off-by: Scott Branden Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/gadget.c | 71 +++++++++++++++++++++++++++++++++++++++++------ drivers/usb/dwc2/hw.h | 1 + 3 files changed, 65 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 305698109000..ebf25045b4e8 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -166,6 +166,7 @@ struct dwc2_hsotg_ep { unsigned int periodic:1; unsigned int isochronous:1; unsigned int send_zlp:1; + unsigned int has_correct_parity:1; char name[10]; }; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 19202c1c79ff..7e5670c4532d 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -1513,6 +1513,19 @@ static void dwc2_hsotg_ep0_zlp(struct dwc2_hsotg *hsotg, bool dir_in) dwc2_hsotg_program_zlp(hsotg, hsotg->eps_out[0]); } +static void dwc2_hsotg_change_ep_iso_parity(struct dwc2_hsotg *hsotg, + u32 epctl_reg) +{ + u32 ctrl; + + ctrl = dwc2_readl(hsotg->regs + epctl_reg); + if (ctrl & DXEPCTL_EOFRNUM) + ctrl |= DXEPCTL_SETEVENFR; + else + ctrl |= DXEPCTL_SETODDFR; + dwc2_writel(ctrl, hsotg->regs + epctl_reg); +} + /** * dwc2_hsotg_handle_outdone - handle receiving OutDone/SetupDone from RXFIFO * @hsotg: The device instance @@ -1583,6 +1596,16 @@ static void dwc2_hsotg_handle_outdone(struct dwc2_hsotg *hsotg, int epnum) return; } + /* + * Slave mode OUT transfers do not go through XferComplete so + * adjust the ISOC parity here. + */ + if (!using_dma(hsotg)) { + hs_ep->has_correct_parity = 1; + if (hs_ep->isochronous && hs_ep->interval == 1) + dwc2_hsotg_change_ep_iso_parity(hsotg, DOEPCTL(epnum)); + } + dwc2_hsotg_complete_request(hsotg, hs_ep, hs_req, result); } @@ -1955,13 +1978,9 @@ static void dwc2_hsotg_epint(struct dwc2_hsotg *hsotg, unsigned int idx, ints &= ~DXEPINT_XFERCOMPL; if (ints & DXEPINT_XFERCOMPL) { - if (hs_ep->isochronous && hs_ep->interval == 1) { - if (ctrl & DXEPCTL_EOFRNUM) - ctrl |= DXEPCTL_SETEVENFR; - else - ctrl |= DXEPCTL_SETODDFR; - dwc2_writel(ctrl, hsotg->regs + epctl_reg); - } + hs_ep->has_correct_parity = 1; + if (hs_ep->isochronous && hs_ep->interval == 1) + dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg); dev_dbg(hsotg->dev, "%s: XferCompl: DxEPCTL=0x%08x, DXEPTSIZ=%08x\n", @@ -2321,7 +2340,8 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, GINTSTS_GOUTNAKEFF | GINTSTS_GINNAKEFF | GINTSTS_USBRST | GINTSTS_RESETDET | GINTSTS_ENUMDONE | GINTSTS_OTGINT | - GINTSTS_USBSUSP | GINTSTS_WKUPINT; + GINTSTS_USBSUSP | GINTSTS_WKUPINT | + GINTSTS_INCOMPL_SOIN | GINTSTS_INCOMPL_SOOUT; if (hsotg->core_params->external_id_pin_ctl <= 0) intmsk |= GINTSTS_CONIDSTSCHNG; @@ -2582,6 +2602,40 @@ irq_retry: dwc2_hsotg_dump(hsotg); } + if (gintsts & GINTSTS_INCOMPL_SOIN) { + u32 idx, epctl_reg; + struct dwc2_hsotg_ep *hs_ep; + + dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOIN\n", __func__); + for (idx = 1; idx < hsotg->num_of_eps; idx++) { + hs_ep = hsotg->eps_in[idx]; + + if (!hs_ep->isochronous || hs_ep->has_correct_parity) + continue; + + epctl_reg = DIEPCTL(idx); + dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg); + } + dwc2_writel(GINTSTS_INCOMPL_SOIN, hsotg->regs + GINTSTS); + } + + if (gintsts & GINTSTS_INCOMPL_SOOUT) { + u32 idx, epctl_reg; + struct dwc2_hsotg_ep *hs_ep; + + dev_dbg(hsotg->dev, "%s: GINTSTS_INCOMPL_SOOUT\n", __func__); + for (idx = 1; idx < hsotg->num_of_eps; idx++) { + hs_ep = hsotg->eps_out[idx]; + + if (!hs_ep->isochronous || hs_ep->has_correct_parity) + continue; + + epctl_reg = DOEPCTL(idx); + dwc2_hsotg_change_ep_iso_parity(hsotg, epctl_reg); + } + dwc2_writel(GINTSTS_INCOMPL_SOOUT, hsotg->regs + GINTSTS); + } + /* * if we've had fifo events, we should try and go around the * loop again to see if there's any point in returning yet. @@ -2668,6 +2722,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep, hs_ep->periodic = 0; hs_ep->halted = 0; hs_ep->interval = desc->bInterval; + hs_ep->has_correct_parity = 0; if (hs_ep->interval > 1 && hs_ep->mc > 1) dev_err(hsotg->dev, "MC > 1 when interval is not 1\n"); diff --git a/drivers/usb/dwc2/hw.h b/drivers/usb/dwc2/hw.h index d0a5ed8fa15a..553f24606c43 100644 --- a/drivers/usb/dwc2/hw.h +++ b/drivers/usb/dwc2/hw.h @@ -142,6 +142,7 @@ #define GINTSTS_RESETDET (1 << 23) #define GINTSTS_FET_SUSP (1 << 22) #define GINTSTS_INCOMPL_IP (1 << 21) +#define GINTSTS_INCOMPL_SOOUT (1 << 21) #define GINTSTS_INCOMPL_SOIN (1 << 20) #define GINTSTS_OEPINT (1 << 19) #define GINTSTS_IEPINT (1 << 18) -- cgit v1.2.3 From 41adc59caece02aa2e988a0e8f9fe8e6f426f82e Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 7 Aug 2015 11:04:14 -0700 Subject: usb: dwc3: pci: Add the Synopsys HAPS AXI Product ID This ID is for the Synopsys DWC_usb3 core with AXI interface on PCIe HAPS platform. This core has the debug registers mapped at a separate BAR in order to support enhanced hibernation. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 89eb3642a78e..4c44a7777857 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -27,6 +27,7 @@ #include "platform_data.h" #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 @@ -179,6 +180,10 @@ static const struct pci_device_id dwc3_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3), }, + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI), + }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, -- cgit v1.2.3 From e8095a25364a30216ad40dbe8893ed5c3c235949 Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 7 Aug 2015 11:47:25 -0700 Subject: usb: dwc3: pci: Add the PCI Product ID for Synopsys USB 3.1 This adds the PCI product ID for the Synopsys USB 3.1 IP core (DWC_usb31) on a HAPS-based PCI development platform. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 4c44a7777857..e09cb40c14fc 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -28,6 +28,7 @@ #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 @@ -184,6 +185,10 @@ static const struct pci_device_id dwc3_pci_id_table[] = { PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI), }, + { + PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, + PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31), + }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, -- cgit v1.2.3 From 690fb3718a70c66004342f6f5e2e8a5f95b977db Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 4 Sep 2015 19:15:10 -0700 Subject: usb: dwc3: Support Synopsys USB 3.1 IP This patch allows the dwc3 driver to run on the new Synopsys USB 3.1 IP core, albeit in USB 3.0 mode only. The Synopsys USB 3.1 IP (DWC_usb31) retains mostly the same register interface and programming model as the existing USB 3.0 controller IP (DWC_usb3). However the GSNPSID and version numbers are different. Add checking for the new ID to pass driver probe. Also, since the DWC_usb31 version number is lower in value than the full GSNPSID of the DWC_usb3 IP, we set the high bit to identify DWC_usb31 and to ensure the values are higher. Finally, add a documentation note about the revision numbering scheme. Any future revision checks (for STARS, workarounds, and new features) should take into consideration how it applies to both the 3.1/3.0 IP. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 10 ++++++++-- drivers/usb/dwc3/core.h | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c72c8c5c1c5a..1e276d5662f2 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -534,12 +534,18 @@ static int dwc3_core_init(struct dwc3 *dwc) reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); /* This should read as U3 followed by revision number */ - if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) { + if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) { + /* Detected DWC_usb3 IP */ + dwc->revision = reg; + } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) { + /* Detected DWC_usb31 IP */ + dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); + dwc->revision |= DWC3_REVISION_IS_DWC31; + } else { dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); ret = -ENODEV; goto err0; } - dwc->revision = reg; /* * Write Linux Version Code to our GUID register so it's easy to figure diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 91887455133a..0d65be744552 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -108,6 +108,9 @@ #define DWC3_GPRTBIMAP_FS0 0xc188 #define DWC3_GPRTBIMAP_FS1 0xc18c +#define DWC3_VER_NUMBER 0xc1a0 +#define DWC3_VER_TYPE 0xc1a4 + #define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04)) #define DWC3_GUSB2I2CCTL(n) (0xc240 + (n * 0x04)) @@ -771,6 +774,14 @@ struct dwc3 { u32 num_event_buffers; u32 u1u2; u32 maximum_speed; + + /* + * All 3.1 IP version constants are greater than the 3.0 IP + * version constants. This works for most version checks in + * dwc3. However, in the future, this may not apply as + * features may be developed on newer versions of the 3.0 IP + * that are not in the 3.1 IP. + */ u32 revision; #define DWC3_REVISION_173A 0x5533173a @@ -793,6 +804,13 @@ struct dwc3 { #define DWC3_REVISION_270A 0x5533270a #define DWC3_REVISION_280A 0x5533280a +/* + * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really + * just so dwc31 revisions are always larger than dwc3. + */ +#define DWC3_REVISION_IS_DWC31 0x80000000 +#define DWC3_USB31_REVISION_110A (0x3131302a | DWC3_REVISION_IS_USB31) + enum dwc3_ep0_next ep0_next_event; enum dwc3_ep0_state ep0state; enum dwc3_link_state link_state; -- cgit v1.2.3 From 9a5a0783e4910d9e2063e87184fbd9cac7161a16 Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 25 Sep 2015 23:47:53 -0700 Subject: usb: dwc3: pci: trivial: Formatting Fix the alignment of the PCI device definitions. Also change the hex digit capitalization of one constant to make it consistent with the rest of the file and driver. Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index e09cb40c14fc..a286db7ffe94 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -26,14 +26,14 @@ #include "platform_data.h" -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce -#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf -#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 -#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e -#define PCI_DEVICE_ID_INTEL_BSW 0x22B7 -#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 -#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce +#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31 0xabcf +#define PCI_DEVICE_ID_INTEL_BYT 0x0f37 +#define PCI_DEVICE_ID_INTEL_MRFLD 0x119e +#define PCI_DEVICE_ID_INTEL_BSW 0x22b7 +#define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 +#define PCI_DEVICE_ID_INTEL_SPTH 0xa130 static const struct acpi_gpio_params reset_gpios = { 0, 0, false }; static const struct acpi_gpio_params cs_gpios = { 1, 0, false }; -- cgit v1.2.3 From bb7f3d6d323a56b9c3b3e727380d1395a7f10107 Mon Sep 17 00:00:00 2001 From: John Youn Date: Sat, 26 Sep 2015 00:11:15 -0700 Subject: usb: dwc3: pci: Add platform data for Synopsys HAPS Add platform data and set usb3_lpm_capable and has_lpm_erratum. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index a286db7ffe94..65165308a04f 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -108,6 +108,21 @@ static int dwc3_pci_quirks(struct pci_dev *pdev) } } + if (pdev->vendor == PCI_VENDOR_ID_SYNOPSYS && + (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 || + pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI || + pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) { + + struct dwc3_platform_data pdata; + + memset(&pdata, 0, sizeof(pdata)); + pdata.usb3_lpm_capable = true; + pdata.has_lpm_erratum = true; + + return platform_device_add_data(pci_get_drvdata(pdev), &pdata, + sizeof(pdata)); + } + return 0; } -- cgit v1.2.3 From ec791d149bca4511e7d3a6a92bb3b030c5a443f9 Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 2 Oct 2015 20:30:57 -0700 Subject: usb: dwc3: Add dis_enblslpm_quirk Add a quirk to clear the GUSB2PHYCFG.ENBLSLPM bit, which controls whether the PHY receives the suspend signal from the controller. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/dwc3.txt | 2 ++ drivers/usb/dwc3/core.c | 6 ++++++ drivers/usb/dwc3/core.h | 4 ++++ drivers/usb/dwc3/platform_data.h | 1 + 4 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 8c7d58553681..9ff48e0defb4 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -35,6 +35,8 @@ Optional properties: LTSSM during USB3 Compliance mode. - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. + - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG, + disabling the suspend signal to the PHY. - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal utmi_l1_suspend_n, false when asserts utmi_sleep_n - snps,hird-threshold: HIRD threshold diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 1e276d5662f2..22b4797383cd 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -515,6 +515,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc) if (dwc->dis_u2_susphy_quirk) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; + if (dwc->dis_enblslpm_quirk) + reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); return 0; @@ -912,6 +915,8 @@ static int dwc3_probe(struct platform_device *pdev) "snps,dis_u3_susphy_quirk"); dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); + dwc->dis_enblslpm_quirk = device_property_read_bool(dev, + "snps,dis_enblslpm_quirk"); dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); @@ -945,6 +950,7 @@ static int dwc3_probe(struct platform_device *pdev) dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; + dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 0d65be744552..36f1cb74588c 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -179,6 +179,7 @@ #define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31) #define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6) #define DWC3_GUSB2PHYCFG_ULPI_UTMI (1 << 4) +#define DWC3_GUSB2PHYCFG_ENBLSLPM (1 << 8) /* Global USB2 PHY Vendor Control Register */ #define DWC3_GUSB2PHYACC_NEWREGREQ (1 << 25) @@ -720,6 +721,8 @@ struct dwc3_scratchpad_array { * @rx_detect_poll_quirk: set if we enable rx_detect to polling lfps quirk * @dis_u3_susphy_quirk: set if we disable usb3 suspend phy * @dis_u2_susphy_quirk: set if we disable usb2 suspend phy + * @dis_enblslpm_quirk: set if we clear enblslpm in GUSB2PHYCFG, + * disabling the suspend signal to the PHY. * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk * @tx_de_emphasis: Tx de-emphasis value * 0 - -6dB de-emphasis @@ -864,6 +867,7 @@ struct dwc3 { unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; unsigned dis_u2_susphy_quirk:1; + unsigned dis_enblslpm_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h index 400b197d9985..2bb4d3ad0e6b 100644 --- a/drivers/usb/dwc3/platform_data.h +++ b/drivers/usb/dwc3/platform_data.h @@ -42,6 +42,7 @@ struct dwc3_platform_data { unsigned rx_detect_poll_quirk:1; unsigned dis_u3_susphy_quirk:1; unsigned dis_u2_susphy_quirk:1; + unsigned dis_enblslpm_quirk:1; unsigned tx_de_emphasis_quirk:1; unsigned tx_de_emphasis:2; -- cgit v1.2.3 From 94218ee31ba56fb3a8625978b393124ad660408e Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 2 Oct 2015 20:32:17 -0700 Subject: usb: dwc3: pci: Set enblslpm quirk for Synopsys platforms Certain Synopsys prototyping PHY boards are not able to meet timings constraints for LPM. This allows the PHY to meet those timings by leaving the PHY clock running during suspend. Cc: # v3.18+ Signed-off-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 65165308a04f..77a622cb48ab 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -118,6 +118,7 @@ static int dwc3_pci_quirks(struct pci_dev *pdev) memset(&pdata, 0, sizeof(pdata)); pdata.usb3_lpm_capable = true; pdata.has_lpm_erratum = true; + pdata.dis_enblslpm_quirk = true; return platform_device_add_data(pci_get_drvdata(pdev), &pdata, sizeof(pdata)); -- cgit v1.2.3 From f301fe22bab90a0377096bfd831ef7c99ece1a40 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 20 Sep 2015 17:02:19 -0400 Subject: musb: sunxi: Make sunxi musb glue work without MUSB_PIO_ONLY Now that it is possible to build in multiple dma engines, we can no longer require MUSB_PIO_ONLY to be set when using the sunxi musb glue. This patch adds dummy dma hooks to make the musb glue work without MUSB_PIO_ONLY. This hooks are fake because we do not support dma with musb on sunxi. The Allwinnner Android kernels have some dma code, but it is disabled as Allwinner never managed to get it to work. Signed-off-by: Hans de Goede Signed-off-by: Felipe Balbi --- drivers/usb/musb/sunxi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index f11b8f681b30..d9b0dc461439 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c @@ -341,6 +341,16 @@ static void sunxi_musb_disable(struct musb *musb) clear_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags); } +struct dma_controller *sunxi_musb_dma_controller_create(struct musb *musb, + void __iomem *base) +{ + return NULL; +} + +void sunxi_musb_dma_controller_destroy(struct dma_controller *c) +{ +} + /* * sunxi musb register layout * 0x00 - 0x17 fifo regs, 1 long per fifo @@ -566,6 +576,8 @@ static const struct musb_platform_ops sunxi_musb_ops = { .writeb = sunxi_musb_writeb, .readw = sunxi_musb_readw, .writew = sunxi_musb_writew, + .dma_init = sunxi_musb_dma_controller_create, + .dma_exit = sunxi_musb_dma_controller_destroy, .set_vbus = sunxi_musb_set_vbus, .pre_root_reset_end = sunxi_musb_pre_root_reset_end, .post_root_reset_end = sunxi_musb_post_root_reset_end, -- cgit v1.2.3 From 5527e73305e8a9958b00331902a27514e62d539b Mon Sep 17 00:00:00 2001 From: Igor Kotrasinski Date: Thu, 20 Aug 2015 10:00:01 +0200 Subject: usb: gadget: composite: fill bcdUSB for any gadget max speed When handling device GET_DESCRIPTOR, composite gadget driver fills the bcdUSB field only if the gadget supports USB 3.0. Otherwise the field is left unfilled. For consistency, set bcdUSB to 0x0200 for gadgets that don't support superspeed. It's correct to use 0x0200 for any setting that doesn't use superspeed, since USB 2.0 devices can restrict themselves to full speed only. It is NOT correct to use 0x0210, since BOS descriptors are handled only if gadget_is_superspeed() is satisfied, otherwise it results in a stall. Signed-off-by: Igor Kotrasinski Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 3e95c0e88b8b..8b14c2a13ac5 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1504,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } else { cdev->desc.bcdUSB = cpu_to_le16(0x0210); } + } else { + cdev->desc.bcdUSB = cpu_to_le16(0x0200); } value = min(w_length, (u16) sizeof cdev->desc); -- cgit v1.2.3 From e5f68b4a3e7b006f209aba078d6a5ff3a78dd783 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 12 Oct 2015 13:25:44 -0500 Subject: Revert "usb: dwc3: gadget: remove unnecessary _irqsave()" This reverts commit 70f3a9caa11665e9f9aace581d85d8483716a4c8. That commit was causing a lockdep splat with g_ether and that was interfering with proper functionality. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index cca806e09e5b..81bfb9ad1e2e 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2642,15 +2642,16 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf) static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc) { struct dwc3 *dwc = _dwc; + unsigned long flags; irqreturn_t ret = IRQ_NONE; int i; - spin_lock(&dwc->lock); + spin_lock_irqsave(&dwc->lock, flags); for (i = 0; i < dwc->num_event_buffers; i++) ret |= dwc3_process_event_buf(dwc, i); - spin_unlock(&dwc->lock); + spin_unlock_irqrestore(&dwc->lock, flags); return ret; } -- cgit v1.2.3 From d115d7050a0d2c4967532f18c9cb522fea6b7280 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 31 Aug 2015 19:48:28 +0300 Subject: Revert "usb: dwc3: gadget: drop unnecessary loop when cleaning up TRBs" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8f2c9544aba636134303105ecb164190a39dece4. As it breaks g_ether on my Baytrail FFRD8 device. Everything starts out fine, but after a bit of data has been transferred it just stops flowing. Note that I do get a bunch of these "NOHZ: local_softirq_pending 08" when booting the machine, but I'm not really sure if they're related to this problem. Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 81bfb9ad1e2e..55ba447fdf8b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1884,27 +1884,32 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, unsigned int i; int ret; - req = next_request(&dep->req_queued); - if (!req) { - WARN_ON_ONCE(1); - return 1; - } - i = 0; do { - slot = req->start_slot + i; - if ((slot == DWC3_TRB_NUM - 1) && + req = next_request(&dep->req_queued); + if (!req) { + WARN_ON_ONCE(1); + return 1; + } + i = 0; + do { + slot = req->start_slot + i; + if ((slot == DWC3_TRB_NUM - 1) && usb_endpoint_xfer_isoc(dep->endpoint.desc)) - slot++; - slot %= DWC3_TRB_NUM; - trb = &dep->trb_pool[slot]; + slot++; + slot %= DWC3_TRB_NUM; + trb = &dep->trb_pool[slot]; + + ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, + event, status); + if (ret) + break; + } while (++i < req->request.num_mapped_sgs); + + dwc3_gadget_giveback(dep, req, status); - ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb, - event, status); if (ret) break; - } while (++i < req->request.num_mapped_sgs); - - dwc3_gadget_giveback(dep, req, status); + } while (1); if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && list_empty(&dep->req_queued)) { -- cgit v1.2.3 From 44e4a60dacf8a96f28b5e021b54ba9eeb793ca2e Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 12 Oct 2015 11:23:27 +0200 Subject: usb: dwc2: fix duplicate argument warning Fix a duplicate argument warning reported by 0-DAY kernel test infrastructure in the following patch: 77dbf71 usb: dwc2: host: add disconnect interrupt to host only interrupts Acked-by: John Youn Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index bf5e951fbb7f..ef73e498e98f 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -863,8 +863,7 @@ void dwc2_enable_host_interrupts(struct dwc2_hsotg *hsotg) /* Enable host mode interrupts without disturbing common interrupts */ intmsk = dwc2_readl(hsotg->regs + GINTMSK); - intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT | - GINTSTS_DISCONNINT; + intmsk |= GINTSTS_DISCONNINT | GINTSTS_PRTINT | GINTSTS_HCHINT; dwc2_writel(intmsk, hsotg->regs + GINTMSK); } -- cgit v1.2.3 From 145f48c518edb945ea5b689a1d21052597f9d64b Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Tue, 13 Oct 2015 15:18:21 +0800 Subject: usb: misc: usbtest: add bulk queue test The bulk queue tests are used to show 'best performance' for bulk transfer, we are often asked this question by users. The implementation is the same with iso test, that is queue request at interrupt completion, so we reuse the iso structures, and rename them as common one. It's result should be very close to IC simulation, in order to get that, the device side should also need to prepare enough queue. We have got the 'best performance' (IN: 41MB, OUT: 39MB) at i.mx platform (USB2, ARM Cortex A9, stream mode need to enable) with below command: Host side: modprobe usbtest ./testusb -a -t 27 -g 64 -s 16384 ./testusb -a -t 28 -g 64 -s 16384 Gadget side: modprobe g_zero loopdefault=1 qlen=64 buflen=16384 Signed-off-by: Peter Chen Cc: Greg KH Cc: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/misc/usbtest.c | 105 ++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index ad6dd4a1de6c..637f3f7cfce8 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -17,6 +17,7 @@ static int override_alt = -1; module_param_named(alt, override_alt, int, 0644); MODULE_PARM_DESC(alt, ">= 0 to override altsetting selection"); +static void complicated_callback(struct urb *urb); /*-------------------------------------------------------------------------*/ @@ -239,7 +240,8 @@ static struct urb *usbtest_alloc_urb( unsigned long bytes, unsigned transfer_flags, unsigned offset, - u8 bInterval) + u8 bInterval, + usb_complete_t complete_fn) { struct urb *urb; @@ -248,10 +250,10 @@ static struct urb *usbtest_alloc_urb( return urb; if (bInterval) - usb_fill_int_urb(urb, udev, pipe, NULL, bytes, simple_callback, + usb_fill_int_urb(urb, udev, pipe, NULL, bytes, complete_fn, NULL, bInterval); else - usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, simple_callback, + usb_fill_bulk_urb(urb, udev, pipe, NULL, bytes, complete_fn, NULL); urb->interval = (udev->speed == USB_SPEED_HIGH) @@ -296,7 +298,17 @@ static struct urb *simple_alloc_urb( u8 bInterval) { return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0, - bInterval); + bInterval, simple_callback); +} + +static struct urb *complicated_alloc_urb( + struct usb_device *udev, + int pipe, + unsigned long bytes, + u8 bInterval) +{ + return usbtest_alloc_urb(udev, pipe, bytes, URB_NO_TRANSFER_DMA_MAP, 0, + bInterval, complicated_callback); } static unsigned pattern; @@ -1795,12 +1807,12 @@ static int ctrl_out(struct usbtest_dev *dev, /*-------------------------------------------------------------------------*/ -/* ISO tests ... mimics common usage +/* ISO/BULK tests ... mimics common usage * - buffer length is split into N packets (mostly maxpacket sized) * - multi-buffers according to sglen */ -struct iso_context { +struct transfer_context { unsigned count; unsigned pending; spinlock_t lock; @@ -1809,11 +1821,12 @@ struct iso_context { unsigned long errors; unsigned long packet_count; struct usbtest_dev *dev; + bool is_iso; }; -static void iso_callback(struct urb *urb) +static void complicated_callback(struct urb *urb) { - struct iso_context *ctx = urb->context; + struct transfer_context *ctx = urb->context; spin_lock(&ctx->lock); ctx->count--; @@ -1822,7 +1835,7 @@ static void iso_callback(struct urb *urb) if (urb->error_count > 0) ctx->errors += urb->error_count; else if (urb->status != 0) - ctx->errors += urb->number_of_packets; + ctx->errors += (ctx->is_iso ? urb->number_of_packets : 1); else if (urb->actual_length != urb->transfer_buffer_length) ctx->errors++; else if (check_guard_bytes(ctx->dev, urb) != 0) @@ -1909,7 +1922,7 @@ static struct urb *iso_alloc_urb( urb->iso_frame_desc[i].offset = maxp * i; } - urb->complete = iso_callback; + urb->complete = complicated_callback; /* urb->context = SET BY CALLER */ urb->interval = 1 << (desc->bInterval - 1); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; @@ -1917,10 +1930,10 @@ static struct urb *iso_alloc_urb( } static int -test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, +test_queue(struct usbtest_dev *dev, struct usbtest_param *param, int pipe, struct usb_endpoint_descriptor *desc, unsigned offset) { - struct iso_context context; + struct transfer_context context; struct usb_device *udev; unsigned i; unsigned long packets = 0; @@ -1930,20 +1943,20 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, memset(&context, 0, sizeof(context)); context.count = param->iterations * param->sglen; context.dev = dev; + context.is_iso = !!desc; init_completion(&context.done); spin_lock_init(&context.lock); udev = testdev_to_usbdev(dev); - dev_info(&dev->intf->dev, - "iso period %d %sframes, wMaxPacket %d, transactions: %d\n", - 1 << (desc->bInterval - 1), - (udev->speed == USB_SPEED_HIGH) ? "micro" : "", - usb_endpoint_maxp(desc) & 0x7ff, - 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11))); for (i = 0; i < param->sglen; i++) { - urbs[i] = iso_alloc_urb(udev, pipe, desc, + if (context.is_iso) + urbs[i] = iso_alloc_urb(udev, pipe, desc, param->length, offset); + else + urbs[i] = complicated_alloc_urb(udev, pipe, + param->length, 0); + if (!urbs[i]) { status = -ENOMEM; goto fail; @@ -1952,11 +1965,21 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, urbs[i]->context = &context; } packets *= param->iterations; - dev_info(&dev->intf->dev, - "total %lu msec (%lu packets)\n", - (packets * (1 << (desc->bInterval - 1))) - / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), - packets); + + if (context.is_iso) { + dev_info(&dev->intf->dev, + "iso period %d %sframes, wMaxPacket %d, transactions: %d\n", + 1 << (desc->bInterval - 1), + (udev->speed == USB_SPEED_HIGH) ? "micro" : "", + usb_endpoint_maxp(desc) & 0x7ff, + 1 + (0x3 & (usb_endpoint_maxp(desc) >> 11))); + + dev_info(&dev->intf->dev, + "total %lu msec (%lu packets)\n", + (packets * (1 << (desc->bInterval - 1))) + / ((udev->speed == USB_SPEED_HIGH) ? 8 : 1), + packets); + } spin_lock_irq(&context.lock); for (i = 0; i < param->sglen; i++) { @@ -1993,7 +2016,8 @@ test_iso_queue(struct usbtest_dev *dev, struct usbtest_param *param, ; else if (context.submit_error) status = -EACCES; - else if (context.errors > context.packet_count / 10) + else if (context.errors > + (context.is_iso ? context.packet_count / 10 : 0)) status = -EIO; return status; @@ -2014,8 +2038,8 @@ static int test_unaligned_bulk( const char *label) { int retval; - struct urb *urb = usbtest_alloc_urb( - testdev_to_usbdev(tdev), pipe, length, transfer_flags, 1, 0); + struct urb *urb = usbtest_alloc_urb(testdev_to_usbdev(tdev), + pipe, length, transfer_flags, 1, 0, simple_callback); if (!urb) return -ENOMEM; @@ -2342,7 +2366,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) param->iterations, param->sglen, param->length); /* FIRMWARE: iso sink */ - retval = test_iso_queue(dev, param, + retval = test_queue(dev, param, dev->out_iso_pipe, dev->iso_out, 0); break; @@ -2355,7 +2379,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) param->iterations, param->sglen, param->length); /* FIRMWARE: iso source */ - retval = test_iso_queue(dev, param, + retval = test_queue(dev, param, dev->in_iso_pipe, dev->iso_in, 0); break; @@ -2436,7 +2460,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 22: write %d iso odd, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); - retval = test_iso_queue(dev, param, + retval = test_queue(dev, param, dev->out_iso_pipe, dev->iso_out, 1); break; @@ -2447,7 +2471,7 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) "TEST 23: read %d iso odd, %d entries of %d bytes\n", param->iterations, param->sglen, param->length); - retval = test_iso_queue(dev, param, + retval = test_queue(dev, param, dev->in_iso_pipe, dev->iso_in, 1); break; @@ -2504,6 +2528,25 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) retval = simple_io(dev, urb, param->iterations, 0, 0, "test26"); simple_free_urb(urb); break; + case 27: + /* We do performance test, so ignore data compare */ + if (dev->out_pipe == 0 || param->sglen == 0 || pattern != 0) + break; + dev_info(&intf->dev, + "TEST 27: bulk write %dMbytes\n", (param->iterations * + param->sglen * param->length) / (1024 * 1024)); + retval = test_queue(dev, param, + dev->out_pipe, NULL, 0); + break; + case 28: + if (dev->in_pipe == 0 || param->sglen == 0 || pattern != 0) + break; + dev_info(&intf->dev, + "TEST 28: bulk read %dMbytes\n", (param->iterations * + param->sglen * param->length) / (1024 * 1024)); + retval = test_queue(dev, param, + dev->in_pipe, NULL, 0); + break; } do_gettimeofday(¶m->duration); param->duration.tv_sec -= start.tv_sec; -- cgit v1.2.3 From 758ed196fcc4373a129fd661875af52d7e7d4e73 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 14 Oct 2015 08:52:28 +0200 Subject: usb: dwc2: remove no longer needed init_mutex init_mutex is a leftover from the time, when s3c-hsotg driver did not implement proper pull up/down control and emulated it by enabling enabling/disabling usb phy. Proper pull up/down control has been added by commit 5b9451f8c4fbaf0549139755fb45ff2b57975b7f ("usb: dwc2: gadget: use soft-disconnect udc feature in pullup() method"), so init_muxtex can be removed now to avoid potential deadlocks with other locks. Signed-off-by: Marek Szyprowski Acked-by: John Youn Tested-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 1 - drivers/usb/dwc2/gadget.c | 17 ----------------- drivers/usb/dwc2/platform.c | 1 - 3 files changed, 19 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index ebf25045b4e8..89091db8cf02 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -712,7 +712,6 @@ struct dwc2_hsotg { struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)]; spinlock_t lock; - struct mutex init_mutex; void *priv; int irq; struct clk *clk; diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 7e5670c4532d..79d9f3bf5cf7 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -3193,7 +3193,6 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, return -EINVAL; } - mutex_lock(&hsotg->init_mutex); WARN_ON(hsotg->driver); driver->driver.bus = NULL; @@ -3220,12 +3219,9 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); - mutex_unlock(&hsotg->init_mutex); - return 0; err: - mutex_unlock(&hsotg->init_mutex); hsotg->driver = NULL; return ret; } @@ -3246,8 +3242,6 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) if (!hsotg) return -ENODEV; - mutex_lock(&hsotg->init_mutex); - /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) { if (hsotg->eps_in[ep]) @@ -3270,8 +3264,6 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); - mutex_unlock(&hsotg->init_mutex); - return 0; } @@ -3307,7 +3299,6 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) return 0; } - mutex_lock(&hsotg->init_mutex); spin_lock_irqsave(&hsotg->lock, flags); if (is_on) { hsotg->enabled = 1; @@ -3321,7 +3312,6 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on) hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); - mutex_unlock(&hsotg->init_mutex); return 0; } @@ -3832,8 +3822,6 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) if (hsotg->lx_state != DWC2_L0) return ret; - mutex_lock(&hsotg->init_mutex); - if (hsotg->driver) { int ep; @@ -3861,8 +3849,6 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) clk_disable(hsotg->clk); } - mutex_unlock(&hsotg->init_mutex); - return ret; } @@ -3874,8 +3860,6 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) if (hsotg->lx_state == DWC2_L2) return ret; - mutex_lock(&hsotg->init_mutex); - if (hsotg->driver) { dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name); @@ -3892,7 +3876,6 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) dwc2_hsotg_core_connect(hsotg); spin_unlock_irqrestore(&hsotg->lock, flags); } - mutex_unlock(&hsotg->init_mutex); return ret; } diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index b920e438cd49..581e9cad6800 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -252,7 +252,6 @@ static int dwc2_driver_probe(struct platform_device *dev) } spin_lock_init(&hsotg->lock); - mutex_init(&hsotg->init_mutex); /* Detect config values from hardware */ retval = dwc2_get_hwparams(hsotg); -- cgit v1.2.3 From 09a75e8577901489f77a14a3b305a9a1f67bf25b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 14 Oct 2015 08:52:29 +0200 Subject: usb: dwc2: refactor common low-level hw code to platform.c DWC2 module on some platforms needs three additional hardware resources: phy controller, clock and power supply. All of them must be enabled/activated to properly initialize and operate. This was initially handled in s3c-hsotg driver, which has been converted to 'gadget' part of dwc2 driver. Unfortunately, not all of this code got moved to common platform code, what resulted in accessing DWC2 registers without enabling low-level hardware resources. This fails for example on Exynos SoCs. This patch moves all the code for managing those resources to common platform.c file and provides convenient wrappers for controlling them. Signed-off-by: Marek Szyprowski Acked-by: John Youn Tested-by: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.h | 24 +++-- drivers/usb/dwc2/gadget.c | 186 ++++---------------------------------- drivers/usb/dwc2/platform.c | 216 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 210 insertions(+), 216 deletions(-) diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 89091db8cf02..a66d3cb62b65 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -579,6 +579,15 @@ struct dwc2_hregs_backup { * - USB_DR_MODE_PERIPHERAL * - USB_DR_MODE_HOST * - USB_DR_MODE_OTG + * @hcd_enabled Host mode sub-driver initialization indicator. + * @gadget_enabled Peripheral mode sub-driver initialization indicator. + * @ll_hw_enabled Status of low-level hardware resources. + * @phy: The otg phy transceiver structure for phy control. + * @uphy: The otg phy transceiver structure for old USB phy control. + * @plat: The platform specific configuration data. This can be removed once + * all SoCs support usb transceiver. + * @supplies: Definition of USB power supplies + * @phyif: PHY interface width * @lock: Spinlock that protects all the driver data structures * @priv: Stores a pointer to the struct usb_hcd * @queuing_high_bandwidth: True if multiple packets of a high-bandwidth @@ -671,12 +680,6 @@ struct dwc2_hregs_backup { * These are for peripheral mode: * * @driver: USB gadget driver - * @phy: The otg phy transceiver structure for phy control. - * @uphy: The otg phy transceiver structure for old USB phy control. - * @plat: The platform specific configuration data. This can be removed once - * all SoCs support usb transceiver. - * @supplies: Definition of USB power supplies - * @phyif: PHY interface width * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. * @num_of_eps: Number of available EPs (excluding EP0) * @debug_root: Root directrory for debugfs. @@ -706,10 +709,13 @@ struct dwc2_hsotg { enum usb_dr_mode dr_mode; unsigned int hcd_enabled:1; unsigned int gadget_enabled:1; + unsigned int ll_hw_enabled:1; struct phy *phy; struct usb_phy *uphy; + struct dwc2_hsotg_plat *plat; struct regulator_bulk_data supplies[ARRAY_SIZE(dwc2_hsotg_supply_names)]; + u32 phyif; spinlock_t lock; void *priv; @@ -812,9 +818,6 @@ struct dwc2_hsotg { #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || IS_ENABLED(CONFIG_USB_DWC2_DUAL_ROLE) /* Gadget structures */ struct usb_gadget_driver *driver; - struct dwc2_hsotg_plat *plat; - - u32 phyif; int fifo_mem; unsigned int dedicated_fifos:1; unsigned char num_of_eps; @@ -1103,7 +1106,8 @@ extern void dwc2_set_all_params(struct dwc2_core_params *params, int value); extern int dwc2_get_hwparams(struct dwc2_hsotg *hsotg); - +extern int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg); +extern int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg); /* * Dump core registers and SPRAM diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 79d9f3bf5cf7..0abf73c91beb 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -25,15 +25,11 @@ #include #include #include -#include -#include #include -#include #include #include #include -#include #include "core.h" #include "hw.h" @@ -3076,50 +3072,6 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = { /* note, don't believe we have any call for the fifo routines */ }; -/** - * dwc2_hsotg_phy_enable - enable platform phy dev - * @hsotg: The driver state - * - * A wrapper for platform code responsible for controlling - * low-level USB code - */ -static void dwc2_hsotg_phy_enable(struct dwc2_hsotg *hsotg) -{ - struct platform_device *pdev = to_platform_device(hsotg->dev); - - dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); - - if (hsotg->uphy) - usb_phy_init(hsotg->uphy); - else if (hsotg->plat && hsotg->plat->phy_init) - hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); - else { - phy_init(hsotg->phy); - phy_power_on(hsotg->phy); - } -} - -/** - * dwc2_hsotg_phy_disable - disable platform phy dev - * @hsotg: The driver state - * - * A wrapper for platform code responsible for controlling - * low-level USB code - */ -static void dwc2_hsotg_phy_disable(struct dwc2_hsotg *hsotg) -{ - struct platform_device *pdev = to_platform_device(hsotg->dev); - - if (hsotg->uphy) - usb_phy_shutdown(hsotg->uphy); - else if (hsotg->plat && hsotg->plat->phy_exit) - hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); - else { - phy_power_off(hsotg->phy); - phy_exit(hsotg->phy); - } -} - /** * dwc2_hsotg_init - initalize the usb core * @hsotg: The driver state @@ -3200,14 +3152,12 @@ static int dwc2_hsotg_udc_start(struct usb_gadget *gadget, hsotg->gadget.dev.of_node = hsotg->dev->of_node; hsotg->gadget.speed = USB_SPEED_UNKNOWN; - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - if (ret) { - dev_err(hsotg->dev, "failed to enable supplies: %d\n", ret); - goto err; + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) { + ret = dwc2_lowlevel_hw_enable(hsotg); + if (ret) + goto err; } - dwc2_hsotg_phy_enable(hsotg); if (!IS_ERR_OR_NULL(hsotg->uphy)) otg_set_peripheral(hsotg->uphy->otg, &hsotg->gadget); @@ -3260,9 +3210,9 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) if (!IS_ERR_OR_NULL(hsotg->uphy)) otg_set_peripheral(hsotg->uphy->otg, NULL); - dwc2_hsotg_phy_disable(hsotg); - regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); return 0; } @@ -3602,15 +3552,11 @@ static inline void dwc2_hsotg_of_probe(struct dwc2_hsotg *hsotg) { } int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) { struct device *dev = hsotg->dev; - struct dwc2_hsotg_plat *plat = dev->platform_data; int epnum; int ret; int i; u32 p_tx_fifo[] = DWC2_G_P_LEGACY_TX_FIFO_SIZE; - /* Set default UTMI width */ - hsotg->phyif = GUSBCFG_PHYIF16; - /* Initialize to legacy fifo configuration values */ hsotg->g_rx_fifo_sz = 2048; hsotg->g_np_g_tx_fifo_sz = 1024; @@ -3624,32 +3570,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) for (i = 0; i < MAX_EPS_CHANNELS; i++) dev_dbg(dev, "Periodic TXFIFO%2d size: %d\n", i, hsotg->g_tx_fifo_sz[i]); - /* - * If platform probe couldn't find a generic PHY or an old style - * USB PHY, fall back to pdata - */ - if (IS_ERR_OR_NULL(hsotg->phy) && IS_ERR_OR_NULL(hsotg->uphy)) { - plat = dev_get_platdata(dev); - if (!plat) { - dev_err(dev, - "no platform data or transceiver defined\n"); - return -EPROBE_DEFER; - } - hsotg->plat = plat; - } else if (hsotg->phy) { - /* - * If using the generic PHY framework, check if the PHY bus - * width is 8-bit and set the phyif appropriately. - */ - if (phy_get_bus_width(hsotg->phy) == 8) - hsotg->phyif = GUSBCFG_PHYIF8; - } - - hsotg->clk = devm_clk_get(dev, "otg"); - if (IS_ERR(hsotg->clk)) { - hsotg->clk = NULL; - dev_dbg(dev, "cannot get otg clock\n"); - } hsotg->gadget.max_speed = USB_SPEED_HIGH; hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; @@ -3659,38 +3579,6 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) else if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) hsotg->op_state = OTG_STATE_B_PERIPHERAL; - /* reset the system */ - - ret = clk_prepare_enable(hsotg->clk); - if (ret) { - dev_err(dev, "failed to enable otg clk\n"); - goto err_clk; - } - - - /* regulators */ - - for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) - hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; - - ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - if (ret) { - dev_err(dev, "failed to request supplies: %d\n", ret); - goto err_clk; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - - if (ret) { - dev_err(dev, "failed to enable supplies: %d\n", ret); - goto err_clk; - } - - /* usb phy enable */ - dwc2_hsotg_phy_enable(hsotg); - /* * Force Device mode before initialization. * This allows correctly configuring fifo for device mode. @@ -3708,7 +3596,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) ret = dwc2_hsotg_hw_cfg(hsotg); if (ret) { dev_err(hsotg->dev, "Hardware configuration failed: %d\n", ret); - goto err_clk; + return ret; } dwc2_hsotg_init(hsotg); @@ -3720,35 +3608,28 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); if (!hsotg->ctrl_buff) { dev_err(dev, "failed to allocate ctrl request buff\n"); - ret = -ENOMEM; - goto err_supplies; + return -ENOMEM; } hsotg->ep0_buff = devm_kzalloc(hsotg->dev, DWC2_CTRL_BUFF_SIZE, GFP_KERNEL); if (!hsotg->ep0_buff) { dev_err(dev, "failed to allocate ctrl reply buff\n"); - ret = -ENOMEM; - goto err_supplies; + return -ENOMEM; } ret = devm_request_irq(hsotg->dev, irq, dwc2_hsotg_irq, IRQF_SHARED, dev_name(hsotg->dev), hsotg); if (ret < 0) { - dwc2_hsotg_phy_disable(hsotg); - clk_disable_unprepare(hsotg->clk); - regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); dev_err(dev, "cannot claim IRQ for gadget\n"); - goto err_supplies; + return ret; } /* hsotg->num_of_eps holds number of EPs other than ep0 */ if (hsotg->num_of_eps == 0) { dev_err(dev, "wrong number of EPs (zero)\n"); - ret = -EINVAL; - goto err_supplies; + return -EINVAL; } /* setup endpoint information */ @@ -3762,8 +3643,7 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) GFP_KERNEL); if (!hsotg->ctrl_req) { dev_err(dev, "failed to allocate ctrl req\n"); - ret = -ENOMEM; - goto err_supplies; + return -ENOMEM; } /* initialise the endpoints now the core has been initialised */ @@ -3776,30 +3656,13 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg, int irq) epnum, 0); } - /* disable power and clock */ - dwc2_hsotg_phy_disable(hsotg); - - ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - if (ret) { - dev_err(dev, "failed to disable supplies: %d\n", ret); - goto err_supplies; - } - ret = usb_add_gadget_udc(dev, &hsotg->gadget); if (ret) - goto err_supplies; + return ret; dwc2_hsotg_dump(hsotg); return 0; - -err_supplies: - dwc2_hsotg_phy_disable(hsotg); -err_clk: - clk_disable_unprepare(hsotg->clk); - - return ret; } /** @@ -3809,7 +3672,6 @@ err_clk: int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg) { usb_del_gadget_udc(&hsotg->gadget); - clk_disable_unprepare(hsotg->clk); return 0; } @@ -3817,10 +3679,9 @@ int dwc2_hsotg_remove(struct dwc2_hsotg *hsotg) int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) { unsigned long flags; - int ret = 0; if (hsotg->lx_state != DWC2_L0) - return ret; + return 0; if (hsotg->driver) { int ep; @@ -3835,41 +3696,28 @@ int dwc2_hsotg_suspend(struct dwc2_hsotg *hsotg) hsotg->gadget.speed = USB_SPEED_UNKNOWN; spin_unlock_irqrestore(&hsotg->lock, flags); - dwc2_hsotg_phy_disable(hsotg); - for (ep = 0; ep < hsotg->num_of_eps; ep++) { if (hsotg->eps_in[ep]) dwc2_hsotg_ep_disable(&hsotg->eps_in[ep]->ep); if (hsotg->eps_out[ep]) dwc2_hsotg_ep_disable(&hsotg->eps_out[ep]->ep); } - - ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - clk_disable(hsotg->clk); } - return ret; + return 0; } int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) { unsigned long flags; - int ret = 0; if (hsotg->lx_state == DWC2_L2) - return ret; + return 0; if (hsotg->driver) { dev_info(hsotg->dev, "resuming usb gadget %s\n", hsotg->driver->driver.name); - clk_enable(hsotg->clk); - ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), - hsotg->supplies); - - dwc2_hsotg_phy_enable(hsotg); - spin_lock_irqsave(&hsotg->lock, flags); dwc2_hsotg_core_init_disconnected(hsotg, false); if (hsotg->enabled) @@ -3877,5 +3725,5 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg) spin_unlock_irqrestore(&hsotg->lock, flags); } - return ret; + return 0; } diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 581e9cad6800..5859b0fa19ee 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -37,11 +37,14 @@ #include #include #include +#include #include #include #include #include #include +#include +#include #include @@ -111,6 +114,145 @@ static const struct dwc2_core_params params_rk3066 = { .hibernation = -1, }; +static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) +{ + struct platform_device *pdev = to_platform_device(hsotg->dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), + hsotg->supplies); + if (ret) + return ret; + + ret = clk_prepare_enable(hsotg->clk); + if (ret) + return ret; + + if (hsotg->uphy) + ret = usb_phy_init(hsotg->uphy); + else if (hsotg->plat && hsotg->plat->phy_init) + ret = hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); + else { + ret = phy_power_on(hsotg->phy); + if (ret == 0) + ret = phy_init(hsotg->phy); + } + + return ret; +} + +/** + * dwc2_lowlevel_hw_enable - enable platform lowlevel hw resources + * @hsotg: The driver state + * + * A wrapper for platform code responsible for controlling + * low-level USB platform resources (phy, clock, regulators) + */ +int dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) +{ + int ret = __dwc2_lowlevel_hw_enable(hsotg); + + if (ret == 0) + hsotg->ll_hw_enabled = true; + return ret; +} + +static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) +{ + struct platform_device *pdev = to_platform_device(hsotg->dev); + int ret = 0; + + if (hsotg->uphy) + usb_phy_shutdown(hsotg->uphy); + else if (hsotg->plat && hsotg->plat->phy_exit) + ret = hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); + else { + ret = phy_exit(hsotg->phy); + if (ret == 0) + ret = phy_power_off(hsotg->phy); + } + if (ret) + return ret; + + clk_disable_unprepare(hsotg->clk); + + ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), + hsotg->supplies); + + return ret; +} + +/** + * dwc2_lowlevel_hw_disable - disable platform lowlevel hw resources + * @hsotg: The driver state + * + * A wrapper for platform code responsible for controlling + * low-level USB platform resources (phy, clock, regulators) + */ +int dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) +{ + int ret = __dwc2_lowlevel_hw_disable(hsotg); + + if (ret == 0) + hsotg->ll_hw_enabled = false; + return ret; +} + +static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) +{ + int i, ret; + + /* Set default UTMI width */ + hsotg->phyif = GUSBCFG_PHYIF16; + + /* + * Attempt to find a generic PHY, then look for an old style + * USB PHY and then fall back to pdata + */ + hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); + if (IS_ERR(hsotg->phy)) { + hsotg->phy = NULL; + hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2); + if (IS_ERR(hsotg->uphy)) + hsotg->uphy = NULL; + else + hsotg->plat = dev_get_platdata(hsotg->dev); + } + + if (hsotg->phy) { + /* + * If using the generic PHY framework, check if the PHY bus + * width is 8-bit and set the phyif appropriately. + */ + if (phy_get_bus_width(hsotg->phy) == 8) + hsotg->phyif = GUSBCFG_PHYIF8; + } + + if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) { + dev_err(hsotg->dev, "no platform data or transceiver defined\n"); + return -EPROBE_DEFER; + } + + /* Clock */ + hsotg->clk = devm_clk_get(hsotg->dev, "otg"); + if (IS_ERR(hsotg->clk)) { + hsotg->clk = NULL; + dev_dbg(hsotg->dev, "cannot get otg clock\n"); + } + + /* Regulators */ + for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) + hsotg->supplies[i].supply = dwc2_hsotg_supply_names[i]; + + ret = devm_regulator_bulk_get(hsotg->dev, ARRAY_SIZE(hsotg->supplies), + hsotg->supplies); + if (ret) { + dev_err(hsotg->dev, "failed to request supplies: %d\n", ret); + return ret; + } + return 0; +} + /** * dwc2_driver_remove() - Called when the DWC_otg core is unregistered with the * DWC_otg driver @@ -132,6 +274,9 @@ static int dwc2_driver_remove(struct platform_device *dev) if (hsotg->gadget_enabled) dwc2_hsotg_remove(hsotg); + if (hsotg->ll_hw_enabled) + dwc2_lowlevel_hw_disable(hsotg); + return 0; } @@ -163,8 +308,6 @@ static int dwc2_driver_probe(struct platform_device *dev) struct dwc2_core_params defparams; struct dwc2_hsotg *hsotg; struct resource *res; - struct phy *phy; - struct usb_phy *uphy; int retval; int irq; @@ -233,31 +376,12 @@ static int dwc2_driver_probe(struct platform_device *dev) "Configuration mismatch. Forcing peripheral mode\n"); } - /* - * Attempt to find a generic PHY, then look for an old style - * USB PHY - */ - phy = devm_phy_get(&dev->dev, "usb2-phy"); - if (IS_ERR(phy)) { - hsotg->phy = NULL; - uphy = devm_usb_get_phy(&dev->dev, USB_PHY_TYPE_USB2); - if (IS_ERR(uphy)) - hsotg->uphy = NULL; - else - hsotg->uphy = uphy; - } else { - hsotg->phy = phy; - phy_power_on(hsotg->phy); - phy_init(hsotg->phy); - } - - spin_lock_init(&hsotg->lock); - - /* Detect config values from hardware */ - retval = dwc2_get_hwparams(hsotg); + retval = dwc2_lowlevel_hw_init(hsotg); if (retval) return retval; + spin_lock_init(&hsotg->lock); + hsotg->core_params = devm_kzalloc(&dev->dev, sizeof(*hsotg->core_params), GFP_KERNEL); if (!hsotg->core_params) @@ -265,13 +389,22 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_set_all_params(hsotg->core_params, -1); + retval = dwc2_lowlevel_hw_enable(hsotg); + if (retval) + return retval; + + /* Detect config values from hardware */ + retval = dwc2_get_hwparams(hsotg); + if (retval) + goto error; + /* Validate parameter values */ dwc2_set_parameters(hsotg, params); if (hsotg->dr_mode != USB_DR_MODE_HOST) { retval = dwc2_gadget_init(hsotg, irq); if (retval) - return retval; + goto error; hsotg->gadget_enabled = 1; } @@ -280,7 +413,7 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) { if (hsotg->gadget_enabled) dwc2_hsotg_remove(hsotg); - return retval; + goto error; } hsotg->hcd_enabled = 1; } @@ -289,6 +422,14 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_debugfs_init(hsotg); + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + + return 0; + +error: + dwc2_lowlevel_hw_disable(hsotg); return retval; } @@ -297,13 +438,12 @@ static int __maybe_unused dwc2_suspend(struct device *dev) struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; - if (dwc2_is_device_mode(dwc2)) { - ret = dwc2_hsotg_suspend(dwc2); - } else { - phy_exit(dwc2->phy); - phy_power_off(dwc2->phy); + if (dwc2_is_device_mode(dwc2)) + dwc2_hsotg_suspend(dwc2); + + if (dwc2->ll_hw_enabled) + ret = __dwc2_lowlevel_hw_disable(dwc2); - } return ret; } @@ -312,13 +452,15 @@ static int __maybe_unused dwc2_resume(struct device *dev) struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); int ret = 0; - if (dwc2_is_device_mode(dwc2)) { + if (dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) + return ret; + } + + if (dwc2_is_device_mode(dwc2)) ret = dwc2_hsotg_resume(dwc2); - } else { - phy_power_on(dwc2->phy); - phy_init(dwc2->phy); - } return ret; } -- cgit v1.2.3 From 897ee0e85e5fad3109264af5b517a1ebb82912c3 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 14 Oct 2015 16:07:14 +0200 Subject: usb: gadget: f_sourcesink: fix function params handling Move function parameters to struct f_sourcesink to make them per instance instead of having them as global variables. Since we can have multiple instances of USB function we also want to have separate set of parameters for each instance. Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_sourcesink.c | 120 +++++++++++++++-------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 68efa01bdf4d..d7646d3acd63 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -50,6 +50,13 @@ struct f_sourcesink { struct usb_ep *iso_in_ep; struct usb_ep *iso_out_ep; int cur_alt; + + unsigned pattern; + unsigned isoc_interval; + unsigned isoc_maxpacket; + unsigned isoc_mult; + unsigned isoc_maxburst; + unsigned buflen; }; static inline struct f_sourcesink *func_to_ss(struct usb_function *f) @@ -57,13 +64,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) return container_of(f, struct f_sourcesink, function); } -static unsigned pattern; -static unsigned isoc_interval; -static unsigned isoc_maxpacket; -static unsigned isoc_mult; -static unsigned isoc_maxburst; -static unsigned buflen; - /*-------------------------------------------------------------------------*/ static struct usb_interface_descriptor source_sink_intf_alt0 = { @@ -298,7 +298,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = { static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) { - return alloc_ep_req(ep, len, buflen); + struct f_sourcesink *ss = ep->driver_data; + + return alloc_ep_req(ep, len, ss->buflen); } void free_ep_req(struct usb_ep *ep, struct usb_request *req) @@ -357,22 +359,22 @@ autoconf_fail: goto autoconf_fail; /* sanity check the isoc module parameters */ - if (isoc_interval < 1) - isoc_interval = 1; - if (isoc_interval > 16) - isoc_interval = 16; - if (isoc_mult > 2) - isoc_mult = 2; - if (isoc_maxburst > 15) - isoc_maxburst = 15; + if (ss->isoc_interval < 1) + ss->isoc_interval = 1; + if (ss->isoc_interval > 16) + ss->isoc_interval = 16; + if (ss->isoc_mult > 2) + ss->isoc_mult = 2; + if (ss->isoc_maxburst > 15) + ss->isoc_maxburst = 15; /* fill in the FS isoc descriptors from the module parameters */ - fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; - fs_iso_source_desc.bInterval = isoc_interval; - fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; - fs_iso_sink_desc.bInterval = isoc_interval; + fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; + fs_iso_source_desc.bInterval = ss->isoc_interval; + fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; + fs_iso_sink_desc.bInterval = ss->isoc_interval; /* allocate iso endpoints */ ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc); @@ -394,8 +396,8 @@ no_iso: ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL; } - if (isoc_maxpacket > 1024) - isoc_maxpacket = 1024; + if (ss->isoc_maxpacket > 1024) + ss->isoc_maxpacket = 1024; /* support high speed hardware */ hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; @@ -406,15 +408,15 @@ no_iso: * We assume that the user knows what they are doing and won't * give parameters that their UDC doesn't support. */ - hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_source_desc.bInterval = isoc_interval; + hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket; + hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11; + hs_iso_source_desc.bInterval = ss->isoc_interval; hs_iso_source_desc.bEndpointAddress = fs_iso_source_desc.bEndpointAddress; - hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_sink_desc.bInterval = isoc_interval; + hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket; + hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11; + hs_iso_sink_desc.bInterval = ss->isoc_interval; hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; /* support super speed hardware */ @@ -428,21 +430,21 @@ no_iso: * We assume that the user knows what they are doing and won't * give parameters that their UDC doesn't support. */ - ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_source_desc.bInterval = isoc_interval; - ss_iso_source_comp_desc.bmAttributes = isoc_mult; - ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_source_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket; + ss_iso_source_desc.bInterval = ss->isoc_interval; + ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult; + ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst; + ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1); ss_iso_source_desc.bEndpointAddress = fs_iso_source_desc.bEndpointAddress; - ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_sink_desc.bInterval = isoc_interval; - ss_iso_sink_comp_desc.bmAttributes = isoc_mult; - ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_sink_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket; + ss_iso_sink_desc.bInterval = ss->isoc_interval; + ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult; + ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst; + ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1); ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_source_sink_descs, @@ -482,11 +484,11 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) struct usb_composite_dev *cdev = ss->function.config->cdev; int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize); - if (pattern == 2) + if (ss->pattern == 2) return 0; for (i = 0; i < req->actual; i++, buf++) { - switch (pattern) { + switch (ss->pattern) { /* all-zeroes has no synchronization issues */ case 0: @@ -518,8 +520,9 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) unsigned i; u8 *buf = req->buf; int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize); + struct f_sourcesink *ss = ep->driver_data; - switch (pattern) { + switch (ss->pattern) { case 0: memset(req->buf, 0, req->length); break; @@ -549,7 +552,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) case 0: /* normal completion? */ if (ep == ss->out_ep) { check_read_data(ss, req); - if (pattern != 2) + if (ss->pattern != 2) memset(req->buf, 0x55, req->length); } break; @@ -598,15 +601,16 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, if (is_iso) { switch (speed) { case USB_SPEED_SUPER: - size = isoc_maxpacket * (isoc_mult + 1) * - (isoc_maxburst + 1); + size = ss->isoc_maxpacket * + (ss->isoc_mult + 1) * + (ss->isoc_maxburst + 1); break; case USB_SPEED_HIGH: - size = isoc_maxpacket * (isoc_mult + 1); + size = ss->isoc_maxpacket * (ss->isoc_mult + 1); break; default: - size = isoc_maxpacket > 1023 ? - 1023 : isoc_maxpacket; + size = ss->isoc_maxpacket > 1023 ? + 1023 : ss->isoc_maxpacket; break; } ep = is_in ? ss->iso_in_ep : ss->iso_out_ep; @@ -622,7 +626,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, req->complete = source_sink_complete; if (is_in) reinit_write_data(ep, req); - else if (pattern != 2) + else if (ss->pattern != 2) memset(req->buf, 0x55, req->length); status = usb_ep_queue(ep, req, GFP_ATOMIC); @@ -859,12 +863,12 @@ static struct usb_function *source_sink_alloc_func( ss_opts->refcnt++; mutex_unlock(&ss_opts->lock); - pattern = ss_opts->pattern; - isoc_interval = ss_opts->isoc_interval; - isoc_maxpacket = ss_opts->isoc_maxpacket; - isoc_mult = ss_opts->isoc_mult; - isoc_maxburst = ss_opts->isoc_maxburst; - buflen = ss_opts->bulk_buflen; + ss->pattern = ss_opts->pattern; + ss->isoc_interval = ss_opts->isoc_interval; + ss->isoc_maxpacket = ss_opts->isoc_maxpacket; + ss->isoc_mult = ss_opts->isoc_mult; + ss->isoc_maxburst = ss_opts->isoc_maxburst; + ss->buflen = ss_opts->bulk_buflen; ss->function.name = "source/sink"; ss->function.bind = sourcesink_bind; -- cgit v1.2.3 From 3e9d992f93fecc746baa9d4854acc026d422094f Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Wed, 14 Oct 2015 23:03:34 +0200 Subject: usb: gadget: loopback: fix: Don't share qlen and buflen between instances Each instance of loopback function may have different qlen and buflen attributes values. When linking function to configuration those values had been assigned to global variables. Linking other instance to config overwrites those values. This commit moves those values to f_loopback structure to avoid overwriting. Now each function has its own instance of those values. Signed-off-by: Krzysztof Opasiak Reviewed-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_loopback.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index abfdb92bde64..79e284bba059 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -34,6 +34,9 @@ struct f_loopback { struct usb_ep *in_ep; struct usb_ep *out_ep; + + unsigned qlen; + unsigned buflen; }; static inline struct f_loopback *func_to_loop(struct usb_function *f) @@ -41,13 +44,10 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f) return container_of(f, struct f_loopback, function); } -static unsigned qlen; -static unsigned buflen; - /*-------------------------------------------------------------------------*/ static struct usb_interface_descriptor loopback_intf = { - .bLength = sizeof loopback_intf, + .bLength = sizeof(loopback_intf), .bDescriptorType = USB_DT_INTERFACE, .bNumEndpoints = 2, @@ -251,7 +251,7 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) } /* queue the buffer for some later OUT packet */ - req->length = buflen; + req->length = loop->buflen; status = usb_ep_queue(ep, req, GFP_ATOMIC); if (status == 0) return; @@ -288,7 +288,9 @@ static void disable_loopback(struct f_loopback *loop) static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) { - return alloc_ep_req(ep, len, buflen); + struct f_loopback *loop = ep->driver_data; + + return alloc_ep_req(ep, len, loop->buflen); } static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop, @@ -315,7 +317,7 @@ static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *lo * we buffer at most 'qlen' transfers; fewer if any need more * than 'buflen' bytes each. */ - for (i = 0; i < qlen && result == 0; i++) { + for (i = 0; i < loop->qlen && result == 0; i++) { req = lb_alloc_ep_req(ep, 0); if (!req) goto fail1; @@ -388,10 +390,10 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi) lb_opts->refcnt++; mutex_unlock(&lb_opts->lock); - buflen = lb_opts->bulk_buflen; - qlen = lb_opts->qlen; - if (!qlen) - qlen = 32; + loop->buflen = lb_opts->bulk_buflen; + loop->qlen = lb_opts->qlen; + if (!loop->qlen) + loop->qlen = 32; loop->function.name = "loopback"; loop->function.bind = loopback_bind; -- cgit v1.2.3 From 91c42b0da8e353697c9b49fe541056c5d0518c49 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Wed, 14 Oct 2015 22:49:40 +0200 Subject: usb: gadget: loopback: Fix looping back logic implementation Since commit e0857ce58e8658657f5f12fe25272b93cfeb16aa ("usb: gadget: loopback: don't queue requests to bogus endpoints") Loopback function is not realy working as that commit removed all looping back logic. After that commit ep-out works like /dev/null and ep-in works like /dev/zero. This commit fix this issue by allocating set of out requests and set of in requests but each out req shares buffer with one in req: out_req->buf ---> buf <--- in_req.buf out_req->context <---> in_req.context The completion routine simply enqueue the suitable req in an oposite direction. Cc: # 3.18+ Fixes: e0857ce58e8658657f5f12fe25272b93cfeb16aa ("usb: gadget: loopback: don't queue requests to bogus endpoints") Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_loopback.c | 131 ++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 39 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 79e284bba059..6b2102bc0699 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -243,22 +243,38 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) int status = req->status; switch (status) { - case 0: /* normal completion? */ if (ep == loop->out_ep) { - req->zero = (req->actual < req->length); - req->length = req->actual; + /* + * We received some data from the host so let's + * queue it so host can read the from our in ep + */ + struct usb_request *in_req = req->context; + + in_req->zero = (req->actual < req->length); + in_req->length = req->actual; + ep = loop->in_ep; + req = in_req; + } else { + /* + * We have just looped back a bunch of data + * to host. Now let's wait for some more data. + */ + req = req->context; + ep = loop->out_ep; } - /* queue the buffer for some later OUT packet */ - req->length = loop->buflen; + /* queue the buffer back to host or for next bunch of data */ status = usb_ep_queue(ep, req, GFP_ATOMIC); - if (status == 0) + if (status == 0) { return; + } else { + ERROR(cdev, "Unable to loop back buffer to %s: %d\n", + ep->name, status); + goto free_req; + } /* "should never get here" */ - /* FALLTHROUGH */ - default: ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); @@ -272,6 +288,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ +free_req: + usb_ep_free_request(ep == loop->in_ep ? + loop->out_ep : loop->in_ep, + req->context); free_ep_req(ep, req); return; } @@ -293,50 +313,72 @@ static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) return alloc_ep_req(ep, len, loop->buflen); } -static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop, - struct usb_ep *ep) +static int alloc_requests(struct usb_composite_dev *cdev, + struct f_loopback *loop) { - struct usb_request *req; - unsigned i; - int result; - - /* - * one endpoint writes data back IN to the host while another endpoint - * just reads OUT packets - */ - result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); - if (result) - goto fail0; - result = usb_ep_enable(ep); - if (result < 0) - goto fail0; - ep->driver_data = loop; + struct usb_request *in_req, *out_req; + int i; + int result = 0; /* * allocate a bunch of read buffers and queue them all at once. - * we buffer at most 'qlen' transfers; fewer if any need more - * than 'buflen' bytes each. + * we buffer at most 'qlen' transfers; We allocate buffers only + * for out transfer and reuse them in IN transfers to implement + * our loopback functionality */ for (i = 0; i < loop->qlen && result == 0; i++) { - req = lb_alloc_ep_req(ep, 0); - if (!req) - goto fail1; + result = -ENOMEM; + + in_req = usb_ep_alloc_request(loop->in_ep, GFP_KERNEL); + if (!in_req) + goto fail; + + out_req = lb_alloc_ep_req(loop->out_ep, 0); + if (!out_req) + goto fail_in; + + in_req->complete = loopback_complete; + out_req->complete = loopback_complete; + + in_req->buf = out_req->buf; + /* length will be set in complete routine */ + in_req->context = out_req; + out_req->context = in_req; - req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); + result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC); if (result) { ERROR(cdev, "%s queue req --> %d\n", - ep->name, result); - goto fail1; + loop->out_ep->name, result); + goto fail_out; } } return 0; -fail1: - usb_ep_disable(ep); +fail_out: + free_ep_req(loop->out_ep, out_req); +fail_in: + usb_ep_free_request(loop->in_ep, in_req); +fail: + return result; +} + +static int enable_endpoint(struct usb_composite_dev *cdev, + struct f_loopback *loop, struct usb_ep *ep) +{ + int result; + + result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); + if (result) + goto out; -fail0: + result = usb_ep_enable(ep); + if (result < 0) + goto out; + ep->driver_data = loop; + result = 0; + +out: return result; } @@ -347,13 +389,24 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) result = enable_endpoint(cdev, loop, loop->in_ep); if (result) - return result; + goto out; result = enable_endpoint(cdev, loop, loop->out_ep); if (result) - return result; + goto disable_in; + + result = alloc_requests(cdev, loop); + if (result) + goto disable_out; DBG(cdev, "%s enabled\n", loop->function.name); + return 0; + +disable_out: + usb_ep_disable(loop->out_ep); +disable_in: + usb_ep_disable(loop->in_ep); +out: return result; } -- cgit v1.2.3 From 3bbafac83775425d0abb68cf9837ee3ca36adb42 Mon Sep 17 00:00:00 2001 From: Roman Alyautdin Date: Mon, 12 Oct 2015 17:14:32 +0300 Subject: usb: musb: core: add common method of getting vbus status Fix musb_platform_get_vbus_status return value in case of platform implementation is not defined, bringing expected behaviour of musb_platform_get wrapper. Add musb_vbus_show default method to determine VBUS status in case platform method is not defined. Signed-off-by: Roman Alyautdin Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 13 ++++++++++--- drivers/usb/musb/musb_core.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index e0e10dd424e0..ba13529cbd52 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1775,13 +1775,20 @@ musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) unsigned long flags; unsigned long val; int vbus; + u8 devctl; spin_lock_irqsave(&musb->lock, flags); val = musb->a_wait_bcon; - /* FIXME get_vbus_status() is normally #defined as false... - * and is effectively TUSB-specific. - */ vbus = musb_platform_get_vbus_status(musb); + if (vbus < 0) { + /* Use default MUSB method by means of DEVCTL register */ + devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + if ((devctl & MUSB_DEVCTL_VBUS) + == (3 << MUSB_DEVCTL_VBUS_SHIFT)) + vbus = 1; + else + vbus = 0; + } spin_unlock_irqrestore(&musb->lock, flags); return sprintf(buf, "Vbus %s, timeout %lu msec\n", diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 4b886d0f6bdf..2337d7a7d62d 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -579,7 +579,7 @@ static inline int musb_platform_recover(struct musb *musb) static inline int musb_platform_get_vbus_status(struct musb *musb) { if (!musb->ops->vbus_status) - return 0; + return -EINVAL; return musb->ops->vbus_status(musb); } -- cgit v1.2.3 From 4d273c2af0fe4fdc84eef27e4521694dc7992065 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 14 Oct 2015 15:58:27 -0700 Subject: usb: dwc2: host: Protect PCGCTL with lock in dwc2_port_resume() From code inspection, it appears to be unsafe to do a read-modify-write of PCGCTL in dwc2_port_resume(). Let's make sure the spinlock is held around this operation. Acked-by: John Youn Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index af4e4a27126f..e79baf73c234 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -1500,6 +1500,8 @@ static void dwc2_port_resume(struct dwc2_hsotg *hsotg) u32 hprt0; u32 pcgctl; + spin_lock_irqsave(&hsotg->lock, flags); + /* * If hibernation is supported, Phy clock is already resumed * after registers restore. @@ -1508,10 +1510,11 @@ static void dwc2_port_resume(struct dwc2_hsotg *hsotg) pcgctl = dwc2_readl(hsotg->regs + PCGCTL); pcgctl &= ~PCGCTL_STOPPCLK; dwc2_writel(pcgctl, hsotg->regs + PCGCTL); + spin_unlock_irqrestore(&hsotg->lock, flags); usleep_range(20000, 40000); + spin_lock_irqsave(&hsotg->lock, flags); } - spin_lock_irqsave(&hsotg->lock, flags); hprt0 = dwc2_read_hprt0(hsotg); hprt0 |= HPRT0_RES; hprt0 &= ~HPRT0_SUSP; -- cgit v1.2.3 From ebd293857797e437fc18f2fb98bf4c63b1d1f381 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 18 Oct 2015 23:31:15 +0800 Subject: usb: gadget: fix a trivial typo s/regsiter/register/ Signed-off-by: Geliang Tang Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/pch_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 3181fc9c1c49..7a04157ff579 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -330,7 +330,7 @@ struct pch_vbus_gpio_data { * @prot_stall: protcol stall requested * @irq_registered: irq registered with system * @mem_region: device memory mapped - * @registered: driver regsitered with system + * @registered: driver registered with system * @suspended: driver in suspended state * @connected: gadget driver associated * @vbus_session: required vbus_session state -- cgit v1.2.3 From dc8730846948e517169f630826cd2c97615f5ee8 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Fri, 16 Oct 2015 16:01:32 -0700 Subject: usb: dwc2: host: Fix use after free w/ simultaneous irqs While plugging / unplugging on a DWC2 host port with "slub_debug=FZPUA" enabled, I found a crash that was quite obviously a use after free. It appears that in some cases when we handle the various sub-cases of HCINT we may end up freeing the QTD. If there is more than one bit set in HCINT we may then end up continuing to use the QTD, which is bad. Let's be paranoid and check for this after each sub-case. This should be safe since we officially have the "hsotg->lock" (it was grabbed in dwc2_handle_hcd_intr). The specific crash I found was: Unable to handle kernel paging request at virtual address 6b6b6b9f At the time of the crash, the kernel reported: (dwc2_hc_nak_intr+0x5c/0x198) (dwc2_handle_hcd_intr+0xa84/0xbf8) (_dwc2_hcd_irq+0x1c/0x20) (usb_hcd_irq+0x34/0x48) Popping into kgdb found that "*qtd" was filled with "0x6b", AKA qtd had been freed and filled with slub_debug poison. kgdb gave a little better stack crawl: 0 dwc2_hc_nak_intr (hsotg=hsotg@entry=0xec42e058, chan=chan@entry=0xec546dc0, chnum=chnum@entry=4, qtd=qtd@entry=0xec679600) at drivers/usb/dwc2/hcd_intr.c:1237 1 dwc2_hc_n_intr (chnum=4, hsotg=0xec42e058) at drivers/usb/dwc2/hcd_intr.c:2041 2 dwc2_hc_intr (hsotg=0xec42e058) at drivers/usb/dwc2/hcd_intr.c:2078 3 dwc2_handle_hcd_intr (hsotg=0xec42e058) at drivers/usb/dwc2/hcd_intr.c:2128 4 _dwc2_hcd_irq (hcd=) at drivers/usb/dwc2/hcd.c:2837 5 usb_hcd_irq (irq=, __hcd=) at drivers/usb/core/hcd.c:2353 Popping up to frame #1 (dwc2_hc_n_intr) found: (gdb) print /x hcint $12 = 0x12 AKA: #define HCINTMSK_CHHLTD (1 << 1) #define HCINTMSK_NAK (1 << 4) Further debugging found that by simulating receiving those two interrupts at the same time it was trivial to replicate the use-after-free. See for a patch and instructions. This lead to getting the following stack crawl of the actual free: 0 arch_kgdb_breakpoint () at arch/arm/include/asm/outercache.h:103 1 kgdb_breakpoint () at kernel/debug/debug_core.c:1054 2 dwc2_hcd_qtd_unlink_and_free (hsotg=, qh=, qtd=0xe4479a00) at drivers/usb/dwc2/hcd.h:488 3 dwc2_deactivate_qh (free_qtd=, qh=0xe5efa280, hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:671 4 dwc2_release_channel (hsotg=hsotg@entry=0xed424618, chan=chan@entry=0xed5be000, qtd=, halt_status=) at drivers/usb/dwc2/hcd_intr.c:742 5 dwc2_halt_channel (hsotg=0xed424618, chan=0xed5be000, qtd=, halt_status=) at drivers/usb/dwc2/hcd_intr.c:804 6 dwc2_complete_non_periodic_xfer (chnum=, halt_status=, qtd=, chan=, hsotg=) at drivers/usb/dwc2/hcd_intr.c:889 7 dwc2_hc_xfercomp_intr (hsotg=hsotg@entry=0xed424618, chan=chan@entry=0xed5be000, chnum=chnum@entry=6, qtd=qtd@entry=0xe4479a00) at drivers/usb/dwc2/hcd_intr.c:1065 8 dwc2_hc_chhltd_intr_dma (qtd=0xe4479a00, chnum=6, chan=0xed5be000, hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:1823 9 dwc2_hc_chhltd_intr (qtd=0xe4479a00, chnum=6, chan=0xed5be000, hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:1944 10 dwc2_hc_n_intr (chnum=6, hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:2052 11 dwc2_hc_intr (hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:2097 12 dwc2_handle_hcd_intr (hsotg=0xed424618) at drivers/usb/dwc2/hcd_intr.c:2147 13 _dwc2_hcd_irq (hcd=) at drivers/usb/dwc2/hcd.c:2837 14 usb_hcd_irq (irq=, __hcd=) at drivers/usb/core/hcd.c:2353 Though we could add specific code to handle this case, adding the general purpose code to check for all cases where qtd might be freed seemed safer. Acked-by: John Youn Signed-off-by: Douglas Anderson Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/hcd_intr.c | 70 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index f70c970707a0..bda0b21b850f 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -1949,6 +1949,24 @@ static void dwc2_hc_chhltd_intr(struct dwc2_hsotg *hsotg, } } +/* + * Check if the given qtd is still the top of the list (and thus valid). + * + * If dwc2_hcd_qtd_unlink_and_free() has been called since we grabbed + * the qtd from the top of the list, this will return false (otherwise true). + */ +static bool dwc2_check_qtd_still_ok(struct dwc2_qtd *qtd, struct dwc2_qh *qh) +{ + struct dwc2_qtd *cur_head; + + if (qh == NULL) + return false; + + cur_head = list_first_entry(&qh->qtd_list, struct dwc2_qtd, + qtd_list_entry); + return (cur_head == qtd); +} + /* Handles interrupt for a specific Host Channel */ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) { @@ -2031,27 +2049,59 @@ static void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) */ hcint &= ~HCINTMSK_NYET; } - if (hcint & HCINTMSK_CHHLTD) + + if (hcint & HCINTMSK_CHHLTD) { dwc2_hc_chhltd_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_AHBERR) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_AHBERR) { dwc2_hc_ahberr_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_STALL) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_STALL) { dwc2_hc_stall_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_NAK) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_NAK) { dwc2_hc_nak_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_ACK) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_ACK) { dwc2_hc_ack_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_NYET) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_NYET) { dwc2_hc_nyet_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_XACTERR) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_XACTERR) { dwc2_hc_xacterr_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_BBLERR) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_BBLERR) { dwc2_hc_babble_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_FRMOVRUN) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_FRMOVRUN) { dwc2_hc_frmovrun_intr(hsotg, chan, chnum, qtd); - if (hcint & HCINTMSK_DATATGLERR) + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } + if (hcint & HCINTMSK_DATATGLERR) { dwc2_hc_datatglerr_intr(hsotg, chan, chnum, qtd); + if (!dwc2_check_qtd_still_ok(qtd, chan->qh)) + goto exit; + } +exit: chan->hcint = 0; } -- cgit v1.2.3 From 81e9d14a53eb1abfbe6ac828a87a2deb4702b5f1 Mon Sep 17 00:00:00 2001 From: Mian Yousaf Kaukab Date: Mon, 19 Oct 2015 16:25:15 +0200 Subject: usb: gadget: net2280: restore ep_cfg after defect7374 workaround Defect 7374 workaround enables all GPEP as endpoint 0. Restore endpoint number when defect 7374 workaround is disabled. Otherwise, check to match USB endpoint number to hardware endpoint number in net2280_enable() fails. Cc: # 4.2 Reported-by: Paul Jones Signed-off-by: Mian Yousaf Kaukab Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/net2280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index cf0ed42f5591..6706aef907f4 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -1913,7 +1913,7 @@ static void defect7374_disable_data_eps(struct net2280 *dev) for (i = 1; i < 5; i++) { ep = &dev->ep[i]; - writel(0, &ep->cfg->ep_cfg); + writel(i, &ep->cfg->ep_cfg); } /* CSROUT, CSRIN, PCIOUT, PCIIN, STATIN, RCIN */ -- cgit v1.2.3