Commit fd3f6cc9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB/PHY fixes from Greg KH:
 "Here are some small USB and PHY driver fixes for reported issues for
  5.6-rc5.

  Included in here are:

   - phy driver fixes

   - new USB quirks

   - USB cdns3 gadget driver fixes

   - USB hub core fixes

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

* tag 'usb-5.6-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: dwc3: gadget: Update chain bit correctly when using sg list
  usb: core: port: do error out if usb_autopm_get_interface() fails
  usb: core: hub: do error out if usb_autopm_get_interface() fails
  usb: core: hub: fix unhandled return by employing a void function
  usb: storage: Add quirk for Samsung Fit flash
  usb: quirks: add NO_LPM quirk for Logitech Screen Share
  usb: usb251xb: fix regulator probe and error handling
  phy: allwinner: Fix GENMASK misuse
  usb: cdns3: gadget: toggle cycle bit before reset endpoint
  usb: cdns3: gadget: link trb should point to next request
  phy: mapphone-mdm6600: Fix timeouts by adding wake-up handling
  phy: brcm-sata: Correct MDIO operations for 40nm platforms
  phy: ti: gmii-sel: do not fail in case of gmii
  phy: ti: gmii-sel: fix set of copy-paste errors
  phy: core: Fix phy_get() to not return error on link creation failure
  phy: mapphone-mdm6600: Fix write timeouts with shorter GPIO toggle interval
