Merge tag 'fixes-for-v4.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus

Felipe writes:

usb: fixes for v4.13-rc2

First set of fixes for the current -rc cycle. Only three fixes on dwc3
this time around (proper order for getting a PHY reference, fix for
unmapping DMA and a fix for requesting IRQ on the OMAP glue layer).

Most fixes are on the renesas USB controller, fixing several old bugs
with most going to stable.

dwc2 also learned that it *must* reset USB Address to zero on Reset
interrupts.

Apart from these, some drivers needed HAS_DMA dependency and there's a
sparse warning fix for bdc udc.
This commit is contained in:
Greg Kroah-Hartman
2017-07-19 13:15:30 +02:00
14 changed files with 100 additions and 68 deletions

View File

@@ -3573,6 +3573,9 @@ irq_retry:
/* Report disconnection if it is not already done. */
dwc2_hsotg_disconnect(hsotg);
/* Reset device address to zero */
__bic32(hsotg->regs + DCFG, DCFG_DEVADDR_MASK);
if (usb_status & GOTGCTL_BSESVLD && connected)
dwc2_hsotg_core_init_disconnected(hsotg, true);
}

View File

@@ -766,6 +766,10 @@ static int dwc3_core_init(struct dwc3 *dwc)
dwc->maximum_speed = USB_SPEED_HIGH;
}
ret = dwc3_core_get_phy(dwc);
if (ret)
goto err0;
ret = dwc3_core_soft_reset(dwc);
if (ret)
goto err0;
@@ -774,10 +778,6 @@ static int dwc3_core_init(struct dwc3 *dwc)
if (ret)
goto err0;
ret = dwc3_core_get_phy(dwc);
if (ret)
goto err0;
dwc3_core_setup_global_control(dwc);
dwc3_core_num_eps(dwc);

View File

@@ -512,15 +512,6 @@ static int dwc3_omap_probe(struct platform_device *pdev)
/* check the DMA Status */
reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
irq_set_status_flags(omap->irq, IRQ_NOAUTOEN);
ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
dwc3_omap_interrupt_thread, IRQF_SHARED,
"dwc3-omap", omap);
if (ret) {
dev_err(dev, "failed to request IRQ #%d --> %d\n",
omap->irq, ret);
goto err1;
}
ret = dwc3_omap_extcon_register(omap);
if (ret < 0)
@@ -532,8 +523,15 @@ static int dwc3_omap_probe(struct platform_device *pdev)
goto err1;
}
ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
dwc3_omap_interrupt_thread, IRQF_SHARED,
"dwc3-omap", omap);
if (ret) {
dev_err(dev, "failed to request IRQ #%d --> %d\n",
omap->irq, ret);
goto err1;
}
dwc3_omap_enable_irqs(omap);
enable_irq(omap->irq);
return 0;
err1:

View File

@@ -191,14 +191,16 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
req->started = false;
list_del(&req->list);
req->trb = NULL;
req->remaining = 0;
if (req->request.status == -EINPROGRESS)
req->request.status = status;
usb_gadget_unmap_request_by_dev(dwc->sysdev,
&req->request, req->direction);
if (req->trb)
usb_gadget_unmap_request_by_dev(dwc->sysdev,
&req->request, req->direction);
req->trb = NULL;
trace_dwc3_gadget_giveback(req);

View File

