usb: dwc3: patches for v3.8

We can finaly drop HAVE_CLK dependency from exynos glue layer
 now that clk API provides no-op stubs when it's not linked
 into the kernel.
 
 We're also switching over event buffer allocation to devm_kzalloc()
 and moving the allocation out of dwc3_core_init() so that can be
 re-used when implementing PM support for v3.9.
 
 After the introduction of PLATFORM_DEVID_AUTO, we can also drop the
 homebrew platform device ID handling we had on dwc3 core and let
 driver core take care of that for us.
 
 Exynos glue layer learns about DeviceTree and drops platform_data
 support completely.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJQnWwFAAoJEIaOsuA1yqREBCwP/0QH34TL292W0BH9wKj7GVgK
 fT9DOKWGJFNr238WcDmnl+NBVVtWuEjqcAplNNWpJndwRm36lD1WCYOe/fPEh01h
 rm0scCijJcvgpBbQDOAR4B9UbMe9YcymWvuZ7Rx9217ryHiy352OlNoKfAkJOt2e
 JXMREHl7yJwWv6x5pN44NaMDgL/LqFnhvf8KAqo5LjR7XUJlkKQcmUmzkqyxGvnq
 9BFiOoIiRSwmTtnieulgvocgWgmlzkMabeAWvY/w5Cq3g2FKWVwBqg1zyRQK9MrE
 YEoEFy6Edc37C2CrmjaK6g/3Mw7p4v5s0AmU4jCRSFcpk2jpqZa+TEHkdCwgyXXY
 g/nlerxhprc5OFw7BnX26A7u1tIEfVMc9K3lcbadc5PpyiHnsveQHlr7kxhfPocF
 12AhfQRx8G/a365Fle88fTZs+aDKiBnIqpzzLNTHBw3riBdgvQsIjx4X+7Y0rE46
 v1SXqW/H0thlY38YpUQ5a4jNVKUNJJM4vamQ7cu7i9m2n0nHshfMPx2xe5NFKUHW
 bI44+pTq1FO73mmkFbWmMRCdE7aRv63aQInQ4nSbVHBi7Nv+xv8nNT8Y3XJu9T27
 bEv9nXxpx0GFwLQYcwzrhyI7Ws7+EZU5W13vemQUf4EEtwBZq4d9NxUYCUg2OpYo
 ivHz3p1AtBkjL6ImFxjc
 =wqLI
 -----END PGP SIGNATURE-----

Merge tag 'dwc3-for-v3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next

USB dwc3 patches from Felipe:

"usb: dwc3: patches for v3.8

We can finaly drop HAVE_CLK dependency from exynos glue layer
now that clk API provides no-op stubs when it's not linked
into the kernel.

We're also switching over event buffer allocation to devm_kzalloc()
and moving the allocation out of dwc3_core_init() so that can be
re-used when implementing PM support for v3.9.

After the introduction of PLATFORM_DEVID_AUTO, we can also drop the
homebrew platform device ID handling we had on dwc3 core and let
driver core take care of that for us.

Exynos glue layer learns about DeviceTree and drops platform_data
support completely."
This commit is contained in:
Greg Kroah-Hartman 2012-11-11 17:22:01 -08:00
commit 0f89fc3fd8
6 changed files with 43 additions and 132 deletions

View File

@ -27,19 +27,7 @@ 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
obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o
ifneq ($(CONFIG_PCI),)
obj-$(CONFIG_USB_DWC3) += dwc3-pci.o

View File

