Re: [PATCH v3 1/2] usb: dwc3: Add Keystone specific glue layer
On Thursday 12 December 2013 02:41 PM, Felipe Balbi wrote: > On Thu, Dec 12, 2013 at 02:36:01PM -0500, Santosh Shilimkar wrote: >> On Thursday 12 December 2013 12:48 PM, Felipe Balbi wrote: >>> Hi, >>> >>> On Tue, Dec 10, 2013 at 10:11:36AM -0500, Santosh Shilimkar wrote: >> +static int kdwc3_remove(struct platform_device *pdev) >> +{ >> +struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); >> + >> +kdwc3_disable_irqs(kdwc); >> +clk_disable_unprepare(kdwc->clk); > > I hope the clock isn't shared between core and wrapper, otherwise you > could run into some troubles here. Can you confirm ? > Yes. the clock isn't shared. Thanks for taking care of other parts. >>> >>> so clock for core is always running too ? >>> >> I take that back. The clock is actually common so we should disable >> it after removing the kdwc3_remove_core() as you suggested. >> >> You won't see issue since the kdwc3_remove_core() not doing >> any register access but moving the clock disable after >> the core remove is right thing to do. > > the problem is not kdwc3_remove_core() accessing registers, but > dwc3_remove() _does_ access registers during remove. If you just > mopdrobe -r dwc3-keystone without removing dwc3.ko first, then > kdwc3_remove_core() will cause dwc3.ko to be removed (because of > platform_driver_unregister()) and, since clocks have already been > disabled, then we'd die :-) > Oh yes, you are right. I see Wingman already posted the updated patch. Regards, Santosh -- 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 1/2] usb: dwc3: Add Keystone specific glue layer
On Thu, Dec 12, 2013 at 02:36:01PM -0500, Santosh Shilimkar wrote: > On Thursday 12 December 2013 12:48 PM, Felipe Balbi wrote: > > Hi, > > > > On Tue, Dec 10, 2013 at 10:11:36AM -0500, Santosh Shilimkar wrote: > +static int kdwc3_remove(struct platform_device *pdev) > +{ > +struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); > + > +kdwc3_disable_irqs(kdwc); > +clk_disable_unprepare(kdwc->clk); > >>> > >>> I hope the clock isn't shared between core and wrapper, otherwise you > >>> could run into some troubles here. Can you confirm ? > >>> > >> Yes. the clock isn't shared. Thanks for taking care of other parts. > > > > so clock for core is always running too ? > > > I take that back. The clock is actually common so we should disable > it after removing the kdwc3_remove_core() as you suggested. > > You won't see issue since the kdwc3_remove_core() not doing > any register access but moving the clock disable after > the core remove is right thing to do. the problem is not kdwc3_remove_core() accessing registers, but dwc3_remove() _does_ access registers during remove. If you just mopdrobe -r dwc3-keystone without removing dwc3.ko first, then kdwc3_remove_core() will cause dwc3.ko to be removed (because of platform_driver_unregister()) and, since clocks have already been disabled, then we'd die :-) cheers -- balbi signature.asc Description: Digital signature
Re: [PATCH v3 1/2] usb: dwc3: Add Keystone specific glue layer
On Thursday 12 December 2013 12:48 PM, Felipe Balbi wrote: > Hi, > > On Tue, Dec 10, 2013 at 10:11:36AM -0500, Santosh Shilimkar wrote: +static int kdwc3_remove(struct platform_device *pdev) +{ + struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); + + kdwc3_disable_irqs(kdwc); + clk_disable_unprepare(kdwc->clk); >>> >>> I hope the clock isn't shared between core and wrapper, otherwise you >>> could run into some troubles here. Can you confirm ? >>> >> Yes. the clock isn't shared. Thanks for taking care of other parts. > > so clock for core is always running too ? > I take that back. The clock is actually common so we should disable it after removing the kdwc3_remove_core() as you suggested. You won't see issue since the kdwc3_remove_core() not doing any register access but moving the clock disable after the core remove is right thing to do. Regards, Santosh -- 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 1/2] usb: dwc3: Add Keystone specific glue layer
Hi, On Tue, Dec 10, 2013 at 10:11:36AM -0500, Santosh Shilimkar wrote: > >> +static int kdwc3_remove(struct platform_device *pdev) > >> +{ > >> + struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); > >> + > >> + kdwc3_disable_irqs(kdwc); > >> + clk_disable_unprepare(kdwc->clk); > > > > I hope the clock isn't shared between core and wrapper, otherwise you > > could run into some troubles here. Can you confirm ? > > > Yes. the clock isn't shared. Thanks for taking care of other parts. so clock for core is always running too ? -- balbi signature.asc Description: Digital signature
Re: [PATCH v3 1/2] usb: dwc3: Add Keystone specific glue layer
On Monday 09 December 2013 09:51 PM, Balbi, Felipe wrote: > Hi, > > On Mon, Dec 09, 2013 at 05:17:03PM -0500, WingMan Kwok wrote: >> +static void kdwc3_enable_irqs(struct dwc3_keystone *kdwc) >> +{ >> +u32 val; >> + >> +val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); >> +val = USBSS_IRQ_COREIRQ_EN; > > this misses the | in |=. I can fix it up while applying, this time only. > >> +static int kdwc3_probe(struct platform_device *pdev) >> +{ >> +struct device *dev = &pdev->dev; >> +struct device_node *node = pdev->dev.of_node; >> +struct dwc3_keystone*kdwc; >> +struct resource *res; >> +int error, irq; >> + >> +kdwc = devm_kzalloc(dev, sizeof(*kdwc), GFP_KERNEL); >> +if (!kdwc) >> +return -ENOMEM; >> + >> +platform_set_drvdata(pdev, kdwc); >> + >> +kdwc->dev = dev; >> + >> +res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> +if (!res) { >> +dev_err(dev, "missing usbss resource\n"); >> +return -EINVAL; >> +} >> + >> +kdwc->usbss = devm_ioremap_resource(dev, res); >> +if (IS_ERR(kdwc->usbss)) >> +return PTR_ERR(kdwc->usbss); >> + >> +kdwc3_dma_mask = dma_get_mask(dev); >> +dev->dma_mask = &kdwc3_dma_mask; >> + >> +kdwc->clk = devm_clk_get(kdwc->dev, "usb"); >> +if (IS_ERR_OR_NULL(kdwc->clk)) { > > clk_get() will never return NULL. This time, I'll fix it while applying. > >> +static int kdwc3_remove(struct platform_device *pdev) >> +{ >> +struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); >> + >> +kdwc3_disable_irqs(kdwc); >> +clk_disable_unprepare(kdwc->clk); > > I hope the clock isn't shared between core and wrapper, otherwise you > could run into some troubles here. Can you confirm ? > Yes. the clock isn't shared. Thanks for taking care of other parts. -- 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 1/2] usb: dwc3: Add Keystone specific glue layer
Hi, On Mon, Dec 09, 2013 at 05:17:03PM -0500, WingMan Kwok wrote: > +static void kdwc3_enable_irqs(struct dwc3_keystone *kdwc) > +{ > + u32 val; > + > + val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); > + val = USBSS_IRQ_COREIRQ_EN; this misses the | in |=. I can fix it up while applying, this time only. > +static int kdwc3_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct device_node *node = pdev->dev.of_node; > + struct dwc3_keystone*kdwc; > + struct resource *res; > + int error, irq; > + > + kdwc = devm_kzalloc(dev, sizeof(*kdwc), GFP_KERNEL); > + if (!kdwc) > + return -ENOMEM; > + > + platform_set_drvdata(pdev, kdwc); > + > + kdwc->dev = dev; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) { > + dev_err(dev, "missing usbss resource\n"); > + return -EINVAL; > + } > + > + kdwc->usbss = devm_ioremap_resource(dev, res); > + if (IS_ERR(kdwc->usbss)) > + return PTR_ERR(kdwc->usbss); > + > + kdwc3_dma_mask = dma_get_mask(dev); > + dev->dma_mask = &kdwc3_dma_mask; > + > + kdwc->clk = devm_clk_get(kdwc->dev, "usb"); > + if (IS_ERR_OR_NULL(kdwc->clk)) { clk_get() will never return NULL. This time, I'll fix it while applying. > +static int kdwc3_remove(struct platform_device *pdev) > +{ > + struct dwc3_keystone *kdwc = platform_get_drvdata(pdev); > + > + kdwc3_disable_irqs(kdwc); > + clk_disable_unprepare(kdwc->clk); I hope the clock isn't shared between core and wrapper, otherwise you could run into some troubles here. Can you confirm ? -- balbi signature.asc Description: Digital signature
[PATCH v3 1/2] usb: dwc3: Add Keystone specific glue layer
Add Keystone platform specific glue layer to support USB3 Host mode. Cc: Santosh Shilimkar Cc: Felipe Balbi Cc: Greg Kroah-Hartman Acked-by: Santosh Shilimkar Signed-off-by: WingMan Kwok --- drivers/usb/dwc3/Kconfig |7 ++ drivers/usb/dwc3/Makefile|1 + drivers/usb/dwc3/dwc3-keystone.c | 205 ++ 3 files changed, 213 insertions(+) create mode 100644 drivers/usb/dwc3/dwc3-keystone.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index 70fc430..e2c730f 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -70,6 +70,13 @@ config USB_DWC3_PCI One such PCIe-based platform is Synopsys' PCIe HAPS model of this IP. +config USB_DWC3_KEYSTONE + tristate "Texas Instruments Keystone2 Platforms" + default USB_DWC3 + help + Support of USB2/3 functionality in TI Keystone2 platforms. + Say 'Y' or 'M' here if you have one such device + comment "Debugging features" config USB_DWC3_DEBUG diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index dd17601..10ac3e7 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -32,3 +32,4 @@ endif obj-$(CONFIG_USB_DWC3_OMAP)+= dwc3-omap.o obj-$(CONFIG_USB_DWC3_EXYNOS) += dwc3-exynos.o obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o +obj-$(CONFIG_USB_DWC3_KEYSTONE)+= dwc3-keystone.o diff --git a/drivers/usb/dwc3/dwc3-keystone.c b/drivers/usb/dwc3/dwc3-keystone.c new file mode 100644 index 000..33f71330b --- /dev/null +++ b/drivers/usb/dwc3/dwc3-keystone.c @@ -0,0 +1,205 @@ +/** + * dwc3-keystone.c - Keystone Specific Glue layer + * + * Copyright (C) 2010-2013 Texas Instruments Incorporated - http://www.ti.com + * + * Author: WingMan Kwok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 of + * the License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* USBSS register offsets */ +#define USBSS_REVISION 0x +#define USBSS_SYSCONFIG0x0010 +#define USBSS_IRQ_EOI 0x0018 +#define USBSS_IRQSTATUS_RAW_0 0x0020 +#define USBSS_IRQSTATUS_0 0x0024 +#define USBSS_IRQENABLE_SET_0 0x0028 +#define USBSS_IRQENABLE_CLR_0 0x002c + +/* IRQ register bits */ +#define USBSS_IRQ_EOI_LINE(n) BIT(n) +#define USBSS_IRQ_EVENT_ST BIT(0) +#define USBSS_IRQ_COREIRQ_EN BIT(0) +#define USBSS_IRQ_COREIRQ_CLR BIT(0) + +static u64 kdwc3_dma_mask; + +struct dwc3_keystone { + struct device *dev; + struct clk *clk; + void __iomem*usbss; +}; + +static inline u32 kdwc3_readl(void __iomem *base, u32 offset) +{ + return readl(base + offset); +} + +static inline void kdwc3_writel(void __iomem *base, u32 offset, u32 value) +{ + writel(value, base + offset); +} + +static void kdwc3_enable_irqs(struct dwc3_keystone *kdwc) +{ + u32 val; + + val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); + val = USBSS_IRQ_COREIRQ_EN; + kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, val); +} + +static void kdwc3_disable_irqs(struct dwc3_keystone *kdwc) +{ + u32 val; + + val = kdwc3_readl(kdwc->usbss, USBSS_IRQENABLE_SET_0); + val &= ~USBSS_IRQ_COREIRQ_EN; + kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, val); +} + +static irqreturn_t dwc3_keystone_interrupt(int irq, void *_kdwc) +{ + struct dwc3_keystone*kdwc = _kdwc; + + kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_CLR_0, USBSS_IRQ_COREIRQ_CLR); + kdwc3_writel(kdwc->usbss, USBSS_IRQSTATUS_0, USBSS_IRQ_EVENT_ST); + kdwc3_writel(kdwc->usbss, USBSS_IRQENABLE_SET_0, USBSS_IRQ_COREIRQ_EN); + kdwc3_writel(kdwc->usbss, USBSS_IRQ_EOI, USBSS_IRQ_EOI_LINE(0)); + + return IRQ_HANDLED; +} + +static int kdwc3_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct dwc3_keystone*kdwc; + struct resource *res; + int error, irq; + + kdwc = devm_kzalloc(dev, sizeof(*kdwc), GFP_KERNEL); + if (!kdwc) + return -ENOMEM; + + platform_set_drvdata(pdev, kdwc); + + kdwc->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "missing usbss resource\n"); + return -EINVAL; + } + + kdwc->usbss = devm_ioremap_resource(dev, res); +