@@ -2490,7 +2490,7 @@ static int fsg_main_thread(void *common_)
int i;
down_write(&common->filesem);
for (i = 0; i < ARRAY_SIZE(common->luns); --i) {
for (i = 0; i < ARRAY_SIZE(common->luns); i++) {
struct fsg_lun *curlun = common->luns[i];
if (!curlun || !fsg_lun_is_open(curlun))
continue;

View File

@@ -92,9 +92,9 @@ static struct uac_input_terminal_descriptor usb_out_it_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
.bTerminalID = USB_OUT_IT_ID,
.wTerminalType = UAC_TERMINAL_STREAMING,
.wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal = 0,
.wChannelConfig = 0x3,
.wChannelConfig = cpu_to_le16(0x3),
};
#define IO_OUT_OT_ID 2
@@ -103,7 +103,7 @@ static struct uac1_output_terminal_descriptor io_out_ot_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID = IO_OUT_OT_ID,
.wTerminalType = UAC_OUTPUT_TERMINAL_SPEAKER,
.wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER),
.bAssocTerminal = 0,
.bSourceID = USB_OUT_IT_ID,
};
@@ -114,9 +114,9 @@ static struct uac_input_terminal_descriptor io_in_it_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_INPUT_TERMINAL,
.bTerminalID = IO_IN_IT_ID,
.wTerminalType = UAC_INPUT_TERMINAL_MICROPHONE,
.wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE),
.bAssocTerminal = 0,
.wChannelConfig = 0x3,
.wChannelConfig = cpu_to_le16(0x3),
};
#define USB_IN_OT_ID 4
@@ -125,7 +125,7 @@ static struct uac1_output_terminal_descriptor usb_in_ot_desc = {
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubtype = UAC_OUTPUT_TERMINAL,
.bTerminalID = USB_IN_OT_ID,
.wTerminalType = UAC_TERMINAL_STREAMING,
.wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING),
.bAssocTerminal = 0,
.bSourceID = IO_IN_IT_ID,
};
@@ -174,7 +174,7 @@ static struct uac1_as_header_descriptor as_out_header_desc = {
.bDescriptorSubtype = UAC_AS_GENERAL,
.bTerminalLink = USB_OUT_IT_ID,
.bDelay = 1,
.wFormatTag = UAC_FORMAT_TYPE_I_PCM,
.wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
};
static struct uac1_as_header_descriptor as_in_header_desc = {
@@ -183,7 +183,7 @@ static struct uac1_as_header_descriptor as_in_header_desc = {
.bDescriptorSubtype = UAC_AS_GENERAL,
.bTerminalLink = USB_IN_OT_ID,
.bDelay = 1,
.wFormatTag = UAC_FORMAT_TYPE_I_PCM,
.wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM),
};
DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1);
@@ -606,8 +606,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
if (status)
goto fail;
audio->out_ep_maxpsize = as_out_ep_desc.wMaxPacketSize;
audio->in_ep_maxpsize = as_in_ep_desc.wMaxPacketSize;
audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize);
audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize);
audio->params.c_chmask = audio_opts->c_chmask;
audio->params.c_srate = audio_opts->c_srate;
audio->params.c_ssize = audio_opts->c_ssize;

View File

