Skip to content

Commit

Permalink
Merge tag 'usb-5.5-rc6' 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 a number of USB and PHY driver fixes for 5.5-rc6

  Nothing all that unusual, just the a bunch of small fixes for a lot of
  different reported issues. The PHY driver fixes are in here as they
  interacted with the usb drivers.

  Full details of the patches are in the shortlog, and all of these have
  been in linux-next with no reported issues"

* tag 'usb-5.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (24 commits)
  usb: missing parentheses in USE_NEW_SCHEME
  usb: ohci-da8xx: ensure error return on variable error is set
  usb: musb: Disable pullup at init
  usb: musb: fix idling for suspend after disconnect interrupt
  usb: typec: ucsi: Fix the notification bit offsets
  USB: Fix: Don't skip endpoint descriptors with maxpacket=0
  USB-PD tcpm: bad warning+size, PPS adapters
  phy/rockchip: inno-hdmi: round clock rate down to closest 1000 Hz
  usb: chipidea: host: Disable port power only if previously enabled
  usb: cdns3: should not use the same dev_id for shared interrupt handler
  usb: dwc3: gadget: Fix request complete check
  usb: musb: dma: Correct parameter passed to IRQ handler
  usb: musb: jz4740: Silence error if code is -EPROBE_DEFER
  usb: udc: tegra: select USB_ROLE_SWITCH
  USB: core: fix check for duplicate endpoints
  phy: cpcap-usb: Drop extra write to usb2 register
  phy: cpcap-usb: Improve host vs docked mode detection
  phy: cpcap-usb: Prevent USB line glitches from waking up modem
  phy: mapphone-mdm6600: Fix uninitialized status value regression
  phy: cpcap-usb: Fix flakey host idling and enumerating of devices
  ...
  • Loading branch information
Linus Torvalds committed Jan 10, 2020
2 parents 9fb7007 + 1530f6f commit 213356f
Show file tree
Hide file tree
Showing 19 changed files with 243 additions and 93 deletions.
128 changes: 90 additions & 38 deletions drivers/phy/motorola/phy-cpcap-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ struct cpcap_usb_ints_state {
enum cpcap_gpio_mode {
CPCAP_DM_DP,
CPCAP_MDM_RX_TX,
CPCAP_UNKNOWN,
CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
CPCAP_OTG_DM_DP,
};

Expand All @@ -134,6 +134,8 @@ struct cpcap_phy_ddata {
struct iio_channel *id;
struct regulator *vusb;
atomic_t active;
unsigned int vbus_provider:1;
unsigned int docked:1;
};

static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
Expand Down Expand Up @@ -207,6 +209,19 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);

static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
enum musb_vbus_id_status status)
{
int error;

error = musb_mailbox(status);
if (!error)
return;

dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n",
__func__, error);
}

static void cpcap_usb_detect(struct work_struct *work)
{
struct cpcap_phy_ddata *ddata;
Expand All @@ -220,16 +235,66 @@ static void cpcap_usb_detect(struct work_struct *work)
if (error)
return;

if (s.id_ground) {
dev_dbg(ddata->dev, "id ground, USB host mode\n");
vbus = cpcap_usb_vbus_valid(ddata);

/* We need to kick the VBUS as USB A-host */
if (s.id_ground && ddata->vbus_provider) {
dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");

cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);

error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_VBUSSTBY_EN |
CPCAP_BIT_VBUSEN_SPI,
CPCAP_BIT_VBUSEN_SPI);
if (error)
goto out_err;

return;
}

if (vbus && s.id_ground && ddata->docked) {
dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");

cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);

return;
}

/* No VBUS needed with docks */
if (vbus && s.id_ground && !ddata->vbus_provider) {
dev_dbg(ddata->dev, "connected to a dock\n");

ddata->docked = true;

error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;

error = musb_mailbox(MUSB_ID_GROUND);
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);

/*
* Force check state again after musb has reoriented,
* otherwise devices won't enumerate after loading PHY
* driver.
*/
schedule_delayed_work(&ddata->detect_work,
msecs_to_jiffies(1000));

return;
}

if (s.id_ground && !ddata->docked) {
dev_dbg(ddata->dev, "id ground, USB host mode\n");

ddata->vbus_provider = true;

error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;

cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);

error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_VBUSSTBY_EN |
CPCAP_BIT_VBUSEN_SPI,
Expand All @@ -248,43 +313,26 @@ static void cpcap_usb_detect(struct work_struct *work)

vbus = cpcap_usb_vbus_valid(ddata);

/* Otherwise assume we're connected to a USB host */
if (vbus) {
/* Are we connected to a docking station with vbus? */
if (s.id_ground) {
dev_dbg(ddata->dev, "connected to a dock\n");

/* No VBUS needed with docks */
error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;
error = musb_mailbox(MUSB_ID_GROUND);
if (error)
goto out_err;

return;
}

/* Otherwise assume we're connected to a USB host */
dev_dbg(ddata->dev, "connected to USB host\n");
error = cpcap_usb_set_usb_mode(ddata);
if (error)
goto out_err;
error = musb_mailbox(MUSB_VBUS_VALID);
if (error)
goto out_err;
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);

return;
}

ddata->vbus_provider = false;
ddata->docked = false;
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);

/* Default to debug UART mode */
error = cpcap_usb_set_uart_mode(ddata);
if (error)
goto out_err;

error = musb_mailbox(MUSB_VBUS_OFF);
if (error)
goto out_err;

dev_dbg(ddata->dev, "set UART mode\n");

