Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58059921 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB/PHY fixes from Greg KH:
 "Here are a small number of USB and PHY driver fixes for 4.14-rc6

  There is the usual musb and xhci fixes in here, as well as some needed
  phy patches. Also is a nasty regression fix for usbfs that has started
  to hit a lot of people using virtual machines.

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

* tag 'usb-4.14-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (26 commits)
  usb: hub: Allow reset retry for USB2 devices on connect bounce
  USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()
  MAINTAINERS: fix git tree url for musb module
  usb: quirks: add quirk for WORLDE MINI MIDI keyboard
  usb: musb: sunxi: Explicitly release USB PHY on exit
  usb: musb: Check for host-mode using is_host_active() on reset interrupt
  usb: musb: musb_cppi41: Configure the number of channels for DA8xx
  usb: musb: musb_cppi41: Fix cppi41_set_dma_mode() for DA8xx
  usb: musb: musb_cppi41: Fix the address of teardown and autoreq registers
  USB: musb: fix late external abort on suspend
  USB: musb: fix session-bit runtime-PM quirk
  usb: cdc_acm: Add quirk for Elatec TWN3
  USB: devio: Revert "USB: devio: Don't corrupt user memory"
  usb: xhci: Handle error condition in xhci_stop_device()
  usb: xhci: Reset halted endpoint if trb is noop
  xhci: Cleanup current_cmd in xhci_cleanup_command_queue()
  xhci: Identify USB 3.1 capable hosts by their port protocol capability
  USB: serial: metro-usb: add MS7820 device id
  phy: rockchip-typec: Check for errors from tcphy_phy_init()
  phy: rockchip-typec: Don't set the aux voltage swing to 400 mV
  ...
parents 02982f85 1ac7db63
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -9213,7 +9213,6 @@ F: include/linux/isicom.h
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
M:	Bin Liu <b-liu@ti.com>
M:	Bin Liu <b-liu@ti.com>
L:	linux-usb@vger.kernel.org
L:	linux-usb@vger.kernel.org
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
S:	Maintained
S:	Maintained
F:	drivers/usb/musb/
F:	drivers/usb/musb/


+14 −4
Original line number Original line Diff line number Diff line
@@ -111,6 +111,8 @@
#define     MVEBU_COMPHY_CONF6_40B		BIT(18)
#define     MVEBU_COMPHY_CONF6_40B		BIT(18)
#define MVEBU_COMPHY_SELECTOR			0x1140
#define MVEBU_COMPHY_SELECTOR			0x1140
#define     MVEBU_COMPHY_SELECTOR_PHY(n)	((n) * 0x4)
#define     MVEBU_COMPHY_SELECTOR_PHY(n)	((n) * 0x4)
#define MVEBU_COMPHY_PIPE_SELECTOR		0x1144
#define     MVEBU_COMPHY_PIPE_SELECTOR_PIPE(n)	((n) * 0x4)


#define MVEBU_COMPHY_LANES	6
#define MVEBU_COMPHY_LANES	6
#define MVEBU_COMPHY_PORTS	3
#define MVEBU_COMPHY_PORTS	3
@@ -468,13 +470,17 @@ static int mvebu_comphy_power_on(struct phy *phy)
{
{
	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
	struct mvebu_comphy_lane *lane = phy_get_drvdata(phy);
	struct mvebu_comphy_priv *priv = lane->priv;
	struct mvebu_comphy_priv *priv = lane->priv;
	int ret;
	int ret, mux;
	u32 mux, val;
	u32 val;


	mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode);
	mux = mvebu_comphy_get_mux(lane->id, lane->port, lane->mode);
	if (mux < 0)
	if (mux < 0)
		return -ENOTSUPP;
		return -ENOTSUPP;


	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);

	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
	regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
	val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
	val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
@@ -526,6 +532,10 @@ static int mvebu_comphy_power_off(struct phy *phy)
	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
	val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
	regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);


	regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
	val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
	regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);

	return 0;
	return 0;
}
}


