[PATCH v3] usb: dwc2: reset dwc2 core before dwc2_get_hwparams()
We initiate dwc2 usb controller in BIOS, dwc2_core_reset() should be called before dwc2_get_hwparams() to reset core registers to default value. Without this the FIFO setting might be incorrect because calculating FIFO size need power-on value of GRXFSIZ/GNPTXFSIZ/HPTXFSIZ registers. This patch could avoid warnning massage like in rk3288 platform: [2.074764] dwc2 ff58.usb: 256 invalid for host_perio_tx_fifo_size. Check HW configuration. Signed-off-by: Yunzhi Li l...@rock-chips.com --- drivers/usb/dwc2/core.c | 2 +- drivers/usb/dwc2/core.h | 1 + drivers/usb/dwc2/platform.c | 21 - 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index c3cc1a7..86d1d65 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -474,7 +474,7 @@ static void dwc2_init_fs_ls_pclk_sel(struct dwc2_hsotg *hsotg) * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ -static int dwc2_core_reset(struct dwc2_hsotg *hsotg) +int dwc2_core_reset(struct dwc2_hsotg *hsotg) { u32 greset; int count = 0; diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h index 0ed87620..5d95aec 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -846,6 +846,7 @@ enum dwc2_halt_status { * The following functions support initialization of the core driver component * and the DWC_otg controller */ +extern int dwc2_core_reset(struct dwc2_hsotg *hsotg); extern void dwc2_core_host_init(struct dwc2_hsotg *hsotg); extern int dwc2_enter_hibernation(struct dwc2_hsotg *hsotg); extern int dwc2_exit_hibernation(struct dwc2_hsotg *hsotg, bool restore); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 9093530..55d378a 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -166,7 +166,8 @@ static int dwc2_driver_probe(struct platform_device *dev) struct phy *phy; struct usb_phy *uphy; int retval; - int irq; + int irq, count = 0; + u32 greset; match = of_match_device(dwc2_of_match_table, dev-dev); if (match match-data) { @@ -243,6 +244,24 @@ static int dwc2_driver_probe(struct platform_device *dev) spin_lock_init(hsotg-lock); mutex_init(hsotg-init_mutex); + /* +* Reset before dwc2_get_hwparams() then it could get power-on real +* reset value form registers. +*/ + count = 0; + greset |= GRSTCTL_CSFTRST; + writel(greset, hsotg-regs + GRSTCTL); + do { + usleep_range(2, 4); + greset = readl(hsotg-regs + GRSTCTL); + if (++count 50) { + dev_warn(hsotg-dev, +%s() HANG! Soft Reset GRSTCTL=%0x\n, +__func__, greset); + return -EBUSY; + } + } while (greset GRSTCTL_CSFTRST); + /* Detect config values from hardware */ retval = dwc2_get_hwparams(hsotg); if (retval) -- 2.0.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
Re: [PATCH] usb: gadget: composite: fill bcdUSB for any gadget max speed
On 08/19/2015 03:56 PM, Alan Stern wrote: On Wed, 19 Aug 2015, Igor Kotrasinski wrote: I would argue that there's no need to check gadget_is_dualspeed(); bcdUSB should always be set to 0x0200. After all, the spec explicitly permits USB-2.0 devices to run only at full speed. we should actually set it to 0x0210 so we get to send BOS descriptors :-) If I understand it correctly then, gadget-max_speed isn't any indicator of supported standard? That's right. There's almost no connection between the USB standard and the supported speeds. All you can depend on is this: If bcdUSB 0x0200 then the device must run at low speed or full speed (it can't use high speed or SuperSpeed). If bcdUSB = 0x0200 then the device must be able to connect at low speed or full speed (although it may not be able to do anything useful). It may also be able to run at high speed. If bcdUSB 0x0300 then the device must run at low, full, or high speed (it can't use SuperSpeed). If bcdUSB = 0x0300 then the device must run at SuperSpeed. Nothing else is guaranteed. Either way, some else block definitely should be there. I don't follow why 0x0210 is appropriate for all other gadget speeds; could you please, if possible, elaborate? As you can see from the above, devices with bcdUSB = 0x0210 are allowed to run at low, full, or high speed. Therefore it is an appropriate value. The extra meaning expressed by bcdUSB has to do with the set of descriptors provided by the device. With 0x0210, the device is obliged to provide BOS descriptors (as Felipe mentioned). With 0x0200, the device is obliged to provide an other-speed descriptor. Alan Stern I see now - it's the gadget layer that handles all relevant setup requests, and the controller is only concerned with an appropriate speed, so bcdUSB is only a matter of what descriptors the gadget layer supports. Many thanks to you and Balbi for explaining it, fixed patch is on the way. Igor Kotrasinski -- 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 3/5] usb: phy: add usb3.0 phy driver for mt65xx SoCs
Hi On Mon, 2015-08-17 at 10:59 +0530, Kishon Vijay Abraham I wrote: Hi, On Friday 07 August 2015 06:00 PM, Chunfeng Yun wrote: support usb3.0 phy of mt65xx SoCs Signed-off-by: Chunfeng Yun chunfeng@mediatek.com change $subject to phy: --- drivers/phy/Kconfig | 9 + drivers/phy/Makefile | 1 + drivers/phy/phy-mt65xx-usb3.c | 467 ++ 3 files changed, 477 insertions(+) create mode 100644 drivers/phy/phy-mt65xx-usb3.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c0e6ede..019cf8b 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -193,6 +193,15 @@ config PHY_HIX5HD2_SATA help Support for SATA PHY on Hisilicon hix5hd2 Soc. +config PHY_MT65XX_USB3 + tristate Mediatek USB3.0 PHY Driver + depends on ARCH_MEDIATEK OF + select GENERIC_PHY + help + Say 'Y' here to add support for Mediatek USB3.0 PHY driver + for mt65xx SoCs. it supports two usb2.0 ports and + one usb3.0 port. + config PHY_SUN4I_USB tristate Allwinner sunxi SoC USB PHY driver depends on ARCH_SUNXI HAS_IOMEM OF diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index f344e1b..3ceff2a 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_TI_PIPE3)+= phy-ti-pipe3.o obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o +obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o obj-$(CONFIG_PHY_SUN4I_USB)+= phy-sun4i-usb.o obj-$(CONFIG_PHY_SUN9I_USB)+= phy-sun9i-usb.o obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c new file mode 100644 index 000..6835bff --- /dev/null +++ b/drivers/phy/phy-mt65xx-usb3.c . . snip . . +static struct phy *mt65xx_phy_xlate(struct device *dev, + struct of_phandle_args *args) +{ + struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev); + struct mt65xx_phy_instance *instance = NULL; + struct device_node *phy_np = args-np; + struct resource res; + int index; + int ret; + + if (args-args_count != 1) { + dev_err(dev, invalid number of cells in 'phy' property\n); + return ERR_PTR(-EINVAL); + } + + for (index = 0; index u3phy-nphys; index++) + if (phy_np == u3phy-phys[index]-phy-dev.of_node) { + instance = u3phy-phys[index]; + break; + } + + if (!instance) { + dev_err(dev, failed to find appropriate phy\n); + return ERR_PTR(-EINVAL); + } + + instance-type = args-args[0]; + + if (!(instance-type == PHY_TYPE_USB2 || + instance-type == PHY_TYPE_USB3)) { + dev_err(dev, unsupported device type: %d\n, instance-type); + return ERR_PTR(-EINVAL); + } + + ret = of_address_to_resource(phy_np, 0, res); + if (ret) { + dev_err(dev, failed to get address resource, err-%d (index-%d)\n, + ret, instance-index); + return ERR_PTR(-EINVAL); + } This should be done in probe itself. + + instance-port_base = devm_ioremap_resource(instance-phy-dev, res); + if (IS_ERR(instance-port_base)) { + dev_err(dev, failed to remap sif regs\n); + return instance-port_base; + } This too should be done in probe. Ok, I'll revise it later. + + return instance-phy; +} + +static struct phy_ops mt65xx_u3phy_ops = { + .init = mt65xx_phy_init, + .power_on = mt65xx_phy_power_on, + .power_off = mt65xx_phy_power_off, + .owner = THIS_MODULE, +}; + +static int mt65xx_u3phy_probe(struct platform_device *pdev) +{ + struct device *dev = pdev-dev; + struct device_node *np = dev-of_node; + struct device_node *child_np; + struct phy_provider *phy_provider; + struct resource *sif_res; + struct mt65xx_u3phy *u3phy; + int port; + + u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL); + if (!u3phy) + return -ENOMEM; + + u3phy-nphys = of_get_child_count(np); + u3phy-phys = devm_kcalloc(dev, u3phy-nphys, + sizeof(*u3phy-phys), GFP_KERNEL); + if (!u3phy-phys) + return -ENOMEM; + + u3phy-dev = dev; + platform_set_drvdata(pdev, u3phy); + + sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + u3phy-sif_base = devm_ioremap_resource(dev, sif_res); + if (IS_ERR(u3phy-sif_base)) { + dev_err(dev, failed to remap sif regs\n); + return
Re: [PATCH] usb: gadget: composite: fill bcdUSB for any gadget max speed
On Wed, 19 Aug 2015, Igor Kotrasinski wrote: I would argue that there's no need to check gadget_is_dualspeed(); bcdUSB should always be set to 0x0200. After all, the spec explicitly permits USB-2.0 devices to run only at full speed. we should actually set it to 0x0210 so we get to send BOS descriptors :-) If I understand it correctly then, gadget-max_speed isn't any indicator of supported standard? That's right. There's almost no connection between the USB standard and the supported speeds. All you can depend on is this: If bcdUSB 0x0200 then the device must run at low speed or full speed (it can't use high speed or SuperSpeed). If bcdUSB = 0x0200 then the device must be able to connect at low speed or full speed (although it may not be able to do anything useful). It may also be able to run at high speed. If bcdUSB 0x0300 then the device must run at low, full, or high speed (it can't use SuperSpeed). If bcdUSB = 0x0300 then the device must run at SuperSpeed. Nothing else is guaranteed. Either way, some else block definitely should be there. I don't follow why 0x0210 is appropriate for all other gadget speeds; could you please, if possible, elaborate? As you can see from the above, devices with bcdUSB = 0x0210 are allowed to run at low, full, or high speed. Therefore it is an appropriate value. The extra meaning expressed by bcdUSB has to do with the set of descriptors provided by the device. With 0x0210, the device is obliged to provide BOS descriptors (as Felipe mentioned). With 0x0200, the device is obliged to provide an other-speed descriptor. Alan Stern -- 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] usbnet: Fix two races between usbnet_stop() and the BH
Eugene Shatokhin eugene.shatok...@rosalab.ru writes: The problem is not in the reordering but rather in the fact that dev-flags = 0 is not necessarily atomic w.r.t. clear_bit(EVENT_RX_KILL, dev-flags), and vice versa. So the following might be possible, although unlikely: CPU0 CPU1 clear_bit: read dev-flags clear_bit: clear EVENT_RX_KILL in the read value dev-flags=0; clear_bit: write updated dev-flags As a result, dev-flags may become non-zero again. Ah, right. Thanks for explaining. I cannot prove yet that this is an impossible situation. If anyone can, please explain. If so, this part of the patch will not be needed. I wonder if we could simply move the dev-flags = 0 down a few lines to fix both issues? It doesn't seem to do anything useful except for resetting the flags to a sane initial state after the device is down. Stopping the tasklet rescheduling etc depends only on netif_running(), which will be false when usbnet_stop is called. There is no need to touch dev-flags for this to happen. The EVENT_NO_RUNTIME_PM bug should definitely be fixed. Please split that out as a separate fix. It's a separate issue, and should be backported to all maintained stable releases it applies to (anything from v3.8 and newer) Yes, that makes sense. However, this fix was originally provided by Oliver Neukum rather than me, so I would like to hear his opinion as well first. If what I write above is correct (please help me verify...), then maybe it does make sense to do these together anyway. Bjørn -- 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] usbnet: Fix two races between usbnet_stop() and the BH
19.08.2015 13:54, Bjørn Mork пишет: Eugene Shatokhin eugene.shatok...@rosalab.ru writes: 19.08.2015 04:54, David Miller пишет: From: Eugene Shatokhin eugene.shatok...@rosalab.ru Date: Fri, 14 Aug 2015 19:58:36 +0300 2. The second race is on dev-flags. dev-flags is set to 0 here: *0 usbnet_stop (usbnet.c:816) /* deferred work (task, timer, softirq) must also stop. * can't flush_scheduled_work() until we drop rtnl (later), * else workers could deadlock; so make workers a NOP. */ dev-flags = 0; del_timer_sync (dev-delay); tasklet_kill (dev-bh); And here, the code clears EVENT_RX_KILL bit in dev-flags, which may execute concurrently with the above operation: *0 clear_bit (bitops.h:113, inlined) *1 usbnet_bh (usbnet.c:1475) /* restart RX again after disabling due to high error rate */ clear_bit(EVENT_RX_KILL, dev-flags); It seems, setting dev-flags to 0 is not necessarily atomic w.r.t. clear_bit() and other bit operations with dev-flags. It is safer to make it atomic and this way, make the race harmless. While at it, the checking of EVENT_NO_RUNTIME_PM bit of dev-flags in usbnet_stop() was fixed too: the bit should be checked before dev-flags is cleared. The fix for this is excessive. Instead of all of this madness, looping over expensive clear_bit() atomics, just do whatever it takes to make sure that usbnet_bh() is quiesced and cannot execute any more. Then you can safely clear dev-flags normally. If I understand it correctly, it is to make sure usbnet_bh() is not scheduled again that dev-flags should be set to 0 first, one way or another. That is what this madness is for. Assuming there is a race which may reorder these, exactly what difference does it make wrt EVENT_RX_KILL if you do a) clear_bit(EVENT_RX_KILL, dev-flags); dev-flags = 0; or b) dev-flags = 0; clear_bit(EVENT_RX_KILL, dev-flags); AFAICS, the result will be a cleared EVENT_RX_KILL bit in either case. Thanks for the review! The problem is not in the reordering but rather in the fact that dev-flags = 0 is not necessarily atomic w.r.t. clear_bit(EVENT_RX_KILL, dev-flags), and vice versa. So the following might be possible, although unlikely: CPU0 CPU1 clear_bit: read dev-flags clear_bit: clear EVENT_RX_KILL in the read value dev-flags=0; clear_bit: write updated dev-flags As a result, dev-flags may become non-zero again. I cannot prove yet that this is an impossible situation. If anyone can, please explain. If so, this part of the patch will not be needed. The EVENT_NO_RUNTIME_PM bug should definitely be fixed. Please split that out as a separate fix. It's a separate issue, and should be backported to all maintained stable releases it applies to (anything from v3.8 and newer) Yes, that makes sense. However, this fix was originally provided by Oliver Neukum rather than me, so I would like to hear his opinion as well first. Bjørn Regards, Eugene -- 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 v4 3/5] gadget: Support for the usb charger framework
Hello. On 8/19/2015 12:13 PM, Baolin Wang wrote: For supporting the usb charger, it adds the usb_charger_init() and usb_charger_exit() functions for usb charger initialization and exit. Introduce a callback 'get_charger_type' which will implemented by user for usb gadget operations to get the usb charger type. Signed-off-by: Baolin Wang baolin.w...@linaro.org [...] diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 755e8bc..44d82f5 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -537,6 +537,7 @@ struct usb_gadget_ops { struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); + enum usb_charger_type (*get_charger_type)(struct usb_gadget *); ^^^ please use space, not tab here }; /** @@ -611,6 +612,7 @@ struct usb_gadget { struct usb_otg_caps *otg_caps; struct raw_notifier_headnh; struct mutexlock; + struct usb_charger *uchger; Why not simply call the field 'charger'? :-) [...] WBR, Sergei -- 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 4/5] xhci: mediatek: support MTK xHCI host controller
Hi On Mon, 2015-08-17 at 18:07 +0300, Mathias Nyman wrote: Hi On 07.08.2015 15:30, Chunfeng Yun wrote: MTK xhci host controller defines some extra SW scheduling parameters for HW to minimize the scheduling effort for synchronous and interrupt endpoints. The parameters are put into reseved DWs of slot context and endpoint context ... + * The TD size is the number of max packet sized packets remaining in the TD + * (including this TRB), right shifted by 10. + * It must fit in bits 21:17, so it can't be bigger than 31. + */ +u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total, + unsigned trb_buffer_length, struct urb *urb) +{ + u32 max = 31; + int remainder, td_packet_count, packet_transferred; + unsigned int td_transfer_size = urb-transfer_buffer_length; + unsigned int maxp; + + maxp = GET_MAX_PACKET(usb_endpoint_maxp(urb-ep-desc)); + + /* 0 for the last TRB */ + if (td_running_total + trb_buffer_length == td_transfer_size) + return 0; + + packet_transferred = td_running_total / maxp; + td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp); + remainder = td_packet_count - packet_transferred; + + if (remainder max) + return max 17; + else + return remainder 17; +} I started looking at this xhci_mtk_td_remainder() function, one of the places this patch touches the existing xhci code. The remainder functions in xhci are already bit too messy, and adding one more function which does almost the same thing makes it even messier. For example queuing a bulk transfer will end up like this: /* Set the TRB length, TD size, and interrupter fields. */ if (xhci-hci_version 0x100) { - remainder = xhci_td_remainder( + if (xhci-quirks XHCI_MTK_HOST) { + remainder = xhci_mtk_td_remainder_quirk( + running_total, trb_buff_len, urb); + } else { + remainder = xhci_td_remainder( urb-transfer_buffer_length - running_total); + } } else { remainder = xhci_v1_0_td_remainder(running_total, trb_buff_len, total_packet_count, urb, and similar for isoc and control transfers. I'll see if I can simplify the existing remainder calculations into one function, then it should be enough to just add something like this into it: if (xhci-quirks XHCI_MTK_HOST) trb_buff_len = 0; This way we can skip all the extra hassle that comes with a new exported quirk function Is the Mediatek xhci really a xHCI 0.96 or older controller? (hci_version 0x100) Not a xHCI 1.0 or 1.1 ? It is xHCI 0.96, but add some feature of xHCI 1.0 Thanks a lot -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: composite: fill bcdUSB for any gadget max speed
Hi, On Wed, Aug 19, 2015 at 11:00:54AM +0200, Igor Kotrasinski wrote: On 08/18/2015 05:42 PM, Felipe Balbi wrote: On Tue, Aug 18, 2015 at 11:06:32AM -0400, Alan Stern wrote: On Tue, 18 Aug 2015, Igor Kotrasinski wrote: When handling device GET_DESCRIPTOR, composite gadget driver fills the bcdUSB field only if the gadget supports USB 3.0. Otherwise the field is left unfilled. Make behaviour consistent by filling bcdUSB for the other two cases of USB 2.0 and USB 1.1 capable gadgets. Given that legacy gadget drivers set bcdUSB manually, it makes sense to place the entire logic in the composite gadget driver. Signed-off-by: Igor Kotrasinski i.kotrasi...@samsung.com --- drivers/usb/gadget/composite.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 58b4657..6eac055 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1499,6 +1499,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } else { cdev-desc.bcdUSB = cpu_to_le16(0x0210); } + } else if (gadget_is_dualspeed(gadget)) { + cdev-desc.bcdUSB = cpu_to_le16(0x0200); + } else { + cdev-desc.bcdUSB = cpu_to_le16(0x0110); } I would argue that there's no need to check gadget_is_dualspeed(); bcdUSB should always be set to 0x0200. After all, the spec explicitly permits USB-2.0 devices to run only at full speed. we should actually set it to 0x0210 so we get to send BOS descriptors :-) If I understand it correctly then, gadget-max_speed isn't any indicator of supported standard? well, it's an indicator of speed. Either way, some else block definitely should be there. I don't follow why 0x0210 is appropriate for all other gadget speeds; could you please, if possible, elaborate? not all. You need to support BOS descriptor and LPM to use 0x0210. If current udc supports that, there's no reason not to tell host we're 0x0210. -- balbi signature.asc Description: Digital signature
Re: [PATCH v4 5/5] power: wm831x_power: Support USB charger current limit management
On Wed, Aug 19, 2015 at 05:13:48PM +0800, Baolin Wang wrote: Integrate with the newly added USB charger interface to limit the current we draw from the USB input based on the input device configuration identified by the USB stack, allowing us to charge more quickly from high current inputs without drawing more current than specified from others. Signed-off-by: Mark Brown broo...@kernel.org Signed-off-by: Baolin Wang baolin.w...@linaro.org When people (like Charles and Lee have) have reviewed a change you should add any tags they gave when you resend the change so they don't have to duplicate their work and other people know that the review has happened. signature.asc Description: Digital signature
Re: USB, TTY, char/misc, and Staging trees now closed for 4.3
2015-08-19 11:52 GMT-03:00 Greg KH gre...@linuxfoundation.org: Given that 4.2 will be out in a few days, it's time to close my trees for new patches until 4.3-rc1 is out. Ok -- Albino B Neto Debian. Freedom to code. Code to freedom! faw twitter.com/b1n0anb gplus.to/AlbinoBNeto -- 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
USB, TTY, char/misc, and Staging trees now closed for 4.3
Hi all, Given that 4.2 will be out in a few days, it's time to close my trees for new patches until 4.3-rc1 is out. Please feel free to send me patches for these trees, but note that I'll be ignoring them until 4.3-rc1 is out, at which point in time I'll start reviewing them again and applying them to the various places they belong. 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 1/1] USB:option:add ZTE PIDs
This is intended to add ZTE device PIDs on kernel. Signed-off-by: Liu.Zhao lzsos...@163.com --- drivers/usb/serial/option.c | 36 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 876423b..e26db28 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -278,13 +278,17 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 -#define ZTE_PRODUCT_AC2726 0xfff1 -#define ZTE_PRODUCT_MG880 0xfffd -#define ZTE_PRODUCT_CDMA_TECH 0xfffe -#define ZTE_PRODUCT_AC8710T0x +#define ZTE_PRODUCT_ZM8620_X 0x0396 +#define ZTE_PRODUCT_ME3620_MBIM0x0426 +#define ZTE_PRODUCT_ME3620_X 0x1432 +#define ZTE_PRODUCT_ME3620_L 0x1433 #define ZTE_PRODUCT_MC2718 0xffe8 #define ZTE_PRODUCT_AD3812 0xffeb #define ZTE_PRODUCT_MC2716 0xffed +#define ZTE_PRODUCT_AC2726 0xfff1 +#define ZTE_PRODUCT_MG880 0xfffd +#define ZTE_PRODUCT_CDMA_TECH 0xfffe +#define ZTE_PRODUCT_AC8710T0x #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -544,6 +548,14 @@ static const struct option_blacklist_info zte_mc2716_z_blacklist = { .sendsetup = BIT(1) | BIT(2) | BIT(3), }; +static const struct option_blacklist_info zte_me3620andzm8620_xl_blacklist = { + .reserved = BIT(3) | BIT(4) | BIT(5), +}; + +static const struct option_blacklist_info zte_me3620_mbim_blacklist = { + .reserved = BIT(2) | BIT(3) | BIT(4), +}; + static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; @@ -1581,16 +1593,24 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff9, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfffb, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfffc, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MG880, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), -.driver_info = (kernel_ulong_t)zte_mc2718_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)zte_ad3812_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)zte_mc2716_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), +.driver_info = (kernel_ulong_t)zte_mc2718_z_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MG880, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), +.driver_info = (kernel_ulong_t)zte_me3620andzm8620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), +.driver_info = (kernel_ulong_t)zte_me3620andzm8620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), +.driver_info = (kernel_ulong_t)zte_me3620andzm8620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), +.driver_info = (kernel_ulong_t)zte_me3620_mbim_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, -- 1.9.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 3/3] power: wm831x_power: Support USB charger current limit management
On Wed, Aug 19, 2015 at 08:02:37AM +0800, Peter Chen wrote: Below code may be correct for the goal you expressed. for (i = 0; i ARRAY_SIZE(wm831x_usb_limits); i++) { if (limit = wm831x_usb_limits[i] wm831x_usb_limits[best] wm831x_usb_limits[i]) best = i; } Yes, that's right. signature.asc Description: Digital signature
Re: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA
On Sat, Aug 15, 2015 at 1:05 PM, Arnd Bergmann a...@arndb.de wrote: On Saturday 08 August 2015 13:31:02 Duc Dang wrote: If we know that pdev-dev.dma_mask will always be initialised at this point, then the above change is fine. If not, it's introducing a regression - dma_set_mask_and_coherent() will fail if pdev-dev.dma_mask is NULL (depending on the architectures implementation of dma_set_mask()). Prefixing the above change with the two lines I mention above would ensure equivalent behaviour. Even if we do want to get rid of this, I'd advise to do it as a separate patch after this change, which can be independently reverted if there's problems with its removal. Hi Russell, I will add the 2 lines you mentioned back to next version of the patch. It is safer to do it that way as I do not see pdev-dev.dma_mask gets initialized before the call dma_set_mask_and_coherent inside this xhci_plat.c file. It would be good to add a WARN_ON() to the case where dma_mask is a NULL pointer at the least. That way, we will at least find out if there are some broken platforms that do not correctly initialize the mask pointer. Hi Arnd, So the check will look like this, please let me know what do you think: if (!pdev-dev.dma_mask) { WARN_ON(1); /* Initialize dma_mask if the broken platform code has not done so */ pdev-dev.dma_mask = pdev-dev.coherent_dma_mask; } Arnd -- Regards, Duc Dang. -- 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: ehci-platform: Add ACPI bindings for the EHCI platform driver.
This enables USB on the ARM juno board when booted with an ACPI kernel. The PNP id comes from the PNP/ACPI registry and describes an EHCI controller without debug. Tested-by: Huang Shijie shijie.hu...@arm.com Reviewed-by: Graeme Gregory graeme.greg...@linaro.org Reviewed-by: Hanjun Guo hanjun@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Signed-off-by: Jeremy Linton jeremy.lin...@arm.com --- drivers/usb/host/ehci-platform.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 3ce38c3..9680a5d 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -19,6 +19,7 @@ * * Licensed under the GNU/GPL. See COPYING for details. */ +#include linux/acpi.h #include linux/clk.h #include linux/dma-mapping.h #include linux/err.h @@ -382,6 +383,12 @@ static const struct of_device_id vt8500_ehci_ids[] = { }; MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); +static const struct acpi_device_id ehci_acpi_match[] = { + { PNP0D20, 0 }, /* EHCI controller without debug */ + { } +}; +MODULE_DEVICE_TABLE(acpi, ehci_acpi_match); + static const struct platform_device_id ehci_platform_table[] = { { ehci-platform, 0 }, { } @@ -400,6 +407,7 @@ static struct platform_driver ehci_platform_driver = { .name = ehci-platform, .pm = ehci_platform_pm_ops, .of_match_table = vt8500_ehci_ids, + .acpi_match_table = ACPI_PTR(ehci_acpi_match), } }; -- 2.4.3 -- 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
[PATCHv2 0/2] USB: Enable EHCI-platform driver for use with ACPI
This patch set enables USB on the ARM Juno development platform when using an ACPI kernel. First it adds an error message if the device cannot be configured with the current DMA settings (missing/unsupported CCA attribute). It then adds the ACPI PNP id to the acpi_match_table entry. Tested-by: Huang Shijie shijie.hu...@arm.com Reviewed-by: Graeme Gregory graeme.greg...@linaro.org Reviewed-by: Hanjun Guo hanjun@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Signed-off-by: Jeremy Linton jeremy.lin...@arm.com Jeremy Linton (2): USB: ehci-platform: Display a DMA configuration error message USB: ehci-platform: Add ACPI bindings for the EHCI platform driver. drivers/usb/host/ehci-platform.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) -- 2.4.3 -- 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: ehci-platform: Display a DMA configuration error message
If the ehci driver fails to configure the dma settings then display a dev error instead of simply failing. This is triggered in an ACPI world if the user fails to set the _CCA on the device. Tested-by: Huang Shijie shijie.hu...@arm.com Reviewed-by: Graeme Gregory graeme.greg...@linaro.org Reviewed-by: Hanjun Guo hanjun@linaro.org Acked-by: Alan Stern st...@rowland.harvard.edu Signed-off-by: Jeremy Linton jeremy.lin...@arm.com --- drivers/usb/host/ehci-platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 2593def..3ce38c3 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev) err = dma_coerce_mask_and_coherent(dev-dev, pdata-dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); - if (err) + if (err) { + dev_err(dev-dev, Error: DMA mask configuration failed\n); return err; + } irq = platform_get_irq(dev, 0); if (irq 0) { -- 2.4.3 -- 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: [v1,1/1] mpc512x: silence a USB Kconfig dependency warning
On Mon, 2013-03-06 at 11:18:06 UTC, Gerhard Sittig wrote: the PPC_MPC512x config automatically selected USB_EHCI_BIG_ENDIAN_* switches, which made Kconfig warn about unmet direct dependencies: scripts/kconfig/conf --silentoldconfig Kconfig warning: (PPC_MPC512x 440EPX) selects USB_EHCI_BIG_ENDIAN_DESC which has unmet direct dependencies (USB_SUPPORT USB USB_EHCI_HCD) warning: (PPC_MPC512x PPC_PS3 PPC_CELLEB 440EPX) selects USB_EHCI_BIG_ENDIAN_MMIO which has unmet direct dependencies (USB_SUPPORT USB USB_EHCI_HCD) warning: (PPC_MPC512x 440EPX) selects USB_EHCI_BIG_ENDIAN_DESC which has unmet direct dependencies (USB_SUPPORT USB USB_EHCI_HCD) warning: (PPC_MPC512x PPC_PS3 PPC_CELLEB 440EPX) selects USB_EHCI_BIG_ENDIAN_MMIO which has unmet direct dependencies (USB_SUPPORT USB USB_EHCI_HCD) make the selected entries additionally depend on USB_EHCI_HCD which silences the warning Signed-off-by: Gerhard Sittig g...@denx.de Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/acf6cec8365bfe1e6435 cheers -- 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 v4 5/5] power: wm831x_power: Support USB charger current limit management
On 20 August 2015 at 00:24, Mark Brown broo...@kernel.org wrote: On Wed, Aug 19, 2015 at 05:13:48PM +0800, Baolin Wang wrote: Integrate with the newly added USB charger interface to limit the current we draw from the USB input based on the input device configuration identified by the USB stack, allowing us to charge more quickly from high current inputs without drawing more current than specified from others. Signed-off-by: Mark Brown broo...@kernel.org Signed-off-by: Baolin Wang baolin.w...@linaro.org When people (like Charles and Lee have) have reviewed a change you should add any tags they gave when you resend the change so they don't have to duplicate their work and other people know that the review has happened. Make sense. Thanks. -- Baolin.wang Best Regards -- 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 v4 3/5] gadget: Support for the usb charger framework
On 19 August 2015 at 20:56, Sergei Shtylyov sergei.shtyl...@cogentembedded.com wrote: Hello. On 8/19/2015 12:13 PM, Baolin Wang wrote: For supporting the usb charger, it adds the usb_charger_init() and usb_charger_exit() functions for usb charger initialization and exit. Introduce a callback 'get_charger_type' which will implemented by user for usb gadget operations to get the usb charger type. Signed-off-by: Baolin Wang baolin.w...@linaro.org [...] diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 755e8bc..44d82f5 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -537,6 +537,7 @@ struct usb_gadget_ops { struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); + enum usb_charger_type (*get_charger_type)(struct usb_gadget *); ^^^ please use space, not tab here OK. }; /** @@ -611,6 +612,7 @@ struct usb_gadget { struct usb_otg_caps *otg_caps; struct raw_notifier_headnh; struct mutexlock; + struct usb_charger *uchger; Why not simply call the field 'charger'? :-) I think 'uchger' is the abbreviation of 'usb charger' which is maybe a little verbous, I'll change it. Thanks for your comments. [...] WBR, Sergei -- Baolin.wang Best Regards -- 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 v4 5/5] power: wm831x_power: Support USB charger current limit management
On 19 August 2015 at 17:56, Lee Jones lee.jo...@linaro.org wrote: On Wed, 19 Aug 2015, Baolin Wang wrote: Integrate with the newly added USB charger interface to limit the current we draw from the USB input based on the input device configuration identified by the USB stack, allowing us to charge more quickly from high current inputs without drawing more current than specified from others. Signed-off-by: Mark Brown broo...@kernel.org Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/power/wm831x_power.c | 69 ++ include/linux/mfd/wm831x/pdata.h |3 ++ I'm not going to keep reviewing this. You should carry forward any Acks received onto subsequent submissions yourself. OK, thanks. 2 files changed, 72 insertions(+) diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index db11ae6..72c661f 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -13,6 +13,7 @@ #include linux/platform_device.h #include linux/power_supply.h #include linux/slab.h +#include linux/usb/usb_charger.h #include linux/mfd/wm831x/core.h #include linux/mfd/wm831x/auxadc.h @@ -31,6 +32,8 @@ struct wm831x_power { char usb_name[20]; char battery_name[20]; bool have_battery; + struct usb_charger *usb_charger; + struct notifier_block usb_notify; }; static int wm831x_power_check_online(struct wm831x *wm831x, int supply, @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_NOW, }; +/* In miliamps */ +static unsigned int wm831x_usb_limits[] = { + 0, + 2, + 100, + 500, + 900, + 1500, + 1800, + 550, +}; + +static int wm831x_usb_limit_change(struct notifier_block *nb, +unsigned long limit, void *data) +{ + struct wm831x_power *wm831x_power = container_of(nb, + struct wm831x_power, + usb_notify); + int i, best; + + /* Find the highest supported limit */ + best = 0; + for (i = 0; i ARRAY_SIZE(wm831x_usb_limits); i++) { + if (limit wm831x_usb_limits[i] + wm831x_usb_limits[best] wm831x_usb_limits[i]) + best = i; + } + + dev_dbg(wm831x_power-wm831x-dev, + Limiting USB current to %dmA, wm831x_usb_limits[best]); + + wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE, + WM831X_USB_ILIM_MASK, best); + + return 0; +} + /* * Battery properties */ @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device *pdev) } } + if (wm831x_pdata wm831x_pdata-usb_gadget) { + power-usb_charger = + usb_charger_find_by_name(wm831x_pdata-usb_gadget); + if (IS_ERR(power-usb_charger)) { + ret = PTR_ERR(power-usb_charger); + dev_err(pdev-dev, + Failed to find USB gadget: %d\n, ret); + goto err_bat_irq; + } + + power-usb_notify.notifier_call = wm831x_usb_limit_change; + + ret = usb_charger_register_notify(power-usb_charger, + power-usb_notify); + if (ret != 0) { + dev_err(pdev-dev, + Failed to register notifier: %d\n, ret); + goto err_usb_charger; + } + } + return ret; +err_usb_charger: + usb_charger_put(power-usb_charger); err_bat_irq: --i; for (; i = 0; i--) { @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device *pdev) struct wm831x *wm831x = wm831x_power-wm831x; int irq, i; + if (wm831x_power-usb_charger) { + usb_charger_unregister_notify(wm831x_power-usb_charger, + wm831x_power-usb_notify); + usb_charger_put(wm831x_power-usb_charger); + } + for (i = 0; i ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index dcc9631..5af8399 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -126,6 +126,9 @@ struct wm831x_pdata { /** The driver should initiate a power off sequence during shutdown */ bool soft_shutdown; + /** dev_name of USB charger gadget to integrate with */ + const char *usb_gadget; + int
Re: [PATCH] usbnet: Fix two races between usbnet_stop() and the BH
Eugene Shatokhin eugene.shatok...@rosalab.ru writes: 19.08.2015 04:54, David Miller пишет: From: Eugene Shatokhin eugene.shatok...@rosalab.ru Date: Fri, 14 Aug 2015 19:58:36 +0300 2. The second race is on dev-flags. dev-flags is set to 0 here: *0 usbnet_stop (usbnet.c:816) /* deferred work (task, timer, softirq) must also stop. * can't flush_scheduled_work() until we drop rtnl (later), * else workers could deadlock; so make workers a NOP. */ dev-flags = 0; del_timer_sync (dev-delay); tasklet_kill (dev-bh); And here, the code clears EVENT_RX_KILL bit in dev-flags, which may execute concurrently with the above operation: *0 clear_bit (bitops.h:113, inlined) *1 usbnet_bh (usbnet.c:1475) /* restart RX again after disabling due to high error rate */ clear_bit(EVENT_RX_KILL, dev-flags); It seems, setting dev-flags to 0 is not necessarily atomic w.r.t. clear_bit() and other bit operations with dev-flags. It is safer to make it atomic and this way, make the race harmless. While at it, the checking of EVENT_NO_RUNTIME_PM bit of dev-flags in usbnet_stop() was fixed too: the bit should be checked before dev-flags is cleared. The fix for this is excessive. Instead of all of this madness, looping over expensive clear_bit() atomics, just do whatever it takes to make sure that usbnet_bh() is quiesced and cannot execute any more. Then you can safely clear dev-flags normally. If I understand it correctly, it is to make sure usbnet_bh() is not scheduled again that dev-flags should be set to 0 first, one way or another. That is what this madness is for. Assuming there is a race which may reorder these, exactly what difference does it make wrt EVENT_RX_KILL if you do a) clear_bit(EVENT_RX_KILL, dev-flags); dev-flags = 0; or b) dev-flags = 0; clear_bit(EVENT_RX_KILL, dev-flags); AFAICS, the result will be a cleared EVENT_RX_KILL bit in either case. The EVENT_NO_RUNTIME_PM bug should definitely be fixed. Please split that out as a separate fix. It's a separate issue, and should be backported to all maintained stable releases it applies to (anything from v3.8 and newer) Bjørn -- 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 3/8][v3]usb:fsl:otg: Add support to add/remove usb host driver
-Original Message- From: Alan Stern [mailto:st...@rowland.harvard.edu] Sent: Friday, August 14, 2015 12:17 AM To: Mehresh Ramneek-B31383 ramneek.mehr...@freescale.com Cc: linux-ker...@vger.kernel.org; ba...@ti.com; gre...@linuxfoundation.org; linux-usb@vger.kernel.org; Li Yang-Leo-R58472 le...@freescale.com Subject: Re: [PATCH 3/8][v3]usb:fsl:otg: Add support to add/remove usb host driver On Thu, 13 Aug 2015, Ramneek Mehresh wrote: Add workqueue to add/remove host driver (outside interrupt context) upon each id change. Signed-off-by: Li Yang le...@freescale.com Signed-off-by: Ramneek Mehresh ramneek.mehr...@freescale.com --- Changes for v3: - removed CONFIG_FSL_USB2_OTG and CONFIG_FSL_USB2_OTG_MODULE macros - removed call to usb_hcd_resume_root_hub(hcd) from ehci_fsl_drv_resume() drivers/usb/host/ehci-fsl.c | 71 - drivers/usb/host/ehci-fsl.h | 18 2 files changed, 69 insertions(+), 20 deletions(-) static int ehci_fsl_drv_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); void __iomem *non_ehci = hcd-regs; + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); + struct usb_bus host = hcd-self; I just noticed this line. It does not look right at all; it does a structure copy instead of copying a pointer. my bad...will change to struct usb_bus *host = hcd-self; if (of_device_is_compatible(dev-parent-of_node, fsl,mpc5121-usb2-dr)) { return ehci_fsl_mpc512x_drv_suspend(dev); } + if (host.is_otg) { + /* remove hcd */ + ehci_fsl-hcd_add = 0; + schedule_work(ehci_fsl-change_hcd_work); + host.is_otg = 0; And here you turn off the flag in the local copy of the structure, which accomplishes nothing. agree...will change to host-is_otg = 0; + return 0; + } + ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), device_may_wakeup(dev)); if (!fsl_deep_sleep()) @@ -557,15 +579,24 @@ static int ehci_fsl_drv_suspend(struct device *dev) static int ehci_fsl_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd); void __iomem *non_ehci = hcd-regs; + struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd); + struct usb_bus host = hcd-self; Same here. agree --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -63,4 +63,22 @@ #define UTMI_PHY_EN (19) #define ULPI_PHY_CLK_SEL(110) #define PHY_CLK_VALID (117) + +struct ehci_fsl { +#ifdef CONFIG_PM + /* Saved USB PHY settings, need to restore after deep sleep. */ + u32 usb_ctrl; +#endif Do you need this #ifdef? Yes, this is required for deep-sleep support...we need to save/restore controller registers during deep-sleep when usb controller power is shut-off. Don't need this during normal usb operation...saving/restoring usb controller registers in non deep-sleep scenario will add unnecessary delays Alan Stern -- 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] usbnet: Fix two races between usbnet_stop() and the BH
19.08.2015 04:54, David Miller пишет: From: Eugene Shatokhin eugene.shatok...@rosalab.ru Date: Fri, 14 Aug 2015 19:58:36 +0300 2. The second race is on dev-flags. dev-flags is set to 0 here: *0 usbnet_stop (usbnet.c:816) /* deferred work (task, timer, softirq) must also stop. * can't flush_scheduled_work() until we drop rtnl (later), * else workers could deadlock; so make workers a NOP. */ dev-flags = 0; del_timer_sync (dev-delay); tasklet_kill (dev-bh); And here, the code clears EVENT_RX_KILL bit in dev-flags, which may execute concurrently with the above operation: *0 clear_bit (bitops.h:113, inlined) *1 usbnet_bh (usbnet.c:1475) /* restart RX again after disabling due to high error rate */ clear_bit(EVENT_RX_KILL, dev-flags); It seems, setting dev-flags to 0 is not necessarily atomic w.r.t. clear_bit() and other bit operations with dev-flags. It is safer to make it atomic and this way, make the race harmless. While at it, the checking of EVENT_NO_RUNTIME_PM bit of dev-flags in usbnet_stop() was fixed too: the bit should be checked before dev-flags is cleared. The fix for this is excessive. Instead of all of this madness, looping over expensive clear_bit() atomics, just do whatever it takes to make sure that usbnet_bh() is quiesced and cannot execute any more. Then you can safely clear dev-flags normally. If I understand it correctly, it is to make sure usbnet_bh() is not scheduled again that dev-flags should be set to 0 first, one way or another. That is what this madness is for. tasklet_kill() will wait then for the already running instance of usbnet_bh() (if one is running). After that, it is guaranteed BH is not running and will not be re-scheduled. As for the performance concerns, I doubt that usbnet_stop() is anywhere on the critical path. I have been testing this patch for some time and haven't seen any new performance issues with it yet. If needed, it is possible to measure and compare the time needed for usbnet_stop() before and after this patch and try to estimate the impact of this on the overall performance. Regards, Eugene -- 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: composite: fill bcdUSB for any gadget max speed
On 08/18/2015 05:42 PM, Felipe Balbi wrote: On Tue, Aug 18, 2015 at 11:06:32AM -0400, Alan Stern wrote: On Tue, 18 Aug 2015, Igor Kotrasinski wrote: When handling device GET_DESCRIPTOR, composite gadget driver fills the bcdUSB field only if the gadget supports USB 3.0. Otherwise the field is left unfilled. Make behaviour consistent by filling bcdUSB for the other two cases of USB 2.0 and USB 1.1 capable gadgets. Given that legacy gadget drivers set bcdUSB manually, it makes sense to place the entire logic in the composite gadget driver. Signed-off-by: Igor Kotrasinski i.kotrasi...@samsung.com --- drivers/usb/gadget/composite.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 58b4657..6eac055 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1499,6 +1499,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } else { cdev-desc.bcdUSB = cpu_to_le16(0x0210); } + } else if (gadget_is_dualspeed(gadget)) { + cdev-desc.bcdUSB = cpu_to_le16(0x0200); + } else { + cdev-desc.bcdUSB = cpu_to_le16(0x0110); } I would argue that there's no need to check gadget_is_dualspeed(); bcdUSB should always be set to 0x0200. After all, the spec explicitly permits USB-2.0 devices to run only at full speed. we should actually set it to 0x0210 so we get to send BOS descriptors :-) If I understand it correctly then, gadget-max_speed isn't any indicator of supported standard? Either way, some else block definitely should be there. I don't follow why 0x0210 is appropriate for all other gadget speeds; could you please, if possible, elaborate? Igor Kotrasinski -- 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 v4 2/5] gadget: Introduce the usb charger framework
This patch introduces the usb charger driver based on usb gadget that makes an enhancement to a power driver. It works well in practice but that requires a system with suitable hardware. The basic conception of the usb charger is that, when one usb charger is added or removed by reporting from the usb gadget state change or the extcon device state change, the usb charger will report to power user to set the current limitation. The usb charger will register notifiees on the usb gadget or the extcon device to get notified the usb charger state. Power user will register a notifiee on the usb charger to get notified by status changes from the usb charger. It will report to power user to set the current limitation when detecting the usb charger is added or removed from extcon device state or usb gadget state. Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/usb/gadget/Kconfig |7 + drivers/usb/gadget/Makefile |1 + drivers/usb/gadget/charger.c| 529 +++ include/linux/usb/usb_charger.h | 138 ++ 4 files changed, 675 insertions(+) create mode 100644 drivers/usb/gadget/charger.c create mode 100644 include/linux/usb/usb_charger.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bcf83c0..3d2b959 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -127,6 +127,13 @@ config USB_GADGET_STORAGE_NUM_BUFFERS a module parameter as well. If unsure, say 2. +config USB_CHARGER + bool USB charger support + help + The usb charger driver based on the usb gadget that makes an + enhancement to a power driver which can set the current limitation + when the usb charger is added or removed. + source drivers/usb/gadget/udc/Kconfig # diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 598a67d..1e421c1 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -10,3 +10,4 @@ libcomposite-y:= usbstring.o config.o epautoconf.o libcomposite-y += composite.o functions.o configfs.o u_f.o obj-$(CONFIG_USB_GADGET) += udc/ function/ legacy/ +obj-$(CONFIG_USB_CHARGER) += charger.o diff --git a/drivers/usb/gadget/charger.c b/drivers/usb/gadget/charger.c new file mode 100644 index 000..35b46c1 --- /dev/null +++ b/drivers/usb/gadget/charger.c @@ -0,0 +1,529 @@ +/* + * charger.c -- USB charger driver + * + * Copyright (C) 2015 Linaro Ltd. + * + * 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. + */ + +#include linux/device.h +#include linux/err.h +#include linux/extcon.h +#include linux/export.h +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/of_device.h +#include linux/of_address.h +#include linux/platform_device.h +#include linux/slab.h +#include linux/usb.h +#include linux/usb/ch9.h +#include linux/usb/gadget.h +#include linux/usb/usb_charger.h + +#define DEFAULT_CUR_PROTECT(50) +#define DEFAULT_SDP_CUR_LIMIT (500 - DEFAULT_CUR_PROTECT) +#define DEFAULT_DCP_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) +#define DEFAULT_CDP_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) +#define DEFAULT_ACA_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) + +static DEFINE_IDA(usb_charger_ida); +static struct bus_type usb_charger_subsys = { + .name = usb-charger, + .dev_name = usb-charger, +}; + +static struct usb_charger *dev_to_uchger(struct device *udev) +{ + return container_of(udev, struct usb_charger, dev); +} + +static ssize_t cur_limit_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct usb_charger *uchger = dev_to_uchger(dev); + + return scnprintf(buf, PAGE_SIZE, %d %d %d %d\n, +uchger-cur_limit.sdp_cur_limit, +uchger-cur_limit.dcp_cur_limit, +uchger-cur_limit.cdp_cur_limit, +uchger-cur_limit.aca_cur_limit); +} + +static ssize_t cur_limit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_charger *uchger = dev_to_uchger(dev); + struct usb_charger_cur_limit cur; + int ret; + + ret = sscanf(buf, %d %d %d %d, +cur.sdp_cur_limit, cur.dcp_cur_limit, +cur.cdp_cur_limit, cur.aca_cur_limit); + if (ret == 0) + return -EINVAL; + + ret = usb_charger_set_cur_limit(uchger, cur); + if (ret 0) + return ret; + + return count; +} +static DEVICE_ATTR_RW(cur_limit); + +static struct attribute *usb_charger_attrs[] = { + dev_attr_cur_limit.attr, + NULL +};
[PATCH v4 3/5] gadget: Support for the usb charger framework
For supporting the usb charger, it adds the usb_charger_init() and usb_charger_exit() functions for usb charger initialization and exit. Introduce a callback 'get_charger_type' which will implemented by user for usb gadget operations to get the usb charger type. Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/usb/gadget/udc/udc-core.c |8 include/linux/usb/gadget.h|2 ++ 2 files changed, 10 insertions(+) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index 4238fc3..370376e 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -28,6 +28,7 @@ #include linux/usb/ch9.h #include linux/usb/gadget.h #include linux/usb.h +#include linux/usb/usb_charger.h /** * struct usb_udc - describes one usb device controller @@ -437,8 +438,14 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, mutex_unlock(udc_lock); + ret = usb_charger_init(gadget); + if (ret) + goto err5; + return 0; +err5: + device_del(udc-dev); err4: list_del(udc-list); mutex_unlock(udc_lock); @@ -513,6 +520,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget) kobject_uevent(udc-dev.kobj, KOBJ_REMOVE); flush_work(gadget-work); device_unregister(udc-dev); + usb_charger_exit(gadget); device_unregister(gadget-dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 755e8bc..44d82f5 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -537,6 +537,7 @@ struct usb_gadget_ops { struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); + enum usb_charger_type (*get_charger_type)(struct usb_gadget *); }; /** @@ -611,6 +612,7 @@ struct usb_gadget { struct usb_otg_caps *otg_caps; struct raw_notifier_headnh; struct mutexlock; + struct usb_charger *uchger; unsignedsg_supported:1; unsignedis_otg:1; -- 1.7.9.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 v4 4/5] gadget: Integrate with the usb gadget supporting for usb charger
When the usb gadget supporting for usb charger is ready, the usb charger should get the type by the 'get_charger_type' callback which is implemented by the usb gadget operations, and get the usb charger pointer from struct 'usb_gadget'. Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/usb/gadget/charger.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/charger.c b/drivers/usb/gadget/charger.c index 35b46c1..93fd36f 100644 --- a/drivers/usb/gadget/charger.c +++ b/drivers/usb/gadget/charger.c @@ -181,6 +181,13 @@ int usb_charger_unregister_notify(struct usb_charger *uchger, enum usb_charger_type usb_charger_detect_type(struct usb_charger *uchger) { + if (uchger-gadget uchger-gadget-ops +uchger-gadget-ops-get_charger_type) + uchger-type = + uchger-gadget-ops-get_charger_type(uchger-gadget); + else + uchger-type = UNKNOWN_TYPE; + return uchger-type; } @@ -313,7 +320,8 @@ static int usb_charger_plug_by_gadget(struct notifier_block *nb, unsigned long state, void *data) { - struct usb_charger *uchger = NULL; + struct usb_gadget *gadget = (struct usb_gadget *)data; + struct usb_charger *uchger = gadget-uchger; enum usb_charger_state uchger_state; if (!uchger) @@ -480,6 +488,7 @@ int usb_charger_init(struct usb_gadget *ugadget) /* register a notifier on a usb gadget device */ uchger-gadget = ugadget; + ugadget-uchger = uchger; uchger-old_gadget_state = ugadget-state; uchger-gadget_nb.notifier_call = usb_charger_plug_by_gadget; usb_gadget_register_notify(ugadget, uchger-gadget_nb); @@ -503,7 +512,7 @@ fail: int usb_charger_exit(struct usb_gadget *ugadget) { - struct usb_charger *uchger = NULL; + struct usb_charger *uchger = ugadget-uchger; if (!uchger) return -EINVAL; -- 1.7.9.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 v4 1/5] gadget: Introduce the notifier functions
The usb charger framework is based on usb gadget. The usb charger need to be notified the state changing of usb gadget to confirm the usb charger state. Thus this patch adds a notifier mechanism for usb gadget to report a event to usb charger when the usb gadget state is changed. Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/usb/gadget/udc/udc-core.c | 32 include/linux/usb/gadget.h| 18 ++ 2 files changed, 50 insertions(+) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index f660afb..4238fc3 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -129,6 +129,32 @@ void usb_gadget_giveback_request(struct usb_ep *ep, } EXPORT_SYMBOL_GPL(usb_gadget_giveback_request); +int usb_gadget_register_notify(struct usb_gadget *gadget, + struct notifier_block *nb) +{ + int ret; + + mutex_lock(gadget-lock); + ret = raw_notifier_chain_register(gadget-nh, nb); + mutex_unlock(gadget-lock); + + return ret; +} +EXPORT_SYMBOL_GPL(usb_gadget_register_notify); + +int usb_gadget_unregister_notify(struct usb_gadget *gadget, +struct notifier_block *nb) +{ + int ret; + + mutex_lock(gadget-lock); + ret = raw_notifier_chain_unregister(gadget-nh, nb); + mutex_unlock(gadget-lock); + + return ret; +} +EXPORT_SYMBOL_GPL(usb_gadget_unregister_notify); + /* - */ /** @@ -226,6 +252,10 @@ static void usb_gadget_state_work(struct work_struct *work) struct usb_gadget *gadget = work_to_gadget(work); struct usb_udc *udc = gadget-udc; + mutex_lock(gadget-lock); + raw_notifier_call_chain(gadget-nh, gadget-state, gadget); + mutex_unlock(gadget-lock); + if (udc) sysfs_notify(udc-dev.kobj, NULL, state); } @@ -364,6 +394,8 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, dev_set_name(gadget-dev, gadget); INIT_WORK(gadget-work, usb_gadget_state_work); + RAW_INIT_NOTIFIER_HEAD(gadget-nh); + mutex_init(gadget-lock); gadget-dev.parent = parent; #ifdef CONFIG_HAS_DMA diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index c14a69b..755e8bc 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -609,6 +609,8 @@ struct usb_gadget { unsignedout_epnum; unsignedin_epnum; struct usb_otg_caps *otg_caps; + struct raw_notifier_headnh; + struct mutexlock; unsignedsg_supported:1; unsignedis_otg:1; @@ -1183,6 +1185,22 @@ extern void usb_gadget_unmap_request(struct usb_gadget *gadget, /*-*/ +/** + * Register a notifiee to get notified by any attach status changes from + * the usb gadget + */ +int usb_gadget_register_notify(struct usb_gadget *gadget, + struct notifier_block *nb); + +/*-*/ + + +/* Unregister a notifiee from the usb gadget */ +int usb_gadget_unregister_notify(struct usb_gadget *gadget, +struct notifier_block *nb); + +/*-*/ + /* utility to set gadget state properly */ extern void usb_gadget_set_state(struct usb_gadget *gadget, -- 1.7.9.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 v4 0/5] Introduce usb charger framework to deal with the usb gadget power negotation
Currently the Linux kernel does not provide any standard integration of this feature that integrates the USB subsystem with the system power regulation provided by PMICs meaning that either vendors must add this in their kernels or USB gadget devices based on Linux (such as mobile phones) may not behave as they should. Providing a standard framework for doing this in the kernel. Now introduce one user with wm831x_power to support and test the usb charger, which is pending testing. Moreover there may be other potential users will use it in future. Changes since v3: - Re-order the patch and split the patch to avoid breaking build. - Other modifications. Baolin Wang (5): gadget: Introduce the notifier functions gadget: Introduce the usb charger framework gadget: Support for the usb charger framework gadget: Integrate with the usb gadget supporting for usb charger power: wm831x_power: Support USB charger current limit management drivers/power/wm831x_power.c | 69 + drivers/usb/gadget/Kconfig|7 + drivers/usb/gadget/Makefile |1 + drivers/usb/gadget/charger.c | 538 + drivers/usb/gadget/udc/udc-core.c | 40 +++ include/linux/mfd/wm831x/pdata.h |3 + include/linux/usb/gadget.h| 20 ++ include/linux/usb/usb_charger.h | 138 ++ 8 files changed, 816 insertions(+) create mode 100644 drivers/usb/gadget/charger.c create mode 100644 include/linux/usb/usb_charger.h -- 1.7.9.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 v4 5/5] power: wm831x_power: Support USB charger current limit management
Integrate with the newly added USB charger interface to limit the current we draw from the USB input based on the input device configuration identified by the USB stack, allowing us to charge more quickly from high current inputs without drawing more current than specified from others. Signed-off-by: Mark Brown broo...@kernel.org Signed-off-by: Baolin Wang baolin.w...@linaro.org --- drivers/power/wm831x_power.c | 69 ++ include/linux/mfd/wm831x/pdata.h |3 ++ 2 files changed, 72 insertions(+) diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index db11ae6..72c661f 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -13,6 +13,7 @@ #include linux/platform_device.h #include linux/power_supply.h #include linux/slab.h +#include linux/usb/usb_charger.h #include linux/mfd/wm831x/core.h #include linux/mfd/wm831x/auxadc.h @@ -31,6 +32,8 @@ struct wm831x_power { char usb_name[20]; char battery_name[20]; bool have_battery; + struct usb_charger *usb_charger; + struct notifier_block usb_notify; }; static int wm831x_power_check_online(struct wm831x *wm831x, int supply, @@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = { POWER_SUPPLY_PROP_VOLTAGE_NOW, }; +/* In miliamps */ +static unsigned int wm831x_usb_limits[] = { + 0, + 2, + 100, + 500, + 900, + 1500, + 1800, + 550, +}; + +static int wm831x_usb_limit_change(struct notifier_block *nb, + unsigned long limit, void *data) +{ + struct wm831x_power *wm831x_power = container_of(nb, +struct wm831x_power, +usb_notify); + int i, best; + + /* Find the highest supported limit */ + best = 0; + for (i = 0; i ARRAY_SIZE(wm831x_usb_limits); i++) { + if (limit wm831x_usb_limits[i] + wm831x_usb_limits[best] wm831x_usb_limits[i]) + best = i; + } + + dev_dbg(wm831x_power-wm831x-dev, + Limiting USB current to %dmA, wm831x_usb_limits[best]); + + wm831x_set_bits(wm831x_power-wm831x, WM831X_POWER_STATE, + WM831X_USB_ILIM_MASK, best); + + return 0; +} + /* * Battery properties */ @@ -606,8 +646,31 @@ static int wm831x_power_probe(struct platform_device *pdev) } } + if (wm831x_pdata wm831x_pdata-usb_gadget) { + power-usb_charger = + usb_charger_find_by_name(wm831x_pdata-usb_gadget); + if (IS_ERR(power-usb_charger)) { + ret = PTR_ERR(power-usb_charger); + dev_err(pdev-dev, + Failed to find USB gadget: %d\n, ret); + goto err_bat_irq; + } + + power-usb_notify.notifier_call = wm831x_usb_limit_change; + + ret = usb_charger_register_notify(power-usb_charger, + power-usb_notify); + if (ret != 0) { + dev_err(pdev-dev, + Failed to register notifier: %d\n, ret); + goto err_usb_charger; + } + } + return ret; +err_usb_charger: + usb_charger_put(power-usb_charger); err_bat_irq: --i; for (; i = 0; i--) { @@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device *pdev) struct wm831x *wm831x = wm831x_power-wm831x; int irq, i; + if (wm831x_power-usb_charger) { + usb_charger_unregister_notify(wm831x_power-usb_charger, + wm831x_power-usb_notify); + usb_charger_put(wm831x_power-usb_charger); + } + for (i = 0; i ARRAY_SIZE(wm831x_bat_irqs); i++) { irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index dcc9631..5af8399 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -126,6 +126,9 @@ struct wm831x_pdata { /** The driver should initiate a power off sequence during shutdown */ bool soft_shutdown; + /** dev_name of USB charger gadget to integrate with */ + const char *usb_gadget; + int irq_base; int gpio_base; int gpio_defaults[WM831X_GPIO_NUM]; -- 1.7.9.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