return;
Expand Down Expand Up @@ -376,7 +424,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
{
int error;

error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
/* Disable lines to prevent glitches from waking up mdm6600 */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
if (error)
goto out_err;

Expand All @@ -403,6 +452,11 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
if (error)
goto out_err;

/* Enable UART mode */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
if (error)
goto out_err;

return 0;

out_err:
Expand All @@ -415,7 +469,8 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
{
int error;

error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
/* Disable lines to prevent glitches from waking up mdm6600 */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
if (error)
return error;

Expand All @@ -434,12 +489,6 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
if (error)
goto out_err;

error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
CPCAP_BIT_USBXCVREN,
CPCAP_BIT_USBXCVREN);
if (error)
goto out_err;

error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
CPCAP_BIT_PU_SPI |
CPCAP_BIT_DMPD_SPI |
Expand All @@ -455,6 +504,11 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
if (error)
goto out_err;

/* Enable USB mode */
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
if (error)
goto out_err;

return 0;

out_err:
Expand Down Expand Up @@ -649,9 +703,7 @@ static int cpcap_usb_phy_remove(struct platform_device *pdev)
if (error)
dev_err(ddata->dev, "could not set UART mode\n");

error = musb_mailbox(MUSB_VBUS_OFF);
if (error)
dev_err(ddata->dev, "could not set mailbox\n");
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);

usb_remove_phy(&ddata->phy);
cancel_delayed_work_sync(&ddata->detect_work);
Expand Down
11 changes: 3 additions & 8 deletions drivers/phy/motorola/phy-mapphone-mdm6600.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ static void phy_mdm6600_status(struct work_struct *work)
struct phy_mdm6600 *ddata;
struct device *dev;
DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES);
int error, i, val = 0;
int error;

ddata = container_of(work, struct phy_mdm6600, status_work.work);
dev = ddata->dev;
Expand All @@ -212,16 +212,11 @@ static void phy_mdm6600_status(struct work_struct *work)
if (error)
return;

for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) {
val |= test_bit(i, values) << i;
dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n",
__func__, i, test_bit(i, values), val);
}
ddata->status = values[0];
ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1);

dev_info(dev, "modem status: %i %s\n",
ddata->status,
phy_mdm6600_status_name[ddata->status & 7]);
phy_mdm6600_status_name[ddata->status]);
complete(&ddata->ack);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/phy/qualcomm/phy-qcom-qmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
#define CLAMP_EN BIT(0) /* enables i/o clamp_n */

#define PHY_INIT_COMPLETE_TIMEOUT 1000
#define PHY_INIT_COMPLETE_TIMEOUT 10000
#define POWER_DOWN_DELAY_US_MIN 10
#define POWER_DOWN_DELAY_US_MAX 11

Expand Down
4 changes: 4 additions & 0 deletions drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,8 @@ static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
{
const struct pre_pll_config *cfg = pre_pll_cfg_table;

rate = (rate / 1000) * 1000;

for (; cfg->pixclock != 0; cfg++)
if (cfg->pixclock == rate && !cfg->fracdiv)
break;
Expand Down Expand Up @@ -755,6 +757,8 @@ static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
{
const struct pre_pll_config *cfg = pre_pll_cfg_table;

rate = (rate / 1000) * 1000;

for (; cfg->pixclock != 0; cfg++)
if (cfg->pixclock == rate)
break;
Expand Down
14 changes: 5 additions & 9 deletions drivers/usb/cdns3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,13 +1375,10 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
*/
static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
{
struct cdns3_device *priv_dev;
struct cdns3 *cdns = data;
struct cdns3_device *priv_dev = data;
irqreturn_t ret = IRQ_NONE;
u32 reg;

priv_dev = cdns->gadget_dev;

/* check USB device interrupt */
reg = readl(&priv_dev->regs->usb_ists);
if (reg) {
Expand Down Expand Up @@ -1419,14 +1416,12 @@ static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
*/
static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
{
struct cdns3_device *priv_dev;
struct cdns3 *cdns = data;
struct cdns3_device *priv_dev = data;
irqreturn_t ret = IRQ_NONE;
unsigned long flags;
int bit;
u32 reg;

priv_dev = cdns->gadget_dev;
spin_lock_irqsave(&priv_dev->lock, flags);

reg = readl(&priv_dev->regs->usb_ists);
Expand Down Expand Up @@ -2539,7 +2534,7 @@ void cdns3_gadget_exit(struct cdns3 *cdns)

priv_dev = cdns->gadget_dev;

devm_free_irq(cdns->dev, cdns->dev_irq, cdns);
devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);

pm_runtime_mark_last_busy(cdns->dev);
pm_runtime_put_autosuspend(cdns->dev);
Expand Down Expand Up @@ -2710,7 +2705,8 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq,
cdns3_device_irq_handler,
cdns3_device_thread_irq_handler,
IRQF_SHARED, dev_name(cdns->dev), cdns);
IRQF_SHARED, dev_name(cdns->dev),
cdns->gadget_dev);

if (ret)
goto err0;
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/chipidea/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd);

struct ehci_ci_priv {
struct regulator *reg_vbus;
bool enabled;
};

static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
Expand All @@ -37,7 +38,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
int ret = 0;
int port = HCS_N_PORTS(ehci->hcs_params);

if (priv->reg_vbus) {
if (priv->reg_vbus && enable != priv->enabled) {
if (port > 1) {
dev_warn(dev,
"Not support multi-port regulator control\n");
Expand All @@ -53,6 +54,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
enable ? "enable" : "disable", ret);
return ret;
}
priv->enabled = enable;
}

if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {
Expand Down
Loading

0 comments on commit 213356f

Please sign in to comment.