Re: [PATCH 1/1] usb: chipidea: add DMA mask configuration API
Hi Peter, [auto build test ERROR on v4.5-rc7] [also build test ERROR on next-20160324] [if your patch is applied to the wrong git tree, please drop us a note to help improving the system] url: https://github.com/0day-ci/linux/commits/Peter-Chen/usb-chipidea-add-DMA-mask-configuration-API/20160325-120535 config: i386-randconfig-s1-201612 (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): >> ERROR: "ci_hdrc_set_dma_mask" [drivers/usb/chipidea/ci_hdrc_msm.ko] >> undefined! --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: Binary data
Re: [PATCH] usb: chipidea: Configure DMA properties and ops from DT
On Tue, Mar 08, 2016 at 07:40:08PM -0800, Bjorn Andersson wrote: > On Tue, Mar 8, 2016 at 11:52 AM, Li Yangwrote: > > On Wed, Mar 2, 2016 at 4:59 PM, Li Yang wrote: > >> On Mon, Feb 22, 2016 at 4:07 PM, Bjorn Andersson > >> wrote: > >>> On Mon 22 Feb 02:03 PST 2016, Srinivas Kandagatla wrote: > >>> > > > On 22/02/16 05:32, Bjorn Andersson wrote: > >On certain platforms (e.g. ARM64) the dma_ops needs to be explicitly set > >to be able to do DMA allocations, so use the of_dma_configure() helper > >to populate the dma properties and assign an appropriate dma_ops. > [..] > None of the drivers call of_dma_configure() explicitly, which makes me > feel > that we are doing something wrong. TBH, this should be handled in more > generic way rather than driver like this having an explicit call to > of_dma_configure(). > > >>> > > I had the chance to go through this with Arnd and the verdict is that > devices not described in DT should not do DMA (or allocate buffers for > doing DMA). > > So I believe the solution is to fall back on Peter's description; the > chipidea driver is the core driver and the Qualcomm code should just > be a platform layer. > > My suggestion is that we turn the chipidea core into a set of APIs > that can called by the platform specific pieces. That way we will have > the chipidea core be the device described in the DT. > Hi Bjorn, After reading the DMA documentation Russell supplied and several related DMA APIs, would you please try below patch on your ARM64 platform? Since the core device has no device node at all, I don't know why your patch can work, or am I missing something? >From bcf7eaf694d29fb7557a9406fb6c89213216069c Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 25 Mar 2016 11:54:21 +0800 Subject: [PATCH 1/1] usb: chipidea: add DMA mask configuration API Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_msm.c |6 ++ drivers/usb/chipidea/core.c| 25 + include/linux/usb/chipidea.h |2 ++ 3 files changed, 33 insertions(+) diff --git a/drivers/usb/chipidea/ci_hdrc_msm.c b/drivers/usb/chipidea/ci_hdrc_msm.c index 3889809..43ceb38 100644 --- a/drivers/usb/chipidea/ci_hdrc_msm.c +++ b/drivers/usb/chipidea/ci_hdrc_msm.c @@ -5,6 +5,7 @@ * only version 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -56,6 +57,7 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) { struct platform_device *plat_ci; struct usb_phy *phy; + int ret; dev_dbg(>dev, "ci_hdrc_msm_probe\n"); @@ -70,6 +72,10 @@ static int ci_hdrc_msm_probe(struct platform_device *pdev) ci_hdrc_msm_platdata.usb_phy = phy; + ret = ci_hdrc_set_dma_mask(>dev, DMA_BIT_MASK(64)); + if (ret) + return ret; + plat_ci = ci_hdrc_add_device(>dev, pdev->resource, pdev->num_resources, _hdrc_msm_platdata); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 69426e6..b8ca5e3 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -811,6 +812,30 @@ static void ci_extcon_unregister(struct ci_hdrc *ci) static DEFINE_IDA(ci_ida); +/** + * ci_hdrc_set_dma_mask + * + * Set dma mask and coherent dma mask for glue layer device, and the core + * device will inherit these values. If the 'dma-ranges' is specified at + * DT, it will use this value for both dma mask and coherent dma mask. + * + * @dev: a pointer to the device struct of glue layer device + * @ci_coherent_dma_mask: the mask for both dma_mask and cohrent_dma_mask + */ +int ci_hdrc_set_dma_mask(struct device *dev, u64 ci_coherent_dma_mask) +{ + int ret = dma_set_mask_and_coherent(dev, ci_coherent_dma_mask); + if (ret) { + dev_err(dev, "dma_set_mask_and_coherent fails\n"); + return ret; + } + + if (dev_of_node(dev)) + of_dma_configure(dev, dev->of_node); + + return ret; +} + struct platform_device *ci_hdrc_add_device(struct device *dev, struct resource *res, int nres, struct ci_hdrc_platform_data *platdata) diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h index 5dd75fa..8649930 100644 --- a/include/linux/usb/chipidea.h +++ b/include/linux/usb/chipidea.h @@ -84,4 +84,6 @@ struct platform_device *ci_hdrc_add_device(struct device *dev, /* Remove ci hdrc device */ void ci_hdrc_remove_device(struct platform_device *pdev); +int ci_hdrc_set_dma_mask(struct device *dev, u64 ci_coherent_dma_mask); + #endif -- Best Regards, Peter Chen -- To
[PATCH] phy: twl4030-usb: fix musb-hdrc name for non-dt case
musb device is allocated with PLATFORM_DEVID_AUTO, fix incorrect lookup name in non-dt case. This fixes issue with musb initialization on Nokia N900 in boardfile boot mode. Signed-off-by: Ruslan Bilovol--- drivers/phy/phy-twl4030-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index 840f3ea..a48214f 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c @@ -735,7 +735,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) } if (pdata) - err = phy_create_lookup(phy, "usb", "musb-hdrc.0"); + err = phy_create_lookup(phy, "usb", "musb-hdrc.0.auto"); if (err) return err; -- 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
[PATCH] phy: da8xx-usb: new driver for DA8xx SoC USB PHY
This is a new phy driver for the SoC USB controllers on the TI DA8xx family of microcontrollers. The USB 1.1 PHY is just a simple on/off. The USB 2.0 PHY also allows overriding the VBUS and ID pins. Signed-off-by: David Lechner--- I made a last minute change and some renames slipped through the crack. This is the corrected patch. drivers/phy/Kconfig | 10 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-da8xx-usb.c | 249 ++ include/linux/phy/phy-da8xx-usb.h | 19 +++ 4 files changed, 279 insertions(+) create mode 100644 drivers/phy/phy-da8xx-usb.c create mode 100644 include/linux/phy/phy-da8xx-usb.h diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 26566db..c1d315f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -35,6 +35,16 @@ config ARMADA375_USBCLUSTER_PHY depends on OF && HAS_IOMEM select GENERIC_PHY +config PHY_DA8XX_USB + tristate "TI DA8xx USB PHY Driver" + depends on ARCH_DAVINCI_DA8XX + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the USB PHY on DA8xx SoCs. + + This driver controls both the USB 1.1 PHY and the USB 2.0 PHY. + config PHY_DM816X_USB tristate "TI dm816x USB PHY driver" depends on ARCH_OMAP2PLUS diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 24596a9..722e01c 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o +obj-$(CONFIG_PHY_DA8XX_USB)+= phy-da8xx-usb.o obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_BCM_KONA_USB2_PHY)+= phy-bcm-kona-usb2.o diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c new file mode 100644 index 000..ecfd607 --- /dev/null +++ b/drivers/phy/phy-da8xx-usb.c @@ -0,0 +1,249 @@ +/* + * phy-da8xx-usb - TI DaVinci DA8xx USB PHY driver + * + * Copyright (C) 2016 David Lechner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct da8xx_usbphy { + struct phy_provider *phy_provider; + struct phy *usb11_phy; + struct phy *usb20_phy; + struct clk *usb11_clk; + struct clk *usb20_clk; + struct regmap *regmap; +}; + +static int da8xx_usb11_phy_power_on(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(d_phy->usb11_clk); + if (ret) + return ret; + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_USB1SUSPENDM, + CFGCHIP2_USB1SUSPENDM); + + return 0; +} + +static int da8xx_usb11_phy_power_off(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_USB1SUSPENDM, 0); + + clk_disable_unprepare(d_phy->usb11_clk); + + return 0; +} + +static const struct phy_ops da8xx_usb11_phy_ops = { + .power_on = da8xx_usb11_phy_power_on, + .power_off = da8xx_usb11_phy_power_off, + .owner = THIS_MODULE, +}; + +static int da8xx_usb20_phy_init(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(d_phy->usb20_clk); + if (ret) + return ret; + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_OTGPWRDN, 0); + + return 0; +} + +static int da8xx_usb20_phy_shutdown(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_OTGPWRDN, + CFGCHIP2_OTGPWRDN); + + clk_disable_unprepare(d_phy->usb20_clk); + + return 0; +} + +static const struct phy_ops da8xx_usb20_phy_ops = { + .power_on = da8xx_usb20_phy_init, + .power_off = da8xx_usb20_phy_shutdown, + .owner = THIS_MODULE, +}; + +int da8xx_usb20_phy_set_mode(struct phy *phy, enum musb_mode mode) +{ +
[PATCH v3 03/16] ARM: davinici: da8xx: move usb code to new file
We will be adding more da8xx-specific code for phy and clocks, so it will be better to have this in a separate file. This way we don't have a bunch of #ifdefs for all of the da8xx stuff. Signed-off-by: David Lechner--- v3 changes: this is a new patch. The diff in git looked much nicer. Instead of a whole new file, usb-da8xx.c is diffed to usb.c. arch/arm/mach-davinci/Makefile| 4 +- arch/arm/mach-davinci/usb-da8xx.c | 124 ++ arch/arm/mach-davinci/usb.c | 74 +-- 3 files changed, 127 insertions(+), 75 deletions(-) create mode 100644 arch/arm/mach-davinci/usb-da8xx.c diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 2e3464b..da4c336 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -14,8 +14,8 @@ obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM355)+= dm355.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o -obj-$(CONFIG_ARCH_DAVINCI_DA830)+= da830.o devices-da8xx.o -obj-$(CONFIG_ARCH_DAVINCI_DA850)+= da850.o devices-da8xx.o +obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o usb-da8xx.o +obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o usb-da8xx.o obj-$(CONFIG_AINTC)+= irq.o obj-$(CONFIG_CP_INTC) += cp_intc.o diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c new file mode 100644 index 000..728a11f --- /dev/null +++ b/arch/arm/mach-davinci/usb-da8xx.c @@ -0,0 +1,124 @@ +/* + * DA8xx USB + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define DA8XX_USB0_BASE0x01e0 +#define DA8XX_USB1_BASE0x01e25000 + +#if IS_ENABLED(CONFIG_USB_MUSB_HDRC) + +static struct musb_hdrc_eps_bits musb_eps[] = { + { "ep1_tx", 8, }, + { "ep1_rx", 8, }, + { "ep2_tx", 8, }, + { "ep2_rx", 8, }, + { "ep3_tx", 5, }, + { "ep3_rx", 5, }, + { "ep4_tx", 5, }, + { "ep4_rx", 5, }, +}; + +static struct musb_hdrc_config musb_config = { + .multipoint = true, + .dyn_fifo = true, + .soft_con = true, + .dma= true, + + .num_eps= 5, + .dma_channels = 8, + .ram_bits = 10, + .eps_bits = musb_eps, +}; + +static struct musb_hdrc_platform_data usb_data = { + /* OTG requires a Mini-AB connector */ + .mode = MUSB_OTG, + .clock = "usb20", + .config = _config, +}; + +static struct resource da8xx_usb20_resources[] = { + { + .start = DA8XX_USB0_BASE, + .end= DA8XX_USB0_BASE + SZ_64K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_DA8XX_USB_INT, + .flags = IORESOURCE_IRQ, + .name = "mc", + }, +}; + +static u64 usb_dmamask = DMA_BIT_MASK(32); + +static struct platform_device usb_dev = { + .name = "musb-da8xx", + .id = -1, + .dev = { + .platform_data = _data, + .dma_mask = _dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .resource = da8xx_usb20_resources, + .num_resources = ARRAY_SIZE(da8xx_usb20_resources), +}; + +int __init da8xx_register_usb20(unsigned mA, unsigned potpgt) +{ + usb_data.power = mA > 510 ? 255 : mA / 2; + usb_data.potpgt = (potpgt + 1) / 2; + + return platform_device_register(_dev); +} + +#else + +int __init da8xx_register_usb20(unsigned mA, unsigned potpgt) +{ + return 0; +} + +#endif /* CONFIG_USB_MUSB_HDRC */ + +static struct resource da8xx_usb11_resources[] = { + [0] = { + .start = DA8XX_USB1_BASE, + .end= DA8XX_USB1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DA8XX_IRQN, + .end= IRQ_DA8XX_IRQN, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device da8xx_usb11_device = { + .name = "ohci", + .id = 0, + .dev = { + .dma_mask = _usb11_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(da8xx_usb11_resources), + .resource = da8xx_usb11_resources, +}; + +int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata) +{ + da8xx_usb11_device.dev.platform_data = pdata; + return platform_device_register(_usb11_device); +} diff --git
[PATCH v3 10/16] ARM: davinci: da8xx: Add CFGCHIPn syscon platform declaration.
The CFGCHIPn registers are used by a number of devices, so using a syscon device to share them. The first consumer of this will by the phy-da8xx-usb driver. Signed-off-by: David Lechner--- v3 changes: This is a new patch. There is one syscon device for all CFGCHIP registers. arch/arm/mach-davinci/board-da830-evm.c | 4 arch/arm/mach-davinci/board-da850-evm.c | 4 arch/arm/mach-davinci/board-mityomapl138.c | 4 arch/arm/mach-davinci/board-omapl138-hawk.c | 4 arch/arm/mach-davinci/devices-da8xx.c | 28 arch/arm/mach-davinci/include/mach/da8xx.h | 2 ++ 6 files changed, 46 insertions(+) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 605d444..3051cb6 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -586,6 +586,10 @@ static __init void da830_evm_init(void) struct davinci_soc_info *soc_info = _soc_info; int ret; + ret = da8xx_register_cfgchip(); + if (ret) + pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); + ret = da830_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 8e4539f..ec5cb10 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -1345,6 +1345,10 @@ static __init void da850_evm_init(void) { int ret; + ret = da8xx_register_cfgchip(); + if (ret) + pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); + ret = da850_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index d97c588..c04b45d 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -509,6 +509,10 @@ static void __init mityomapl138_init(void) { int ret; + ret = da8xx_register_cfgchip(); + if (ret) + pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); + /* for now, no special EDMA channels are reserved */ ret = da850_register_edma(NULL); if (ret) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index d4930b6..8691a25 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -294,6 +294,10 @@ static __init void omapl138_hawk_init(void) { int ret; + ret = da8xx_register_cfgchip(); + if (ret) + pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); + ret = da850_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 725e693..69d11a1 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -11,6 +11,7 @@ * (at your option) any later version. */ #include +#include #include #include #include @@ -1109,3 +1110,30 @@ int __init da850_register_sata(unsigned long refclkpn) return platform_device_register(_sata_device); } #endif + +static struct syscon_platform_data da8xx_cfgchip_platform_data = { + .label = "cfgchip", +}; + +static struct resource da8xx_cfgchip_resources[] = { + { + .start = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP0_REG, + .end= DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP4_REG + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da8xx_cfgchip_device = { + .name = "syscon", + .id = 0, + .dev= { + .platform_data = _cfgchip_platform_data, + }, + .num_resources = ARRAY_SIZE(da8xx_cfgchip_resources), + .resource = da8xx_cfgchip_resources, +}; + +int __init da8xx_register_cfgchip(void) +{ + return platform_device_register(_cfgchip_device); +} diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index c367530..c32444b 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -61,6 +61,7 @@ extern unsigned int da850_max_speed; #define DA8XX_CFGCHIP1_REG 0x180 #define DA8XX_CFGCHIP2_REG 0x184 #define DA8XX_CFGCHIP3_REG 0x188 +#define DA8XX_CFGCHIP4_REG 0x18c #define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000) #define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x)) @@ -116,6 +117,7 @@ void da8xx_rproc_reserve_cma(void); int da8xx_register_rproc(void); int da850_register_gpio(void); int da830_register_gpio(void);
[PATCH v3 06/16] ARM: davinci: da850: use clk->set_parent for async3
The da850 family of processors has an async3 clock domain that can be muxed to either pll0_sysclk2 or pll1_sysclk2. Now that the davinci clocks have a set_parent callback, we can use this to control the async3 mux instead of a stand-alone function. This adds a new async3_clk and sets the appropriate child clocks. The default is use to pll1_sysclk2 since it is not affected by processor frequency scaling. Signed-off-by: David Lechner--- v3 changes: * Does not use ioremap in da850_async3_set_parent(). This works now becuase the clock init has been moved. * Fixed copy/paste error in a comment. arch/arm/mach-davinci/da850.c | 82 ++- 1 file changed, 34 insertions(+), 48 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 9f46706..10bfbed 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -34,9 +34,6 @@ #include "clock.h" #include "mux.h" -/* SoC specific clock flags */ -#define DA850_CLK_ASYNC3 BIT(16) - #define DA850_PLL1_BASE0x01e1a000 #define DA850_TIMER64P2_BASE 0x01f0c000 #define DA850_TIMER64P3_BASE 0x01f0d000 @@ -161,6 +158,33 @@ static struct clk pll1_sysclk3 = { .div_reg= PLLDIV3, }; +static int da850_async3_set_parent(struct clk *clk, struct clk *parent) +{ + u32 val; + + val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); + + /* Set the Async3 clock domain mux based on the parent clock. */ + if (parent == _sysclk2) + val &= ~CFGCHIP3_ASYNC3_CLKSRC; + else if (parent == _sysclk2) + val |= CFGCHIP3_ASYNC3_CLKSRC; + else { + pr_err("Bad parent on async3 clock mux.\n"); + return -EINVAL; + } + + writel(val, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); + + return 0; +} + +static struct clk async3_clk = { + .name = "async3", + .parent = _sysclk2, + .set_parent = da850_async3_set_parent, +}; + static struct clk i2c0_clk = { .name = "i2c0", .parent = _aux_clk, @@ -234,18 +258,16 @@ static struct clk uart0_clk = { static struct clk uart1_clk = { .name = "uart1", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_UART1, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; static struct clk uart2_clk = { .name = "uart2", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_UART2, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; static struct clk aintc_clk = { @@ -300,10 +322,9 @@ static struct clk emac_clk = { static struct clk mcasp_clk = { .name = "mcasp", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_McASP0, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; static struct clk lcdc_clk = { @@ -355,10 +376,9 @@ static struct clk spi0_clk = { static struct clk spi1_clk = { .name = "spi1", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_SPI1, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; static struct clk vpif_clk = { @@ -386,10 +406,9 @@ static struct clk dsp_clk = { static struct clk ehrpwm_clk = { .name = "ehrpwm", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_PWM, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; #define DA8XX_EHRPWM_TBCLKSYNC BIT(12) @@ -421,10 +440,9 @@ static struct clk ehrpwm_tbclk = { static struct clk ecap_clk = { .name = "ecap", - .parent = _sysclk2, + .parent = _clk, .lpsc = DA8XX_LPSC1_ECAP, .gpsc = 1, - .flags = DA850_CLK_ASYNC3, }; static struct clk_lookup da850_clks[] = { @@ -442,6 +460,7 @@ static struct clk_lookup da850_clks[] = { CLK(NULL, "pll1_aux", _aux_clk), CLK(NULL, "pll1_sysclk2", _sysclk2), CLK(NULL, "pll1_sysclk3", _sysclk3), + CLK(NULL, "async3", _clk), CLK("i2c_davinci.1",NULL, _clk), CLK(NULL, "timer0", _0_clk), CLK("davinci-wdt", NULL, _1_clk), @@ -909,30 +928,6 @@ static struct davinci_timer_info da850_timer_info = { .clocksource_id = T0_TOP, }; -static void da850_set_async3_src(int pllnum) -{ - struct clk *clk, *newparent = pllnum ? _sysclk2 : _sysclk2; - struct clk_lookup *c; - unsigned int v; - int ret; - - for (c = da850_clks; c->clk; c++) { -
[PATCH v3 04/16] ARM: davinci: Move clock init after ioremap.
Some clocks (such as the USB PHY clocks in DA8xx) will need to use iomem. The davinci_common_init() function must be called before the ioremap, so the clock init is now split out as separate function. Signed-off-by: David Lechner--- v3 changes: This is a new patch. It takes care of the issue of unwanted ioremap in clock set_parent functions. arch/arm/mach-davinci/clock.c | 4 ++-- arch/arm/mach-davinci/clock.h | 7 ++- arch/arm/mach-davinci/common.c | 6 -- arch/arm/mach-davinci/da830.c | 2 ++ arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm365.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + 9 files changed, 16 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 3424eac6..a5c2629 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -560,7 +560,7 @@ EXPORT_SYMBOL(davinci_set_pllrate); * than that used by default in .c file. The reference clock rate * should be updated early in the boot process; ideally soon after the * clock tree has been initialized once with the default reference clock - * rate (davinci_common_init()). + * rate (davinci_clk_init()). * * Returns 0 on success, error otherwise. */ @@ -581,7 +581,7 @@ int davinci_set_refclk_rate(unsigned long rate) return 0; } -int __init davinci_clk_init(struct clk_lookup *clocks) +int __init _davinci_clk_init(struct clk_lookup *clocks) { struct clk_lookup *c; struct clk *clk; diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 1e4e836..8b0fbbe 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -124,7 +124,12 @@ struct clk { .clk = ck, \ } \ -int davinci_clk_init(struct clk_lookup *clocks); +int _davinci_clk_init(struct clk_lookup *clocks); +static inline void davinci_clk_init(struct davinci_soc_info *soc_info) +{ + if (soc_info->cpu_clks && _davinci_clk_init(soc_info->cpu_clks)) + panic("davinci_clk_init: Failed to init clocks.\n"); +} int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, unsigned int mult, unsigned int postdiv); int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c index f55ef2e..6bc8c22 100644 --- a/arch/arm/mach-davinci/common.c +++ b/arch/arm/mach-davinci/common.c @@ -103,12 +103,6 @@ void __init davinci_common_init(struct davinci_soc_info *soc_info) if (ret < 0) goto err; - if (davinci_soc_info.cpu_clks) { - ret = davinci_clk_init(davinci_soc_info.cpu_clks); - - if (ret != 0) - goto err; - } return; diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 7187e7f..79d5fc3 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1214,4 +1214,6 @@ void __init da830_init(void) da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"); + + davinci_clk_init(_soc_info_da830); } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 97d8779..9f46706 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1346,4 +1346,6 @@ void __init da850_init(void) v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); v &= ~CFGCHIP3_PLL1_MASTER_LOCK; __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); + + davinci_clk_init(_soc_info_da850); } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index a0ecf49..b311b84 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -1052,6 +1052,7 @@ void __init dm355_init(void) { davinci_common_init(_soc_info_dm355); davinci_map_sysmod(); + davinci_clk_init(_soc_info_dm355); } int __init dm355_init_video(struct vpfe_config *vpfe_cfg, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 384d367..2338875 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1176,6 +1176,7 @@ void __init dm365_init(void) { davinci_common_init(_soc_info_dm365); davinci_map_sysmod(); + davinci_clk_init(_soc_info_dm365); } static struct resource dm365_vpss_resources[] = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index b4b3a8b..5e672ed 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -932,6 +932,7 @@ void __init dm644x_init(void) { davinci_common_init(_soc_info_dm644x); davinci_map_sysmod(); + davinci_clk_init(_soc_info_dm644x); } int __init
[PATCH v3 09/16] phy: da8xx-usb: new driver for DA8xx SoC USB PHY
This is a new phy driver for the SoC USB controllers on the TI DA8xx family of microcontrollers. The USB 1.1 PHY is just a simple on/off. The USB 2.0 PHY also allows overriding the VBUS and ID pins. Signed-off-by: David Lechner--- v3 changes: * Uses syscon device for CFGCHIP2 instead of using it directly. * Got rid of nop inline funtions * Correct suffix on funtions to match ops.* * Added header file for extern method. drivers/phy/Kconfig | 10 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-da8xx-usb.c | 249 ++ include/linux/phy/phy-da8xx-usb.h | 19 +++ 4 files changed, 279 insertions(+) create mode 100644 drivers/phy/phy-da8xx-usb.c create mode 100644 include/linux/phy/phy-da8xx-usb.h diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 26566db..c1d315f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -35,6 +35,16 @@ config ARMADA375_USBCLUSTER_PHY depends on OF && HAS_IOMEM select GENERIC_PHY +config PHY_DA8XX_USB + tristate "TI DA8xx USB PHY Driver" + depends on ARCH_DAVINCI_DA8XX + select GENERIC_PHY + select MFD_SYSCON + help + Enable this to support the USB PHY on DA8xx SoCs. + + This driver controls both the USB 1.1 PHY and the USB 2.0 PHY. + config PHY_DM816X_USB tristate "TI dm816x USB PHY driver" depends on ARCH_OMAP2PLUS diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 24596a9..722e01c 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o +obj-$(CONFIG_PHY_DA8XX_USB)+= phy-da8xx-usb.o obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o obj-$(CONFIG_BCM_KONA_USB2_PHY)+= phy-bcm-kona-usb2.o diff --git a/drivers/phy/phy-da8xx-usb.c b/drivers/phy/phy-da8xx-usb.c new file mode 100644 index 000..687d9a0 --- /dev/null +++ b/drivers/phy/phy-da8xx-usb.c @@ -0,0 +1,249 @@ +/* + * phy-da8xx-usb - TI DaVinci DA8xx USB PHY driver + * + * Copyright (C) 2016 David Lechner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct da8xx_usbphy { + struct phy_provider *phy_provider; + struct phy *usb11_phy; + struct phy *usb20_phy; + struct clk *usb11_clk; + struct clk *usb20_clk; + struct regmap *regmap; +}; + +static int da8xx_usb11_phy_power_on(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(d_phy->usb11_clk); + if (ret) + return ret; + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_USB1SUSPENDM, + CFGCHIP2_USB1SUSPENDM); + + return 0; +} + +static int da8xx_usb11_phy_power_off(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_USB1SUSPENDM, 0); + + clk_disable_unprepare(d_phy->usb11_clk); + + return 0; +} + +static const struct phy_ops da8xx_usb11_phy_ops = { + .power_on = da8xx_usb11_phy_power_on, + .power_off = da8xx_usb11_phy_power_off, + .owner = THIS_MODULE, +}; + +static int da8xx_usb20_phy_init(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(d_phy->usb20_clk); + if (ret) + return ret; + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_OTGPWRDN, 0); + + return 0; +} + +static int da8xx_usb20_phy_shutdown(struct phy *phy) +{ + struct da8xx_usbphy *d_phy = phy_get_drvdata(phy); + + regmap_write_bits(d_phy->regmap, CFGCHIP2_REG, CFGCHIP2_OTGPWRDN, + CFGCHIP2_OTGPWRDN); + + clk_disable_unprepare(d_phy->usb20_clk); + + return 0; +} + +static const struct phy_ops da8xx_usb20_phy_ops = { + .power_on = da8xx_usb20_phy_init, + .power_off = da8xx_usb20_phy_shutdown, + .owner =
[PATCH v3 01/16] dt: davinci: use proper address after @
TI has been using the physical address in DT after the @ in device nodes. The device tree convention is to use the same address that is used for the reg property. This updates all davinci DT files to use the proper convention. Signed-off-by: David Lechner--- v3 changes: This is a new patch. arch/arm/boot/dts/da850-enbw-cmc.dts | 8 +++--- arch/arm/boot/dts/da850-evm.dts | 26 +- arch/arm/boot/dts/da850.dtsi | 52 ++-- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/arch/arm/boot/dts/da850-enbw-cmc.dts b/arch/arm/boot/dts/da850-enbw-cmc.dts index 645549e..101d1a1 100644 --- a/arch/arm/boot/dts/da850-enbw-cmc.dts +++ b/arch/arm/boot/dts/da850-enbw-cmc.dts @@ -16,14 +16,14 @@ compatible = "enbw,cmc", "ti,da850"; model = "EnBW CMC"; - soc { - serial0: serial@1c42000 { + soc@1c0 { + serial0: serial@42000 { status = "okay"; }; - serial1: serial@1d0c000 { + serial1: serial@10c000 { status = "okay"; }; - serial2: serial@1d0d000 { + serial2: serial@10d000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts index ef061e9..1a15db8 100644 --- a/arch/arm/boot/dts/da850-evm.dts +++ b/arch/arm/boot/dts/da850-evm.dts @@ -14,8 +14,8 @@ compatible = "ti,da850-evm", "ti,da850"; model = "DA850/AM1808/OMAP-L138 EVM"; - soc { - pmx_core: pinmux@1c14120 { + soc@1c0 { + pmx_core: pinmux@14120 { status = "okay"; mcasp0_pins: pinmux_mcasp0_pins { @@ -30,19 +30,19 @@ >; }; }; - serial0: serial@1c42000 { + serial0: serial@42000 { status = "okay"; }; - serial1: serial@1d0c000 { + serial1: serial@10c000 { status = "okay"; }; - serial2: serial@1d0d000 { + serial2: serial@10d000 { status = "okay"; }; - rtc0: rtc@1c23000 { + rtc0: rtc@23000 { status = "okay"; }; - i2c0: i2c@1c22000 { + i2c0: i2c@22000 { status = "okay"; clock-frequency = <10>; pinctrl-names = "default"; @@ -66,17 +66,17 @@ }; }; - wdt: wdt@1c21000 { + wdt: wdt@21000 { status = "okay"; }; - mmc0: mmc@1c4 { + mmc0: mmc@4 { max-frequency = <5000>; bus-width = <4>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_pins>; }; - spi1: spi@1f0e000 { + spi1: spi@30e000 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_pins _cs0_pin>; @@ -116,18 +116,18 @@ }; }; }; - mdio: mdio@1e24000 { + mdio: mdio@224000 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_pins>; bus_freq = <220>; }; - eth0: ethernet@1e2 { + eth0: ethernet@22 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <_pins>; }; - gpio: gpio@1e26000 { + gpio: gpio@226000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index 226cda7..4294849 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -15,7 +15,7 @@ #address-cells = <1>; #size-cells = <1>; ranges; - intc: interrupt-controller { + intc: interrupt-controller@fffee000 { compatible = "ti,cp-intc"; interrupt-controller; #interrupt-cells = <1>; @@ -23,7 +23,7 @@ reg = <0xfffee000 0x2000>; }; }; - soc { + soc@1c0 { compatible = "simple-bus"; model = "da850";
[PATCH v3 00/16] da8xx USB clocks
This is a reworking of the v2 series based of feedback and review. There were very many suggestions, so hopefully I didn't miss any. Here are the highlights... New stuff: * Fixed the davinci device tree declarations to use the preferred DT address convention so that the items I have added can be correct too. * Moved that davinci clock init so that we don't have to call ioremap in the clock mux functions. * Added a new "syscon" device for the CFGCHIP registers. This is used by the USB PHY driver and will be used in the future in common clock framework drivers. Changed: * USB clocks are moved to a common file instead of having duplicated code. * PHY driver uses syscon for CFGCHIP registers instead of using them directly. David Lechner (16): dt: davinci: use proper address after @ mfd: da8xx-cfgchip: New header file for CFGCHIP registers. ARM: davinici: da8xx: move usb code to new file ARM: davinci: Move clock init after ioremap. ARM: davinci: add set_parent callback for mux clocks ARM: davinci: da850: use clk->set_parent for async3 ARM: davinci: da8xx: add usb phy clocks dt-bindings: Add bindings for phy-da8xx-usb phy: da8xx-usb: new driver for DA8xx SoC USB PHY ARM: davinci: da8xx: Add CFGCHIPn syscon platform declaration. ARM: davinci: da8xx: Add USB PHY platform declaration ARM: dt: da850: Add cfgchip syscon node ARM: dt: da850: Add usb phy node usb: ohci-da8xx: Remove code that references mach usb: musb: da8xx: Use devm in probe usb: musb: da8xx: Remove mach code .../devicetree/bindings/phy/phy-da8xx-usb.txt | 40 +++ arch/arm/boot/dts/da850-enbw-cmc.dts | 8 +- arch/arm/boot/dts/da850-evm.dts| 26 +- arch/arm/boot/dts/da850.dtsi | 61 ++-- arch/arm/mach-davinci/Makefile | 4 +- arch/arm/mach-davinci/board-da830-evm.c| 52 ++- arch/arm/mach-davinci/board-da850-evm.c| 4 + arch/arm/mach-davinci/board-mityomapl138.c | 4 + arch/arm/mach-davinci/board-omapl138-hawk.c| 23 +- arch/arm/mach-davinci/clock.c | 21 +- arch/arm/mach-davinci/clock.h | 8 +- arch/arm/mach-davinci/common.c | 6 - arch/arm/mach-davinci/da830.c | 2 + arch/arm/mach-davinci/da850.c | 84 +++-- arch/arm/mach-davinci/devices-da8xx.c | 28 ++ arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm365.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/include/mach/da8xx.h | 6 + arch/arm/mach-davinci/usb-da8xx.c | 351 + arch/arm/mach-davinci/usb.c| 74 + drivers/phy/Kconfig| 10 + drivers/phy/Makefile | 1 + drivers/phy/phy-da8xx-usb.c| 249 +++ drivers/usb/host/Kconfig | 1 + drivers/usb/host/ohci-da8xx.c | 102 +++--- drivers/usb/musb/Kconfig | 2 +- drivers/usb/musb/da8xx.c | 160 +++--- include/linux/mfd/da8xx-cfgchip.h | 160 ++ include/linux/phy/phy-da8xx-usb.h | 19 ++ include/linux/platform_data/usb-davinci.h | 23 -- 32 files changed, 1137 insertions(+), 396 deletions(-) create mode 100644 Documentation/devicetree/bindings/phy/phy-da8xx-usb.txt create mode 100644 arch/arm/mach-davinci/usb-da8xx.c create mode 100644 drivers/phy/phy-da8xx-usb.c create mode 100644 include/linux/mfd/da8xx-cfgchip.h create mode 100644 include/linux/phy/phy-da8xx-usb.h -- 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
[PATCH v3 02/16] mfd: da8xx-cfgchip: New header file for CFGCHIP registers.
We will be using a generic syscon device for the TI DA8XX SoC CFGCHIPx retisters. This will be used by a number of planned drivers including a new USB PHY driver and common clock framework drivers. The same defines are removed from the platform_data header file since they are now redundant and they didn't really belong there anyway. Signed-off-by: David Lechner--- v3 changes: This is a new patch. It replaces the previous patch that just added some missing CFGCHIP2 registers to the platform_data/usb-davinci.h file. I took David Laight's advice and included all of the possible registers. Many of these registers will be used for clocks - hopefully in the near future. include/linux/mfd/da8xx-cfgchip.h | 160 ++ include/linux/platform_data/usb-davinci.h | 23 - 2 files changed, 160 insertions(+), 23 deletions(-) create mode 100644 include/linux/mfd/da8xx-cfgchip.h diff --git a/include/linux/mfd/da8xx-cfgchip.h b/include/linux/mfd/da8xx-cfgchip.h new file mode 100644 index 000..6940cf9 --- /dev/null +++ b/include/linux/mfd/da8xx-cfgchip.h @@ -0,0 +1,160 @@ +/* + * TI DaVinci DA8xx CHIPCFGx registers for syscon consumers. + * + * Copyright (C) 2016 David Lechner + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +#ifndef __LINUX_MFD_DA8XX_CFGCHIP_H +#define __LINUX_MFD_DA8XX_CFGCHIP_H + +#include + +/* register offsets */ +#define CFGCHIP_REG(n) (n * 4) +#define CFGCHIP0_REG CFGCHIP_REG(0) +#define CFGCHIP1_REG CFGCHIP_REG(1) +#define CFGCHIP2_REG CFGCHIP_REG(2) +#define CFGCHIP3_REG CFGCHIP_REG(3) +#define CFGCHIP4_REG CFGCHIP_REG(4) + +/* CFGCHIP0 (PLL0/EDMA3_0) register bits */ +#define CFGCHIP0_PLL_MASTER_LOCK BIT(4) +#define CFGCHIP0_EDMA30TC1DBS(n) (n << 2) +#define CFGCHIP0_EDMA30TC1DBS_MASK CFGCHIP0_EDMA30TC1DBS(0x3) +#define CFGCHIP0_EDMA30TC1DBS_16 CFGCHIP0_EDMA30TC1DBS(0x0) +#define CFGCHIP0_EDMA30TC1DBS_32 CFGCHIP0_EDMA30TC1DBS(0x1) +#define CFGCHIP0_EDMA30TC1DBS_64 CFGCHIP0_EDMA30TC1DBS(0x2) +#define CFGCHIP0_EDMA30TC0DBS(n) (n << 0) +#define CFGCHIP0_EDMA30TC0DBS_MASK CFGCHIP0_EDMA30TC0DBS(0x3) +#define CFGCHIP0_EDMA30TC0DBS_16 CFGCHIP0_EDMA30TC0DBS(0x0) +#define CFGCHIP0_EDMA30TC0DBS_32 CFGCHIP0_EDMA30TC0DBS(0x1) +#define CFGCHIP0_EDMA30TC0DBS_64 CFGCHIP0_EDMA30TC0DBS(0x2) + +/* CFGCHIP1 (eCAP/HPI/EDMA3_1/eHRPWM TBCLK/McASP0 AMUTEIN) register bits */ +#define CFGCHIP1_CAP2SRC(n)(n << 27) +#define CFGCHIP1_CAP2SRC_MASK CFGCHIP1_CAP2SRC(0x1f) +#define CFGCHIP1_CAP2SRC_ECAP_PIN CFGCHIP1_CAP2SRC(0x0) +#define CFGCHIP1_CAP2SRC_MCASP0_TX CFGCHIP1_CAP2SRC(0x1) +#define CFGCHIP1_CAP2SRC_MCASP0_RX CFGCHIP1_CAP2SRC(0x2) +#define CFGCHIP1_CAP2SRC_EMAC_C0_RX_THRESHOLD CFGCHIP1_CAP2SRC(0x7) +#define CFGCHIP1_CAP2SRC_EMAC_C0_RXCFGCHIP1_CAP2SRC(0x8) +#define CFGCHIP1_CAP2SRC_EMAC_C0_TXCFGCHIP1_CAP2SRC(0x9) +#define CFGCHIP1_CAP2SRC_EMAC_C0_MISC CFGCHIP1_CAP2SRC(0xa) +#define CFGCHIP1_CAP2SRC_EMAC_C1_RX_THRESHOLD CFGCHIP1_CAP2SRC(0xb) +#define CFGCHIP1_CAP2SRC_EMAC_C1_RXCFGCHIP1_CAP2SRC(0xc) +#define CFGCHIP1_CAP2SRC_EMAC_C1_TXCFGCHIP1_CAP2SRC(0xd) +#define CFGCHIP1_CAP2SRC_EMAC_C1_MISC CFGCHIP1_CAP2SRC(0xe) +#define CFGCHIP1_CAP2SRC_EMAC_C2_RX_THRESHOLD CFGCHIP1_CAP2SRC(0xf) +#define CFGCHIP1_CAP2SRC_EMAC_C2_RXCFGCHIP1_CAP2SRC(0x10) +#define CFGCHIP1_CAP2SRC_EMAC_C2_TXCFGCHIP1_CAP2SRC(0x11) +#define CFGCHIP1_CAP2SRC_EMAC_C2_MISC CFGCHIP1_CAP2SRC(0x12) +#define CFGCHIP1_CAP1SRC(n)(n << 22) +#define CFGCHIP1_CAP1SRC_MASK CFGCHIP1_CAP1SRC(0x1f) +#define CFGCHIP1_CAP1SRC_ECAP_PIN CFGCHIP1_CAP1SRC(0x0) +#define CFGCHIP1_CAP1SRC_MCASP0_TX CFGCHIP1_CAP1SRC(0x1) +#define CFGCHIP1_CAP1SRC_MCASP0_RX CFGCHIP1_CAP1SRC(0x2) +#define CFGCHIP1_CAP1SRC_EMAC_C0_RX_THRESHOLD CFGCHIP1_CAP1SRC(0x7) +#define CFGCHIP1_CAP1SRC_EMAC_C0_RXCFGCHIP1_CAP1SRC(0x8) +#define CFGCHIP1_CAP1SRC_EMAC_C0_TXCFGCHIP1_CAP1SRC(0x9) +#define CFGCHIP1_CAP1SRC_EMAC_C0_MISC CFGCHIP1_CAP1SRC(0xa) +#define
[PATCH v3 07/16] ARM: davinci: da8xx: add usb phy clocks
Up to this point, the USB phy clock configuration was handled manually in the board files and in the usb drivers. This adds proper clocks so that the usb drivers can use clk_get and clk_enable and not have to worry about the details. Also, the related code is removed from the board files and replaced with the new clock registration functions. Signed-off-by: David Lechner--- v3 changes: * Clocks are now in usb-da8xx.c instead of having duplicated code in da830.c and da850.c. * No longer calling ioremap in set_parent() functions. * Added timeout while waiting for PLL to lock. * Renamed USB reference clock to usb_refclkin. * Clocks are now dynamically registered. * usb_refclkin rate is specified when registered, so it no longer has a default value of 48MHz. It does not have to be registered if it is not used. * Parent clock for clock muxes are set when clock is registered. * Board files that use da8xx usb are updated to call the new register functions. arch/arm/mach-davinci/board-da830-evm.c | 22 ++- arch/arm/mach-davinci/board-omapl138-hawk.c | 16 +- arch/arm/mach-davinci/include/mach/da8xx.h | 3 + arch/arm/mach-davinci/usb-da8xx.c | 218 +++- 4 files changed, 239 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 3d8cf8c..605d444 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -115,18 +115,6 @@ static __init void da830_evm_usb_init(void) */ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); - /* USB2.0 PHY reference clock is 24 MHz */ - cfgchip2 &= ~CFGCHIP2_REFFREQ; - cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; - - /* -* Select internal reference clock for USB 2.0 PHY -* and use it as a clock source for USB 1.1 PHY -* (this is the default setting anyway). -*/ - cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX; - cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX; - /* * We have to override VBUS/ID signals when MUSB is configured into the * host-only mode -- ID pin will float if no cable is connected, so the @@ -143,6 +131,16 @@ static __init void da830_evm_usb_init(void) __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); /* USB_REFCLKIN is not used. */ + ret = da8xx_register_usb20_phy_clk(false); + if (ret) + pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n", + __func__, ret); + + ret = da8xx_register_usb11_phy_clk(false); + if (ret) + pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n", + __func__, ret); + ret = davinci_cfg_reg(DA830_USB0_DRVVBUS); if (ret) pr_warn("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ee62486..d4930b6 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -243,7 +243,6 @@ static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) static __init void omapl138_hawk_usb_init(void) { int ret; - u32 cfgchip2; ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); if (ret) { @@ -251,12 +250,15 @@ static __init void omapl138_hawk_usb_init(void) return; } - /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */ - - cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); - cfgchip2 &= ~CFGCHIP2_REFFREQ; - cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; - __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + /* USB_REFCLKIN is not used. */ + ret = da8xx_register_usb20_phy_clk(false); + if (ret) + pr_warn("%s: USB 2.0 PHY CLK registration failed: %d\n", + __func__, ret); + ret = da8xx_register_usb11_phy_clk(false); + if (ret) + pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n", + __func__, ret); ret = gpio_request_one(DA850_USB1_VBUS_PIN, GPIOF_DIR_OUT, "USB1 VBUS"); diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index f9f9713..c367530 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -88,6 +88,9 @@ int da850_register_edma(struct edma_rsv_info *rsv[2]); int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); int da8xx_register_spi_bus(int instance, unsigned num_chipselect); int da8xx_register_watchdog(void); +int da8xx_register_usb_refclkin(int rate); +int da8xx_register_usb20_phy_clk(bool use_usb_refclkin); +int da8xx_register_usb11_phy_clk(bool use_usb_refclkin);
[PATCH v3 08/16] dt-bindings: Add bindings for phy-da8xx-usb
Device tree binding for new phy-da8xx-usb driver. Signed-off-by: David Lechner--- v3 changes: * added cfgchip info and example * correct usage of "DA8xx" * correct address after @ * dropped 11 before @ in usb@ .../devicetree/bindings/phy/phy-da8xx-usb.txt | 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-da8xx-usb.txt diff --git a/Documentation/devicetree/bindings/phy/phy-da8xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-da8xx-usb.txt new file mode 100644 index 000..684c548 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/phy-da8xx-usb.txt @@ -0,0 +1,40 @@ +TI DaVinci DA8xx USB PHY + +Required properties: + - compatible: must be "ti,da830-usbphy". + - #phy-cells: must be 1. + +This device controls the PHY for both the USB 1.1 OHCI and USB 2.0 OTG +controllers on DA8xx SoCs. Consumers of this device should use index 1 for +the USB 1.1 phy device and index 2 for the USB 2.0 phy device. + +It also requires a "syscon" node with compatible = "ti,da830-cfgchip", "syscon" +to access the CFGCHIP2 register. + +Example: + + cfgchip: cfgchip@1417c { + compatible = "ti,da830-cfgchip", "syscon"; + reg = <0x1417c 0x14>; + }; + + usbphy: usbphy { + compatible = "ti,da830-usbphy"; + #phy-cells = <1>; + }; + + usb11: usb@225000 { + compatible = "ti,da830-ohci"; + reg = <0x225000 0x1000>; + interrupts = <59>; + phys = < 1>; + phy-names = "usbphy"; + }; + + usb20: usb@20 { + compatible = "ti,da830-musb"; + reg = <0x20 0x1000>; + interrupts = <58>; + phys = < 2>; + phy-names = "usbphy"; + }; -- 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
[PATCH v3 11/16] ARM: davinci: da8xx: Add USB PHY platform declaration
There is now a proper phy driver for the DA8xx SoC USB PHY. This adds the platform device declarations needed to use it. Signed-off-by: David Lechner--- v3 changes: * The declaration is now in the new usb-da8xx.c file. arch/arm/mach-davinci/board-da830-evm.c | 28 +--- arch/arm/mach-davinci/board-omapl138-hawk.c | 5 + arch/arm/mach-davinci/include/mach/da8xx.h | 1 + arch/arm/mach-davinci/usb-da8xx.c | 11 +++ 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 3051cb6..6421cfe 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -106,30 +105,8 @@ static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id) static __init void da830_evm_usb_init(void) { - u32 cfgchip2; int ret; - /* -* Set up USB clock/mode in the CFGCHIP2 register. -* FYI: CFGCHIP2 is 0xef00 initially. -*/ - cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); - - /* -* We have to override VBUS/ID signals when MUSB is configured into the -* host-only mode -- ID pin will float if no cable is connected, so the -* controller won't be able to drive VBUS thinking that it's a B-device. -* Otherwise, we want to use the OTG mode and enable VBUS comparators. -*/ - cfgchip2 &= ~CFGCHIP2_OTGMODE; -#ifdef CONFIG_USB_MUSB_HOST - cfgchip2 |= CFGCHIP2_FORCE_HOST; -#else - cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN; -#endif - - __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); - /* USB_REFCLKIN is not used. */ ret = da8xx_register_usb20_phy_clk(false); if (ret) @@ -141,6 +118,11 @@ static __init void da830_evm_usb_init(void) pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n", __func__, ret); + ret = da8xx_register_usbphy(); + if (ret) + pr_warn("%s: USB PHY registration failed: %d\n", + __func__, ret); + ret = davinci_cfg_reg(DA830_USB0_DRVVBUS); if (ret) pr_warn("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 8691a25..79aaa84 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -260,6 +260,11 @@ static __init void omapl138_hawk_usb_init(void) pr_warn("%s: USB 1.1 PHY CLK registration failed: %d\n", __func__, ret); + ret = da8xx_register_usbphy(); + if (ret) + pr_warn("%s: USB PHY registration failed: %d\n", + __func__, ret); + ret = gpio_request_one(DA850_USB1_VBUS_PIN, GPIOF_DIR_OUT, "USB1 VBUS"); if (ret < 0) { diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index c32444b..44ab55e 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -92,6 +92,7 @@ int da8xx_register_watchdog(void); int da8xx_register_usb_refclkin(int rate); int da8xx_register_usb20_phy_clk(bool use_usb_refclkin); int da8xx_register_usb11_phy_clk(bool use_usb_refclkin); +int da8xx_register_usbphy(void); int da8xx_register_usb20(unsigned mA, unsigned potpgt); int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); int da8xx_register_emac(void); diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c index aca5867..6bd0009 100644 --- a/arch/arm/mach-davinci/usb-da8xx.c +++ b/arch/arm/mach-davinci/usb-da8xx.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -231,6 +232,16 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin) return ret; } +static struct platform_device da8xx_usbphy = { + .name = "da8xx-usbphy", + .id = 0, +}; + +int __init da8xx_register_usbphy(void) +{ + return platform_device_register(_usbphy); +} + #if IS_ENABLED(CONFIG_USB_MUSB_HDRC) static struct musb_hdrc_eps_bits musb_eps[] = { -- 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
[PATCH v3 13/16] ARM: dt: da850: Add usb phy node
Add a node for the new usb phy driver. Signed-off-by: David Lechner--- v3 changes: * No longer needs reg property since we are now using syscon instead. arch/arm/boot/dts/da850.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index a360713..83ea8f6 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -313,6 +313,11 @@ 36 >; }; + usbphy: usbphy { + compatible = "ti,da830-usbphy"; + #phy-cells = <1>; + status = "disabled"; + }; gpio: gpio@226000 { compatible = "ti,dm6441-gpio"; gpio-controller; -- 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
[PATCH v3 14/16] usb: ohci-da8xx: Remove code that references mach
Including mach/* is frowned upon in device drivers, so get rid of it. This replaces usb20_clk and code that pokes CFGCHIP2 with a proper phy driver. Signed-off-by: David LechnerAcked-by: Alan Stern --- v3 changes: * add phy_init and phy_exit calls for completness (they are nops for this particular phy driver). * add select PHY_DA8XX_USB to Kconfig drivers/usb/host/Kconfig | 1 + drivers/usb/host/ohci-da8xx.c | 102 +++--- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3050b18..e4432c6 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -472,6 +472,7 @@ config USB_OHCI_HCD_DAVINCI bool "OHCI support for TI DaVinci DA8xx" depends on ARCH_DAVINCI_DA8XX depends on USB_OHCI_HCD=y + select PHY_DA8XX_USB default y help Enables support for the DaVinci DA8xx integrated OHCI diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index e5c33bc..9d093ac 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -15,58 +15,50 @@ #include #include #include - -#include +#include #include #ifndef CONFIG_ARCH_DAVINCI_DA8XX #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX." #endif -#define CFGCHIP2 DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG) - static struct clk *usb11_clk; -static struct clk *usb20_clk; +static struct phy *usb11_phy; /* Over-current indicator change bitmask */ static volatile u16 ocic_mask; -static void ohci_da8xx_clock(int on) +static int ohci_da8xx_enable(void) { - u32 cfgchip2; - - cfgchip2 = __raw_readl(CFGCHIP2); - if (on) { - clk_enable(usb11_clk); - - /* -* If USB 1.1 reference clock is sourced from USB 2.0 PHY, we -* need to enable the USB 2.0 module clocking, start its PHY, -* and not allow it to stop the clock during USB 2.0 suspend. -*/ - if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) { - clk_enable(usb20_clk); - - cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN); - cfgchip2 |= CFGCHIP2_PHY_PLLON; - __raw_writel(cfgchip2, CFGCHIP2); - - pr_info("Waiting for USB PHY clock good...\n"); - while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD)) - cpu_relax(); - } + int ret; - /* Enable USB 1.1 PHY */ - cfgchip2 |= CFGCHIP2_USB1SUSPENDM; - } else { - clk_disable(usb11_clk); - if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX)) - clk_disable(usb20_clk); + ret = clk_prepare_enable(usb11_clk); + if (ret) + return ret; - /* Disable USB 1.1 PHY */ - cfgchip2 &= ~CFGCHIP2_USB1SUSPENDM; - } - __raw_writel(cfgchip2, CFGCHIP2); + ret = phy_init(usb11_phy); + if (ret) + goto err_phy_init; + + ret = phy_power_on(usb11_phy); + if (ret) + goto err_phy_power_on; + + return 0; + +err_phy_power_on: + phy_exit(usb11_phy); +err_phy_init: + clk_disable_unprepare(usb11_clk); + + return ret; +} + +static void ohci_da8xx_disable(void) +{ + phy_power_off(usb11_phy); + phy_exit(usb11_phy); + clk_disable_unprepare(usb11_clk); } /* @@ -92,7 +84,9 @@ static int ohci_da8xx_init(struct usb_hcd *hcd) dev_dbg(dev, "starting USB controller\n"); - ohci_da8xx_clock(1); + result = ohci_da8xx_enable(); + if (result < 0) + return result; /* * DA8xx only have 1 port connected to the pins but the HC root hub @@ -101,8 +95,10 @@ static int ohci_da8xx_init(struct usb_hcd *hcd) ohci->num_ports = 1; result = ohci_init(ohci); - if (result < 0) + if (result < 0) { + ohci_da8xx_disable(); return result; + } /* * Since we're providing a board-specific root hub port power control @@ -129,7 +125,7 @@ static int ohci_da8xx_init(struct usb_hcd *hcd) static void ohci_da8xx_stop(struct usb_hcd *hcd) { ohci_stop(hcd); - ohci_da8xx_clock(0); + ohci_da8xx_disable(); } static int ohci_da8xx_start(struct usb_hcd *hcd) @@ -301,12 +297,18 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver, return -ENODEV; usb11_clk = devm_clk_get(>dev, "usb11"); - if (IS_ERR(usb11_clk)) + if (IS_ERR(usb11_clk)) { + if (PTR_ERR(usb11_clk) != -EPROBE_DEFER) + dev_err(>dev, "Failed to get clock.\n"); return PTR_ERR(usb11_clk); +
[PATCH v3 15/16] usb: musb: da8xx: Use devm in probe
Simplify things a bit by using devm functions where possible. Signed-off-by: David Lechner--- v3 changes: * Kept clk variable to minimize noise. drivers/usb/musb/da8xx.c | 19 +-- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index b03d3b8..0c1997c 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -490,20 +490,18 @@ static int da8xx_probe(struct platform_device *pdev) struct da8xx_glue *glue; struct platform_device_info pinfo; struct clk *clk; + int ret; - int ret = -ENOMEM; - - glue = kzalloc(sizeof(*glue), GFP_KERNEL); + glue = devm_kzalloc(>dev, sizeof(*glue), GFP_KERNEL); if (!glue) { dev_err(>dev, "failed to allocate glue context\n"); - goto err0; + return -ENOMEM; } - clk = clk_get(>dev, "usb20"); + clk = devm_clk_get(>dev, "usb20"); if (IS_ERR(clk)) { dev_err(>dev, "failed to get clock\n"); - ret = PTR_ERR(clk); - goto err3; + return PTR_ERR(clk); } ret = clk_enable(clk); @@ -560,12 +558,7 @@ err5: clk_disable(clk); err4: - clk_put(clk); - -err3: - kfree(glue); -err0: return ret; } @@ -576,8 +569,6 @@ static int da8xx_remove(struct platform_device *pdev) platform_device_unregister(glue->musb); usb_phy_generic_unregister(glue->phy); clk_disable(glue->clk); - clk_put(glue->clk); - kfree(glue); return 0; } -- 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
[PATCH v3 16/16] usb: musb: da8xx: Remove mach code
Use the new phy-da8xx-usb driver to take the place of the mach code that pokes CFGCHIP2 in the da8xx musb glue driver. This unbreaks the driver. Signed-off-by: David Lechner--- v3 changes: * removed depends on BROKEN and added select PHY_DA8XX_USB to Kconfig * Added calls to phy_init and phy_exit drivers/usb/musb/Kconfig | 2 +- drivers/usb/musb/da8xx.c | 141 --- 2 files changed, 47 insertions(+), 96 deletions(-) diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 886526b..c73221a 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -82,7 +82,7 @@ config USB_MUSB_DA8XX tristate "DA8xx/OMAP-L1x" depends on ARCH_DAVINCI_DA8XX depends on NOP_USB_XCEIV - depends on BROKEN + select PHY_DA8XX_USB config USB_MUSB_TUSB6010 tristate "TUSB6010" diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 0c1997c..de210cb 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -30,13 +30,12 @@ #include #include #include +#include +#include #include #include #include -#include -#include - #include "musb_core.h" /* @@ -80,61 +79,15 @@ #define DA8XX_MENTOR_CORE_OFFSET 0x400 -#define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG) - struct da8xx_glue { struct device *dev; struct platform_device *musb; - struct platform_device *phy; + struct platform_device *usb_phy; struct clk *clk; + struct phy *phy; }; /* - * REVISIT (PM): we should be able to keep the PHY in low power mode most - * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 - * and, when in host mode, autosuspending idle root ports... PHY_PLLON - * (overriding SUSPENDM?) then likely needs to stay off. - */ - -static inline void phy_on(void) -{ - u32 cfgchip2 = __raw_readl(CFGCHIP2); - - /* -* Start the on-chip PHY and its PLL. -*/ - cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN); - cfgchip2 |= CFGCHIP2_PHY_PLLON; - __raw_writel(cfgchip2, CFGCHIP2); - - pr_info("Waiting for USB PHY clock good...\n"); - while (!(__raw_readl(CFGCHIP2) & CFGCHIP2_PHYCLKGD)) - cpu_relax(); -} - -static inline void phy_off(void) -{ - u32 cfgchip2 = __raw_readl(CFGCHIP2); - - /* -* Ensure that USB 1.1 reference clock is not being sourced from -* USB 2.0 PHY. Otherwise do not power down the PHY. -*/ - if (!(cfgchip2 & CFGCHIP2_USB1PHYCLKMUX) && -(cfgchip2 & CFGCHIP2_USB1SUSPENDM)) { - pr_warning("USB 1.1 clocked from USB 2.0 PHY -- " - "can't power it down\n"); - return; - } - - /* -* Power down the on-chip PHY. -*/ - cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN; - __raw_writel(cfgchip2, CFGCHIP2); -} - -/* * Because we don't set CTRL.UINT, it's "important" to: * - not read/write INTRUSB/INTRUSBE (except during * initial setup, as a workaround); @@ -385,29 +338,14 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode) { - u32 cfgchip2 = __raw_readl(CFGCHIP2); + struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); - cfgchip2 &= ~CFGCHIP2_OTGMODE; - switch (musb_mode) { - case MUSB_HOST: /* Force VBUS valid, ID = 0 */ - cfgchip2 |= CFGCHIP2_FORCE_HOST; - break; - case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ - cfgchip2 |= CFGCHIP2_FORCE_DEVICE; - break; - case MUSB_OTG: /* Don't override the VBUS/ID comparators */ - cfgchip2 |= CFGCHIP2_NO_OVERRIDE; - break; - default: - dev_dbg(musb->controller, "Trying to set unsupported mode %u\n", musb_mode); - } - - __raw_writel(cfgchip2, CFGCHIP2); - return 0; + return da8xx_usb20_phy_set_mode(glue->phy, musb_mode); } static int da8xx_musb_init(struct musb *musb) { + struct da8xx_glue *glue = dev_get_drvdata(musb->controller->parent); void __iomem *reg_base = musb->ctrl_base; u32 rev; int ret = -ENODEV; @@ -425,32 +363,56 @@ static int da8xx_musb_init(struct musb *musb) goto fail; } + ret = clk_prepare_enable(glue->clk); + if (ret) { + dev_err(glue->dev, "failed to enable clock\n"); + goto fail; + } + setup_timer(_workaround, otg_timer, (unsigned long)musb); /* Reset the controller */ musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); /* Start the on-chip PHY and its PLL. */ - phy_on(); + ret =
[PATCH v3 12/16] ARM: dt: da850: Add cfgchip syscon node
Add a syscon node for the SoC CFGCHIPn registers. This is needed for the new usb phy driver. Signed-off-by: David Lechner--- v3 changes: This is a new patch. arch/arm/boot/dts/da850.dtsi | 4 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index 4294849..a360713 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -150,6 +150,10 @@ }; }; + cfgchip: cfgchip@1417c { + compatible = "ti,da830-cfgchip", "syscon"; + reg = <0x1417c 0x14>; + }; edma0: edma@0 { compatible = "ti,edma3-tpcc"; /* eDMA3 CC0: 0x01c0 - 0x01c0 7fff */ -- 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
[PATCH v3 05/16] ARM: davinci: add set_parent callback for mux clocks
Introduce a set_parent callback that will be used for mux clocks, such as the USB PHY muxes and the async3 clock domain mux. Signed-off-by: David Lechner--- v3 changes: none. arch/arm/mach-davinci/clock.c | 17 - arch/arm/mach-davinci/clock.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index a5c2629..dfc2eb3 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -195,6 +195,13 @@ int clk_set_parent(struct clk *clk, struct clk *parent) return -EINVAL; mutex_lock(_mutex); + if (clk->set_parent) { + int ret = clk->set_parent(clk, parent); + if (ret) { + mutex_unlock(_mutex); + return ret; + } + } clk->parent = parent; list_del_init(>childnode); list_add(>childnode, >parent->children); @@ -224,8 +231,16 @@ int clk_register(struct clk *clk) mutex_lock(_mutex); list_add_tail(>node, ); - if (clk->parent) + if (clk->parent) { + if (clk->set_parent) { + int ret = clk->set_parent(clk, clk->parent); + if (ret) { + mutex_unlock(_mutex); + return ret; + } + } list_add_tail(>childnode, >parent->children); + } mutex_unlock(_mutex); /* If rate is already set, use it */ diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 8b0fbbe..96a591f 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -106,6 +106,7 @@ struct clk { int (*reset) (struct clk *clk, bool reset); void (*clk_enable) (struct clk *clk); void (*clk_disable) (struct clk *clk); + int (*set_parent) (struct clk *clk, struct clk *parent); }; /* Clock flags: SoC-specific flags start at BIT(16) */ -- 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
[PATCH] usb: gadget: fsl_udc_core: Fix pullup status
udc->softconnect should be set regardless of the VBUS state, otherwise the USB peripheral device, connected during suspend, won't be detected since can_pullup() would return false the UDC controller won't be enabled. Fixes: 252455c40316 (usb: gadget: fsl driver pullup fix) Signed-off-by: Dmitry Osipenko--- drivers/usb/gadget/udc/fsl_udc_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index aab5221..118cf7a 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -1220,10 +1220,11 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) udc = container_of(gadget, struct fsl_udc, gadget); + udc->softconnect = (is_on != 0); + if (!udc->vbus_active) return -EOPNOTSUPP; - udc->softconnect = (is_on != 0); if (can_pullup(udc)) fsl_writel((fsl_readl(_regs->usbcmd) | USB_CMD_RUN_STOP), _regs->usbcmd); -- 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] usb: dwc2: do not override forced dr_mode in gadget setup
On 3/16/2016 3:10 PM, Przemek Rudy wrote: > The host/device mode set with dr_mode should be kept all the time, > not being changed to OTG in gadget setup (by overriding CFGUSB_FORCEDEVMODE > and CFGUSB_FORCEHOSTMODE bits). > > Signed-off-by: Przemek Rudy> --- > drivers/usb/dwc2/gadget.c | 23 ++- > 1 file changed, 18 insertions(+), 5 deletions(-) > > diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c > index e9940dd..818f158 100644 > --- a/drivers/usb/dwc2/gadget.c > +++ b/drivers/usb/dwc2/gadget.c > @@ -2254,6 +2254,7 @@ void dwc2_hsotg_core_init_disconnected(struct > dwc2_hsotg *hsotg, > { > u32 intmsk; > u32 val; > + u32 usbcfg; > > /* Kill any ep0 requests as controller will be reinitialized */ > kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET); > @@ -2267,10 +2268,16 @@ void dwc2_hsotg_core_init_disconnected(struct > dwc2_hsotg *hsotg, >* set configuration. >*/ > > + /* keep other bits untouched (so e.g. forced modes are not lost) */ > + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); > + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | > + GUSBCFG_HNPCAP); > + > /* set the PLL on, remove the HNP/SRP and set the PHY */ > val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; > - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | > -(val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG); > + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | > + (val << GUSBCFG_USBTRDTIM_SHIFT); > + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); > > dwc2_hsotg_init_fifo(hsotg); > > @@ -3031,6 +3038,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = { > static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) > { > u32 trdtim; > + u32 usbcfg; > /* unmask subset of endpoint interrupts */ > > dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK | > @@ -3054,11 +3062,16 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg) > > dwc2_hsotg_init_fifo(hsotg); > > + /* keep other bits untouched (so e.g. forced modes are not lost) */ > + usbcfg = dwc2_readl(hsotg->regs + GUSBCFG); > + usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP | > + GUSBCFG_HNPCAP); > + > /* set the PLL on, remove the HNP/SRP and set the PHY */ > trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5; > - dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) | > - (trdtim << GUSBCFG_USBTRDTIM_SHIFT), > - hsotg->regs + GUSBCFG); > + usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) | > + (trdtim << GUSBCFG_USBTRDTIM_SHIFT); > + dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); > > if (using_dma(hsotg)) > __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN); > Acked-by: John Youn Tested-by: John Youn Regards, John -- 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: USB gadgets with configfs hang reboot
Hi, On 24.03.2016 09:11, Felipe Balbi wrote: Hi, Ivaylo Dimitrovwrites: Ivaylo Dimitrov writes: On 16.01.2016 12:40, Ivaylo Dimitrov wrote: Hi, On 16.01.2016 00:48, Tony Lindgren wrote: Hi all, Looks like there's some issue with the USB gadgets and configfs. I'm seeing rmmod of the UDC driver cause a warning and then reboot hangs the system. This happens at least with v4.4, and I've reproduced it with dwc3 and musb so it seems to be generic. Having configfs is not needed, disabling usb gadgets (# CONFIG_USB_MUSB_GADGET is not set) seems to solved at least poweroff hang issue on N900. Also, g_nokia is not a module in the config I use, so I guess the problem is not related whether gadgets are modular or not. Unfortunately I was not able to test reboot, as rootfs became corrupted after the first poweroff :( . So it looks like my theory that onenand corruption on N900 is because poweroff/reboot hangs is wrong. Ivo Is there any progress on the issue? Doing Nokia-N900:/sys/bus/platform/drivers/musb-hdrc# echo musb-hdrc.0.auto > unbind results in: <1>[ 1418.511260] Unable to handle kernel paging request at virtual address 6c6c757a <7>[ 1418.677215] pvr: Xorg: cleaning up 49 unfreed resources <1>[ 1418.683349] pgd = c0004000 <1>[ 1418.739959] [6c6c757a] *pgd= <0>[ 1418.746307] Internal error: Oops: 5 [#1] PREEMPT ARM <4>[ 1418.753997] Modules linked in: sha256_generic hmac drbg ansi_cprng ctr ccm vfat fat rfcomm sd_mod scsi_mod bnep bluetooth omaplfb pvrsrvkm ipv6 bq2415x_charger uinput radio_platform_si4713 joydev cmt_speech hsi_char video_bus_switch arc4 wl1251_spi wl1251 isp1704_charger gpio_keys mac80211 smc91x mii cfg80211 omap_wdt crc7 omap_sham tsc2005 tsc200x_core bq27xxx_battery_i2c si4713 adp1653 tsl2563 leds_lp5523 leds_lp55xx_common bq27xxx_battery rtc_twl twl4030_wdt et8ek8 ad5820 v4l2_common smiaregs twl4030_vibra videodev ff_memless lis3lv02d_i2c lis3lv02d media input_polldev omap_ssi_port ti_soc_thermal nokia_modem ssi_protocol omap_ssi hsi rx51_battery <4>[ 1418.835906] CPU: 0 PID: 53 Comm: file-storage Not tainted 4.5.0-rc5+ #59 <4>[ 1418.846130] Hardware name: Nokia RX-51 board <4>[ 1418.853820] task: ceb8a300 ti: ce008000 task.ti: ce008000 <4>[ 1418.862792] PC is at handle_exception+0xa8/0x418 <4>[ 1418.871002] LR is at recalc_sigpending+0x18/0x7c <4>[ 1418.879241] pc : []lr : []psr: 8013 <4>[ 1418.879241] sp : ce009ea0 ip : fp : <4>[ 1418.898284] r10: r9 : r8 : <4>[ 1418.907287] r7 : c031d8d0 r6 : 6c6c7566 r5 : r4 : cebe1600 <4>[ 1418.917663] r3 : 6f642820 r2 : r1 : r0 : <4>[ 1418.928039] Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none <4>[ 1418.939025] Control: 10c5387d Table: 8e244019 DAC: 0051 <0>[ 1418.948516] Process file-storage (pid: 53, stack limit = 0xce008210) <0>[ 1418.958679] Stack: (0xce009ea0 to 0xce00a000) <0>[ 1418.966735] 9ea0: 000f 0b07 0001 03ff 0001 <0>[ 1418.978973] 9ec0: ceb8a300 ceb8a300 c004841c 0002 ce888000 c0451a50 <0>[ 1418.991180] 9ee0: 0008 cebe1600 0001 c0717dd0 0001 <0>[ 1419.003387] 9f00: ce009f14 c044ddf4 c031c020 0042 ce009f30 <0>[ 1419.015686] 9f20: ce009f30 cebe1600 c031d958 c044d864 a013 <0>[ 1419.027923] 9f40: cebe1600 c031d8d0 cebfa100 cebfa100 cebe1600 c031d8d0 <0>[ 1419.040130] 9f60: c00474e4 dc4d900d 31bc92e7 cebe1600 <0>[ 1419.052429] 9f80: ce009f84 ce009f84 ce009f90 ce009f90 ce009fac cebfa100 <0>[ 1419.064697] 9fa0: c0047418 c000f218 <0>[ 1419.076934] 9fc0: <0>[ 1419.089050] 9fe0: 0013 2000 3891 <4>[ 1419.101043] [] (handle_exception) from [] (fsg_main_thread+0x88/0x13dc) <4>[ 1419.113189] [] (fsg_main_thread) from [] (kthread+0xcc/0xe0) <4>[ 1419.124267] [] (kthread) from [] (ret_from_fork+0x14/0x3c) <0>[ 1419.135101] Code: 1a15 ea40 e5946038 e0866285 (e5963014) <4>[ 1419.330841] ---[ end trace 3377457e25b0732c ]--- <0>[ 1419.340972] Kernel panic - not syncing: Fatal exception weirdly, I have that log only in mtdoops, but not in dmesg. However, after that oops "reboot" command does not hang, but reboots the device. So, what is handle_exception + 0xa8 ? You can figure that out either with gdb or addr2line assuming your vmlinux has dbg symbols. For gdb you would: gdb vmlinux (gdb) l *(handle_exception + 0xa8) Yeah, sorry I didn't do it with the previous mail. Reading symbols from /home/ivo/workspace/linux-upstream/github/fmg/linux-n900/vmlinux...done. (gdb) l *(handle_exception + 0xa8) 0xc031d0e4
Re: [PATCH v4] USB: serial: cp210x: Adding GPIO support for CP2105
On 01/02/16 12:43, Martyn Welch wrote: On 31/01/16 19:54, Johan Hovold wrote: On Mon, Jan 18, 2016 at 02:14:37PM +, Martyn Welch wrote: + +/* 2 banks of GPIO - One for the pins taken from each serial port */ +if (port_priv->bInterfaceNumber == 0 && (buf[0] & 0xFF) != 0) { No need to AND a u8 with 0xff. +port_priv->gc.label = "cp210x_eci"; +port_priv->gc.ngpio = 2; +} else if (port_priv->bInterfaceNumber == 1 && + (buf[1] & 0xFF) != 0) { +port_priv->gc.label = "cp210x_sci"; +port_priv->gc.ngpio = 3; +} else { +result = 0; +goto err; +} So this is cp2105 specific. Also cp2102, cp2103 and cp2108 supports gpios. You don't have to add support for all types at once, but at least make sure whatever design decisions you make allows for easy extension to these types. The cp2105 is the only one of these devices that muxes GPIO with serial control signals. The cp2102, cp2103 and cp2108 provide both GPIO and serial control signals separately, so the logic to configure the GPIO for those devices will be much simpler. (Hence why I called this cp210x_shared_gpio_init, as I figured the best approach for supporting the other devices would be through a separate init routine). What about the other configurations supported for these pins (e.g. traffic indication, rs485, ...). Would you also end up with non-zero values for those? Will investigate. Sorry for the long delay - I got diverted by other things. I've now worked out how to both program a device for these alternate modes (it's not clear in the data sheet and the configuration GUI available for Linux at least doesn't seem to be able to configure devices into these modes) and worked out how to check which GPIO are being used by them. The configuration allows one or both of the 2 ECI GPIO to be used and one or both of the first 2 SCI GPIO to be used. i.e. I could have: ECI: - Both GPIO available. - GPIO 0 available. - GPIO 1 available. SCI: - All 3 GPIO available. - GPIO 0 & 2 available. - GPIO 1 & 2 available. - GPIO 2 available. Can anyone provide some advise on best to map this into the GPIO framework? Martyn -- 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: Problem with dwc2 gadget isochronous in transfers
On 3/24/2016 4:32 AM, John Keeping wrote: > Hi, > > I've been trying to use the uac2 gadget function on a Radxa Rock2 board > which uses the dwc2 driver, but it seems there is a problem with > isochronous in endpoints (out works fine). > > When trying to use the audio gadget no data is transferred and the other > end of the link ends up timing out. With debug logging enabled in dwc2 > the GINTSTS_INCOMPL_SOIN interrupt triggers continuously, as seen in the > log below (from which I snipped 6,000+ more occurences). I'm guessing > the root cause of this relates to the line: > > [ 320.656450] dwc2 ff58.usb: dwc2_hsotg_epint: EPDisbld > > during the setup phase, but I have no idea why that's happening. > Hi John, We have a patch series that fixes up the ISOC code and which possibly addresses the failures here. We hope to submit them for review within the next week or so. Appreciate if you would test and report any problems based off of those patches. Regards, John -- 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] USBHID: fix inconsistent reset/resume/reset-resume behavior
On Wed, 23 Mar 2016, Alan Stern wrote: > The usbhid driver has inconsistently duplicated code in its post-reset, > resume, and reset-resume pathways. > > reset-resume doesn't check HID_STARTED before trying to > restart the I/O queues. > > resume fails to clear the HID_SUSPENDED flag if HID_STARTED > isn't set. > > resume calls usbhid_restart_queues() with usbhid->lock held > and the others call it without holding the lock. > > The first item in particular causes a problem following a reset-resume > if the driver hasn't started up its I/O. URB submission fails because > usbhid->urbin is NULL, and this triggers an unending reset-retry loop. > > This patch fixes the problem by creating a new subroutine, > hid_restart_io(), to carry out all the common activities. It also > adds some checks that were missing in the original code: > > After a reset, there's no need to clear any halted endpoints. > > After a resume, if a reset is pending there's no need to > restart any I/O until the reset is finished. > > After a resume, if the interrupt-IN endpoint is halted there's > no need to submit the input URB until the halt has been > cleared. In addition to this being an actual fix, it's a nice cleanup as well. Thanks a lot; queuing for 4.6. -- Jiri Kosina SUSE Labs -- 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: bcma: use simpler devm helper for getting vcc GPIO
On 03/24/2016 05:26 PM, Rafał Miłecki wrote: Thanks to switching to devm_gpiod_get: 1) We don't have to pass fwnode pointer 2) We can request initial GPIO value at getting call This was successfully tested on Netgear R6250 (BCM4708). Signed-off-by: Rafał Miłecki--- drivers/usb/host/bcma-hcd.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 963e2d0..172ef17 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -352,10 +352,8 @@ static int bcma_hcd_probe(struct bcma_device *core) usb_dev->core = core; if (core->dev.of_node) - usb_dev->gpio_desc = devm_get_gpiod_from_child(>dev, "vcc", - >dev.of_node->fwnode); - if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) - gpiod_direction_output(usb_dev->gpio_desc, 1); + usb_dev->gpio_desc = devm_gpiod_get(>dev, "vcc", + GPIOD_OUT_HIGH); Do you need to check the returned descriptor? Do you mean like in future, after initialization? Yes. You can check it with grep gpio_desc drivers/usb/host/bcma-hcd.c Oh, sorry! I mean you need to check the pointer returned by devm_gpiod_get(). Sure. I don't need to. Only some of devices have USB power controlled using GPIO, so having this entry in DT is optional. Then use devm_gpiod_get_optional()? I see this function (_optional) hides err number from caller. I'm not sure why it should matter for us. Is there any difference at the end? It only hides an error caused by missing prop, so that you can filter out the other errors. OTOH, with gpiolib disabled, -ENOSYS is returned. That kinda makes little sense... :-/ MBR, 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] USB: bcma: use simpler devm helper for getting vcc GPIO
On 24 March 2016 at 14:58, Sergei Shtylyovwrote: > On 03/24/2016 08:37 AM, Rafał Miłecki wrote: > >> Thanks to switching to devm_gpiod_get: >> 1) We don't have to pass fwnode pointer >> 2) We can request initial GPIO value at getting call >> This was successfully tested on Netgear R6250 (BCM4708). >> >> Signed-off-by: Rafał Miłecki >> --- >> drivers/usb/host/bcma-hcd.c | 6 ++ >> 1 file changed, 2 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c >> index 963e2d0..172ef17 100644 >> --- a/drivers/usb/host/bcma-hcd.c >> +++ b/drivers/usb/host/bcma-hcd.c >> @@ -352,10 +352,8 @@ static int bcma_hcd_probe(struct bcma_device >> *core) >>usb_dev->core = core; >> >>if (core->dev.of_node) >> - usb_dev->gpio_desc = >> devm_get_gpiod_from_child(>dev, "vcc", >> - >> >dev.of_node->fwnode); >> - if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) >> - gpiod_direction_output(usb_dev->gpio_desc, 1); >> + usb_dev->gpio_desc = devm_gpiod_get(>dev, "vcc", >> + GPIOD_OUT_HIGH); > > Do you need to check the returned descriptor? Do you mean like in future, after initialization? Yes. You can check it with grep gpio_desc drivers/usb/host/bcma-hcd.c >>> >>> >>> Oh, sorry! >>> >>> I mean you need to check the pointer returned by devm_gpiod_get(). >> >> >> Sure. I don't need to. Only some of devices have USB power controlled >> using GPIO, so having this entry in DT is optional. > > >Then use devm_gpiod_get_optional()? I see this function (_optional) hides err number from caller. I'm not sure why it should matter for us. Is there any difference at the end? -- Rafał -- 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 06/11] phy: da8xx-usb: new driver for DA8XX SoC USB PHY
From: David Lechner > Sent: 23 March 2016 18:07 > On 03/23/2016 12:21 PM, Sekhar Nori wrote: > >> +/* DA8xx CFGCHIP2 (USB PHY Control) register bits */ > >> +#define PHYCLKGD (1 << 17) > >> +#define VBUSSENSE (1 << 16) > >> +#define RESET (1 << 15) > >> +#define OTGMODE_MASK (3 << 13) > >> +#define NO_OVERRIDE (0 << 13) > >> +#define FORCE_HOST(1 << 13) > >> +#define FORCE_DEVICE (2 << 13) > >> +#define FORCE_HOST_VBUS_LOW (3 << 13) I think I'd define the above as: #define OTG_MODE(x) ((x) << 13) #define OTGMODE_MASKOTG_MODE(3) #define NO_OVERRIDE OTG_MODE(0) #define FORCE_HOST OTG_MODE(1) #define FORCE_DEVICEOTG_MODE(2) #define FORCE_HOST_VBUS_LOW OTG_MODE(3) Then realise that all the names need changing (to include OTG). > >> +#define USB1PHYCLKMUX (1 << 12) > >> +#define USB2PHYCLKMUX (1 << 11) > >> +#define PHYPWRDN (1 << 10) > >> +#define OTGPWRDN (1 << 9) > >> +#define DATPOL(1 << 8) > >> +#define USB1SUSPENDM (1 << 7) > >> +#define PHY_PLLON (1 << 6) > >> +#define SESENDEN (1 << 5) > >> +#define VBDTCTEN (1 << 4) > >> +#define REFFREQ_MASK (0xf << 0) > >> +#define REFFREQ_12MHZ (1 << 0) > >> +#define REFFREQ_24MHZ (2 << 0) > >> +#define REFFREQ_48MHZ (3 << 0) > >> +#define REFFREQ_19_2MHZ (4 << 0) > >> +#define REFFREQ_38_4MHZ (5 << 0) > >> +#define REFFREQ_13MHZ (6 << 0) > >> +#define REFFREQ_26MHZ (7 << 0) > >> +#define REFFREQ_20MHZ (8 << 0) > >> +#define REFFREQ_40MHZ (9 << 0) I'd define these similarly to the OTGxxx values. > > Many of these register bits are unused. I guess opinion varies around > > this, but I get confused with unnecessary bit definitions and register > > offsets. I tend to search for it and its sort of disappointing to see > > that its basically unused. Of course, you should wait for PHY > > maintainers preference. It can be useful to see what isn't being set. Sometimes this can be very useful when making changes to a driver. For status values it is particularly important to know what all the bits mean. > My thinking was that since this driver *owns* the CFGCHIP2 register that > is would eventually register clocks using the common clock framework, in > which case, it would use many of these registers. > > But, based on feedback on another commit, if we go the syscon route, > then yes, I will remove the unused values. > > > >> +EXPORT_SYMBOL_GPL(da8xx_usb20_phy_set_mode); > > > > Hmm, since this driver exports this symbol, I think it should also > > provide an include file in include/linux/phy for users of the symbol. Or > > perhaps there should be a generic API around this since it looks like > > most USB phys will need something similar? > > > > The reason I didn't make a header file is that this function is only > meant to be use in one place and would likely cause a crash if used > anywhere else. And a compilation error if compiled with -Wmissing-prototypes. Sounds like you need a header file just for this driver's 'private' exports. IMHO .c files shouldn't contain 'extern' anywhere. I removed a load from some local code and found quite a few lurking bugs where the types didn't match. David -- 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: bcma: use simpler devm helper for getting vcc GPIO
Hello. On 03/24/2016 08:37 AM, Rafał Miłecki wrote: Thanks to switching to devm_gpiod_get: 1) We don't have to pass fwnode pointer 2) We can request initial GPIO value at getting call This was successfully tested on Netgear R6250 (BCM4708). Signed-off-by: Rafał Miłecki--- drivers/usb/host/bcma-hcd.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 963e2d0..172ef17 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -352,10 +352,8 @@ static int bcma_hcd_probe(struct bcma_device *core) usb_dev->core = core; if (core->dev.of_node) - usb_dev->gpio_desc = devm_get_gpiod_from_child(>dev, "vcc", - >dev.of_node->fwnode); - if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) - gpiod_direction_output(usb_dev->gpio_desc, 1); + usb_dev->gpio_desc = devm_gpiod_get(>dev, "vcc", + GPIOD_OUT_HIGH); Do you need to check the returned descriptor? Do you mean like in future, after initialization? Yes. You can check it with grep gpio_desc drivers/usb/host/bcma-hcd.c Oh, sorry! I mean you need to check the pointer returned by devm_gpiod_get(). Sure. I don't need to. Only some of devices have USB power controlled using GPIO, so having this entry in DT is optional. Then use devm_gpiod_get_optional()? MBR, 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 v3] usb: hcd: out of bounds access in for_each_companion
On Thu, 24 Mar 2016, Robert Dobrowolski wrote: > From: Robert Dobrowolski> > On BXT platform Host Controller and Device Controller figure as > same PCI device but with different device function. HCD should > not pass data to Device Controller but only to Host Controllers. > Checking if companion device is Host Controller, otherwise skip. > > Cc: > Signed-off-by: Robert Dobrowolski > --- > Changes in v3: > - Removed footer from patch, added CC > Changes in v2: > - Changed condition to skip companion if its not known >host controller type Acked-by: 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: unable to handle kernel NULL pointer dereference at usb_audio_probe
On Thu, Mar 24, 2016 at 01:34:32PM +, Ian T. Jacobsen wrote: > [ 21.434822] BUG: unable to handle kernel NULL pointer dereference at > 0014 [ 21.435516] IP: [] > usb_audio_probe+0x2ca/0x9a0 [snd_usb_audio] > > I have a PreSonus AudioBox iTwo causing this issue. > I updated from torvalds git yesterday A patch has been sent to the sound mailing list for this: http://lkml.kernel.org/g/1458045306-4170-1-git-send-email-nicsta...@gmail.com It solved the issue for me, please let the developers of it know if it didn't work for you. 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 03/11] ARM: davinci: da850: use clk->set_parent for async3
On Thursday 24 March 2016 12:02 AM, David Lechner wrote: > On 03/23/2016 12:29 PM, Sekhar Nori wrote: >> >> Alright, I guess 'can be called' in the comment should have used >> stronger language :) How about late registration of USB clocks as I >> suggested. It should also help consolidate code across da830 and da850. >> > > What about the new async3 clock? It will require later registration too, > but it has many children that depend on it. I guess that was the reason why it was done the way it was. Can we leave that alone for now (not use the new set_parent interface)? You don't really need that to be changed for USB functionality, right? Thanks, sekhar -- 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
unable to handle kernel NULL pointer dereference at usb_audio_probe
[ 21.434822] BUG: unable to handle kernel NULL pointer dereference at 0014 [ 21.435516] IP: [] usb_audio_probe+0x2ca/0x9a0 [snd_usb_audio] I have a PreSonus AudioBox iTwo causing this issue. I updated from torvalds git yesterday dmesg.output Description: Binary data
Re: [RFC] PANTHERPOINT needing yet another quirk
On 22.03.2016 18:23, Oliver Neukum wrote: I have a report of a T430 laptop needing this unless you want shut downs turn into reboot. Is there any hope of investigating this further at Intel, or do we go for the cautious approach? Oliver Neukum (1): xhci: one more quirk for PANTHERPOINT drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) I don't have a T430 to try this on, I need to revisit the code related to XHCI_SLOW_SUSPEND, XHCI_SPURIOUS_REBOOT and XHCI_SPURIOUS_WAKEUP flags again -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
[PATCH v8 1/4] 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. It also supplies the notification mechanism to userspace When the usb charger state is changed. 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. This patch doesn't yet integrate with the gadget code, so some functions which rely on the 'gadget' are not completed, that will be implemented in the following patches. Signed-off-by: Baolin Wang--- drivers/usb/gadget/Kconfig |7 + drivers/usb/gadget/Makefile |1 + drivers/usb/gadget/charger.c| 675 +++ include/linux/usb/usb_charger.h | 164 ++ 4 files changed, 847 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 af5d922..82a5b3c 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -133,6 +133,13 @@ config U_SERIAL_CONSOLE help It supports the serial gadget can be used as a console. +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..861c144 --- /dev/null +++ b/drivers/usb/gadget/charger.c @@ -0,0 +1,675 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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) +#define UCHGER_STATE_LENGTH(50) + +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); +} + +/* + * Sysfs attributes: + * + * These sysfs attributes are used for showing and setting different type + * (SDP/DCP/CDP/ACA) chargers' current limitation. + */ +static ssize_t sdp_limit_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct usb_charger *uchger = dev_to_uchger(dev); + + return sprintf(buf, "%d\n", uchger->cur_limit.sdp_cur_limit); +} + +static ssize_t sdp_limit_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_charger *uchger = dev_to_uchger(dev); + unsigned int sdp_limit; + int ret; + + ret = kstrtouint(buf, 10, _limit); + if (ret < 0) + return ret; + + ret = usb_charger_set_cur_limit_by_type(uchger, SDP_TYPE, sdp_limit); + if (ret < 0) + return ret; + + return count; +} +static DEVICE_ATTR_RW(sdp_limit); + +static ssize_t dcp_limit_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ +
[PATCH v8 3/4] 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--- drivers/usb/gadget/charger.c | 43 -- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/charger.c b/drivers/usb/gadget/charger.c index 861c144..b02c842 100644 --- a/drivers/usb/gadget/charger.c +++ b/drivers/usb/gadget/charger.c @@ -278,7 +278,11 @@ EXPORT_SYMBOL_GPL(usb_charger_unregister_notify); enum usb_charger_type usb_charger_detect_type(struct usb_charger *uchger) { - if (uchger->psy) { + if (uchger->gadget && uchger->gadget->ops + && uchger->gadget->ops->get_charger_type) { + uchger->type = + uchger->gadget->ops->get_charger_type(uchger->gadget); + } else if (uchger->psy) { union power_supply_propval val; power_supply_get_property(uchger->psy, @@ -485,6 +489,29 @@ usb_charger_plug_by_extcon(struct notifier_block *nb, int usb_charger_plug_by_gadget(struct usb_gadget *gadget, unsigned long state) { + struct usb_charger *uchger = gadget->charger; + enum usb_charger_state uchger_state; + + if (!uchger) + return -EINVAL; + + /* Report event to power to setting the current limitation +* for this usb charger when one usb charger state is changed +* with detecting by usb gadget state. +*/ + if (uchger->old_gadget_state != state) { + uchger->old_gadget_state = state; + + if (state >= USB_STATE_ATTACHED) + uchger_state = USB_CHARGER_PRESENT; + else if (state == USB_STATE_NOTATTACHED) + uchger_state = USB_CHARGER_REMOVE; + else + uchger_state = USB_CHARGER_DEFAULT; + + usb_charger_notify_others(uchger, uchger_state); + } + return 0; } EXPORT_SYMBOL_GPL(usb_charger_plug_by_gadget); @@ -641,6 +668,7 @@ int usb_charger_init(struct usb_gadget *ugadget) /* register a notifier on a usb gadget device */ uchger->gadget = ugadget; + ugadget->charger = uchger; uchger->old_gadget_state = ugadget->state; /* register a new usb charger */ @@ -661,7 +689,18 @@ fail: int usb_charger_exit(struct usb_gadget *ugadget) { - return 0; + struct usb_charger *uchger = ugadget->charger; + + if (!uchger) + return -EINVAL; + + if (uchger->extcon_dev) + extcon_unregister_notifier(uchger->extcon_dev, + EXTCON_USB, >extcon_nb.nb); + + ida_simple_remove(_charger_ida, uchger->id); + + return usb_charger_unregister(uchger); } static int __init usb_charger_sysfs_init(void) -- 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 v8 2/4] 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. It will report to the usb charger when the gadget state is changed, then the usb charger can do the power things. 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--- drivers/usb/gadget/udc/udc-core.c | 11 +++ include/linux/usb/gadget.h| 11 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index b86a6f0..3d9a489 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -28,6 +28,7 @@ #include #include #include +#include /** * struct usb_udc - describes one usb device controller @@ -230,6 +231,9 @@ static void usb_gadget_state_work(struct work_struct *work) struct usb_gadget *gadget = work_to_gadget(work); struct usb_udc *udc = gadget->udc; + /* when the gadget state is changed, then report to USB charger */ + usb_charger_plug_by_gadget(gadget, gadget->state); + if (udc) sysfs_notify(>dev.kobj, NULL, "state"); } @@ -423,8 +427,14 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, mutex_unlock(_lock); + ret = usb_charger_init(gadget); + if (ret) + goto err5; + return 0; +err5: + device_del(>dev); err4: list_del(>list); mutex_unlock(_lock); @@ -503,6 +513,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget) kobject_uevent(>dev.kobj, KOBJ_REMOVE); flush_work(>work); device_unregister(>dev); + usb_charger_exit(gadget); device_unregister(>dev); } EXPORT_SYMBOL_GPL(usb_del_gadget_udc); diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index d82d006..024b33d 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -24,6 +24,7 @@ #include #include #include +#include struct usb_ep; @@ -563,6 +564,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 *); }; /** @@ -635,6 +637,8 @@ struct usb_gadget { unsignedout_epnum; unsignedin_epnum; struct usb_otg_caps *otg_caps; + /* negotiate the power with the usb charger */ + struct usb_charger *charger; unsignedsg_supported:1; unsignedis_otg:1; @@ -839,10 +843,17 @@ static inline int usb_gadget_vbus_connect(struct usb_gadget *gadget) * reporting how much power the device may consume. For example, this * could affect how quickly batteries are recharged. * + * It will also notify the USB charger how much power the device may + * consume if there is a USB charger linking with the gadget. + * * Returns zero on success, else negative errno. */ static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) { + if (gadget->charger) + usb_charger_set_cur_limit_by_type(gadget->charger, + usb_charger_detect_type(gadget->charger), mA); + if (!gadget->ops->vbus_draw) return -EOPNOTSUPP; return gadget->ops->vbus_draw(gadget, mA); -- 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 v8 0/4] 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. Thus provide a standard framework for doing this in 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 v7: - Add documentations for sysfs attributes. Other prominent improvements since v5: - Remove the notifier chain things from the gadget and introduce one callback function to report to the usb charger when the gadget state is changed. - Flesh out the port type detection which combines the USB negotiation and PMICs detection. - Supply the notification mechanism to userspace when charger state is changed. - Integrate with the vbus staff in the gadget API. Baolin Wang (4): 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 | 714 + drivers/usb/gadget/udc/udc-core.c | 11 + include/linux/mfd/wm831x/pdata.h |3 + include/linux/usb/gadget.h| 11 + include/linux/usb/usb_charger.h | 164 + 8 files changed, 980 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 v8 4/4] 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 BrownSigned-off-by: Baolin Wang Acked-by: Lee Jones Acked-by: Charles Keepax Acked-by: Peter Chen Acked-by: Sebastian Reichel --- 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 7082301..043f1f4 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -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 milliamps */ +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 */ @@ -607,8 +647,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(>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, + >usb_notify); + if (ret != 0) { + dev_err(>dev, + "Failed to register notifier: %d\n", ret); + goto err_usb_charger; + } + } + return ret; +err_usb_charger: + /* put_device on 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, + _power->usb_notify); + /* Free 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
Problem with dwc2 gadget isochronous in transfers
Hi, I've been trying to use the uac2 gadget function on a Radxa Rock2 board which uses the dwc2 driver, but it seems there is a problem with isochronous in endpoints (out works fine). When trying to use the audio gadget no data is transferred and the other end of the link ends up timing out. With debug logging enabled in dwc2 the GINTSTS_INCOMPL_SOIN interrupt triggers continuously, as seen in the log below (from which I snipped 6,000+ more occurences). I'm guessing the root cause of this relates to the line: [ 320.656450] dwc2 ff58.usb: dwc2_hsotg_epint: EPDisbld during the setup phase, but I have no idea why that's happening. The log below was captured on master at 968f3e374faf (Merge branch 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs) with the commit I posted last week [1] cherry-picked on top and rk3288-rock2-square.dts modified to enable the OTG port, although I see the same behaviour on 4.4. My test case is: cd /sys/kernel/config && mkdir -p usb_gadget/g1 && cd usb_gadget/g1 && echo 0x0001 >idVendor && echo 0x0001 >idProduct && mkdir -p strings/0x409 && echo 1234567890 >strings/0x409/serialnumber && echo 'Dummy Corp.' >strings/0x409/manufacturer && echo 'Dummy Product' >strings/0x409/product && mkdir -p configs/c.1 && ( cd configs/c.1 && mkdir -p strings/0x409 && echo 'My Configuration' >strings/0x409/configuration && echo 100 >MaxPower ) && mkdir functions/uac2.otg0 && echo 44100 >functions/uac2.otg0/p_srate && echo 44100 >functions/uac2.otg0/c_srate && ln -s functions/uac2.otg0 configs/c.1 && echo ff58.usb >UDC and then running "arecord -c2 -r44100 -Dhw:2,0" on the machine at the other end. [1] http://article.gmane.org/gmane.linux.kernel/2176675 Thanks, John -- >8 -- [0.00] Booting Linux on physical CPU 0x500 [0.00] Linux version 4.5.0 (john@leela) (gcc version 5.3.0 (Buildroot 2016.02-rc1-dirty) ) #7 SMP Wed Mar 23 16:51:43 GMT 2016 [0.00] CPU: ARMv7 Processor [410fc0d1] revision 1 (ARMv7), cr=10c5387d [0.00] CPU: div instructions available: patching division code [0.00] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [0.00] Machine model: InMusic MPC [0.00] cma: Reserved 64 MiB at 0x1980 [0.00] Memory policy: Data cache writealloc [0.00] On node 0 totalpages: 131072 [0.00] free_area_init_node: node 0, pgdat c140d740, node_mem_map dfbd9000 [0.00] DMA zone: 1024 pages used for memmap [0.00] DMA zone: 0 pages reserved [0.00] DMA zone: 131072 pages, LIFO batch:31 [0.00] percpu: Embedded 12 pages/cpu @dfb89000 s19776 r8192 d21184 u49152 [0.00] pcpu-alloc: s19776 r8192 d21184 u49152 alloc=12*4096 [0.00] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0.00] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048 [0.00] Kernel command line: console=ttyS2,115200 init=/sbin/init root=/dev/mmcblk0p2 rootfstype=ext4 ro rootwait earlyprintk [0.00] PID hash table entries: 2048 (order: 1, 8192 bytes) [0.00] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes) [0.00] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes) [0.00] Memory: 434000K/524288K available (9470K kernel code, 1085K rwdata, 4252K rodata, 2048K init, 2260K bss, 24752K reserved, 65536K cma-reserved, 0K highmem) [0.00] Virtual kernel memory layout: vector : 0x - 0x1000 ( 4 kB) fixmap : 0xffc0 - 0xfff0 (3072 kB) vmalloc : 0xe080 - 0xff80 ( 496 MB) lowmem : 0xc000 - 0xe000 ( 512 MB) pkmap : 0xbfe0 - 0xc000 ( 2 MB) modules : 0xbf00 - 0xbfe0 ( 14 MB) .text : 0xc0208000 - 0xc1066bb8 (14715 kB) .init : 0xc110 - 0xc130 (2048 kB) .data : 0xc130 - 0xc140f7a0 (1086 kB) .bss : 0xc1411000 - 0xc16463c0 (2261 kB) [0.00] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 [0.00] Hierarchical RCU implementation. [0.00] Build-time adjustment of leaf fanout to 32. [0.00] RCU restricting CPUs from NR_CPUS=16 to nr_cpu_ids=4. [0.00] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=4 [0.00] NR_IRQS:16 nr_irqs:16 16 [0.00] Architected cp15 timer(s) running at 24.00MHz (phys). [0.00] clocksource: arch_sys_counter: mask: 0xff max_cycles: 0x588fe9dc0, max_idle_ns:
[PATCH v3] usb: hcd: out of bounds access in for_each_companion
From: Robert DobrowolskiOn BXT platform Host Controller and Device Controller figure as same PCI device but with different device function. HCD should not pass data to Device Controller but only to Host Controllers. Checking if companion device is Host Controller, otherwise skip. Cc: Signed-off-by: Robert Dobrowolski --- Changes in v3: - Removed footer from patch, added CC Changes in v2: - Changed condition to skip companion if its not known host controller type drivers/usb/core/hcd-pci.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index f9d42cf..7859d73 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -73,6 +73,15 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd, if (companion->bus != pdev->bus || PCI_SLOT(companion->devfn) != slot) continue; + + /* +* Companion device should be either UHCI,OHCI or EHCI host +* controller, otherwise skip. +*/ + if (companion->class != CL_UHCI && companion->class != CL_OHCI && + companion->class != CL_EHCI) + continue; + companion_hcd = pci_get_drvdata(companion); if (!companion_hcd || !companion_hcd->self.root_hub) continue; -- 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
[PATCH v4] usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host
From: Rafal RedzimskiBroxton B0 also requires XHCI_PME_STUCK_QUIRK. Adding PCI device ID for Broxton B and adding to quirk. Cc: Signed-off-by: Rafal Redzimski Signed-off-by: Robert Dobrowolski --- Changes in v4: - Updating commit message Changes in v3: - Corrected cc list Changes in v2: - Fixed commit message drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f0640b7..071b34a 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -48,6 +48,7 @@ #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI0xa12f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 +#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8 static const char hcd_name[] = "xhci_hcd"; @@ -155,7 +156,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || -pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { +pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || +pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && -- 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 v3] usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host
Robert Dobrowolskiwrites: > [ text/plain ] > From: Rafal Redzimski > > Broxton B0 also requires XHCI_PME_STUCK_QUIRK. > Adding PCI device ID for Broxton B and adding to quirk. > > Signed-off-by: Rafal Redzimski > Signed-off-by: Robert Dobrowolski you still missed mathias (who I've added to the Cc list). You can always rely on scripts/get_maintainer.pl to give you sensible list of addresses who should be Cced for a give patch. And you're also missing a: Cc: here on your commit log. Before Rafal's S-o-B. See commit e18b7975c885bc3a938b9a76daf32957ea0235fa for example :-) -- balbi signature.asc Description: PGP signature
Re: [PATCH] Add DCD line support to CP210x driver
Sorry, I missed the branch. Here it is. This patch adds DCD line support to CP210x USB serial driver. First it enables CP210x events embedding to incoming URB's by calling: cp210x_set_config_single(port, CP210X_EMBED_EVENTS, CP210X_ESCCHAR); Then it parses incoming URB's via custom routine: cp210x_process_read_urb(...) searches for event sequences and handles all of DCD changes calling usb_serial_handle_dcd_change(...) Signed-off-by: Valentin Yakovenkov--- drivers/usb/serial/cp210x.c | 118 +++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index c740592..ef0e8b1 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -47,6 +47,7 @@ static void cp210x_break_ctl(struct tty_struct *, int); static int cp210x_port_probe(struct usb_serial_port *); static int cp210x_port_remove(struct usb_serial_port *); static void cp210x_dtr_rts(struct usb_serial_port *p, int on); +static void cp210x_process_read_urb(struct urb *urb); static const struct usb_device_id id_table[] = { { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */ @@ -199,9 +200,21 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); +#define CP210X_ESCCHAR 0x1e +enum cp210x_rx_state { + CP210X_STATE_IDLE = 0, + CP210X_STATE_ESC, + CP210X_STATE_LS0, + CP210X_STATE_LS1, + CP210X_STATE_LS, + CP210X_STATE_MS +}; + + struct cp210x_port_private { __u8bInterfaceNumber; boolhas_swapped_line_ctl; + enum cp210x_rx_staterx_state; }; static struct usb_serial_driver cp210x_device = { @@ -222,7 +235,8 @@ static struct usb_serial_driver cp210x_device = { .tiocmset = cp210x_tiocmset, .port_probe = cp210x_port_probe, .port_remove= cp210x_port_remove, - .dtr_rts= cp210x_dtr_rts + .dtr_rts= cp210x_dtr_rts, + .process_read_urb = cp210x_process_read_urb }; static struct usb_serial_driver * const serial_drivers[] = { @@ -588,6 +602,11 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) { int result; + struct usb_serial *serial = port->serial; + struct cp210x_port_private *spriv = usb_get_serial_data(serial); + + spriv->rx_state = CP210X_STATE_IDLE; + result = cp210x_write_u16_reg(port, CP210X_IFC_ENABLE, UART_ENABLE); if (result) { dev_err(>dev, "%s - Unable to enable UART\n", __func__); @@ -601,6 +620,15 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) if (tty) cp210x_change_speed(tty, port, NULL); + /* Enable events embedding to data stream */ + result = cp210x_write_u16_reg(port, CP210X_EMBED_EVENTS, + CP210X_ESCCHAR); + if (result) { + dev_err(>dev, "%s - Unable to enable event embedding on UART\n", + __func__); + return result; + } + return usb_serial_generic_open(tty, port); } @@ -659,6 +687,94 @@ static bool cp210x_tx_empty(struct usb_serial_port *port) return !count; } +static void cp210x_process_read_urb(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + char *ch = (char *)urb->transfer_buffer; + char *tbuf = (char *)urb->transfer_buffer; + int i; + int tcnt = 0; + struct usb_serial *serial = port->serial; + struct cp210x_port_private *spriv = usb_get_serial_data(serial); + + if (!urb->actual_length) + return; + + /* Process escape chars */ + for (i = 0; i < urb->actual_length; i++) { + char c = ch[i]; + + switch (spriv->rx_state) { + case CP210X_STATE_IDLE: + if (c == CP210X_ESCCHAR) + spriv->rx_state = CP210X_STATE_ESC; + else + tbuf[tcnt++] = c; + break; + + case CP210X_STATE_ESC: + if (c == 0x01) + spriv->rx_state = CP210X_STATE_LS0; + else if (c == 0x02) + spriv->rx_state = CP210X_STATE_LS; + else if (c == 0x03) + spriv->rx_state = CP210X_STATE_MS; + else { + tbuf[tcnt++] = (c == 0x00) ? CP210X_ESCCHAR : c; + spriv->rx_state = CP210X_STATE_IDLE; + } + break; + + case CP210X_STATE_LS0: + spriv->rx_state =
[PATCH v3] usb: xhci: applying XHCI_PME_STUCK_QUIRK to Intel BXT B0 host
From: Rafal RedzimskiBroxton B0 also requires XHCI_PME_STUCK_QUIRK. Adding PCI device ID for Broxton B and adding to quirk. Signed-off-by: Rafal Redzimski Signed-off-by: Robert Dobrowolski --- Changes in v3: - Corrected cc list Changes in v2: - Fixed commit message drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index f0640b7..071b34a 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -48,6 +48,7 @@ #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI0xa12f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 +#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8 static const char hcd_name[] = "xhci_hcd"; @@ -155,7 +156,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || -pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { +pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI || +pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } if (pdev->vendor == PCI_VENDOR_ID_INTEL && -- 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: USB gadgets with configfs hang reboot
Hi, Ivaylo Dimitrovwrites: >> Ivaylo Dimitrov writes: >>> On 16.01.2016 12:40, Ivaylo Dimitrov wrote: Hi, On 16.01.2016 00:48, Tony Lindgren wrote: > Hi all, > > Looks like there's some issue with the USB gadgets and configfs. > > I'm seeing rmmod of the UDC driver cause a warning and then reboot > hangs the system. This happens at least with v4.4, and I've reproduced > it with dwc3 and musb so it seems to be generic. > Having configfs is not needed, disabling usb gadgets (# CONFIG_USB_MUSB_GADGET is not set) seems to solved at least poweroff hang issue on N900. Also, g_nokia is not a module in the config I use, so I guess the problem is not related whether gadgets are modular or not. Unfortunately I was not able to test reboot, as rootfs became corrupted after the first poweroff :( . So it looks like my theory that onenand corruption on N900 is because poweroff/reboot hangs is wrong. Ivo >>> >>> >>> Is there any progress on the issue? >> > > Doing Nokia-N900:/sys/bus/platform/drivers/musb-hdrc# echo > musb-hdrc.0.auto > unbind results in: > > <1>[ 1418.511260] Unable to handle kernel paging request at virtual > address 6c6c757a > <7>[ 1418.677215] pvr: Xorg: cleaning up 49 unfreed resources > <1>[ 1418.683349] pgd = c0004000 > <1>[ 1418.739959] [6c6c757a] *pgd= > <0>[ 1418.746307] Internal error: Oops: 5 [#1] PREEMPT ARM > <4>[ 1418.753997] Modules linked in: sha256_generic hmac drbg ansi_cprng > ctr ccm vfat fat rfcomm sd_mod scsi_mod bnep bluetooth omaplfb pvrsrvkm > ipv6 bq2415x_charger uinput radio_platform_si4713 joydev cmt_speech > hsi_char video_bus_switch arc4 wl1251_spi wl1251 isp1704_charger > gpio_keys mac80211 smc91x mii cfg80211 omap_wdt crc7 omap_sham tsc2005 > tsc200x_core bq27xxx_battery_i2c si4713 adp1653 tsl2563 leds_lp5523 > leds_lp55xx_common bq27xxx_battery rtc_twl twl4030_wdt et8ek8 ad5820 > v4l2_common smiaregs twl4030_vibra videodev ff_memless lis3lv02d_i2c > lis3lv02d media input_polldev omap_ssi_port ti_soc_thermal nokia_modem > ssi_protocol omap_ssi hsi rx51_battery > <4>[ 1418.835906] CPU: 0 PID: 53 Comm: file-storage Not tainted > 4.5.0-rc5+ #59 > <4>[ 1418.846130] Hardware name: Nokia RX-51 board > <4>[ 1418.853820] task: ceb8a300 ti: ce008000 task.ti: ce008000 > <4>[ 1418.862792] PC is at handle_exception+0xa8/0x418 > <4>[ 1418.871002] LR is at recalc_sigpending+0x18/0x7c > <4>[ 1418.879241] pc : []lr : []psr: 8013 > <4>[ 1418.879241] sp : ce009ea0 ip : fp : > <4>[ 1418.898284] r10: r9 : r8 : > <4>[ 1418.907287] r7 : c031d8d0 r6 : 6c6c7566 r5 : r4 : cebe1600 > <4>[ 1418.917663] r3 : 6f642820 r2 : r1 : r0 : > <4>[ 1418.928039] Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM > Segment none > <4>[ 1418.939025] Control: 10c5387d Table: 8e244019 DAC: 0051 > <0>[ 1418.948516] Process file-storage (pid: 53, stack limit = 0xce008210) > <0>[ 1418.958679] Stack: (0xce009ea0 to 0xce00a000) > <0>[ 1418.966735] 9ea0: 000f 0b07 > 0001 03ff 0001 > <0>[ 1418.978973] 9ec0: ceb8a300 ceb8a300 c004841c > 0002 ce888000 c0451a50 > <0>[ 1418.991180] 9ee0: 0008 cebe1600 > 0001 c0717dd0 0001 > <0>[ 1419.003387] 9f00: ce009f14 c044ddf4 > c031c020 0042 ce009f30 > <0>[ 1419.015686] 9f20: ce009f30 cebe1600 c031d958 > c044d864 a013 > <0>[ 1419.027923] 9f40: cebe1600 c031d8d0 cebfa100 cebfa100 > cebe1600 c031d8d0 > <0>[ 1419.040130] 9f60: c00474e4 dc4d900d > 31bc92e7 cebe1600 > <0>[ 1419.052429] 9f80: ce009f84 ce009f84 ce009f90 > ce009f90 ce009fac cebfa100 > <0>[ 1419.064697] 9fa0: c0047418 c000f218 > > <0>[ 1419.076934] 9fc0: > > <0>[ 1419.089050] 9fe0: 0013 > 2000 3891 > <4>[ 1419.101043] [] (handle_exception) from [] > (fsg_main_thread+0x88/0x13dc) > <4>[ 1419.113189] [] (fsg_main_thread) from [] > (kthread+0xcc/0xe0) > <4>[ 1419.124267] [] (kthread) from [] > (ret_from_fork+0x14/0x3c) > <0>[ 1419.135101] Code: 1a15 ea40 e5946038 e0866285 (e5963014) > <4>[ 1419.330841] ---[ end trace 3377457e25b0732c ]--- > <0>[ 1419.340972] Kernel panic - not syncing: Fatal exception > > weirdly, I have that log only in mtdoops, but not in dmesg. However, > after that oops "reboot" command does not hang, but reboots the device. So, what is handle_exception + 0xa8 ? You can figure that out either with gdb or addr2line assuming your vmlinux has dbg symbols. For gdb you would: gdb vmlinux
Re: USB gadgets with configfs hang reboot
Hi, On 24.03.2016 08:50, Felipe Balbi wrote: Hi, Ivaylo Dimitrovwrites: On 16.01.2016 12:40, Ivaylo Dimitrov wrote: Hi, On 16.01.2016 00:48, Tony Lindgren wrote: Hi all, Looks like there's some issue with the USB gadgets and configfs. I'm seeing rmmod of the UDC driver cause a warning and then reboot hangs the system. This happens at least with v4.4, and I've reproduced it with dwc3 and musb so it seems to be generic. Having configfs is not needed, disabling usb gadgets (# CONFIG_USB_MUSB_GADGET is not set) seems to solved at least poweroff hang issue on N900. Also, g_nokia is not a module in the config I use, so I guess the problem is not related whether gadgets are modular or not. Unfortunately I was not able to test reboot, as rootfs became corrupted after the first poweroff :( . So it looks like my theory that onenand corruption on N900 is because poweroff/reboot hangs is wrong. Ivo Is there any progress on the issue? Doing Nokia-N900:/sys/bus/platform/drivers/musb-hdrc# echo musb-hdrc.0.auto > unbind results in: <1>[ 1418.511260] Unable to handle kernel paging request at virtual address 6c6c757a <7>[ 1418.677215] pvr: Xorg: cleaning up 49 unfreed resources <1>[ 1418.683349] pgd = c0004000 <1>[ 1418.739959] [6c6c757a] *pgd= <0>[ 1418.746307] Internal error: Oops: 5 [#1] PREEMPT ARM <4>[ 1418.753997] Modules linked in: sha256_generic hmac drbg ansi_cprng ctr ccm vfat fat rfcomm sd_mod scsi_mod bnep bluetooth omaplfb pvrsrvkm ipv6 bq2415x_charger uinput radio_platform_si4713 joydev cmt_speech hsi_char video_bus_switch arc4 wl1251_spi wl1251 isp1704_charger gpio_keys mac80211 smc91x mii cfg80211 omap_wdt crc7 omap_sham tsc2005 tsc200x_core bq27xxx_battery_i2c si4713 adp1653 tsl2563 leds_lp5523 leds_lp55xx_common bq27xxx_battery rtc_twl twl4030_wdt et8ek8 ad5820 v4l2_common smiaregs twl4030_vibra videodev ff_memless lis3lv02d_i2c lis3lv02d media input_polldev omap_ssi_port ti_soc_thermal nokia_modem ssi_protocol omap_ssi hsi rx51_battery <4>[ 1418.835906] CPU: 0 PID: 53 Comm: file-storage Not tainted 4.5.0-rc5+ #59 <4>[ 1418.846130] Hardware name: Nokia RX-51 board <4>[ 1418.853820] task: ceb8a300 ti: ce008000 task.ti: ce008000 <4>[ 1418.862792] PC is at handle_exception+0xa8/0x418 <4>[ 1418.871002] LR is at recalc_sigpending+0x18/0x7c <4>[ 1418.879241] pc : []lr : []psr: 8013 <4>[ 1418.879241] sp : ce009ea0 ip : fp : <4>[ 1418.898284] r10: r9 : r8 : <4>[ 1418.907287] r7 : c031d8d0 r6 : 6c6c7566 r5 : r4 : cebe1600 <4>[ 1418.917663] r3 : 6f642820 r2 : r1 : r0 : <4>[ 1418.928039] Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none <4>[ 1418.939025] Control: 10c5387d Table: 8e244019 DAC: 0051 <0>[ 1418.948516] Process file-storage (pid: 53, stack limit = 0xce008210) <0>[ 1418.958679] Stack: (0xce009ea0 to 0xce00a000) <0>[ 1418.966735] 9ea0: 000f 0b07 0001 03ff 0001 <0>[ 1418.978973] 9ec0: ceb8a300 ceb8a300 c004841c 0002 ce888000 c0451a50 <0>[ 1418.991180] 9ee0: 0008 cebe1600 0001 c0717dd0 0001 <0>[ 1419.003387] 9f00: ce009f14 c044ddf4 c031c020 0042 ce009f30 <0>[ 1419.015686] 9f20: ce009f30 cebe1600 c031d958 c044d864 a013 <0>[ 1419.027923] 9f40: cebe1600 c031d8d0 cebfa100 cebfa100 cebe1600 c031d8d0 <0>[ 1419.040130] 9f60: c00474e4 dc4d900d 31bc92e7 cebe1600 <0>[ 1419.052429] 9f80: ce009f84 ce009f84 ce009f90 ce009f90 ce009fac cebfa100 <0>[ 1419.064697] 9fa0: c0047418 c000f218 <0>[ 1419.076934] 9fc0: <0>[ 1419.089050] 9fe0: 0013 2000 3891 <4>[ 1419.101043] [] (handle_exception) from [] (fsg_main_thread+0x88/0x13dc) <4>[ 1419.113189] [] (fsg_main_thread) from [] (kthread+0xcc/0xe0) <4>[ 1419.124267] [] (kthread) from [] (ret_from_fork+0x14/0x3c) <0>[ 1419.135101] Code: 1a15 ea40 e5946038 e0866285 (e5963014) <4>[ 1419.330841] ---[ end trace 3377457e25b0732c ]--- <0>[ 1419.340972] Kernel panic - not syncing: Fatal exception weirdly, I have that log only in mtdoops, but not in dmesg. However, after that oops "reboot" command does not hang, but reboots the device. Regards, Ivo -- 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 1/2] usb: dwc3: core: Introduce dwc3_device_reinit()
Hi, John Younwrites: > [ text/plain ] > On 3/21/2016 11:40 PM, Felipe Balbi wrote: >> >> Hi, >> >> John Youn writes: >>> [ text/plain ] >>> On 3/18/2016 12:17 PM, John Youn wrote: On 3/16/2016 6:56 AM, Felipe Balbi wrote: > > heh, +john > > Felipe Balbi writes: >> [ text/plain ] >> >> Hi, >> >> Roger Quadros writes: >>> [ text/plain ] >>> We will need this function for a workaround. >>> The function issues a softreset only to the device >>> controller and performs minimal re-initialization >>> so that the device controller can be usable. >>> >>> As some code is similar to dwc3_core_init() take out >>> common code into dwc3_get_gctl_quirks(). >>> >>> We add a new member (prtcap_mode) to struct dwc3 to >>> keep track of the current mode in the PRTCAPDIR register. >>> >>> Signed-off-by: Roger Quadros >> >> I must say, I don't like this at all :-p There's ONE known silicon which >> needs this because of a poor silicon integration which took an IP with a >> known erratum where it can't be made to work on lower speeds and STILL >> was integrated without a superspeed PHY. >> >> There's a reason why I never tried to push this upstream myself ;-) >> >> I'm really thinking we might be better off adding a quirk flag to skip >> the metastability workaround and allow this ONE silicon to set the >> controller to lower speed. >> >> John, can you check with your colleagues if we would ever fall into >> STAR#9000525659 if we set maximum speed to high speed during driver >> probe and never touch it again ? I would assume we don't really fall >> into the metastability workaround, right ? We're not doing any sort of >> PM for dwc3... >> >>> >>> Hi Felipe, >>> >>> Do you mean to keep DCFG.speed to SS and set dwc->maximum_speed to HS? >>> I don't see an issue with that as long as we always ignore >>> dwc->maximum_speed when programming DCFG.speed for all affected >>> versions of the core. As long as the DCFG.speed = SS, you should not >>> hit the STAR. >> >> I actually mean changing DCFG.speed during driver probe and never >> touching it again. Would that still cause problems ? >> > > In that case I'm not sure. The engineer who would know is off until > next week so I'll get back to you as soon as I can talk to him about > it. Thank you :-) -- balbi signature.asc Description: PGP signature
Re: USB gadgets with configfs hang reboot
Hi, Ivaylo Dimitrovwrites: > On 16.01.2016 12:40, Ivaylo Dimitrov wrote: >> Hi, >> >> On 16.01.2016 00:48, Tony Lindgren wrote: >>> Hi all, >>> >>> Looks like there's some issue with the USB gadgets and configfs. >>> >>> I'm seeing rmmod of the UDC driver cause a warning and then reboot >>> hangs the system. This happens at least with v4.4, and I've reproduced >>> it with dwc3 and musb so it seems to be generic. >>> >> >> Having configfs is not needed, disabling usb gadgets (# >> CONFIG_USB_MUSB_GADGET is not set) seems to solved at least poweroff >> hang issue on N900. Also, g_nokia is not a module in the config I use, >> so I guess the problem is not related whether gadgets are modular or >> not. Unfortunately I was not able to test reboot, as rootfs became >> corrupted after the first poweroff :( . So it looks like my theory that >> onenand corruption on N900 is because poweroff/reboot hangs is wrong. >> >> Ivo > > > Is there any progress on the issue? I don't have any DT-based system anymore, so there's very little I can do to help. That being said, it's not the first time of_platform_depopulate() causes problems. -- balbi signature.asc Description: PGP signature
Re: [RFT PATCH 2/2] Revert "usb: dwc2: Fix probe problem on bcm2835"
On 3/22/2016 12:44 PM, Doug Anderson wrote: > John, > > On Tue, Mar 22, 2016 at 12:26 PM, John Younwrote: >> Thanks for the debug logs and everyones help. >> >> After reviewing with our hardware engineers, it seems this is likely >> to do with the IDDIG debounce filtering when switching between >> modes. You can see if this is enabled in your core by checking >> GHWCFG4.IddgFltr. >> >> From the databook: >> >> OTG_EN_IDDIG_FILTER >> >> Specifies whether to add a filter on the "iddig" input from the >> PHY. If your PHY already has a filter on iddig for de-bounce, then >> it is not necessary to enable the one in the DWC_otg. The filter >> is implemented in the DWC_otg_wpc module as a 20-bit counter that >> works on the PHY clock. In the case of the UTMI+ PHY, this pin is >> from the PHY. In the case of the ULPI PHY, this signal is >> generated by the ULPI Wrapper inside the core. >> >> >> This only affects OTG cores and the delay is 10ms for 30MHz PHY clock >> and 50ms with a 6MHz PHY clock. > > Wow, nice to have it so perfectly explained! :) > > >> The reason we see this after a reset is that by default the IDDIG >> indicates device mode. But if the id pin is set to host the core will >> immediately detect it after the reset and trigger the filtering delay >> before changing to host mode. >> >> This delay is also triggered by force mode. This is the origin of the >> 25 ms delay specified in the databook. The databook did not take into >> account that there might be a 6MHz clock so this delay could actually >> be up to 50 ms. So we aren't delaying enough time for those cases. >> >> I think this explains all the problems and platform differences we are >> seeing related to this. >> >> I think we can just add an IDDIG delay after a force mode, a clear >> force mode, and any time after reset where we don't do either a force >> or clear force mode immediately afterwards. Maybe set the delay time >> via a core parameter or measure it once on probe. Or we can probably >> just poll for the mode change in all of the above conditions. > > The driver seems to be able to figure out the PHY clock in most cases > in dwc2_calc_frame_interval(). It doesn't seem to handle 6MHz there, > though. I wonder if that's another bug? > The 6 MHz is from a dedicated FS PHY operating at low speed. So that must be the case for the platforms showing 50 ms delay. > Polling seems fine too, though. I'm thinking that's the way to go as it can be troublesome to figure out the correct PHY clock speed. Regards, John -- 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