@@ -576,8 +586,8 @@ static int mvebu_comphy_probe(struct platform_device *pdev)
		return PTR_ERR(priv->regmap);
		return PTR_ERR(priv->regmap);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->base = devm_ioremap_resource(&pdev->dev, res);
	priv->base = devm_ioremap_resource(&pdev->dev, res);
	if (!priv->base)
	if (IS_ERR(priv->base))
		return -ENOMEM;
		return PTR_ERR(priv->base);


	for_each_available_child_of_node(pdev->dev.of_node, child) {
	for_each_available_child_of_node(pdev->dev.of_node, child) {
		struct mvebu_comphy_lane *lane;
		struct mvebu_comphy_lane *lane;
+2 −1
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@
/* banks shared by multiple phys */
/* banks shared by multiple phys */
#define SSUSB_SIFSLV_V1_SPLLC		0x000	/* shared by u3 phys */
#define SSUSB_SIFSLV_V1_SPLLC		0x000	/* shared by u3 phys */
#define SSUSB_SIFSLV_V1_U2FREQ		0x100	/* shared by u2 phys */
#define SSUSB_SIFSLV_V1_U2FREQ		0x100	/* shared by u2 phys */
#define SSUSB_SIFSLV_V1_CHIP		0x300	/* shared by u3 phys */
/* u2 phy bank */
/* u2 phy bank */
#define SSUSB_SIFSLV_V1_U2PHY_COM	0x000
#define SSUSB_SIFSLV_V1_U2PHY_COM	0x000
/* u3/pcie/sata phy banks */
/* u3/pcie/sata phy banks */
@@ -762,7 +763,7 @@ static void phy_v1_banks_init(struct mtk_tphy *tphy,
	case PHY_TYPE_USB3:
	case PHY_TYPE_USB3:
	case PHY_TYPE_PCIE:
	case PHY_TYPE_PCIE:
		u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
		u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
		u3_banks->chip = NULL;
		u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP;
		u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
		u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
		u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
		u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
		break;
		break;
+55 −27
Original line number Original line Diff line number Diff line
@@ -443,14 +443,34 @@ static inline int property_enable(struct rockchip_typec_phy *tcphy,
	return regmap_write(tcphy->grf_regs, reg->offset, val | mask);
	return regmap_write(tcphy->grf_regs, reg->offset, val | mask);
}
}


static void tcphy_dp_aux_set_flip(struct rockchip_typec_phy *tcphy)
{
	u16 tx_ana_ctrl_reg_1;

	/*
	 * Select the polarity of the xcvr:
	 * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull
	 * down aux_m)
	 * 0, Normal polarity (if TYPEC, pulls up aux_m and pulls down
	 * aux_p)
	 */
	tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
	if (!tcphy->flip)
		tx_ana_ctrl_reg_1 |= BIT(12);
	else
		tx_ana_ctrl_reg_1 &= ~BIT(12);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
}

static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
{
{
	u16 tx_ana_ctrl_reg_1;
	u16 rdata, rdata2, val;
	u16 rdata, rdata2, val;


	/* disable txda_cal_latch_en for rewrite the calibration values */
	/* disable txda_cal_latch_en for rewrite the calibration values */
	rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 = readl(tcphy->base + TX_ANA_CTRL_REG_1);
	val = rdata & 0xdfff;
	tx_ana_ctrl_reg_1 &= ~BIT(13);
	writel(val, tcphy->base + TX_ANA_CTRL_REG_1);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);


	/*
	/*
	 * read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and
	 * read a resistor calibration code from CMN_TXPUCAL_CTRL[6:0] and
@@ -472,9 +492,8 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
	 * Activate this signal for 1 clock cycle to sample new calibration
	 * Activate this signal for 1 clock cycle to sample new calibration
	 * values.
	 * values.
	 */
	 */
	rdata = readl(tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |= BIT(13);
	val = rdata | 0x2000;
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
	writel(val, tcphy->base + TX_ANA_CTRL_REG_1);
	usleep_range(150, 200);
	usleep_range(150, 200);


	/* set TX Voltage Level and TX Deemphasis to 0 */
	/* set TX Voltage Level and TX Deemphasis to 0 */
@@ -482,8 +501,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
	/* re-enable decap */
	/* re-enable decap */
	writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2);
	writel(0x100, tcphy->base + TX_ANA_CTRL_REG_2);
	writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2);
	writel(0x300, tcphy->base + TX_ANA_CTRL_REG_2);
	writel(0x2008, tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |= BIT(3);
	writel(0x2018, tcphy->base + TX_ANA_CTRL_REG_1);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |= BIT(4);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);


	writel(0, tcphy->base + TX_ANA_CTRL_REG_5);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_5);


@@ -494,8 +515,10 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
	writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4);
	writel(0x1001, tcphy->base + TX_ANA_CTRL_REG_4);


	/* re-enables Bandgap reference for LDO */
	/* re-enables Bandgap reference for LDO */
	writel(0x2098, tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |= BIT(7);
	writel(0x2198, tcphy->base + TX_ANA_CTRL_REG_1);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |= BIT(8);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);


	/*
	/*
	 * re-enables the transmitter pre-driver, driver data selection MUX,
	 * re-enables the transmitter pre-driver, driver data selection MUX,
@@ -505,27 +528,26 @@ static void tcphy_dp_aux_calibration(struct rockchip_typec_phy *tcphy)
	writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2);
	writel(0x303, tcphy->base + TX_ANA_CTRL_REG_2);


	/*
	/*
	 * BIT 12: Controls auxda_polarity, which selects the polarity of the
	 * Do some magic undocumented stuff, some of which appears to
	 * xcvr:
	 * undo the "re-enables Bandgap reference for LDO" above.
	 * 1, Reverses the polarity (If TYPEC, Pulls ups aux_p and pull
	 * down aux_m)
	 * 0, Normal polarity (if TYPE_C, pulls up aux_m and pulls down
	 * aux_p)
	 */
	 */
	val = 0xa078;
	tx_ana_ctrl_reg_1 |=  BIT(15);
	if (!tcphy->flip)
	tx_ana_ctrl_reg_1 &= ~BIT(8);
		val |= BIT(12);
	tx_ana_ctrl_reg_1 &= ~BIT(7);
	writel(val, tcphy->base + TX_ANA_CTRL_REG_1);
	tx_ana_ctrl_reg_1 |=  BIT(6);
	tx_ana_ctrl_reg_1 |=  BIT(5);
	writel(tx_ana_ctrl_reg_1, tcphy->base + TX_ANA_CTRL_REG_1);


	writel(0, tcphy->base + TX_ANA_CTRL_REG_3);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_3);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_4);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_4);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_5);
	writel(0, tcphy->base + TX_ANA_CTRL_REG_5);


	/*
	/*
	 * Controls low_power_swing_en, set the voltage swing of the driver
	 * Controls low_power_swing_en, don't set the voltage swing of the
	 * to 400mv. The values	below are peak to peak (differential) values.
	 * driver to 400mv. The values below are peak to peak (differential)
	 * values.
	 */
	 */
	writel(4, tcphy->base + TXDA_COEFF_CALC_CTRL);
	writel(0, tcphy->base + TXDA_COEFF_CALC_CTRL);
	writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA);
	writel(0, tcphy->base + TXDA_CYA_AUXDA_CYA);


	/* Controls tx_high_z_tm_en */
	/* Controls tx_high_z_tm_en */
