Skip to content

Commit

Permalink
Merge tag 'usb-6.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are some small USB fixes for 6.1-rc7 that resolve some reported
  problems:

   - cdnsp driver fixes for reported problems

   - dwc3 fixes for some small reported problems

   - uvc gadget driver fix for reported regression

  All of these have been in linux-next with no reported problems"

* tag 'usb-6.1-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: cdnsp: fix issue with ZLP - added TD_SIZE = 1
  usb: dwc3: gadget: Clear ep descriptor last
  usb: dwc3: exynos: Fix remove() function
  usb: cdnsp: Fix issue with Clear Feature Halt Endpoint
  usb: dwc3: gadget: Disable GUSB2PHYCFG.SUSPHY for End Transfer
  usb: gadget: uvc: also use try_format in set_format
  • Loading branch information
Linus Torvalds committed Nov 27, 2022
2 parents db31824 + 7a21b27 commit 9066e15
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 81 deletions.
12 changes: 4 additions & 8 deletions drivers/usb/cdns3/cdnsp-gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,11 +600,11 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,

trace_cdnsp_ep_halt(value ? "Set" : "Clear");

if (value) {
ret = cdnsp_cmd_stop_ep(pdev, pep);
if (ret)
return ret;
ret = cdnsp_cmd_stop_ep(pdev, pep);
if (ret)
return ret;

if (value) {
if (GET_EP_CTX_STATE(pep->out_ctx) == EP_STATE_STOPPED) {
cdnsp_queue_halt_endpoint(pdev, pep->idx);
cdnsp_ring_cmd_db(pdev);
Expand All @@ -613,10 +613,6 @@ int cdnsp_halt_endpoint(struct cdnsp_device *pdev,

pep->ep_state |= EP_HALTED;
} else {
/*
* In device mode driver can call reset endpoint command
* from any endpoint state.
*/
cdnsp_queue_reset_ep(pdev, pep->idx);
cdnsp_ring_cmd_db(pdev);
ret = cdnsp_wait_for_cmd_compl(pdev);
Expand Down
17 changes: 12 additions & 5 deletions drivers/usb/cdns3/cdnsp-ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -1763,10 +1763,15 @@ static u32 cdnsp_td_remainder(struct cdnsp_device *pdev,
int trb_buff_len,
unsigned int td_total_len,
struct cdnsp_request *preq,
bool more_trbs_coming)
bool more_trbs_coming,
bool zlp)
{
u32 maxp, total_packet_count;

/* Before ZLP driver needs set TD_SIZE = 1. */
if (zlp)
return 1;

/* One TRB with a zero-length data packet. */
if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
trb_buff_len == td_total_len)
Expand Down Expand Up @@ -1960,7 +1965,8 @@ int cdnsp_queue_bulk_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)
/* Set the TRB length, TD size, and interrupter fields. */
remainder = cdnsp_td_remainder(pdev, enqd_len, trb_buff_len,
full_len, preq,
more_trbs_coming);
more_trbs_coming,
zero_len_trb);

length_field = TRB_LEN(trb_buff_len) | TRB_TD_SIZE(remainder) |
TRB_INTR_TARGET(0);
Expand Down Expand Up @@ -2025,7 +2031,7 @@ int cdnsp_queue_ctrl_tx(struct cdnsp_device *pdev, struct cdnsp_request *preq)

if (preq->request.length > 0) {
remainder = cdnsp_td_remainder(pdev, 0, preq->request.length,
preq->request.length, preq, 1);
preq->request.length, preq, 1, 0);

length_field = TRB_LEN(preq->request.length) |
TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0);
Expand Down Expand Up @@ -2076,7 +2082,8 @@ int cdnsp_cmd_stop_ep(struct cdnsp_device *pdev, struct cdnsp_ep *pep)
u32 ep_state = GET_EP_CTX_STATE(pep->out_ctx);
int ret = 0;

if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED) {
if (ep_state == EP_STATE_STOPPED || ep_state == EP_STATE_DISABLED ||
ep_state == EP_STATE_HALTED) {
trace_cdnsp_ep_stopped_or_disabled(pep->out_ctx);
goto ep_stopped;
}
Expand Down Expand Up @@ -2225,7 +2232,7 @@ static int cdnsp_queue_isoc_tx(struct cdnsp_device *pdev,
/* Set the TRB length, TD size, & interrupter fields. */
remainder = cdnsp_td_remainder(pdev, running_total,
trb_buff_len, td_len, preq,
more_trbs_coming);
more_trbs_coming, 0);

length_field = TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0);

Expand Down
11 changes: 1 addition & 10 deletions drivers/usb/dwc3/dwc3-exynos.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ struct dwc3_exynos {
struct regulator *vdd10;
};

