aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorSudeep Dutt <sudeep.dutt@intel.com>2014-07-11 17:04:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-11 21:27:56 -0400
commit726526c3552c5718d5aba11ac2e914b0081a5c88 (patch)
treec5f8f571d6b56e687c4b26257fcb2d8aa732c1e1 /drivers/misc
parenta8035843770f34392bbadf0ba81ffa31ecb1209b (diff)
misc: mic: add a bus driver for virtual MIC devices
This MIC virtual bus driver takes the responsibility of creating all the virtual devices connected to the PCIe device on the host and the platform device on the card. The MIC bus hardware operations provide a way to abstract certain hardware details from the base physical devices. Examples of devices added on the MIC virtual bus include host DMA and card DMA. This abstraction enables using a common DMA driver on host and card. Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Reviewed-by: Nikhil Rao <nikhil.rao@intel.com> Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com> Signed-off-by: Siva Yerramreddy <yshivakrishna@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/mic/Kconfig17
-rw-r--r--drivers/misc/mic/Makefile1
-rw-r--r--drivers/misc/mic/bus/Makefile5
-rw-r--r--drivers/misc/mic/bus/mic_bus.c218
4 files changed, 241 insertions, 0 deletions
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
index 462a5b1d8651..ee1d2ac3cd09 100644
--- a/drivers/misc/mic/Kconfig
+++ b/drivers/misc/mic/Kconfig
@@ -1,3 +1,20 @@
1comment "Intel MIC Bus Driver"
2
3config INTEL_MIC_BUS
4 tristate "Intel MIC Bus Driver"
5 depends on 64BIT && PCI && X86 && X86_DEV_DMA_OPS
6 help
7 This option is selected by any driver which registers a
8 device or driver on the MIC Bus, such as CONFIG_INTEL_MIC_HOST,
9 CONFIG_INTEL_MIC_CARD, CONFIG_INTEL_MIC_X100_DMA etc.
10
11 If you are building a host/card kernel with an Intel MIC device
12 then say M (recommended) or Y, else say N. If unsure say N.
13
14 More information about the Intel MIC family as well as the Linux
15 OS and tools for MIC to use with this driver are available from
16 <http://software.intel.com/en-us/mic-developer>.
17
1comment "Intel MIC Host Driver" 18comment "Intel MIC Host Driver"
2 19
3config INTEL_MIC_HOST 20config INTEL_MIC_HOST
diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile
index 05b34d683a58..e9bf148755e2 100644
--- a/drivers/misc/mic/Makefile
+++ b/drivers/misc/mic/Makefile
@@ -4,3 +4,4 @@
4# 4#
5obj-$(CONFIG_INTEL_MIC_HOST) += host/ 5obj-$(CONFIG_INTEL_MIC_HOST) += host/
6obj-$(CONFIG_INTEL_MIC_CARD) += card/ 6obj-$(CONFIG_INTEL_MIC_CARD) += card/
7obj-$(CONFIG_INTEL_MIC_BUS) += bus/
diff --git a/drivers/misc/mic/bus/Makefile b/drivers/misc/mic/bus/Makefile
new file mode 100644
index 000000000000..d85c7f2a0af4
--- /dev/null
+++ b/drivers/misc/mic/bus/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2014, Intel Corporation.
4#
5obj-$(CONFIG_INTEL_MIC_BUS) += mic_bus.o
diff --git a/drivers/misc/mic/bus/mic_bus.c b/drivers/misc/mic/bus/mic_bus.c
new file mode 100644
index 000000000000..961ae90aae47
--- /dev/null
+++ b/drivers/misc/mic/bus/mic_bus.c
@@ -0,0 +1,218 @@
1/*
2 * Intel MIC Platform Software Stack (MPSS)
3 *
4 * Copyright(c) 2014 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 Bus driver.
19 *
20 * This implementation is very similar to the the virtio bus driver
21 * implementation @ drivers/virtio/virtio.c
22 */
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/idr.h>
26#include <linux/mic_bus.h>
27
28/* Unique numbering for mbus devices. */
29static DEFINE_IDA(mbus_index_ida);
30
31static ssize_t device_show(struct device *d,
32 struct device_attribute *attr, char *buf)
33{
34 struct mbus_device *dev = dev_to_mbus(d);
35 return sprintf(buf, "0x%04x\n", dev->id.device);
36}
37static DEVICE_ATTR_RO(device);
38
39static ssize_t vendor_show(struct device *d,
40 struct device_attribute *attr, char *buf)
41{
42 struct mbus_device *dev = dev_to_mbus(d);
43 return sprintf(buf, "0x%04x\n", dev->id.vendor);
44}
45static DEVICE_ATTR_RO(vendor);
46
47static ssize_t modalias_show(struct device *d,
48 struct device_attribute *attr, char *buf)
49{
50 struct mbus_device *dev = dev_to_mbus(d);
51 return sprintf(buf, "mbus:d%08Xv%08X\n",
52 dev->id.device, dev->id.vendor);
53}
54static DEVICE_ATTR_RO(modalias);
55
56static struct attribute *mbus_dev_attrs[] = {
57 &dev_attr_device.attr,
58 &dev_attr_vendor.attr,
59 &dev_attr_modalias.attr,
60 NULL,
61};
62ATTRIBUTE_GROUPS(mbus_dev);
63
64static inline int mbus_id_match(const struct mbus_device *dev,
65 const struct mbus_device_id *id)
66{
67 if (id->device != dev->id.device && id->device != MBUS_DEV_ANY_ID)
68 return 0;
69
70 return id->vendor == MBUS_DEV_ANY_ID || id->vendor == dev->id.vendor;
71}
72
73/*
74 * This looks through all the IDs a driver claims to support. If any of them
75 * match, we return 1 and the kernel will call mbus_dev_probe().
76 */
77static int mbus_dev_match(struct device *dv, struct device_driver *dr)
78{
79 unsigned int i;
80 struct mbus_device *dev = dev_to_mbus(dv);
81 const struct mbus_device_id *ids;
82
83 ids = drv_to_mbus(dr)->id_table;
84 for (i = 0; ids[i].device; i++)
85 if (mbus_id_match(dev, &ids[i]))
86 return 1;
87 return 0;
88}
89
90static int mbus_uevent(struct device *dv, struct kobj_uevent_env *env)
91{
92 struct mbus_device *dev = dev_to_mbus(dv);
93
94 return add_uevent_var(env, "MODALIAS=mbus:d%08Xv%08X",
95 dev->id.device, dev->id.vendor);
96}
97
98static int mbus_dev_probe(struct device *d)
99{
100 int err;
101 struct mbus_device *dev = dev_to_mbus(d);
102 struct mbus_driver *drv = drv_to_mbus(dev->dev.driver);
103
104 err = drv->probe(dev);
105 if (!err)
106 if (drv->scan)
107 drv->scan(dev);
108 return err;
109}
110
111static int mbus_dev_remove(struct device *d)
112{
113 struct mbus_device *dev = dev_to_mbus(d);
114 struct mbus_driver *drv = drv_to_mbus(dev->dev.driver);
115
116 drv->remove(dev);
117 return 0;
118}
119
120static struct bus_type mic_bus = {
121 .name = "mic_bus",
122 .match = mbus_dev_match,
123 .dev_groups = mbus_dev_groups,
124 .uevent = mbus_uevent,
125 .probe = mbus_dev_probe,
126 .remove = mbus_dev_remove,
127};
128
129int mbus_register_driver(struct mbus_driver *driver)
130{
131 driver->driver.bus = &mic_bus;
132 return driver_register(&driver->driver);
133}
134EXPORT_SYMBOL_GPL(mbus_register_driver);
135
136void mbus_unregister_driver(struct mbus_driver *driver)
137{
138 driver_unregister(&driver->driver);
139}
140EXPORT_SYMBOL_GPL(mbus_unregister_driver);
141
142static void mbus_release_dev(struct device *d)
143{
144 struct mbus_device *mbdev = dev_to_mbus(d);
145 kfree(mbdev);
146}
147
148struct mbus_device *
149mbus_register_device(struct device *pdev, int id, struct dma_map_ops *dma_ops,
150 struct mbus_hw_ops *hw_ops, void __iomem *mmio_va)
151{
152 int ret;
153 struct mbus_device *mbdev;
154
155 mbdev = kzalloc(sizeof(*mbdev), GFP_KERNEL);
156 if (!mbdev)
157 return ERR_PTR(-ENOMEM);
158
159 mbdev->mmio_va = mmio_va;
160 mbdev->dev.parent = pdev;
161 mbdev->id.device = id;
162 mbdev->id.vendor = MBUS_DEV_ANY_ID;
163 mbdev->dev.archdata.dma_ops = dma_ops;
164 mbdev->dev.dma_mask = &mbdev->dev.coherent_dma_mask;
165 dma_set_mask(&mbdev->dev, DMA_BIT_MASK(64));
166 mbdev->dev.release = mbus_release_dev;
167 mbdev->hw_ops = hw_ops;
168 mbdev->dev.bus = &mic_bus;
169
170 /* Assign a unique device index and hence name. */
171 ret = ida_simple_get(&mbus_index_ida, 0, 0, GFP_KERNEL);
172 if (ret < 0)
173 goto free_mbdev;
174
175 mbdev->index = ret;
176 dev_set_name(&mbdev->dev, "mbus-dev%u", mbdev->index);
177 /*
178 * device_register() causes the bus infrastructure to look for a
179 * matching driver.
180 */
181 ret = device_register(&mbdev->dev);
182 if (ret)
183 goto ida_remove;
184 return mbdev;
185ida_remove:
186 ida_simple_remove(&mbus_index_ida, mbdev->index);
187free_mbdev:
188 kfree(mbdev);
189 return ERR_PTR(ret);
190}
191EXPORT_SYMBOL_GPL(mbus_register_device);
192
193void mbus_unregister_device(struct mbus_device *mbdev)
194{
195 int index = mbdev->index; /* save for after device release */
196
197 device_unregister(&mbdev->dev);
198 ida_simple_remove(&mbus_index_ida, index);
199}
200EXPORT_SYMBOL_GPL(mbus_unregister_device);
201
202static int __init mbus_init(void)
203{
204 return bus_register(&mic_bus);
205}
206
207static void __exit mbus_exit(void)
208{
209 bus_unregister(&mic_bus);
210 ida_destroy(&mbus_index_ida);
211}
212
213core_initcall(mbus_init);
214module_exit(mbus_exit);
215
216MODULE_AUTHOR("Intel Corporation");
217MODULE_DESCRIPTION("Intel(R) MIC Bus driver");
218MODULE_LICENSE("GPL v2");