@@ -555,6 +577,7 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
	reset_control_deassert(tcphy->tcphy_rst);
	reset_control_deassert(tcphy->tcphy_rst);


	property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip);
	property_enable(tcphy, &cfg->typec_conn_dir, tcphy->flip);
	tcphy_dp_aux_set_flip(tcphy);


	tcphy_cfg_24m(tcphy);
	tcphy_cfg_24m(tcphy);


@@ -685,8 +708,11 @@ static int rockchip_usb3_phy_power_on(struct phy *phy)
	if (tcphy->mode == new_mode)
	if (tcphy->mode == new_mode)
		goto unlock_ret;
		goto unlock_ret;


	if (tcphy->mode == MODE_DISCONNECT)
	if (tcphy->mode == MODE_DISCONNECT) {
		tcphy_phy_init(tcphy, new_mode);
		ret = tcphy_phy_init(tcphy, new_mode);
		if (ret)
			goto unlock_ret;
	}


	/* wait TCPHY for pipe ready */
	/* wait TCPHY for pipe ready */
	for (timeout = 0; timeout < 100; timeout++) {
	for (timeout = 0; timeout < 100; timeout++) {
@@ -760,10 +786,12 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
	 */
	 */
	if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) {
	if (new_mode == MODE_DFP_DP && tcphy->mode != MODE_DISCONNECT) {
		tcphy_phy_deinit(tcphy);
		tcphy_phy_deinit(tcphy);
		tcphy_phy_init(tcphy, new_mode);
		ret = tcphy_phy_init(tcphy, new_mode);
	} else if (tcphy->mode == MODE_DISCONNECT) {
	} else if (tcphy->mode == MODE_DISCONNECT) {
		tcphy_phy_init(tcphy, new_mode);
		ret = tcphy_phy_init(tcphy, new_mode);
	}
	}
	if (ret)
		goto unlock_ret;


	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
	ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
				 val, val & DP_MODE_A2, 1000,
				 val, val & DP_MODE_A2, 1000,
+2 −0
Original line number Original line Diff line number Diff line
@@ -454,6 +454,8 @@ tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type,
		char *name;
		char *name;


		name = kasprintf(GFP_KERNEL, "%s-%u", type, index);
		name = kasprintf(GFP_KERNEL, "%s-%u", type, index);
		if (!name)
			return ERR_PTR(-ENOMEM);
		np = of_find_node_by_name(np, name);
		np = of_find_node_by_name(np, name);
		kfree(name);
		kfree(name);
	}
	}
Loading