Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uhci-platform.c
Go to the documentation of this file.
1 /*
2  * Generic UHCI HCD (Host Controller Driver) for Platform Devices
3  *
4  * Copyright (c) 2011 Tony Prisk <[email protected]>
5  *
6  * This file is based on uhci-grlib.c
7  * (C) Copyright 2004-2007 Alan Stern, [email protected]
8  */
9 
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
12 
13 static int uhci_platform_init(struct usb_hcd *hcd)
14 {
15  struct uhci_hcd *uhci = hcd_to_uhci(hcd);
16 
17  uhci->rh_numports = uhci_count_ports(hcd);
18 
19  /* Set up pointers to to generic functions */
20  uhci->reset_hc = uhci_generic_reset_hc;
21  uhci->check_and_reset_hc = uhci_generic_check_and_reset_hc;
22 
23  /* No special actions need to be taken for the functions below */
24  uhci->configure_hc = NULL;
27 
28  /* Reset if the controller isn't already safely quiescent. */
29  check_and_reset_hc(uhci);
30  return 0;
31 }
32 
33 static const struct hc_driver uhci_platform_hc_driver = {
34  .description = hcd_name,
35  .product_desc = "Generic UHCI Host Controller",
36  .hcd_priv_size = sizeof(struct uhci_hcd),
37 
38  /* Generic hardware linkage */
39  .irq = uhci_irq,
40  .flags = HCD_MEMORY | HCD_USB11,
41 
42  /* Basic lifecycle operations */
43  .reset = uhci_platform_init,
44  .start = uhci_start,
45 #ifdef CONFIG_PM
46  .pci_suspend = NULL,
47  .pci_resume = NULL,
48  .bus_suspend = uhci_rh_suspend,
49  .bus_resume = uhci_rh_resume,
50 #endif
51  .stop = uhci_stop,
52 
53  .urb_enqueue = uhci_urb_enqueue,
54  .urb_dequeue = uhci_urb_dequeue,
55 
56  .endpoint_disable = uhci_hcd_endpoint_disable,
57  .get_frame_number = uhci_hcd_get_frame_number,
58 
59  .hub_status_data = uhci_hub_status_data,
60  .hub_control = uhci_hub_control,
61 };
62 
63 static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
64 
65 static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
66 {
67  struct usb_hcd *hcd;
68  struct uhci_hcd *uhci;
69  struct resource *res;
70  int ret;
71 
72  if (usb_disabled())
73  return -ENODEV;
74 
75  /*
76  * Right now device-tree probed devices don't get dma_mask set.
77  * Since shared usb code relies on it, set it here for now.
78  * Once we have dma capability bindings this can go away.
79  */
80  if (!pdev->dev.dma_mask)
81  pdev->dev.dma_mask = &platform_uhci_dma_mask;
82 
83  hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
84  pdev->name);
85  if (!hcd)
86  return -ENOMEM;
87 
88  res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
89  hcd->rsrc_start = res->start;
90  hcd->rsrc_len = resource_size(res);
91 
92  if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
93  pr_err("%s: request_mem_region failed\n", __func__);
94  ret = -EBUSY;
95  goto err_rmr;
96  }
97 
98  hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
99  if (!hcd->regs) {
100  pr_err("%s: ioremap failed\n", __func__);
101  ret = -ENOMEM;
102  goto err_irq;
103  }
104  uhci = hcd_to_uhci(hcd);
105 
106  uhci->regs = hcd->regs;
107 
108  ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED |
109  IRQF_SHARED);
110  if (ret)
111  goto err_uhci;
112 
113  return 0;
114 
115 err_uhci:
116  iounmap(hcd->regs);
117 err_irq:
118  release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
119 err_rmr:
120  usb_put_hcd(hcd);
121 
122  return ret;
123 }
124 
125 static int uhci_hcd_platform_remove(struct platform_device *pdev)
126 {
127  struct usb_hcd *hcd = platform_get_drvdata(pdev);
128 
129  usb_remove_hcd(hcd);
130  iounmap(hcd->regs);
131  release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
132  usb_put_hcd(hcd);
133  platform_set_drvdata(pdev, NULL);
134 
135  return 0;
136 }
137 
138 /* Make sure the controller is quiescent and that we're not using it
139  * any more. This is mainly for the benefit of programs which, like kexec,
140  * expect the hardware to be idle: not doing DMA or generating IRQs.
141  *
142  * This routine may be called in a damaged or failing kernel. Hence we
143  * do not acquire the spinlock before shutting down the controller.
144  */
145 static void uhci_hcd_platform_shutdown(struct platform_device *op)
146 {
147  struct usb_hcd *hcd = dev_get_drvdata(&op->dev);
148 
149  uhci_hc_died(hcd_to_uhci(hcd));
150 }
151 
152 static const struct of_device_id platform_uhci_ids[] = {
153  { .compatible = "platform-uhci", },
154  {}
155 };
156 
157 static struct platform_driver uhci_platform_driver = {
158  .probe = uhci_hcd_platform_probe,
159  .remove = uhci_hcd_platform_remove,
160  .shutdown = uhci_hcd_platform_shutdown,
161  .driver = {
162  .name = "platform-uhci",
163  .owner = THIS_MODULE,
164  .of_match_table = of_match_ptr(platform_uhci_ids),
165  },
166 };