linux/drivers/usb/host/ohci-at91.c
<<
>>
Prefs
   1/*
   2 * OHCI HCD (Host Controller Driver) for USB.
   3 *
   4 *  Copyright (C) 2004 SAN People (Pty) Ltd.
   5 *  Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
   6 *
   7 * AT91 Bus Glue
   8 *
   9 * Based on fragments of 2.4 driver by Rick Bronson.
  10 * Based on ohci-omap.c
  11 *
  12 * This file is licenced under the GPL.
  13 */
  14
  15#include <linux/clk.h>
  16#include <linux/platform_device.h>
  17
  18#include <mach/hardware.h>
  19#include <asm/gpio.h>
  20
  21#include <mach/board.h>
  22#include <mach/cpu.h>
  23
  24#ifndef CONFIG_ARCH_AT91
  25#error "CONFIG_ARCH_AT91 must be defined."
  26#endif
  27
  28/* interface and function clocks; sometimes also an AHB clock */
  29static struct clk *iclk, *fclk, *hclk;
  30static int clocked;
  31
  32extern int usb_disabled(void);
  33
  34/*-------------------------------------------------------------------------*/
  35
  36static void at91_start_clock(void)
  37{
  38        if (cpu_is_at91sam9261())
  39                clk_enable(hclk);
  40        clk_enable(iclk);
  41        clk_enable(fclk);
  42        clocked = 1;
  43}
  44
  45static void at91_stop_clock(void)
  46{
  47        clk_disable(fclk);
  48        clk_disable(iclk);
  49        if (cpu_is_at91sam9261())
  50                clk_disable(hclk);
  51        clocked = 0;
  52}
  53
  54static void at91_start_hc(struct platform_device *pdev)
  55{
  56        struct usb_hcd *hcd = platform_get_drvdata(pdev);
  57        struct ohci_regs __iomem *regs = hcd->regs;
  58
  59        dev_dbg(&pdev->dev, "start\n");
  60
  61        /*
  62         * Start the USB clocks.
  63         */
  64        at91_start_clock();
  65
  66        /*
  67         * The USB host controller must remain in reset.
  68         */
  69        writel(0, &regs->control);
  70}
  71
  72static void at91_stop_hc(struct platform_device *pdev)
  73{
  74        struct usb_hcd *hcd = platform_get_drvdata(pdev);
  75        struct ohci_regs __iomem *regs = hcd->regs;
  76
  77        dev_dbg(&pdev->dev, "stop\n");
  78
  79        /*
  80         * Put the USB host controller into reset.
  81         */
  82        writel(0, &regs->control);
  83
  84        /*
  85         * Stop the USB clocks.
  86         */
  87        at91_stop_clock();
  88}
  89
  90
  91/*-------------------------------------------------------------------------*/
  92
  93static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
  94
  95/* configure so an HC device and id are always provided */
  96/* always called with process context; sleeping is OK */
  97
  98
  99/**
 100 * usb_hcd_at91_probe - initialize AT91-based HCDs
 101 * Context: !in_interrupt()
 102 *
 103 * Allocates basic resources for this USB host controller, and
 104 * then invokes the start() method for the HCD associated with it
 105 * through the hotplug entry's driver_data.
 106 */
 107static int usb_hcd_at91_probe(const struct hc_driver *driver,
 108                        struct platform_device *pdev)
 109{
 110        int retval;
 111        struct usb_hcd *hcd = NULL;
 112
 113        if (pdev->num_resources != 2) {
 114                pr_debug("hcd probe: invalid num_resources");
 115                return -ENODEV;
 116        }
 117
 118        if ((pdev->resource[0].flags != IORESOURCE_MEM)
 119                        || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
 120                pr_debug("hcd probe: invalid resource type\n");
 121                return -ENODEV;
 122        }
 123
 124        hcd = usb_create_hcd(driver, &pdev->dev, "at91");
 125        if (!hcd)
 126                return -ENOMEM;
 127        hcd->rsrc_start = pdev->resource[0].start;
 128        hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 129
 130        if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 131                pr_debug("request_mem_region failed\n");
 132                retval = -EBUSY;
 133                goto err1;
 134        }
 135
 136        hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
 137        if (!hcd->regs) {
 138                pr_debug("ioremap failed\n");
 139                retval = -EIO;
 140                goto err2;
 141        }
 142
 143        iclk = clk_get(&pdev->dev, "ohci_clk");
 144        fclk = clk_get(&pdev->dev, "uhpck");
 145        if (cpu_is_at91sam9261())
 146                hclk = clk_get(&pdev->dev, "hck0");
 147
 148        at91_start_hc(pdev);
 149        ohci_hcd_init(hcd_to_ohci(hcd));
 150
 151        retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);
 152        if (retval == 0)
 153                return retval;
 154
 155        /* Error handling */
 156        at91_stop_hc(pdev);
 157
 158        if (cpu_is_at91sam9261())
 159                clk_put(hclk);
 160        clk_put(fclk);
 161        clk_put(iclk);
 162
 163        iounmap(hcd->regs);
 164
 165 err2:
 166        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 167
 168 err1:
 169        usb_put_hcd(hcd);
 170        return retval;
 171}
 172
 173
 174/* may be called with controller, bus, and devices active */
 175
 176/**
 177 * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
 178 * @dev: USB Host Controller being removed
 179 * Context: !in_interrupt()
 180 *
 181 * Reverses the effect of usb_hcd_at91_probe(), first invoking
 182 * the HCD's stop() method.  It is always called from a thread
 183 * context, "rmmod" or something similar.
 184 *
 185 */
 186static void usb_hcd_at91_remove(struct usb_hcd *hcd,
 187                                struct platform_device *pdev)
 188{
 189        usb_remove_hcd(hcd);
 190        at91_stop_hc(pdev);
 191        iounmap(hcd->regs);
 192        release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 193        usb_put_hcd(hcd);
 194
 195        if (cpu_is_at91sam9261())
 196                clk_put(hclk);
 197        clk_put(fclk);
 198        clk_put(iclk);
 199        fclk = iclk = hclk = NULL;
 200
 201        dev_set_drvdata(&pdev->dev, NULL);
 202}
 203
 204/*-------------------------------------------------------------------------*/
 205
 206static int __devinit
 207ohci_at91_start (struct usb_hcd *hcd)
 208{
 209        struct at91_usbh_data   *board = hcd->self.controller->platform_data;
 210        struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
 211        int                     ret;
 212
 213        if ((ret = ohci_init(ohci)) < 0)
 214                return ret;
 215
 216        ohci->num_ports = board->ports;
 217
 218        if ((ret = ohci_run(ohci)) < 0) {
 219                err("can't start %s", hcd->self.bus_name);
 220                ohci_stop(hcd);
 221                return ret;
 222        }
 223        return 0;
 224}
 225
 226/*-------------------------------------------------------------------------*/
 227
 228static const struct hc_driver ohci_at91_hc_driver = {
 229        .description =          hcd_name,
 230        .product_desc =         "AT91 OHCI",
 231        .hcd_priv_size =        sizeof(struct ohci_hcd),
 232
 233        /*
 234         * generic hardware linkage
 235         */
 236        .irq =                  ohci_irq,
 237        .flags =                HCD_USB11 | HCD_MEMORY,
 238
 239        /*
 240         * basic lifecycle operations
 241         */
 242        .start =                ohci_at91_start,
 243        .stop =                 ohci_stop,
 244        .shutdown =             ohci_shutdown,
 245
 246        /*
 247         * managing i/o requests and associated device resources
 248         */
 249        .urb_enqueue =          ohci_urb_enqueue,
 250        .urb_dequeue =          ohci_urb_dequeue,
 251        .endpoint_disable =     ohci_endpoint_disable,
 252
 253        /*
 254         * scheduling support
 255         */
 256        .get_frame_number =     ohci_get_frame,
 257
 258        /*
 259         * root hub support
 260         */
 261        .hub_status_data =      ohci_hub_status_data,
 262        .hub_control =          ohci_hub_control,
 263#ifdef CONFIG_PM
 264        .bus_suspend =          ohci_bus_suspend,
 265        .bus_resume =           ohci_bus_resume,
 266#endif
 267        .start_port_reset =     ohci_start_port_reset,
 268};
 269
 270/*-------------------------------------------------------------------------*/
 271
 272static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 273{
 274        struct at91_usbh_data   *pdata = pdev->dev.platform_data;
 275        int                     i;
 276
 277        if (pdata) {
 278                /* REVISIT make the driver support per-port power switching,
 279                 * and also overcurrent detection.  Here we assume the ports
 280                 * are always powered while this driver is active, and use
 281                 * active-low power switches.
 282                 */
 283                for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
 284                        if (pdata->vbus_pin[i] <= 0)
 285                                continue;
 286                        gpio_request(pdata->vbus_pin[i], "ohci_vbus");
 287                        gpio_direction_output(pdata->vbus_pin[i], 0);
 288                }
 289        }
 290
 291        device_init_wakeup(&pdev->dev, 1);
 292        return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 293}
 294
 295static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
 296{
 297        struct at91_usbh_data   *pdata = pdev->dev.platform_data;
 298        int                     i;
 299
 300        if (pdata) {
 301                for (i = 0; i < ARRAY_SIZE(pdata->vbus_pin); i++) {
 302                        if (pdata->vbus_pin[i] <= 0)
 303                                continue;
 304                        gpio_direction_output(pdata->vbus_pin[i], 1);
 305                        gpio_free(pdata->vbus_pin[i]);
 306                }
 307        }
 308
 309        device_init_wakeup(&pdev->dev, 0);
 310        usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
 311        return 0;
 312}
 313
 314#ifdef CONFIG_PM
 315
 316static int
 317ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
 318{
 319        struct usb_hcd  *hcd = platform_get_drvdata(pdev);
 320        struct ohci_hcd *ohci = hcd_to_ohci(hcd);
 321
 322        if (device_may_wakeup(&pdev->dev))
 323                enable_irq_wake(hcd->irq);
 324
 325        /*
 326         * The integrated transceivers seem unable to notice disconnect,
 327         * reconnect, or wakeup without the 48 MHz clock active.  so for
 328         * correctness, always discard connection state (using reset).
 329         *
 330         * REVISIT: some boards will be able to turn VBUS off...
 331         */
 332        if (at91_suspend_entering_slow_clock()) {
 333                ohci_usb_reset (ohci);
 334                at91_stop_clock();
 335        }
 336
 337        return 0;
 338}
 339
 340static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 341{
 342        struct usb_hcd  *hcd = platform_get_drvdata(pdev);
 343
 344        if (device_may_wakeup(&pdev->dev))
 345                disable_irq_wake(hcd->irq);
 346
 347        if (!clocked)
 348                at91_start_clock();
 349
 350        ohci_finish_controller_resume(hcd);
 351        return 0;
 352}
 353#else
 354#define ohci_hcd_at91_drv_suspend NULL
 355#define ohci_hcd_at91_drv_resume  NULL
 356#endif
 357
 358MODULE_ALIAS("platform:at91_ohci");
 359
 360static struct platform_driver ohci_hcd_at91_driver = {
 361        .probe          = ohci_hcd_at91_drv_probe,
 362        .remove         = ohci_hcd_at91_drv_remove,
 363        .shutdown       = usb_hcd_platform_shutdown,
 364        .suspend        = ohci_hcd_at91_drv_suspend,
 365        .resume         = ohci_hcd_at91_drv_resume,
 366        .driver         = {
 367                .name   = "at91_ohci",
 368                .owner  = THIS_MODULE,
 369        },
 370};
 371