static int dwc3_exynos_remove_child(struct device *dev, void *unused)
{
struct platform_device *pdev = to_platform_device(dev);

platform_device_unregister(pdev);

return 0;
}

static int dwc3_exynos_probe(struct platform_device *pdev)
{
struct dwc3_exynos *exynos;
Expand Down Expand Up @@ -142,7 +133,7 @@ static int dwc3_exynos_remove(struct platform_device *pdev)
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
int i;

device_for_each_child(&pdev->dev, NULL, dwc3_exynos_remove_child);
of_platform_depopulate(&pdev->dev);

for (i = exynos->num_clks - 1; i >= 0; i--)
clk_disable_unprepare(exynos->clks[i]);
Expand Down
15 changes: 8 additions & 7 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd,
*
* DWC_usb3 3.30a and DWC_usb31 1.90a programming guide section 3.2.2
*/
if (dwc->gadget->speed <= USB_SPEED_HIGH) {
if (dwc->gadget->speed <= USB_SPEED_HIGH ||
DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) {
saved_config |= DWC3_GUSB2PHYCFG_SUSPHY;
Expand Down Expand Up @@ -1023,12 +1024,6 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
reg &= ~DWC3_DALEPENA_EP(dep->number);
dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);

/* Clear out the ep descriptors for non-ep0 */
if (dep->number > 1) {
dep->endpoint.comp_desc = NULL;
dep->endpoint.desc = NULL;
}

dwc3_remove_requests(dwc, dep, -ESHUTDOWN);

dep->stream_capable = false;
Expand All @@ -1043,6 +1038,12 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
mask |= (DWC3_EP_DELAY_STOP | DWC3_EP_TRANSFER_STARTED);
dep->flags &= mask;

/* Clear out the ep descriptors for non-ep0 */
if (dep->number > 1) {
dep->endpoint.comp_desc = NULL;
dep->endpoint.desc = NULL;
}

return 0;
}

Expand Down
72 changes: 21 additions & 51 deletions drivers/usb/gadget/function/uvc_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,6 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
* V4L2 ioctls
*/

struct uvc_format {
u8 bpp;
u32 fcc;
};

static struct uvc_format uvc_formats[] = {
{ 16, V4L2_PIX_FMT_YUYV },
{ 0, V4L2_PIX_FMT_MJPEG },
};

static int
uvc_v4l2_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
{
Expand Down Expand Up @@ -242,47 +232,6 @@ uvc_v4l2_get_format(struct file *file, void *fh, struct v4l2_format *fmt)
return 0;
}

static int
uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct video_device *vdev = video_devdata(file);
struct uvc_device *uvc = video_get_drvdata(vdev);
struct uvc_video *video = &uvc->video;
struct uvc_format *format;
unsigned int imagesize;
unsigned int bpl;
unsigned int i;

for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) {
format = &uvc_formats[i];
if (format->fcc == fmt->fmt.pix.pixelformat)
break;
}

if (i == ARRAY_SIZE(uvc_formats)) {
uvcg_info(&uvc->func, "Unsupported format 0x%08x.\n",
fmt->fmt.pix.pixelformat);
return -EINVAL;
}

bpl = format->bpp * fmt->fmt.pix.width / 8;
imagesize = bpl ? bpl * fmt->fmt.pix.height : fmt->fmt.pix.sizeimage;

video->fcc = format->fcc;
video->bpp = format->bpp;
video->width = fmt->fmt.pix.width;
video->height = fmt->fmt.pix.height;
video->imagesize = imagesize;

fmt->fmt.pix.field = V4L2_FIELD_NONE;
fmt->fmt.pix.bytesperline = bpl;
fmt->fmt.pix.sizeimage = imagesize;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
fmt->fmt.pix.priv = 0;

return 0;
}

static int
uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
{
Expand Down Expand Up @@ -323,6 +272,27 @@ uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
return 0;
}

static int
uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct video_device *vdev = video_devdata(file);
struct uvc_device *uvc = video_get_drvdata(vdev);
struct uvc_video *video = &uvc->video;
int ret;

ret = uvc_v4l2_try_format(file, fh, fmt);
if (ret)
return ret;

video->fcc = fmt->fmt.pix.pixelformat;
video->bpp = fmt->fmt.pix.bytesperline * 8 / video->width;
video->width = fmt->fmt.pix.width;
video->height = fmt->fmt.pix.height;
video->imagesize = fmt->fmt.pix.sizeimage;

return ret;
}

static int
uvc_v4l2_enum_frameintervals(struct file *file, void *fh,
struct v4l2_frmivalenum *fival)
Expand Down

0 comments on commit 9066e15

Please sign in to comment.