228c96c04a0313164531990a8c615bf41e3c2145
[deliverable/linux.git] / drivers / misc / mic / host / mic_main.c
1 /*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2013 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
17 *
18 * Intel MIC Host driver.
19 *
20 * Global TODO's across the driver to be added after initial base
21 * patches are accepted upstream:
22 * 1) Enable DMA support.
23 * 2) Enable per vring interrupt support.
24 */
25 #include <linux/fs.h>
26 #include <linux/idr.h>
27 #include <linux/module.h>
28 #include <linux/pci.h>
29
30 #include "../common/mic_device.h"
31 #include "mic_device.h"
32 #include "mic_x100.h"
33
34 static const char mic_driver_name[] = "mic";
35
36 static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = {
37 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
38 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
39 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
40 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)},
41 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)},
42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)},
43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)},
44 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)},
45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)},
46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)},
47 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)},
48 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)},
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)},
52
53 /* required last entry */
54 { 0, }
55 };
56
57 MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
58
59 /* ID allocator for MIC devices */
60 static struct ida g_mic_ida;
61 /* Class of MIC devices for sysfs accessibility. */
62 static struct class *g_mic_class;
63 /* Base device node number for MIC devices */
64 static dev_t g_mic_devno;
65
66 /**
67 * mic_ops_init: Initialize HW specific operation tables.
68 *
69 * @mdev: pointer to mic_device instance
70 *
71 * returns none.
72 */
73 static void mic_ops_init(struct mic_device *mdev)
74 {
75 switch (mdev->family) {
76 case MIC_FAMILY_X100:
77 mdev->ops = &mic_x100_ops;
78 break;
79 default:
80 break;
81 }
82 }
83
84 /**
85 * mic_get_family - Determine hardware family to which this MIC belongs.
86 *
87 * @pdev: The pci device structure
88 *
89 * returns family.
90 */
91 static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
92 {
93 enum mic_hw_family family;
94
95 switch (pdev->device) {
96 case MIC_X100_PCI_DEVICE_2250:
97 case MIC_X100_PCI_DEVICE_2251:
98 case MIC_X100_PCI_DEVICE_2252:
99 case MIC_X100_PCI_DEVICE_2253:
100 case MIC_X100_PCI_DEVICE_2254:
101 case MIC_X100_PCI_DEVICE_2255:
102 case MIC_X100_PCI_DEVICE_2256:
103 case MIC_X100_PCI_DEVICE_2257:
104 case MIC_X100_PCI_DEVICE_2258:
105 case MIC_X100_PCI_DEVICE_2259:
106 case MIC_X100_PCI_DEVICE_225a:
107 case MIC_X100_PCI_DEVICE_225b:
108 case MIC_X100_PCI_DEVICE_225c:
109 case MIC_X100_PCI_DEVICE_225d:
110 case MIC_X100_PCI_DEVICE_225e:
111 family = MIC_FAMILY_X100;
112 break;
113 default:
114 family = MIC_FAMILY_UNKNOWN;
115 break;
116 }
117 return family;
118 }
119
120 /**
121 * mic_device_init - Allocates and initializes the MIC device structure
122 *
123 * @mdev: pointer to mic_device instance
124 * @pdev: The pci device structure
125 *
126 * returns none.
127 */
128 static void
129 mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
130 {
131 mdev->family = mic_get_family(pdev);
132 mdev->stepping = pdev->revision;
133 mic_ops_init(mdev);
134 mic_sysfs_init(mdev);
135 }
136
137 /**
138 * mic_probe - Device Initialization Routine
139 *
140 * @pdev: PCI device structure
141 * @ent: entry in mic_pci_tbl
142 *
143 * returns 0 on success, < 0 on failure.
144 */
145 static int mic_probe(struct pci_dev *pdev,
146 const struct pci_device_id *ent)
147 {
148 int rc;
149 struct mic_device *mdev;
150
151 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
152 if (!mdev) {
153 rc = -ENOMEM;
154 dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc);
155 goto mdev_alloc_fail;
156 }
157 mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL);
158 if (mdev->id < 0) {
159 rc = mdev->id;
160 dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc);
161 goto ida_fail;
162 }
163
164 mic_device_init(mdev, pdev);
165
166 rc = pci_enable_device(pdev);
167 if (rc) {
168 dev_err(&pdev->dev, "failed to enable pci device.\n");
169 goto ida_remove;
170 }
171
172 pci_set_master(pdev);
173
174 rc = pci_request_regions(pdev, mic_driver_name);
175 if (rc) {
176 dev_err(&pdev->dev, "failed to get pci regions.\n");
177 goto disable_device;
178 }
179
180 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
181 if (rc) {
182 dev_err(&pdev->dev, "Cannot set DMA mask\n");
183 goto release_regions;
184 }
185
186 mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar);
187 mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar);
188 mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar);
189 if (!mdev->mmio.va) {
190 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
191 rc = -EIO;
192 goto release_regions;
193 }
194
195 mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar);
196 mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar);
197 mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len);
198 if (!mdev->aper.va) {
199 dev_err(&pdev->dev, "Cannot remap Aperture BAR\n");
200 rc = -EIO;
201 goto unmap_mmio;
202 }
203
204 pci_set_drvdata(pdev, mdev);
205
206 mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev,
207 MKDEV(MAJOR(g_mic_devno), mdev->id), NULL,
208 mdev->attr_group, "mic%d", mdev->id);
209 if (IS_ERR(mdev->sdev)) {
210 rc = PTR_ERR(mdev->sdev);
211 dev_err(&pdev->dev,
212 "device_create_with_groups failed rc %d\n", rc);
213 goto unmap_aper;
214 }
215 return 0;
216 unmap_aper:
217 iounmap(mdev->aper.va);
218 unmap_mmio:
219 iounmap(mdev->mmio.va);
220 release_regions:
221 pci_release_regions(pdev);
222 disable_device:
223 pci_disable_device(pdev);
224 ida_remove:
225 ida_simple_remove(&g_mic_ida, mdev->id);
226 ida_fail:
227 kfree(mdev);
228 mdev_alloc_fail:
229 dev_err(&pdev->dev, "Probe failed rc %d\n", rc);
230 return rc;
231 }
232
233 /**
234 * mic_remove - Device Removal Routine
235 * mic_remove is called by the PCI subsystem to alert the driver
236 * that it should release a PCI device.
237 *
238 * @pdev: PCI device structure
239 */
240 static void mic_remove(struct pci_dev *pdev)
241 {
242 struct mic_device *mdev;
243
244 mdev = pci_get_drvdata(pdev);
245 if (!mdev)
246 return;
247
248 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
249 iounmap(mdev->mmio.va);
250 iounmap(mdev->aper.va);
251 pci_release_regions(pdev);
252 pci_disable_device(pdev);
253 ida_simple_remove(&g_mic_ida, mdev->id);
254 kfree(mdev);
255 }
256 static struct pci_driver mic_driver = {
257 .name = mic_driver_name,
258 .id_table = mic_pci_tbl,
259 .probe = mic_probe,
260 .remove = mic_remove
261 };
262
263 static int __init mic_init(void)
264 {
265 int ret;
266
267 ret = alloc_chrdev_region(&g_mic_devno, 0,
268 MIC_MAX_NUM_DEVS, mic_driver_name);
269 if (ret) {
270 pr_err("alloc_chrdev_region failed ret %d\n", ret);
271 goto error;
272 }
273
274 g_mic_class = class_create(THIS_MODULE, mic_driver_name);
275 if (IS_ERR(g_mic_class)) {
276 ret = PTR_ERR(g_mic_class);
277 pr_err("class_create failed ret %d\n", ret);
278 goto cleanup_chrdev;
279 }
280
281 ida_init(&g_mic_ida);
282 ret = pci_register_driver(&mic_driver);
283 if (ret) {
284 pr_err("pci_register_driver failed ret %d\n", ret);
285 goto class_destroy;
286 }
287 return ret;
288 class_destroy:
289 class_destroy(g_mic_class);
290 cleanup_chrdev:
291 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
292 error:
293 return ret;
294 }
295
296 static void __exit mic_exit(void)
297 {
298 pci_unregister_driver(&mic_driver);
299 ida_destroy(&g_mic_ida);
300 class_destroy(g_mic_class);
301 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
302 }
303
304 module_init(mic_init);
305 module_exit(mic_exit);
306
307 MODULE_AUTHOR("Intel Corporation");
308 MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver");
309 MODULE_LICENSE("GPL v2");
This page took 0.039168 seconds and 4 git commands to generate.