Skip to content

Commit 213356f

Browse files
committed
Merge tag 'usb-5.5-rc6' of git://git.kernel.org/pub/scm/linux/kernel/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 ...
2 parents 9fb7007 + 1530f6f commit 213356f

File tree

19 files changed

+243
-93
lines changed

19 files changed

+243
-93
lines changed

drivers/phy/motorola/phy-cpcap-usb.c

Lines changed: 90 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ struct cpcap_usb_ints_state {
115115
enum cpcap_gpio_mode {
116116
CPCAP_DM_DP,
117117
CPCAP_MDM_RX_TX,
118-
CPCAP_UNKNOWN,
118+
CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
119119
CPCAP_OTG_DM_DP,
120120
};
121121

@@ -134,6 +134,8 @@ struct cpcap_phy_ddata {
134134
struct iio_channel *id;
135135
struct regulator *vusb;
136136
atomic_t active;
137+
unsigned int vbus_provider:1;
138+
unsigned int docked:1;
137139
};
138140

139141
static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
@@ -207,6 +209,19 @@ static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
207209
static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
208210
static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
209211

212+
static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata,
213+
enum musb_vbus_id_status status)
214+
{
215+
int error;
216+
217+
error = musb_mailbox(status);
218+
if (!error)
219+
return;
220+
221+
dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n",
222+
__func__, error);
223+
}
224+
210225
static void cpcap_usb_detect(struct work_struct *work)
211226
{
212227
struct cpcap_phy_ddata *ddata;
@@ -220,16 +235,66 @@ static void cpcap_usb_detect(struct work_struct *work)
220235
if (error)
221236
return;
222237

223-
if (s.id_ground) {
224-
dev_dbg(ddata->dev, "id ground, USB host mode\n");
238+
vbus = cpcap_usb_vbus_valid(ddata);
239+
240+
/* We need to kick the VBUS as USB A-host */
241+
if (s.id_ground && ddata->vbus_provider) {
242+
dev_dbg(ddata->dev, "still in USB A-host mode, kicking VBUS\n");
243+
244+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
245+
246+
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
247+
CPCAP_BIT_VBUSSTBY_EN |
248+
CPCAP_BIT_VBUSEN_SPI,
249+
CPCAP_BIT_VBUSEN_SPI);
250+
if (error)
251+
goto out_err;
252+
253+
return;
254+
}
255+
256+
if (vbus && s.id_ground && ddata->docked) {
257+
dev_dbg(ddata->dev, "still docked as A-host, signal ID down\n");
258+
259+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
260+
261+
return;
262+
}
263+
264+
/* No VBUS needed with docks */
265+
if (vbus && s.id_ground && !ddata->vbus_provider) {
266+
dev_dbg(ddata->dev, "connected to a dock\n");
267+
268+
ddata->docked = true;
269+
225270
error = cpcap_usb_set_usb_mode(ddata);
226271
if (error)
227272
goto out_err;
228273

229-
error = musb_mailbox(MUSB_ID_GROUND);
274+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
275+
276+
/*
277+
* Force check state again after musb has reoriented,
278+
* otherwise devices won't enumerate after loading PHY
279+
* driver.
280+
*/
281+
schedule_delayed_work(&ddata->detect_work,
282+
msecs_to_jiffies(1000));
283+
284+
return;
285+
}
286+
287+
if (s.id_ground && !ddata->docked) {
288+
dev_dbg(ddata->dev, "id ground, USB host mode\n");
289+
290+
ddata->vbus_provider = true;
291+
292+
error = cpcap_usb_set_usb_mode(ddata);
230293
if (error)
231294
goto out_err;
232295

296+
cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND);
297+
233298
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
234299
CPCAP_BIT_VBUSSTBY_EN |
235300
CPCAP_BIT_VBUSEN_SPI,
@@ -248,43 +313,26 @@ static void cpcap_usb_detect(struct work_struct *work)
248313

249314
vbus = cpcap_usb_vbus_valid(ddata);
250315

316+
/* Otherwise assume we're connected to a USB host */
251317
if (vbus) {
252-
/* Are we connected to a docking station with vbus? */
253-
if (s.id_ground) {
254-
dev_dbg(ddata->dev, "connected to a dock\n");
255-
256-
/* No VBUS needed with docks */
257-
error = cpcap_usb_set_usb_mode(ddata);
258-
if (error)
259-
goto out_err;
260-
error = musb_mailbox(MUSB_ID_GROUND);
261-
if (error)
262-
goto out_err;
263-
264-
return;
265-
}
266-
267-
/* Otherwise assume we're connected to a USB host */
268318
dev_dbg(ddata->dev, "connected to USB host\n");
269319
error = cpcap_usb_set_usb_mode(ddata);
270320
if (error)
271321
goto out_err;
272-
error = musb_mailbox(MUSB_VBUS_VALID);
273-
if (error)
274-
goto out_err;
322+
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID);
275323

276324
return;
277325
}
278326

