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.
 -----BEGIN PGP SIGNATURE-----
 
 iQJRBAABCAA7FiEElLzh7wn96CXwjh2IzL64meEamQYFAllvOp0dHGZlbGlwZS5i
 YWxiaUBsaW51eC5pbnRlbC5jb20ACgkQzL64meEamQaSfhAAzo8MRbnsjSHSvp0h
 Yos9pfUy40mizoNHrxgjlWgSVlw/dCgFc+F9Zzx0md2Q4Rjl3/5IYBX+wirTqa2R
 w5lQ+KgE1zUqAMOk4X7tet4TRLm3WX01yQ7NPIVuLP3N+eMa7MKavCRjSUg2DT6x
 5EM4qmYepKWUEmr4x6K1pndRT660Yq/Tic/Af6kg+kIU/glkOL58TGRavJtRAybz
 zGOI5SIdVdUsosDzqvZYR21M4lW5JnZ4xdcZHhDjkqvXnOtbkTMsZKWeOVBx/bS/
 PeWPb67BjldTCseZ7LHl+BTtPhiOVl/EAxjLTkG0hJ1hPhDt/TM1P7H6vBk61RPL
 wO9Qy3yIAqaMldYCSX1Vm8kv/L49C2dCs0Efxn9Lf68C6QQ4R2MTxTXIFiS3Tdkq
 Sx2pGrn0rSFkmIhsNECZmTRn5tOVNCYFRncepUcd+IAfZeqDiSy7/yR0+Z3wHrBM
 i3xGy9gkEo+VGqA9XK4QMbsHC1ThqgnGbwx5LTPF8dQxGTlpEaj5E9z3WjNozFX2
 ndwlb1sNKWrmnyG53hUcMUOEUKCYN5t8Mp7OZoqFFJsLWsV4WpmEyTq7t1KwXncV
 aTfDrLUieOjjugv0LUl7jZZC8W2z4+uoG9Tmvl7vuQPf6iQsP+arb+vK4TVg7s+I
 lCXl/A2zH15byu0HfBwhqtKry7M=
 =eMHd
 -----END PGP SIGNATURE-----

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
commit 3d69f3a8c2
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",

View File

@ -115,13 +115,13 @@ struct uac2_input_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
__u16 wTerminalType;
__le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bCSourceID;
__u8 bNrChannels;
__u32 bmChannelConfig;
__le32 bmChannelConfig;
__u8 iChannelNames;
__u16 bmControls;
__le16 bmControls;
__u8 iTerminal;
} __attribute__((packed));
@ -132,11 +132,11 @@ struct uac2_output_terminal_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalID;
__u16 wTerminalType;
__le16 wTerminalType;
__u8 bAssocTerminal;
__u8 bSourceID;
__u8 bCSourceID;
__u16 bmControls;
__le16 bmControls;
__u8 iTerminal;
} __attribute__((packed));
@ -164,9 +164,9 @@ struct uac2_as_header_descriptor {
__u8 bTerminalLink;
__u8 bmControls;
__u8 bFormatType;
__u32 bmFormats;
__le32 bmFormats;
__u8 bNrChannels;
__u32 bmChannelConfig;
__le32 bmChannelConfig;
__u8 iChannelNames;
} __attribute__((packed));

View File

@ -333,7 +333,7 @@ struct uac_processing_unit_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u16 wProcessType;
__le16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
@ -491,8 +491,8 @@ struct uac_format_type_ii_ext_descriptor {
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__u16 wMaxBitRate;
__u16 wSamplesPerFrame;
__le16 wMaxBitRate;
__le16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
} __attribute__((packed));