From: linux@prisktech.co.nz (Tony Prisk)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] ARM: vt8500: Add support for UHCI companion controller
Date: Fri, 20 Jul 2012 01:31:24 +1200 [thread overview]
Message-ID: <1342704684-4858-2-git-send-email-linux@prisktech.co.nz> (raw)
In-Reply-To: <1342704684-4858-1-git-send-email-linux@prisktech.co.nz>
Add support for the UHCI companion controller in arch-vt8500.
This patch is based almost entirely off uhci-grlib.c with
additions for device tree support.
Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
drivers/usb/host/Kconfig | 4 +-
drivers/usb/host/uhci-hcd.c | 5 +
drivers/usb/host/uhci-vt8500.c | 158 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 165 insertions(+), 2 deletions(-)
create mode 100644 drivers/usb/host/uhci-vt8500.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 83e58df..1c4de8f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -450,7 +450,7 @@ config USB_OHCI_LITTLE_ENDIAN
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
- depends on USB && (PCI || SPARC_LEON)
+ depends on USB && (PCI || SPARC_LEON || ARCH_VT8500)
---help---
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
@@ -468,7 +468,7 @@ config USB_UHCI_HCD
config USB_UHCI_SUPPORT_NON_PCI_HC
bool
depends on USB_UHCI_HCD
- default y if SPARC_LEON
+ default y if (SPARC_LEON || ARCH_VT8500)
config USB_UHCI_BIG_ENDIAN_MMIO
bool
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index e4db350..28f885d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -846,6 +846,11 @@ static const char hcd_name[] = "uhci_hcd";
#define PLATFORM_DRIVER uhci_grlib_driver
#endif
+#ifdef CONFIG_ARCH_VT8500
+#include "uhci-vt8500.c"
+#define PLATFORM_DRIVER uhci_vt8500_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER)
#error "missing bus glue for uhci-hcd"
#endif
diff --git a/drivers/usb/host/uhci-vt8500.c b/drivers/usb/host/uhci-vt8500.c
new file mode 100644
index 0000000..d349c82
--- /dev/null
+++ b/drivers/usb/host/uhci-vt8500.c
@@ -0,0 +1,158 @@
+/*
+ * UHCI HCD (Host Controller Driver) for VT8500/WM8505/WM8650
+ *
+ * Copyright (c) 2011 Tony Prisk <linux@prisktech.co.nz>
+ *
+ * This file is based on uhci-grlib.c
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int uhci_vt8500_init(struct usb_hcd *hcd)
+{
+ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+ uhci->rh_numports = uhci_count_ports(hcd);
+
+ /* Set up pointers to to generic functions */
+ uhci->reset_hc = uhci_generic_reset_hc;
+ uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
+
+ /* No special actions need to be taken for the functions below */
+ uhci->configure_hc = NULL;
+ uhci->resume_detect_interrupts_are_broken = NULL;
+ uhci->global_suspend_mode_is_broken = NULL;
+
+ /* Reset if the controller isn't already safely quiescent. */
+ check_and_reset_hc(uhci);
+ return 0;
+}
+
+static const struct hc_driver uhci_vt8500_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "WonderMedia UHCI Host Controller",
+ .hcd_priv_size = sizeof(struct uhci_hcd),
+
+ /* Generic hardware linkage */
+ .irq = uhci_irq,
+ .flags = HCD_MEMORY | HCD_USB11,
+
+ /* Basic lifecycle operations */
+ .reset = uhci_vt8500_init,
+ .start = uhci_start,
+#ifdef CONFIG_PM
+ .pci_suspend = NULL,
+ .pci_resume = NULL,
+ .bus_suspend = uhci_rh_suspend,
+ .bus_resume = uhci_rh_resume,
+#endif
+ .stop = uhci_stop,
+
+ .urb_enqueue = uhci_urb_enqueue,
+ .urb_dequeue = uhci_urb_dequeue,
+
+ .endpoint_disable = uhci_hcd_endpoint_disable,
+ .get_frame_number = uhci_hcd_get_frame_number,
+
+ .hub_status_data = uhci_hub_status_data,
+ .hub_control = uhci_hub_control,
+};
+
+
+static int __devinit uhci_hcd_vt8500_probe(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ struct uhci_hcd *uhci;
+ struct resource *res;
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ hcd = usb_create_hcd(&uhci_vt8500_hc_driver, &pdev->dev,
+ pdev->name);
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_err("%s: request_mem_region failed\n", __func__);
+ ret = -EBUSY;
+ goto err_rmr;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_err("%s: ioremap failed\n", __func__);
+ ret = -ENOMEM;
+ goto err_irq;
+ }
+
+ uhci = hcd_to_uhci(hcd);
+
+ uhci->regs = hcd->regs;
+
+ ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED |
+ IRQF_SHARED);
+ if (ret)
+ goto err_uhci;
+
+ return 0;
+
+err_uhci:
+ iounmap(hcd->regs);
+err_irq:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_rmr:
+ usb_put_hcd(hcd);
+
+ return ret;
+}
+
+static int uhci_hcd_vt8500_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+/* Make sure the controller is quiescent and that we're not using it
+ * any more. This is mainly for the benefit of programs which, like kexec,
+ * expect the hardware to be idle: not doing DMA or generating IRQs.
+ *
+ * This routine may be called in a damaged or failing kernel. Hence we
+ * do not acquire the spinlock before shutting down the controller.
+ */
+static void uhci_hcd_vt8500_shutdown(struct platform_device *op)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+
+ uhci_hc_died(hcd_to_uhci(hcd));
+}
+
+static const struct of_device_id vt8500_uhci_ids[] = {
+ { .compatible = "via,vt8500-uhci", },
+ { .compatible = "wm,prizm-uhci", },
+ {}
+};
+
+static struct platform_driver uhci_vt8500_driver = {
+ .probe = uhci_hcd_vt8500_probe,
+ .remove = uhci_hcd_vt8500_remove,
+ .shutdown = uhci_hcd_vt8500_shutdown,
+ .driver = {
+ .name = "vt8500-uhci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(vt8500_uhci_ids),
+ },
+};
--
1.7.2.5
WARNING: multiple messages have this Message-ID (diff)
From: Tony Prisk <linux-ci5G2KO2hbZ+pU9mqzGVBQ@public.gmane.org>
To: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
vt8500-wm8505-linux-kernel-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
Subject: [PATCH 2/2] ARM: vt8500: Add support for UHCI companion controller
Date: Fri, 20 Jul 2012 01:31:24 +1200 [thread overview]
Message-ID: <1342704684-4858-2-git-send-email-linux@prisktech.co.nz> (raw)
In-Reply-To: <1342704684-4858-1-git-send-email-linux-ci5G2KO2hbZ+pU9mqzGVBQ@public.gmane.org>
Add support for the UHCI companion controller in arch-vt8500.
This patch is based almost entirely off uhci-grlib.c with
additions for device tree support.
Signed-off-by: Tony Prisk <linux-ci5G2KO2hbZ+pU9mqzGVBQ@public.gmane.org>
---
drivers/usb/host/Kconfig | 4 +-
drivers/usb/host/uhci-hcd.c | 5 +
drivers/usb/host/uhci-vt8500.c | 158 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 165 insertions(+), 2 deletions(-)
create mode 100644 drivers/usb/host/uhci-vt8500.c
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 83e58df..1c4de8f 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -450,7 +450,7 @@ config USB_OHCI_LITTLE_ENDIAN
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
- depends on USB && (PCI || SPARC_LEON)
+ depends on USB && (PCI || SPARC_LEON || ARCH_VT8500)
---help---
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
@@ -468,7 +468,7 @@ config USB_UHCI_HCD
config USB_UHCI_SUPPORT_NON_PCI_HC
bool
depends on USB_UHCI_HCD
- default y if SPARC_LEON
+ default y if (SPARC_LEON || ARCH_VT8500)
config USB_UHCI_BIG_ENDIAN_MMIO
bool
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index e4db350..28f885d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -846,6 +846,11 @@ static const char hcd_name[] = "uhci_hcd";
#define PLATFORM_DRIVER uhci_grlib_driver
#endif
+#ifdef CONFIG_ARCH_VT8500
+#include "uhci-vt8500.c"
+#define PLATFORM_DRIVER uhci_vt8500_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER)
#error "missing bus glue for uhci-hcd"
#endif
diff --git a/drivers/usb/host/uhci-vt8500.c b/drivers/usb/host/uhci-vt8500.c
new file mode 100644
index 0000000..d349c82
--- /dev/null
+++ b/drivers/usb/host/uhci-vt8500.c
@@ -0,0 +1,158 @@
+/*
+ * UHCI HCD (Host Controller Driver) for VT8500/WM8505/WM8650
+ *
+ * Copyright (c) 2011 Tony Prisk <linux-ci5G2KO2hbZ+pU9mqzGVBQ@public.gmane.org>
+ *
+ * This file is based on uhci-grlib.c
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static int uhci_vt8500_init(struct usb_hcd *hcd)
+{
+ struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+ uhci->rh_numports = uhci_count_ports(hcd);
+
+ /* Set up pointers to to generic functions */
+ uhci->reset_hc = uhci_generic_reset_hc;
+ uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
+
+ /* No special actions need to be taken for the functions below */
+ uhci->configure_hc = NULL;
+ uhci->resume_detect_interrupts_are_broken = NULL;
+ uhci->global_suspend_mode_is_broken = NULL;
+
+ /* Reset if the controller isn't already safely quiescent. */
+ check_and_reset_hc(uhci);
+ return 0;
+}
+
+static const struct hc_driver uhci_vt8500_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "WonderMedia UHCI Host Controller",
+ .hcd_priv_size = sizeof(struct uhci_hcd),
+
+ /* Generic hardware linkage */
+ .irq = uhci_irq,
+ .flags = HCD_MEMORY | HCD_USB11,
+
+ /* Basic lifecycle operations */
+ .reset = uhci_vt8500_init,
+ .start = uhci_start,
+#ifdef CONFIG_PM
+ .pci_suspend = NULL,
+ .pci_resume = NULL,
+ .bus_suspend = uhci_rh_suspend,
+ .bus_resume = uhci_rh_resume,
+#endif
+ .stop = uhci_stop,
+
+ .urb_enqueue = uhci_urb_enqueue,
+ .urb_dequeue = uhci_urb_dequeue,
+
+ .endpoint_disable = uhci_hcd_endpoint_disable,
+ .get_frame_number = uhci_hcd_get_frame_number,
+
+ .hub_status_data = uhci_hub_status_data,
+ .hub_control = uhci_hub_control,
+};
+
+
+static int __devinit uhci_hcd_vt8500_probe(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ struct uhci_hcd *uhci;
+ struct resource *res;
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ hcd = usb_create_hcd(&uhci_vt8500_hc_driver, &pdev->dev,
+ pdev->name);
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = resource_size(res);
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_err("%s: request_mem_region failed\n", __func__);
+ ret = -EBUSY;
+ goto err_rmr;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_err("%s: ioremap failed\n", __func__);
+ ret = -ENOMEM;
+ goto err_irq;
+ }
+
+ uhci = hcd_to_uhci(hcd);
+
+ uhci->regs = hcd->regs;
+
+ ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED |
+ IRQF_SHARED);
+ if (ret)
+ goto err_uhci;
+
+ return 0;
+
+err_uhci:
+ iounmap(hcd->regs);
+err_irq:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_rmr:
+ usb_put_hcd(hcd);
+
+ return ret;
+}
+
+static int uhci_hcd_vt8500_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+/* Make sure the controller is quiescent and that we're not using it
+ * any more. This is mainly for the benefit of programs which, like kexec,
+ * expect the hardware to be idle: not doing DMA or generating IRQs.
+ *
+ * This routine may be called in a damaged or failing kernel. Hence we
+ * do not acquire the spinlock before shutting down the controller.
+ */
+static void uhci_hcd_vt8500_shutdown(struct platform_device *op)
+{
+ struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
+
+ uhci_hc_died(hcd_to_uhci(hcd));
+}
+
+static const struct of_device_id vt8500_uhci_ids[] = {
+ { .compatible = "via,vt8500-uhci", },
+ { .compatible = "wm,prizm-uhci", },
+ {}
+};
+
+static struct platform_driver uhci_vt8500_driver = {
+ .probe = uhci_hcd_vt8500_probe,
+ .remove = uhci_hcd_vt8500_remove,
+ .shutdown = uhci_hcd_vt8500_shutdown,
+ .driver = {
+ .name = "vt8500-uhci",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(vt8500_uhci_ids),
+ },
+};
--
1.7.2.5
next prev parent reply other threads:[~2012-07-19 13:31 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-19 13:31 [PATCH 1/2] ARM: vt8500: Update vt8500-ehci driver to support device tree Tony Prisk
2012-07-19 13:31 ` Tony Prisk
2012-07-19 13:31 ` Tony Prisk [this message]
2012-07-19 13:31 ` [PATCH 2/2] ARM: vt8500: Add support for UHCI companion controller Tony Prisk
2012-07-19 14:27 ` Arnd Bergmann
2012-07-19 14:27 ` Arnd Bergmann
2012-07-19 14:23 ` [PATCH 1/2] ARM: vt8500: Update vt8500-ehci driver to support device tree Arnd Bergmann
2012-07-19 14:23 ` Arnd Bergmann
2012-07-19 14:45 ` Alexey Charkov
2012-07-19 14:45 ` Alexey Charkov
2012-07-19 14:51 ` Tony Prisk
2012-07-19 14:51 ` Tony Prisk
2012-07-19 15:31 ` Tony Prisk
2012-07-19 15:31 ` Tony Prisk
-- strict thread matches above, loose matches on Subject: below --
2012-07-19 16:07 Tony Prisk
2012-07-19 16:07 ` [PATCH 2/2] ARM: vt8500: Add support for UHCI companion controller Tony Prisk
2012-07-19 16:07 ` Tony Prisk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1342704684-4858-2-git-send-email-linux@prisktech.co.nz \
--to=linux@prisktech.co.nz \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.