327+
ddata->vbus_provider = false;
328+
ddata->docked = false;
329+
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
330+
279331
/* Default to debug UART mode */
280332
error = cpcap_usb_set_uart_mode(ddata);
281333
if (error)
282334
goto out_err;
283335

284-
error = musb_mailbox(MUSB_VBUS_OFF);
285-
if (error)
286-
goto out_err;
287-
288336
dev_dbg(ddata->dev, "set UART mode\n");
289337

290338
return;
@@ -376,7 +424,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
376424
{
377425
int error;
378426

379-
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
427+
/* Disable lines to prevent glitches from waking up mdm6600 */
428+
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
380429
if (error)
381430
goto out_err;
382431

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

455+
/* Enable UART mode */
456+
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
457+
if (error)
458+
goto out_err;
459+
406460
return 0;
407461

408462
out_err:
@@ -415,7 +469,8 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
415469
{
416470
int error;
417471

418-
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
472+
/* Disable lines to prevent glitches from waking up mdm6600 */
473+
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
419474
if (error)
420475
return error;
421476

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

437-
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
438-
CPCAP_BIT_USBXCVREN,
439-
CPCAP_BIT_USBXCVREN);
440-
if (error)
441-
goto out_err;
442-
443492
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
444493
CPCAP_BIT_PU_SPI |
445494
CPCAP_BIT_DMPD_SPI |
@@ -455,6 +504,11 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
455504
if (error)
456505
goto out_err;
457506

507+
/* Enable USB mode */
508+
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
509+
if (error)
510+
goto out_err;
511+
458512
return 0;
459513

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

652-
error = musb_mailbox(MUSB_VBUS_OFF);
653-
if (error)
654-
dev_err(ddata->dev, "could not set mailbox\n");
706+
cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF);
655707

656708
usb_remove_phy(&ddata->phy);
657709
cancel_delayed_work_sync(&ddata->detect_work);

drivers/phy/motorola/phy-mapphone-mdm6600.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static void phy_mdm6600_status(struct work_struct *work)
200200
struct phy_mdm6600 *ddata;
201201
struct device *dev;
202202
DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES);
203-
int error, i, val = 0;
203+
int error;
204204

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

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

222217
dev_info(dev, "modem status: %i %s\n",
223218
ddata->status,
224-
phy_mdm6600_status_name[ddata->status & 7]);
219+
phy_mdm6600_status_name[ddata->status]);
225220
complete(&ddata->ack);
226221
}
227222

drivers/phy/qualcomm/phy-qcom-qmp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
6767
#define CLAMP_EN BIT(0) /* enables i/o clamp_n */
6868

69-
#define PHY_INIT_COMPLETE_TIMEOUT 1000
69+
#define PHY_INIT_COMPLETE_TIMEOUT 10000
7070
#define POWER_DOWN_DELAY_US_MIN 10
7171
#define POWER_DOWN_DELAY_US_MAX 11
7272

