diff options
author | Sudeep Dutt <sudeep.dutt@intel.com> | 2013-09-05 19:41:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-26 16:49:23 -0400 |
commit | b170d8ce3f81bd97e85756e9184779a56a5f55a7 (patch) | |
tree | aa441b1a6ebd510695b16ee685567409210e3a2a /drivers/misc | |
parent | 9089e3be60b13a1114e8afdc37c605e75cfc4a26 (diff) |
Intel MIC Host Driver for X100 family.
This patch enables the following:
a) Initializes the Intel MIC X100 PCIe devices.
b) Provides sysfs entries for family and stepping information.
Co-author: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Caz Yokoyama <Caz.Yokoyama@intel.com>
Signed-off-by: Dasaratharaman Chandramouli <dasaratharaman.chandramouli@intel.com>
Signed-off-by: Harshavardhan R Kharche <harshavardhan.r.kharche@intel.com>
Signed-off-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Acked-by: Yaozu (Eddie) Dong <eddie.dong@intel.com>
Reviewed-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/mic/Kconfig | 19 | ||||
-rw-r--r-- | drivers/misc/mic/Makefile | 5 | ||||
-rw-r--r-- | drivers/misc/mic/common/mic_device.h | 37 | ||||
-rw-r--r-- | drivers/misc/mic/host/Makefile | 8 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_device.h | 109 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_main.c | 309 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_sysfs.c | 97 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_x100.c | 75 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_x100.h | 47 |
11 files changed, 708 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8dacd4c9ee87..e760715bd9cb 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -537,4 +537,5 @@ source "drivers/misc/carma/Kconfig" | |||
537 | source "drivers/misc/altera-stapl/Kconfig" | 537 | source "drivers/misc/altera-stapl/Kconfig" |
538 | source "drivers/misc/mei/Kconfig" | 538 | source "drivers/misc/mei/Kconfig" |
539 | source "drivers/misc/vmw_vmci/Kconfig" | 539 | source "drivers/misc/vmw_vmci/Kconfig" |
540 | source "drivers/misc/mic/Kconfig" | ||
540 | endmenu | 541 | endmenu |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index c235d5b68311..0b7ea3ea8bb8 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/ | |||
53 | obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ | 53 | obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ |
54 | obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o | 54 | obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o |
55 | obj-$(CONFIG_SRAM) += sram.o | 55 | obj-$(CONFIG_SRAM) += sram.o |
56 | obj-y += mic/ | ||
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig new file mode 100644 index 000000000000..aaefd0cf82a7 --- /dev/null +++ b/drivers/misc/mic/Kconfig | |||
@@ -0,0 +1,19 @@ | |||
1 | comment "Intel MIC Host Driver" | ||
2 | |||
3 | config INTEL_MIC_HOST | ||
4 | tristate "Intel MIC Host Driver" | ||
5 | depends on 64BIT && PCI | ||
6 | default N | ||
7 | help | ||
8 | This enables Host Driver support for the Intel Many Integrated | ||
9 | Core (MIC) family of PCIe form factor coprocessor devices that | ||
10 | run a 64 bit Linux OS. The driver manages card OS state and | ||
11 | enables communication between host and card. Intel MIC X100 | ||
12 | devices are currently supported. | ||
13 | |||
14 | If you are building a host kernel with an Intel MIC device then | ||
15 | say M (recommended) or Y, else say N. If unsure say N. | ||
16 | |||
17 | More information about the Intel MIC family as well as the Linux | ||
18 | OS and tools for MIC to use with this driver are available from | ||
19 | <http://software.intel.com/en-us/mic-developer>. | ||
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile new file mode 100644 index 000000000000..8e724212d94c --- /dev/null +++ b/drivers/misc/mic/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile - Intel MIC Linux driver. | ||
3 | # Copyright(c) 2013, Intel Corporation. | ||
4 | # | ||
5 | obj-$(CONFIG_INTEL_MIC_HOST) += host/ | ||
diff --git a/drivers/misc/mic/common/mic_device.h b/drivers/misc/mic/common/mic_device.h new file mode 100644 index 000000000000..f02262e1c9d3 --- /dev/null +++ b/drivers/misc/mic/common/mic_device.h | |||
@@ -0,0 +1,37 @@ | |||
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 driver. | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __MIC_COMMON_DEVICE_H_ | ||
22 | #define __MIC_COMMON_DEVICE_H_ | ||
23 | |||
24 | /** | ||
25 | * struct mic_mw - MIC memory window | ||
26 | * | ||
27 | * @pa: Base physical address. | ||
28 | * @va: Base ioremap'd virtual address. | ||
29 | * @len: Size of the memory window. | ||
30 | */ | ||
31 | struct mic_mw { | ||
32 | phys_addr_t pa; | ||
33 | void __iomem *va; | ||
34 | resource_size_t len; | ||
35 | }; | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile new file mode 100644 index 000000000000..93b9d25d2c88 --- /dev/null +++ b/drivers/misc/mic/host/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile - Intel MIC Linux driver. | ||
3 | # Copyright(c) 2013, Intel Corporation. | ||
4 | # | ||
5 | obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o | ||
6 | mic_host-objs := mic_main.o | ||
7 | mic_host-objs += mic_x100.o | ||
8 | mic_host-objs += mic_sysfs.o | ||
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h new file mode 100644 index 000000000000..6cd904cdfdf9 --- /dev/null +++ b/drivers/misc/mic/host/mic_device.h | |||
@@ -0,0 +1,109 @@ | |||
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 | */ | ||
21 | #ifndef _MIC_DEVICE_H_ | ||
22 | #define _MIC_DEVICE_H_ | ||
23 | |||
24 | /* The maximum number of MIC devices supported in a single host system. */ | ||
25 | #define MIC_MAX_NUM_DEVS 256 | ||
26 | |||
27 | /** | ||
28 | * enum mic_hw_family - The hardware family to which a device belongs. | ||
29 | */ | ||
30 | enum mic_hw_family { | ||
31 | MIC_FAMILY_X100 = 0, | ||
32 | MIC_FAMILY_UNKNOWN | ||
33 | }; | ||
34 | |||
35 | /** | ||
36 | * enum mic_stepping - MIC stepping ids. | ||
37 | */ | ||
38 | enum mic_stepping { | ||
39 | MIC_A0_STEP = 0x0, | ||
40 | MIC_B0_STEP = 0x10, | ||
41 | MIC_B1_STEP = 0x11, | ||
42 | MIC_C0_STEP = 0x20, | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * struct mic_device - MIC device information for each card. | ||
47 | * | ||
48 | * @mmio: MMIO bar information. | ||
49 | * @aper: Aperture bar information. | ||
50 | * @family: The MIC family to which this device belongs. | ||
51 | * @ops: MIC HW specific operations. | ||
52 | * @id: The unique device id for this MIC device. | ||
53 | * @stepping: Stepping ID. | ||
54 | * @attr_group: Pointer to list of sysfs attribute groups. | ||
55 | * @sdev: Device for sysfs entries. | ||
56 | */ | ||
57 | struct mic_device { | ||
58 | struct mic_mw mmio; | ||
59 | struct mic_mw aper; | ||
60 | enum mic_hw_family family; | ||
61 | struct mic_hw_ops *ops; | ||
62 | int id; | ||
63 | enum mic_stepping stepping; | ||
64 | const struct attribute_group **attr_group; | ||
65 | struct device *sdev; | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * struct mic_hw_ops - MIC HW specific operations. | ||
70 | * @aper_bar: Aperture bar resource number. | ||
71 | * @mmio_bar: MMIO bar resource number. | ||
72 | * @read_spad: Read from scratch pad register. | ||
73 | * @write_spad: Write to scratch pad register. | ||
74 | */ | ||
75 | struct mic_hw_ops { | ||
76 | u8 aper_bar; | ||
77 | u8 mmio_bar; | ||
78 | u32 (*read_spad)(struct mic_device *mdev, unsigned int idx); | ||
79 | void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val); | ||
80 | }; | ||
81 | |||
82 | /** | ||
83 | * mic_mmio_read - read from an MMIO register. | ||
84 | * @mw: MMIO register base virtual address. | ||
85 | * @offset: register offset. | ||
86 | * | ||
87 | * RETURNS: register value. | ||
88 | */ | ||
89 | static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset) | ||
90 | { | ||
91 | return ioread32(mw->va + offset); | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * mic_mmio_write - write to an MMIO register. | ||
96 | * @mw: MMIO register base virtual address. | ||
97 | * @val: the data value to put into the register | ||
98 | * @offset: register offset. | ||
99 | * | ||
100 | * RETURNS: none. | ||
101 | */ | ||
102 | static inline void | ||
103 | mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset) | ||
104 | { | ||
105 | iowrite32(val, mw->va + offset); | ||
106 | } | ||
107 | |||
108 | void mic_sysfs_init(struct mic_device *mdev); | ||
109 | #endif | ||
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c new file mode 100644 index 000000000000..228c96c04a03 --- /dev/null +++ b/drivers/misc/mic/host/mic_main.c | |||
@@ -0,0 +1,309 @@ | |||
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"); | ||
diff --git a/drivers/misc/mic/host/mic_sysfs.c b/drivers/misc/mic/host/mic_sysfs.c new file mode 100644 index 000000000000..972c18255263 --- /dev/null +++ b/drivers/misc/mic/host/mic_sysfs.c | |||
@@ -0,0 +1,97 @@ | |||
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 | */ | ||
21 | #include <linux/pci.h> | ||
22 | |||
23 | #include "../common/mic_device.h" | ||
24 | #include "mic_device.h" | ||
25 | |||
26 | static ssize_t | ||
27 | mic_show_family(struct device *dev, struct device_attribute *attr, char *buf) | ||
28 | { | ||
29 | static const char x100[] = "x100"; | ||
30 | static const char unknown[] = "Unknown"; | ||
31 | const char *card = NULL; | ||
32 | struct mic_device *mdev = dev_get_drvdata(dev->parent); | ||
33 | |||
34 | if (!mdev) | ||
35 | return -EINVAL; | ||
36 | |||
37 | switch (mdev->family) { | ||
38 | case MIC_FAMILY_X100: | ||
39 | card = x100; | ||
40 | break; | ||
41 | default: | ||
42 | card = unknown; | ||
43 | break; | ||
44 | } | ||
45 | return scnprintf(buf, PAGE_SIZE, "%s\n", card); | ||
46 | } | ||
47 | static DEVICE_ATTR(family, S_IRUGO, mic_show_family, NULL); | ||
48 | |||
49 | static ssize_t | ||
50 | mic_show_stepping(struct device *dev, struct device_attribute *attr, char *buf) | ||
51 | { | ||
52 | struct mic_device *mdev = dev_get_drvdata(dev->parent); | ||
53 | char *string = "??"; | ||
54 | |||
55 | if (!mdev) | ||
56 | return -EINVAL; | ||
57 | |||
58 | switch (mdev->stepping) { | ||
59 | case MIC_A0_STEP: | ||
60 | string = "A0"; | ||
61 | break; | ||
62 | case MIC_B0_STEP: | ||
63 | string = "B0"; | ||
64 | break; | ||
65 | case MIC_B1_STEP: | ||
66 | string = "B1"; | ||
67 | break; | ||
68 | case MIC_C0_STEP: | ||
69 | string = "C0"; | ||
70 | break; | ||
71 | default: | ||
72 | break; | ||
73 | } | ||
74 | return scnprintf(buf, PAGE_SIZE, "%s\n", string); | ||
75 | } | ||
76 | static DEVICE_ATTR(stepping, S_IRUGO, mic_show_stepping, NULL); | ||
77 | |||
78 | static struct attribute *mic_default_attrs[] = { | ||
79 | &dev_attr_family.attr, | ||
80 | &dev_attr_stepping.attr, | ||
81 | |||
82 | NULL | ||
83 | }; | ||
84 | |||
85 | static struct attribute_group mic_attr_group = { | ||
86 | .attrs = mic_default_attrs, | ||
87 | }; | ||
88 | |||
89 | static const struct attribute_group *__mic_attr_group[] = { | ||
90 | &mic_attr_group, | ||
91 | NULL | ||
92 | }; | ||
93 | |||
94 | void mic_sysfs_init(struct mic_device *mdev) | ||
95 | { | ||
96 | mdev->attr_group = __mic_attr_group; | ||
97 | } | ||
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c new file mode 100644 index 000000000000..da481b173af9 --- /dev/null +++ b/drivers/misc/mic/host/mic_x100.c | |||
@@ -0,0 +1,75 @@ | |||
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 | */ | ||
21 | #include <linux/fs.h> | ||
22 | #include <linux/pci.h> | ||
23 | |||
24 | #include "../common/mic_device.h" | ||
25 | #include "mic_device.h" | ||
26 | #include "mic_x100.h" | ||
27 | |||
28 | /** | ||
29 | * mic_x100_write_spad - write to the scratchpad register | ||
30 | * @mdev: pointer to mic_device instance | ||
31 | * @idx: index to the scratchpad register, 0 based | ||
32 | * @val: the data value to put into the register | ||
33 | * | ||
34 | * This function allows writing of a 32bit value to the indexed scratchpad | ||
35 | * register. | ||
36 | * | ||
37 | * RETURNS: none. | ||
38 | */ | ||
39 | static void | ||
40 | mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val) | ||
41 | { | ||
42 | dev_dbg(mdev->sdev->parent, "Writing 0x%x to scratch pad index %d\n", | ||
43 | val, idx); | ||
44 | mic_mmio_write(&mdev->mmio, val, | ||
45 | MIC_X100_SBOX_BASE_ADDRESS + | ||
46 | MIC_X100_SBOX_SPAD0 + idx * 4); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * mic_x100_read_spad - read from the scratchpad register | ||
51 | * @mdev: pointer to mic_device instance | ||
52 | * @idx: index to scratchpad register, 0 based | ||
53 | * | ||
54 | * This function allows reading of the 32bit scratchpad register. | ||
55 | * | ||
56 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | ||
57 | */ | ||
58 | static u32 | ||
59 | mic_x100_read_spad(struct mic_device *mdev, unsigned int idx) | ||
60 | { | ||
61 | u32 val = mic_mmio_read(&mdev->mmio, | ||
62 | MIC_X100_SBOX_BASE_ADDRESS + | ||
63 | MIC_X100_SBOX_SPAD0 + idx * 4); | ||
64 | |||
65 | dev_dbg(mdev->sdev->parent, | ||
66 | "Reading 0x%x from scratch pad index %d\n", val, idx); | ||
67 | return val; | ||
68 | } | ||
69 | |||
70 | struct mic_hw_ops mic_x100_ops = { | ||
71 | .aper_bar = MIC_X100_APER_BAR, | ||
72 | .mmio_bar = MIC_X100_MMIO_BAR, | ||
73 | .read_spad = mic_x100_read_spad, | ||
74 | .write_spad = mic_x100_write_spad, | ||
75 | }; | ||
diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h new file mode 100644 index 000000000000..1f4e6305dcf5 --- /dev/null +++ b/drivers/misc/mic/host/mic_x100.h | |||
@@ -0,0 +1,47 @@ | |||
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 | */ | ||
21 | #ifndef _MIC_X100_HW_H_ | ||
22 | #define _MIC_X100_HW_H_ | ||
23 | |||
24 | #define MIC_X100_PCI_DEVICE_2250 0x2250 | ||
25 | #define MIC_X100_PCI_DEVICE_2251 0x2251 | ||
26 | #define MIC_X100_PCI_DEVICE_2252 0x2252 | ||
27 | #define MIC_X100_PCI_DEVICE_2253 0x2253 | ||
28 | #define MIC_X100_PCI_DEVICE_2254 0x2254 | ||
29 | #define MIC_X100_PCI_DEVICE_2255 0x2255 | ||
30 | #define MIC_X100_PCI_DEVICE_2256 0x2256 | ||
31 | #define MIC_X100_PCI_DEVICE_2257 0x2257 | ||
32 | #define MIC_X100_PCI_DEVICE_2258 0x2258 | ||
33 | #define MIC_X100_PCI_DEVICE_2259 0x2259 | ||
34 | #define MIC_X100_PCI_DEVICE_225a 0x225a | ||
35 | #define MIC_X100_PCI_DEVICE_225b 0x225b | ||
36 | #define MIC_X100_PCI_DEVICE_225c 0x225c | ||
37 | #define MIC_X100_PCI_DEVICE_225d 0x225d | ||
38 | #define MIC_X100_PCI_DEVICE_225e 0x225e | ||
39 | |||
40 | #define MIC_X100_APER_BAR 0 | ||
41 | #define MIC_X100_MMIO_BAR 4 | ||
42 | |||
43 | #define MIC_X100_SBOX_BASE_ADDRESS 0x00010000 | ||
44 | #define MIC_X100_SBOX_SPAD0 0x0000AB20 | ||
45 | extern struct mic_hw_ops mic_x100_ops; | ||
46 | |||
47 | #endif | ||