Skip to content

Commit

Permalink
Merge tag 'dwc3-for-v3.4' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/balbi/usb into usb-next

usb: dwc3: changes for v3.4 merge window

Here are the changes for v3.4 merge window.

It includes a new glue layer for Samsung's Exynos platform, a simplification of
memory management on DWC3 driver by using dev_xxx functions, a few
optimizations to IRQ handling by dropping memcpy() and using bitshifts, a fix
for TI's OMAP5430 TX Fifo Allocation, two fixes on USB2 test mode
implementation (one on debugfs and one on ep0), and several minor changes such
as whitespace cleanups, simplification of a few parts of the code, decreasing a
long delay to something a bit saner, dropping a header which was included twice
and so on.

The highlight on this merge is the support for Samsung's Exynos platform,
increasing the number of different users for this driver to three.

Note that Samsung Exynos glue layer will only compile on platforms which
provide implementation for the clk API for now. Once Samsung supports
pm_runtime, that limitation can be dropped from the Makefile.

Conflicts:
	drivers/usb/dwc3/gadget.c
  • Loading branch information
Greg Kroah-Hartman committed Mar 2, 2012
2 parents cd70469 + c2df85c commit 3d71769
Show file tree
Hide file tree
Showing 12 changed files with 921 additions and 413 deletions.
13 changes: 13 additions & 0 deletions drivers/usb/dwc3/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ endif

obj-$(CONFIG_USB_DWC3) += dwc3-omap.o

##
# REVISIT Samsung Exynos platform needs the clk API which isn't
# defined on all architectures. If we allow dwc3-exynos.c compile
# always we will fail the linking phase on those architectures
# which don't provide clk api implementation and that's unnaceptable.
#
# When Samsung's platform start supporting pm_runtime, this check
# for HAVE_CLK should be removed.
##
ifneq ($(CONFIG_HAVE_CLK),)
obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
endif

ifneq ($(CONFIG_PCI),)
obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
endif
Expand Down
108 changes: 50 additions & 58 deletions drivers/usb/dwc3/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/of.h>

#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/module.h>

#include "core.h"
#include "gadget.h"
Expand Down Expand Up @@ -86,7 +86,7 @@ int dwc3_get_device_id(void)
id = -ENOMEM;
}

return 0;
return id;
}
EXPORT_SYMBOL_GPL(dwc3_get_device_id);

Expand Down Expand Up @@ -167,11 +167,11 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
}

/**
* dwc3_alloc_one_event_buffer - Allocated one event buffer structure
* dwc3_alloc_one_event_buffer - Allocates one event buffer structure
* @dwc: Pointer to our controller context structure
* @length: size of the event buffer
*
* Returns a pointer to the allocated event buffer structure on succes
* Returns a pointer to the allocated event buffer structure on success
* otherwise ERR_PTR(errno).
*/
static struct dwc3_event_buffer *__devinit
Expand Down Expand Up @@ -215,10 +215,10 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)

/**
* dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
* @dwc: Pointer to out controller context structure
* @dwc: pointer to our controller context structure
* @length: size of event buffer
*
* Returns 0 on success otherwise negative errno. In error the case, dwc
* Returns 0 on success otherwise negative errno. In the error case, dwc
* may contain some buffers allocated but not all which were requested.
*/
static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
Expand Down Expand Up @@ -251,7 +251,7 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)

/**
* dwc3_event_buffers_setup - setup our allocated event buffers
* @dwc: Pointer to out controller context structure
* @dwc: pointer to our controller context structure
*
* Returns 0 on success otherwise negative errno.
*/
Expand Down Expand Up @@ -350,7 +350,7 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
dwc3_cache_hwparams(dwc);

reg = dwc3_readl(dwc->regs, DWC3_GCTL);
reg &= ~DWC3_GCTL_SCALEDOWN(3);
reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
reg &= ~DWC3_GCTL_DISSCRAMBLE;

switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
Expand All @@ -363,9 +363,9 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)

/*
* WORKAROUND: DWC3 revisions <1.90a have a bug
* when The device fails to connect at SuperSpeed
* where the device can fail to connect at SuperSpeed
* and falls back to high-speed mode which causes
* the device to enter in a Connect/Disconnect loop
* the device to enter a Connect/Disconnect loop
*/
if (dwc->revision < DWC3_REVISION_190A)
reg |= DWC3_GCTL_U2RSTECN;
Expand Down Expand Up @@ -404,8 +404,10 @@ static void dwc3_core_exit(struct dwc3 *dwc)