drivers/phy/rockchip/phy-rockchip-inno-hdmi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw,
603603
{
604604
const struct pre_pll_config *cfg = pre_pll_cfg_table;
605605

606+
rate = (rate / 1000) * 1000;
607+
606608
for (; cfg->pixclock != 0; cfg++)
607609
if (cfg->pixclock == rate && !cfg->fracdiv)
608610
break;
@@ -755,6 +757,8 @@ static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw,
755757
{
756758
const struct pre_pll_config *cfg = pre_pll_cfg_table;
757759

760+
rate = (rate / 1000) * 1000;
761+
758762
for (; cfg->pixclock != 0; cfg++)
759763
if (cfg->pixclock == rate)
760764
break;

drivers/usb/cdns3/gadget.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,13 +1375,10 @@ static void cdns3_check_usb_interrupt_proceed(struct cdns3_device *priv_dev,
13751375
*/
13761376
static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
13771377
{
1378-
struct cdns3_device *priv_dev;
1379-
struct cdns3 *cdns = data;
1378+
struct cdns3_device *priv_dev = data;
13801379
irqreturn_t ret = IRQ_NONE;
13811380
u32 reg;
13821381

1383-
priv_dev = cdns->gadget_dev;
1384-
13851382
/* check USB device interrupt */
13861383
reg = readl(&priv_dev->regs->usb_ists);
13871384
if (reg) {
@@ -1419,14 +1416,12 @@ static irqreturn_t cdns3_device_irq_handler(int irq, void *data)
14191416
*/
14201417
static irqreturn_t cdns3_device_thread_irq_handler(int irq, void *data)
14211418
{
1422-
struct cdns3_device *priv_dev;
1423-
struct cdns3 *cdns = data;
1419+
struct cdns3_device *priv_dev = data;
14241420
irqreturn_t ret = IRQ_NONE;
14251421
unsigned long flags;
14261422
int bit;
14271423
u32 reg;
14281424

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

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

25402535
priv_dev = cdns->gadget_dev;
25412536

2542-
devm_free_irq(cdns->dev, cdns->dev_irq, cdns);
2537+
devm_free_irq(cdns->dev, cdns->dev_irq, priv_dev);
25432538

25442539
pm_runtime_mark_last_busy(cdns->dev);
25452540
pm_runtime_put_autosuspend(cdns->dev);
@@ -2710,7 +2705,8 @@ static int __cdns3_gadget_init(struct cdns3 *cdns)
27102705
ret = devm_request_threaded_irq(cdns->dev, cdns->dev_irq,
27112706
cdns3_device_irq_handler,
27122707
cdns3_device_thread_irq_handler,
2713-
IRQF_SHARED, dev_name(cdns->dev), cdns);
2708+
IRQF_SHARED, dev_name(cdns->dev),
2709+
cdns->gadget_dev);
27142710

27152711
if (ret)
27162712
goto err0;

drivers/usb/chipidea/host.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static int (*orig_bus_suspend)(struct usb_hcd *hcd);
2626

2727
struct ehci_ci_priv {
2828
struct regulator *reg_vbus;
29+
bool enabled;
2930
};
3031

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

40-
if (priv->reg_vbus) {
41+
if (priv->reg_vbus && enable != priv->enabled) {
4142
if (port > 1) {
4243
dev_warn(dev,
4344
"Not support multi-port regulator control\n");
@@ -53,6 +54,7 @@ static int ehci_ci_portpower(struct usb_hcd *hcd, int portnum, bool enable)
5354
enable ? "enable" : "disable", ret);
5455
return ret;
5556
}
57+
priv->enabled = enable;
5658
}
5759

5860
if (enable && (ci->platdata->phy_mode == USBPHY_INTERFACE_MODE_HSIC)) {

0 commit comments

Comments
 (0)