[PATCH] Add Proliic new chip: PL2303TB & PL2303N(G)
Add new PID to support PL2303TB (TYPE_HX) Add new PID to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Flow Control to support PL2303(N)GC/GB/GS/GT/GL/GE (TYPE_HXN) Add new Pull-Up Mode to support PL2303HXD (TYPE_HX) Fixed warning:restricted__le16 degrades to integer Signed-off-by: Charles Yeh --- drivers/usb/serial/pl2303.c | 116 +--- drivers/usb/serial/pl2303.h | 11 2 files changed, 106 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index a4e0d13fc121..8c71612e1811 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -46,6 +46,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ZTEK) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_TB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GC) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GB) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GT) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GL) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GE) }, + { USB_DEVICE(PL2303_VENDOR_ID, PL2303G_PRODUCT_ID_GS) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID), @@ -123,9 +130,11 @@ MODULE_DEVICE_TABLE(usb, id_table); #define VENDOR_WRITE_REQUEST_TYPE 0x40 #define VENDOR_WRITE_REQUEST 0x01 +#define VENDOR_WRITE_NREQUEST 0x80 #define VENDOR_READ_REQUEST_TYPE 0xc0 #define VENDOR_READ_REQUEST0x01 +#define VENDOR_READ_NREQUEST 0x81 #define UART_STATE_INDEX 8 #define UART_STATE_MSR_MASK0x8b @@ -139,11 +148,21 @@ MODULE_DEVICE_TABLE(usb, id_table); #define UART_OVERRUN_ERROR 0x40 #define UART_CTS 0x80 +#define TYPE_HX_READ_OTP_STATUS_REGISTER 0x8484 +#define TYPE_HX_EXTERNAL_PULLUP_MODE 0x08 +#define TYPE_HX_PULLUP_MODE_REG0x09 +#define TYPE_HXN_UART_FLOWCONTROL 0x0A +#define TYPE_HXN_HARDWAREFLOW 0xFA +#define TYPE_HXN_SOFTWAREFLOW 0xEE +#define TYPE_HXN_NOFLOW0xFF +#define TYPE_HXN_RESET_DOWN_UPSTREAM 0x07 + static void pl2303_set_break(struct usb_serial_port *port, bool enable); enum pl2303_type { TYPE_01,/* Type 0 and 1 (difference unknown) */ TYPE_HX,/* HX version of the pl2303 chip */ + TYPE_HXN, /* HXN version of the pl2303 chip */ TYPE_COUNT }; @@ -173,16 +192,26 @@ static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = { [TYPE_HX] = { .max_baud_rate =1200, }, + [TYPE_HXN] = { + .max_baud_rate =1200, + }, }; static int pl2303_vendor_read(struct usb_serial *serial, u16 value, unsigned char buf[1]) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; + + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_READ_NREQUEST; + else + request = VENDOR_READ_REQUEST; res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - VENDOR_READ_REQUEST, VENDOR_READ_REQUEST_TYPE, + request, VENDOR_READ_REQUEST_TYPE, value, 0, buf, 1, 100); if (res != 1) { dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__, @@ -201,12 +230,19 @@ static int pl2303_vendor_read(struct usb_serial *serial, u16 value, static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index) { struct device *dev = &serial->interface->dev; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int res; + u8 request; dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, index); + if (spriv->type == &pl2303_type_data[TYPE_HXN]) + request = VENDOR_WRITE_NREQUEST; + else + request = VENDOR_WRITE_REQUEST; + res = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - VENDOR_WRITE_REQUEST, VENDOR_WRITE_REQUEST_TYPE, + request, VENDOR_WRITE_REQUEST_TYPE, value, index, NULL, 0, 100); if (res) { dev_err(dev, "%s - failed to write [%04x]: %d\n", __func__, @@ -286,6 +322,7 @@ static int pl2303_startup(struct usb_serial *serial) struct pl2303_serial_private *spriv; enu
Re: [PATCH 2/2] phy: qualcomm: usb: Add Super-Speed PHY driver
On 12/20/18 21:29, Stephen Boyd wrote: Quoting Jorge Ramirez-Ortiz (2018-12-07 01:55:58) From: Shawn Guo Driver to control the Synopsys SS PHY 1.0.0 implemeneted in QCS404 Based on Sriharsha Allenki's original code. Signed-off-by: Jorge Ramirez-Ortiz Signed-off-by: Shawn Guo chain should be swapped? ok. Shawn asked me to remove him from the authors list so will remove. Reviewed-by: Vinod Koul will remove the reviewed-by line as well. --- diff --git a/drivers/phy/qualcomm/phy-qcom-usb-ss.c b/drivers/phy/qualcomm/phy-qcom-usb-ss.c new file mode 100644 index 000..7b6a55e --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-usb-ss.c + +struct ssphy_priv { + void __iomem *base; + struct device *dev; + struct reset_control *reset_com; + struct reset_control *reset_phy; + struct clk *clk_ref; + struct clk *clk_phy; + struct clk *clk_pipe; Use bulk clk APIs? And just get and enable all the clks? yes. + struct regulator *vdda1p8; + struct regulator *vbus; + struct regulator *vdd; + unsigned int vdd_levels[LEVEL_NUM]; +}; + +static inline void qcom_ssphy_updatel(void __iomem *addr, u32 mask, u32 val) +{ + writel((readl(addr) & ~mask) | val, addr); +} + +static int qcom_ssphy_config_vdd(struct ssphy_priv *priv, +enum phy_vdd_level level) +{ + return regulator_set_voltage(priv->vdd, +priv->vdd_levels[level], +priv->vdd_levels[LEVEL_MAX]); regulator_set_voltage(reg, 0, max) is very suspicious. It's voltage corners where the voltages are known? sorry I dont understand the question this regulator on the ss phy wold be vreg_l3_1p05: l3 { regulator-min-microvolt = <976000>; regulator-max-microvolt = <116>; }; +} + +static int qcom_ssphy_ldo_enable(struct ssphy_priv *priv) +{ + int ret; + + ret = regulator_set_load(priv->vdda1p8, 23000); Do you need to do this? Why can't the regulator be in high power mode all the time and then go low power when it's disabled? this regulator is shared with the usb hs phy and each (ss/hs) have different load requirements. why would it be wrong for the ss phy to announce its needs (which will differ from those of the hs phy)? + if (ret < 0) { + dev_err(priv->dev, "Failed to set regulator1p8 load\n"); + return ret; + } + + ret = regulator_set_voltage(priv->vdda1p8, 180, 180); This looks unnecessary. The 1.8V regulator sounds like it better be 1.8V so board constraints should enforce that. All that should be here is enabling the regulator. ok + if (ret) { + dev_err(priv->dev, "Failed to set regulator1p8 voltage\n"); + goto put_vdda1p8_lpm; + } + + ret = regulator_enable(priv->vdda1p8); + if (ret) { + dev_err(priv->dev, "Failed to enable regulator1p8\n"); + goto unset_vdda1p8; + } + + return ret; + + /* rollback regulator changes */ + +unset_vdda1p8: + regulator_set_voltage(priv->vdda1p8, 0, 180); + +put_vdda1p8_lpm: + regulator_set_load(priv->vdda1p8, 0); + + return ret; +} + +static void qcom_ssphy_ldo_disable(struct ssphy_priv *priv) +{ + regulator_disable(priv->vdda1p8); + regulator_set_voltage(priv->vdda1p8, 0, 180); Urgh why? since it is being shared with the hs phy I understand this is required to vote the transition to the lowest voltage state. + regulator_set_load(priv->vdda1p8, 0); +}
Re: [PATCH 1/2] dt-bindings: Add Qualcomm USB Super-Speed PHY bindings
On 12/20/18 21:25, Stephen Boyd wrote: Quoting Jorge Ramirez-Ortiz (2018-12-07 01:55:57) + +- qcom,vdd-voltage-level: +Value type: +Definition: This is a list of three integer values where +each value corresponding to voltage corner in uV. As far as I'm aware, this isn't how qcom's voltage corners are handled or are going to be handled. Can't you hardcode it in the driver for now? sure will do. if there is any other driver in some tree/branch that I could be looking as a reference - to avoid having to hardcode the values in the driver- please let me know.
[PATCH v2] usb: chipidea: add a check for the availability of next child
of_get_next_available_child returns NULL when no child nodes are found. The fix checks its return value instead of assuming a child is found. Signed-off-by: Kangjie Lu --- drivers/usb/chipidea/ci_hdrc_msm.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 880009987460..b7f7acef72d4 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -250,6 +250,10 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); if (ulpi_node) { phy_node = of_get_next_available_child(ulpi_node, NULL); + if (!phy_node) { + dev_err(&pdev->dev, "no child nodes found\n"); + return -ENODEV; + } ci->hsic = of_device_is_compatible(phy_node, "qcom,usb-hsic-phy"); of_node_put(phy_node); } -- 2.17.2 (Apple Git-113)
[PATCH AUTOSEL 4.19 94/97] qmi_wwan: Add support for Fibocom NL678 series
From: Jörgen Storvist [ Upstream commit 7c3db4105ce8d69bcb5c04bfa9acd1e9119af8d5 ] Added support for Fibocom NL678 series cellular module QMI interface. Using QMI_QUIRK_SET_DTR required for Qualcomm MDM9x40 series chipsets. Signed-off-by: Jörgen Storvist Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index c8872dd5ff5e..f5bac5075386 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1265,6 +1265,7 @@ static const struct usb_device_id products[] = { {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},/* Quectel BG96 */ + {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},/* Acer Gobi Modem Device */ -- 2.19.1
[PATCH AUTOSEL 4.19 95/97] qmi_wwan: Fix qmap header retrieval in qmimux_rx_fixup
From: Daniele Palmas [ Upstream commit d667044f49513d55fcfefe4fa8f8d96091782901 ] This patch fixes qmap header retrieval when modem is configured for dl data aggregation. Signed-off-by: Daniele Palmas Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index f5bac5075386..774e1ff01c9a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -151,17 +151,18 @@ static bool qmimux_has_slaves(struct usbnet *dev) static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { - unsigned int len, offset = sizeof(struct qmimux_hdr); + unsigned int len, offset = 0; struct qmimux_hdr *hdr; struct net_device *net; struct sk_buff *skbn; + u8 qmimux_hdr_sz = sizeof(*hdr); - while (offset < skb->len) { - hdr = (struct qmimux_hdr *)skb->data; + while (offset + qmimux_hdr_sz < skb->len) { + hdr = (struct qmimux_hdr *)(skb->data + offset); len = be16_to_cpu(hdr->pkt_len); /* drop the packet, bogus length */ - if (offset + len > skb->len) + if (offset + len + qmimux_hdr_sz > skb->len) return 0; /* control packet, we do not know what to do */ @@ -176,7 +177,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; skbn->dev = net; - switch (skb->data[offset] & 0xf0) { + switch (skb->data[offset + qmimux_hdr_sz] & 0xf0) { case 0x40: skbn->protocol = htons(ETH_P_IP); break; @@ -188,12 +189,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) goto skip; } - skb_put_data(skbn, skb->data + offset, len); + skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len); if (netif_rx(skbn) != NET_RX_SUCCESS) return 0; skip: - offset += len + sizeof(struct qmimux_hdr); + offset += len + qmimux_hdr_sz; } return 1; } -- 2.19.1
[PATCH AUTOSEL 4.14 58/59] qmi_wwan: Fix qmap header retrieval in qmimux_rx_fixup
From: Daniele Palmas [ Upstream commit d667044f49513d55fcfefe4fa8f8d96091782901 ] This patch fixes qmap header retrieval when modem is configured for dl data aggregation. Signed-off-by: Daniele Palmas Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index d88e6a15022b..429d08a68a63 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -151,17 +151,18 @@ static bool qmimux_has_slaves(struct usbnet *dev) static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) { - unsigned int len, offset = sizeof(struct qmimux_hdr); + unsigned int len, offset = 0; struct qmimux_hdr *hdr; struct net_device *net; struct sk_buff *skbn; + u8 qmimux_hdr_sz = sizeof(*hdr); - while (offset < skb->len) { - hdr = (struct qmimux_hdr *)skb->data; + while (offset + qmimux_hdr_sz < skb->len) { + hdr = (struct qmimux_hdr *)(skb->data + offset); len = be16_to_cpu(hdr->pkt_len); /* drop the packet, bogus length */ - if (offset + len > skb->len) + if (offset + len + qmimux_hdr_sz > skb->len) return 0; /* control packet, we do not know what to do */ @@ -176,7 +177,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) return 0; skbn->dev = net; - switch (skb->data[offset] & 0xf0) { + switch (skb->data[offset + qmimux_hdr_sz] & 0xf0) { case 0x40: skbn->protocol = htons(ETH_P_IP); break; @@ -188,12 +189,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) goto skip; } - skb_put_data(skbn, skb->data + offset, len); + skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len); if (netif_rx(skbn) != NET_RX_SUCCESS) return 0; skip: - offset += len + sizeof(struct qmimux_hdr); + offset += len + qmimux_hdr_sz; } return 1; } -- 2.19.1
[PATCH AUTOSEL 4.14 48/59] lan78xx: Resolve issue with changing MAC address
From: Jason Martinsen [ Upstream commit 1551569659c502003926a2067ee76176148a ] Current state for the lan78xx driver does not allow for changing the MAC address of the interface, without either removing the module (if you compiled it that way) or rebooting the machine. If you attempt to change the MAC address, ifconfig will show the new address, however, the system/interface will not respond to any traffic using that configuration. A few short-term options to work around this are to unload the module and reload it with the new MAC address, change the interface to "promisc", or reboot with the correct configuration to change the MAC. This patch enables the ability to change the MAC address via fairly normal means... ifdown modify entry in /etc/network/interfaces OR a similar method ifup Then test via any network communication, such as ICMP requests to gateway. My only test platform for this patch has been a raspberry pi model 3b+. Signed-off-by: Jason Martinsen - Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index e069b310d6a6..b62c41114e34 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2212,6 +2212,10 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + /* Added to support MAC address changes */ + ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + return 0; } -- 2.19.1
[PATCH AUTOSEL 4.14 32/59] qmi_wwan: Added support for Telit LN940 series
From: Jörgen Storvist [ Upstream commit 1986af16e8ed355822600c24b3d2f0be46b573df ] Added support for the Telit LN940 series cellular modules QMI interface. QMI_QUIRK_SET_DTR quirk requied for Qualcomm MDM9x40 chipset. Signed-off-by: Jörgen Storvist Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 11a25cef113f..d88e6a15022b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1221,6 +1221,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},/* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},/* Telit LE920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1900, 1)}, /* Telit LN940 series */ {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},/* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},/* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},/* XS Stick W100-2 from 4G Systems */ -- 2.19.1
[PATCH AUTOSEL 4.14 21/59] USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
From: Hui Peng [ Upstream commit 5146f95df782b0ac61abde36567e718692725c89 ] The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data. Add a length check for both locations and updated hso_probe to bail on error. This issue has been assigned CVE-2018-19985. Reported-by: Hui Peng Reported-by: Mathias Payer Signed-off-by: Hui Peng Signed-off-by: Mathias Payer Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/hso.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index d7a3379ea668..18a0952f68a8 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2806,6 +2806,12 @@ static int hso_get_config_data(struct usb_interface *interface) return -EIO; } + /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2876,10 +2882,18 @@ static int hso_probe(struct usb_interface *interface, /* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated +* array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + } /* Check if we need to switch to alt interfaces prior to port * configuration */ -- 2.19.1
[PATCH AUTOSEL 4.19 77/97] lan78xx: Resolve issue with changing MAC address
From: Jason Martinsen [ Upstream commit 1551569659c502003926a2067ee76176148a ] Current state for the lan78xx driver does not allow for changing the MAC address of the interface, without either removing the module (if you compiled it that way) or rebooting the machine. If you attempt to change the MAC address, ifconfig will show the new address, however, the system/interface will not respond to any traffic using that configuration. A few short-term options to work around this are to unload the module and reload it with the new MAC address, change the interface to "promisc", or reboot with the correct configuration to change the MAC. This patch enables the ability to change the MAC address via fairly normal means... ifdown modify entry in /etc/network/interfaces OR a similar method ifup Then test via any network communication, such as ICMP requests to gateway. My only test platform for this patch has been a raspberry pi model 3b+. Signed-off-by: Jason Martinsen - Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index c3c9ba44e2a1..8d140495da79 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2335,6 +2335,10 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + /* Added to support MAC address changes */ + ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + return 0; } -- 2.19.1
[PATCH AUTOSEL 4.19 52/97] qmi_wwan: Added support for Telit LN940 series
From: Jörgen Storvist [ Upstream commit 1986af16e8ed355822600c24b3d2f0be46b573df ] Added support for the Telit LN940 series cellular modules QMI interface. QMI_QUIRK_SET_DTR quirk requied for Qualcomm MDM9x40 chipset. Signed-off-by: Jörgen Storvist Acked-by: Bjørn Mork Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index dada68f279bc..c8872dd5ff5e 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1230,6 +1230,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},/* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},/* Telit LE920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1900, 1)}, /* Telit LN940 series */ {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},/* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},/* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},/* XS Stick W100-2 from 4G Systems */ -- 2.19.1
[PATCH AUTOSEL 4.19 51/97] qmi_wwan: Added support for Fibocom NL668 series
From: Jörgen Storvist [ Upstream commit 110a1cc28bc383adb4885eff27e18c61ddebffb4 ] Added support for Fibocom NL668 series QMI interface. Using QMI_QUIRK_SET_DTR required for Qualcomm MDM9x07 chipsets. Signed-off-by: Jörgen Storvist Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/qmi_wwan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 72a55b6b4211..dada68f279bc 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -1117,6 +1117,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x1435, 0xd181, 4)},/* Wistron NeWeb D18Q1 */ {QMI_FIXED_INTF(0x1435, 0xd181, 5)},/* Wistron NeWeb D18Q1 */ {QMI_FIXED_INTF(0x1435, 0xd191, 4)},/* Wistron NeWeb D19Q1 */ + {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ {QMI_FIXED_INTF(0x16d8, 0x6003, 0)},/* CMOTech 6003 */ {QMI_FIXED_INTF(0x16d8, 0x6007, 0)},/* CMOTech CHE-628S */ {QMI_FIXED_INTF(0x16d8, 0x6008, 0)},/* CMOTech CMU-301 */ -- 2.19.1
[PATCH AUTOSEL 4.19 33/97] USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
From: Hui Peng [ Upstream commit 5146f95df782b0ac61abde36567e718692725c89 ] The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data. Add a length check for both locations and updated hso_probe to bail on error. This issue has been assigned CVE-2018-19985. Reported-by: Hui Peng Reported-by: Mathias Payer Signed-off-by: Hui Peng Signed-off-by: Mathias Payer Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/hso.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 184c24baca15..d6916f787fce 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2807,6 +2807,12 @@ static int hso_get_config_data(struct usb_interface *interface) return -EIO; } + /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2877,10 +2883,18 @@ static int hso_probe(struct usb_interface *interface, /* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated +* array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + } /* Check if we need to switch to alt interfaces prior to port * configuration */ -- 2.19.1
[PATCH AUTOSEL 4.9 31/35] lan78xx: Resolve issue with changing MAC address
From: Jason Martinsen [ Upstream commit 1551569659c502003926a2067ee76176148a ] Current state for the lan78xx driver does not allow for changing the MAC address of the interface, without either removing the module (if you compiled it that way) or rebooting the machine. If you attempt to change the MAC address, ifconfig will show the new address, however, the system/interface will not respond to any traffic using that configuration. A few short-term options to work around this are to unload the module and reload it with the new MAC address, change the interface to "promisc", or reboot with the correct configuration to change the MAC. This patch enables the ability to change the MAC address via fairly normal means... ifdown modify entry in /etc/network/interfaces OR a similar method ifup Then test via any network communication, such as ICMP requests to gateway. My only test platform for this patch has been a raspberry pi model 3b+. Signed-off-by: Jason Martinsen - Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 6b4e38105b72..e143a7fe9320 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -2014,6 +2014,10 @@ static int lan78xx_set_mac_addr(struct net_device *netdev, void *p) ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + /* Added to support MAC address changes */ + ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + return 0; } -- 2.19.1
[PATCH AUTOSEL 4.4 17/21] lan78xx: Resolve issue with changing MAC address
From: Jason Martinsen [ Upstream commit 1551569659c502003926a2067ee76176148a ] Current state for the lan78xx driver does not allow for changing the MAC address of the interface, without either removing the module (if you compiled it that way) or rebooting the machine. If you attempt to change the MAC address, ifconfig will show the new address, however, the system/interface will not respond to any traffic using that configuration. A few short-term options to work around this are to unload the module and reload it with the new MAC address, change the interface to "promisc", or reboot with the correct configuration to change the MAC. This patch enables the ability to change the MAC address via fairly normal means... ifdown modify entry in /etc/network/interfaces OR a similar method ifup Then test via any network communication, such as ICMP requests to gateway. My only test platform for this patch has been a raspberry pi model 3b+. Signed-off-by: Jason Martinsen - Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/lan78xx.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 45a6a7cae4bf..59a7fa3420a6 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1679,6 +1679,10 @@ int lan78xx_set_mac_addr(struct net_device *netdev, void *p) ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + /* Added to support MAC address changes */ + ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + return 0; } -- 2.19.1
[PATCH AUTOSEL 4.4 08/21] USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
From: Hui Peng [ Upstream commit 5146f95df782b0ac61abde36567e718692725c89 ] The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data. Add a length check for both locations and updated hso_probe to bail on error. This issue has been assigned CVE-2018-19985. Reported-by: Hui Peng Reported-by: Mathias Payer Signed-off-by: Hui Peng Signed-off-by: Mathias Payer Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/hso.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 111d907e0c11..79cede19e0c4 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2825,6 +2825,12 @@ static int hso_get_config_data(struct usb_interface *interface) return -EIO; } + /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2895,10 +2901,18 @@ static int hso_probe(struct usb_interface *interface, /* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated +* array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + } /* Check if we need to switch to alt interfaces prior to port * configuration */ -- 2.19.1
[PATCH AUTOSEL 4.9 11/35] USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
From: Hui Peng [ Upstream commit 5146f95df782b0ac61abde36567e718692725c89 ] The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data. Add a length check for both locations and updated hso_probe to bail on error. This issue has been assigned CVE-2018-19985. Reported-by: Hui Peng Reported-by: Mathias Payer Signed-off-by: Hui Peng Signed-off-by: Mathias Payer Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/hso.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index e7b516342678..66ae647b712e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2808,6 +2808,12 @@ static int hso_get_config_data(struct usb_interface *interface) return -EIO; } + /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2878,10 +2884,18 @@ static int hso_probe(struct usb_interface *interface, /* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated +* array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + } /* Check if we need to switch to alt interfaces prior to port * configuration */ -- 2.19.1
[PATCH AUTOSEL 3.18 05/12] USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data
From: Hui Peng [ Upstream commit 5146f95df782b0ac61abde36567e718692725c89 ] The function hso_probe reads if_num from the USB device (as an u8) and uses it without a length check to index an array, resulting in an OOB memory read in hso_probe or hso_get_config_data. Add a length check for both locations and updated hso_probe to bail on error. This issue has been assigned CVE-2018-19985. Reported-by: Hui Peng Reported-by: Mathias Payer Signed-off-by: Hui Peng Signed-off-by: Mathias Payer Reviewed-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- drivers/net/usb/hso.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index babda7d8693e..f040bf558430 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2814,6 +2814,12 @@ static int hso_get_config_data(struct usb_interface *interface) return -EIO; } + /* check if we have a valid interface */ + if (if_num > 16) { + kfree(config_data); + return -EINVAL; + } + switch (config_data[if_num]) { case 0x0: result = 0; @@ -2884,10 +2890,18 @@ static int hso_probe(struct usb_interface *interface, /* Get the interface/port specification from either driver_info or from * the device itself */ - if (id->driver_info) + if (id->driver_info) { + /* if_num is controlled by the device, driver_info is a 0 terminated +* array. Make sure, the access is in bounds! */ + for (i = 0; i <= if_num; ++i) + if (((u32 *)(id->driver_info))[i] == 0) + goto exit; port_spec = ((u32 *)(id->driver_info))[if_num]; - else + } else { port_spec = hso_get_config_data(interface); + if (port_spec < 0) + goto exit; + } /* Check if we need to switch to alt interfaces prior to port * configuration */ -- 2.19.1
RE: [PATCH v2] usb: chipidea: add a check for the availability of next child
> Signed-off-by: Kangjie Lu > --- > drivers/usb/chipidea/ci_hdrc_msm.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c > b/drivers/usb/chipidea/ci_hdrc_msm.c > index 880009987460..b7f7acef72d4 100644 > --- a/drivers/usb/chipidea/ci_hdrc_msm.c > +++ b/drivers/usb/chipidea/ci_hdrc_msm.c > @@ -250,6 +250,10 @@ static int ci_hdrc_msm_probe(struct platform_device > *pdev) > ulpi_node = of_get_child_by_name(pdev->dev.of_node, "ulpi"); > if (ulpi_node) { > phy_node = of_get_next_available_child(ulpi_node, NULL); > + if (!phy_node) { > + dev_err(&pdev->dev, "no child nodes found\n"); > + return -ENODEV; > + } There are still two issues for this patch: - It can't return -ENODEV directly, instead, it needs to goto err_mux - Before goto err_mux, it needs to call of_node_put(ulpi_node); Besides, for kernel code style, you may leave one blank line after if () {} statement. Peter > ci->hsic = of_device_is_compatible(phy_node, > "qcom,usb-hsic-phy"); > of_node_put(phy_node); > } > -- > 2.17.2 (Apple Git-113)
SHANWAN pad rumbling not working on USB
Rumbling function on SHANWAN DS3 clone joystick doesn't work. Meanwhile it can work fine on Windows ScpToolkit v1.7.277.16103-BETA. (Tested with PCSX2 lilypad Win32 build). SDL2/test/testhaptic was able to find out its supported effect. But NO rumble at all. INFO: 1 Haptic devices detected. INFO: Device: SHANWAN PS3 GamePad INFO:Supported effects [16 effects, 16 playing]: INFO: sine INFO: triangle INFO: left/right INFO:Supported capabilities: INFO: gain INFO: Uploading effects INFO:effect 0: Sine Wave INFO:effect 1: Left/Right INFO: Now playing effects for 5 seconds each with 1 second delay between INFO:Playing effect 0 INFO:Playing effect 1 lsusb: Bus 001 Device 017: ID 054c:0268 Sony Corp. Batoh Device / PlayStation 3 Controller lsusb -v: Bus 001 Device 017: ID 054c:0268 Sony Corp. Batoh Device / PlayStation 3 Controller Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize064 idVendor 0x054c Sony Corp. idProduct 0x0268 Batoh Device / PlayStation 3 Controller bcdDevice1.00 iManufacturer 1 SHANWAN iProduct2 PS3 GamePad iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0029 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType33 bcdHID 1.10 bCountryCode0 Not supported bNumDescriptors 1 bDescriptorType34 Report wDescriptorLength 148 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes3 Transfer TypeInterrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Status: 0x0004 (Bus Powered) Test Mode
Re: SHANWAN pad rumbling not working on USB
uname: Linux archlinux 4.19.12-arch1-1-ARCH #1 SMP PREEMPT Fri Dec 21 13:56:54 UTC 2018 x86_64 GNU/Linux liquid 于2018年12月27日周四 上午9:17写道: > > Rumbling function on SHANWAN DS3 clone joystick doesn't work. > Meanwhile it can work fine on Windows ScpToolkit v1.7.277.16103-BETA. > (Tested with PCSX2 lilypad Win32 build). > > SDL2/test/testhaptic was able to find out its supported effect. But NO > rumble at all. > INFO: 1 Haptic devices detected. > INFO: Device: SHANWAN PS3 GamePad > INFO:Supported effects [16 effects, 16 playing]: > INFO: sine > INFO: triangle > INFO: left/right > INFO:Supported capabilities: > INFO: gain > INFO: > Uploading effects > INFO:effect 0: Sine Wave > INFO:effect 1: Left/Right > INFO: > Now playing effects for 5 seconds each with 1 second delay between > INFO:Playing effect 0 > INFO:Playing effect 1 > > lsusb: > Bus 001 Device 017: ID 054c:0268 Sony Corp. Batoh Device / PlayStation > 3 Controller > > lsusb -v: > Bus 001 Device 017: ID 054c:0268 Sony Corp. Batoh Device / PlayStation > 3 Controller > Device Descriptor: > bLength18 > bDescriptorType 1 > bcdUSB 1.10 > bDeviceClass0 > bDeviceSubClass 0 > bDeviceProtocol 0 > bMaxPacketSize064 > idVendor 0x054c Sony Corp. > idProduct 0x0268 Batoh Device / PlayStation 3 Controller > bcdDevice1.00 > iManufacturer 1 SHANWAN > iProduct2 PS3 GamePad > iSerial 0 > bNumConfigurations 1 > Configuration Descriptor: > bLength 9 > bDescriptorType 2 > wTotalLength 0x0029 > bNumInterfaces 1 > bConfigurationValue 1 > iConfiguration 0 > bmAttributes 0x80 > (Bus Powered) > MaxPower 500mA > Interface Descriptor: > bLength 9 > bDescriptorType 4 > bInterfaceNumber0 > bAlternateSetting 0 > bNumEndpoints 2 > bInterfaceClass 3 Human Interface Device > bInterfaceSubClass 0 > bInterfaceProtocol 0 > iInterface 0 > HID Device Descriptor: > bLength 9 > bDescriptorType33 > bcdHID 1.10 > bCountryCode0 Not supported > bNumDescriptors 1 > bDescriptorType34 Report > wDescriptorLength 148 > Report Descriptors: >** UNAVAILABLE ** > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x02 EP 2 OUT > bmAttributes3 > Transfer TypeInterrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x0040 1x 64 bytes > bInterval 1 > Endpoint Descriptor: > bLength 7 > bDescriptorType 5 > bEndpointAddress 0x81 EP 1 IN > bmAttributes3 > Transfer TypeInterrupt > Synch Type None > Usage Type Data > wMaxPacketSize 0x0040 1x 64 bytes > bInterval 1 > Device Status: 0x0004 > (Bus Powered) > Test Mode
[PATCH 4/4] usb: musb: Add support for MediaTek musb controller
From: Min Guo This adds support for MediaTek musb controller in host, peripheral and otg mode Signed-off-by: Min Guo Signed-off-by: Yonglong Wu --- drivers/usb/musb/Kconfig | 8 +- drivers/usb/musb/Makefile| 1 + drivers/usb/musb/mediatek.c | 562 +++ drivers/usb/musb/musb_core.c | 10 + drivers/usb/musb/musb_core.h | 1 + drivers/usb/musb/musb_dma.h | 1 + drivers/usb/musb/musb_host.c | 79 -- drivers/usb/musb/musb_regs.h | 6 + drivers/usb/musb/musbhsdma.c | 34 ++- 9 files changed, 671 insertions(+), 31 deletions(-) create mode 100644 drivers/usb/musb/mediatek.c diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ad08895..540fc9f 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -115,6 +115,12 @@ config USB_MUSB_JZ4740 depends on USB_MUSB_GADGET depends on USB_OTG_BLACKLIST_HUB +config USB_MUSB_MEDIATEK + tristate "MediaTek platforms" + depends on ARCH_MEDIATEK + depends on NOP_USB_XCEIV + depends on GENERIC_PHY + config USB_MUSB_AM335X_CHILD tristate @@ -141,7 +147,7 @@ config USB_UX500_DMA config USB_INVENTRA_DMA bool 'Inventra' - depends on USB_MUSB_OMAP2PLUS + depends on USB_MUSB_OMAP2PLUS || USB_MUSB_MEDIATEK help Enable DMA transfers using Mentor's engine. diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index 3a88c79..63d82d0 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_UX500) += ux500.o obj-$(CONFIG_USB_MUSB_JZ4740) += jz4740.o obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o +obj-$(CONFIG_USB_MUSB_MEDIATEK)+= mediatek.o obj-$(CONFIG_USB_MUSB_AM335X_CHILD)+= musb_am335x.o diff --git a/drivers/usb/musb/mediatek.c b/drivers/usb/musb/mediatek.c new file mode 100644 index 000..15a6460 --- /dev/null +++ b/drivers/usb/musb/mediatek.c @@ -0,0 +1,562 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 MediaTek Inc. + * + * Author: + * Min Guo + * Yonglong Wu + */ + +#include +#include +#include +#include +#include +#include "musb_core.h" +#include "musb_dma.h" + +#define USB_L1INTS 0x00a0 +#define USB_L1INTM 0x00a4 +#define MTK_MUSB_TXFUNCADDR0x0480 + +#define TX_INT_STATUS BIT(0) +#define RX_INT_STATUS BIT(1) +#define USBCOM_INT_STATUS BIT(2) +#define DMA_INT_STATUS BIT(3) + +#define DMA_INTR_STATUS_MSKGENMASK(7, 0) +#define DMA_INTR_UNMASK_SET_MSKGENMASK(31, 24) + +enum mtk_vbus_id_state { + MTK_ID_FLOAT = 1, + MTK_ID_GROUND, + MTK_VBUS_OFF, + MTK_VBUS_VALID, +}; + +struct mtk_glue { + struct device *dev; + struct musb *musb; + struct platform_device *musb_pdev; + struct platform_device *usb_phy; + struct phy *phy; + struct usb_phy *xceiv; + enum phy_mode phy_mode; + struct clk *main; + struct clk *mcu; + struct clk *univpll; + struct regulator *vbus; + struct extcon_dev *edev; + struct notifier_block vbus_nb; + struct notifier_block id_nb; +}; + +static int mtk_musb_clks_get(struct mtk_glue *glue) +{ + struct device *dev = glue->dev; + + glue->main = devm_clk_get(dev, "main"); + if (IS_ERR(glue->main)) { + dev_err(dev, "fail to get main clock\n"); + return PTR_ERR(glue->main); + } + + glue->mcu = devm_clk_get(dev, "mcu"); + if (IS_ERR(glue->mcu)) { + dev_err(dev, "fail to get mcu clock\n"); + return PTR_ERR(glue->mcu); + } + + glue->univpll = devm_clk_get(dev, "univpll"); + if (IS_ERR(glue->univpll)) { + dev_err(dev, "fail to get univpll clock\n"); + return PTR_ERR(glue->univpll); + } + + return 0; +} + +static int mtk_musb_clks_enable(struct mtk_glue *glue) +{ + int ret; + + ret = clk_prepare_enable(glue->main); + if (ret) { + dev_err(glue->dev, "failed to enable main clock\n"); + goto err_main_clk; + } + + ret = clk_prepare_enable(glue->mcu); + if (ret) { + dev_err(glue->dev, "failed to enable mcu clock\n"); + goto err_mcu_clk; + } + + ret = clk_prepare_enable(glue->univpll); + if (ret) { + dev_err(glue->dev, "failed to enable univpll clock\n"); + goto err_univpll_clk; + } + + return 0; + +err_univpll_clk: + clk_disable_unprepare(glue->mcu); +err_mcu_clk: + clk_disable_unprepare(glue->main); +err_main_clk: + return ret; +} + +static void mtk_musb_clks_disable(struct mtk_glue *glue) +{ + clk_disable_unprepare(glue->univpll); + clk_disable_unprepare(glue->m
[PATCH 1/4] dt-bindings: usb: musb: Add support for MediaTek musb controller
From: Min Guo This adds support for MediaTek musb controller in host, peripheral and otg mode Signed-off-by: Min Guo --- .../devicetree/bindings/usb/mediatek,musb.txt | 49 ++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/mediatek,musb.txt diff --git a/Documentation/devicetree/bindings/usb/mediatek,musb.txt b/Documentation/devicetree/bindings/usb/mediatek,musb.txt new file mode 100644 index 000..e899c9b --- /dev/null +++ b/Documentation/devicetree/bindings/usb/mediatek,musb.txt @@ -0,0 +1,49 @@ +MediaTek musb DRC/OTG controller +--- + +Required properties: + - compatible : should be "mediatek,-musb", + "mediatek,mtk-musb", soc-model is the name of SoC, such as + mt2701, when using "mediatek,mtk-musb" compatible string, you + need SoC specific ones in addition, one of: + - "mediatek,mt2701-musb" + - reg : specifies physical base address and size of + the registers + - interrupts : interrupt used by musb controller + - interrupt-names : must be "mc" + - phys: PHY specifier for the OTG phy + - phy-names : should be "usb2-phy" + - dr_mode : should be one of "host", "peripheral" or "otg", + refer to usb/generic.txt + - clocks : a list of phandle + clock-specifier pairs, one for + each entry in clock-names + - clock-names : must contain "main","mcu","univpll" + for clocks of controller + +Optional properties: + - extcon : external connector for VBUS and IDPIN changes detection, + needed when supports dual-role mode. + - vbus-supply : reference to the VBUS regulator, needed when supports + dual-role mode. + - power-domains : a phandle to USB power domain node to control USB's + MTCMOS + +Example: + +usb2: usb@1120 { + compatible = "mediatek,mt2701-musb"; + "mediatek,mtk-musb"; + reg = <0 0x1120 0 0x1000>; + interrupts = ; + interrupt-names = "mc"; + phys = <&u2port2 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + vbus-supply = <&usb_vbus>; + extcon = <&extcon_usb>; + dr_mode = "otg"; + clocks = <&pericfg CLK_PERI_USB0>, +<&pericfg CLK_PERI_USB0_MCU>, +<&pericfg CLK_PERI_USB_SLV>; + clock-names = "main","mcu","univpll"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; +}; -- 1.9.1
[PATCH 2/4] arm: dts: mt2701: Add usb2 device nodes
From: Min Guo Add musb nodes and usb2 phy nodes for MT2701 Signed-off-by: Min Guo --- arch/arm/boot/dts/mt2701-evb.dts | 21 + arch/arm/boot/dts/mt2701.dtsi| 34 ++ 2 files changed, 55 insertions(+) diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts index be0edb3..2635911 100644 --- a/arch/arm/boot/dts/mt2701-evb.dts +++ b/arch/arm/boot/dts/mt2701-evb.dts @@ -6,6 +6,7 @@ */ /dts-v1/; +#include #include "mt2701.dtsi" / { @@ -60,6 +61,20 @@ >; default-brightness-level = <9>; }; + + extcon_usb: extcon_iddig { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pio 44 GPIO_ACTIVE_HIGH>; + }; + + usb_vbus: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "usb_vbus"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + gpio = <&pio 45 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; }; &auxadc { @@ -229,3 +244,9 @@ &uart0 { status = "okay"; }; + +&usb2 { + vbus-supply = <&usb_vbus>; + extcon = <&extcon_usb>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index 180377e..495ece9 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -670,6 +670,40 @@ }; }; + usb2: usb@1120 { + compatible = "mediatek,mt2701-musb", + "mediatek,mtk-musb"; + reg = <0 0x1120 0 0x1000>; + interrupts = ; + interrupt-names = "mc"; + phys = <&u2port2 PHY_TYPE_USB2>; + phy-names = "usb2-phy"; + dr_mode = "otg"; + clocks = <&pericfg CLK_PERI_USB0>, +<&pericfg CLK_PERI_USB0_MCU>, +<&pericfg CLK_PERI_USB_SLV>; + clock-names = "main","mcu","univpll"; + power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; + status = "disabled"; + }; + + u2phy0: usb-phy@1121 { + compatible = "mediatek,generic-tphy-v1"; + reg = <0 0x1121 0 0x0800>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + status = "okay"; + + u2port2: usb-phy@1a1c4800 { + reg = <0 0x11210800 0 0x0100>; + clocks = <&topckgen CLK_TOP_USB_PHY48M>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; + ethsys: syscon@1b00 { compatible = "mediatek,mt2701-ethsys", "syscon"; reg = <0 0x1b00 0 0x1000>; -- 1.9.1
[PATCH 0/4] Add MediaTek MUSB Controller Driver
From: Min Guo These patches introduce the MediaTek MUSB controller driver. The driver can be configured as Dual-Role Device (DRD), Peripheral Only and Host Only modes. This has beed tested on MT2701 with a variety of devices in host mode and with the f_mass gadget driver in peripheral mode, plugging otg cables in/out a lot of times in all possible imaginable plug orders Min Guo (4): dt-bindings: usb: musb: Add support for MediaTek musb controller arm: dts: mt2701: Add usb2 device nodes usb: musb: Move musbhsdma macro definition to musb_dma.h usb: musb: Add support for MediaTek musb controller .../devicetree/bindings/usb/mediatek,musb.txt | 49 ++ arch/arm/boot/dts/mt2701-evb.dts | 21 + arch/arm/boot/dts/mt2701.dtsi | 34 ++ drivers/usb/musb/Kconfig | 8 +- drivers/usb/musb/Makefile | 1 + drivers/usb/musb/mediatek.c| 562 + drivers/usb/musb/musb_core.c | 10 + drivers/usb/musb/musb_core.h | 1 + drivers/usb/musb/musb_dma.h| 7 + drivers/usb/musb/musb_host.c | 79 ++- drivers/usb/musb/musb_regs.h | 6 + drivers/usb/musb/musbhsdma.c | 41 +- 12 files changed, 782 insertions(+), 37 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/mediatek,musb.txt create mode 100644 drivers/usb/musb/mediatek.c -- 1.9.1
[PATCH 3/4] usb: musb: Move musbhsdma macro definition to musb_dma.h
From: Min Guo Because the MediaTek musb controller dose not have a separate DMA interrupt, these macros are required to access the dma registers Signed-off-by: Min Guo --- drivers/usb/musb/musb_dma.h | 6 ++ drivers/usb/musb/musbhsdma.c | 7 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 8f60271..281e75d3 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h @@ -35,6 +35,12 @@ *whether shared with the Inventra core or separate. */ +#define MUSB_HSDMA_BASE0x200 +#define MUSB_HSDMA_INTR(MUSB_HSDMA_BASE + 0) +#define MUSB_HSDMA_CONTROL 0x4 +#define MUSB_HSDMA_ADDRESS 0x8 +#define MUSB_HSDMA_COUNT 0xc + #defineDMA_ADDR_INVALID(~(dma_addr_t)0) #ifdef CONFIG_MUSB_PIO_ONLY diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index a688f7f..824adcb 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -10,12 +10,7 @@ #include #include #include "musb_core.h" - -#define MUSB_HSDMA_BASE0x200 -#define MUSB_HSDMA_INTR(MUSB_HSDMA_BASE + 0) -#define MUSB_HSDMA_CONTROL 0x4 -#define MUSB_HSDMA_ADDRESS 0x8 -#define MUSB_HSDMA_COUNT 0xc +#include "musb_dma.h" #define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \ (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset) -- 1.9.1