@@ -168,7 +168,7 @@ static struct uac2_input_terminal_descriptor usb_out_it_desc = {
.bAssocTerminal = 0,
.bCSourceID = USB_OUT_CLK_ID,
.iChannelNames = 0,
.bmControls = (CONTROL_RDWR << COPY_CTRL),
.bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Input Terminal for I/O-In */
@@ -182,7 +182,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = {
.bAssocTerminal = 0,
.bCSourceID = USB_IN_CLK_ID,
.iChannelNames = 0,
.bmControls = (CONTROL_RDWR << COPY_CTRL),
.bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Ouput Terminal for USB_IN */
@@ -196,7 +196,7 @@ static struct uac2_output_terminal_descriptor usb_in_ot_desc = {
.bAssocTerminal = 0,
.bSourceID = IO_IN_IT_ID,
.bCSourceID = USB_IN_CLK_ID,
.bmControls = (CONTROL_RDWR << COPY_CTRL),
.bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
/* Ouput Terminal for I/O-Out */
@@ -210,7 +210,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = {
.bAssocTerminal = 0,
.bSourceID = USB_OUT_IT_ID,
.bCSourceID = USB_OUT_CLK_ID,
.bmControls = (CONTROL_RDWR << COPY_CTRL),
.bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL),
};
static struct uac2_ac_header_descriptor ac_hdr_desc = {
@@ -220,9 +220,10 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = {
.bDescriptorSubtype = UAC_MS_HEADER,
.bcdADC = cpu_to_le16(0x200),
.bCategory = UAC2_FUNCTION_IO_BOX,
.wTotalLength = sizeof in_clk_src_desc + sizeof out_clk_src_desc
+ sizeof usb_out_it_desc + sizeof io_in_it_desc
+ sizeof usb_in_ot_desc + sizeof io_out_ot_desc,
.wTotalLength = cpu_to_le16(sizeof in_clk_src_desc
+ sizeof out_clk_src_desc + sizeof usb_out_it_desc
+ sizeof io_in_it_desc + sizeof usb_in_ot_desc
+ sizeof io_out_ot_desc),
.bmControls = 0,
};
@@ -569,10 +570,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
return ret;
}
agdev->in_ep_maxpsize = max(fs_epin_desc.wMaxPacketSize,
hs_epin_desc.wMaxPacketSize);
agdev->out_ep_maxpsize = max(fs_epout_desc.wMaxPacketSize,
hs_epout_desc.wMaxPacketSize);
agdev->in_ep_maxpsize = max_t(u16,
le16_to_cpu(fs_epin_desc.wMaxPacketSize),
le16_to_cpu(hs_epin_desc.wMaxPacketSize));
agdev->out_ep_maxpsize = max_t(u16,
le16_to_cpu(fs_epout_desc.wMaxPacketSize),
le16_to_cpu(hs_epout_desc.wMaxPacketSize));
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;

View File

@@ -192,7 +192,7 @@ config USB_RENESAS_USBHS_UDC
config USB_RENESAS_USB3
tristate 'Renesas USB3.0 Peripheral controller'
depends on ARCH_RENESAS || COMPILE_TEST
depends on EXTCON
depends on EXTCON && HAS_DMA
help
Renesas USB3.0 Peripheral controller is a USB peripheral controller
that supports super, high, and full speed USB 3.0 data transfers.
@@ -257,6 +257,7 @@ config USB_MV_U3D
config USB_SNP_CORE
depends on (USB_AMD5536UDC || USB_SNP_UDC_PLAT)
depends on HAS_DMA
tristate
help
This enables core driver support for Synopsys USB 2.0 Device
@@ -271,7 +272,7 @@ config USB_SNP_CORE
config USB_SNP_UDC_PLAT
tristate "Synopsys USB 2.0 Device controller"
depends on (USB_GADGET && OF)
depends on USB_GADGET && OF && HAS_DMA
select USB_GADGET_DUALSPEED
select USB_SNP_CORE
default ARCH_BCM_IPROC

View File

@@ -89,6 +89,9 @@
/* USB_COM_CON */
#define USB_COM_CON_CONF BIT(24)
#define USB_COM_CON_PN_WDATAIF_NL BIT(23)
#define USB_COM_CON_PN_RDATAIF_NL BIT(22)
#define USB_COM_CON_PN_LSTTR_PP BIT(21)
#define USB_COM_CON_SPD_MODE BIT(17)
#define USB_COM_CON_EP0_EN BIT(16)
#define USB_COM_CON_DEV_ADDR_SHIFT 8
@@ -686,6 +689,9 @@ static void renesas_usb3_init_controller(struct renesas_usb3 *usb3)
{
usb3_init_axi_bridge(usb3);
usb3_init_epc_registers(usb3);
usb3_set_bit(usb3, USB_COM_CON_PN_WDATAIF_NL |
USB_COM_CON_PN_RDATAIF_NL | USB_COM_CON_PN_LSTTR_PP,
USB3_USB_COM_CON);
usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_STA);
usb3_write(usb3, USB_OTG_IDMON, USB3_USB_OTG_INT_ENA);
@@ -1369,7 +1375,7 @@ static int renesas_usb3_dma_free_prd(struct renesas_usb3 *usb3,
usb3_for_each_dma(usb3, dma, i) {
if (dma->prd) {
dma_free_coherent(dev, USB3_DMA_MAX_XFER_SIZE,
dma_free_coherent(dev, USB3_DMA_PRD_SIZE,
dma->prd, dma->prd_dma);
dma->prd = NULL;
}
@@ -1409,12 +1415,12 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep,
int ret = -EAGAIN;
u32 enable_bits = 0;
if (usb3_ep->halt || usb3_ep->started)
return;
if (usb3_req != usb3_req_first)
return;
spin_lock_irqsave(&usb3->lock, flags);
if (usb3_ep->halt || usb3_ep->started)
goto out;
if (usb3_req != usb3_req_first)
goto out;
if (usb3_pn_change(usb3, usb3_ep->num) < 0)
goto out;

View File

@@ -28,7 +28,7 @@
/* description */
#define UDC_MOD_DESCRIPTION "Synopsys UDC platform driver"
void start_udc(struct udc *udc)
static void start_udc(struct udc *udc)
{
if (udc->driver) {
dev_info(udc->dev, "Connecting...\n");
@@ -38,7 +38,7 @@ void start_udc(struct udc *udc)
}
}
void stop_udc(struct udc *udc)
static void stop_udc(struct udc *udc)
{
int tmp;
u32 reg;
@@ -76,7 +76,7 @@ void stop_udc(struct udc *udc)
dev_info(udc->dev, "Device disconnected\n");
}
void udc_drd_work(struct work_struct *work)
static void udc_drd_work(struct work_struct *work)
{
struct udc *udc;

View File

@@ -752,8 +752,10 @@ static int usbhsc_resume(struct device *dev)
struct usbhs_priv *priv = dev_get_drvdata(dev);
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
usbhsc_power_ctrl(priv, 1);
usbhs_mod_autonomy_mode(priv);
}
usbhs_platform_call(priv, phy_reset, pdev);

View File

@@ -37,6 +37,7 @@ struct usbhsg_gpriv;
struct usbhsg_uep {
struct usb_ep ep;
struct usbhs_pipe *pipe;
spinlock_t lock; /* protect the pipe */
char ep_name[EP_NAME_SIZE];
@@ -636,10 +637,16 @@ usbhsg_ep_enable_end:
static int usbhsg_ep_disable(struct usb_ep *ep)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
struct usbhs_pipe *pipe;
unsigned long flags;
int ret = 0;
if (!pipe)
return -EINVAL;
spin_lock_irqsave(&uep->lock, flags);
pipe = usbhsg_uep_to_pipe(uep);
if (!pipe) {
ret = -EINVAL;
goto out;
}
usbhsg_pipe_disable(uep);
usbhs_pipe_free(pipe);
@@ -647,6 +654,9 @@ static int usbhsg_ep_disable(struct usb_ep *ep)
uep->pipe->mod_private = NULL;
uep->pipe = NULL;
out:
spin_unlock_irqrestore(&uep->lock, flags);
return 0;
}
@@ -696,8 +706,11 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
{
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
struct usbhs_pipe *pipe;
unsigned long flags;
spin_lock_irqsave(&uep->lock, flags);
pipe = usbhsg_uep_to_pipe(uep);
if (pipe)
usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
@@ -706,6 +719,7 @@ static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
* even if the pipe is NULL.
*/
usbhsg_queue_pop(uep, ureq, -ECONNRESET);
spin_unlock_irqrestore(&uep->lock, flags);
return 0;
}
@@ -852,10 +866,10 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
{
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
struct usbhs_mod *mod = usbhs_mod_get_current(priv);
struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
struct usbhsg_uep *uep;
struct device *dev = usbhs_priv_to_dev(priv);
unsigned long flags;
int ret = 0;
int ret = 0, i;
/******************** spin lock ********************/
usbhs_lock(priv, flags);
@@ -887,7 +901,9 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
usbhs_sys_set_test_mode(priv, 0);
usbhs_sys_function_ctrl(priv, 0);
usbhsg_ep_disable(&dcp->ep);
/* disable all eps */
usbhsg_for_each_uep_with_dcp(uep, gpriv, i)
usbhsg_ep_disable(&uep->ep);
dev_dbg(dev, "stop gadget\n");
@@ -1069,6 +1085,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
ret = -ENOMEM;
goto usbhs_mod_gadget_probe_err_gpriv;
}
spin_lock_init(&uep->lock);
gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
dev_info(dev, "%stransceiver found\n",