Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ci13xxx_pci.c
Go to the documentation of this file.
1 /*
2  * ci13xxx_pci.c - MIPS USB IP core family device controller
3  *
4  * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
5  *
6  * Author: David Lopo
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/platform_device.h>
14 #include <linux/module.h>
15 #include <linux/pci.h>
16 #include <linux/interrupt.h>
17 #include <linux/usb/gadget.h>
18 #include <linux/usb/chipidea.h>
19 
20 /* driver name */
21 #define UDC_DRIVER_NAME "ci13xxx_pci"
22 
23 /******************************************************************************
24  * PCI block
25  *****************************************************************************/
27  .name = UDC_DRIVER_NAME,
28  .capoffset = DEF_CAPOFFSET,
29 };
30 
32  .name = UDC_DRIVER_NAME,
33  .capoffset = 0,
34 };
35 
37  .name = UDC_DRIVER_NAME,
38  .capoffset = 0,
39  .power_budget = 200,
40 };
41 
51 static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev,
52  const struct pci_device_id *id)
53 {
54  struct ci13xxx_platform_data *platdata = (void *)id->driver_data;
55  struct platform_device *plat_ci;
56  struct resource res[3];
57  int retval = 0, nres = 2;
58 
59  if (!platdata) {
60  dev_err(&pdev->dev, "device doesn't provide driver data\n");
61  return -ENODEV;
62  }
63 
64  retval = pci_enable_device(pdev);
65  if (retval)
66  goto done;
67 
68  if (!pdev->irq) {
69  dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!");
70  retval = -ENODEV;
71  goto disable_device;
72  }
73 
75  pci_set_master(pdev);
76  pci_try_set_mwi(pdev);
77 
78  memset(res, 0, sizeof(res));
79  res[0].start = pci_resource_start(pdev, 0);
80  res[0].end = pci_resource_end(pdev, 0);
81  res[0].flags = IORESOURCE_MEM;
82  res[1].start = pdev->irq;
83  res[1].flags = IORESOURCE_IRQ;
84 
85  plat_ci = ci13xxx_add_device(&pdev->dev, res, nres, platdata);
86  if (IS_ERR(plat_ci)) {
87  dev_err(&pdev->dev, "ci13xxx_add_device failed!\n");
88  retval = PTR_ERR(plat_ci);
89  goto disable_device;
90  }
91 
92  pci_set_drvdata(pdev, plat_ci);
93 
94  return 0;
95 
96  disable_device:
97  pci_disable_device(pdev);
98  done:
99  return retval;
100 }
101 
110 static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev)
111 {
112  struct platform_device *plat_ci = pci_get_drvdata(pdev);
113 
114  ci13xxx_remove_device(plat_ci);
115  pci_set_drvdata(pdev, NULL);
116  pci_disable_device(pdev);
117 }
118 
125 static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = {
126  {
127  PCI_DEVICE(0x153F, 0x1004),
128  .driver_data = (kernel_ulong_t)&pci_platdata,
129  },
130  {
131  PCI_DEVICE(0x153F, 0x1006),
132  .driver_data = (kernel_ulong_t)&pci_platdata,
133  },
134  {
136  .driver_data = (kernel_ulong_t)&langwell_pci_platdata,
137  },
138  {
140  .driver_data = (kernel_ulong_t)&penwell_pci_platdata,
141  },
142  { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ }
143 };
144 MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table);
145 
146 static struct pci_driver ci13xxx_pci_driver = {
147  .name = UDC_DRIVER_NAME,
148  .id_table = ci13xxx_pci_id_table,
149  .probe = ci13xxx_pci_probe,
150  .remove = __devexit_p(ci13xxx_pci_remove),
151 };
152 
153 module_pci_driver(ci13xxx_pci_driver);
154 
155 MODULE_AUTHOR("MIPS - David Lopo <[email protected]>");
156 MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller");
157 MODULE_LICENSE("GPL");
158 MODULE_VERSION("June 2008");