@ -66,45 +66,6 @@ MODULE_PARM_DESC(maximum_speed, "Maximum supported speed.");
/* -------------------------------------------------------------------------- */
#define DWC3_DEVS_POSSIBLE 32
static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE);
int dwc3_get_device_id(void)
{
int id;
again:
id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE);
if (id < DWC3_DEVS_POSSIBLE) {
int old;
old = test_and_set_bit(id, dwc3_devs);
if (old)
goto again;
} else {
pr_err("dwc3: no space for new device\n");
id = -ENOMEM;
}
return id;
}
EXPORT_SYMBOL_GPL(dwc3_get_device_id);
void dwc3_put_device_id(int id)
{
int ret;
if (id < 0)
return;
ret = test_bit(id, dwc3_devs);
WARN(!ret, "dwc3: ID %d not in use\n", id);
smp_mb__before_clear_bit();
clear_bit(id, dwc3_devs);
}
EXPORT_SYMBOL_GPL(dwc3_put_device_id);
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
{
u32 reg;
@ -169,7 +130,6 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
struct dwc3_event_buffer *evt)
{
dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
kfree(evt);
}
/**
@ -185,7 +145,7 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
{
struct dwc3_event_buffer *evt;
evt = kzalloc(sizeof(*evt), GFP_KERNEL);
evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL);
if (!evt)
return ERR_PTR(-ENOMEM);
@ -193,10 +153,8 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
evt->length = length;
evt->buf = dma_alloc_coherent(dwc->dev, length,
&evt->dma, GFP_KERNEL);
if (!evt->buf) {
kfree(evt);
if (!evt->buf)
return ERR_PTR(-ENOMEM);
}
return evt;
}
@ -215,8 +173,6 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
if (evt)
dwc3_free_one_event_buffer(dwc, evt);
}
kfree(dwc->ev_buffs);
}
/**
@ -235,7 +191,8 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length)
num = DWC3_NUM_INT(dwc->hwparams.hwparams1);
dwc->num_event_buffers = num;
dwc->ev_buffs = kzalloc(sizeof(*dwc->ev_buffs) * num, GFP_KERNEL);
dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num,
GFP_KERNEL);
if (!dwc->ev_buffs) {
dev_err(dwc->dev, "can't allocate event buffers array\n");
return -ENOMEM;
@ -383,24 +340,14 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc)
dwc3_writel(dwc->regs, DWC3_GCTL, reg);
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
if (ret) {
dev_err(dwc->dev, "failed to allocate event buffers\n");
ret = -ENOMEM;
goto err1;
}
ret = dwc3_event_buffers_setup(dwc);
if (ret) {
dev_err(dwc->dev, "failed to setup event buffers\n");
goto err1;
goto err0;
}
return 0;
err1:
dwc3_free_event_buffers(dwc);
err0:
return ret;
}
@ -408,11 +355,9 @@ err0:
static void dwc3_core_exit(struct dwc3 *dwc)
{
dwc3_event_buffers_cleanup(dwc);
dwc3_free_event_buffers(dwc);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
}
#define DWC3_ALIGN_MASK (16 - 1)
@ -515,10 +460,17 @@ static int __devinit dwc3_probe(struct platform_device *pdev)
pm_runtime_get_sync(dev);
pm_runtime_forbid(dev);
ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
if (ret) {
dev_err(dwc->dev, "failed to allocate event buffers\n");
ret = -ENOMEM;
goto err0;
}
ret = dwc3_core_init(dwc);
if (ret) {
dev_err(dev, "failed to initialize core\n");
return ret;
goto err0;
}
mode = DWC3_MODE(dwc->hwparams.hwparams0);
@ -590,6 +542,9 @@ err2:
err1:
dwc3_core_exit(dwc);
err0:
dwc3_free_event_buffers(dwc);
return ret;
}

View File

@ -868,7 +868,4 @@ void dwc3_host_exit(struct dwc3 *dwc);
int dwc3_gadget_init(struct dwc3 *dwc);
void dwc3_gadget_exit(struct dwc3 *dwc);
extern int dwc3_get_device_id(void);
extern void dwc3_put_device_id(int id);
#endif /* __DRIVERS_USB_DWC3_CORE_H */

View File

