Re: [PATCH 06/11] mux: Add Pericom PI3USB30532 Type-C mux driver
On 2017-09-04 13:19, Peter Rosin wrote: > Hi! > > One comment inline... Oh, and one more small nit, I think you should do s/pi3usb30532_mux/pi3usb30532/g to shorten the identifiers a bit. The _mux suffix (or infix) is kind of selfevident from where the file lives anyway. pi3usb30532_mux_set_mux in particular feels a bit much Cheers, peda > On 2017-09-01 23:48, Hans de Goede wrote: >> Add a driver for the Pericom PI3USB30532 Type-C cross switch / >> mux chip found on some devices with a Type-C port. >> >> Signed-off-by: Hans de Goede >> --- >> drivers/mux/Kconfig | 10 + >> drivers/mux/Makefile | 2 + >> drivers/mux/pi3usb30532.c | 97 >> +++ >> 3 files changed, 109 insertions(+) >> create mode 100644 drivers/mux/pi3usb30532.c >> >> diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig >> index 17938918bf93..19a3065c34e6 100644 >> --- a/drivers/mux/Kconfig >> +++ b/drivers/mux/Kconfig >> @@ -58,4 +58,14 @@ config MUX_MMIO >>To compile the driver as a module, choose M here: the module will >>be called mux-mmio. >> >> +config MUX_PI3USB30532 >> +tristate "Pericom PI3USB30532 Type-C cross switch driver" >> +depends on I2C >> +help >> + This driver adds support for the Pericom PI3USB30532 Type-C cross >> + switch / mux chip found on some devices with a Type-C port. >> + >> + To compile the driver as a module, choose M here: the module will >> + be called mux-pi3usb30532. >> + >> endmenu >> diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile >> index a12e812c7966..7563dbf04593 100644 >> --- a/drivers/mux/Makefile >> +++ b/drivers/mux/Makefile >> @@ -7,9 +7,11 @@ mux-adg792a-objs:= adg792a.o >> mux-gpio-objs := gpio.o >> mux-mmio-objs := mmio.o >> mux-intel_cht_usb_mux-objs := intel_cht_usb_mux.o >> +mux-pi3usb30532-objs:= pi3usb30532.o >> >> obj-$(CONFIG_MULTIPLEXER) += mux-core.o >> obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o >> obj-$(CONFIG_MUX_GPIO) += mux-gpio.o >> obj-$(CONFIG_MUX_MMIO) += mux-mmio.o >> obj-$(CONFIG_MUX_CHT_USB_MUX) += mux-intel_cht_usb_mux.o >> +obj-$(CONFIG_MUX_PI3USB30532) += mux-pi3usb30532.o >> diff --git a/drivers/mux/pi3usb30532.c b/drivers/mux/pi3usb30532.c >> new file mode 100644 >> index ..fa8abd851520 >> --- /dev/null >> +++ b/drivers/mux/pi3usb30532.c >> @@ -0,0 +1,97 @@ >> +/* >> + * Pericom PI3USB30532 Type-C cross switch / mux driver >> + * >> + * Copyright (c) 2017 Hans de Goede >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation, or (at your option) >> + * any later version. >> + */ >> + >> +#include >> +#include >> +#include >> +#include /* For the MUX_USB_* defines */ >> +#include >> + >> +#define PI3USB30532_CONF0x00 >> + >> +#define PI3USB30532_CONF_OPEN 0x00 >> +#define PI3USB30532_CONF_SWAP 0x01 >> +#define PI3USB30532_CONF_4LANE_DP 0x02 >> +#define PI3USB30532_CONF_USB3 0x04 >> +#define PI3USB30532_CONF_USB3_AND_2LANE_DP 0x06 >> + >> +struct pi3usb30532_mux { >> +struct i2c_client *client; >> +}; >> + >> +static int pi3usb30532_mux_set_mux(struct mux_control *mux_ctrl, int state) >> +{ >> +struct pi3usb30532_mux *mux = mux_chip_priv(mux_ctrl->chip); > > The "mux" variable name is used for the mux_control in other drivers, and > I don't think the private data is needed. Like so: > > static int pi3usb30532_mux_set_mux(struct mux_control *mux, int state) > { > struct i2c_client *i2c = to_i2c_client(mux->chip->dev.parent); > > ... > > Cheers, > Peter > >> +u8 conf = PI3USB30532_CONF_OPEN; >> + >> +switch (state & ~MUX_USB_POLARITY_INV) { >> +case MUX_USB_NONE: >> +conf = PI3USB30532_CONF_OPEN; >> +break; >> +case MUX_USB_DEVICE: >> +case MUX_USB_HOST: >> +conf = PI3USB30532_CONF_USB3; >> +break; >> +case MUX_USB_HOST_AND_DP_SRC: >> +conf = PI3USB30532_CONF_USB3_AND_2LANE_DP; >> +break; >> +case MUX_USB_DP_SRC: >> +conf = PI3USB30532_CONF_4LANE_DP; >> +break; >> +} >> + >> +if (state & MUX_USB_POLARITY_INV) >> +conf |= PI3USB30532_CONF_SWAP; >> + >> +return i2c_smbus_write_byte_data(mux->client, PI3USB30532_CONF, conf); >> +} >> + >> +static const struct mux_control_ops pi3usb30532_mux_ops = { >> +.set = pi3usb30532_mux_set_mux, >> +}; >> + >> +static int pi3usb30532_mux_probe(struct i2c_client *client) >> +{ >> +struct device *dev = &client->dev; >> +struct pi3usb30532_mux *mux; >> +struct mux_chip *mux_chip; >> + >> +mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux)); >>
[PATCH] usb: gadget: dummy: fix nonsensical comparisons
gcc-8 points out two comparisons that are clearly bogus and almost certainly not what the author intended to write: drivers/usb/gadget/udc/dummy_hcd.c: In function 'set_link_state_by_speed': drivers/usb/gadget/udc/dummy_hcd.c:379:31: error: bitwise comparison always evaluates to false [-Werror=tautological-compare] USB_PORT_STAT_ENABLE) == 1 && ^~ drivers/usb/gadget/udc/dummy_hcd.c:381:25: error: bitwise comparison always evaluates to false [-Werror=tautological-compare] USB_SS_PORT_LS_U0) == 1 && ^~ I looked at the code for a bit and came up with a change that makes it look like what the author probably meant here. This makes it look reasonable to me and to gcc, shutting up the warning. It does of course change behavior as the two conditions are actually evaluated rather than being hardcoded to false, and I have made no attempt at verifying that the changed logic makes sense in the context of a USB HCD, so that part needs to be reviewed carefully. Fixes: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support") Cc: Tatyana Brokhman Cc: Felipe Balbi Signed-off-by: Arnd Bergmann --- drivers/usb/gadget/udc/dummy_hcd.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index a030d7923d7d..54e8e37d2bc8 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -376,10 +376,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); if ((dum_hcd->port_status & -USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & -USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) +USB_PORT_STAT_ENABLE) == USB_PORT_STAT_ENABLE && + (dum_hcd->port_status & +USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] usb: Increase quirk delay for USB devices
Commit e0429362ab15 ("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e") introduced quirk to workaround an issue with some Logitech webcams. The workaround is introducing delay for some USB operations. According to our testing, delay introduced by original commit is not long enough and in rare cases we still see issues described by the aforementioned commit. This patch increases delays introduced by original commit. Having this patch applied we do not see those problems anymore. Signed-off-by: Dmitry Fleytman --- drivers/usb/core/config.c | 2 +- drivers/usb/core/hub.c| 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 4be52c6..854c8d6 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -852,7 +852,7 @@ int usb_get_configuration(struct usb_device *dev) } if (dev->quirks & USB_QUIRK_DELAY_INIT) - msleep(100); + msleep(200); result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 822f8c5..78c2aca 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4825,7 +4825,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, goto loop; if (udev->quirks & USB_QUIRK_DELAY_INIT) - msleep(1000); + msleep(2000); /* consecutive bus-powered hubs aren't reliable; they can * violate the voltage drop budget. if the new child has -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 04/11] usb: xhci: Add Intel cherrytrail extended cap / otg phy mux handling
Hi, On 04-09-17 09:31, Heikki Krogerus wrote: Hi, On Fri, Sep 01, 2017 at 11:48:38PM +0200, Hans de Goede wrote: The Intel cherrytrail xhci controller has an extended cap mmio-range which contains registers to control the muxing to the xhci (host mode) or the dwc3 (device mode) and vbus-detection for the otg usb-phy. Having a mux driver included in the xhci code (or under drivers/usb/host) is not desirable. So this commit adds a simple handler for this extended capability, which creates a platform device with the caps mmio region as resource, this allows us to write a separate platform mux driver for the mux. Signed-off-by: Hans de Goede --- Changes in v2: -Check xHCI controller PCI device-id instead of only checking for the Intel Extended capability ID, as the Extended capability ID is used on other model Intel xHCI controllers too --- drivers/usb/host/Makefile| 2 +- drivers/usb/host/xhci-intel-quirks.c | 85 drivers/usb/host/xhci-pci.c | 4 ++ drivers/usb/host/xhci.h | 2 + 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/xhci-intel-quirks.c diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index cf2691fffcc0..441edf82eb1c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_USB_OHCI_HCD_DAVINCI)+= ohci-da8xx.o obj-$(CONFIG_USB_UHCI_HCD)+= uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD)+= fhci.o obj-$(CONFIG_USB_XHCI_HCD)+= xhci-hcd.o -obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o +obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o xhci-intel-quirks.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o obj-$(CONFIG_USB_XHCI_MTK)+= xhci-mtk.o obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o diff --git a/drivers/usb/host/xhci-intel-quirks.c b/drivers/usb/host/xhci-intel-quirks.c new file mode 100644 index ..819f5f9da9ee --- /dev/null +++ b/drivers/usb/host/xhci-intel-quirks.c @@ -0,0 +1,85 @@ +/* + * Intel Vendor Defined XHCI extended capability handling + * + * Copyright (c) 2016) Hans de Goede + * + * Loosely based on android x86 kernel code which is: + * + * Copyright (C) 2014 Intel Corp. + * + * Author: Wu, Hao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; + */ + +#include +#include "xhci.h" + +/* Extended capability IDs for Intel Vendor Defined */ +#define XHCI_EXT_CAPS_INTEL_HOST_CAP 192 + +static void xhci_intel_unregister_pdev(void *arg) +{ + platform_device_unregister(arg); +} + +int xhci_create_intel_cht_mux_pdev(struct xhci_hcd *xhci) +{ + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct device *dev = hcd->self.controller; + struct platform_device *pdev; + struct resource res = { 0, }; + int ret, ext_offset; + + ext_offset = xhci_find_next_ext_cap(&xhci->cap_regs->hc_capbase, 0, + XHCI_EXT_CAPS_INTEL_HOST_CAP); + if (!ext_offset) { + xhci_err(xhci, "couldn't find Intel ext caps\n"); + return -ENODEV; + } + + pdev = platform_device_alloc("intel_cht_usb_mux", PLATFORM_DEVID_NONE); + if (!pdev) { + xhci_err(xhci, "couldn't allocate intel_cht_usb_mux pdev\n"); + return -ENOMEM; + } + + res.start = hcd->rsrc_start + ext_offset; + res.end = res.start + 0x3ff; + res.name = "intel_cht_usb_mux"; + res.flags = IORESOURCE_MEM; + + ret = platform_device_add_resources(pdev, &res, 1); + if (ret) { + dev_err(dev, "couldn't add resources to intel_cht_usb_mux pdev\n"); + platform_device_put(pdev); + return ret; + } Previously the problem with this was that since platform bus reserves the memory region, usb core fails to register the hcd, as it also wants to reserve the same memory region. So xhci with this failed to probe. So has that been fixed? Does xhci really get registered with this? This is not a problem if you set the xhci device as parent: + pdev->dev.parent = dev; And yes both the xhci and the intel_cht_usb_mux devices get registered and work fine: [root@localhost ~]# cat /proc/iomem 8000-dfff : PCI Bus :00 a1c0-a1c0 : :00:14.0 a1c0-a1c0 : xhci-hcd a1c08070-a1c0846f : intel_cht_usb_mux [root@localhost ~]# lsusb -t /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd
Re: [PATCH 00/11] mux/typec: Add USB / TypeC mux drivers and hook them up on some x86 systems
Hi Peter, On 04-09-17 13:18, Peter Rosin wrote: On 2017-09-01 23:48, Hans de Goede wrote: Hi All, This series consists of 4 parts: 1) Core mux changes to add support for getting mux-controllers on non DT platforms and to add some standardised state values for USB 2) Add Intel CHT USB mux and Pericom-PI3USB30532 Type-C mux drivers 3) Hookup the Intel CHT USB mux driver for CHT devices without Type-C 4) Hookup both the Intel CHT USB mux and Pericom-PI3USB30532 Type-C mux drivers to the fusb302 Type-C port controller found on some CHT x86 devs Please review, or in the case of the drivers/mux changes (which are a dep for some of the other patches) merge if the patches are ready. Hi Hans, I see commonalities with this and the below patch seriess from Stephen Boyd [added to Cc]. https://lkml.org/lkml/2017/7/11/696 [PATCH 0/3] USB Mux support for Chipidea https://lkml.org/lkml/2017/7/14/654 [PATCH v2 0/3] USB Mux support for Chipidea Interesting, it seems that Stephen and I are trying to use the mux-framework for identical (device/host selection) purposes, except that in some cases I also gave a Type-C cross-switch to deal with. I noticed this discussion in the thread: """ > + usb-switch-states = <0>, <1>; I don't see the need for usb-switch-states? Just assume states 0/1 and if someone later needs some other states, make them add a property that overrides the defaults. Just document that 0 is host and 1 is device. """ I think it makes sense to just agree on fixed "state" values for certain use-cases, as done in my "mux: consumer.h: Add MUX_USB_* state constant defines" patch. This means that the "state" register in the hardware and the state as passed to mux_control_select() may not map 1:1, but that can easily be mapped in the driver and it allows inter-changeble (compatible) mux drivers for some common mux use-cases such as an USB device/host mux. Edit: Ah I see you already suggest this below, good :) Stephen had a patch that added mux_control_get_optional() that I think could be of use for this series? Ack, I think that would be useful. If you plan to merge Stephen's patch for this, please give me a link to a git repo with that merged then I will rebase my series on top. Anyway, there seems to be some interest in using the mux subsystem for handling the USB host/device role. I think the role-switch interface between the USB and mux subsystems should be done similarly, regardless of what particular USB driver needs to switch role using whatever particular mux driver. If at all possible. > The way I read it, the pi3usb30532 driver is the one adding the need to involve the DP states and the inverted bit. Correct, the pi3usb30532 mux is a mux designed for Type-C ports, it switches to 4 high-speed differential data-pairs the Type-C connector has to one on: USB-controller(s), DisplayPort outputs on the GPU, or a combination of both (2 data-pairs to each). It also takes into account if the Type-C connector has been inserted normally or "upside-down", which is where the inverted bits comes into play. Those things are not used by anything else, and I think it clutters up things for everybody when the weird needs of one driver "invades" the mux states needed to control the USB role. So, I would like USB role switching to have 2 states, device and host (0 and 1 is used by the above chipidea code). And then the USB switch can of course be idle, which is best represented with one of MUX_IDLE_DISCONNECT, MUX_IDLE_AS_IS or one of the modes depending on if the USB switch can or can't disconnect (or other considerations). Now, you can't explicitly set the idle state using mux_control_select(), it can only be set implicitly using mux_control_deselect(), so that will require some changes in the consumer logic. Regarding the pi3usb30532 driver, I think the above is in fact also better since the "swap bit" means something totally different when the switch is "open" (if I read the datasheet correctly > I.e. PI3USB30532_CONF_OPEN | PI3USB30532_CONF_SWAP is not sane, The only "datasheet" I could find is "PI3USB30532-PI3USB31532_App_Type-C application Note_Rev.A.pdf" and that says the swap bits does not do anything when the switch is "open" but that does not matter for the rest of the discussion, I do agree that mapping deselected to open makes sense. and that would just go away completely if the driver implemented MUX_IDLE_DISCONNECT as PI3USB30532_CONF_OPEN and removed the possibility to explicitly set the "open" state with mux_control_select(). So, I think the generic USB role switch interface should be something like: #define MUX_USB_DEVICE (0) /* USB device mode */ #define MUX_USB_HOST(1) /* USB host mode */ Those 2 work for me. And then the pi3usb30532 driver can extend that: #define MUX_PI3USB30352_HOST_AND_DP_SRC (2)/* USB host + 2 lanes Display Port */ #define MUX_PI3USB30352_DP_SRC (3)/* 4 lanes Display Port source */ #define
Re: [PATCH 02/11] mux: core: Add support for getting a mux controller on a non DT platform
Hi, On 04-09-17 13:19, Peter Rosin wrote: Hi! Some comments inline... On 2017-09-01 23:48, Hans de Goede wrote: On non DT platforms we cannot get the mux_chip by pnode. Other subsystems (regulator, clock, pwm) have the same problem and solve this by allowing platform / board-setup code to add entries to a lookup table and then use this table to look things up. This commit adds support for getting a mux controller on a non DT platform following this pattern. It is based on a simplified version of the pwm subsys lookup code, the dev_id and mux_name parts of a lookup table entry are mandatory in the mux-core implementation. Signed-off-by: Hans de Goede --- drivers/mux/core.c | 96 +++- include/linux/mux/consumer.h | 11 + 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/drivers/mux/core.c b/drivers/mux/core.c index 6142493c327b..8864cc745506 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c @@ -24,6 +24,9 @@ #include #include +static DEFINE_MUTEX(mux_lookup_lock); +static LIST_HEAD(mux_lookup_list); + /* * The idle-as-is "state" is not an actual state that may be selected, it * only implies that the state should not be changed. So, use that state @@ -408,6 +411,23 @@ int mux_control_deselect(struct mux_control *mux) } EXPORT_SYMBOL_GPL(mux_control_deselect); +static int parent_name_match(struct device *dev, const void *data) +{ + const char *parent_name = dev_name(dev->parent); + const char *name = data; + + return strcmp(parent_name, name) == 0; +} + +static struct mux_chip *mux_chip_get_by_name(const char *name) +{ + struct device *dev; + + dev = class_find_device(&mux_class, NULL, name, parent_name_match); + + return dev ? to_mux_chip(dev) : NULL; +} + static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; @@ -479,6 +499,42 @@ static struct mux_control *of_mux_control_get(struct device *dev, } /** + * mux_add_table() - register PWM device consumers register mux controllers (because you are not registering consumers, right? someone is registering controllers so that they can be found by consumers?) Actually what is being registered is a "consumer to mux-controller mapping", I will update the kernel-doc comments to use that everywhere. + * @table: array of consumers to register + * @num: number of consumers in table controllers? mappings :) + */ +void mux_add_table(struct mux_lookup *table, size_t num) +{ + mutex_lock(&mux_lookup_lock); + + while (num--) { + list_add_tail(&table->list, &mux_lookup_list); + table++; + } I prefer for (; num--; table++) list_add_tail(&table->list, &mux_lookup_list); Sure, works for me. + + mutex_unlock(&mux_lookup_lock); +} +EXPORT_SYMBOL_GPL(mux_add_table); + +/** + * mux_remove_table() - unregister PWM device consumers unregister mux controllers(?) + * @table: array of consumers to unregister + * @num: number of consumers in table controllers? + */ +void mux_remove_table(struct mux_lookup *table, size_t num) +{ + mutex_lock(&mux_lookup_lock); + + while (num--) { + list_del(&table->list); + table++; + } for() loop here as well. Ack. + + mutex_unlock(&mux_lookup_lock); +} +EXPORT_SYMBOL_GPL(mux_remove_table); + +/** * mux_control_get() - Get the mux-control for a device. * @dev: The device that needs a mux-control. * @mux_name: The name identifying the mux-control. @@ -487,11 +543,49 @@ static struct mux_control *of_mux_control_get(struct device *dev, */ struct mux_control *mux_control_get(struct device *dev, const char *mux_name) { + struct mux_lookup *m, *chosen = NULL; + const char *dev_id = dev_name(dev); + struct mux_chip *mux_chip; + /* look up via DT first */ if (IS_ENABLED(CONFIG_OF) && dev->of_node) return of_mux_control_get(dev, mux_name); - return ERR_PTR(-ENODEV); + /* +* For non DT we look up the provider in the static table typically +* provided by board setup code. +* +* If a match is found, the provider mux chip is looked up by name +* and a mux-control is requested using the table provided index. +*/ + mutex_lock(&mux_lookup_lock); + list_for_each_entry(m, &mux_lookup_list, list) { + if (WARN_ON(!m->dev_id || !m->mux_name || !m->provider)) + continue; + + if (strcmp(m->dev_id, dev_id) == 0 && + strcmp(m->mux_name, mux_name) == 0) { I want the below format (with ! instead of == 0 and the brace on the next line when the condition has a line break): Ok, I think checkpatch is going to not like that "{" there, but I'm fine with putting it there. if (!strcmp(m->dev_id, dev
Re: [PATCH 05/11] mux: Add Intel Cherrytrail USB mux driver
Hi, On 04-09-17 13:19, Peter Rosin wrote: Hi! Some comments inline... On 2017-09-01 23:48, Hans de Goede wrote: Intel Cherrytrail SoCs have an internal USB mux for muxing the otg-port USB data lines between the xHCI host controller and the dwc3 gadget controller. On some Cherrytrail systems this mux is controlled through AML code reacting on a GPIO IRQ connected to the USB OTG id pin (through an _AIE ACPI method) so things just work. But on other Cherrytrail systems we need to control the mux ourselves this driver exports the mux through the mux subsys, so that other drivers can control it if necessary. This driver also updates the vbus-valid reporting to the dwc3 gadget controller, as this uses the same registers as the mux. This is needed for gadget/device mode to work properly (even on systems which control the mux from their AML code). Note this depends on the xhci driver registering a platform device named "intel_cht_usb_mux", which has an IOMEM resource 0 which points to the Intel Vendor Defined XHCI extended capabilities region. Signed-off-by: Hans de Goede --- Changes in v2: -Complete rewrite as a stand-alone platform-driver rather then as a phy driver, since this is just a mux, not a phy Changes in v3: -Make this a mux subsys driver instead of listening to USB_HOST extcon cable events and responding to those --- drivers/mux/Kconfig | 11 ++ drivers/mux/Makefile| 2 + drivers/mux/intel_cht_usb_mux.c | 269 3 files changed, 282 insertions(+) create mode 100644 drivers/mux/intel_cht_usb_mux.c diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index 19e4e904c9bf..17938918bf93 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -34,6 +34,17 @@ config MUX_GPIO To compile the driver as a module, choose M here: the module will be called mux-gpio. +config MUX_CHT_USB_MUX + tristate "Intel Cherrytrail USB Multiplexer" + depends on ACPI && X86 && EXTCON + help + This driver adds support for the internal USB mux for muxing the OTG + USB data lines between the xHCI host controller and the dwc3 gadget + controller found on Intel Cherrytrail SoCs. + + To compile the driver as a module, choose M here: the module will + be called mux-intel_cht_usb_mux. + config MUX_MMIO tristate "MMIO register bitfield-controlled Multiplexer" depends on (OF && MFD_SYSCON) || COMPILE_TEST diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index 0e1e59760e3f..a12e812c7966 100644 --- a/drivers/mux/Makefile +++ b/drivers/mux/Makefile @@ -6,8 +6,10 @@ mux-core-objs := core.o mux-adg792a-objs := adg792a.o mux-gpio-objs := gpio.o mux-mmio-objs := mmio.o +mux-intel_cht_usb_mux-objs := intel_cht_usb_mux.o I dislike underscores in file names (and other names), please use dashes where possible. Also, please keep the list sorted. obj-$(CONFIG_MULTIPLEXER) += mux-core.o obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o obj-$(CONFIG_MUX_GPIO)+= mux-gpio.o obj-$(CONFIG_MUX_MMIO)+= mux-mmio.o +obj-$(CONFIG_MUX_CHT_USB_MUX) += mux-intel_cht_usb_mux.o Dito. Ok, will fix both for v2. diff --git a/drivers/mux/intel_cht_usb_mux.c b/drivers/mux/intel_cht_usb_mux.c new file mode 100644 index ..7b1621a081d8 --- /dev/null +++ b/drivers/mux/intel_cht_usb_mux.c @@ -0,0 +1,269 @@ +/* + * Intel Cherrytrail USB OTG MUX driver + * + * Copyright (c) 2016 Hans de Goede + * + * Loosely based on android x86 kernel code which is: + * + * Copyright (C) 2014 Intel Corp. + * + * Author: Wu, Hao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* For the MUX_USB_* defines */ +#include +#include +#include + +/* register definition */ +#define DUAL_ROLE_CFG0 0x68 +#define SW_VBUS_VALID (1 << 24) +#define SW_IDPIN_EN(1 << 21) +#define SW_IDPIN (1 << 20) + +#define DUAL_ROLE_CFG1 0x6c +#define HOST_MODE (1 << 29) + +#define DUAL_ROLE_CFG1_POLL_TIMEOUT1000 + +#define DRV_NAME "intel_cht_usb_mux" Dashes, please, if possible. Or are there perhaps a lot of precedent for other cherrytrail driver names? Because consistency across the tree is a tad more important than my issues with underscores... The Cherry Trail code uses _ for device-names everywhere, so lets keep this one as is. + +struct intel_cht_usb_mux { + struct mutex cfg0_lock; + void __iomem *base; + struct extcon_dev *vbus_extcon; +
Re: [PATCH v2 1/1] usb:xhci: update condition to select bus->sysdev from parent device
On 24.08.2017 05:53, Thang Q. Nguyen wrote: On Sat, Aug 19, 2017 at 10:43 AM, Thang Q. Nguyen wrote: From: "Thang Q. Nguyen" For commit 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration"), sysdev points to devices known to the system firmware or hardware for DMA parameters. However, the parent of the system firmware/hardware device checking logic does not work in ACPI boot mode. This patch updates the formulation to check this case in both DT and ACPI. Signed-off-by: Tung Nguyen Signed-off-by: Thang Q. Nguyen --- Change since v1: - Update codes to work with kernel 4.13-rc5 --- drivers/usb/host/xhci-plat.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b..1bb9729 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -187,7 +187,10 @@ static int xhci_plat_probe(struct platform_device *pdev) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) + if (sysdev->parent && !is_of_node(sysdev->fwnode) && + !is_acpi_device_node(sysdev->fwnode) && + (is_of_node(sysdev->parent->fwnode) || +is_acpi_device_node(sysdev->parent->fwnode))) sysdev = sysdev->parent; #ifdef CONFIG_PCI else if (sysdev->parent && sysdev->parent->parent && -- 1.8.3.1 Is there any comment about the patch? With current kernel (4.13.0-rc6), booting the Linux using ACPI boot, kernel is crashed right after probing the USB DWC3 driver with the following messages: That should work, but the if statements are getting quite elaborate. How about replacing it all with: - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; -#ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && -sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; -#endif + + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; + #ifdef CONFIG_PCI + else if (sysdev->bus == &pci_bus_type) + break; + #endif + } + + if (!sysdev) + sysdev = &pdev->dev Does that work for you? -Mathias -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On 31.08.2017 20:54, Adam Wallis wrote: Currently, xhci_plat is not set up properly when the parent device is an ACPI node. The conditions that xhci_plat_probe should satisfy are 1. xhci_plat comes from firmware 2. xhci_plat is child of a device from firmware (dwc3-plat) 3. xhci_plat is grandchild of a pci device (dwc3-pci) Case 2 is covered when the child is an OF node (by checking sysdev->parent->of_node), however, an ACPI parent will return NULL in the of_node check and will thus not result in sysdev being set to sysdev->parent [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 This change adds a check for ACPI to completely allow for condition 2. This is done by first checking if the parent node is of type ACPI (e.g., dwc3-plat) and set sysdev to sysdev->parent if either of the two following conditions are met: 1: If fwnode is empty (in the case that platform_device_add_properties was not called on the allocated platform device) 2: fwnode exists but is not of type ACPI (this would happen if platform_device_add_properties was called on the allocated device. Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) Cc: sta...@vger.kernel.org # 4.12.x Signed-off-by: Adam Wallis --- Thang Q. Nguyen (in CC) proposed a patch for the same issue earlier, I just replied to his patch with a new proposal (added you to CC) Basically replace it all with: - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; -#ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && -sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; -#endif + + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; + #ifdef CONFIG_PCI + else if (sysdev->bus == &pci_bus_type) + break; + #endif + } + + if (!sysdev) + sysdev = &pdev->dev; -Mathias -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[no subject]
9634556022.doc Description: MS-Word document
[PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
Currently, xhci_plat is not set up properly when the parent device is an ACPI node. The conditions that xhci_plat_probe should satisfy are 1. xhci_plat comes from firmware 2. xhci_plat is child of a device from firmware (dwc3-plat) 3. xhci_plat is grandchild of a pci device (dwc3-pci) Case 2 is covered when the child is an OF node (by checking sysdev->parent->of_node), however, an ACPI parent will return NULL in the of_node check and will thus not result in sysdev being set to sysdev->parent [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 This change adds a check for ACPI to completely allow for condition 2. This is done by first checking if the parent node is of type ACPI (e.g., dwc3-plat) and set sysdev to sysdev->parent if either of the two following conditions are met: 1: If fwnode is empty (in the case that platform_device_add_properties was not called on the allocated platform device) 2: fwnode exists but is not of type ACPI (this would happen if platform_device_add_properties was called on the allocated device. Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) Cc: sta...@vger.kernel.org #4.12.x Cc: sta...@vger.kernel.org #4.13.x Signed-off-by: Adam Wallis --- Changes in v2: Incorporate the simplified fwnode check as suggested by Mathias drivers/usb/host/xhci-plat.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b..2087407 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -186,14 +186,18 @@ static int xhci_plat_probe(struct platform_device *pdev) * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; #ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && -sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; + else if (sysdev->bus == &pci_bus_type) + break; #endif + } + + if (!sysdev) + sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On Tue, Sep 05, 2017 at 09:57:29AM -0400, Adam Wallis wrote: > Currently, xhci_plat is not set up properly when the parent device is an > ACPI node. The conditions that xhci_plat_probe should satisfy are > > 1. xhci_plat comes from firmware > 2. xhci_plat is child of a device from firmware (dwc3-plat) > 3. xhci_plat is grandchild of a pci device (dwc3-pci) > > Case 2 is covered when the child is an OF node (by checking > sysdev->parent->of_node), however, an ACPI parent will return NULL in > the of_node check and will thus not result in sysdev being set to > sysdev->parent > > [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 > > This change adds a check for ACPI to completely allow for condition 2. > This is done by first checking if the parent node is of type ACPI (e.g., > dwc3-plat) and set sysdev to sysdev->parent if either of the two > following conditions are met: > > 1: If fwnode is empty (in the case that platform_device_add_properties > was not called on the allocated platform device) > 2: fwnode exists but is not of type ACPI (this would happen if > platform_device_add_properties was called on the allocated device. > Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) > > Cc: sta...@vger.kernel.org #4.12.x > Cc: sta...@vger.kernel.org #4.13.x What bug is this fixing that needs to go into the stable kernel trees? Is this a regression, or a new feature for those versions? thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] USB: musb: PM fixes
These patches fix a couple of bugs introduced by the recent runtime-PM work. Note that the external abort was due to the irq work never being flushed on suspend, and that we may need similar fixes for the delayed reset and resume work which are likewise never cancelled on suspend. Johan Johan Hovold (2): USB: musb: fix late external abort on suspend USB: musb: fix session-bit runtime-PM quirk drivers/usb/musb/musb_core.c | 20 +++- 1 file changed, 15 insertions(+), 5 deletions(-) -- 2.14.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] USB: musb: fix late external abort on suspend
The musb delayed irq work was never flushed on suspend, something which since 4.9 can lead to an external abort if the work is scheduled after the grandparent's clock has been disabled: PM: Suspending system (mem) PM: suspend of devices complete after 125.224 msecs PM: suspend devices took 0.132 seconds PM: late suspend of devices complete after 7.423 msecs PM: noirq suspend of devices complete after 7.083 msecs suspend debug: Waiting for 5 second(s). Unhandled fault: external abort on non-linefetch (0x1008) at 0xd0262c60 ... [] (musb_default_readb) from [] (musb_irq_work+0x48/0x220) [] (musb_irq_work) from [] (process_one_work+0x1f4/0x758) [] (process_one_work) from [] (worker_thread+0x54/0x514) [] (worker_thread) from [] (kthread+0x128/0x158) [] (kthread) from [] (ret_from_fork+0x14/0x24) Commit 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") started scheduling musb_irq_work with a delay of up to a second and with retries thereby making this easy to trigger, for example, by suspending shortly after a disconnect. Note that the session flag is cleared and runtime-PM usage count balanced after having cancelled the irq work instead of always rescheduling on resume as the latter would have broken PM for host mode, which always has the session bit set. Fixes: 550a7375fe72 ("USB: Add MUSB and TUSB support") Fixes: 467d5c980709 ("usb: musb: Implement session bit based runtime PM for musb-core") Fixes: 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") Cc: stable # 4.9 Cc: Felipe Balbi Cc: Tony Lindgren Signed-off-by: Johan Hovold --- drivers/usb/musb/musb_core.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b67692857daf..8645432337cb 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2681,8 +2681,18 @@ static int musb_suspend(struct device *dev) musb_platform_disable(musb); musb_disable_interrupts(musb); - if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) + + cancel_delayed_work_sync(&musb->irq_work); + + if (!(musb->io.quirks & MUSB_PRESERVE_SESSION)) { musb_writeb(musb->mregs, MUSB_DEVCTL, 0); + + if (musb->session) { + musb->session = false; + pm_runtime_put_noidle(musb->controller); + } + } + WARN_ON(!list_empty(&musb->pending_list)); spin_lock_irqsave(&musb->lock, flags); -- 2.14.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] USB: musb: fix session-bit runtime-PM quirk
The current session-bit quirk implementation does not prevent the retry counter from underflowing, something which could break runtime PM and keep the device active for a very long time (about 2^32 seconds) after a disconnect. This notably breaks the B-device timeout case, but could potentially cause problems also when the controller is operating as an A-device. Fixes: 2bff3916fda9 ("usb: musb: Fix PM for hub disconnect") Cc: stable # 4.9 Cc: Tony Lindgren Signed-off-by: Johan Hovold --- drivers/usb/musb/musb_core.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8645432337cb..8c40fc555eb0 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1861,22 +1861,22 @@ static void musb_pm_runtime_check_session(struct musb *musb) MUSB_DEVCTL_HR; switch (devctl & ~s) { case MUSB_QUIRK_B_INVALID_VBUS_91: - if (musb->quirk_retries--) { + if (musb->quirk_retries) { musb_dbg(musb, "Poll devctl on invalid vbus, assume no session"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } /* fall through */ case MUSB_QUIRK_A_DISCONNECT_19: - if (musb->quirk_retries--) { + if (musb->quirk_retries) { musb_dbg(musb, "Poll devctl on possible host mode disconnect"); schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); - + musb->quirk_retries--; return; } if (!musb->session) -- 2.14.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On 9/5/2017 10:16 AM, Greg Kroah-Hartman wrote: > On Tue, Sep 05, 2017 at 09:57:29AM -0400, Adam Wallis wrote: >> Currently, xhci_plat is not set up properly when the parent device is an >> ACPI node. The conditions that xhci_plat_probe should satisfy are >> >> 1. xhci_plat comes from firmware >> 2. xhci_plat is child of a device from firmware (dwc3-plat) >> 3. xhci_plat is grandchild of a pci device (dwc3-pci) >> >> Case 2 is covered when the child is an OF node (by checking >> sysdev->parent->of_node), however, an ACPI parent will return NULL in >> the of_node check and will thus not result in sysdev being set to >> sysdev->parent >> >> [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 >> >> This change adds a check for ACPI to completely allow for condition 2. >> This is done by first checking if the parent node is of type ACPI (e.g., >> dwc3-plat) and set sysdev to sysdev->parent if either of the two >> following conditions are met: >> >> 1: If fwnode is empty (in the case that platform_device_add_properties >> was not called on the allocated platform device) >> 2: fwnode exists but is not of type ACPI (this would happen if >> platform_device_add_properties was called on the allocated device. >> Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) >> >> Cc: sta...@vger.kernel.org #4.12.x >> Cc: sta...@vger.kernel.org #4.13.x > > What bug is this fixing that needs to go into the stable kernel trees? > Is this a regression, or a new feature for those versions? > Greg The following patch 4c39d4b949d36f usb: xhci: use bus->sysdev for DMA configuration provided an incomplete check for all firmware nodes (only checked for PCI and OF case, but not the ACPI case). This bug affects the 4.12 and 4.13 kernels. Adam > thanks, > > greg k-h > > ___ > linux-arm-kernel mailing list > linux-arm-ker...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > -- Adam Wallis Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 0/6] usb: xhci: Handle USB transaction error on address command
On 01.09.2017 04:41, Lu Baolu wrote: Hi Mathias, Xhci driver handles USB transaction errors on transfer events, but transaction errors are possible on address device command completion events as well. The xHCI specification (section 4.6.5) says: A USB Transaction Error Completion Code for an Address Device Command may be due to a Stall response from a device. Software should issue a Disable Slot Command for the Device Slot then an Enable Slot Command to recover from this error. The related discussion threads can be found through below links. http://marc.info/?l=linux-usb&m=149362010728921&w=2 http://marc.info/?l=linux-usb&m=149252752825755&w=2 This patch set includes some fixes in xhci_disable_slot() as well which will be used to handle USB transaction error on address command. This patch set is based on the top of for-usb-next branch in your xhci tree. Best regards, Lu Baolu Looks good, applying Thanks -Mathias -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] usb: gadget: dummy: fix nonsensical comparisons
On Tue, 5 Sep 2017, Arnd Bergmann wrote: > gcc-8 points out two comparisons that are clearly bogus > and almost certainly not what the author intended to write: > > drivers/usb/gadget/udc/dummy_hcd.c: In function 'set_link_state_by_speed': > drivers/usb/gadget/udc/dummy_hcd.c:379:31: error: bitwise comparison always > evaluates to false [-Werror=tautological-compare] > USB_PORT_STAT_ENABLE) == 1 && >^~ > drivers/usb/gadget/udc/dummy_hcd.c:381:25: error: bitwise comparison always > evaluates to false [-Werror=tautological-compare] > USB_SS_PORT_LS_U0) == 1 && > ^~ > > I looked at the code for a bit and came up with a change that makes > it look like what the author probably meant here. This makes it > look reasonable to me and to gcc, shutting up the warning. > > It does of course change behavior as the two conditions are actually > evaluated rather than being hardcoded to false, and I have made no > attempt at verifying that the changed logic makes sense in the context > of a USB HCD, so that part needs to be reviewed carefully. > > Fixes: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support") > Cc: Tatyana Brokhman > Cc: Felipe Balbi > Signed-off-by: Arnd Bergmann > --- > drivers/usb/gadget/udc/dummy_hcd.c | 8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/gadget/udc/dummy_hcd.c > b/drivers/usb/gadget/udc/dummy_hcd.c > index a030d7923d7d..54e8e37d2bc8 100644 > --- a/drivers/usb/gadget/udc/dummy_hcd.c > +++ b/drivers/usb/gadget/udc/dummy_hcd.c > @@ -376,10 +376,10 @@ static void set_link_state_by_speed(struct dummy_hcd > *dum_hcd) > dum_hcd->port_status |= > (USB_PORT_STAT_C_CONNECTION << 16); > if ((dum_hcd->port_status & > - USB_PORT_STAT_ENABLE) == 1 && > - (dum_hcd->port_status & > - USB_SS_PORT_LS_U0) == 1 && > - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) > + USB_PORT_STAT_ENABLE) == USB_PORT_STAT_ENABLE && This test can simply become (dum_hcd->port_status & USB_PORT_STAT_ENABLE), since the latter is a single bit. If you don't mind making its form different from the forms of the other two tests. Alan Stern > + (dum_hcd->port_status & > + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && > + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) > dum_hcd->active = 1; > } > } else { > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On Tue, Sep 05, 2017 at 10:25:19AM -0400, Adam Wallis wrote: > On 9/5/2017 10:16 AM, Greg Kroah-Hartman wrote: > > On Tue, Sep 05, 2017 at 09:57:29AM -0400, Adam Wallis wrote: > >> Currently, xhci_plat is not set up properly when the parent device is an > >> ACPI node. The conditions that xhci_plat_probe should satisfy are > >> > >> 1. xhci_plat comes from firmware > >> 2. xhci_plat is child of a device from firmware (dwc3-plat) > >> 3. xhci_plat is grandchild of a pci device (dwc3-pci) > >> > >> Case 2 is covered when the child is an OF node (by checking > >> sysdev->parent->of_node), however, an ACPI parent will return NULL in > >> the of_node check and will thus not result in sysdev being set to > >> sysdev->parent > >> > >> [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 > >> > >> This change adds a check for ACPI to completely allow for condition 2. > >> This is done by first checking if the parent node is of type ACPI (e.g., > >> dwc3-plat) and set sysdev to sysdev->parent if either of the two > >> following conditions are met: > >> > >> 1: If fwnode is empty (in the case that platform_device_add_properties > >> was not called on the allocated platform device) > >> 2: fwnode exists but is not of type ACPI (this would happen if > >> platform_device_add_properties was called on the allocated device. > >> Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) > >> > >> Cc: sta...@vger.kernel.org #4.12.x > >> Cc: sta...@vger.kernel.org #4.13.x > > > > What bug is this fixing that needs to go into the stable kernel trees? > > Is this a regression, or a new feature for those versions? > > > Greg > > The following patch > > 4c39d4b949d36f usb: xhci: use bus->sysdev for DMA configuration > > provided an incomplete check for all firmware nodes (only checked for PCI and > OF > case, but not the ACPI case). This bug affects the 4.12 and 4.13 kernels. What is the symptom of "incomplete check"? Something that used to work now does not? Or just that it doesn't work "correctly" and this patch resolves that issue so that new hardware can now work properly? I ask as you have read the stable kernel rules, right? thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On 9/5/2017 10:31 AM, Greg Kroah-Hartman wrote: > On Tue, Sep 05, 2017 at 10:25:19AM -0400, Adam Wallis wrote: >> On 9/5/2017 10:16 AM, Greg Kroah-Hartman wrote: >>> On Tue, Sep 05, 2017 at 09:57:29AM -0400, Adam Wallis wrote: Currently, xhci_plat is not set up properly when the parent device is an ACPI node. The conditions that xhci_plat_probe should satisfy are 1. xhci_plat comes from firmware 2. xhci_plat is child of a device from firmware (dwc3-plat) 3. xhci_plat is grandchild of a pci device (dwc3-pci) Case 2 is covered when the child is an OF node (by checking sysdev->parent->of_node), however, an ACPI parent will return NULL in the of_node check and will thus not result in sysdev being set to sysdev->parent [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 This change adds a check for ACPI to completely allow for condition 2. This is done by first checking if the parent node is of type ACPI (e.g., dwc3-plat) and set sysdev to sysdev->parent if either of the two following conditions are met: 1: If fwnode is empty (in the case that platform_device_add_properties was not called on the allocated platform device) 2: fwnode exists but is not of type ACPI (this would happen if platform_device_add_properties was called on the allocated device. Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) Cc: sta...@vger.kernel.org #4.12.x Cc: sta...@vger.kernel.org #4.13.x >>> >>> What bug is this fixing that needs to go into the stable kernel trees? >>> Is this a regression, or a new feature for those versions? >>> >> Greg >> >> The following patch >> >> 4c39d4b949d36f usb: xhci: use bus->sysdev for DMA configuration >> >> provided an incomplete check for all firmware nodes (only checked for PCI >> and OF >> case, but not the ACPI case). This bug affects the 4.12 and 4.13 kernels. > > What is the symptom of "incomplete check"? Something that used to work > now does not? Or just that it doesn't work "correctly" and this patch > resolves that issue so that new hardware can now work properly? Greg, the change I reference above broke behavior that previously worked. Previously, it was possible to have a an ACPI host driver (e.g., dwc3) that created a platform xhci device as a child. The above change removed the ability to have a parent ACPI device to the platform xhci platform device (so drivers like dwc3 host do not work with ACPI now in 4.12/4.13) I ask > as you have read the stable kernel rules, right? I have read the rules. Are you asking for me to update my sign-off area with the fix commit information? > > thanks, > > greg k-h > Thank you for your help Adam -- Adam Wallis Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] usb: host: xhci-plat: allow sysdev to inherit from ACPI
On Tue, Sep 05, 2017 at 10:38:03AM -0400, Adam Wallis wrote: > On 9/5/2017 10:31 AM, Greg Kroah-Hartman wrote: > > On Tue, Sep 05, 2017 at 10:25:19AM -0400, Adam Wallis wrote: > >> On 9/5/2017 10:16 AM, Greg Kroah-Hartman wrote: > >>> On Tue, Sep 05, 2017 at 09:57:29AM -0400, Adam Wallis wrote: > Currently, xhci_plat is not set up properly when the parent device is an > ACPI node. The conditions that xhci_plat_probe should satisfy are > > 1. xhci_plat comes from firmware > 2. xhci_plat is child of a device from firmware (dwc3-plat) > 3. xhci_plat is grandchild of a pci device (dwc3-pci) > > Case 2 is covered when the child is an OF node (by checking > sysdev->parent->of_node), however, an ACPI parent will return NULL in > the of_node check and will thus not result in sysdev being set to > sysdev->parent > > [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 > > This change adds a check for ACPI to completely allow for condition 2. > This is done by first checking if the parent node is of type ACPI (e.g., > dwc3-plat) and set sysdev to sysdev->parent if either of the two > following conditions are met: > > 1: If fwnode is empty (in the case that platform_device_add_properties > was not called on the allocated platform device) > 2: fwnode exists but is not of type ACPI (this would happen if > platform_device_add_properties was called on the allocated device. > Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) > > Cc: sta...@vger.kernel.org #4.12.x > Cc: sta...@vger.kernel.org #4.13.x > >>> > >>> What bug is this fixing that needs to go into the stable kernel trees? > >>> Is this a regression, or a new feature for those versions? > >>> > >> Greg > >> > >> The following patch > >> > >> 4c39d4b949d36f usb: xhci: use bus->sysdev for DMA configuration > >> > >> provided an incomplete check for all firmware nodes (only checked for PCI > >> and OF > >> case, but not the ACPI case). This bug affects the 4.12 and 4.13 kernels. > > > > What is the symptom of "incomplete check"? Something that used to work > > now does not? Or just that it doesn't work "correctly" and this patch > > resolves that issue so that new hardware can now work properly? > Greg, the change I reference above broke behavior that previously worked. > Previously, it was possible to have a an ACPI host driver (e.g., dwc3) that > created a platform xhci device as a child. The above change removed the > ability > to have a parent ACPI device to the platform xhci platform device (so drivers > like dwc3 host do not work with ACPI now in 4.12/4.13) Ok, then provide this information with a "Fixes:" tag please. thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V3] usb: host: xhci-plat: allow sysdev to inherit from ACPI
Commit 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration") updated the method determining DMA for XHCI from sysdev. However, this patch broke the ability to enumerate the FWNODE from parent ACPI devices from the child plat XHCI device. Currently, xhci_plat is not set up properly when the parent device is an ACPI node. The conditions that xhci_plat_probe should satisfy are 1. xhci_plat comes from firmware 2. xhci_plat is child of a device from firmware (dwc3-plat) 3. xhci_plat is grandchild of a pci device (dwc3-pci) Case 2 is covered when the child is an OF node (by checking sysdev->parent->of_node), however, an ACPI parent will return NULL in the of_node check and will thus not result in sysdev being set to sysdev->parent [ 17.591549] xhci-hcd: probe of xhci-hcd.6.auto failed with error -5 This change adds a check for ACPI to completely allow for condition 2. This is done by first checking if the parent node is of type ACPI (e.g., dwc3-plat) and set sysdev to sysdev->parent if either of the two following conditions are met: 1: If fwnode is empty (in the case that platform_device_add_properties was not called on the allocated platform device) 2: fwnode exists but is not of type ACPI (this would happen if platform_device_add_properties was called on the allocated device. Instead of type FWNODE_ACPI, you would end up with FWNODE_PDATA) Cc: sta...@vger.kernel.org #4.12.x Cc: sta...@vger.kernel.org #4.13.x Fixes: 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration") Signed-off-by: Adam Wallis --- Changes in v3: Add "fixes" to commit message per greg k-h Changes in v2: Incorporate the simplified fwnode check as suggested by Mathias drivers/usb/host/xhci-plat.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b..2087407 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -186,14 +186,18 @@ static int xhci_plat_probe(struct platform_device *pdev) * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; #ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && -sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; + else if (sysdev->bus == &pci_bus_type) + break; #endif + } + + if (!sysdev) + sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 24/25 v2] net/cdc_ncm: Replace tasklet with softirq hrtimer
From: Thomas Gleixner The bh tasklet is used in invoke the hrtimer (cdc_ncm_tx_timer_cb) in softirq context. This can be also achieved without the tasklet but with CLOCK_MONOTONIC_SOFT as hrtimer base. Signed-off-by: Thomas Gleixner Signed-off-by: Anna-Maria Gleixner Cc: Oliver Neukum Cc: Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org Cc: net...@vger.kernel.org Acked-by: Greg Kroah-Hartman [bigeasy: using usb_get_intfdata() as suggested by Bjørn Mork] Signed-off-by: Sebastian Andrzej Siewior --- On 2017-08-31 15:57:04 [+0200], Bjørn Mork wrote: > I believe the struct usbnet pointer is redundant. We already have lots > of pointers back and forth here. This should work, but is not tested: > > struct usbnet *dev = usb_get_intfdata(ctx->control): I think so, too. Still untested as I don't have a working gadget around. v1…v2: Updated as suggested by Bjørn and added Greg's Acked-by. drivers/net/usb/cdc_ncm.c | 36 +++- include/linux/usb/cdc_ncm.h | 1 - 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 8f572b9f3625..42f7bd90e6a4 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -61,7 +61,6 @@ static bool prefer_mbim; module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions"); -static void cdc_ncm_txpath_bh(unsigned long param); static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); static struct usb_driver cdc_ncm_driver; @@ -777,10 +776,8 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ if (!ctx) return -ENOMEM; - hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&ctx->tx_timer, CLOCK_MONOTONIC_SOFT, HRTIMER_MODE_REL); ctx->tx_timer.function = &cdc_ncm_tx_timer_cb; - ctx->bh.data = (unsigned long)dev; - ctx->bh.func = cdc_ncm_txpath_bh; atomic_set(&ctx->stop, 0); spin_lock_init(&ctx->mtx); @@ -967,10 +964,7 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) atomic_set(&ctx->stop, 1); - if (hrtimer_active(&ctx->tx_timer)) - hrtimer_cancel(&ctx->tx_timer); - - tasklet_kill(&ctx->bh); + hrtimer_cancel(&ctx->tx_timer); /* handle devices with combined control and data interface */ if (ctx->control == ctx->data) @@ -1348,20 +1342,9 @@ static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx) HRTIMER_MODE_REL); } -static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer) +static void cdc_ncm_txpath_bh(struct cdc_ncm_ctx *ctx) { - struct cdc_ncm_ctx *ctx = - container_of(timer, struct cdc_ncm_ctx, tx_timer); - - if (!atomic_read(&ctx->stop)) - tasklet_schedule(&ctx->bh); - return HRTIMER_NORESTART; -} - -static void cdc_ncm_txpath_bh(unsigned long param) -{ - struct usbnet *dev = (struct usbnet *)param; - struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; + struct usbnet *dev = usb_get_intfdata(ctx->control); spin_lock_bh(&ctx->mtx); if (ctx->tx_timer_pending != 0) { @@ -1379,6 +1362,17 @@ static void cdc_ncm_txpath_bh(unsigned long param) } } +static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *timer) +{ + struct cdc_ncm_ctx *ctx = + container_of(timer, struct cdc_ncm_ctx, tx_timer); + + if (!atomic_read(&ctx->stop)) + cdc_ncm_txpath_bh(ctx); + + return HRTIMER_NORESTART; +} + struct sk_buff * cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h index 1a59699cf82a..62b506fddf8d 100644 --- a/include/linux/usb/cdc_ncm.h +++ b/include/linux/usb/cdc_ncm.h @@ -92,7 +92,6 @@ struct cdc_ncm_ctx { struct usb_cdc_ncm_ntb_parameters ncm_parm; struct hrtimer tx_timer; - struct tasklet_struct bh; const struct usb_cdc_ncm_desc *func_desc; const struct usb_cdc_mbim_desc *mbim_desc; -- 2.14.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 03/11] mux: core: Add usb.h header with MUX_USB_* and and MUX_TYPEC_* state constants
Add MUX_USB_* and MUX_TYPEC_* state constant defines, which can be used by USB device/host, resp. Type-C polarity/role/altmode mux drivers and consumers to ensure that they agree on the meaning of the mux_control_select() state argument. Signed-off-by: Hans de Goede --- Changes in v2: -Start numbering of defines at 0 not 1 -Use a new usb.h header, rather then adding these to consumer.h -Add separate MUX_USB_* and MUX_TYPEC_* defines --- include/linux/mux/usb.h | 32 1 file changed, 32 insertions(+) create mode 100644 include/linux/mux/usb.h diff --git a/include/linux/mux/usb.h b/include/linux/mux/usb.h new file mode 100644 index ..44df5eca5256 --- /dev/null +++ b/include/linux/mux/usb.h @@ -0,0 +1,32 @@ +/* + * mux/usb.h - definitions for USB multiplexers + * + * Copyright (C) 2017 Hans de Goede + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _LINUX_MUX_USB_H +#define _LINUX_MUX_USB_H + +/* Mux state values for USB device/host role muxes */ +#define MUX_USB_DEVICE (0) /* USB device mode */ +#define MUX_USB_HOST (1) /* USB host mode */ +#define MUX_USB_STATES (2) + +/* + * Mux state values for Type-C polarity/role/altmode muxes. + * + * MUX_TYPEC_POLARITY_INV may be or-ed together with any other mux-state as + * inverted-polarity (Type-C plugged in upside down) can happen with any + * other mux-state. + */ +#define MUX_TYPEC_POLARITY_INV BIT(0) /* Polarity inverted bit */ +#define MUX_TYPEC_DEVICE (0 << 1) /* USB device mode */ +#define MUX_TYPEC_HOST (1 << 1) /* USB host mode */ +#define MUX_TYPEC_HOST_AND_DP_SRC (2 << 1) /* USB host + 2 lanes DP src */ +#define MUX_TYPEC_DP_SRC (3 << 1) /* 4 lanes Display Port src */ +#define MUX_TYPEC_STATES (4 << 1) + +#endif /* _LINUX_MUX_TYPEC_H */ -- 2.13.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 01/11] mux: core: Add of_mux_control_get helper function
Currently the mux_control_get implementation only deals with getting mux controllers on DT platforms. This commit renames the current implementation to of_mux_control_get to reflect this and makes mux_control_get a wrapper around of_mux_control_get. This is a preparation patch for adding support for getting muxes on non DT platforms. Signed-off-by: Hans de Goede --- drivers/mux/core.c | 26 ++ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/mux/core.c b/drivers/mux/core.c index 6e5cf9d9cd99..99d29f982c0e 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c @@ -423,14 +423,8 @@ static struct mux_chip *of_find_mux_chip_by_node(struct device_node *np) return dev ? to_mux_chip(dev) : NULL; } -/** - * mux_control_get() - Get the mux-control for a device. - * @dev: The device that needs a mux-control. - * @mux_name: The name identifying the mux-control. - * - * Return: A pointer to the mux-control, or an ERR_PTR with a negative errno. - */ -struct mux_control *mux_control_get(struct device *dev, const char *mux_name) +static struct mux_control *of_mux_control_get(struct device *dev, + const char *mux_name) { struct device_node *np = dev->of_node; struct of_phandle_args args; @@ -484,6 +478,22 @@ struct mux_control *mux_control_get(struct device *dev, const char *mux_name) return &mux_chip->mux[controller]; } + +/** + * mux_control_get() - Get the mux-control for a device. + * @dev: The device that needs a mux-control. + * @mux_name: The name identifying the mux-control. + * + * Return: A pointer to the mux-control, or an ERR_PTR with a negative errno. + */ +struct mux_control *mux_control_get(struct device *dev, const char *mux_name) +{ + /* look up via DT first */ + if (IS_ENABLED(CONFIG_OF) && dev->of_node) + return of_mux_control_get(dev, mux_name); + + return ERR_PTR(-ENODEV); +} EXPORT_SYMBOL_GPL(mux_control_get); /** -- 2.13.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 11/11] platform/x86: intel_cht_int33fe: Add mux mappings for the Type-C port
We need to add mappings for the mux subsys to be able to find the muxes for the fusb302 driver to be able to control the PI3USB30532 Type-C mux and the device/host mux integrated in the CHT SoC. Signed-off-by: Hans de Goede Acked-by: Andy Shevchenko --- drivers/platform/x86/Kconfig | 1 + drivers/platform/x86/intel_cht_int33fe.c | 23 +++ 2 files changed, 24 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 312d2472b8b3..830ff8d0a1eb 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -794,6 +794,7 @@ config ACPI_CMPC config INTEL_CHT_INT33FE tristate "Intel Cherry Trail ACPI INT33FE Driver" depends on X86 && ACPI && I2C && REGULATOR + select MULTIPLEXER ---help--- This driver add support for the INT33FE ACPI device found on some Intel Cherry Trail devices. diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index b2925d996613..89ba510dac78 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,19 @@ struct cht_int33fe_data { struct i2c_client *pi3usb30532; }; +static struct mux_lookup cht_int33fe_mux_lookup[] = { + { + .provider = "i2c-pi3usb30532", + .dev_id = "i2c-fusb302", + .mux_name = "type-c-mode-mux", + }, + { + .provider = "intel_cht_usb_mux", + .dev_id = "i2c-fusb302", + .mux_name = "usb-role-mux", + }, +}; + /* * Grrr I severly dislike buggy BIOS-es. At least one BIOS enumerates * the max17047 both through the INT33FE ACPI device (it is right there @@ -177,6 +191,9 @@ static int cht_int33fe_probe(struct i2c_client *client) board_info.properties = fusb302_props; board_info.irq = fusb302_irq; + mux_add_table(cht_int33fe_mux_lookup, + ARRAY_SIZE(cht_int33fe_mux_lookup)); + data->fusb302 = i2c_acpi_new_device(dev, 2, &board_info); if (!data->fusb302) goto out_unregister_max17047; @@ -200,6 +217,9 @@ static int cht_int33fe_probe(struct i2c_client *client) if (data->max17047) i2c_unregister_device(data->max17047); + mux_remove_table(cht_int33fe_mux_lookup, + ARRAY_SIZE(cht_int33fe_mux_lookup)); + return -EPROBE_DEFER; /* Wait for the i2c-adapter to load */ } @@ -212,6 +232,9 @@ static int cht_int33fe_remove(struct i2c_client *i2c) if (data->max17047) i2c_unregister_device(data->max17047); + mux_remove_table(cht_int33fe_mux_lookup, + ARRAY_SIZE(cht_int33fe_mux_lookup)); + return 0; } -- 2.13.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 07/11] extcon: intel-int3496: Add support for controlling the USB-role mux
Cherry Trail SoCs have a built-in USB-role mux for switching between the host and device controllers, rather then using an external mux controller by a GPIO. There is a driver using the mux-subsys to control this mux, this commit adds support to the intel-int3496 driver to get a mux_controller handle for the mux and set the mux through the mux-subsys rather then through a GPIO. Signed-off-by: Hans de Goede --- Changes in v2: -Drop || COMPILE_TEST from Kconfig deepnds on, as we will now fail to compile on !X86 -Minor code style tweaks --- drivers/extcon/Kconfig| 3 +- drivers/extcon/extcon-intel-int3496.c | 59 +++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index a7bca4207f44..168f9d710ea0 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig @@ -44,7 +44,8 @@ config EXTCON_GPIO config EXTCON_INTEL_INT3496 tristate "Intel INT3496 ACPI device extcon driver" - depends on GPIOLIB && ACPI && (X86 || COMPILE_TEST) + depends on GPIOLIB && ACPI && X86 + select MULTIPLEXER help Say Y here to enable extcon support for USB OTG ports controlled by an Intel INT3496 ACPI device. diff --git a/drivers/extcon/extcon-intel-int3496.c b/drivers/extcon/extcon-intel-int3496.c index 1a45e745717d..3c8e17449c12 100644 --- a/drivers/extcon/extcon-intel-int3496.c +++ b/drivers/extcon/extcon-intel-int3496.c @@ -23,8 +23,13 @@ #include #include #include +#include +#include #include +#include +#include + #define INT3496_GPIO_USB_ID0 #define INT3496_GPIO_VBUS_EN 1 #define INT3496_GPIO_USB_MUX 2 @@ -37,6 +42,8 @@ struct int3496_data { struct gpio_desc *gpio_usb_id; struct gpio_desc *gpio_vbus_en; struct gpio_desc *gpio_usb_mux; + struct mux_control *usb_mux; + bool usb_mux_set; int usb_id_irq; }; @@ -56,11 +63,32 @@ static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = { { }, }; +static struct mux_lookup acpi_int3496_cht_mux_lookup[] = { + { + .provider = "intel_cht_usb_mux", + .dev_id = "INT3496:00", + .mux_name = "usb-role-mux", + }, +}; + +#define ICPU(model){ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } + +static const struct x86_cpu_id cht_cpu_ids[] = { + ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */ + {} +}; + +static bool int3496_soc_has_mux(void) +{ + return x86_match_cpu(cht_cpu_ids); +} + static void int3496_do_usb_id(struct work_struct *work) { struct int3496_data *data = container_of(work, struct int3496_data, work.work); int id = gpiod_get_value_cansleep(data->gpio_usb_id); + int ret; /* id == 1: PERIPHERAL, id == 0: HOST */ dev_dbg(data->dev, "Connected %s cable\n", id ? "PERIPHERAL" : "HOST"); @@ -72,6 +100,22 @@ static void int3496_do_usb_id(struct work_struct *work) if (!IS_ERR(data->gpio_usb_mux)) gpiod_direction_output(data->gpio_usb_mux, id); + if (data->usb_mux) { + /* +* The mux framework expects multiple competing users, we must +* release our previous setting before applying the new one. +*/ + if (data->usb_mux_set) + mux_control_deselect(data->usb_mux); + + ret = mux_control_select(data->usb_mux, +id ? MUX_USB_DEVICE : MUX_USB_HOST); + if (ret) + dev_err(data->dev, "Error setting mux: %d\n", ret); + + data->usb_mux_set = ret == 0; + } + if (!IS_ERR(data->gpio_vbus_en)) gpiod_direction_output(data->gpio_vbus_en, !id); @@ -107,6 +151,21 @@ static int int3496_probe(struct platform_device *pdev) data->dev = dev; INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); + if (int3496_soc_has_mux()) { + mux_add_table(acpi_int3496_cht_mux_lookup, + ARRAY_SIZE(acpi_int3496_cht_mux_lookup)); + data->usb_mux = devm_mux_control_get(dev, "usb-role-mux"); + /* Doing this here keeps our error handling clean. */ + mux_remove_table(acpi_int3496_cht_mux_lookup, +ARRAY_SIZE(acpi_int3496_cht_mux_lookup)); + if (IS_ERR(data->usb_mux)) { + ret = PTR_ERR(data->usb_mux); + if (ret != -EPROBE_DEFER) + dev_err(dev, "can't get mux: %d\n", ret); + return ret; + } + } + data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN); if (IS_ERR(data->gpio_usb_id)) { ret = PTR_ERR(data->gpio_usb_id); -- 2.13.5 -- To unsubscribe from this list: send the li
[PATCH v2 10/11] staging: typec: fusb302: Hook up mux support using tcpc_gen_mux support
Add mux support to the fusb302 driver, call devm_tcpc_gen_mux_create() to let the generic tcpc_mux_dev code create a tcpc_mux_dev for us. Also document the mux-names used by the generic tcpc_mux_dev code in our devicetree bindings. Cc: Rob Herring Cc: Mark Rutland Cc: devicet...@vger.kernel.org Signed-off-by: Hans de Goede --- Documentation/devicetree/bindings/usb/fcs,fusb302.txt | 3 +++ drivers/staging/typec/fusb302/fusb302.c | 11 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/fcs,fusb302.txt b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt index 472facfa5a71..63d639eadacd 100644 --- a/Documentation/devicetree/bindings/usb/fcs,fusb302.txt +++ b/Documentation/devicetree/bindings/usb/fcs,fusb302.txt @@ -6,6 +6,9 @@ Required properties : - interrupts : Interrupt specifier Optional properties : +- mux-controls : List of mux-ctrl-specifiers containing 1 or 2 muxes +- mux-names : "type-c-mode-mux" when using 1 mux, or + "type-c-mode-mux", "usb-role-mux" when using 2 muxes - fcs,max-sink-microvolt : Maximum voltage to negotiate when configured as sink - fcs,max-sink-microamp : Maximum current to negotiate when configured as sink - fcs,max-sink-microwatt : Maximum power to negotiate when configured as sink diff --git a/drivers/staging/typec/fusb302/fusb302.c b/drivers/staging/typec/fusb302/fusb302.c index cf6355f59cd9..00d045d0246b 100644 --- a/drivers/staging/typec/fusb302/fusb302.c +++ b/drivers/staging/typec/fusb302/fusb302.c @@ -1259,7 +1259,6 @@ static void init_tcpc_dev(struct tcpc_dev *fusb302_tcpc_dev) fusb302_tcpc_dev->set_roles = tcpm_set_roles; fusb302_tcpc_dev->start_drp_toggling = tcpm_start_drp_toggling; fusb302_tcpc_dev->pd_transmit = tcpm_pd_transmit; - fusb302_tcpc_dev->mux = NULL; } static const char * const cc_polarity_name[] = { @@ -1817,6 +1816,16 @@ static int fusb302_probe(struct i2c_client *client, return -EPROBE_DEFER; } + chip->tcpc_dev.mux = devm_tcpc_gen_mux_create(dev); + if (IS_ERR(chip->tcpc_dev.mux)) { + ret = PTR_ERR(chip->tcpc_dev.mux); + /* Use of a mux is optional (for now?), ignore -ENODEV errors */ + if (ret == -ENODEV) + chip->tcpc_dev.mux = NULL; + else + return ret; + } + cfg.drv_data = chip; chip->psy = devm_power_supply_register(dev, &fusb302_psy_desc, &cfg); if (IS_ERR(chip->psy)) { -- 2.13.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 09/11] staging: typec: Add Generic TCPC mux driver using the mux subsys
So far the mux functionality of the tcpm code has not been hooked up in any tcpc drivers. This commit adds a generic TCPC mux driver using the mux subsys, which tcpc drivers can use to provide mux functionality in cases where an external my is used. Signed-off-by: Hans de Goede --- drivers/staging/typec/Makefile | 2 +- drivers/staging/typec/tcpc_gen_mux.c | 131 +++ drivers/staging/typec/tcpm.h | 2 + 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 drivers/staging/typec/tcpc_gen_mux.c diff --git a/drivers/staging/typec/Makefile b/drivers/staging/typec/Makefile index 30a7e29cbc9e..623d78114ee3 100644 --- a/drivers/staging/typec/Makefile +++ b/drivers/staging/typec/Makefile @@ -1,3 +1,3 @@ -obj-$(CONFIG_TYPEC_TCPM) += tcpm.o +obj-$(CONFIG_TYPEC_TCPM) += tcpm.o tcpc_gen_mux.o obj-$(CONFIG_TYPEC_TCPCI) += tcpci.o obj-y += fusb302/ diff --git a/drivers/staging/typec/tcpc_gen_mux.c b/drivers/staging/typec/tcpc_gen_mux.c new file mode 100644 index ..d40f9eaaddf5 --- /dev/null +++ b/drivers/staging/typec/tcpc_gen_mux.c @@ -0,0 +1,131 @@ +/* + * Generic TCPC mux driver using the mux subsys + * + * Copyright (c) 2017 Hans de Goede + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include "tcpm.h" + +struct tcpc_gen_mux_data { + struct tcpc_mux_dev mux; + struct device *dev; + struct mux_control *type_c_mode_mux; /* Type-C cross switch / mux */ + struct mux_control *usb_role_mux;/* USB Device / Host mode mux */ + bool muxes_set; +}; + +static int tcpc_gen_mux_set(struct tcpc_mux_dev *mux_dev, + enum tcpc_mux_mode mux_mode, + enum tcpc_usb_switch usb_config, + enum typec_cc_polarity polarity) +{ + struct tcpc_gen_mux_data *data = + container_of(mux_dev, struct tcpc_gen_mux_data, mux); + unsigned int typec_state = MUX_TYPEC_DEVICE; + unsigned int usb_state = MUX_USB_DEVICE; + int ret; + + /* Put the muxes back in their open (idle) state */ + if (data->muxes_set) { + mux_control_deselect(data->type_c_mode_mux); + if (data->usb_role_mux) + mux_control_deselect(data->usb_role_mux); + data->muxes_set = false; + } + + switch (mux_mode) { + case TYPEC_MUX_NONE: + /* Muxes are in their open state, done. */ + return 0; + case TYPEC_MUX_USB_DEVICE: + typec_state = MUX_TYPEC_DEVICE; + usb_state = MUX_USB_DEVICE; + break; + case TYPEC_MUX_USB_HOST: + typec_state = MUX_TYPEC_HOST; + usb_state = MUX_USB_HOST; + break; + case TYPEC_MUX_DP: + typec_state = MUX_TYPEC_DP_SRC; + break; + case TYPEC_MUX_DOCK: + typec_state = MUX_TYPEC_HOST_AND_DP_SRC; + usb_state = MUX_USB_HOST; + break; + } + + if (polarity) + typec_state |= MUX_TYPEC_POLARITY_INV; + + ret = mux_control_select(data->type_c_mode_mux, typec_state); + if (ret) { + dev_err(data->dev, "Error setting Type-C mode mux: %d\n", ret); + return ret; + } + + if (!data->usb_role_mux) + goto out; + + ret = mux_control_select(data->usb_role_mux, usb_state); + if (ret) { + dev_err(data->dev, "Error setting USB role mux: %d\n", ret); + mux_control_deselect(data->type_c_mode_mux); + return ret; + } + +out: + data->muxes_set = true; + return 0; +} + +struct tcpc_mux_dev *devm_tcpc_gen_mux_create(struct device *dev) +{ + struct tcpc_gen_mux_data *data; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + + data->type_c_mode_mux = devm_mux_control_get(dev, "type-c-mode-mux"); + if (IS_ERR(data->type_c_mode_mux)) { + ret = PTR_ERR(data->type_c_mode_mux); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Error getting Type-C mux: %d\n", ret); + return ERR_PTR(-ret); + } + + data->usb_role_mux = devm_mux_control_get(dev, "usb-role-mux"); + if (IS_ERR(data->usb_role_mux)) { + ret = PTR_ERR(data->usb_role_mux); + /* The USB role mux is optional */ + if (ret == -ENODEV) { + data->usb_role_mux = NULL; + } else { + if (ret != -EPROBE_DEFER)
[PATCH v2 06/11] mux: Add Pericom PI3USB30532 Type-C mux driver
Add a driver for the Pericom PI3USB30532 Type-C cross switch / mux chip found on some devices with a Type-C port. Signed-off-by: Hans de Goede --- Changes in v2: -Adjust for new MUX_TYPEC_foo state defines -Add MAINTAINERS entry -Various code-style fixes --- MAINTAINERS | 5 +++ drivers/mux/Kconfig | 10 + drivers/mux/Makefile | 2 + drivers/mux/pi3usb30532.c | 93 +++ 4 files changed, 110 insertions(+) create mode 100644 drivers/mux/pi3usb30532.c diff --git a/MAINTAINERS b/MAINTAINERS index dfaed958db85..5527b0efcef3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8996,6 +8996,11 @@ M: Hans de Goede S: Maintained F: drivers/mix/intel-cht-usb-mux.c +MULTIPLEXER SUBSYSTEM PI3USB30532 DRIVER +M: Hans de Goede +S: Maintained +F: drivers/mix/pi3usb30532.c + MULTISOUND SOUND DRIVER M: Andrew Veliath S: Maintained diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index 947cfd7af02a..1f6f017ee920 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -58,4 +58,14 @@ config MUX_MMIO To compile the driver as a module, choose M here: the module will be called mux-mmio. +config MUX_PI3USB30532 + tristate "Pericom PI3USB30532 Type-C cross switch driver" + depends on I2C + help + This driver adds support for the Pericom PI3USB30532 Type-C cross + switch / mux chip found on some devices with a Type-C port. + + To compile the driver as a module, choose M here: the module will + be called mux-pi3usb30532. + endmenu diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index 6cf41be2754f..df381c219708 100644 --- a/drivers/mux/Makefile +++ b/drivers/mux/Makefile @@ -7,9 +7,11 @@ mux-adg792a-objs := adg792a.o mux-gpio-objs := gpio.o mux-intel-cht-usb-mux-objs := intel-cht-usb-mux.o mux-mmio-objs := mmio.o +mux-pi3usb30532-objs := pi3usb30532.o obj-$(CONFIG_MULTIPLEXER) += mux-core.o obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o obj-$(CONFIG_MUX_GPIO) += mux-gpio.o obj-$(CONFIG_MUX_INTEL_CHT_USB_MUX)+= mux-intel-cht-usb-mux.o obj-$(CONFIG_MUX_MMIO) += mux-mmio.o +obj-$(CONFIG_MUX_PI3USB30532) += mux-pi3usb30532.o diff --git a/drivers/mux/pi3usb30532.c b/drivers/mux/pi3usb30532.c new file mode 100644 index ..3d959e3ee8c6 --- /dev/null +++ b/drivers/mux/pi3usb30532.c @@ -0,0 +1,93 @@ +/* + * Pericom PI3USB30532 Type-C cross switch / mux driver + * + * Copyright (c) 2017 Hans de Goede + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include + +#define PI3USB30532_CONF 0x00 + +#define PI3USB30532_CONF_OPEN 0x00 +#define PI3USB30532_CONF_SWAP 0x01 +#define PI3USB30532_CONF_4LANE_DP 0x02 +#define PI3USB30532_CONF_USB3 0x04 +#define PI3USB30532_CONF_USB3_AND_2LANE_DP 0x06 + +static int pi3usb30532_set_mux(struct mux_control *mux, int state) +{ + struct i2c_client *i2c = to_i2c_client(mux->chip->dev.parent); + u8 conf = PI3USB30532_CONF_OPEN; + + if (state == MUX_IDLE_DISCONNECT) + return i2c_smbus_write_byte_data(i2c, PI3USB30532_CONF, conf); + + switch (state & ~MUX_TYPEC_POLARITY_INV) { + case MUX_TYPEC_DEVICE: + case MUX_TYPEC_HOST: + conf = PI3USB30532_CONF_USB3; + break; + case MUX_TYPEC_HOST_AND_DP_SRC: + conf = PI3USB30532_CONF_USB3_AND_2LANE_DP; + break; + case MUX_TYPEC_DP_SRC: + conf = PI3USB30532_CONF_4LANE_DP; + break; + } + + if (state & MUX_TYPEC_POLARITY_INV) + conf |= PI3USB30532_CONF_SWAP; + + return i2c_smbus_write_byte_data(i2c, PI3USB30532_CONF, conf); +} + +static const struct mux_control_ops pi3usb30532_ops = { + .set = pi3usb30532_set_mux, +}; + +static int pi3usb30532_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct mux_chip *mux_chip; + + mux_chip = devm_mux_chip_alloc(dev, 1, 0); + if (IS_ERR(mux_chip)) + return PTR_ERR(mux_chip); + + mux_chip->ops = &pi3usb30532_ops; + mux_chip->mux[0].idle_state = MUX_IDLE_DISCONNECT; + /* Keep initial state as is, for e.g. booting from an USB disk */ + mux_chip->mux[0].cached_state = MUX_IDLE_DISCONNECT; + mux_chip->mux[0].states = MUX_TYPEC_STATES; + + return devm_mux_chip_register(dev, mux_chip); +} + +static const struct i2c_device_id pi3usb30532_table[] = { + { "pi3usb30532" }, + { } +};
[PATCH v2 08/11] staging: typec: tcpm: Set mux to device mode when configured as such
Setting the mux to TYPEC_MUX_NONE, TCPC_USB_SWITCH_DISCONNECT when the data-role is device is not correct. Plenty of devices support operating as USB device through a (separate) USB device controller. So this commit instead splits out TYPEC_MUX_USB into TYPEC_MUX_USB_HOST and TYPEC_MUX_USB_DEVICE and makes tcpm_set_roles() set the mux accordingly. Likewise TCPC_MUX_DP gets renamed to TCPC_MUX_DP_SRC to make clear that this is for configuring the Type-C port as a Display Port source, not a sink. Last this commit makes tcpm_reset_port() to set the mux to TYPEC_MUX_NONE, TCPC_USB_SWITCH_DISCONNECT so that it does not and up staying in host (and with this commit also device) mode after a detach. Signed-off-by: Hans de Goede --- drivers/staging/typec/tcpm.c | 7 --- drivers/staging/typec/tcpm.h | 22 ++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index 8af62e74d54c..ffe7e26d4ed3 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -752,11 +752,11 @@ static int tcpm_set_roles(struct tcpm_port *port, bool attached, int ret; if (data == TYPEC_HOST) - ret = tcpm_mux_set(port, TYPEC_MUX_USB, + ret = tcpm_mux_set(port, TYPEC_MUX_USB_HOST, TCPC_USB_SWITCH_CONNECT); else - ret = tcpm_mux_set(port, TYPEC_MUX_NONE, - TCPC_USB_SWITCH_DISCONNECT); + ret = tcpm_mux_set(port, TYPEC_MUX_USB_DEVICE, + TCPC_USB_SWITCH_CONNECT); if (ret < 0) return ret; @@ -2025,6 +2025,7 @@ static void tcpm_reset_port(struct tcpm_port *port) tcpm_init_vconn(port); tcpm_set_current_limit(port, 0, 0); tcpm_set_polarity(port, TYPEC_POLARITY_CC1); + tcpm_mux_set(port, TYPEC_MUX_NONE, TCPC_USB_SWITCH_DISCONNECT); tcpm_set_attached_state(port, false); port->try_src_count = 0; port->try_snk_count = 0; diff --git a/drivers/staging/typec/tcpm.h b/drivers/staging/typec/tcpm.h index 7e9a6b7b5cd6..f662eed48c86 100644 --- a/drivers/staging/typec/tcpm.h +++ b/drivers/staging/typec/tcpm.h @@ -83,17 +83,23 @@ enum tcpc_usb_switch { }; /* Mux state attributes */ -#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */ -#define TCPC_MUX_DP_ENABLEDBIT(1) /* DP enabled */ -#define TCPC_MUX_POLARITY_INVERTED BIT(2) /* Polarity inverted */ +#define TCPC_MUX_USB_DEVICE_ENABLEDBIT(0) /* USB device enabled */ +#define TCPC_MUX_USB_HOST_ENABLED BIT(1) /* USB host enabled */ +#define TCPC_MUX_DP_SRC_ENABLEDBIT(2) /* DP enabled */ +#define TCPC_MUX_POLARITY_INVERTED BIT(3) /* Polarity inverted */ /* Mux modes, decoded to attributes */ enum tcpc_mux_mode { - TYPEC_MUX_NONE = 0,/* Open switch */ - TYPEC_MUX_USB = TCPC_MUX_USB_ENABLED, /* USB only */ - TYPEC_MUX_DP= TCPC_MUX_DP_ENABLED, /* DP only */ - TYPEC_MUX_DOCK = TCPC_MUX_USB_ENABLED |/* Both USB and DP */ - TCPC_MUX_DP_ENABLED, + /* Open switch */ + TYPEC_MUX_NONE = 0, + /* USB device only */ + TYPEC_MUX_USB_DEVICE = TCPC_MUX_USB_DEVICE_ENABLED, + /* USB host only */ + TYPEC_MUX_USB_HOST = TCPC_MUX_USB_HOST_ENABLED, + /* DP source only */ + TYPEC_MUX_DP = TCPC_MUX_DP_SRC_ENABLED, + /* Both USB host and DP source */ + TYPEC_MUX_DOCK = TCPC_MUX_USB_HOST_ENABLED | TCPC_MUX_DP_SRC_ENABLED, }; struct tcpc_mux_dev { -- 2.13.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 05/11] mux: Add Intel Cherrytrail USB mux driver
Intel Cherrytrail SoCs have an internal USB mux for muxing the otg-port USB data lines between the xHCI host controller and the dwc3 gadget controller. On some Cherrytrail systems this mux is controlled through AML code reacting on a GPIO IRQ connected to the USB OTG id pin (through an _AIE ACPI method) so things just work. But on other Cherrytrail systems we need to control the mux ourselves this driver exports the mux through the mux subsys, so that other drivers can control it if necessary. This driver also updates the vbus-valid reporting to the dwc3 gadget controller, as this uses the same registers as the mux. This is needed for gadget/device mode to work properly (even on systems which control the mux from their AML code). Note this depends on the xhci driver registering a platform device named "intel_cht_usb_mux", which has an IOMEM resource 0 which points to the Intel Vendor Defined XHCI extended capabilities region. Signed-off-by: Hans de Goede --- Changes in v2: -Complete rewrite as a stand-alone platform-driver rather then as a phy driver, since this is just a mux, not a phy Changes in v3: -Make this a mux subsys driver instead of listening to USB_HOST extcon cable events and responding to those Changes in v4 (of patch, v2 of new mux based series): -Rename C-file to use - in name -Add MAINTAINERS entry -Various code-style fixes --- MAINTAINERS | 5 + drivers/mux/Kconfig | 11 ++ drivers/mux/Makefile| 10 +- drivers/mux/intel-cht-usb-mux.c | 257 4 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 drivers/mux/intel-cht-usb-mux.c diff --git a/MAINTAINERS b/MAINTAINERS index 14a2fd905217..dfaed958db85 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8991,6 +8991,11 @@ F: include/linux/dt-bindings/mux/ F: include/linux/mux/ F: drivers/mux/ +MULTIPLEXER SUBSYSTEM INTEL CHT USB MUX DRIVER +M: Hans de Goede +S: Maintained +F: drivers/mix/intel-cht-usb-mux.c + MULTISOUND SOUND DRIVER M: Andrew Veliath S: Maintained diff --git a/drivers/mux/Kconfig b/drivers/mux/Kconfig index 19e4e904c9bf..947cfd7af02a 100644 --- a/drivers/mux/Kconfig +++ b/drivers/mux/Kconfig @@ -34,6 +34,17 @@ config MUX_GPIO To compile the driver as a module, choose M here: the module will be called mux-gpio. +config MUX_INTEL_CHT_USB_MUX + tristate "Intel Cherrytrail USB Multiplexer" + depends on ACPI && X86 && EXTCON + help + This driver adds support for the internal USB mux for muxing the OTG + USB data lines between the xHCI host controller and the dwc3 gadget + controller found on Intel Cherrytrail SoCs. + + To compile the driver as a module, choose M here: the module will + be called mux-intel_cht_usb_mux. + config MUX_MMIO tristate "MMIO register bitfield-controlled Multiplexer" depends on (OF && MFD_SYSCON) || COMPILE_TEST diff --git a/drivers/mux/Makefile b/drivers/mux/Makefile index 0e1e59760e3f..6cf41be2754f 100644 --- a/drivers/mux/Makefile +++ b/drivers/mux/Makefile @@ -5,9 +5,11 @@ mux-core-objs := core.o mux-adg792a-objs := adg792a.o mux-gpio-objs := gpio.o +mux-intel-cht-usb-mux-objs := intel-cht-usb-mux.o mux-mmio-objs := mmio.o -obj-$(CONFIG_MULTIPLEXER) += mux-core.o -obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o -obj-$(CONFIG_MUX_GPIO) += mux-gpio.o -obj-$(CONFIG_MUX_MMIO) += mux-mmio.o +obj-$(CONFIG_MULTIPLEXER) += mux-core.o +obj-$(CONFIG_MUX_ADG792A) += mux-adg792a.o +obj-$(CONFIG_MUX_GPIO) += mux-gpio.o +obj-$(CONFIG_MUX_INTEL_CHT_USB_MUX)+= mux-intel-cht-usb-mux.o +obj-$(CONFIG_MUX_MMIO) += mux-mmio.o diff --git a/drivers/mux/intel-cht-usb-mux.c b/drivers/mux/intel-cht-usb-mux.c new file mode 100644 index ..9cd1a1f5027f --- /dev/null +++ b/drivers/mux/intel-cht-usb-mux.c @@ -0,0 +1,257 @@ +/* + * Intel Cherrytrail USB OTG MUX driver + * + * Copyright (c) 2016 Hans de Goede + * + * Loosely based on android x86 kernel code which is: + * + * Copyright (C) 2014 Intel Corp. + * + * Author: Wu, Hao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* register definition */ +#define DUAL_ROLE_CFG0 0x68 +#define SW_VBUS_VALID (1 << 24) +#define SW_IDPIN_EN(1 << 21) +#define SW_IDPIN (1 << 20) + +#define DUAL_ROLE_CFG1 0x6c +#define HOST_MODE (1 << 29) + +#define DUAL_ROLE_C
[PATCH v2 00/11] mux/typec: Add USB / TypeC mux drivers and hook them up on some x86 systems
Hi All, Here is v2 of my USB / Type-C mux series, addressing various comments from the reviews of v1. See the per patch changelogs for details. For reference here the cover letter of v1: This series consists of 4 parts: 1) Core mux changes to add support for getting mux-controllers on non DT platforms and to add some standardised state values for USB 2) Add Intel CHT USB mux and Pericom-PI3USB30532 Type-C mux drivers 3) Hookup the Intel CHT USB mux driver for CHT devices without Type-C 4) Hookup both the Intel CHT USB mux and Pericom-PI3USB30532 Type-C mux drivers to the fusb302 Type-C port controller found on some CHT x86 devs Please review, or in the case of the drivers/mux changes (which are a dep for some of the other patches) merge if the patches are ready. Regards, Hans -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/11] mux: core: Add support for getting a mux controller on a non DT platform
On non DT platforms we cannot get the mux_chip by pnode. Other subsystems (regulator, clock, pwm) have the same problem and solve this by allowing platform / board-setup code to add entries to a lookup table and then use this table to look things up. This commit adds support for getting a mux controller on a non DT platform following this pattern. It is based on a simplified version of the pwm subsys lookup code, the dev_id and mux_name parts of a lookup table entry are mandatory in the mux-core implementation. Signed-off-by: Hans de Goede --- Changes in v2: -Fixup some kerneldoc comments, add kerneldoc comment to structs -Minor code-style tweaks --- drivers/mux/core.c | 93 +++- include/linux/mux/consumer.h | 19 + 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/drivers/mux/core.c b/drivers/mux/core.c index 99d29f982c0e..e25bb7ab03ce 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c @@ -24,6 +24,9 @@ #include #include +static DEFINE_MUTEX(mux_lookup_lock); +static LIST_HEAD(mux_lookup_list); + /* * The idle-as-is "state" is not an actual state that may be selected, it * only implies that the state should not be changed. So, use that state @@ -408,6 +411,23 @@ int mux_control_deselect(struct mux_control *mux) } EXPORT_SYMBOL_GPL(mux_control_deselect); +static int parent_name_match(struct device *dev, const void *data) +{ + const char *parent_name = dev_name(dev->parent); + const char *name = data; + + return strcmp(parent_name, name) == 0; +} + +static struct mux_chip *mux_chip_get_by_name(const char *name) +{ + struct device *dev; + + dev = class_find_device(&mux_class, NULL, name, parent_name_match); + + return dev ? to_mux_chip(dev) : NULL; +} + static int of_dev_node_match(struct device *dev, const void *data) { return dev->of_node == data; @@ -480,6 +500,38 @@ static struct mux_control *of_mux_control_get(struct device *dev, } /** + * mux_add_table() - Register consumer to mux-controller mappings + * @table: array of mappings to register + * @num: number of mappings in table + */ +void mux_add_table(struct mux_lookup *table, size_t num) +{ + mutex_lock(&mux_lookup_lock); + + for (; num--; table++) + list_add_tail(&table->list, &mux_lookup_list); + + mutex_unlock(&mux_lookup_lock); +} +EXPORT_SYMBOL_GPL(mux_add_table); + +/** + * mux_remove_table() - Unregister consumer to mux-controller mappings + * @table: array of mappings to unregister + * @num: number of mappings in table + */ +void mux_remove_table(struct mux_lookup *table, size_t num) +{ + mutex_lock(&mux_lookup_lock); + + for (; num--; table++) + list_del(&table->list); + + mutex_unlock(&mux_lookup_lock); +} +EXPORT_SYMBOL_GPL(mux_remove_table); + +/** * mux_control_get() - Get the mux-control for a device. * @dev: The device that needs a mux-control. * @mux_name: The name identifying the mux-control. @@ -488,11 +540,50 @@ static struct mux_control *of_mux_control_get(struct device *dev, */ struct mux_control *mux_control_get(struct device *dev, const char *mux_name) { + struct mux_lookup *m, *chosen = NULL; + const char *dev_id = dev_name(dev); + struct mux_chip *mux_chip; + /* look up via DT first */ if (IS_ENABLED(CONFIG_OF) && dev->of_node) return of_mux_control_get(dev, mux_name); - return ERR_PTR(-ENODEV); + /* +* For non DT we look up the provider in the static table typically +* provided by board setup code. +* +* If a match is found, the provider mux chip is looked up by name +* and a mux-control is requested using the table provided index. +*/ + mutex_lock(&mux_lookup_lock); + list_for_each_entry(m, &mux_lookup_list, list) { + if (WARN_ON(!m->dev_id || !m->mux_name || !m->provider)) + continue; + + if (!strcmp(m->dev_id, dev_id) && + !strcmp(m->mux_name, mux_name)) + { + chosen = m; + break; + } + } + mutex_unlock(&mux_lookup_lock); + + if (!chosen) + return ERR_PTR(-ENODEV); + + mux_chip = mux_chip_get_by_name(chosen->provider); + if (!mux_chip) + return ERR_PTR(-EPROBE_DEFER); + + if (chosen->index >= mux_chip->controllers) { + dev_err(dev, "Mux lookup table index out of bounds %u >= %u\n", + chosen->index, mux_chip->controllers); + put_device(&mux_chip->dev); + return ERR_PTR(-EINVAL); + } + + return &mux_chip->mux[chosen->index]; } EXPORT_SYMBOL_GPL(mux_control_get); diff --git a/include/linux/mux/consumer.h b/include/linux/mux/consumer.h index ea96d4c82be7..62a8ec6171c9 100644 --- a/include/linux/mux/consume
[PATCH v2 04/11] usb: xhci: Add Intel cherrytrail extended cap / otg phy mux handling
The Intel cherrytrail xhci controller has an extended cap mmio-range which contains registers to control the muxing to the xhci (host mode) or the dwc3 (device mode) and vbus-detection for the otg usb-phy. Having a mux driver included in the xhci code (or under drivers/usb/host) is not desirable. So this commit adds a simple handler for this extended capability, which creates a platform device with the caps mmio region as resource, this allows us to write a separate platform mux driver for the mux. Signed-off-by: Hans de Goede --- Changes in v2: -Check xHCI controller PCI device-id instead of only checking for the Intel Extended capability ID, as the Extended capability ID is used on other model Intel xHCI controllers too --- drivers/usb/host/Makefile| 2 +- drivers/usb/host/xhci-intel-quirks.c | 85 drivers/usb/host/xhci-pci.c | 4 ++ drivers/usb/host/xhci.h | 2 + 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/host/xhci-intel-quirks.c diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index cf2691fffcc0..441edf82eb1c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_USB_OHCI_HCD_DAVINCI)+= ohci-da8xx.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_FHCI_HCD) += fhci.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o -obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o +obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o xhci-intel-quirks.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o diff --git a/drivers/usb/host/xhci-intel-quirks.c b/drivers/usb/host/xhci-intel-quirks.c new file mode 100644 index ..819f5f9da9ee --- /dev/null +++ b/drivers/usb/host/xhci-intel-quirks.c @@ -0,0 +1,85 @@ +/* + * Intel Vendor Defined XHCI extended capability handling + * + * Copyright (c) 2016) Hans de Goede + * + * Loosely based on android x86 kernel code which is: + * + * Copyright (C) 2014 Intel Corp. + * + * Author: Wu, Hao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; + */ + +#include +#include "xhci.h" + +/* Extended capability IDs for Intel Vendor Defined */ +#define XHCI_EXT_CAPS_INTEL_HOST_CAP 192 + +static void xhci_intel_unregister_pdev(void *arg) +{ + platform_device_unregister(arg); +} + +int xhci_create_intel_cht_mux_pdev(struct xhci_hcd *xhci) +{ + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct device *dev = hcd->self.controller; + struct platform_device *pdev; + struct resource res = { 0, }; + int ret, ext_offset; + + ext_offset = xhci_find_next_ext_cap(&xhci->cap_regs->hc_capbase, 0, + XHCI_EXT_CAPS_INTEL_HOST_CAP); + if (!ext_offset) { + xhci_err(xhci, "couldn't find Intel ext caps\n"); + return -ENODEV; + } + + pdev = platform_device_alloc("intel_cht_usb_mux", PLATFORM_DEVID_NONE); + if (!pdev) { + xhci_err(xhci, "couldn't allocate intel_cht_usb_mux pdev\n"); + return -ENOMEM; + } + + res.start = hcd->rsrc_start + ext_offset; + res.end = res.start + 0x3ff; + res.name = "intel_cht_usb_mux"; + res.flags = IORESOURCE_MEM; + + ret = platform_device_add_resources(pdev, &res, 1); + if (ret) { + dev_err(dev, "couldn't add resources to intel_cht_usb_mux pdev\n"); + platform_device_put(pdev); + return ret; + } + + pdev->dev.parent = dev; + + ret = platform_device_add(pdev); + if (ret) { + dev_err(dev, "couldn't register intel_cht_usb_mux pdev\n"); + platform_device_put(pdev); + return ret; + } + + ret = devm_add_action_or_reset(dev, xhci_intel_unregister_pdev, pdev); + if (ret) { + dev_err(dev, "couldn't add unregister action for intel_cht_usb_mux pdev\n"); + return ret; + } + + return 0; +} diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8071c8fdd15e..b55c1e96abf0 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -188,6 +188,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == PCI_
Re: [PATCH] usb: Increase quirk delay for USB devices
On Tue, Sep 05, 2017 at 11:40:56AM +0300, Dmitry Fleytman wrote: > Commit e0429362ab15 > ("usb: Add device quirk for Logitech HD Pro Webcams C920 and C930e") > introduced quirk to workaround an issue with some Logitech webcams. > > The workaround is introducing delay for some USB operations. > > According to our testing, delay introduced by original commit > is not long enough and in rare cases we still see issues described > by the aforementioned commit. > > This patch increases delays introduced by original commit. > Having this patch applied we do not see those problems anymore. > > Signed-off-by: Dmitry Fleytman > --- > drivers/usb/core/config.c | 2 +- > drivers/usb/core/hub.c| 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c > index 4be52c6..854c8d6 100644 > --- a/drivers/usb/core/config.c > +++ b/drivers/usb/core/config.c > @@ -852,7 +852,7 @@ int usb_get_configuration(struct usb_device *dev) > } > > if (dev->quirks & USB_QUIRK_DELAY_INIT) > - msleep(100); > + msleep(200); How did you determine the new delays ? Was it discussed with the vendor, or is it based on trial and error ? Either case, did you confirm that you need to increase both delays for the problem to disappear ? Thanks, Guenter > > result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, > bigbuffer, length); > diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c > index 822f8c5..78c2aca 100644 > --- a/drivers/usb/core/hub.c > +++ b/drivers/usb/core/hub.c > @@ -4825,7 +4825,7 @@ static void hub_port_connect(struct usb_hub *hub, int > port1, u16 portstatus, > goto loop; > > if (udev->quirks & USB_QUIRK_DELAY_INIT) > - msleep(1000); > + msleep(2000); > > /* consecutive bus-powered hubs aren't reliable; they can >* violate the voltage drop budget. if the new child has > -- > 2.7.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Debugging USB 3.0 Speeds
I've added a USB 3.0 card that should support super speed to a server I have, but it's not working at super-speed speeds for the external hard drives I connect, and a having a hard time diagnosing why (hardware issue/quirk? driver issue?) Before installing the card, xhci wasn't ever used, now it is, so that makes it clear that it is a usb 3.0 card. It's a 4 port card, but what's weird is that the card seems to expose 2 USB hubs with 4 ports. i.e. [2.086988] xhci_hcd :07:00.0: xHCI Host Controller [2.086996] xhci_hcd :07:00.0: new USB bus registered, assigned bus number 2 [2.092364] xhci_hcd :07:00.0: hcc params 0x014051cf hci version 0x100 quirks 0x0010 [2.092561] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002 [2.092563] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [2.092564] usb usb2: Product: xHCI Host Controller [2.092565] usb usb2: Manufacturer: Linux 4.9.0-3-amd64 xhci-hcd [2.092566] usb usb2: SerialNumber: :07:00.0 [2.092741] hub 2-0:1.0: USB hub found [2.092749] hub 2-0:1.0: 4 ports detected quickly followed by [2.092881] xhci_hcd :07:00.0: xHCI Host Controller [2.092884] xhci_hcd :07:00.0: new USB bus registered, assigned bus number 3 [2.095951] usb usb3: We don't know the algorithms for LPM for this host, disabling LPM. [2.095965] usb usb3: New USB device found, idVendor=1d6b, idProduct=0003 [2.095966] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [2.095967] usb usb3: Product: xHCI Host Controller [2.095968] usb usb3: Manufacturer: Linux 4.9.0-3-amd64 xhci-hcd [2.095969] usb usb3: SerialNumber: :07:00.0 [2.096100] hub 3-0:1.0: USB hub found [2.096116] hub 3-0:1.0: 4 ports detected lsusb -t shows the hubs and the problem /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M |__ Port 3: Dev 5, If 0, Class=Mass Storage, Driver=uas, 480M |__ Port 4: Dev 6, If 0, Class=Hub, Driver=hub/3p, 480M |__ Port 1: Dev 11, If 0, Class=Mass Storage, Driver=uas, 480M the hard drives I plug in are connecting to the 480Mbps "hub", not the 5000Mbps hub. and this is clear from the kernel logs when connecting the external hard drive [538663.101097] usb 2-4: new high-speed USB device number 6 using xhci_hcd [538663.246919] usb 2-4: New USB device found, idVendor=0bc2, idProduct=ab44 [538663.246922] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [538663.246923] usb 2-4: Product: Backup+ Hub [538663.246924] usb 2-4: Manufacturer: Seagate [538663.248429] hub 2-4:1.0: USB hub found [538663.248973] hub 2-4:1.0: 3 ports detected [538664.169034] usb 2-4.1: new high-speed USB device number 11 using xhci_hcd [538664.319996] usb 2-4.1: New USB device found, idVendor=0bc2, idProduct=ab38 [538664.31] usb 2-4.1: New USB device strings: Mfr=2, Product=3, SerialNumber=1 [538664.32] usb 2-4.1: Product: Backup+ Hub BK [538664.320001] usb 2-4.1: Manufacturer: Seagate I have tested these drives in other computers (windows) and they seemed to work at super-speed speeds, plan is to try a different usb 3.0 card as well in this machine which I also know worked in windows at super-speed speeds, but trying to understand f there are other ways to debug it. i.e. even lsusb -v shows that these devices should be capable of super-speed speeds SuperSpeed USB Device Capability: bLength10 bDescriptorType16 bDevCapabilityType 3 bmAttributes 0x00 wSpeedsSupported 0x000e Device can operate at Full Speed (12Mbps) Device can operate at High Speed (480Mbps) Device can operate at SuperSpeed (5Gbps) For reference, this is the stock Debian 4.9 kernel in Debian stretch Linux spotter 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u3 (2017-08-06) x86_64 GNU/Linux any help in understanding what's going on would be appreciated. -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Bug 196559: xhci_hcd: kernel panic using thunderbolt dell dock TB16 on 4.12.4
Hi, I found a way to reliably trigger this bug: - Boot laptop - Plug in dock (with external display connected to dock) - Send output to external display - Suspend I did a bisect between 4.12.3 and 4.12.4 and here is the result: 5cc9b698a494827b15f74ef70a31d7911d00e52a is the first bad commit commit 5cc9b698a494827b15f74ef70a31d7911d00e52a Author: Jiahau Chang Date: Thu Jul 20 14:48:27 2017 +0300 xhci: Bad Ethernet performance plugged in ASM1042A host commit 9da5a1092b13468839b1a864b126cacfb72ad016 upstream. When USB Ethernet is plugged in ASMEDIA ASM1042A xHCI host, bad performance was manifesting in Web browser use (like download large file such as ISO image). It is known limitation of ASM1042A that is not compatible with driver scheduling, As a workaround we can modify flow control handling of ASM1042A. The register we modify is changes the behavior [use quirk bit 28, usleep_range 40-60us, empty non-pci function -Mathias] Signed-off-by: Jiahau Chang Signed-off-by: Ian Pilcher Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman :04 04 876e102bde34482389d90d3394c369557a6e0d98 a84e4099274ef8c0eb35d70fbe69013f011c7c78 M drivers I have added kernel messages stored by journald to the bugzilla bug report (https://bugzilla.kernel.org/show_bug.cgi?id=196559). They complement the pstore logs I previously attached. I can confirm that the thunderbolt dock I'm using (Dell TB16) has an ASMEDIA ASM1042A USB controller. This is the output from lspci with the dock plugged in: $ lspci | grep USB 00:14.0 USB controller: Intel Corporation Sunrise Point-H USB 3.0 xHCI Controller (rev 31) 0e:00.0 USB controller: ASMedia Technology Inc. ASM1042A USB 3.0 Host Controller Jose On 08/01/2017 01:00 PM, Jose Marino wrote: I'm running archlinux on a Dell XPS15 9550 and I connect it to a TB16 thunderbolt dock. Connected to the dock I have a 4k external display and a USB logitech transmitter for my wireless keyboard and mouse. The TB16 dock is a finicky beast and doesn't currently work 100% with linux. However, if I follow a strict set of steps every time I plug it in and suspend/resume the laptop everything works reasonably well and I have an acceptable work environment. For the record the correct set of steps is: plug in dock, then connect dock to still asleep laptop, then resume laptop. Also, to help things along I automatically unload/reload module 'xhci_pci' on suspend/resume. Things were running smoothly with kernel 4.12.3, with only little hiccups here and there until I upgraded to kernel 4.12.4. I have suffered at least 3 kernel panics since yesterday. The kernel panics happened right after resume or when switching the video output from the external display to the laptop display. I have efi_pstore module loaded so I was able to capture the panic logs in each of these 3 occasions. The logs from one of the kernel panics can be found here: https://bugzilla.kernel.org/attachment.cgi?id=257781 The logs from the other kernel panics are pretty much identical. After the 3rd panic I have downgraded back to 4.12.3 and so far I haven't had any issues. NOTE: I filed a bug report about this: https://bugzilla.kernel.org/show_bug.cgi?id=196559 Jose -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/1] usb:xhci: update condition to select bus->sysdev from parent device
On 06.09.2017 06:47, Thang Q. Nguyen wrote: On Tue, Sep 5, 2017 at 6:14 PM, Mathias Nyman mailto:mathias.ny...@linux.intel.com>> wrote: On 24.08.2017 05 :53, Thang Q. Nguyen wrote: On Sat, Aug 19, 2017 at 10:43 AM, Thang Q. Nguyen mailto:tqngu...@apm.com>> wrote: From: "Thang Q. Nguyen" mailto:tqngu...@apm.com>> For commit 4c39d4b949d3 ("usb: xhci: use bus->sysdev for DMA configuration"), sysdev points to devices known to the system firmware or hardware for DMA parameters. However, the parent of the system firmware/hardware device checking logic does not work in ACPI boot mode. This patch updates the formulation to check this case in both DT and ACPI. Signed-off-by: Tung Nguyen mailto:tungu...@apm.com>> Signed-off-by: Thang Q. Nguyen mailto:tqngu...@apm.com>> --- Change since v1: - Update codes to work with kernel 4.13-rc5 --- drivers/usb/host/xhci-plat.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index c04144b..1bb9729 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -187,7 +187,10 @@ static int xhci_plat_probe(struct platform_device *pdev) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) + if (sysdev->parent && !is_of_node(sysdev->fwnode) && + !is_acpi_device_node(sysdev->fwnode) && + (is_of_node(sysdev->parent->fwnode) || + is_acpi_device_node(sysdev->parent->fwnode))) sysdev = sysdev->parent; #ifdef CONFIG_PCI else if (sysdev->parent && sysdev->parent->parent && -- 1.8.3.1 Is there any comment about the patch? With current kernel (4.13.0-rc6), booting the Linux using ACPI boot, kernel is crashed right after probing the USB DWC3 driver with the following messages: That should work, but the if statements are getting quite elaborate. How about replacing it all with: - sysdev = &pdev->dev; - if (sysdev->parent && !sysdev->of_node && sysdev->parent->of_node) - sysdev = sysdev->parent; -#ifdef CONFIG_PCI - else if (sysdev->parent && sysdev->parent->parent && -sysdev->parent->parent->bus == &pci_bus_type) - sysdev = sysdev->parent->parent; -#endif + + for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { + if (is_of_node(sysdev->fwnode) || + is_acpi_device_node(sysdev->fwnode)) + break; + #ifdef CONFIG_PCI + else if (sysdev->bus == &pci_bus_type) + break; + #endif + } + + if (!sysdev) + sysdev = &pdev->dev Does that work for you? -Mathias It works for me. I tested the followings: - ACPI boot: 808622B7 (DWC3) and PNP0D10 (xhci-platform) - DT boot: snps,dwc3 (DWC3) and xhci-platform. Will you apply your codes into 4.14 kernel? I will, thanks for testing -Mathias -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html