F: drivers/pci/*/*acpi*
F: drivers/pci/*/*/*acpi*
+ACPI COMPONENT ARCHITECTURE (ACPICA)
+M: Robert Moore <robert.moore@intel.com>
+M: Lv Zheng <lv.zheng@intel.com>
+M: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+L: linux-acpi@vger.kernel.org
+L: devel@acpica.org
+W: https://acpica.org/
+W: https://github.com/acpica/acpica/
+Q: https://patchwork.kernel.org/project/linux-acpi/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
+S: Supported
+F: drivers/acpi/acpica/
+F: include/acpi/
+
ACPI FAN DRIVER
M: Zhang Rui <rui.zhang@intel.com>
L: linux-acpi@vger.kernel.org
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/misc/eeprom/at24.c
-F: include/linux/i2c/at24.h
+F: include/linux/platform_data/at24.h
ATA OVER ETHERNET (AOE) DRIVER
M: "Ed L. Cashin" <ecashin@coraid.com>
F: include/linux/backlight.h
BATMAN ADVANCED
-M: Marek Lindner <lindner_marek@yahoo.de>
-M: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
-M: Antonio Quartulli <ordex@autistici.org>
+M: Marek Lindner <mareklindner@neomailbox.ch>
+M: Simon Wunderlich <sw@simonwunderlich.de>
+M: Antonio Quartulli <antonio@meshcoding.com>
L: b.a.t.m.a.n@lists.open-mesh.org
W: http://www.open-mesh.org/
S: Maintained
BONDING DRIVER
M: Jay Vosburgh <fubar@us.ibm.com>
+M: Veaceslav Falico <vfalico@redhat.com>
M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
W: http://sourceforge.net/projects/bonding/
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM
M: Vinod Koul <vinod.koul@intel.com>
M: Dan Williams <dan.j.williams@intel.com>
+L: dmaengine@vger.kernel.org
+Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
S: Supported
F: drivers/dma/
F: include/linux/dma*
L: linux-tegra@vger.kernel.org
T: git git://anongit.freedesktop.org/tegra/linux.git
S: Maintained
+F: drivers/gpu/drm/tegra/
F: drivers/gpu/host1x/
+F: include/linux/host1x.h
F: include/uapi/drm/tegra_drm.h
F: Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
F: include/asm-generic/
F: include/uapi/asm-generic/
+ GENERIC PHY FRAMEWORK
+ M: Kishon Vijay Abraham I <kishon@ti.com>
+ L: linux-kernel@vger.kernel.org
+ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy.git
+ S: Supported
+ F: drivers/phy/
+ F: include/linux/phy/
+
GENERIC UIO DRIVER FOR PCI DEVICES
M: "Michael S. Tsirkin" <mst@redhat.com>
L: kvm@vger.kernel.org
INTEL I/OAT DMA DRIVER
M: Dan Williams <dan.j.williams@intel.com>
-S: Maintained
+M: Dave Jiang <dave.jiang@intel.com>
+L: dmaengine@vger.kernel.org
+Q: https://patchwork.kernel.org/project/linux-dmaengine/list/
+S: Supported
F: drivers/dma/ioat*
INTEL IOMMU (VT-d)
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
F: drivers/pci/host/pci-tegra.c
+PCI DRIVER FOR SAMSUNG EXYNOS
+M: Jingoo Han <jg1.han@samsung.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: drivers/pci/host/pci-exynos.c
+
PCMCIA SUBSYSTEM
P: Linux PCMCIA Team
L: linux-pcmcia@lists.infradead.org
S: Supported
F: arch/hexagon/
+QUALCOMM WCN36XX WIRELESS DRIVER
+M: Eugene Krasnikov <k.eugene.e@gmail.com>
+L: wcn36xx@lists.infradead.org
+W: http://wireless.kernel.org/en/users/Drivers/wcn36xx
+T: git git://github.com/KrasnikovEugene/wcn36xx.git
+S: Supported
+F: drivers/net/wireless/ath/wcn36xx/
+
QUICKCAM PARALLEL PORT WEBCAMS
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
F: Documentation/RCU/torture.txt
-F: kernel/rcutorture.c
+F: kernel/rcu/torture.c
RDC R-321X SoC
M: Florian Fainelli <florian@openwrt.org>
F: Documentation/RCU/
X: Documentation/RCU/torture.txt
F: include/linux/rcu*
-F: kernel/rcu*
-X: kernel/rcutorture.c
+X: include/linux/srcu.h
+F: kernel/rcu/
+X: kernel/rcu/torture.c
REAL TIME CLOCK (RTC) SUBSYSTEM
M: Alessandro Zummo <a.zummo@towertech.it>
F: kernel/sched/
F: include/linux/sched.h
F: include/uapi/linux/sched.h
+F: kernel/wait.c
+F: include/linux/wait.h
SCORE ARCHITECTURE
M: Chen Liqin <liqin.linux@gmail.com>
M: Stephen Smalley <sds@tycho.nsa.gov>
M: James Morris <james.l.morris@oracle.com>
M: Eric Paris <eparis@parisplace.org>
+M: Paul Moore <paul@paul-moore.com>
L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
W: http://selinuxproject.org
-T: git git://git.infradead.org/users/eparis/selinux.git
+T: git git://git.infradead.org/users/pcmoore/selinux
S: Supported
F: include/linux/selinux*
F: security/selinux/
W: http://www.rdrop.com/users/paulmck/RCU/
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git
-F: include/linux/srcu*
-F: kernel/srcu*
+F: include/linux/srcu.h
+F: kernel/rcu/srcu.c
SMACK SECURITY MODULE
M: Casey Schaufler <casey@schaufler-ca.com>
F: sound/soc/
F: include/sound/soc*
+SOUND - DMAENGINE HELPERS
+M: Lars-Peter Clausen <lars@metafoo.de>
+S: Supported
+F: include/sound/dmaengine_pcm.h
+F: sound/core/pcm_dmaengine.c
+F: sound/soc/soc-generic-dmaengine-pcm.c
+
SPARC + UltraSPARC (sparc/sparc64)
M: "David S. Miller" <davem@davemloft.net>
L: sparclinux@vger.kernel.org
TPM DEVICE DRIVER
M: Leonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>
M: Ashley Lai <ashley@ashleylai.com>
+M: Peter Huewe <peterhuewe@gmx.de>
M: Rajiv Andrade <mail@srajiv.net>
W: http://tpmdd.sourceforge.net
M: Marcel Selhorst <tpmdd@selhorst.net>
F: arch/m68k/*/*_no.*
F: arch/m68k/include/asm/*_no.*
-UCLINUX FOR RENESAS H8/300 (H8300)
-M: Yoshinori Sato <ysato@users.sourceforge.jp>
-W: http://uclinux-h8.sourceforge.jp/
-S: Supported
-F: arch/h8300/
-F: drivers/ide/ide-h8300.c
-F: drivers/net/ethernet/8390/ne-h8300.c
-
UDF FILESYSTEM
M: Jan Kara <jack@suse.cz>
S: Maintained
source "drivers/fmc/Kconfig"
+source "drivers/powercap/Kconfig"
+
+ source "drivers/phy/Kconfig"
+
endmenu
obj-y += irqchip/
obj-y += bus/
+ obj-$(CONFIG_GENERIC_PHY) += phy/
+
# GPIO must come after pinctrl as gpios may need to mux pins etc
obj-y += pinctrl/
obj-y += gpio/
obj-$(CONFIG_IPACK_BUS) += ipack/
obj-$(CONFIG_NTB) += ntb/
obj-$(CONFIG_FMC) += fmc/
+obj-$(CONFIG_POWERCAP) += powercap/
}
data->phy = devm_usb_get_phy_by_phandle(&pdev->dev, "fsl,usbphy", 0);
- if (!IS_ERR(data->phy)) {
- ret = usb_phy_init(data->phy);
- if (ret) {
- dev_err(&pdev->dev, "unable to init phy: %d\n", ret);
- goto err_clk;
- }
- } else if (PTR_ERR(data->phy) == -EPROBE_DEFER) {
- ret = -EPROBE_DEFER;
+ if (IS_ERR(data->phy)) {
+ ret = PTR_ERR(data->phy);
goto err_clk;
}
pdata.phy = data->phy;
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ goto err_clk;
if (data->usbmisc_data) {
ret = imx_usbmisc_init(data->usbmisc_data);
if (ret) {
dev_err(&pdev->dev, "usbmisc init failed, ret=%d\n",
ret);
- goto err_phy;
+ goto err_clk;
}
}
dev_err(&pdev->dev,
"Can't register ci_hdrc platform device, err=%d\n",
ret);
- goto err_phy;
+ goto err_clk;
}
if (data->usbmisc_data) {
disable_device:
ci_hdrc_remove_device(data->ci_pdev);
- err_phy:
- if (data->phy)
- usb_phy_shutdown(data->phy);
err_clk:
clk_disable_unprepare(data->clk);
return ret;
pm_runtime_disable(&pdev->dev);
ci_hdrc_remove_device(data->ci_pdev);
-
- if (data->phy)
- usb_phy_shutdown(data->phy);
-
clk_disable_unprepare(data->clk);
return 0;
/*
- * SAMSUNG S5P USB HOST EHCI Controller
+ * SAMSUNG EXYNOS USB HOST EHCI Controller
*
* Copyright (C) 2011 Samsung Electronics Co.Ltd
* Author: Jingoo Han <jg1.han@samsung.com>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
- #include <linux/platform_data/usb-ehci-s5p.h>
#include <linux/usb/phy.h>
#include <linux/usb/samsung_usb_phy.h>
#include <linux/usb.h>
#include "ehci.h"
- #define DRIVER_DESC "EHCI s5p driver"
+ #define DRIVER_DESC "EHCI EXYNOS driver"
#define EHCI_INSNREG00(base) (base + 0x90)
#define EHCI_INSNREG00_ENA_INCR16 (0x1 << 25)
(EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 | \
EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
- static const char hcd_name[] = "ehci-s5p";
- static struct hc_driver __read_mostly s5p_ehci_hc_driver;
+ static const char hcd_name[] = "ehci-exynos";
+ static struct hc_driver __read_mostly exynos_ehci_hc_driver;
- struct s5p_ehci_hcd {
+ struct exynos_ehci_hcd {
struct clk *clk;
struct usb_phy *phy;
struct usb_otg *otg;
- struct s5p_ehci_platdata *pdata;
};
- static struct s5p_ehci_platdata empty_platdata;
+ #define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
- #define to_s5p_ehci(hcd) (struct s5p_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
-
- static void s5p_setup_vbus_gpio(struct platform_device *pdev)
+ static void exynos_setup_vbus_gpio(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int err;
dev_err(dev, "can't request ehci vbus gpio %d", gpio);
}
- static int s5p_ehci_probe(struct platform_device *pdev)
+ static int exynos_ehci_probe(struct platform_device *pdev)
{
- struct s5p_ehci_platdata *pdata = dev_get_platdata(&pdev->dev);
- struct s5p_ehci_hcd *s5p_ehci;
+ struct exynos_ehci_hcd *exynos_ehci;
struct usb_hcd *hcd;
struct ehci_hcd *ehci;
struct resource *res;
* 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 = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
- s5p_setup_vbus_gpio(pdev);
+ exynos_setup_vbus_gpio(pdev);
- hcd = usb_create_hcd(&s5p_ehci_hc_driver,
+ hcd = usb_create_hcd(&exynos_ehci_hc_driver,
&pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
dev_err(&pdev->dev, "Unable to create HCD\n");
return -ENOMEM;
}
- s5p_ehci = to_s5p_ehci(hcd);
+ exynos_ehci = to_exynos_ehci(hcd);
if (of_device_is_compatible(pdev->dev.of_node,
- "samsung,exynos5440-ehci")) {
- s5p_ehci->pdata = &empty_platdata;
+ "samsung,exynos5440-ehci"))
goto skip_phy;
- }
phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
if (IS_ERR(phy)) {
- /* Fallback to pdata */
- if (!pdata) {
- usb_put_hcd(hcd);
- dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
- return -EPROBE_DEFER;
- } else {
- s5p_ehci->pdata = pdata;
- }
+ usb_put_hcd(hcd);
+ dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
+ return -EPROBE_DEFER;
} else {
- s5p_ehci->phy = phy;
- s5p_ehci->otg = phy->otg;
+ exynos_ehci->phy = phy;
+ exynos_ehci->otg = phy->otg;
}
skip_phy:
- s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
+ exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
- if (IS_ERR(s5p_ehci->clk)) {
+ if (IS_ERR(exynos_ehci->clk)) {
dev_err(&pdev->dev, "Failed to get usbhost clock\n");
- err = PTR_ERR(s5p_ehci->clk);
+ err = PTR_ERR(exynos_ehci->clk);
goto fail_clk;
}
- err = clk_prepare_enable(s5p_ehci->clk);
+ err = clk_prepare_enable(exynos_ehci->clk);
if (err)
goto fail_clk;
goto fail_io;
}
- if (s5p_ehci->otg)
- s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+ if (exynos_ehci->otg)
+ exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
- if (s5p_ehci->phy)
- usb_phy_init(s5p_ehci->phy);
- else if (s5p_ehci->pdata->phy_init)
- s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+ if (exynos_ehci->phy)
+ usb_phy_init(exynos_ehci->phy);
ehci = hcd_to_ehci(hcd);
ehci->caps = hcd->regs;
return 0;
fail_add_hcd:
- if (s5p_ehci->phy)
- usb_phy_shutdown(s5p_ehci->phy);
- else if (s5p_ehci->pdata->phy_exit)
- s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+ if (exynos_ehci->phy)
+ usb_phy_shutdown(exynos_ehci->phy);
fail_io:
- clk_disable_unprepare(s5p_ehci->clk);
+ clk_disable_unprepare(exynos_ehci->clk);
fail_clk:
usb_put_hcd(hcd);
return err;
}
- static int s5p_ehci_remove(struct platform_device *pdev)
+ static int exynos_ehci_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
+ struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
usb_remove_hcd(hcd);
- if (s5p_ehci->otg)
- s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+ if (exynos_ehci->otg)
+ exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
- if (s5p_ehci->phy)
- usb_phy_shutdown(s5p_ehci->phy);
- else if (s5p_ehci->pdata->phy_exit)
- s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+ if (exynos_ehci->phy)
+ usb_phy_shutdown(exynos_ehci->phy);
- clk_disable_unprepare(s5p_ehci->clk);
+ clk_disable_unprepare(exynos_ehci->clk);
usb_put_hcd(hcd);
}
#ifdef CONFIG_PM
- static int s5p_ehci_suspend(struct device *dev)
+ static int exynos_ehci_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
- struct platform_device *pdev = to_platform_device(dev);
+ struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
bool do_wakeup = device_may_wakeup(dev);
int rc;
rc = ehci_suspend(hcd, do_wakeup);
- if (s5p_ehci->otg)
- s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+ if (exynos_ehci->otg)
+ exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
- if (s5p_ehci->phy)
- usb_phy_shutdown(s5p_ehci->phy);
- else if (s5p_ehci->pdata->phy_exit)
- s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
+ if (exynos_ehci->phy)
+ usb_phy_shutdown(exynos_ehci->phy);
- clk_disable_unprepare(s5p_ehci->clk);
+ clk_disable_unprepare(exynos_ehci->clk);
return rc;
}
- static int s5p_ehci_resume(struct device *dev)
+ static int exynos_ehci_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd);
- struct platform_device *pdev = to_platform_device(dev);
+ struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
- clk_prepare_enable(s5p_ehci->clk);
+ clk_prepare_enable(exynos_ehci->clk);
- if (s5p_ehci->otg)
- s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self);
+ if (exynos_ehci->otg)
+ exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
- if (s5p_ehci->phy)
- usb_phy_init(s5p_ehci->phy);
- else if (s5p_ehci->pdata->phy_init)
- s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
+ if (exynos_ehci->phy)
+ usb_phy_init(exynos_ehci->phy);
/* DMA burst Enable */
writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
return 0;
}
#else
- #define s5p_ehci_suspend NULL
- #define s5p_ehci_resume NULL
+ #define exynos_ehci_suspend NULL
+ #define exynos_ehci_resume NULL
#endif
- static const struct dev_pm_ops s5p_ehci_pm_ops = {
- .suspend = s5p_ehci_suspend,
- .resume = s5p_ehci_resume,
+ static const struct dev_pm_ops exynos_ehci_pm_ops = {
+ .suspend = exynos_ehci_suspend,
+ .resume = exynos_ehci_resume,
};
#ifdef CONFIG_OF
MODULE_DEVICE_TABLE(of, exynos_ehci_match);
#endif
- static struct platform_driver s5p_ehci_driver = {
- .probe = s5p_ehci_probe,
- .remove = s5p_ehci_remove,
+ static struct platform_driver exynos_ehci_driver = {
+ .probe = exynos_ehci_probe,
+ .remove = exynos_ehci_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
- .name = "s5p-ehci",
+ .name = "exynos-ehci",
.owner = THIS_MODULE,
- .pm = &s5p_ehci_pm_ops,
+ .pm = &exynos_ehci_pm_ops,
.of_match_table = of_match_ptr(exynos_ehci_match),
}
};
- static const struct ehci_driver_overrides s5p_overrides __initdata = {
- .extra_priv_size = sizeof(struct s5p_ehci_hcd),
+ static const struct ehci_driver_overrides exynos_overrides __initdata = {
+ .extra_priv_size = sizeof(struct exynos_ehci_hcd),
};
- static int __init ehci_s5p_init(void)
+ static int __init ehci_exynos_init(void)
{
if (usb_disabled())
return -ENODEV;
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
- ehci_init_driver(&s5p_ehci_hc_driver, &s5p_overrides);
- return platform_driver_register(&s5p_ehci_driver);
+ ehci_init_driver(&exynos_ehci_hc_driver, &exynos_overrides);
+ return platform_driver_register(&exynos_ehci_driver);
}
- module_init(ehci_s5p_init);
+ module_init(ehci_exynos_init);
- static void __exit ehci_s5p_cleanup(void)
+ static void __exit ehci_exynos_cleanup(void)
{
- platform_driver_unregister(&s5p_ehci_driver);
+ platform_driver_unregister(&exynos_ehci_driver);
}
- module_exit(ehci_s5p_cleanup);
+ module_exit(ehci_exynos_cleanup);
MODULE_DESCRIPTION(DRIVER_DESC);
- MODULE_ALIAS("platform:s5p-ehci");
+ MODULE_ALIAS("platform:exynos-ehci");
MODULE_AUTHOR("Jingoo Han");
MODULE_AUTHOR("Joonyoung Shim");
MODULE_LICENSE("GPL v2");
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+ .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
* We can DMA from anywhere. But the descriptors must be in
* the lower 4GB.
*/
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
pdev->dev.dma_mask = &ehci_octeon_dma_mask;
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");
if (!hcd)
#include <linux/signal.h>
#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <linux/of_platform.h>
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
+ .flags = HCD_MEMORY | HCD_USB2 | HCD_BH,
/*
* basic lifecycle operations
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,
dev_name(&pdev->dev));
err = clk_prepare_enable(tegra->clk);
if (err)
- goto cleanup_clk_get;
+ goto cleanup_hcd_create;
tegra_periph_reset_assert(tegra->clk);
udelay(1);
usb_phy_shutdown(hcd->phy);
cleanup_clk_en:
clk_disable_unprepare(tegra->clk);
- cleanup_clk_get:
- clk_put(tegra->clk);
cleanup_hcd_create:
usb_put_hcd(hcd);
return err;
*/
#include <linux/clk.h>
- #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
+ #include <linux/platform_device.h>
#include <linux/platform_data/atmel.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
#include <mach/hardware.h>
#include <asm/gpio.h>
#include <mach/cpu.h>
- #ifndef CONFIG_ARCH_AT91
- #error "CONFIG_ARCH_AT91 must be defined."
- #endif
+
+ #include "ohci.h"
#define valid_port(index) ((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)
#define at91_for_each_port(index) \
/* interface, function and usb clocks; sometimes also an AHB clock */
static struct clk *iclk, *fclk, *uclk, *hclk;
+ /* interface and function clocks; sometimes also an AHB clock */
+
+ #define DRIVER_DESC "OHCI Atmel driver"
+
+ static const char hcd_name[] = "ohci-atmel";
+
+ static struct hc_driver __read_mostly ohci_at91_hc_driver;
static int clocked;
+ static int (*orig_ohci_hub_control)(struct usb_hcd *hcd, u16 typeReq,
+ u16 wValue, u16 wIndex, char *buf, u16 wLength);
+ static int (*orig_ohci_hub_status_data)(struct usb_hcd *hcd, char *buf);
extern int usb_disabled(void);
static int usb_hcd_at91_probe(const struct hc_driver *driver,
struct platform_device *pdev)
{
+ struct at91_usbh_data *board;
+ struct ohci_hcd *ohci;
int retval;
struct usb_hcd *hcd = NULL;
}
}
+ board = hcd->self.controller->platform_data;
+ ohci = hcd_to_ohci(hcd);
+ ohci->num_ports = board->ports;
at91_start_hc(pdev);
- ohci_hcd_init(hcd_to_ohci(hcd));
retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
if (retval == 0)
}
/*-------------------------------------------------------------------------*/
-
- static int
- ohci_at91_reset (struct usb_hcd *hcd)
- {
- struct at91_usbh_data *board = dev_get_platdata(hcd->self.controller);
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- ohci->num_ports = board->ports;
- return 0;
- }
-
- static int
- ohci_at91_start (struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
- return 0;
- }
-
static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)
{
if (!valid_port(port))
*/
static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)
{
- struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller);
- int length = ohci_hub_status_data(hcd, buf);
+ struct at91_usbh_data *pdata = hcd->self.controller->platform_data;
+ int length = orig_ohci_hub_status_data(hcd, buf);
int port;
at91_for_each_port(port) {
break;
}
- ret = ohci_hub_control(hcd, typeReq, wValue, wIndex + 1, buf, wLength);
+ ret = orig_ohci_hub_control(hcd, typeReq, wValue, wIndex + 1,
+ buf, wLength);
if (ret)
goto out;
/*-------------------------------------------------------------------------*/
- static const struct hc_driver ohci_at91_hc_driver = {
- .description = hcd_name,
- .product_desc = "AT91 OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .reset = ohci_at91_reset,
- .start = ohci_at91_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_at91_hub_status_data,
- .hub_control = ohci_at91_hub_control,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
- .start_port_reset = ohci_start_port_reset,
- };
-
- /*-------------------------------------------------------------------------*/
-
static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
{
struct platform_device *pdev = data;
static int ohci_at91_of_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
- int i, gpio;
+ int i, gpio, ret;
enum of_gpio_flags flags;
struct at91_usbh_data *pdata;
u32 ports;
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
* REVISIT: some boards will be able to turn VBUS off...
*/
if (at91_suspend_entering_slow_clock()) {
- ohci_usb_reset (ohci);
+ ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
+ ohci->hc_control &= OHCI_CTRL_RWC;
+ ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
+ ohci->rh_state = OHCI_RH_HALTED;
+
/* flush the writes */
(void) ohci_readl (ohci, &ohci->regs->control);
at91_stop_clock();
#define ohci_hcd_at91_drv_resume NULL
#endif
- MODULE_ALIAS("platform:at91_ohci");
-
static struct platform_driver ohci_hcd_at91_driver = {
.probe = ohci_hcd_at91_drv_probe,
.remove = ohci_hcd_at91_drv_remove,
.of_match_table = of_match_ptr(at91_ohci_dt_ids),
},
};
+
+ static int __init ohci_at91_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+ ohci_init_driver(&ohci_at91_hc_driver, NULL);
+
+ /*
+ * The Atmel HW has some unusual quirks, which require Atmel-specific
+ * workarounds. We override certain hc_driver functions here to
+ * achieve that. We explicitly do not enhance ohci_driver_overrides to
+ * allow this more easily, since this is an unusual case, and we don't
+ * want to encourage others to override these functions by making it
+ * too easy.
+ */
+
+ orig_ohci_hub_control = ohci_at91_hc_driver.hub_control;
+ orig_ohci_hub_status_data = ohci_at91_hc_driver.hub_status_data;
+
+ ohci_at91_hc_driver.hub_status_data = ohci_at91_hub_status_data;
+ ohci_at91_hc_driver.hub_control = ohci_at91_hub_control;
+
+ return platform_driver_register(&ohci_hcd_at91_driver);
+ }
+ module_init(ohci_at91_init);
+
+ static void __exit ohci_at91_cleanup(void)
+ {
+ platform_driver_unregister(&ohci_hcd_at91_driver);
+ }
+ module_exit(ohci_at91_cleanup);
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL");
+ MODULE_ALIAS("platform:at91_ohci");
*/
#include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
- #include <linux/platform_data/usb-ohci-exynos.h>
#include <linux/usb/phy.h>
#include <linux/usb/samsung_usb_phy.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
+ #include <linux/usb/otg.h>
+
+ #include "ohci.h"
+
+ #define DRIVER_DESC "OHCI EXYNOS driver"
+
+ static const char hcd_name[] = "ohci-exynos";
+ static struct hc_driver __read_mostly exynos_ohci_hc_driver;
+
+ #define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv)
struct exynos_ohci_hcd {
- struct device *dev;
- struct usb_hcd *hcd;
struct clk *clk;
struct usb_phy *phy;
struct usb_otg *otg;
- struct exynos4_ohci_platdata *pdata;
};
- static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
+ static void exynos_ohci_phy_enable(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
if (exynos_ohci->phy)
usb_phy_init(exynos_ohci->phy);
- else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_init)
- exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
}
- static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
+ static void exynos_ohci_phy_disable(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
if (exynos_ohci->phy)
usb_phy_shutdown(exynos_ohci->phy);
- else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_exit)
- exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
- }
-
- static int ohci_exynos_reset(struct usb_hcd *hcd)
- {
- return ohci_init(hcd_to_ohci(hcd));
}
- static int ohci_exynos_start(struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci);
-
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start %s\n",
- hcd->self.bus_name);
- ohci_stop(hcd);
- return ret;
- }
-
- return 0;
- }
-
- static const struct hc_driver exynos_ohci_hc_driver = {
- .description = hcd_name,
- .product_desc = "EXYNOS OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- .irq = ohci_irq,
- .flags = HCD_MEMORY|HCD_USB11,
-
- .reset = ohci_exynos_reset,
- .start = ohci_exynos_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- .get_frame_number = ohci_get_frame,
-
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
- .start_port_reset = ohci_start_port_reset,
- };
-
static int exynos_ohci_probe(struct platform_device *pdev)
{
- struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev);
struct exynos_ohci_hcd *exynos_ohci;
struct usb_hcd *hcd;
- struct ohci_hcd *ohci;
struct resource *res;
struct usb_phy *phy;
int irq;
* 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 = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (err)
+ return err;
- exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd),
- GFP_KERNEL);
- if (!exynos_ohci)
+ hcd = usb_create_hcd(&exynos_ohci_hc_driver,
+ &pdev->dev, dev_name(&pdev->dev));
+ if (!hcd) {
+ dev_err(&pdev->dev, "Unable to create HCD\n");
return -ENOMEM;
+ }
+
+ exynos_ohci = to_exynos_ohci(hcd);
if (of_device_is_compatible(pdev->dev.of_node,
"samsung,exynos5440-ohci"))
phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
if (IS_ERR(phy)) {
- /* Fallback to pdata */
- if (!pdata) {
- dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
- return -EPROBE_DEFER;
- } else {
- exynos_ohci->pdata = pdata;
- }
+ usb_put_hcd(hcd);
+ dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
+ return -EPROBE_DEFER;
} else {
exynos_ohci->phy = phy;
exynos_ohci->otg = phy->otg;
}
skip_phy:
-
- exynos_ohci->dev = &pdev->dev;
-
- hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
- if (!hcd) {
- dev_err(&pdev->dev, "Unable to create HCD\n");
- return -ENOMEM;
- }
-
- exynos_ohci->hcd = hcd;
exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");
if (IS_ERR(exynos_ohci->clk)) {
}
if (exynos_ohci->otg)
- exynos_ohci->otg->set_host(exynos_ohci->otg,
- &exynos_ohci->hcd->self);
+ exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
- exynos_ohci_phy_enable(exynos_ohci);
+ platform_set_drvdata(pdev, hcd);
- ohci = hcd_to_ohci(hcd);
- ohci_hcd_init(ohci);
+ exynos_ohci_phy_enable(pdev);
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err) {
dev_err(&pdev->dev, "Failed to add USB HCD\n");
goto fail_add_hcd;
}
-
- platform_set_drvdata(pdev, exynos_ohci);
-
return 0;
fail_add_hcd:
- exynos_ohci_phy_disable(exynos_ohci);
+ exynos_ohci_phy_disable(pdev);
fail_io:
clk_disable_unprepare(exynos_ohci->clk);
fail_clk:
static int exynos_ohci_remove(struct platform_device *pdev)
{
- struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
- struct usb_hcd *hcd = exynos_ohci->hcd;
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
usb_remove_hcd(hcd);
if (exynos_ohci->otg)
- exynos_ohci->otg->set_host(exynos_ohci->otg,
- &exynos_ohci->hcd->self);
+ exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
- exynos_ohci_phy_disable(exynos_ohci);
+ exynos_ohci_phy_disable(pdev);
clk_disable_unprepare(exynos_ohci->clk);
static void exynos_ohci_shutdown(struct platform_device *pdev)
{
- struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
- struct usb_hcd *hcd = exynos_ohci->hcd;
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
if (hcd->driver->shutdown)
hcd->driver->shutdown(hcd);
#ifdef CONFIG_PM
static int exynos_ohci_suspend(struct device *dev)
{
- struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
- struct usb_hcd *hcd = exynos_ohci->hcd;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct platform_device *pdev = to_platform_device(dev);
unsigned long flags;
int rc = 0;
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
if (exynos_ohci->otg)
- exynos_ohci->otg->set_host(exynos_ohci->otg,
- &exynos_ohci->hcd->self);
+ exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
- exynos_ohci_phy_disable(exynos_ohci);
+ exynos_ohci_phy_disable(pdev);
clk_disable_unprepare(exynos_ohci->clk);
static int exynos_ohci_resume(struct device *dev)
{
- struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
- struct usb_hcd *hcd = exynos_ohci->hcd;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);
+ struct platform_device *pdev = to_platform_device(dev);
clk_prepare_enable(exynos_ohci->clk);
if (exynos_ohci->otg)
- exynos_ohci->otg->set_host(exynos_ohci->otg,
- &exynos_ohci->hcd->self);
+ exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self);
- exynos_ohci_phy_enable(exynos_ohci);
+ exynos_ohci_phy_enable(pdev);
ohci_resume(hcd, false);
#define exynos_ohci_resume NULL
#endif
+ static const struct ohci_driver_overrides exynos_overrides __initconst = {
+ .extra_priv_size = sizeof(struct exynos_ohci_hcd),
+ };
+
static const struct dev_pm_ops exynos_ohci_pm_ops = {
.suspend = exynos_ohci_suspend,
.resume = exynos_ohci_resume,
.of_match_table = of_match_ptr(exynos_ohci_match),
}
};
+ static int __init ohci_exynos_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+ ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides);
+ return platform_driver_register(&exynos_ohci_driver);
+ }
+ module_init(ohci_exynos_init);
+
+ static void __exit ohci_exynos_cleanup(void)
+ {
+ platform_driver_unregister(&exynos_ohci_driver);
+ }
+ module_exit(ohci_exynos_cleanup);
MODULE_ALIAS("platform:exynos-ohci");
MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>");
+ MODULE_LICENSE("GPL v2");
* or implied.
*/
#include <linux/clk.h>
- #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/io.h>
#include <linux/i2c.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
#include <linux/of.h>
+ #include <linux/platform_device.h>
#include <linux/usb/isp1301.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
+
+ #include "ohci.h"
+
#include <mach/hardware.h>
#include <asm/mach-types.h>
#define start_int_umask(irq)
#endif
+ #define DRIVER_DESC "OHCI NXP driver"
+
+ static const char hcd_name[] = "ohci-nxp";
+ static struct hc_driver __read_mostly ohci_nxp_hc_driver;
+
static struct i2c_client *isp1301_i2c_client;
extern int usb_disabled(void);
OTG1_VBUS_DRV);
}
- static void nxp_start_hc(void)
+ static void ohci_nxp_start_hc(void)
{
unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
__raw_writel(tmp, USB_OTG_STAT_CONTROL);
isp1301_vbus_on();
}
- static void nxp_stop_hc(void)
+ static void ohci_nxp_stop_hc(void)
{
unsigned long tmp;
isp1301_vbus_off();
__raw_writel(tmp, USB_OTG_STAT_CONTROL);
}
- static int ohci_nxp_start(struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run(ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start\n");
- ohci_stop(hcd);
- return ret;
- }
- return 0;
- }
-
- static const struct hc_driver ohci_nxp_hc_driver = {
- .description = hcd_name,
- .product_desc = "nxp OHCI",
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- .hcd_priv_size = sizeof(struct ohci_hcd),
- /*
- * basic lifecycle operations
- */
- .start = ohci_nxp_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
- .start_port_reset = ohci_start_port_reset,
- };
-
- static int usb_hcd_nxp_probe(struct platform_device *pdev)
+ static int ohci_hcd_nxp_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd = 0;
- struct ohci_hcd *ohci;
const struct hc_driver *driver = &ohci_nxp_hc_driver;
struct resource *res;
int ret = 0, irq;
return -EPROBE_DEFER;
}
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ goto fail_disable;
dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);
if (usb_disabled()) {
goto fail_resource;
}
- nxp_start_hc();
+ ohci_nxp_start_hc();
platform_set_drvdata(pdev, hcd);
- ohci = hcd_to_ohci(hcd);
- ohci_hcd_init(ohci);
dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
ret = usb_add_hcd(hcd, irq, 0);
if (ret == 0)
return ret;
- nxp_stop_hc();
+ ohci_nxp_stop_hc();
fail_resource:
usb_put_hcd(hcd);
fail_hcd:
return ret;
}
- static int usb_hcd_nxp_remove(struct platform_device *pdev)
+ static int ohci_hcd_nxp_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_remove_hcd(hcd);
- nxp_stop_hc();
+ ohci_nxp_stop_hc();
usb_put_hcd(hcd);
clk_disable(usb_pll_clk);
clk_put(usb_pll_clk);
MODULE_ALIAS("platform:usb-ohci");
#ifdef CONFIG_OF
- static const struct of_device_id usb_hcd_nxp_match[] = {
+ static const struct of_device_id ohci_hcd_nxp_match[] = {
{ .compatible = "nxp,ohci-nxp" },
{},
};
- MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match);
+ MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);
#endif
- static struct platform_driver usb_hcd_nxp_driver = {
+ static struct platform_driver ohci_hcd_nxp_driver = {
.driver = {
.name = "usb-ohci",
.owner = THIS_MODULE,
- .of_match_table = of_match_ptr(usb_hcd_nxp_match),
+ .of_match_table = of_match_ptr(ohci_hcd_nxp_match),
},
- .probe = usb_hcd_nxp_probe,
- .remove = usb_hcd_nxp_remove,
+ .probe = ohci_hcd_nxp_probe,
+ .remove = ohci_hcd_nxp_remove,
};
+ static int __init ohci_nxp_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ohci_init_driver(&ohci_nxp_hc_driver, NULL);
+ return platform_driver_register(&ohci_hcd_nxp_driver);
+ }
+ module_init(ohci_nxp_init);
+
+ static void __exit ohci_nxp_cleanup(void)
+ {
+ platform_driver_unregister(&ohci_hcd_nxp_driver);
+ }
+ module_exit(ohci_nxp_cleanup);
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL v2");
* - add kernel-doc
*/
+ #include <linux/dma-mapping.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/usb/otg.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
- #include <linux/of.h>
- #include <linux/dma-mapping.h>
-
- /*-------------------------------------------------------------------------*/
-
- static int ohci_omap3_init(struct usb_hcd *hcd)
- {
- dev_dbg(hcd->self.controller, "starting OHCI controller\n");
-
- return ohci_init(hcd_to_ohci(hcd));
- }
-
- /*-------------------------------------------------------------------------*/
-
- static int ohci_omap3_start(struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- /*
- * RemoteWakeupConnected has to be set explicitly before
- * calling ohci_run. The reset value of RWC is 0.
- */
- ohci->hc_control = OHCI_CTRL_RWC;
- writel(OHCI_CTRL_RWC, &ohci->regs->control);
-
- ret = ohci_run(ohci);
-
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start\n");
- ohci_stop(hcd);
- }
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
- return ret;
- }
+ #include "ohci.h"
- /*-------------------------------------------------------------------------*/
+ #define DRIVER_DESC "OHCI OMAP3 driver"
- static const struct hc_driver ohci_omap3_hc_driver = {
- .description = hcd_name,
- .product_desc = "OMAP3 OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .reset = ohci_omap3_init,
- .start = ohci_omap3_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
- .start_port_reset = ohci_start_port_reset,
- };
-
- /*-------------------------------------------------------------------------*/
+ static const char hcd_name[] = "ohci-omap3";
+ static struct hc_driver __read_mostly ohci_omap3_hc_driver;
/*
* configure so an HC device and id are always provided
static int ohci_hcd_omap3_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct ohci_hcd *ohci;
struct usb_hcd *hcd = NULL;
void __iomem *regs = NULL;
struct resource *res;
- int ret = -ENODEV;
+ int ret;
int irq;
if (usb_disabled())
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!dev->dma_mask)
- dev->dma_mask = &dev->coherent_dma_mask;
- if (!dev->coherent_dma_mask)
- dev->coherent_dma_mask = DMA_BIT_MASK(32);
+ ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (ret)
+ goto err_io;
+ ret = -ENODEV;
hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,
dev_name(dev));
if (!hcd) {
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- ohci_hcd_init(hcd_to_ohci(hcd));
+ ohci = hcd_to_ohci(hcd);
+ /*
+ * RemoteWakeupConnected has to be set explicitly before
+ * calling ohci_run. The reset value of RWC is 0.
+ */
+ ohci->hc_control = OHCI_CTRL_RWC;
ret = usb_add_hcd(hcd, irq, 0);
if (ret) {
},
};
+ static int __init ohci_omap3_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ohci_init_driver(&ohci_omap3_hc_driver, NULL);
+ return platform_driver_register(&ohci_hcd_omap3_driver);
+ }
+ module_init(ohci_omap3_init);
+
+ static void __exit ohci_omap3_cleanup(void)
+ {
+ platform_driver_unregister(&ohci_hcd_omap3_driver);
+ }
+ module_exit(ohci_omap3_cleanup);
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_ALIAS("platform:ohci-omap3");
MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>");
+ MODULE_LICENSE("GPL");
* This file is licenced under the GPL.
*/
- #include <linux/device.h>
- #include <linux/signal.h>
- #include <linux/platform_device.h>
#include <linux/clk.h>
+ #include <linux/device.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
- #include <mach/hardware.h>
#include <linux/platform_data/usb-ohci-pxa27x.h>
#include <linux/platform_data/usb-pxa3xx-ulpi.h>
+ #include <linux/platform_device.h>
+ #include <linux/signal.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
+ #include <linux/usb/otg.h>
+
+ #include <mach/hardware.h>
+
+ #include "ohci.h"
+
+ #define DRIVER_DESC "OHCI PXA27x/PXA3x driver"
/*
* UHC: USB Host Controller (OHCI-like) register definitions
#define PXA_UHC_MAX_PORTNUM 3
- struct pxa27x_ohci {
- /* must be 1st member here for hcd_to_ohci() to work */
- struct ohci_hcd ohci;
+ static const char hcd_name[] = "ohci-pxa27x";
- struct device *dev;
+ static struct hc_driver __read_mostly ohci_pxa27x_hc_driver;
+
+ struct pxa27x_ohci {
struct clk *clk;
void __iomem *mmio_base;
};
- #define to_pxa27x_ohci(hcd) (struct pxa27x_ohci *)hcd_to_ohci(hcd)
+ #define to_pxa27x_ohci(hcd) (struct pxa27x_ohci *)(hcd_to_ohci(hcd)->priv)
/*
PMM_NPS_MODE -- PMM Non-power switching mode
PMM_PERPORT_MODE -- PMM per port switching mode
Ports are powered individually.
*/
- static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
+ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)
{
- uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
- uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+ uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
+ uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);
switch (mode) {
case PMM_NPS_MODE:
uhcrhda |= RH_A_NPS;
}
- __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
- __raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
+ __raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
+ __raw_writel(uhcrhdb, pxa_ohci->mmio_base + UHCRHDB);
return 0;
}
- extern int usb_disabled(void);
-
/*-------------------------------------------------------------------------*/
- static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+ static inline void pxa27x_setup_hc(struct pxa27x_ohci *pxa_ohci,
struct pxaohci_platform_data *inf)
{
- uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
- uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+ uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
+ uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);
if (inf->flags & ENABLE_PORT1)
uhchr &= ~UHCHR_SSEP1;
uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
}
- __raw_writel(uhchr, ohci->mmio_base + UHCHR);
- __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+ __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+ __raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);
}
- static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+ static inline void pxa27x_reset_hc(struct pxa27x_ohci *pxa_ohci)
{
- uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+ uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR);
- __raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+ __raw_writel(uhchr | UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
udelay(11);
- __raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+ __raw_writel(uhchr & ~UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);
}
#ifdef CONFIG_PXA27x
#define pxa27x_clear_otgph() do {} while (0)
#endif
- static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
+ static int pxa27x_start_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
{
int retval = 0;
struct pxaohci_platform_data *inf;
uint32_t uhchr;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
inf = dev_get_platdata(dev);
- clk_prepare_enable(ohci->clk);
+ clk_prepare_enable(pxa_ohci->clk);
- pxa27x_reset_hc(ohci);
+ pxa27x_reset_hc(pxa_ohci);
- uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
- __raw_writel(uhchr, ohci->mmio_base + UHCHR);
+ uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+ __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
- while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
+ while (__raw_readl(pxa_ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
cpu_relax();
- pxa27x_setup_hc(ohci, inf);
+ pxa27x_setup_hc(pxa_ohci, inf);
if (inf->init)
retval = inf->init(dev);
return retval;
if (cpu_is_pxa3xx())
- pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self);
+ pxa3xx_u2d_start_hc(&hcd->self);
- uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
- __raw_writel(uhchr, ohci->mmio_base + UHCHR);
- __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
+ uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+ __raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR);
+ __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, pxa_ohci->mmio_base + UHCHIE);
/* Clear any OTG Pin Hold */
pxa27x_clear_otgph();
return 0;
}
- static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
+ static void pxa27x_stop_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)
{
struct pxaohci_platform_data *inf;
+ struct usb_hcd *hcd = dev_get_drvdata(dev);
uint32_t uhccoms;
inf = dev_get_platdata(dev);
if (cpu_is_pxa3xx())
- pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self);
+ pxa3xx_u2d_stop_hc(&hcd->self);
if (inf->exit)
inf->exit(dev);
- pxa27x_reset_hc(ohci);
+ pxa27x_reset_hc(pxa_ohci);
/* Host Controller Reset */
- uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
- __raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
+ uhccoms = __raw_readl(pxa_ohci->mmio_base + UHCCOMS) | 0x01;
+ __raw_writel(uhccoms, pxa_ohci->mmio_base + UHCCOMS);
udelay(10);
- clk_disable_unprepare(ohci->clk);
+ clk_disable_unprepare(pxa_ohci->clk);
}
#ifdef CONFIG_OF
struct device_node *np = pdev->dev.of_node;
struct pxaohci_platform_data *pdata;
u32 tmp;
+ int ret;
if (!np)
return 0;
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
int retval, irq;
struct usb_hcd *hcd;
struct pxaohci_platform_data *inf;
- struct pxa27x_ohci *ohci;
+ struct pxa27x_ohci *pxa_ohci;
+ struct ohci_hcd *ohci;
struct resource *r;
struct clk *usb_clk;
}
/* initialize "struct pxa27x_ohci" */
- ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
- ohci->dev = &pdev->dev;
- ohci->clk = usb_clk;
- ohci->mmio_base = (void __iomem *)hcd->regs;
+ pxa_ohci = to_pxa27x_ohci(hcd);
+ pxa_ohci->clk = usb_clk;
+ pxa_ohci->mmio_base = (void __iomem *)hcd->regs;
- if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
+ retval = pxa27x_start_hc(pxa_ohci, &pdev->dev);
+ if (retval < 0) {
pr_debug("pxa27x_start_hc failed");
goto err3;
}
/* Select Power Management Mode */
- pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+ pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
if (inf->power_budget)
hcd->power_budget = inf->power_budget;
- ohci_hcd_init(hcd_to_ohci(hcd));
+ /* The value of NDP in roothub_a is incorrect on this hardware */
+ ohci = hcd_to_ohci(hcd);
+ ohci->num_ports = 3;
retval = usb_add_hcd(hcd, irq, 0);
if (retval == 0)
return retval;
- pxa27x_stop_hc(ohci, &pdev->dev);
+ pxa27x_stop_hc(pxa_ohci, &pdev->dev);
err3:
iounmap(hcd->regs);
err2:
*/
void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
- struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+ struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
usb_remove_hcd(hcd);
- pxa27x_stop_hc(ohci, &pdev->dev);
+ pxa27x_stop_hc(pxa_ohci, &pdev->dev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ clk_put(pxa_ohci->clk);
usb_put_hcd(hcd);
- clk_put(ohci->clk);
- }
-
- /*-------------------------------------------------------------------------*/
-
- static int
- ohci_pxa27x_start (struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
- ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci);
-
- /* The value of NDP in roothub_a is incorrect on this hardware */
- ohci->num_ports = 3;
-
- if ((ret = ohci_init(ohci)) < 0)
- return ret;
-
- if ((ret = ohci_run (ohci)) < 0) {
- dev_err(hcd->self.controller, "can't start %s",
- hcd->self.bus_name);
- ohci_stop (hcd);
- return ret;
- }
-
- return 0;
}
/*-------------------------------------------------------------------------*/
- static const struct hc_driver ohci_pxa27x_hc_driver = {
- .description = hcd_name,
- .product_desc = "PXA27x OHCI",
- .hcd_priv_size = sizeof(struct pxa27x_ohci),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /*
- * basic lifecycle operations
- */
- .start = ohci_pxa27x_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
- .start_port_reset = ohci_start_port_reset,
- };
-
- /*-------------------------------------------------------------------------*/
-
static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
{
pr_debug ("In ohci_hcd_pxa27x_drv_probe");
static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+ struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ bool do_wakeup = device_may_wakeup(dev);
+ int ret;
- if (time_before(jiffies, ohci->ohci.next_statechange))
+
+ if (time_before(jiffies, ohci->next_statechange))
msleep(5);
- ohci->ohci.next_statechange = jiffies;
+ ohci->next_statechange = jiffies;
- pxa27x_stop_hc(ohci, dev);
- return 0;
+ ret = ohci_suspend(hcd, do_wakeup);
+ if (ret)
+ return ret;
+
+ pxa27x_stop_hc(pxa_ohci, dev);
+ return ret;
}
static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+ struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);
struct pxaohci_platform_data *inf = dev_get_platdata(dev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int status;
- if (time_before(jiffies, ohci->ohci.next_statechange))
+ if (time_before(jiffies, ohci->next_statechange))
msleep(5);
- ohci->ohci.next_statechange = jiffies;
+ ohci->next_statechange = jiffies;
- if ((status = pxa27x_start_hc(ohci, dev)) < 0)
+ status = pxa27x_start_hc(pxa_ohci, dev);
+ if (status < 0)
return status;
/* Select Power Management Mode */
- pxa27x_ohci_select_pmm(ohci, inf->port_mode);
+ pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);
ohci_resume(hcd, false);
return 0;
};
#endif
- /* work with hotplug and coldplug */
- MODULE_ALIAS("platform:pxa27x-ohci");
-
static struct platform_driver ohci_hcd_pxa27x_driver = {
.probe = ohci_hcd_pxa27x_drv_probe,
.remove = ohci_hcd_pxa27x_drv_remove,
},
};
+ static const struct ohci_driver_overrides pxa27x_overrides __initconst = {
+ .extra_priv_size = sizeof(struct pxa27x_ohci),
+ };
+
+ static int __init ohci_pxa27x_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+ ohci_init_driver(&ohci_pxa27x_hc_driver, &pxa27x_overrides);
+ return platform_driver_register(&ohci_hcd_pxa27x_driver);
+ }
+ module_init(ohci_pxa27x_init);
+
+ static void __exit ohci_pxa27x_cleanup(void)
+ {
+ platform_driver_unregister(&ohci_hcd_pxa27x_driver);
+ }
+ module_exit(ohci_pxa27x_cleanup);
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL");
+ MODULE_ALIAS("platform:pxa27x-ohci");
* warranty of any kind, whether express or implied.
*/
- #include <linux/signal.h>
- #include <linux/platform_device.h>
#include <linux/clk.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
#include <linux/of.h>
+ #include <linux/platform_device.h>
+ #include <linux/signal.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
+
+ #include "ohci.h"
+ #define DRIVER_DESC "OHCI SPEAr driver"
+
+ static const char hcd_name[] = "SPEAr-ohci";
struct spear_ohci {
- struct ohci_hcd ohci;
struct clk *clk;
};
- #define to_spear_ohci(hcd) (struct spear_ohci *)hcd_to_ohci(hcd)
-
- static void spear_start_ohci(struct spear_ohci *ohci)
- {
- clk_prepare_enable(ohci->clk);
- }
-
- static void spear_stop_ohci(struct spear_ohci *ohci)
- {
- clk_disable_unprepare(ohci->clk);
- }
-
- static int ohci_spear_start(struct usb_hcd *hcd)
- {
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ret = ohci_init(ohci);
- if (ret < 0)
- return ret;
- ohci->regs = hcd->regs;
-
- ret = ohci_run(ohci);
- if (ret < 0) {
- dev_err(hcd->self.controller, "can't start\n");
- ohci_stop(hcd);
- return ret;
- }
-
- create_debug_files(ohci);
-
- #ifdef DEBUG
- ohci_dump(ohci, 1);
- #endif
- return 0;
- }
-
- static const struct hc_driver ohci_spear_hc_driver = {
- .description = hcd_name,
- .product_desc = "SPEAr OHCI",
- .hcd_priv_size = sizeof(struct spear_ohci),
-
- /* generic hardware linkage */
- .irq = ohci_irq,
- .flags = HCD_USB11 | HCD_MEMORY,
-
- /* basic lifecycle operations */
- .start = ohci_spear_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
- #ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
- #endif
-
- /* managing i/o requests and associated device resources */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /* scheduling support */
- .get_frame_number = ohci_get_frame,
+ #define to_spear_ohci(hcd) (struct spear_ohci *)(hcd_to_ohci(hcd)->priv)
- /* root hub support */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-
- .start_port_reset = ohci_start_port_reset,
- };
+ static struct hc_driver __read_mostly ohci_spear_hc_driver;
static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)
{
const struct hc_driver *driver = &ohci_spear_hc_driver;
+ struct ohci_hcd *ohci;
struct usb_hcd *hcd = NULL;
struct clk *usbh_clk;
- struct spear_ohci *ohci_p;
+ struct spear_ohci *sohci_p;
struct resource *res;
int retval, irq;
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (retval)
+ goto fail;
usbh_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(usbh_clk)) {
goto err_put_hcd;
}
- ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd);
- ohci_p->clk = usbh_clk;
- spear_start_ohci(ohci_p);
- ohci_hcd_init(hcd_to_ohci(hcd));
+ sohci_p = to_spear_ohci(hcd);
+ sohci_p->clk = usbh_clk;
+
+ clk_prepare_enable(sohci_p->clk);
+
+ ohci = hcd_to_ohci(hcd);
retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0);
if (retval == 0)
return retval;
- spear_stop_ohci(ohci_p);
+ clk_disable_unprepare(sohci_p->clk);
err_put_hcd:
usb_put_hcd(hcd);
fail:
static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+ struct spear_ohci *sohci_p = to_spear_ohci(hcd);
usb_remove_hcd(hcd);
- if (ohci_p->clk)
- spear_stop_ohci(ohci_p);
+ if (sohci_p->clk)
+ clk_disable_unprepare(sohci_p->clk);
usb_put_hcd(hcd);
return 0;
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+ struct spear_ohci *sohci_p = to_spear_ohci(hcd);
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
- spear_stop_ohci(ohci_p);
+ clk_disable_unprepare(sohci_p->clk);
+
return 0;
}
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- struct spear_ohci *ohci_p = to_spear_ohci(hcd);
+ struct spear_ohci *sohci_p = to_spear_ohci(hcd);
if (time_before(jiffies, ohci->next_statechange))
msleep(5);
ohci->next_statechange = jiffies;
- spear_start_ohci(ohci_p);
+ clk_prepare_enable(sohci_p->clk);
ohci_resume(hcd, false);
return 0;
}
},
};
+ static const struct ohci_driver_overrides spear_overrides __initconst = {
+ .extra_priv_size = sizeof(struct spear_ohci),
+ };
+ static int __init ohci_spear_init(void)
+ {
+ if (usb_disabled())
+ return -ENODEV;
+
+ pr_info("%s: " DRIVER_DESC "\n", hcd_name);
+
+ ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides);
+ return platform_driver_register(&spear_ohci_hcd_driver);
+ }
+ module_init(ohci_spear_init);
+
+ static void __exit ohci_spear_cleanup(void)
+ {
+ platform_driver_unregister(&spear_ohci_hcd_driver);
+ }
+ module_exit(ohci_spear_cleanup);
+
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_AUTHOR("Deepak Sikri");
+ MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:spear-ohci");
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
- if (!pdev->dev.dma_mask)
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- if (!pdev->dev.coherent_dma_mask)
- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
pdev->name);
uhci->regs = hcd->regs;
- ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED |
- IRQF_SHARED);
+ ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
if (ret)
goto err_uhci;