Skip to content

Commit

Permalink
Merge tag 'usb-4.8-rc5' 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/PHY fixes from Greg KH:
 "Here are some USB and PHY driver fixes for 4.8-rc5

  Nothing major, lots of little fixes for reported bugs, and a build fix
  for a missing .h file that the phy drivers needed.  All of these have
  been in linux-next for a while with no reported issues"

* tag 'usb-4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (24 commits)
  usb: musb: Fix locking errors for host only mode
  usb: dwc3: gadget: always decrement by 1
  usb: dwc3: debug: fix ep name on trace output
  usb: gadget: udc: core: don't starve DMA resources
  USB: serial: option: add WeTelecom 0x6802 and 0x6803 products
  USB: avoid left shift by -1
  USB: fix typo in wMaxPacketSize validation
  usb: gadget: Add the gserial port checking in gs_start_tx()
  usb: dwc3: gadget: don't rely on jiffies while holding spinlock
  usb: gadget: fsl_qe_udc: signedness bug in qe_get_frame()
  usb: gadget: function: f_rndis: socket buffer may be NULL
  usb: gadget: function: f_eem: socket buffer may be NULL
  usb: renesas_usbhs: gadget: fix return value check in usbhs_mod_gadget_probe()
  usb: dwc2: Add reset control to dwc2
  usb: dwc3: core: allow device to runtime_suspend several times
  usb: dwc3: pci: runtime_resume child device
  USB: serial: option: add WeTelecom WM-D200
  usb: chipidea: udc: don't touch DP when controller is in host mode
  USB: serial: mos7840: fix non-atomic allocation in write path
  USB: serial: mos7720: fix non-atomic allocation in write path
  ...
  • Loading branch information
Linus Torvalds committed Sep 3, 2016
2 parents 3e42394 + 2c55754 commit 70dad49
Show file tree
Hide file tree
Showing 23 changed files with 294 additions and 57 deletions.
2 changes: 1 addition & 1 deletion drivers/phy/phy-brcm-sata.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ static int brcm_sata_phy_init(struct phy *phy)
rc = -ENODEV;
};

return 0;
return rc;
}