@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/usb/otg.h>
#include <linux/usb/nop-usb-xceiv.h>
#include <linux/of.h>
#include "core.h"
@ -87,14 +88,14 @@ err1:
return ret;
}
static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32);
static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
{
struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
struct platform_device *dwc3;
struct dwc3_exynos *exynos;
struct clk *clk;
int devid;
int ret = -ENOMEM;
exynos = kzalloc(sizeof(*exynos), GFP_KERNEL);
@ -103,11 +104,15 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
goto err0;
}
platform_set_drvdata(pdev, exynos);
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we move to full device tree support this will vanish off.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &dwc3_exynos_dma_mask;
devid = dwc3_get_device_id();
if (devid < 0)
goto err1;
platform_set_drvdata(pdev, exynos);
ret = dwc3_exynos_register_phys(exynos);
if (ret) {
@ -115,10 +120,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
goto err1;
}
dwc3 = platform_device_alloc("dwc3", devid);
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
goto err2;
goto err1;
}
clk = clk_get(&pdev->dev, "usbdrd30");
@ -139,14 +144,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
clk_enable(exynos->clk);
/* PHY initialization */
if (!pdata) {
dev_dbg(&pdev->dev, "missing platform data\n");
} else {
if (pdata->phy_init)
pdata->phy_init(pdev, pdata->phy_type);
}
ret = platform_device_add_resources(dwc3, pdev->resource,
pdev->num_resources);
if (ret) {
@ -163,15 +160,10 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev)
return 0;
err4:
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, pdata->phy_type);
clk_disable(clk);
clk_put(clk);
err3:
platform_device_put(dwc3);
err2:
dwc3_put_device_id(devid);
err1:
kfree(exynos);
err0:
@ -181,17 +173,11 @@ err0:
static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
{
struct dwc3_exynos *exynos = platform_get_drvdata(pdev);
struct dwc3_exynos_data *pdata = pdev->dev.platform_data;
platform_device_unregister(exynos->dwc3);
platform_device_unregister(exynos->usb2_phy);
platform_device_unregister(exynos->usb3_phy);
dwc3_put_device_id(exynos->dwc3->id);
if (pdata && pdata->phy_exit)
pdata->phy_exit(pdev, pdata->phy_type);
clk_disable(exynos->clk);
clk_put(exynos->clk);
@ -200,11 +186,20 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id exynos_dwc3_match[] = {
{ .compatible = "samsung,exynos-dwc3" },
{},
};
MODULE_DEVICE_TABLE(of, exynos_dwc3_match);
#endif
static struct platform_driver dwc3_exynos_driver = {
.probe = dwc3_exynos_probe,
.remove = __devexit_p(dwc3_exynos_remove),
.driver = {
.name = "exynos-dwc3",
.of_match_table = of_match_ptr(exynos_dwc3_match),
},
};

View File

@ -272,7 +272,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
struct resource *res;
struct device *dev = &pdev->dev;
int devid;
int size;
int ret = -ENOMEM;
int irq;
@ -315,14 +314,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
return ret;
}
devid = dwc3_get_device_id();
if (devid < 0)
return -ENODEV;
dwc3 = platform_device_alloc("dwc3", devid);
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(dev, "couldn't allocate dwc3 device\n");
goto err1;
return -ENOMEM;
}
context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL);
@ -423,10 +418,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev)
err2:
platform_device_put(dwc3);
err1:
dwc3_put_device_id(devid);
return ret;
}
@ -437,9 +428,6 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev)
platform_device_unregister(omap->dwc3);
platform_device_unregister(omap->usb2_phy);
platform_device_unregister(omap->usb3_phy);
dwc3_put_device_id(omap->dwc3->id);
return 0;
}

View File

@ -119,7 +119,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
struct platform_device *dwc3;
struct dwc3_pci *glue;
int ret = -ENOMEM;
int devid;
struct device *dev = &pci->dev;
glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL);
@ -145,13 +144,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
return ret;
}
devid = dwc3_get_device_id();
if (devid < 0) {
ret = -ENOMEM;
goto err1;
}
dwc3 = platform_device_alloc("dwc3", devid);
dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO);
if (!dwc3) {
dev_err(dev, "couldn't allocate dwc3 device\n");
ret = -ENOMEM;
@ -172,7 +165,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
if (ret) {
dev_err(dev, "couldn't add resources to dwc3 device\n");
goto err2;
goto err1;
}
pci_set_drvdata(pci, glue);
@ -195,10 +188,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci,
err3:
pci_set_drvdata(pci, NULL);
platform_device_put(dwc3);
err2:
dwc3_put_device_id(devid);
err1:
pci_disable_device(pci);
@ -211,7 +200,6 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci)
platform_device_unregister(glue->usb2_phy);
platform_device_unregister(glue->usb3_phy);
dwc3_put_device_id(glue->dwc3->id);
platform_device_unregister(glue->dwc3);
pci_set_drvdata(pci, NULL);
pci_disable_device(pci);