static int __devinit dwc3_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct resource *res;
struct dwc3 *dwc;
struct device *dev = &pdev->dev;

int ret = -ENOMEM;
int irq;
Expand All @@ -415,47 +417,47 @@ static int __devinit dwc3_probe(struct platform_device *pdev)

u8 mode;

mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
if (!mem) {
dev_err(&pdev->dev, "not enough memory\n");
goto err0;
dev_err(dev, "not enough memory\n");
return -ENOMEM;
}
dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
dwc->mem = mem;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "missing resource\n");
goto err1;
dev_err(dev, "missing resource\n");
return -ENODEV;
}

dwc->res = res;

res = request_mem_region(res->start, resource_size(res),
dev_name(&pdev->dev));
res = devm_request_mem_region(dev, res->start, resource_size(res),
dev_name(dev));
if (!res) {
dev_err(&pdev->dev, "can't request mem region\n");
goto err1;
dev_err(dev, "can't request mem region\n");
return -ENOMEM;
}

regs = ioremap(res->start, resource_size(res));
regs = devm_ioremap(dev, res->start, resource_size(res));
if (!regs) {
dev_err(&pdev->dev, "ioremap failed\n");
goto err2;
dev_err(dev, "ioremap failed\n");
return -ENOMEM;
}

irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "missing IRQ\n");
goto err3;
dev_err(dev, "missing IRQ\n");
return -ENODEV;
}

spin_lock_init(&dwc->lock);
platform_set_drvdata(pdev, dwc);

dwc->regs = regs;
dwc->regs_size = resource_size(res);
dwc->dev = &pdev->dev;
dwc->dev = dev;
dwc->irq = irq;

if (!strncmp("super", maximum_speed, 5))
Expand All @@ -469,14 +471,17 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
else
dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;

pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
pm_runtime_forbid(&pdev->dev);
if (of_get_property(node, "tx-fifo-resize", NULL))
dwc->needs_fifo_resize = true;

pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
pm_runtime_forbid(dev);

ret = dwc3_core_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize core\n");
goto err3;
dev_err(dev, "failed to initialize core\n");
return ret;
}

mode = DWC3_MODE(dwc->hwparams.hwparams0);
Expand All @@ -486,49 +491,49 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize gadget\n");
goto err4;
dev_err(dev, "failed to initialize gadget\n");
goto err1;
}
break;
case DWC3_MODE_HOST:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
goto err4;
dev_err(dev, "failed to initialize host\n");
goto err1;
}
break;
case DWC3_MODE_DRD:
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
ret = dwc3_host_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n");
goto err4;
dev_err(dev, "failed to initialize host\n");
goto err1;
}

ret = dwc3_gadget_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize gadget\n");
goto err4;
dev_err(dev, "failed to initialize gadget\n");
goto err1;
}
break;
default:
dev_err(&pdev->dev, "Unsupported mode of operation %d\n", mode);
goto err4;
dev_err(dev, "Unsupported mode of operation %d\n", mode);
goto err1;
}
dwc->mode = mode;

ret = dwc3_debugfs_init(dwc);
if (ret) {
dev_err(&pdev->dev, "failed to initialize debugfs\n");
goto err5;
dev_err(dev, "failed to initialize debugfs\n");
goto err2;
}

pm_runtime_allow(&pdev->dev);
pm_runtime_allow(dev);

return 0;

err5:
err2:
switch (mode) {
case DWC3_MODE_DEVICE:
dwc3_gadget_exit(dwc);
Expand All @@ -545,19 +550,9 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
break;
}

err4:
dwc3_core_exit(dwc);

err3:
iounmap(regs);

err2:
release_mem_region(res->start, resource_size(res));

err1:
kfree(dwc->mem);
dwc3_core_exit(dwc);

err0:
return ret;
}

Expand Down Expand Up @@ -590,9 +585,6 @@ static int __devexit dwc3_remove(struct platform_device *pdev)
}

dwc3_core_exit(dwc);
release_mem_region(res->start, resource_size(res));
iounmap(dwc->regs);
kfree(dwc->mem);

return 0;
}
Expand Down
Loading

0 comments on commit 3d71769

Please sign in to comment.