parents 61a09258 19f3c1e9
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define SUNXI_LOS_BIAS(n) ((n) << 3) #define SUNXI_LOS_BIAS(n) ((n) << 3)
#define SUNXI_LOS_BIAS_MASK GENMASK(5, 3) #define SUNXI_LOS_BIAS_MASK GENMASK(5, 3)
#define SUNXI_TXVBOOSTLVL(n) ((n) << 0) #define SUNXI_TXVBOOSTLVL(n) ((n) << 0)
#define SUNXI_TXVBOOSTLVL_MASK GENMASK(0, 2) #define SUNXI_TXVBOOSTLVL_MASK GENMASK(2, 0)
struct sun50i_usb3_phy { struct sun50i_usb3_phy {
struct phy *phy; struct phy *phy;
......
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */ #define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */
#define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */ #define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */
#define PHY_MDM6600_WAKE_KICK_MS 600 /* time on after GPIO toggle */
#define MDM6600_MODEM_IDLE_DELAY_MS 1000 /* modem after USB suspend */ #define MDM6600_MODEM_IDLE_DELAY_MS 1000 /* modem after USB suspend */
#define MDM6600_MODEM_WAKE_DELAY_MS 200 /* modem response after idle */ #define MDM6600_MODEM_WAKE_DELAY_MS 200 /* modem response after idle */
...@@ -243,10 +244,24 @@ static irqreturn_t phy_mdm6600_wakeirq_thread(int irq, void *data) ...@@ -243,10 +244,24 @@ static irqreturn_t phy_mdm6600_wakeirq_thread(int irq, void *data)
{ {
struct phy_mdm6600 *ddata = data; struct phy_mdm6600 *ddata = data;
struct gpio_desc *mode_gpio1; struct gpio_desc *mode_gpio1;
int error, wakeup;
mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1]; mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1];
dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", wakeup = gpiod_get_value(mode_gpio1);
gpiod_get_value(mode_gpio1)); if (!wakeup)
return IRQ_NONE;
dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", wakeup);
error = pm_runtime_get_sync(ddata->dev);
if (error < 0) {
pm_runtime_put_noidle(ddata->dev);
return IRQ_NONE;
}
/* Just wake-up and kick the autosuspend timer */
pm_runtime_mark_last_busy(ddata->dev);
pm_runtime_put_autosuspend(ddata->dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -496,8 +511,14 @@ static void phy_mdm6600_modem_wake(struct work_struct *work) ...@@ -496,8 +511,14 @@ static void phy_mdm6600_modem_wake(struct work_struct *work)
ddata = container_of(work, struct phy_mdm6600, modem_wake_work.work); ddata = container_of(work, struct phy_mdm6600, modem_wake_work.work);
phy_mdm6600_wake_modem(ddata); phy_mdm6600_wake_modem(ddata);
/*
* The modem does not always stay awake 1.2 seconds after toggling
* the wake GPIO, and sometimes it idles after about some 600 ms
* making writes time out.
*/
schedule_delayed_work(&ddata->modem_wake_work, schedule_delayed_work(&ddata->modem_wake_work,
msecs_to_jiffies(MDM6600_MODEM_IDLE_DELAY_MS)); msecs_to_jiffies(PHY_MDM6600_WAKE_KICK_MS));
} }
static int __maybe_unused phy_mdm6600_runtime_suspend(struct device *dev) static int __maybe_unused phy_mdm6600_runtime_suspend(struct device *dev)
......
...@@ -688,11 +688,9 @@ struct phy *phy_get(struct device *dev, const char *string) ...@@ -688,11 +688,9 @@ struct phy *phy_get(struct device *dev, const char *string)
get_device(&phy->dev); get_device(&phy->dev);
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) { if (!link)
dev_err(dev, "failed to create device link to %s\n", dev_dbg(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent)); dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy; return phy;
} }
...@@ -803,11 +801,9 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, ...@@ -803,11 +801,9 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
} }
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) { if (!link)
dev_err(dev, "failed to create device link to %s\n", dev_dbg(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent)); dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy; return phy;
} }
...@@ -852,11 +848,9 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, ...@@ -852,11 +848,9 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
devres_add(dev, ptr); devres_add(dev, ptr);
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) { if (!link)
dev_err(dev, "failed to create device link to %s\n", dev_dbg(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent)); dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy; return phy;
} }
......
...@@ -80,20 +80,20 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode) ...@@ -80,20 +80,20 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
break; break;
case PHY_INTERFACE_MODE_MII: case PHY_INTERFACE_MODE_MII:
mode = AM33XX_GMII_SEL_MODE_MII; case PHY_INTERFACE_MODE_GMII:
gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII;
break; break;
default: default:
dev_warn(dev, dev_warn(dev, "port%u: unsupported mode: \"%s\"\n",
"port%u: unsupported mode: \"%s\". Defaulting to MII.\n", if_phy->id, phy_modes(submode));
if_phy->id, phy_modes(rgmii_id));
return -EINVAL; return -EINVAL;
} }
if_phy->phy_if_mode = submode; if_phy->phy_if_mode = submode;
dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n", dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n",
__func__, if_phy->id, mode, rgmii_id, __func__, if_phy->id, submode, rgmii_id,
if_phy->rmii_clock_external); if_phy->rmii_clock_external);
regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE]; regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE];
......
...@@ -2550,7 +2550,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, ...@@ -2550,7 +2550,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep,
/* Update ring only if removed request is on pending_req_list list */ /* Update ring only if removed request is on pending_req_list list */
if (req_on_hw_ring) { if (req_on_hw_ring) {
link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma +
(priv_req->start_trb * TRB_SIZE)); ((priv_req->end_trb + 1) * TRB_SIZE));
link_trb->control = (link_trb->control & TRB_CYCLE) | link_trb->control = (link_trb->control & TRB_CYCLE) |
TRB_TYPE(TRB_LINK) | TRB_CHAIN; TRB_TYPE(TRB_LINK) | TRB_CHAIN;
...@@ -2595,11 +2595,21 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) ...@@ -2595,11 +2595,21 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
{ {
struct cdns3_device *priv_dev = priv_ep->cdns3_dev; struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
struct usb_request *request; struct usb_request *request;
struct cdns3_request *priv_req;
struct cdns3_trb *trb = NULL;
int ret; int ret;
int val; int val;
trace_cdns3_halt(priv_ep, 0, 0); trace_cdns3_halt(priv_ep, 0, 0);
request = cdns3_next_request(&priv_ep->pending_req_list);
if (request) {
priv_req = to_cdns3_request(request);
trb = priv_req->trb;
if (trb)
trb->control = trb->control ^ TRB_CYCLE;
}
writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
/* wait for EPRST cleared */ /* wait for EPRST cleared */
...@@ -2610,10 +2620,11 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) ...@@ -2610,10 +2620,11 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING); priv_ep->flags &= ~(EP_STALLED | EP_STALL_PENDING);
request = cdns3_next_request(&priv_ep->pending_req_list); if (request) {
if (trb)
if (request) trb->control = trb->control ^ TRB_CYCLE;
cdns3_rearm_transfer(priv_ep, 1); cdns3_rearm_transfer(priv_ep, 1);
}
cdns3_start_all_request(priv_dev, priv_ep); cdns3_start_all_request(priv_dev, priv_ep);
return ret; return ret;
......
...@@ -988,13 +988,17 @@ int usb_remove_device(struct usb_device *udev) ...@@ -988,13 +988,17 @@ int usb_remove_device(struct usb_device *udev)
{ {
struct usb_hub *hub; struct usb_hub *hub;
struct usb_interface *intf; struct usb_interface *intf;
int ret;
if (!udev->parent) /* Can't remove a root hub */ if (!udev->parent) /* Can't remove a root hub */
return -EINVAL; return -EINVAL;
hub = usb_hub_to_struct_hub(udev->parent); hub = usb_hub_to_struct_hub(udev->parent);
intf = to_usb_interface(hub->intfdev); intf = to_usb_interface(hub->intfdev);
usb_autopm_get_interface(intf); ret = usb_autopm_get_interface(intf);
if (ret < 0)
return ret;
set_bit(udev->portnum, hub->removed_bits); set_bit(udev->portnum, hub->removed_bits);
hub_port_logical_disconnect(hub, udev->portnum); hub_port_logical_disconnect(hub, udev->portnum);
usb_autopm_put_interface(intf); usb_autopm_put_interface(intf);
...@@ -1866,7 +1870,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1866,7 +1870,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) {
hub->quirk_disable_autosuspend = 1; hub->quirk_disable_autosuspend = 1;
usb_autopm_get_interface(intf); usb_autopm_get_interface_no_resume(intf);
} }
if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) if (hub_configure(hub, &desc->endpoint[0].desc) >= 0)
......
...@@ -213,7 +213,10 @@ static int usb_port_runtime_resume(struct device *dev) ...@@ -213,7 +213,10 @@ static int usb_port_runtime_resume(struct device *dev)
if (!port_dev->is_superspeed && peer) if (!port_dev->is_superspeed && peer)
pm_runtime_get_sync(&peer->dev); pm_runtime_get_sync(&peer->dev);
usb_autopm_get_interface(intf); retval = usb_autopm_get_interface(intf);
if (retval < 0)
return retval;
retval = usb_hub_set_port_power(hdev, hub, port1, true); retval = usb_hub_set_port_power(hdev, hub, port1, true);
msleep(hub_power_on_good_delay(hub)); msleep(hub_power_on_good_delay(hub));
if (udev && !retval) { if (udev && !retval) {
...@@ -266,7 +269,10 @@ static int usb_port_runtime_suspend(struct device *dev) ...@@ -266,7 +269,10 @@ static int usb_port_runtime_suspend(struct device *dev)
if (usb_port_block_power_off) if (usb_port_block_power_off)
return -EBUSY; return -EBUSY;
usb_autopm_get_interface(intf); retval = usb_autopm_get_interface(intf);
if (retval < 0)
return retval;
retval = usb_hub_set_port_power(hdev, hub, port1, false); retval = usb_hub_set_port_power(hdev, hub, port1, false);
usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION); usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
if (!port_dev->is_superspeed) if (!port_dev->is_superspeed)
......
...@@ -231,6 +231,9 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -231,6 +231,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Logitech PTZ Pro Camera */ /* Logitech PTZ Pro Camera */
{ USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT },
/* Logitech Screen Share */
{ USB_DEVICE(0x046d, 0x086c), .driver_info = USB_QUIRK_NO_LPM },
/* Logitech Quickcam Fusion */ /* Logitech Quickcam Fusion */
{ USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME },
......
...@@ -1071,7 +1071,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, ...@@ -1071,7 +1071,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
unsigned int rem = length % maxp; unsigned int rem = length % maxp;
unsigned chain = true; unsigned chain = true;
if (sg_is_last(s)) /*
* IOMMU driver is coalescing the list of sgs which shares a
* page boundary into one and giving it to USB driver. With
* this the number of sgs mapped is not equal to the number of
* sgs passed. So mark the chain bit to false if it isthe last
* mapped sg.
*/
if (i == remaining - 1)
chain = false; chain = false;
if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) {
......
...@@ -424,10 +424,6 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, ...@@ -424,10 +424,6 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
return err; return err;
} }
hub->vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(hub->vdd))
return PTR_ERR(hub->vdd);
if (of_property_read_u16_array(np, "vendor-id", &hub->vendor_id, 1)) if (of_property_read_u16_array(np, "vendor-id", &hub->vendor_id, 1))
hub->vendor_id = USB251XB_DEF_VENDOR_ID; hub->vendor_id = USB251XB_DEF_VENDOR_ID;
...@@ -640,6 +636,13 @@ static int usb251xb_get_ofdata(struct usb251xb *hub, ...@@ -640,6 +636,13 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
} }
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
static void usb251xb_regulator_disable_action(void *data)
{
struct usb251xb *hub = data;
regulator_disable(hub->vdd);
}
static int usb251xb_probe(struct usb251xb *hub) static int usb251xb_probe(struct usb251xb *hub)
{ {
struct device *dev = hub->dev; struct device *dev = hub->dev;
...@@ -676,10 +679,19 @@ static int usb251xb_probe(struct usb251xb *hub) ...@@ -676,10 +679,19 @@ static int usb251xb_probe(struct usb251xb *hub)
if (err) if (err)
return err; return err;
hub->vdd = devm_regulator_get(dev, "vdd");
if (IS_ERR(hub->vdd))
return PTR_ERR(hub->vdd);
err = regulator_enable(hub->vdd); err = regulator_enable(hub->vdd);
if (err) if (err)
return err; return err;
err = devm_add_action_or_reset(dev,
usb251xb_regulator_disable_action, hub);
if (err)
return err;
err = usb251xb_connect(hub); err = usb251xb_connect(hub);
if (err) { if (err) {
dev_err(dev, "Failed to connect hub (%d)\n", err); dev_err(dev, "Failed to connect hub (%d)\n", err);
......
...@@ -1258,6 +1258,12 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, ...@@ -1258,6 +1258,12 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999,
USB_SC_RBC, USB_PR_BULK, NULL, USB_SC_RBC, USB_PR_BULK, NULL,
0 ), 0 ),
UNUSUAL_DEV(0x090c, 0x1000, 0x1100, 0x1100,
"Samsung",
"Flash Drive FIT",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64),
/* aeb */ /* aeb */
UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff,
"Feiya", "Feiya",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment