[PATCH 06/11] usb: mtu3: rebuild qmu_gpd struct to prepare to support new QMU format
To support USB3 Gen2 ISOC, the data buffer length need be extended, it's hard to make the current qmu_gpd struct compatible, so here rebuild qmu_gpd struct and make easy to support new QMU format Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3.h | 45 +++-- drivers/usb/mtu3/mtu3_qmu.c | 56 + 2 files changed, 42 insertions(+), 59 deletions(-) diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index e3143f81b6a0..4dda7ed6e24e 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -144,45 +144,32 @@ struct mtu3_fifo_info { * The format of TX GPD is a little different from RX one. * And the size of GPD is 16 bytes. * - * @flag: + * @dw0_info: * bit0: Hardware Own (HWO) * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1 * bit7: Interrupt On Completion (IOC) - * @chksum: This is used to validate the contents of this GPD; - * If TXQ_CS_EN / RXQ_CS_EN bit is set, an interrupt is issued - * when checksum validation fails; - * Checksum value is calculated over the 16 bytes of the GPD by default; - * @data_buf_len (RX ONLY): This value indicates the length of - * the assigned data buffer - * @tx_ext_addr (TX ONLY): [3:0] are 4 extension bits of @buffer, - * [7:4] are 4 extension bits of @next_gpd + * bit[31:16]: allow data buffer length (RX ONLY), + * the buffer length of the data to receive + * bit[23:16]: extension address (TX ONLY), + * lower 4 bits are extension bits of @buffer, + * upper 4 bits are extension bits of @next_gpd * @next_gpd: Physical address of the next GPD * @buffer: Physical address of the data buffer - * @buf_len: - * (TX): This value indicates the length of the assigned data buffer - * (RX): The total length of data received - * @ext_len: reserved - * @rx_ext_addr(RX ONLY): [3:0] are 4 extension bits of @buffer, - * [7:4] are 4 extension bits of @next_gpd - * @ext_flag: - * bit5 (TX ONLY): Zero Length Packet (ZLP), + * @dw3_info: + * bit[15:0]: data buffer length, + * (TX): the buffer length of the data to transmit + * (RX): The total length of data received + * bit[23:16]: extension address (RX ONLY), + * lower 4 bits are extension bits of @buffer, + * upper 4 bits are extension bits of @next_gpd + * bit29: Zero Length Packet (ZLP) (TX ONLY) */ struct qmu_gpd { - __u8 flag; - __u8 chksum; - union { - __le16 data_buf_len; - __le16 tx_ext_addr; - }; + __le32 dw0_info; __le32 next_gpd; __le32 buffer; - __le16 buf_len; - union { - __u8 ext_len; - __u8 rx_ext_addr; - }; - __u8 ext_flag; + __le32 dw3_info; } __packed; /** diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c index f4b5431264c1..7a1919fc9f9e 100644 --- a/drivers/usb/mtu3/mtu3_qmu.c +++ b/drivers/usb/mtu3/mtu3_qmu.c @@ -29,10 +29,13 @@ #define GPD_FLAGS_BDP BIT(1) #define GPD_FLAGS_BPS BIT(2) #define GPD_FLAGS_IOC BIT(7) +#define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO) -#define GPD_EXT_FLAG_ZLP BIT(5) -#define GPD_EXT_NGP(x) (((x) & 0xf) << 4) -#define GPD_EXT_BUF(x) (((x) & 0xf) << 0) +#define GPD_RX_BUF_LEN(x) (((x) & 0x) << 16) +#define GPD_DATA_LEN(x)((x) & 0x) +#define GPD_EXT_FLAG_ZLP BIT(29) +#define GPD_EXT_NGP(x) (((x) & 0xf) << 20) +#define GPD_EXT_BUF(x) (((x) & 0xf) << 16) #define HILO_GEN64(hi, lo) (((u64)(hi) << 32) + (lo)) #define HILO_DMA(hi, lo) \ @@ -125,7 +128,7 @@ static void reset_gpd_list(struct mtu3_ep *mep) struct qmu_gpd *gpd = ring->start; if (gpd) { - gpd->flag &= ~GPD_FLAGS_HWO; + gpd->dw0_info &= cpu_to_le32(~GPD_FLAGS_HWO); gpd_ring_init(ring, gpd); } } @@ -215,15 +218,12 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) struct qmu_gpd *gpd = ring->enqueue; struct usb_request *req = &mreq->request; dma_addr_t enq_dma; - u16 ext_addr; - - /* set all fields to zero as default value */ - memset(gpd, 0, sizeof(*gpd)); + u32 ext_addr; + gpd->dw0_info = 0; /* SW own it */ gpd->buffer = cpu_to_le32(lower_32_bits(req->dma)); ext_addr = GPD_EXT_BUF(upper_32_bits(req->dma)); - gpd->buf_len = cpu_to_le16(req->length); - gpd->flag |= GPD_FLAGS_IOC; + gpd->dw3_info = cpu_to_le32(GPD_DATA_LEN(req->length)); /* get the next GPD */ enq = advance_enq_gpd(ring); @@ -231,15 +231,15 @@ static int mtu3_prepare_tx_gpd(struct mtu3_ep *mep, struct mtu3_request *mreq) dev_dbg(mep->mtu-
[PATCH 11/11] usb: mtu3: add a function to switch mailbox state to string
By introducing mailbox_state_string(), allow to make debug log more readable Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_dr.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 82913120622b..5fcb71af875a 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -21,6 +21,22 @@ enum mtu3_vbus_id_state { MTU3_VBUS_VALID, }; +static char *mailbox_state_string(enum mtu3_vbus_id_state state) +{ + switch (state) { + case MTU3_ID_FLOAT: + return "ID_FLOAT"; + case MTU3_ID_GROUND: + return "ID_GROUND"; + case MTU3_VBUS_OFF: + return "VBUS_OFF"; + case MTU3_VBUS_VALID: + return "VBUS_VALID"; + default: + return "UNKNOWN"; + } +} + static void toggle_opstate(struct ssusb_mtk *ssusb) { if (!ssusb->otg_switch.is_u3_drd) { @@ -140,8 +156,8 @@ static void ssusb_set_mailbox(struct otg_switch_mtk *otg_sx, container_of(otg_sx, struct ssusb_mtk, otg_switch); struct mtu3 *mtu = ssusb->u3d; - dev_dbg(ssusb->dev, "mailbox state(%d)\n", status); - mtu3_dbg_trace(ssusb->dev, "mailbox %d", status); + dev_dbg(ssusb->dev, "mailbox %s\n", mailbox_state_string(status)); + mtu3_dbg_trace(ssusb->dev, "mailbox %s", mailbox_state_string(status)); switch (status) { case MTU3_ID_GROUND: -- 2.20.1
[PATCH 03/11] usb: mtu3: remove unnecessary local variable @req
The local variable @req is unnecessary in qmu_tx_zlp_error_handler, so remove it. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_qmu.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c index 09f19f70fe8f..f4b5431264c1 100644 --- a/drivers/usb/mtu3/mtu3_qmu.c +++ b/drivers/usb/mtu3/mtu3_qmu.c @@ -382,16 +382,13 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum) struct mtu3_gpd_ring *ring = &mep->gpd_ring; void __iomem *mbase = mtu->mac_base; struct qmu_gpd *gpd_current = NULL; - struct usb_request *req = NULL; struct mtu3_request *mreq; dma_addr_t cur_gpd_dma; u32 txcsr = 0; int ret; mreq = next_request(mep); - if (mreq && mreq->request.length == 0) - req = &mreq->request; - else + if (mreq && mreq->request.length != 0) return; cur_gpd_dma = read_txq_cur_addr(mbase, epnum); @@ -402,7 +399,7 @@ static void qmu_tx_zlp_error_handler(struct mtu3 *mtu, u8 epnum) return; } - dev_dbg(mtu->dev, "%s send ZLP for req=%p\n", __func__, req); + dev_dbg(mtu->dev, "%s send ZLP for req=%p\n", __func__, mreq); mtu3_clrbits(mbase, MU3D_EP_TXCR0(mep->epnum), TX_DMAREQEN); -- 2.20.1
[PATCH 05/11] usb: mtu3: fix transfer error of USB3 Gen2 isoc
To support USB3 Gen2 ISOC, the registers of TXCSR1 and RXCSR1 are adjusted to support greater maxpkt and mult value, this patch fix this issue Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3.h | 11 ++ drivers/usb/mtu3/mtu3_core.c| 14 +++-- drivers/usb/mtu3/mtu3_hw_regs.h | 36 + 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 87823ac0d120..e3143f81b6a0 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -62,6 +62,15 @@ struct mtu3_request; #define MTU3_U3_IP_SLOT_DEFAULT 2 #define MTU3_U2_IP_SLOT_DEFAULT 1 +/** + * IP TRUNK version + * from 0x1003 version, USB3 Gen2 is supported, two changes affect driver: + * 1. MAXPKT and MULTI bits layout of TXCSR1 and RXCSR1 are adjusted, + *but not backward compatible + * 2. QMU extend buffer length supported + */ +#define MTU3_TRUNK_VERS_1003 0x1003 + /** * Normally the device works on HS or SS, to simplify fifo management, * devide fifo into some 512B parts, use bitmap to manage it; And @@ -316,6 +325,7 @@ static inline struct ssusb_mtk *dev_to_ssusb(struct device *dev) * @may_wakeup: means device's remote wakeup is enabled * @is_self_powered: is reported in device status and the config descriptor * @delayed_status: true when function drivers ask for delayed status + * @gen2cp: compatible with USB3 Gen2 IP * @ep0_req: dummy request used while handling standard USB requests * for GET_STATUS and SET_SEL * @setup_buf: ep0 response buffer for GET_STATUS and SET_SEL requests @@ -356,6 +366,7 @@ struct mtu3 { unsigned u2_enable:1; unsigned is_u3_ip:1; unsigned delayed_status:1; + unsigned gen2cp:1; u8 address; u8 test_mode_nr; diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index 4fee200795a5..ef27c2052ad6 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -299,6 +299,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep, int interval, int burst, int mult) { void __iomem *mbase = mtu->mac_base; + bool gen2cp = mtu->gen2cp; int epnum = mep->epnum; u32 csr0, csr1, csr2; int fifo_sgsz, fifo_addr; @@ -319,7 +320,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep, num_pkts = (burst + 1) * (mult + 1) - 1; csr1 = TX_SS_BURST(burst) | TX_SLOT(mep->slot); - csr1 |= TX_MAX_PKT(num_pkts) | TX_MULT(mult); + csr1 |= TX_MAX_PKT(gen2cp, num_pkts) | TX_MULT(gen2cp, mult); csr2 = TX_FIFOADDR(fifo_addr >> 4); csr2 |= TX_FIFOSEGSIZE(fifo_sgsz); @@ -355,7 +356,7 @@ int mtu3_config_ep(struct mtu3 *mtu, struct mtu3_ep *mep, num_pkts = (burst + 1) * (mult + 1) - 1; csr1 = RX_SS_BURST(burst) | RX_SLOT(mep->slot); - csr1 |= RX_MAX_PKT(num_pkts) | RX_MULT(mult); + csr1 |= RX_MAX_PKT(gen2cp, num_pkts) | RX_MULT(gen2cp, mult); csr2 = RX_FIFOADDR(fifo_addr >> 4); csr2 |= RX_FIFOSEGSIZE(fifo_sgsz); @@ -749,13 +750,14 @@ static irqreturn_t mtu3_irq(int irq, void *data) static int mtu3_hw_init(struct mtu3 *mtu) { - u32 cap_dev; + u32 value; int ret; - mtu->hw_version = mtu3_readl(mtu->ippc_base, U3D_SSUSB_HW_ID); + value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS); + mtu->hw_version = IP_TRUNK_VERS(value); - cap_dev = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP); - mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(cap_dev); + value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP); + mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value); dev_info(mtu->dev, "IP version 0x%x(%s IP)\n", mtu->hw_version, mtu->is_u3_ip ? "U3" : "U2"); diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h index 1d65b7476f23..fae3b8de1092 100644 --- a/drivers/usb/mtu3/mtu3_hw_regs.h +++ b/drivers/usb/mtu3/mtu3_hw_regs.h @@ -133,11 +133,23 @@ #define TX_W1C_BITS(~(TX_SENTSTALL)) /* U3D_TX1CSR1 */ -#define TX_MULT(x) (((x) & 0x3) << 22) -#define TX_MAX_PKT(x) (((x) & 0x3f) << 16) +#define TX_MAX_PKT_G2(x) (((x) & 0x7f) << 24) +#define TX_MULT_G2(x) (((x) & 0x7) << 21) +#define TX_MULT_OG(x) (((x) & 0x3) << 22) +#define TX_MAX_PKT_OG(x) (((x) & 0x3f) << 16) #define TX_SLOT(x) (((x) & 0x3f) << 8) #define TX_TYPE(x) (((x) & 0x3) << 4) #define TX_SS_BURST(x) (((x) & 0xf) << 0) +#define TX_MULT(g2c, x)\ +({ \ + typeof(x) x_ = (x); \ + (g2c) ? TX_MULT_G2(x_) : TX_MULT_OG(x_);\ +}) +#define TX_MAX_PKT(g2c, x) \ +({ \ + typeof(x) x_ = (x);
[PATCH 01/11] usb: mtu3: check return value of devm_extcon_register_notifier()
Check the return value of devm_extcon_register_notifier() and add error handling. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_dr.c | 13 + drivers/usb/mtu3/mtu3_plat.c | 8 +++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index ac60e9c8564e..61694c40e101 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -238,14 +238,18 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) otg_sx->vbus_nb.notifier_call = ssusb_vbus_notifier; ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB, &otg_sx->vbus_nb); - if (ret < 0) + if (ret < 0) { dev_err(ssusb->dev, "failed to register notifier for USB\n"); + return ret; + } otg_sx->id_nb.notifier_call = ssusb_id_notifier; ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, &otg_sx->id_nb); - if (ret < 0) + if (ret < 0) { dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); + return ret; + } dev_dbg(ssusb->dev, "EXTCON_USB: %d, EXTCON_USB_HOST: %d\n", extcon_get_state(edev, EXTCON_USB), @@ -415,6 +419,7 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) { struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + int ret = 0; INIT_WORK(&otg_sx->id_work, ssusb_id_work); INIT_WORK(&otg_sx->vbus_work, ssusb_vbus_work); @@ -422,9 +427,9 @@ int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) if (otg_sx->manual_drd_enabled) ssusb_debugfs_init(ssusb); else - ssusb_extcon_register(otg_sx); + ret = ssusb_extcon_register(otg_sx); - return 0; + return ret; } void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index e086630e41a9..dee31d5eefe1 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -401,7 +401,11 @@ static int mtu3_probe(struct platform_device *pdev) goto gadget_exit; } - ssusb_otg_switch_init(ssusb); + ret = ssusb_otg_switch_init(ssusb); + if (ret) { + dev_err(dev, "failed to initialize switch\n"); + goto host_exit; + } break; default: dev_err(dev, "unsupported mode: %d\n", ssusb->dr_mode); @@ -411,6 +415,8 @@ static int mtu3_probe(struct platform_device *pdev) return 0; +host_exit: + ssusb_host_exit(ssusb); gadget_exit: ssusb_gadget_exit(ssusb); comm_exit: -- 2.20.1
[PATCH 04/11] usb: mtu3: rebuild the code of getting vbus regulator
Remove local variable @vbus and use @dev instead of @pdev->dev Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_plat.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index 3a4a80f15957..a326b1d6006a 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -228,7 +228,6 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) struct device_node *node = pdev->dev.of_node; struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; struct device *dev = &pdev->dev; - struct regulator *vbus; struct resource *res; int i; int ret; @@ -299,12 +298,11 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) of_property_read_u32(node, "mediatek,u3p-dis-msk", &ssusb->u3p_dis_msk); - vbus = devm_regulator_get(&pdev->dev, "vbus"); - if (IS_ERR(vbus)) { + otg_sx->vbus = devm_regulator_get(dev, "vbus"); + if (IS_ERR(otg_sx->vbus)) { dev_err(dev, "failed to get vbus\n"); - return PTR_ERR(vbus); + return PTR_ERR(otg_sx->vbus); } - otg_sx->vbus = vbus; if (ssusb->dr_mode == USB_DR_MODE_HOST) goto out; -- 2.20.1
[PATCH 00/11] add debugfs consumers, tracepoints and rebuild QMU
In order to help debug, this series add more debugfs consumers, introduce a few initial tracepoints; And support new features introduced by USB3 Gen2 ISOC: 1. TXCSR/RXCSR registers are adjusted to support greater MULT and MAX_PKT 2. QMU format is also improved last, some small problems are fixed. Chunfeng Yun (11): usb: mtu3: check return value of devm_extcon_register_notifier() usb: mtu3: print useful information also for device and host modes usb: mtu3: remove unnecessary local variable @req usb: mtu3: rebuild the code of getting vbus regulator usb: mtu3: fix transfer error of USB3 Gen2 isoc usb: mtu3: rebuild qmu_gpd struct to prepare to support new QMU format usb: mtu3: supports new QMU format usb: mtu3: add debugfs interface files usb: mtu3: move vbus and mode debugfs interfaces into mtu3_debugfs.c usb: mtu3: add tracepoints to help debug usb: mtu3: add a function to switch mailbox state to string drivers/usb/mtu3/Makefile | 11 + drivers/usb/mtu3/mtu3.h| 57 ++- drivers/usb/mtu3/mtu3_core.c | 27 +- drivers/usb/mtu3/mtu3_debug.h | 50 +++ drivers/usb/mtu3/mtu3_debugfs.c| 539 + drivers/usb/mtu3/mtu3_dr.c | 156 ++--- drivers/usb/mtu3/mtu3_dr.h | 4 + drivers/usb/mtu3/mtu3_gadget.c | 20 +- drivers/usb/mtu3/mtu3_gadget_ep0.c | 4 + drivers/usb/mtu3/mtu3_hw_regs.h| 48 ++- drivers/usb/mtu3/mtu3_plat.c | 28 +- drivers/usb/mtu3/mtu3_qmu.c| 118 --- drivers/usb/mtu3/mtu3_qmu.h| 1 + drivers/usb/mtu3/mtu3_trace.c | 23 ++ drivers/usb/mtu3/mtu3_trace.h | 279 +++ 15 files changed, 1146 insertions(+), 219 deletions(-) create mode 100644 drivers/usb/mtu3/mtu3_debug.h create mode 100644 drivers/usb/mtu3/mtu3_debugfs.c create mode 100644 drivers/usb/mtu3/mtu3_trace.c create mode 100644 drivers/usb/mtu3/mtu3_trace.h -- 2.20.1
Re: [PATCH 4/9] usb: gadget: udc: renesas_usb3: use extcon framework to receive connect/disconnect
On Wed, Mar 06, 2019 at 09:07:21AM +, Biju Das wrote: > RZ/G2E cat874 board is capable of detecting cable connect and disconnect > events. Add support for renesas_usb3 to receive connect and disconnect > notification using extcon framework. I think you will need the series from Yu Chen [1], but once we have that, you can do this with USB role class instead of relying on extcon, and that is what you need to do. There is a reason why we need to use a dedicated class with the USB role switching instead of relying on extcon. We actually originally planned on using extcon with the USB role switches, but the extcon maintainers refused some the USB mux drivers. The problem from extcon perspective is that the consumer/supplier roles seem to be inverted in some cases. USB role switch can simply be too many things - discrete mux, integrated mux (like in your case) or something like a dual role capable USB controller could simply represent one. On the other hand, using a dedicated API and class now feel like a much better idea in general compared to a multipurpose thing like extcon. [1] https://lkml.org/lkml/2019/3/2/42 thanks, -- heikki
Re: [PATCH 0/9] Add USB3.0 and TI HD3SS3220 driver support
On Wed, Mar 06, 2019 at 09:07:17AM +, Biju Das wrote: > This series adds USB 3.0 support for the CAT874 platform, including a > new driver for the TI HD3SS3220 USB Type-C DRP port controller. > > This patch series supports: > 1) Host hotplug operation > 2) Device hot plug operation > 3) USB type-C data_role switch >(Tested with 2 RZ/G2E boards connected with a Type-C cable) > > This patchset is based on usb_next and renesas-devel-20190304-v5.0 branch. > > Biju Das (9): > dt-bindings: usb: hd3ss3220 device tree binding document > dt-bindings: usb: renesas_usb3: add extcon support > usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller > usb: gadget: udc: renesas_usb3: use extcon framework to receive > connect/disconnect Hi Biju, I am marking the patches below as deffered pending acceptance of the dt-bindings patches above. > arm64: defconfig: enable TYPEC_HD3SS3220 config option > arm64: renesas_defconfig: Enable TYPEC_HD3SS3220 config option > arm64: dts: renesas: r8a774c0-cat874: enable USB3.0 host/peripheral > device node > arm64: dts: renesas: r8a774c0-cat874: Enable TI HD3SS3220 support > arm64: dts: renesas: r8a774c0-cat874: Enable extcon support > > .../devicetree/bindings/usb/renesas_usb3.txt | 2 + > .../devicetree/bindings/usb/ti,hd3ss3220.txt | 15 ++ > arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts| 31 +++ > arch/arm64/configs/defconfig | 2 + > arch/arm64/configs/renesas_defconfig | 2 + > drivers/usb/gadget/udc/renesas_usb3.c | 115 +++-- > drivers/usb/typec/Kconfig | 10 + > drivers/usb/typec/Makefile | 1 + > drivers/usb/typec/hd3ss3220.c | 284 > + > 9 files changed, 446 insertions(+), 16 deletions(-) > create mode 100644 Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt > create mode 100644 drivers/usb/typec/hd3ss3220.c > > -- > 2.7.4 >
Re: [PATCH 0/4] Add USB-HOST support to cat874
On Fri, Mar 01, 2019 at 11:05:44AM +, Fabrizio Castro wrote: > While trying to add USB-HOST support to the cat874 board, > it came up that of_usb_get_dr_mode_by_phy was selecting > the wrong DT node to use for dr_mode. > Also, drivers/phy/renesas/phy-rcar-gen3-usb2.c was registering > IRQs, no matter the dr_mode. > > This series adds all that is required to add USB-HOST support > to the cat874 board, and also removes the hsusb from Draak's DT > as not necessary anymore. > > Thanks, > Fab > > Fabrizio Castro (4): > usb: common: Consider only available nodes for dr_mode > phy: renesas: rcar-gen3-usb2: No need to request IRQ for non-OTG Hi Fabrizio, I am marking the patches below deferred pending acceptance of the patches above. > arm64: dts: renesas: r8a774c0-cat874: Add USB-HOST support > arm64: dts: renesas: r8a77995: draak: Remove hsusb node > > arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts | 15 ++ > arch/arm64/boot/dts/renesas/r8a77995-draak.dts | 5 - > drivers/phy/renesas/phy-rcar-gen3-usb2.c| 26 > - > drivers/usb/common/common.c | 2 ++ > 4 files changed, 30 insertions(+), 18 deletions(-) > > -- > 2.7.4 >
Re: [PATCH] usbip: Remove unnecessary null check
Hi Suwan, On 3/5/19 8:11 AM, Suwan Kim wrote: "vdev" points to vhci_hcd->vdev[] array and vhci_hcd->vdev[] array is not a pointer array but a structure array and it is already used in vhci_urb_enqueue() and then passed to vhci_tx_urb() as an argument. vhci_tx_urb() is not called except vhci_urb_enqueue(). So, "vdev" can not be null pointer. This null check statement is meaningless. Signed-off-by: Suwan Kim --- drivers/usb/usbip/vhci_hcd.c | 8 +--- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index f46ee1fefe02..667d9c0ec905 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -654,15 +654,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) { struct vhci_priv *priv; - struct vhci_hcd *vhci_hcd; + struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev); unsigned long flags; - if (!vdev) { - pr_err("could not get virtual device"); - return; - } - vhci_hcd = vdev_to_vhci_hcd(vdev); - priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); if (!priv) { usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); Thanks for the patch. Looks good to me. Acked-by: Shuah Khan thanks, -- Shuah
[PATCH] drivers: uwb: Kconfig: pedantic cleanups
Signed-off-by: Enrico Weigelt, metux IT consult --- drivers/uwb/Kconfig | 42 +- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig index afac258..d0e15e1 100644 --- a/drivers/uwb/Kconfig +++ b/drivers/uwb/Kconfig @@ -41,31 +41,31 @@ config UWB_HWA is safe to select any even if you do not have the hardware. config UWB_WHCI -tristate "UWB Radio Control driver for WHCI-compliant cards" -depends on PCI -help - This driver enables the radio controller for WHCI cards. + tristate "UWB Radio Control driver for WHCI-compliant cards" + depends on PCI + help + This driver enables the radio controller for WHCI cards. - WHCI is a specification developed by Intel - (http://www.intel.com/technology/comms/wusb/whci.htm) much - in the spirit of USB's EHCI, but for UWB and Wireless USB - radio/host controllers connected via memory mapping (eg: - PCI). Most of these cards come also with a Wireless USB host - controller. + WHCI is a specification developed by Intel + (http://www.intel.com/technology/comms/wusb/whci.htm) much + in the spirit of USB's EHCI, but for UWB and Wireless USB + radio/host controllers connected via memory mapping (eg: + PCI). Most of these cards come also with a Wireless USB host + controller. - To compile this driver select Y (built in) or M (module). It - is safe to select any even if you do not have the hardware. + To compile this driver select Y (built in) or M (module). It + is safe to select any even if you do not have the hardware. config UWB_I1480U -tristate "Support for Intel Wireless UWB Link 1480 HWA" -depends on UWB_HWA -select FW_LOADER -help - This driver enables support for the i1480 when connected via - USB. It consists of a firmware uploader that will enable it - to behave as an HWA device. + tristate "Support for Intel Wireless UWB Link 1480 HWA" + depends on UWB_HWA + select FW_LOADER + help + This driver enables support for the i1480 when connected via + USB. It consists of a firmware uploader that will enable it + to behave as an HWA device. - To compile this driver select Y (built in) or M (module). It - is safe to select any even if you do not have the hardware. + To compile this driver select Y (built in) or M (module). It + is safe to select any even if you do not have the hardware. endif # UWB -- 1.9.1
Re: [PATCH] drivers: uwb: Kconfig: pedantic cleanups
On Wed, Mar 06, 2019 at 07:51:46PM +0100, Enrico Weigelt, metux IT consult wrote: > Signed-off-by: Enrico Weigelt, metux IT consult > --- > drivers/uwb/Kconfig | 42 +- > 1 file changed, 21 insertions(+), 21 deletions(-) I do not take patches without any changelog comments. thanks, greg k-h
Re: [PATCH v2 5/8] phy: amlogic: add Amlogic G12A USB2 PHY Driver
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: [...] > +#include > +#include > +#include > +#include > +#include > +#include > +#include there's a "regmap" include right above. this driver doesn't use syscon so this include can be dropped [...] > +static int phy_meson_g12a_usb2_exit(struct phy *phy) > +{ > + struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); > + > + return reset_control_reset(priv->reset); do you know whether we should reset_control_assert here instead of reset_control_reset? the probe function below already uses reset_control_deassert, so the current implementation is inconsistent. in v1 you replied with "Maybe it would be better, indeed." - if there's a reason why reset_control_assert doesn't work here then I would like to have a comment stating why Apart from these two this is looking good! Human readable BIT/GENMASK #defines for the register bits would be nice, but I'm not sure if you have the details to add these. Regards Martin
Re: [PATCH v2 6/8] phy: amlogic: Add Amlogic G12A USB3 + PCIE Combo PHY Driver
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: [...] > +static int phy_g12a_usb3_init(struct phy *phy) > +{ > + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); > + int data, ret; > + > + /* Switch PHY to USB3 */ > + regmap_update_bits(priv->regmap, PHY_R0, > + PHY_R0_PCIE_USB3_SWITCH, > + PHY_R0_PCIE_USB3_SWITCH); does this automatically clear PHY_R0_PCIE_POWER_STATE (in case the bootloader incorrectly set that)? [...] > +static int phy_g12a_usb3_pcie_init(struct phy *phy) > +{ > + struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); > + int ret; > + > + ret = reset_control_reset(priv->reset); > + if (ret) > + return ret; > + > + if (priv->mode == PHY_TYPE_USB3) > + return phy_g12a_usb3_init(phy); > + > + /* Power UP PCIE */ > + regmap_update_bits(priv->regmap, PHY_R0, > + PHY_R0_PCIE_POWER_STATE, > + FIELD_PREP(PHY_R0_PCIE_POWER_STATE, 0x1c)); similar to my question above: does this automatically clear PHY_R0_PCIE_USB3_SWITCH (in case the bootloader incorrectly set that)? Apart from these two questions this looks good to me! Regards Martin
[PATCH] dt-bindings: usb: dwc2: document the vbus-supply property
Various boards have an external VBUS supply regulator. This regulator depends on the current mode of the controller which is defined as: - dr_mode set to either "host" or "peripheral" (fixed value) - dr_mode set to "otg", based on the OTG status the dwc2 controller internally switches between "host" and "peripheral" mode (selection happens at runtime) Based on the current mode the regulator has to be enabled or disabled: - host: provide power to the connected USB device, thus the regulator has to be enabled - peripheral: the host device to which the controller is connected provides power, thus the regulator has to be disabled Add the dt-bindings documentation for this property so .dts authors know that this property exists and how it behaves. Fixes: 531ef5ebea9639 ("usb: dwc2: add support for host mode external vbus supply") Signed-off-by: Martin Blumenstingl --- Documentation/devicetree/bindings/usb/dwc2.txt | 4 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index 6dc3c4a34483..1e8a775a0e72 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -31,6 +31,10 @@ Refer to clk/clock-bindings.txt for generic clock consumer properties Optional properties: - phys: phy provider specifier - phy-names: shall be "usb2-phy" +- vbus-supply: reference to the VBUS regulator. Depending on the current mode + this is enabled (in "host" mode") or disabled (in "peripheral" mode). The + regulator is updated if the controller is configured in "otg" mode and the + status changes between "host" and "peripheral". Refer to phy/phy-bindings.txt for generic phy consumer properties - dr_mode: shall be one of "host", "peripheral" and "otg" Refer to usb/generic.txt -- 2.21.0
Re: [PATCH v2 4/8] dt-bindings: usb: dwc3: Add Amlogic G12A DWC3 Glue Bindings
Hi Neil, On Mon, Mar 4, 2019 at 11:40 AM Neil Armstrong wrote: > > Adds the bindings for the Amlogic G12A USB Glue HW. > > The Amlogic G12A SoC Family embeds 2 USB Controllers : > - a DWC3 IP configured as Host for USB2 and USB3 > - a DWC2 IP configured as Peripheral USB2 Only > > A glue connects these both controllers to 2 USB2 PHYs, > and optionnally to an USB3+PCIE Combo PHY shared with the PCIE controller. > > The Glue configures the UTMI 8bit interfaces for the USB2 PHYs, including > routing of the OTG PHY between the DWC3 and DWC2 controllers, and > setups the on-chip OTG mode selection for this PHY. > > The PHYs phandles are passed to the Glue node since the Glue controls the > interface with the PHY, not the DWC3 controller. > > Signed-off-by: Neil Armstrong Reviewed-by: Martin Blumenstingl [...] > + dwc3: usb@ff50 { > + compatible = "snps,dwc3"; > + reg = <0x0 0xff50 0x0 0x10>; > + interrupts = ; > + dr_mode = "host"; > + snps,dis_u2_susphy_quirk; > + snps,quirk-frame-length-adjustment; > + }; in v1 of the patch I asked whether we should pass the PHYs which are connected to the dwc3 controller here as well (instead of only passing them to the USBCTRL node). we can still do this later on, the important part is: USBCTRL interfaces with the PHYs -> that is already part of the binding. Regards Martin
[PATCH v2] drivers: uwb: Kconfig: pedantic cleanups
Formatting of Kconfig files doesn't look so pretty, so just take damp cloth and clean it up. Signed-off-by: Enrico Weigelt, metux IT consult --- drivers/uwb/Kconfig | 42 +- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig index afac258..d0e15e1 100644 --- a/drivers/uwb/Kconfig +++ b/drivers/uwb/Kconfig @@ -41,31 +41,31 @@ config UWB_HWA is safe to select any even if you do not have the hardware. config UWB_WHCI -tristate "UWB Radio Control driver for WHCI-compliant cards" -depends on PCI -help - This driver enables the radio controller for WHCI cards. + tristate "UWB Radio Control driver for WHCI-compliant cards" + depends on PCI + help + This driver enables the radio controller for WHCI cards. - WHCI is a specification developed by Intel - (http://www.intel.com/technology/comms/wusb/whci.htm) much - in the spirit of USB's EHCI, but for UWB and Wireless USB - radio/host controllers connected via memory mapping (eg: - PCI). Most of these cards come also with a Wireless USB host - controller. + WHCI is a specification developed by Intel + (http://www.intel.com/technology/comms/wusb/whci.htm) much + in the spirit of USB's EHCI, but for UWB and Wireless USB + radio/host controllers connected via memory mapping (eg: + PCI). Most of these cards come also with a Wireless USB host + controller. - To compile this driver select Y (built in) or M (module). It - is safe to select any even if you do not have the hardware. + To compile this driver select Y (built in) or M (module). It + is safe to select any even if you do not have the hardware. config UWB_I1480U -tristate "Support for Intel Wireless UWB Link 1480 HWA" -depends on UWB_HWA -select FW_LOADER -help - This driver enables support for the i1480 when connected via - USB. It consists of a firmware uploader that will enable it - to behave as an HWA device. + tristate "Support for Intel Wireless UWB Link 1480 HWA" + depends on UWB_HWA + select FW_LOADER + help + This driver enables support for the i1480 when connected via + USB. It consists of a firmware uploader that will enable it + to behave as an HWA device. - To compile this driver select Y (built in) or M (module). It - is safe to select any even if you do not have the hardware. + To compile this driver select Y (built in) or M (module). It + is safe to select any even if you do not have the hardware. endif # UWB -- 1.9.1
[PATCH] tools: usb: usbip: adding support for older kernel versions
The current usbip tool relies on the behavior of the vhci-hcd driver in order to work correctly. In instances where a newer version of the tool is used with an older version of the kernel, there are incompatibilities that can sometimes result in failure. This patch adds some fallback capabilities so that the tool will work with the vhci-hcd driver from kernel version 3.18 onward. Signed-off-by: David Valleau --- tools/usb/usbip/libsrc/vhci_driver.c | 246 --- tools/usb/usbip/libsrc/vhci_driver.h | 7 + 2 files changed, 228 insertions(+), 25 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ed8c9d360c0f..4e02cf6832a6 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -37,7 +37,136 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) return NULL; } -static int parse_status(const char *value) +static void assign_idev(struct usbip_imported_device *idev, uint8_t port, + uint32_t status, uint32_t devid) +{ + idev->port = port; + idev->status= status; + idev->devid = devid; + idev->busnum= (devid >> 16); + idev->devnum= (devid & 0x); +} + +static int init_idev(struct usbip_imported_device *idev, const char *lbusid) +{ + if (idev->status != VDEV_ST_NULL && + idev->status != VDEV_ST_NOTASSIGNED) { + idev = imported_device_init(idev, lbusid); + if (!idev) { + dbg("imported_device_init failed"); + return -1; + } + } + return 0; +} + +static int parse_status_3_18(const char *value) +{ + int ret = 0; + char *c; + + /* skip a header line */ + c = strchr(value, '\n'); + if (!c) + return -1; + c++; + + while (*c != '\0') { + int port, status, speed, devid; + unsigned long socket; + char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; + + ret = sscanf(c, "%d %d %d %x %lx %31s\n", + &port, &status, &speed, + &devid, &socket, lbusid); + + if (ret < 5) { + dbg("sscanf failed: %d", ret); + return -1; + } + + dbg("port %d status %d speed %d devid %x", + port, status, speed, devid); + dbg("socket %lx lbusid %s", socket, lbusid); + + /* if a device is connected, look at it */ + idev = &vhci_driver->idev[port]; + memset(idev, 0, sizeof(*idev)); + + /* assume that the hub is high-speed */ + idev->hub = HUB_SPEED_HIGH; + assign_idev(idev, port, status, devid); + + if (init_idev(idev, lbusid)) + return -1; + + /* go to the next line */ + c = strchr(c, '\n'); + if (!c) + break; + c++; + } + + dbg("exit"); + + return 0; +} + +static int parse_status_4_4(const char *value) +{ + int ret = 0; + char *c; + + /* skip a header line */ + c = strchr(value, '\n'); + if (!c) + return -1; + c++; + + while (*c != '\0') { + int port, status, speed, devid; + int sockfd; + char lbusid[SYSFS_BUS_ID_SIZE]; + struct usbip_imported_device *idev; + + ret = sscanf(c, "%d %d %d %x %u %31s\n", + &port, &status, &speed, + &devid, &sockfd, lbusid); + + if (ret < 5) { + dbg("sscanf failed: %d", ret); + return -1; + } + + dbg("port %d status %d speed %d devid %x", + port, status, speed, devid); + dbg("sockfd %u lbusid %s", sockfd, lbusid); + + /* if a device is connected, look at it */ + idev = &vhci_driver->idev[port]; + memset(idev, 0, sizeof(*idev)); + + /* assume that the hub is high-speed */ + idev->hub = HUB_SPEED_HIGH; + assign_idev(idev, port, status, devid); + + if (init_idev(idev, lbusid)) + return -1; + + /* go to the next line */ + c = strchr(c, '\n'); + if (!c) + break; + c++; + } + + dbg("exit"); + + return 0; +} + +static int parse_status_4_14(const char *value) { int ret = 0; char *c; @@ -61,7 +190,7 @@ static int parse_status(const char *value) if (ret < 5) { dbg("sscanf
Re: [GIT PULL] USB/PHY driver patches for 5.1-rc1
The pull request you sent on Wed, 6 Mar 2019 11:35:31 +0100: > git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git tags/usb-5.1-rc1 has been merged into torvalds/linux.git: https://git.kernel.org/torvalds/c/f90d64483ebd394958841f67f8794ab203b319a7 Thank you! -- Deet-doot-dot, I am a bot. https://korg.wiki.kernel.org/userdoc/prtracker
Re: [PATCH v2 8/8] usb: dwc3: Add Amlogic G12A DWC3 glue
Hi, On Mon, 2019-03-04 at 11:38 +0100, Neil Armstrong wrote: > Adds support for Amlogic G12A USB Control Glue HW. > > The Amlogic G12A SoC Family embeds 2 USB Controllers : > - a DWC3 IP configured as Host for USB2 and USB3 > - a DWC2 IP configured as Peripheral USB2 Only > > A glue connects these both controllers to 2 USB2 PHYs, and optionnally > to an USB3+PCIE Combo PHY shared with the PCIE controller. > > The Glue configures the UTMI 8bit interfaces for the USB2 PHYs, including > routing of the OTG PHY between the DWC3 and DWC2 controllers, and > setups the on-chip OTG mode selection for this PHY. > > This drivers supports the on-probe setup of the OTG mode, and manually > via a debugfs interface. The IRQ mode change detect is yet to be added > in a future patchset, mainly due to lack of hardware to validate on. > > Signed-off-by: Neil Armstrong > --- > drivers/usb/dwc3/Kconfig | 10 + > drivers/usb/dwc3/Makefile | 1 + > drivers/usb/dwc3/dwc3-meson-g12a.c | 601 + > 3 files changed, 612 insertions(+) > create mode 100644 drivers/usb/dwc3/dwc3-meson-g12a.c > > diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig > index 1a0404fda596..21ce7368d325 100644 > --- a/drivers/usb/dwc3/Kconfig > +++ b/drivers/usb/dwc3/Kconfig > @@ -93,6 +93,16 @@ config USB_DWC3_KEYSTONE > Support of USB2/3 functionality in TI Keystone2 platforms. > Say 'Y' or 'M' here if you have one such device > > +config USB_DWC3_MESON_G12A > + tristate "Amlogic Meson G12A Platforms" > + depends on OF && COMMON_CLK > + depends on ARCH_MESON || COMPILE_TEST > + default USB_DWC3 > + select USB_ROLE_SWITCH > + help > + Support USB2/3 functionality in Amlogic G12A platforms. > + Say 'Y' or 'M' if you have one such device. > + > config USB_DWC3_OF_SIMPLE > tristate "Generic OF Simple Glue Layer" > depends on OF && COMMON_CLK > diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile > index 6e3ef6144e5d..ae86da0dc5bd 100644 > --- a/drivers/usb/dwc3/Makefile > +++ b/drivers/usb/dwc3/Makefile > @@ -47,6 +47,7 @@ obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o > obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o > obj-$(CONFIG_USB_DWC3_HAPS) += dwc3-haps.o > obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o > +obj-$(CONFIG_USB_DWC3_MESON_G12A)+= dwc3-meson-g12a.o > obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o > obj-$(CONFIG_USB_DWC3_ST)+= dwc3-st.o > obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o > diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c > b/drivers/usb/dwc3/dwc3-meson-g12a.c > new file mode 100644 > index ..75942614a034 > --- /dev/null > +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c > @@ -0,0 +1,601 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * USB Glue for Amlogic G12A SoCs > + * > + * Copyright (c) 2019 BayLibre, SAS > + * Author: Neil Armstrong > + */ > + > +/* > + * The USB is organized with a glue around the DWC3 Controller IP as : > + * - Control registers for each USB2 Ports > + * - Control registers for the USB PHY layer > + * - SuperSpeed PHY can be enabled only if port is used > + * > + * TOFIX: > + * - Add dynamic OTG switching with ID change interrupt > + */ > + [...] > + > +static int dwc3_meson_g12a_probe(struct platform_device *pdev) > +{ > + struct dwc3_meson_g12a *priv; > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > + void __iomem *base; > + struct resource *res; > + enum phy_mode otg_id; > + int ret, i; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + base = devm_ioremap_resource(dev, res); > + if (IS_ERR(base)) > + return PTR_ERR(base); > + > + priv->regmap = devm_regmap_init_mmio(dev, base, > + &phy_meson_g12a_usb3_regmap_conf); > + if (IS_ERR(priv->regmap)) > + return PTR_ERR(priv->regmap); > + > + priv->vbus = devm_regulator_get_optional(dev, "vbus"); > + if (IS_ERR(priv->vbus)) { > + if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) > + return PTR_ERR(priv->vbus); > + priv->vbus = NULL; > + } > + > + priv->clk = devm_clk_get(dev, NULL); > + if (IS_ERR(priv->clk)) > + return PTR_ERR(priv->clk); > + > + ret = clk_prepare_enable(priv->clk); > + if (ret) > + return ret; > + > + platform_set_drvdata(pdev, priv); > + priv->dev = dev; > + > + priv->reset = devm_reset_control_get(dev, NULL); > + if (IS_ERR(priv->reset)) { > + ret = PTR_ERR(priv->reset); > + dev_err(dev, "failed to get device reset, err=%d\n", ret); > + return ret; > + } >
RE: [PATCH v4 5/6] usb:cdns3 Add Cadence USB3 DRD Driver
Hi, >Pawel, > >On 14/02/2019 21:45, Pawel Laszczak wrote: >> This patch introduce new Cadence USBSS DRD driver to linux kernel. >> >> The Cadence USBSS DRD Driver is a highly configurable IP Core whichi >> can be instantiated as Dual-Role Device (DRD), Peripheral Only and >> Host Only (XHCI)configurations. >> >> The current driver has been validated with FPGA burned. We have support >> for PCIe bus, which is used on FPGA prototyping. >> >> The host side of USBSS-DRD controller is compliance with XHCI >> specification, so it works with standard XHCI linux driver. >> >> Signed-off-by: Pawel Laszczak >> --- >> drivers/usb/Kconfig|2 + >> drivers/usb/Makefile |2 + >> drivers/usb/cdns3/Kconfig | 44 + >> drivers/usb/cdns3/Makefile | 14 + >> drivers/usb/cdns3/cdns3-pci-wrap.c | 155 +++ >> drivers/usb/cdns3/core.c | 403 ++ >> drivers/usb/cdns3/core.h | 116 ++ >> drivers/usb/cdns3/debug.h | 168 +++ >> drivers/usb/cdns3/debugfs.c| 164 +++ >> drivers/usb/cdns3/drd.c| 365 + >> drivers/usb/cdns3/drd.h| 162 +++ >> drivers/usb/cdns3/ep0.c| 907 + >> drivers/usb/cdns3/gadget-export.h | 28 + >> drivers/usb/cdns3/gadget.c | 2003 >> drivers/usb/cdns3/gadget.h | 1207 + >> drivers/usb/cdns3/host-export.h| 28 + >> drivers/usb/cdns3/host.c | 72 + >> drivers/usb/cdns3/trace.c | 23 + >> drivers/usb/cdns3/trace.h | 404 ++ >> 19 files changed, 6267 insertions(+) >> create mode 100644 drivers/usb/cdns3/Kconfig >> create mode 100644 drivers/usb/cdns3/Makefile >> create mode 100644 drivers/usb/cdns3/cdns3-pci-wrap.c >> create mode 100644 drivers/usb/cdns3/core.c >> create mode 100644 drivers/usb/cdns3/core.h >> create mode 100644 drivers/usb/cdns3/debug.h >> create mode 100644 drivers/usb/cdns3/debugfs.c >> create mode 100644 drivers/usb/cdns3/drd.c >> create mode 100644 drivers/usb/cdns3/drd.h >> create mode 100644 drivers/usb/cdns3/ep0.c >> create mode 100644 drivers/usb/cdns3/gadget-export.h >> create mode 100644 drivers/usb/cdns3/gadget.c >> create mode 100644 drivers/usb/cdns3/gadget.h >> create mode 100644 drivers/usb/cdns3/host-export.h >> create mode 100644 drivers/usb/cdns3/host.c >> create mode 100644 drivers/usb/cdns3/trace.c >> create mode 100644 drivers/usb/cdns3/trace.h >> >> diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig >> index 987fc5ba6321..5f9334019d04 100644 >> --- a/drivers/usb/Kconfig >> +++ b/drivers/usb/Kconfig >> @@ -112,6 +112,8 @@ source "drivers/usb/usbip/Kconfig" >> >> endif >> >> +source "drivers/usb/cdns3/Kconfig" >> + >> source "drivers/usb/mtu3/Kconfig" >> >> source "drivers/usb/musb/Kconfig" >> diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile >> index 7d1b8c82b208..ab125b966cac 100644 >> --- a/drivers/usb/Makefile >> +++ b/drivers/usb/Makefile >> @@ -12,6 +12,8 @@ obj-$(CONFIG_USB_DWC3) += dwc3/ >> obj-$(CONFIG_USB_DWC2) += dwc2/ >> obj-$(CONFIG_USB_ISP1760) += isp1760/ >> >> +obj-$(CONFIG_USB_CDNS3) += cdns3/ >> + >> obj-$(CONFIG_USB_MON) += mon/ >> obj-$(CONFIG_USB_MTU3) += mtu3/ >> >> diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig >> new file mode 100644 >> index ..27cb3d8dbe3d >> --- /dev/null >> +++ b/drivers/usb/cdns3/Kconfig >> @@ -0,0 +1,44 @@ >> +config USB_CDNS3 >> +tristate "Cadence USB3 Dual-Role Controller" >> +depends on USB_SUPPORT && (USB || USB_GADGET) && HAS_DMA >> +help >> + Say Y here if your system has a cadence USB3 dual-role controller. >> + It supports: dual-role switch, Host-only, and Peripheral-only. >> + >> + If you choose to build this driver is a dynamically linked >> + as module, the module will be called cdns3.ko. >> + >> +if USB_CDNS3 >> + >> +config USB_CDNS3_GADGET >> +bool "Cadence USB3 device controller" >> +depends on USB_GADGET >> +help >> + Say Y here to enable device controller functionality of the >> + cadence USBSS-DEV driver. > >"Cadence" ? > >> + >> + This controller supports FF, HS and SS mode. It doesn't support >> + LS and SSP mode. >> + >> +config USB_CDNS3_HOST >> +bool "Cadence USB3 host controller" >> +depends on USB_XHCI_HCD >> +help >> + Say Y here to enable host controller functionality of the >> + cadence driver. >> + >> + Host controller is compliant with XHCI so it will use >> + standard XHCI driver. >> + >> +config USB_CDNS3_PCI_WRAP >> +tristate "Cadence USB3 support on PCIe-based platforms" >> +depends on USB_PCI && ACPI >> +default USB_CDNS3 >> +help >> + If you're using the USBSS Core IP with a PCIe, please say >> + 'Y' or 'M' here. >> + >> + If
RE: [PATCH v4 6/6] usb:cdns3 Fix for stuck packets in on-chip OUT buffer.
Hi, >Hi, > >On 21/02/2019 09:14, Felipe Balbi wrote: >> >> Hi, >> >> (please break your emails at 80-columns) >> >> Pawel Laszczak writes: > One more thing. Workaround has implemented algorithm that decide for which > endpoint it should be enabled. e.g for composite device MSC+NCM+ACM it > should work only for ACM OUT endpoint. > If ACM driver didn't queue the request for ACM OUT endpoint, why does the controller accept the data at all? I didn't understand why we need a workaround for this. It should be standard behaviour to NAK data if function driver didn't request for all endpoints. >>> >>> Yes, I agree with you. Controller shouldn’t accept such packet. As I know >>> this >>> behavior will be fixed in RTL. >>> >>> But I assume that some older version of this controller are one the market, >>> and driver should work correct with them. >>> >>> In the feature this workaround can be limited only to selected controllers. >>> >>> Even now I assume that it can be enabled/disabled by module parameter. >> >> no module parameters, please. Use revision detection in runtime. >> > >This is about whether to enable or disable the workaround. >By default we don't want this workaround to be enabled. > >I'm debating whether we should have this workaround at all or not. > >It has the following problems. > >1) It ACKs packets even when gadget end is not ready to accept the transfers. >2) It stores these packets in a temporary buffer and then pushes them to the >gadget driver whenever the gadget driver is ready to process the data. >3) Since the gadget driver can become ready at an indefinite time in the >future, it poses 2 problems: > a) It is sending stale data to the sink. (problematic at next protocol level?) > b) If this temporary buffer runs out we still hit the lock up issue. > >I think the right solution is to make sure that the gadget driver is always >reading all the enabled OUT endpoints *or* (keep the OUT endpoints disabled >if gadget driver is not ready to process OUT transfers). If driver disable endpoint then it not answer for packets from host. It will result that host reset the device, so I can't disable such endpoints. Other good solution is to change ACM driver in a way that it sends requests to controller driver after enabling endpoint. The class driver could decide what should do with such not expected packets. It could delete all or e.g keep only few last packets. This issue will be fixed in RTL but maybe driver should be compatible with previous controller’s version. By default, this workaround will be disabled or will depend on controller version. > >cheers, >-roger >-- >Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. >Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki Cheers, Pawel
Configuring host_addr and device_addr for u_ether
Hey, I'm trying to use a composite gadget on a embedded linux platform using configfs. The kernel-doc was fine and I can now create my gadgets as needed. One big drawback is that the host_addr and dev_addr change on every start. So I tried to change them, without success: * Most web documentation applies only to g_ether (eg setting module/kernel parameters) * ${CONFIGFS}/usb_gadget/g1/functions/rndis.0/host_addr reports EBUSY if I try to write it * I checked the sources of my kernel (4.19) and the current ones to check if I can somehow add a MAC to the dtb of my system: It seems that there is no such binding. Can sb point me the right way to show me what I need to do (or in what order I have to create the entries in the configfs) to manually set MAC addresses? Best regards, Olli
Re: Configuring host_addr and device_addr for u_ether
Hi, (please break your lines at 80-columns) "Westermann, Oliver" writes: > Hey, > > I'm trying to use a composite gadget on a embedded linux platform > using configfs. The kernel-doc was fine and I can now create my > gadgets as needed. One big drawback is that the host_addr and dev_addr > change on every start. > > So I tried to change them, without success: > > * Most web documentation applies only to g_ether (eg setting > module/kernel parameters) > > * ${CONFIGFS}/usb_gadget/g1/functions/rndis.0/host_addr reports EBUSY > if I try to write it because the gadget is already configured. > * I checked the sources of my kernel (4.19) and the current ones to > check if I can somehow add a MAC to the dtb of my system: It seems > that there is no such binding. you can write host_addr and dev_addr via configufs, but according to code, you have to do it before adding the functions to the gadget. This, to me, seems a bit odd. Does this patch help the situation in any way? diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 6ce044008cf6..31279aaf3f3b 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -530,14 +530,19 @@ static int ecm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_ecm*ecm = func_to_ecm(f); + struct f_ecm_opts *ecm_opts; struct usb_composite_dev *cdev = f->config->cdev; + ecm_opts = container_of(f->fi, struct f_ecm_opts, func_inst); + /* Control interface has only altsetting 0 */ if (intf == ecm->ctrl_id) { if (alt != 0) goto fail; VDBG(cdev, "reset ecm control %d\n", intf); + + ecm_opts->running = false; usb_ep_disable(ecm->notify); if (!(ecm->notify->desc)) { VDBG(cdev, "init ecm ctrl %d\n", intf); @@ -545,6 +550,7 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; } usb_ep_enable(ecm->notify); + ecm_opts->running = true; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ecm->data_id) { @@ -553,6 +559,7 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (ecm->port.in_ep->enabled) { DBG(cdev, "reset ecm\n"); + ecm_opts->running = false; gether_disconnect(&ecm->port); } @@ -585,6 +592,7 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) net = gether_connect(&ecm->port); if (IS_ERR(net)) return PTR_ERR(net); + ecm_opts->running = true; } /* NOTE this can be a minor disagreement with the ECM spec, diff --git a/drivers/usb/gadget/function/u_ecm.h b/drivers/usb/gadget/function/u_ecm.h index 050aa672ee7f..752258dd1c3e 100644 --- a/drivers/usb/gadget/function/u_ecm.h +++ b/drivers/usb/gadget/function/u_ecm.h @@ -19,6 +19,7 @@ struct f_ecm_opts { struct usb_function_instancefunc_inst; struct net_device *net; boolbound; + boolrunning; /* * Read/write access to configfs attributes is handled by configfs. diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index cd33cee4d78b..7fe0a7fa4e7a 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -46,7 +46,7 @@ int ret;\ \ mutex_lock(&opts->lock);\ - if (opts->refcnt) { \ + if (opts->running) {\ mutex_unlock(&opts->lock); \ return -EBUSY; \ } \ @@ -81,7 +81,7 @@ int ret;\ \ mutex_lock(&opts->lock);\ - if (opts->refcnt) { \ + if (opts->running) {\ mutex_unlock(&opts->lock); \ return -EBUSY;
[PATCH 3/9] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller
Driver for TI HD3SS3220 USB Type-C DRP port controller. The driver currently registers the port and supports data role swapping. Signed-off-by: Biju Das --- drivers/usb/typec/Kconfig | 10 ++ drivers/usb/typec/Makefile| 1 + drivers/usb/typec/hd3ss3220.c | 284 ++ 3 files changed, 295 insertions(+) create mode 100644 drivers/usb/typec/hd3ss3220.c diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig index 30a847c..91696d2 100644 --- a/drivers/usb/typec/Kconfig +++ b/drivers/usb/typec/Kconfig @@ -49,6 +49,16 @@ source "drivers/usb/typec/tcpm/Kconfig" source "drivers/usb/typec/ucsi/Kconfig" +config TYPEC_HD3SS3220 + tristate "TI HD3SS3220 Type-C DRP Port controller driver" + depends on I2C + help + Say Y or M here if your system has TI HD3SS3220 Type-C DRP Port + controller driver. + + If you choose to build this driver as a dynamically linked module, the + module will be called hd3ss3220.ko. + config TYPEC_TPS6598X tristate "TI TPS6598x USB Power Delivery controller driver" depends on I2C diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 6696b72..7753a5c3 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -4,5 +4,6 @@ typec-y := class.o mux.o bus.o obj-$(CONFIG_TYPEC)+= altmodes/ obj-$(CONFIG_TYPEC_TCPM) += tcpm/ obj-$(CONFIG_TYPEC_UCSI) += ucsi/ +obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o obj-$(CONFIG_TYPEC_TPS6598X) += tps6598x.o obj-$(CONFIG_TYPEC)+= mux/ diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c new file mode 100644 index 000..bd3e1ec --- /dev/null +++ b/drivers/usb/typec/hd3ss3220.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * TI HD3SS3220 Type-C DRP Port Controller Driver + * + * Copyright (C) 2019 Renesas Electronics Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HD3SS3220_REG_CN_STAT_CTRL 0x09 +#define HD3SS3220_REG_GEN_CTRL 0x0A +#define HD3SS3220_REG_DEV_REV 0xA0 + +/* Register HD3SS3220_REG_CN_STAT_CTRL*/ +#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | BIT(6)) +#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFP BIT(6) +#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFP BIT(7) +#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY(BIT(7) | BIT(6)) +#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUS BIT(4) + +/* Register HD3SS3220_REG_GEN_CTRL*/ +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1)) +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT0x00 +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNKBIT(1) +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC(BIT(2) | BIT(1)) + +struct hd3ss3220 { + struct device *dev; + struct regmap *regmap; + struct extcon_dev *extcon; + struct typec_port *port; + struct typec_capability typec_cap; +}; + +static const unsigned int hd3ss3220_cable[] = { + EXTCON_USB, + EXTCON_USB_HOST, + EXTCON_NONE +}; + +static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int src_pref) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, ®_val); + if (ret < 0) + return ret; + + reg_val &= ~HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK; + reg_val |= src_pref; + + return regmap_write(hd3ss3220->regmap, + HD3SS3220_REG_GEN_CTRL, reg_val); +} + +static int hd3ss3220_attached_state_detect(struct hd3ss3220 *hd3ss3220) +{ + unsigned int reg_val; + int ret, attached_state; + + ret = regmap_read(hd3ss3220->regmap, + HD3SS3220_REG_CN_STAT_CTRL, ®_val); + if (ret < 0) + return ret; + + reg_val &= HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK; + switch (reg_val) { + case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP: + attached_state = EXTCON_USB_HOST; + break; + case HD3SS3220_REG_CN_STAT_CTRL_AS_UFP: + attached_state = EXTCON_USB; + break; + default: + attached_state = EXTCON_NONE; + } + + return attached_state; +} + +static int hd3ss3220_dr_set(const struct typec_capability *cap, + enum typec_data_role role) +{ + struct hd3ss3220 *hd3ss3220 = + container_of(cap, struct hd3ss3220, typec_cap); + int ret = 0; + + if (role == TYPEC_HOST) { + extcon_set_state_sync(hd3ss3220->extcon, EXTCON_USB, false); + ret = hd3ss3220_set_source_pref(hd3ss3220, + HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC); +
[PATCH 2/9] dt-bindings: usb: renesas_usb3: add extcon support
Add support for renesas_usb3 to receive connect and disconnect notification using extcon framework. Signed-off-by: Biju Das --- Documentation/devicetree/bindings/usb/renesas_usb3.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/usb/renesas_usb3.txt b/Documentation/devicetree/bindings/usb/renesas_usb3.txt index d366555..ae35674 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usb3.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usb3.txt @@ -21,6 +21,8 @@ Required properties: Optional properties: - phys: phandle + phy specifier pair - phy-names: must be "usb" + - extcon: phandle for the extcon device renesas usb3 uses to detect + connect/disconnect events. Example of R-Car H3 ES1.x: usb3_peri0: usb@ee02 { -- 2.7.4
[PATCH 4/9] usb: gadget: udc: renesas_usb3: use extcon framework to receive connect/disconnect
RZ/G2E cat874 board is capable of detecting cable connect and disconnect events. Add support for renesas_usb3 to receive connect and disconnect notification using extcon framework. Signed-off-by: Biju Das --- drivers/usb/gadget/udc/renesas_usb3.c | 115 +- 1 file changed, 99 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 7dc2485..2c69d5d 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -351,6 +351,11 @@ struct renesas_usb3 { int disabled_count; struct usb_request *ep0_req; + + struct extcon_dev *edev; + struct notifier_block ufp_nb; + struct notifier_block dfp_nb; + u16 test_mode; u8 ep0_buf[USB3_EP0_BUF_SIZE]; bool softconnect; @@ -644,22 +649,6 @@ static void usb3_disconnect(struct renesas_usb3 *usb3) usb3->driver->disconnect(&usb3->gadget); } -static void usb3_check_vbus(struct renesas_usb3 *usb3) -{ - if (usb3->workaround_for_vbus) { - usb3_connect(usb3); - } else { - usb3->extcon_usb = !!(usb3_read(usb3, USB3_USB_STA) & - USB_STA_VBUS_STA); - if (usb3->extcon_usb) - usb3_connect(usb3); - else - usb3_disconnect(usb3); - - schedule_work(&usb3->extcon_work); - } -} - static void renesas_usb3_role_work(struct work_struct *work) { struct renesas_usb3 *usb3 = @@ -724,6 +713,32 @@ static void usb3_check_id(struct renesas_usb3 *usb3) schedule_work(&usb3->extcon_work); } +static void usb3_check_vbus(struct renesas_usb3 *usb3) +{ + if (usb3->workaround_for_vbus) { + if (usb3->edev) { + if (extcon_get_state(usb3->edev, EXTCON_USB) == true) { + usb3->forced_b_device = true; + usb3->start_to_connect = true; + usb3_disconnect(usb3); + usb3_check_id(usb3); + } else if (extcon_get_state(usb3->edev, + EXTCON_USB_HOST) == false) + usb3_vbus_out(usb3, false); + } else + usb3_connect(usb3); + } else { + usb3->extcon_usb = !!(usb3_read(usb3, USB3_USB_STA) & + USB_STA_VBUS_STA); + if (usb3->extcon_usb) + usb3_connect(usb3); + else + usb3_disconnect(usb3); + + schedule_work(&usb3->extcon_work); + } +} + static void renesas_usb3_init_controller(struct renesas_usb3 *usb3) { usb3_init_axi_bridge(usb3); @@ -2656,6 +2671,47 @@ static const struct usb_role_switch_desc renesas_usb3_role_switch_desc = { .allow_userspace_control = true, }; +static int renesas_usb3_ufp_notifier(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct renesas_usb3 *usb3 = container_of(nb, + struct renesas_usb3, ufp_nb); + + usb3->start_to_connect = false; + if (event && usb3->driver) { + usb3->forced_b_device = true; + usb3->start_to_connect = true; + } + + if (usb3->driver) { + usb3_disconnect(usb3); + usb3_check_id(usb3); + } + + usb3_vbus_out(usb3, false); + dev_dbg(usb3_to_dev(usb3), "ufp_notifier event=%ld", event); + + return NOTIFY_DONE; +} + +static int renesas_usb3_dfp_notifier(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct renesas_usb3 *usb3 = container_of(nb, + struct renesas_usb3, dfp_nb); + + if (event) { + usb3->forced_b_device = false; + usb3_disconnect(usb3); + usb3_check_id(usb3); + } else + usb3_vbus_out(usb3, false); + + dev_dbg(usb3_to_dev(usb3), "dfp_notifier event=%ld", event); + + return NOTIFY_DONE; +} + static int renesas_usb3_probe(struct platform_device *pdev) { struct renesas_usb3 *usb3; @@ -2703,6 +2759,33 @@ static int renesas_usb3_probe(struct platform_device *pdev) return ret; INIT_WORK(&usb3->extcon_work, renesas_usb3_extcon_work); + + if (priv->workaround_for_vbus && + of_property_read_bool(pdev->dev.of_node, "extcon")) { + usb3->edev = extcon_get_edev_by_phandle(&pdev->dev, 0); + if (IS_ERR(usb3->edev)) + return PTR_ERR(usb3->edev); + + usb3->ufp_nb.notifier_call = renesas_usb3_ufp_notifie
[PATCH 1/9] dt-bindings: usb: hd3ss3220 device tree binding document
Add device tree binding document for TI HD3SS3220 Type-C DRP port controller driver. Signed-off-by: Biju Das --- Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt | 15 +++ 1 file changed, 15 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt diff --git a/Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt new file mode 100644 index 000..1fcf6f6 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt @@ -0,0 +1,15 @@ +TI HD3SS3220 TypeC DRP Port Controller. + +Required properties: + - compatible: Must be "ti,hd3ss3220". + - reg: I2C slave address, must be 0x47 or 0x67 based on ADDR pin. + - interrupts: where a is the interrupt number and b represents an + encoding of the sense and level information for the interrupt. + +Example: +hd3ss3220@47 { + compatible = "ti,hd3ss3220"; + reg = <0x47>; + interrupt-parent = <&gpio6>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; +}; -- 2.7.4
[PATCH 5/9] arm64: defconfig: enable TYPEC_HD3SS3220 config option
Enable support for the TI HD3SS320 USB Type-C DRP Port controller driver by turning on CONFIG_TYPEC and CONFIG_TYPEC_HD3SS3220 as modules. Signed-off-by: Biju Das --- arch/arm64/configs/defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index b263b14..40a085a 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -544,6 +544,8 @@ CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_USB_RENESAS_USB3=m +CONFIG_TYPEC=m +CONFIG_TYPEC_HD3SS3220=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y -- 2.7.4
[PATCH 0/9] Add USB3.0 and TI HD3SS3220 driver support
This series adds USB 3.0 support for the CAT874 platform, including a new driver for the TI HD3SS3220 USB Type-C DRP port controller. This patch series supports: 1) Host hotplug operation 2) Device hot plug operation 3) USB type-C data_role switch (Tested with 2 RZ/G2E boards connected with a Type-C cable) This patchset is based on usb_next and renesas-devel-20190304-v5.0 branch. Biju Das (9): dt-bindings: usb: hd3ss3220 device tree binding document dt-bindings: usb: renesas_usb3: add extcon support usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller usb: gadget: udc: renesas_usb3: use extcon framework to receive connect/disconnect arm64: defconfig: enable TYPEC_HD3SS3220 config option arm64: renesas_defconfig: Enable TYPEC_HD3SS3220 config option arm64: dts: renesas: r8a774c0-cat874: enable USB3.0 host/peripheral device node arm64: dts: renesas: r8a774c0-cat874: Enable TI HD3SS3220 support arm64: dts: renesas: r8a774c0-cat874: Enable extcon support .../devicetree/bindings/usb/renesas_usb3.txt | 2 + .../devicetree/bindings/usb/ti,hd3ss3220.txt | 15 ++ arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts| 31 +++ arch/arm64/configs/defconfig | 2 + arch/arm64/configs/renesas_defconfig | 2 + drivers/usb/gadget/udc/renesas_usb3.c | 115 +++-- drivers/usb/typec/Kconfig | 10 + drivers/usb/typec/Makefile | 1 + drivers/usb/typec/hd3ss3220.c | 284 + 9 files changed, 446 insertions(+), 16 deletions(-) create mode 100644 Documentation/devicetree/bindings/usb/ti,hd3ss3220.txt create mode 100644 drivers/usb/typec/hd3ss3220.c -- 2.7.4
[GIT PULL] USB/PHY driver patches for 5.1-rc1
The following changes since commit d13937116f1e82bf508a6325111b322c30c85eb9: Linux 5.0-rc6 (2019-02-10 14:42:20 -0800) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git tags/usb-5.1-rc1 for you to fetch changes up to 1c7cf3d5e1c181caca75012b65252288c18a25f2: wusb: Remove unnecessary static function ckhdid_printf (2019-03-01 20:53:41 +0100) USB/PHY patches for 5.1-rc1 Here is the big USB/PHY driver pull request for 5.1-rc1. The usual set of gadget driver updates, phy driver updates (you will have a merge issue with Kconfig and Makefile), xhci updates, and typec additions. Also included in here are a lot of small cleanups and fixes and driver updates where needed. All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman Abel Vesa (1): phy: freescale: Break dependency on SOC_IMX8MQ for USB PHY Alan Stern (1): USB: gadget: Improve kerneldoc for usb_ep_dequeue() Andrzej Pietrasiewicz (4): usb: dwc2: gadget: Add scatter-gather mode usb: gadget: move non-super speed code out of usb_ep_autoconfig_ss() usb: gadget: f_fs: preserve wMaxPacketSize across usb_ep_autoconfig() call usb: gadget: Change Andrzej Pietrasiewicz's e-mail address Andy Shevchenko (1): usb: dwc3: drd: Defer probe if extcon device is not found Balaji Manoharan (1): usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on INTEL_SUNRISEPOINT_LP_XHCI Bharath Vedartham (1): USB: storage: karma: add whitespace after declarations Christoph Hellwig (2): fotg210-udc: remove a bogus dma_sync_single_for_device call fotg210-udc: pass struct device to DMA API functions Chunfeng Yun (2): usb: devio: update max count of DPs per interval for ISOC usb: xhci: remove unused member 'parent' in xhci_regset struct Colin Ian King (6): usb: host: u132-hcd: fix a couple of indentation issues usb: gadget: fix various indentation issues USB: musb: fix indentation issue on a return statement usb: host: oxu210hp-hcd: fix indentation issue USB: renesas_usbhs: fix spelling mistake "doens't" -> "doesn't" usb: typec: mux: remove redundant check on variable match Daniele Palmas (1): USB: serial: option: add Telit ME910 ECM composition Dmitry Osipenko (1): usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() Dmitry Torokhov (1): usb: core: add option of only authorizing internal devices Enric Balletbo i Serra (3): phy: rockchip-inno-usb2: fix misspelling and kernel-doc documentation dt-bindings: phy-rockchip-inno-usb2: add documentation for extcon property phy: phy-rockchip-inno-usb2: drop reading the utmi-avalid property Fabrizio Castro (4): usb: gadget: udc: renesas_usb3: Add bindings for r8a774c0 dt-bindings: usb: renesas_usbhs: Add r8a774c0 support usb: gadget: udc: renesas_usb3: add support for r8a774c0 dt-bindings: rcar-gen3-phy-usb2: Add r8a774c0 support Felipe Balbi (10): usb: dwc3: gadget: add dwc3_request status tracking usb: dwc3: gadget: prevent dwc3_request from being queued twice usb: dwc3: gadget: remove req->started flag usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete usb: dwc3: gadget: don't use resource_index as a flag usb: dwc3: gadget: early giveback if End Transfer already completed usb: dwc3: gadget: remove DWC3_EP_END_TRANSFER_PENDING usb: dwc3: trace: pass trace buffer size to decoding functions usb: dwc3: debug: purge usage of strcat usb: dwc3: gadget: don't enable interrupt when disabling endpoint Greg Kroah-Hartman (10): Merge 5.0-rc2 into usb-next USB: add missing SPDX lines to Kconfig and Makefiles USB: remove README file USB: host: whci: rename Kbuild file Merge 5.0-rc4 into usb-next Merge 5.0-rc6 into usb-next Merge tag 'phy-for-5.1' of git://git.kernel.org/.../kishon/linux-phy into usb-next Merge tag 'usb-for-v5.1' of git://git.kernel.org/.../balbi/usb into usb-next Merge tag 'usb-serial-5.1-rc1' of https://git.kernel.org/.../johan/usb-serial into usb-next Merge tag 'usb-serial-5.1-rc1-2' of https://git.kernel.org/.../johan/usb-serial into usb-next Gregory CLEMENT (1): phy: armada375-usb2: switch to SPDX license identifier Guenter Roeck (1): usb: typec: tcpm: Remove unused functions Guido Kiener (1): udc: net2280: Fix net2280_disable Gustavo A. R. Silva (7): USB: core: urb: Use struct_size() in kmalloc() xhci: Use struct_size() in kzalloc() uwb: use struct_size() in kzalloc() USB: musb: mark expected switch fall-through usb: dwc2: use struct_size() in kzalloc() usb: core: config: Use struct_size() in kzalloc() usb
Re: [PATCH 3/9] usb: typec: driver for TI HD3SS3220 USB Type-C DRP port controller
Hi Biju, On Wed, Mar 06, 2019 at 09:07:20AM +, Biju Das wrote: > Driver for TI HD3SS3220 USB Type-C DRP port controller. > > The driver currently registers the port and supports data role swapping. > > Signed-off-by: Biju Das > --- > drivers/usb/typec/Kconfig | 10 ++ > drivers/usb/typec/Makefile| 1 + > drivers/usb/typec/hd3ss3220.c | 284 > ++ > 3 files changed, 295 insertions(+) > create mode 100644 drivers/usb/typec/hd3ss3220.c > > diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig > index 30a847c..91696d2 100644 > --- a/drivers/usb/typec/Kconfig > +++ b/drivers/usb/typec/Kconfig > @@ -49,6 +49,16 @@ source "drivers/usb/typec/tcpm/Kconfig" > > source "drivers/usb/typec/ucsi/Kconfig" > > +config TYPEC_HD3SS3220 > + tristate "TI HD3SS3220 Type-C DRP Port controller driver" > + depends on I2C > + help > + Say Y or M here if your system has TI HD3SS3220 Type-C DRP Port > + controller driver. > + > + If you choose to build this driver as a dynamically linked module, the > + module will be called hd3ss3220.ko. > + > config TYPEC_TPS6598X > tristate "TI TPS6598x USB Power Delivery controller driver" > depends on I2C > diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile > index 6696b72..7753a5c3 100644 > --- a/drivers/usb/typec/Makefile > +++ b/drivers/usb/typec/Makefile > @@ -4,5 +4,6 @@ typec-y := class.o mux.o bus.o > obj-$(CONFIG_TYPEC) += altmodes/ > obj-$(CONFIG_TYPEC_TCPM) += tcpm/ > obj-$(CONFIG_TYPEC_UCSI) += ucsi/ > +obj-$(CONFIG_TYPEC_HD3SS3220)+= hd3ss3220.o > obj-$(CONFIG_TYPEC_TPS6598X) += tps6598x.o > obj-$(CONFIG_TYPEC) += mux/ > diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c > new file mode 100644 > index 000..bd3e1ec > --- /dev/null > +++ b/drivers/usb/typec/hd3ss3220.c > @@ -0,0 +1,284 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * TI HD3SS3220 Type-C DRP Port Controller Driver > + * > + * Copyright (C) 2019 Renesas Electronics Corp. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define HD3SS3220_REG_CN_STAT_CTRL 0x09 > +#define HD3SS3220_REG_GEN_CTRL 0x0A > +#define HD3SS3220_REG_DEV_REV0xA0 > + > +/* Register HD3SS3220_REG_CN_STAT_CTRL*/ > +#define HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK (BIT(7) | > BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_DFPBIT(6) > +#define HD3SS3220_REG_CN_STAT_CTRL_AS_UFPBIT(7) > +#define HD3SS3220_REG_CN_STAT_CTRL_TO_ACCESSORY (BIT(7) | > BIT(6)) > +#define HD3SS3220_REG_CN_STAT_CTRL_INT_STATUSBIT(4) > + > +/* Register HD3SS3220_REG_GEN_CTRL*/ > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK (BIT(2) | BIT(1)) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_DEFAULT 0x00 > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SNK BIT(1) > +#define HD3SS3220_REG_GEN_CTRL_SRC_PREF_DRP_TRY_SRC (BIT(2) | BIT(1)) > + > +struct hd3ss3220 { > + struct device *dev; > + struct regmap *regmap; > + struct extcon_dev *extcon; > + struct typec_port *port; > + struct typec_capability typec_cap; > +}; > + > +static const unsigned int hd3ss3220_cable[] = { > + EXTCON_USB, > + EXTCON_USB_HOST, > + EXTCON_NONE > +}; You need to use the USB role class instead of extcon. Check drivers/usb/roles/class/ and include/linux/usb/role.h You may also want to check the updates Yu Chen is introducing to that class: https://lkml.org/lkml/2019/3/2/42 > +static int hd3ss3220_set_source_pref(struct hd3ss3220 *hd3ss3220, int > src_pref) > +{ > + unsigned int reg_val; > + int ret; > + > + ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, ®_val); > + if (ret < 0) > + return ret; > + > + reg_val &= ~HD3SS3220_REG_GEN_CTRL_SRC_PREF_MASK; > + reg_val |= src_pref; > + > + return regmap_write(hd3ss3220->regmap, > + HD3SS3220_REG_GEN_CTRL, reg_val); Please fix the alignment: return regmap_write(hd3ss3220->regmap, HD3SS3220_REG_GEN_CTRL, reg_val); > +} > + > +static int hd3ss3220_attached_state_detect(struct hd3ss3220 *hd3ss3220) > +{ > + unsigned int reg_val; > + int ret, attached_state; > + > + ret = regmap_read(hd3ss3220->regmap, > + HD3SS3220_REG_CN_STAT_CTRL, ®_val); ditto: ret = regmap_read(hd3ss3220->regmap, HD3SS3220_REG_CN_STAT_CTRL, ®_val); > + if (ret < 0) > + return ret; > + > + reg_val &= HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK; > + switch (reg_val) { switch (reg_val & HD3SS3220_REG_CN_STAT_CTRL_ATTACHED_STATE_MASK) > + case HD3SS3220_REG_CN_STAT_CTRL_AS_DFP: > +
[PATCH 07/11] usb: mtu3: supports new QMU format
In order to support U3gen2 ISOC transfer upto 96DPs, extend the data buffer length. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3.h | 11 +++--- drivers/usb/mtu3/mtu3_core.c| 5 +++ drivers/usb/mtu3/mtu3_gadget.c | 6 ++-- drivers/usb/mtu3/mtu3_hw_regs.h | 1 + drivers/usb/mtu3/mtu3_qmu.c | 64 + drivers/usb/mtu3/mtu3_qmu.h | 1 + 6 files changed, 66 insertions(+), 22 deletions(-) diff --git a/drivers/usb/mtu3/mtu3.h b/drivers/usb/mtu3/mtu3.h index 4dda7ed6e24e..76ecf12fdf62 100644 --- a/drivers/usb/mtu3/mtu3.h +++ b/drivers/usb/mtu3/mtu3.h @@ -148,22 +148,23 @@ struct mtu3_fifo_info { * bit0: Hardware Own (HWO) * bit1: Buffer Descriptor Present (BDP), always 0, BD is not supported * bit2: Bypass (BPS), 1: HW skips this GPD if HWO = 1 + * bit6: [EL] Zero Length Packet (ZLP), moved from @dw3_info[29] * bit7: Interrupt On Completion (IOC) - * bit[31:16]: allow data buffer length (RX ONLY), + * bit[31:16]: ([EL] bit[31:12]) allow data buffer length (RX ONLY), * the buffer length of the data to receive - * bit[23:16]: extension address (TX ONLY), + * bit[23:16]: ([EL] bit[31:24]) extension address (TX ONLY), * lower 4 bits are extension bits of @buffer, * upper 4 bits are extension bits of @next_gpd * @next_gpd: Physical address of the next GPD * @buffer: Physical address of the data buffer * @dw3_info: - * bit[15:0]: data buffer length, + * bit[15:0]: ([EL] bit[19:0]) data buffer length, * (TX): the buffer length of the data to transmit * (RX): The total length of data received - * bit[23:16]: extension address (RX ONLY), + * bit[23:16]: ([EL] bit[31:24]) extension address (RX ONLY), * lower 4 bits are extension bits of @buffer, * upper 4 bits are extension bits of @next_gpd - * bit29: Zero Length Packet (ZLP) (TX ONLY) + * bit29: ([EL] abandoned) Zero Length Packet (ZLP) (TX ONLY) */ struct qmu_gpd { __le32 dw0_info; diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index ef27c2052ad6..d354f5c3805a 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -601,6 +601,10 @@ static void mtu3_regs_init(struct mtu3 *mtu) mtu3_clrbits(mbase, U3D_MISC_CTRL, VBUS_FRC_EN | VBUS_ON); /* enable automatical HWRW from L1 */ mtu3_setbits(mbase, U3D_POWER_MANAGEMENT, LPM_HRWE); + + /* use new QMU format when HW version >= 0x1003 */ + if (mtu->gen2cp) + mtu3_writel(mbase, U3D_QFCR, ~0x0); } static irqreturn_t mtu3_link_isr(struct mtu3 *mtu) @@ -755,6 +759,7 @@ static int mtu3_hw_init(struct mtu3 *mtu) value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_TRUNK_VERS); mtu->hw_version = IP_TRUNK_VERS(value); + mtu->gen2cp = !!(mtu->hw_version >= MTU3_TRUNK_VERS_1003); value = mtu3_readl(mtu->ippc_base, U3D_SSUSB_IP_DEV_CAP); mtu->is_u3_ip = !!SSUSB_IP_DEV_U3_PORT_NUM(value); diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c index bbcd3332471d..fe798b94a357 100644 --- a/drivers/usb/mtu3/mtu3_gadget.c +++ b/drivers/usb/mtu3/mtu3_gadget.c @@ -278,10 +278,12 @@ static int mtu3_gadget_queue(struct usb_ep *ep, __func__, mep->is_in ? "TX" : "RX", mreq->epnum, ep->name, mreq, ep->maxpacket, mreq->request.length); - if (req->length > GPD_BUF_SIZE) { + if (req->length > GPD_BUF_SIZE || + (mtu->gen2cp && req->length > GPD_BUF_SIZE_EL)) { dev_warn(mtu->dev, "req length > supported MAX:%d requested:%d\n", - GPD_BUF_SIZE, req->length); + mtu->gen2cp ? GPD_BUF_SIZE_EL : GPD_BUF_SIZE, + req->length); return -EOPNOTSUPP; } diff --git a/drivers/usb/mtu3/mtu3_hw_regs.h b/drivers/usb/mtu3/mtu3_hw_regs.h index fae3b8de1092..bf70ea2426a9 100644 --- a/drivers/usb/mtu3/mtu3_hw_regs.h +++ b/drivers/usb/mtu3/mtu3_hw_regs.h @@ -49,6 +49,7 @@ #define U3D_QCR1 (SSUSB_DEV_BASE + 0x0404) #define U3D_QCR2 (SSUSB_DEV_BASE + 0x0408) #define U3D_QCR3 (SSUSB_DEV_BASE + 0x040C) +#define U3D_QFCR (SSUSB_DEV_BASE + 0x0428) #define U3D_TXQHIAR1 (SSUSB_DEV_BASE + 0x0484) #define U3D_RXQHIAR1 (SSUSB_DEV_BASE + 0x04C4) diff --git a/drivers/usb/mtu3/mtu3_qmu.c b/drivers/usb/mtu3/mtu3_qmu.c index 7a1919fc9f9e..9f017aa8fbeb 100644 --- a/drivers/usb/mtu3/mtu3_qmu.c +++ b/drivers/usb/mtu3/mtu3_qmu.c @@ -28,14 +28,42 @@ #define GPD_FLAGS_HWO BIT(0) #define GPD_FLAGS_BDP BIT(1) #define GPD_FLAGS_BPS BIT(2) +#define GPD_FLAGS_ZLP BIT(6) #define GPD_FLAGS_IOC BIT(7) #define GET_GPD_HWO(gpd) (le32_to_cpu((gpd)->dw0_info) & GPD_FLAGS_HWO) -#define GPD_RX_BUF_LEN(x) (((x) & 0x) <<
[PATCH 09/11] usb: mtu3: move vbus and mode debugfs interfaces into mtu3_debugfs.c
Due to the separated debugfs files are added, move vbus and mode debugfs interfaces related with dual-role switch from mtu3_dr.c into mtu3_debugfs.c Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_debug.h | 2 + drivers/usb/mtu3/mtu3_debugfs.c | 101 drivers/usb/mtu3/mtu3_dr.c | 113 +--- drivers/usb/mtu3/mtu3_dr.h | 4 ++ 4 files changed, 110 insertions(+), 110 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_debug.h b/drivers/usb/mtu3/mtu3_debug.h index 94d39b00403e..d97a48c73469 100644 --- a/drivers/usb/mtu3/mtu3_debug.h +++ b/drivers/usb/mtu3/mtu3_debug.h @@ -27,11 +27,13 @@ struct mtu3_file_map { #if IS_ENABLED(CONFIG_DEBUG_FS) void ssusb_dev_debugfs_init(struct ssusb_mtk *ssusb); +void ssusb_dr_debugfs_init(struct ssusb_mtk *ssusb); void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb); void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb); #else static inline void ssusb_dev_debugfs_init(struct ssusb_mtk *ssusb) {} +static inline void ssusb_dr_debugfs_init(struct ssusb_mtk *ssusb) {} static inline void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb) {} static inline void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb) {} diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c index 7cb1cad5a4b3..62c57ddc554e 100644 --- a/drivers/usb/mtu3/mtu3_debugfs.c +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -10,6 +10,7 @@ #include #include "mtu3.h" +#include "mtu3_dr.h" #include "mtu3_debug.h" #define dump_register(nm) \ @@ -425,6 +426,106 @@ void ssusb_dev_debugfs_init(struct ssusb_mtk *ssusb) mtu, &mtu3_ep_used_fops); } +static int ssusb_mode_show(struct seq_file *sf, void *unused) +{ + struct ssusb_mtk *ssusb = sf->private; + + seq_printf(sf, "current mode: %s(%s drd)\n(echo device/host)\n", + ssusb->is_host ? "host" : "device", + ssusb->otg_switch.manual_drd_enabled ? "manual" : "auto"); + + return 0; +} + +static int ssusb_mode_open(struct inode *inode, struct file *file) +{ + return single_open(file, ssusb_mode_show, inode->i_private); +} + +static ssize_t ssusb_mode_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *sf = file->private_data; + struct ssusb_mtk *ssusb = sf->private; + char buf[16]; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "host", 4) && !ssusb->is_host) { + ssusb_mode_manual_switch(ssusb, 1); + } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { + ssusb_mode_manual_switch(ssusb, 0); + } else { + dev_err(ssusb->dev, "wrong or duplicated setting\n"); + return -EINVAL; + } + + return count; +} + +static const struct file_operations ssusb_mode_fops = { + .open = ssusb_mode_open, + .write = ssusb_mode_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int ssusb_vbus_show(struct seq_file *sf, void *unused) +{ + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + + seq_printf(sf, "vbus state: %s\n(echo on/off)\n", + regulator_is_enabled(otg_sx->vbus) ? "on" : "off"); + + return 0; +} + +static int ssusb_vbus_open(struct inode *inode, struct file *file) +{ + return single_open(file, ssusb_vbus_show, inode->i_private); +} + +static ssize_t ssusb_vbus_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *sf = file->private_data; + struct ssusb_mtk *ssusb = sf->private; + struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; + char buf[16]; + bool enable; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (kstrtobool(buf, &enable)) { + dev_err(ssusb->dev, "wrong setting\n"); + return -EINVAL; + } + + ssusb_set_vbus(otg_sx, enable); + + return count; +} + +static const struct file_operations ssusb_vbus_fops = { + .open = ssusb_vbus_open, + .write = ssusb_vbus_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void ssusb_dr_debugfs_init(struct ssusb_mtk *ssusb) +{ + struct dentry *root = ssusb->dbgfs_root; + + debugfs_create_file("mode", 0644, root, ssusb, &ssusb_mode_fops); + debugfs_create_file("vbus", 0644, root, ssusb, &ssusb_vbus_fops); +} + void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb) { ssusb->dbgfs_root = diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 3f86ae1e73e8..ff295627
[PATCH 10/11] usb: mtu3: add tracepoints to help debug
This patch implements a few initial tracepoints for the mtu3 driver. More traces can be added as necessary in order to ease the task of debugging. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/Makefile | 7 + drivers/usb/mtu3/mtu3_core.c | 5 + drivers/usb/mtu3/mtu3_debug.h | 8 + drivers/usb/mtu3/mtu3_dr.c | 1 + drivers/usb/mtu3/mtu3_gadget.c | 14 +- drivers/usb/mtu3/mtu3_gadget_ep0.c | 4 + drivers/usb/mtu3/mtu3_qmu.c| 7 + drivers/usb/mtu3/mtu3_trace.c | 23 +++ drivers/usb/mtu3/mtu3_trace.h | 279 + 9 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/mtu3/mtu3_trace.c create mode 100644 drivers/usb/mtu3/mtu3_trace.h diff --git a/drivers/usb/mtu3/Makefile b/drivers/usb/mtu3/Makefile index 7c1826bbcebb..3bf8cbcc1add 100644 --- a/drivers/usb/mtu3/Makefile +++ b/drivers/usb/mtu3/Makefile @@ -2,10 +2,17 @@ ccflags-$(CONFIG_USB_MTU3_DEBUG) += -DDEBUG +# define_trace.h needs to know how to find our header +CFLAGS_mtu3_trace.o:= -I$(src) + obj-$(CONFIG_USB_MTU3) += mtu3.o mtu3-y := mtu3_plat.o +ifneq ($(CONFIG_TRACING),) + mtu3-y += mtu3_trace.o +endif + ifneq ($(filter y,$(CONFIG_USB_MTU3_HOST) $(CONFIG_USB_MTU3_DUAL_ROLE)),) mtu3-y += mtu3_host.o endif diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index f106fe81ae10..f8bd1d57e795 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -17,6 +17,7 @@ #include "mtu3.h" #include "mtu3_debug.h" +#include "mtu3_trace.h" static int ep_fifo_alloc(struct mtu3_ep *mep, u32 seg_size) { @@ -656,6 +657,8 @@ static irqreturn_t mtu3_link_isr(struct mtu3 *mtu) break; } dev_dbg(mtu->dev, "%s: %s\n", __func__, usb_speed_string(udev_speed)); + mtu3_dbg_trace(mtu->dev, "link speed %s", + usb_speed_string(udev_speed)); mtu->g.speed = udev_speed; mtu->g.ep0->maxpacket = maxpkt; @@ -678,6 +681,7 @@ static irqreturn_t mtu3_u3_ltssm_isr(struct mtu3 *mtu) ltssm &= mtu3_readl(mbase, U3D_LTSSM_INTR_ENABLE); mtu3_writel(mbase, U3D_LTSSM_INTR, ltssm); /* W1C */ dev_dbg(mtu->dev, "=== LTSSM[%x] ===\n", ltssm); + trace_mtu3_u3_ltssm_isr(ltssm); if (ltssm & (HOT_RST_INTR | WARM_RST_INTR)) mtu3_gadget_reset(mtu); @@ -708,6 +712,7 @@ static irqreturn_t mtu3_u2_common_isr(struct mtu3 *mtu) u2comm &= mtu3_readl(mbase, U3D_COMMON_USB_INTR_ENABLE); mtu3_writel(mbase, U3D_COMMON_USB_INTR, u2comm); /* W1C */ dev_dbg(mtu->dev, "=== U2COMM[%x] ===\n", u2comm); + trace_mtu3_u2_common_isr(u2comm); if (u2comm & SUSPEND_INTR) mtu3_gadget_suspend(mtu); diff --git a/drivers/usb/mtu3/mtu3_debug.h b/drivers/usb/mtu3/mtu3_debug.h index d97a48c73469..e96a69234d05 100644 --- a/drivers/usb/mtu3/mtu3_debug.h +++ b/drivers/usb/mtu3/mtu3_debug.h @@ -39,4 +39,12 @@ static inline void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb) {} #endif /* CONFIG_DEBUG_FS */ +#if IS_ENABLED(CONFIG_TRACING) +void mtu3_dbg_trace(struct device *dev, const char *fmt, ...); + +#else +static inline void mtu3_dbg_trace(struct device *dev, const char *fmt, ...) {} + +#endif /* CONFIG_TRACING */ + #endif /* __MTU3_DEBUG_H__ */ diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index ff2956272e15..82913120622b 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -141,6 +141,7 @@ static void ssusb_set_mailbox(struct otg_switch_mtk *otg_sx, struct mtu3 *mtu = ssusb->u3d; dev_dbg(ssusb->dev, "mailbox state(%d)\n", status); + mtu3_dbg_trace(ssusb->dev, "mailbox %d", status); switch (status) { case MTU3_ID_GROUND: diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c index fe798b94a357..f93732e53fd8 100644 --- a/drivers/usb/mtu3/mtu3_gadget.c +++ b/drivers/usb/mtu3/mtu3_gadget.c @@ -8,6 +8,7 @@ */ #include "mtu3.h" +#include "mtu3_trace.h" void mtu3_req_complete(struct mtu3_ep *mep, struct usb_request *req, int status) @@ -25,6 +26,8 @@ __acquires(mep->mtu->lock) mtu = mreq->mtu; mep->busy = 1; + + trace_mtu3_req_complete(mreq); spin_unlock(&mtu->lock); /* ep0 makes use of PIO, needn't unmap it */ @@ -201,6 +204,7 @@ static int mtu3_gadget_ep_enable(struct usb_ep *ep, spin_unlock_irqrestore(&mtu->lock, flags); dev_dbg(mtu->dev, "%s active_ep=%d\n", __func__, mtu->active_ep); + trace_mtu3_gadget_ep_enable(mep); return ret; } @@ -212,6 +216,7 @@ static int mtu3_gadget_ep_disable(struct usb_ep *ep) unsigned long flags; dev_dbg(mtu->dev, "%s %s\n", __func__, mep->name); + trace_mtu3_gadget_ep_disable(mep); if (!(mep->flags & MTU3_EP_ENABLED)) { dev_warn(mtu->dev, "%s i
[PATCH 02/11] usb: mtu3: print useful information also for device and host modes
Print useful information not only dual-role mode but also device mode and host mode. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/mtu3_plat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c index dee31d5eefe1..3a4a80f15957 100644 --- a/drivers/usb/mtu3/mtu3_plat.c +++ b/drivers/usb/mtu3/mtu3_plat.c @@ -286,7 +286,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) ssusb->dr_mode = USB_DR_MODE_OTG; if (ssusb->dr_mode == USB_DR_MODE_PERIPHERAL) - return 0; + goto out; /* if host role is supported */ ret = ssusb_wakeup_of_property_parse(ssusb, node); @@ -307,7 +307,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) otg_sx->vbus = vbus; if (ssusb->dr_mode == USB_DR_MODE_HOST) - return 0; + goto out; /* if dual-role mode is supported */ otg_sx->is_u3_drd = of_property_read_bool(node, "mediatek,usb3-drd"); @@ -322,6 +322,7 @@ static int get_ssusb_rscs(struct platform_device *pdev, struct ssusb_mtk *ssusb) } } +out: dev_info(dev, "dr_mode: %d, is_u3_dr: %d, u3p_dis_msk: %x, drd: %s\n", ssusb->dr_mode, otg_sx->is_u3_drd, ssusb->u3p_dis_msk, otg_sx->manual_drd_enabled ? "manual" : "auto"); -- 2.20.1
[PATCH 08/11] usb: mtu3: add debugfs interface files
This adds more debugfs consumers. The debugfs entries read some important registers, fifo status, QMU ring, endpoint status, and IPPC probe interface to get internal status. With these entries, users can check the registers, endpoint and GPD used during run time. Signed-off-by: Chunfeng Yun --- drivers/usb/mtu3/Makefile | 4 + drivers/usb/mtu3/mtu3_core.c| 3 + drivers/usb/mtu3/mtu3_debug.h | 40 +++ drivers/usb/mtu3/mtu3_debugfs.c | 438 drivers/usb/mtu3/mtu3_dr.c | 13 +- drivers/usb/mtu3/mtu3_hw_regs.h | 11 + drivers/usb/mtu3/mtu3_plat.c| 7 +- 7 files changed, 503 insertions(+), 13 deletions(-) create mode 100644 drivers/usb/mtu3/mtu3_debug.h create mode 100644 drivers/usb/mtu3/mtu3_debugfs.c diff --git a/drivers/usb/mtu3/Makefile b/drivers/usb/mtu3/Makefile index 4a9715812bf9..7c1826bbcebb 100644 --- a/drivers/usb/mtu3/Makefile +++ b/drivers/usb/mtu3/Makefile @@ -17,3 +17,7 @@ endif ifneq ($(CONFIG_USB_MTU3_DUAL_ROLE),) mtu3-y += mtu3_dr.o endif + +ifneq ($(CONFIG_DEBUG_FS),) + mtu3-y += mtu3_debugfs.o +endif diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index d354f5c3805a..f106fe81ae10 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -16,6 +16,7 @@ #include #include "mtu3.h" +#include "mtu3_debug.h" static int ep_fifo_alloc(struct mtu3_ep *mep, u32 seg_size) { @@ -900,6 +901,8 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb) if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) mtu3_stop(mtu); + ssusb_dev_debugfs_init(ssusb); + dev_dbg(dev, " %s() done...\n", __func__); return 0; diff --git a/drivers/usb/mtu3/mtu3_debug.h b/drivers/usb/mtu3/mtu3_debug.h new file mode 100644 index ..94d39b00403e --- /dev/null +++ b/drivers/usb/mtu3/mtu3_debug.h @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mtu3_debug.h - debug header + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun + */ + +#ifndef __MTU3_DEBUG_H__ +#define __MTU3_DEBUG_H__ + +#include + +#define MTU3_DEBUGFS_NAME_LEN 32 + +struct mtu3_regset { + char name[MTU3_DEBUGFS_NAME_LEN]; + struct debugfs_regset32 regset; + size_t nregs; +}; + +struct mtu3_file_map { + const char *name; + int (*show)(struct seq_file *s, void *unused); +}; + +#if IS_ENABLED(CONFIG_DEBUG_FS) +void ssusb_dev_debugfs_init(struct ssusb_mtk *ssusb); +void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb); +void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb); + +#else +static inline void ssusb_dev_debugfs_init(struct ssusb_mtk *ssusb) {} +static inline void ssusb_debugfs_create_root(struct ssusb_mtk *ssusb) {} +static inline void ssusb_debugfs_remove_root(struct ssusb_mtk *ssusb) {} + +#endif /* CONFIG_DEBUG_FS */ + +#endif /* __MTU3_DEBUG_H__ */ diff --git a/drivers/usb/mtu3/mtu3_debugfs.c b/drivers/usb/mtu3/mtu3_debugfs.c new file mode 100644 index ..7cb1cad5a4b3 --- /dev/null +++ b/drivers/usb/mtu3/mtu3_debugfs.c @@ -0,0 +1,438 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mtu3_debugfs.c - debugfs interface + * + * Copyright (C) 2019 MediaTek Inc. + * + * Author: Chunfeng Yun + */ + +#include + +#include "mtu3.h" +#include "mtu3_debug.h" + +#define dump_register(nm) \ +{ \ + .name = __stringify(nm),\ + .offset = U3D_ ##nm,\ +} + +#define dump_prb_reg(nm, os) \ +{ \ + .name = nm, \ + .offset = os, \ +} + +static const struct debugfs_reg32 mtu3_ippc_regs[] = { + dump_register(SSUSB_IP_PW_CTRL0), + dump_register(SSUSB_IP_PW_CTRL1), + dump_register(SSUSB_IP_PW_CTRL2), + dump_register(SSUSB_IP_PW_CTRL3), + dump_register(SSUSB_OTG_STS), + dump_register(SSUSB_IP_XHCI_CAP), + dump_register(SSUSB_IP_DEV_CAP), + dump_register(SSUSB_U3_CTRL_0P), + dump_register(SSUSB_U2_CTRL_0P), + dump_register(SSUSB_HW_ID), + dump_register(SSUSB_HW_SUB_ID), + dump_register(SSUSB_IP_SPARE0), +}; + +static const struct debugfs_reg32 mtu3_dev_regs[] = { + dump_register(LV1ISR), + dump_register(LV1IER), + dump_register(EPISR), + dump_register(EPIER), + dump_register(EP0CSR), + dump_register(RXCOUNT0), + dump_register(QISAR0), + dump_register(QIER0), + dump_register(QISAR1), + dump_register(QIER1), + dump_register(CAP_EPNTXFFSZ), + dump_register(CAP_EPNRXFFSZ), + dump_register(CAP_EPINFO), + dump_register(MISC_CTRL), +}; + +static const struct debugfs_reg32 mtu3_csr_regs[] = { + dump_register(DEVICE_CONF), + dump_register(DEV_LINK_INTR_ENABLE), + dump_register(DEV_LINK_INTR), + dump_register(LTSSM_CTRL), + dump_register(USB3_CONFIG), + dump_register(LINK_STATE_MACHINE), + dump_regi