static const struct phy_ops phy_ops = {
Expand Down
68 changes: 46 additions & 22 deletions drivers/phy/phy-sun4i-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/power_supply.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/usb/of.h>
#include <linux/workqueue.h>

#define REG_ISCR 0x00
Expand Down Expand Up @@ -110,6 +111,7 @@ struct sun4i_usb_phy_cfg {
struct sun4i_usb_phy_data {
void __iomem *base;
const struct sun4i_usb_phy_cfg *cfg;
enum usb_dr_mode dr_mode;
struct mutex mutex;
struct sun4i_usb_phy {
struct phy *phy;
Expand All @@ -120,6 +122,7 @@ struct sun4i_usb_phy_data {
bool regulator_on;
int index;
} phys[MAX_PHYS];
int first_phy;
/* phy0 / otg related variables */
struct extcon_dev *extcon;
bool phy0_init;
Expand Down Expand Up @@ -285,16 +288,10 @@ static int sun4i_usb_phy_init(struct phy *_phy)
sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_DPDM_PULLUP_EN);
sun4i_usb_phy0_update_iscr(_phy, 0, ISCR_ID_PULLUP_EN);

if (data->id_det_gpio) {
/* OTG mode, force ISCR and cable state updates */
data->id_det = -1;
data->vbus_det = -1;
queue_delayed_work(system_wq, &data->detect, 0);
} else {
/* Host only mode */
sun4i_usb_phy0_set_id_detect(_phy, 0);
sun4i_usb_phy0_set_vbus_detect(_phy, 1);
}
/* Force ISCR and cable state updates */
data->id_det = -1;
data->vbus_det = -1;
queue_delayed_work(system_wq, &data->detect, 0);
}

return 0;
Expand All @@ -319,6 +316,19 @@ static int sun4i_usb_phy_exit(struct phy *_phy)
return 0;
}

static int sun4i_usb_phy0_get_id_det(struct sun4i_usb_phy_data *data)
{
switch (data->dr_mode) {
case USB_DR_MODE_OTG:
return gpiod_get_value_cansleep(data->id_det_gpio);
case USB_DR_MODE_HOST:
return 0;
case USB_DR_MODE_PERIPHERAL:
default:
return 1;
}
}

static int sun4i_usb_phy0_get_vbus_det(struct sun4i_usb_phy_data *data)
{
if (data->vbus_det_gpio)
Expand Down Expand Up @@ -432,7 +442,10 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
struct phy *phy0 = data->phys[0].phy;
int id_det, vbus_det, id_notify = 0, vbus_notify = 0;

id_det = gpiod_get_value_cansleep(data->id_det_gpio);
if (phy0 == NULL)
return;

id_det = sun4i_usb_phy0_get_id_det(data);
vbus_det = sun4i_usb_phy0_get_vbus_det(data);

mutex_lock(&phy0->mutex);
Expand All @@ -448,7 +461,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
* without vbus detection report vbus low for long enough for
* the musb-ip to end the current device session.
*/
if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) {
if (data->dr_mode == USB_DR_MODE_OTG &&
!sun4i_usb_phy0_have_vbus_det(data) && id_det == 0) {
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
msleep(200);
sun4i_usb_phy0_set_vbus_detect(phy0, 1);
Expand All @@ -474,7 +488,8 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work)
* without vbus detection report vbus low for long enough to
* the musb-ip to end the current host session.
*/
if (!sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
if (data->dr_mode == USB_DR_MODE_OTG &&
!sun4i_usb_phy0_have_vbus_det(data) && id_det == 1) {
mutex_lock(&phy0->mutex);
sun4i_usb_phy0_set_vbus_detect(phy0, 0);
msleep(1000);
Expand Down Expand Up @@ -519,7 +534,8 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev,
{
struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);

if (args->args[0] >= data->cfg->num_phys)
if (args->args[0] < data->first_phy ||
args->args[0] >= data->cfg->num_phys)
return ERR_PTR(-ENODEV);

return data->phys[args->args[0]].phy;
Expand Down Expand Up @@ -593,13 +609,17 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
}

/* vbus_det without id_det makes no sense, and is not supported */
if (sun4i_usb_phy0_have_vbus_det(data) && !data->id_det_gpio) {
dev_err(dev, "usb0_id_det missing or invalid\n");
return -ENODEV;
}

if (data->id_det_gpio) {
data->dr_mode = of_usb_get_dr_mode_by_phy(np, 0);
switch (data->dr_mode) {
case USB_DR_MODE_OTG:
/* otg without id_det makes no sense, and is not supported */
if (!data->id_det_gpio) {
dev_err(dev, "usb0_id_det missing or invalid\n");
return -ENODEV;
}
/* fall through */
case USB_DR_MODE_HOST:
case USB_DR_MODE_PERIPHERAL:
data->extcon = devm_extcon_dev_allocate(dev,
sun4i_usb_phy0_cable);
if (IS_ERR(data->extcon))
Expand All @@ -610,9 +630,13 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
dev_err(dev, "failed to register extcon: %d\n", ret);
return ret;
}
break;
default:
dev_info(dev, "dr_mode unknown, not registering usb phy0\n");
data->first_phy = 1;
}

for (i = 0; i < data->cfg->num_phys; i++) {
for (i = data->first_phy; i < data->cfg->num_phys; i++) {
struct sun4i_usb_phy *phy = data->phys + i;
char name[16];

Expand Down
4 changes: 2 additions & 2 deletions drivers/phy/phy-sun9i-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ static int sun9i_usb_phy_probe(struct platform_device *pdev)
}

phy->hsic_clk = devm_clk_get(dev, "hsic_12M");
if (IS_ERR(phy->clk)) {
if (IS_ERR(phy->hsic_clk)) {
dev_err(dev, "failed to get hsic_12M clock\n");
return PTR_ERR(phy->clk);
return PTR_ERR(phy->hsic_clk);
}

phy->reset = devm_reset_control_get(dev, "hsic");
Expand Down
7 changes: 5 additions & 2 deletions drivers/usb/chipidea/udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1596,8 +1596,11 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
{
struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);

/* Data+ pullup controlled by OTG state machine in OTG fsm mode */
if (ci_otg_is_fsm_mode(ci))
/*
* Data+ pullup controlled by OTG state machine in OTG fsm mode;
* and don't touch Data+ in host mode for dual role config.
*/
if (ci_otg_is_fsm_mode(ci) || ci->role == CI_ROLE_HOST)
return 0;

pm_runtime_get_sync(&ci->gadget.dev);
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/core/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ static const unsigned short high_speed_maxpacket_maxes[4] = {
[USB_ENDPOINT_XFER_CONTROL] = 64,
[USB_ENDPOINT_XFER_ISOC] = 1024,
[USB_ENDPOINT_XFER_BULK] = 512,
[USB_ENDPOINT_XFER_INT] = 1023,
[USB_ENDPOINT_XFER_INT] = 1024,
};
static const unsigned short super_speed_maxpacket_maxes[4] = {
[USB_ENDPOINT_XFER_CONTROL] = 512,
Expand Down
16 changes: 11 additions & 5 deletions drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1709,11 +1709,17 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
as->urb->start_frame = uurb->start_frame;
as->urb->number_of_packets = number_of_packets;
as->urb->stream_id = stream_id;
if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
ps->dev->speed == USB_SPEED_HIGH)
as->urb->interval = 1 << min(15, ep->desc.bInterval - 1);
else
as->urb->interval = ep->desc.bInterval;

if (ep->desc.bInterval) {
if (uurb->type == USBDEVFS_URB_TYPE_ISO ||
ps->dev->speed == USB_SPEED_HIGH ||
ps->dev->speed >= USB_SPEED_SUPER)
as->urb->interval = 1 <<
min(15, ep->desc.bInterval - 1);
else
as->urb->interval = ep->desc.bInterval;
}

as->urb->context = as;
as->urb->complete = async_completed;
for (totlen = u = 0; u < number_of_packets; u++) {
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc2/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ struct dwc2_hsotg {
void *priv;
int irq;
struct clk *clk;
struct reset_control *reset;

unsigned int queuing_high_bandwidth:1;
unsigned int srp_success:1;
Expand Down
22 changes: 22 additions & 0 deletions drivers/usb/dwc2/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
#include <linux/platform_data/s3c-hsotg.h>
#include <linux/reset.h>

#include <linux/usb/of.h>

Expand Down Expand Up @@ -337,6 +338,24 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
{
int i, ret;

hsotg->reset = devm_reset_control_get_optional(hsotg->dev, "dwc2");
if (IS_ERR(hsotg->reset)) {
ret = PTR_ERR(hsotg->reset);
switch (ret) {
case -ENOENT:
case -ENOTSUPP:
hsotg->reset = NULL;
break;
default:
dev_err(hsotg->dev, "error getting reset control %d\n",
ret);
return ret;
}
}

if (hsotg->reset)
reset_control_deassert(hsotg->reset);

/* Set default UTMI width */
hsotg->phyif = GUSBCFG_PHYIF16;

Expand Down Expand Up @@ -434,6 +453,9 @@ static int dwc2_driver_remove(struct platform_device *dev)
if (hsotg->ll_hw_enabled)
dwc2_lowlevel_hw_disable(hsotg);

if (hsotg->reset)
reset_control_assert(hsotg->reset);

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ static int dwc3_runtime_resume(struct device *dev)
}

pm_runtime_mark_last_busy(dev);
pm_runtime_put(dev);

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/dwc3/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ dwc3_ep_event_string(const struct dwc3_event_depevt *event)
int ret;

ret = sprintf(str, "ep%d%s: ", epnum >> 1,
(epnum & 1) ? "in" : "in");
(epnum & 1) ? "in" : "out");
if (ret < 0)
return "UNKNOWN";

Expand Down
9 changes: 8 additions & 1 deletion drivers/usb/dwc3/dwc3-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ static int dwc3_pci_runtime_suspend(struct device *dev)
return -EBUSY;
}

static int dwc3_pci_runtime_resume(struct device *dev)
{
struct platform_device *dwc3 = dev_get_drvdata(dev);

return pm_runtime_get(&dwc3->dev);
}

static int dwc3_pci_pm_dummy(struct device *dev)
{
/*
Expand All @@ -259,7 +266,7 @@ static int dwc3_pci_pm_dummy(struct device *dev)

static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy)
SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_pm_dummy,
SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_runtime_resume,
NULL)
};

Expand Down
11 changes: 4 additions & 7 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -884,12 +884,9 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
return DWC3_TRB_NUM - 1;
}

trbs_left = dep->trb_dequeue - dep->trb_enqueue;
trbs_left = dep->trb_dequeue - dep->trb_enqueue - 1;
trbs_left &= (DWC3_TRB_NUM - 1);

if (dep->trb_dequeue < dep->trb_enqueue)
trbs_left--;

return trbs_left;
}

Expand Down Expand Up @@ -1433,7 +1430,7 @@ static int dwc3_gadget_get_frame(struct usb_gadget *g)

static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
{
unsigned long timeout;
int retries;

int ret;
u32 reg;
Expand Down Expand Up @@ -1484,9 +1481,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc)
}

/* poll until Link State changes to ON */
timeout = jiffies + msecs_to_jiffies(100);
retries = 20000;

while (!time_after(jiffies, timeout)) {
while (retries--) {
reg = dwc3_readl(dwc->regs, DWC3_DSTS);

/* in HS, means ON */
Expand Down
10 changes: 7 additions & 3 deletions drivers/usb/gadget/function/f_eem.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,11 +341,15 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb)
{
struct sk_buff *skb2 = NULL;
struct usb_ep *in = port->in_ep;
int padlen = 0;
int headroom, tailroom, padlen = 0;
u16 len = skb->len;

int headroom = skb_headroom(skb);
int tailroom = skb_tailroom(skb);
if (!skb)
return NULL;

len = skb->len;
headroom = skb_headroom(skb);
tailroom = skb_tailroom(skb);

/* When (len + EEM_HLEN + ETH_FCS_LEN) % in->maxpacket) is 0,
* stick two bytes of zero-length EEM packet on the end.
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/gadget/function/f_rndis.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,9 @@ static struct sk_buff *rndis_add_header(struct gether *port,
{
struct sk_buff *skb2;

if (!skb)
return NULL;

skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type));
rndis_add_hdr(skb2);

Expand Down
7 changes: 6 additions & 1 deletion drivers/usb/gadget/function/u_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,10 +375,15 @@ __acquires(&port->port_lock)
*/
{
struct list_head *pool = &port->write_pool;
struct usb_ep *in = port->port_usb->in;
struct usb_ep *in;
int status = 0;
bool do_tty_wake = false;

if (!port->port_usb)
return status;

in = port->port_usb->in;

while (!port->write_busy && !list_empty(pool)) {
struct usb_request *req;
int len;
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/udc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ void usb_gadget_unmap_request_by_dev(struct device *dev,
return;

if (req->num_mapped_sgs) {
dma_unmap_sg(dev, req->sg, req->num_mapped_sgs,
dma_unmap_sg(dev, req->sg, req->num_sgs,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);

req->num_mapped_sgs = 0;
Expand Down
Loading

0 comments on commit 70dad49

Please sign in to comment.