diff options
-rw-r--r-- | Documentation/mic/mic_overview.txt | 54 | ||||
-rwxr-xr-x | Documentation/mic/mpssd/mpss | 2 | ||||
-rw-r--r-- | Documentation/mic/mpssd/mpssd.c | 2 | ||||
-rw-r--r-- | drivers/misc/mic/Kconfig | 7 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_device.c | 84 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_device.h | 3 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_x100.c | 1 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_boot.c | 123 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_device.h | 3 | ||||
-rw-r--r-- | drivers/misc/mic/host/mic_main.c | 1 |
10 files changed, 247 insertions, 33 deletions
diff --git a/Documentation/mic/mic_overview.txt b/Documentation/mic/mic_overview.txt index 73f44fc3e715..074adbdf83a4 100644 --- a/Documentation/mic/mic_overview.txt +++ b/Documentation/mic/mic_overview.txt | |||
@@ -12,10 +12,19 @@ for the X100 devices. | |||
12 | 12 | ||
13 | Since it is a PCIe card, it does not have the ability to host hardware | 13 | Since it is a PCIe card, it does not have the ability to host hardware |
14 | devices for networking, storage and console. We provide these devices | 14 | devices for networking, storage and console. We provide these devices |
15 | on X100 coprocessors thus enabling a self-bootable equivalent environment | 15 | on X100 coprocessors thus enabling a self-bootable equivalent |
16 | for applications. A key benefit of our solution is that it leverages | 16 | environment for applications. A key benefit of our solution is that it |
17 | the standard virtio framework for network, disk and console devices, | 17 | leverages the standard virtio framework for network, disk and console |
18 | though in our case the virtio framework is used across a PCIe bus. | 18 | devices, though in our case the virtio framework is used across a PCIe |
19 | bus. A Virtio Over PCIe (VOP) driver allows creating user space | ||
20 | backends or devices on the host which are used to probe virtio drivers | ||
21 | for these devices on the MIC card. The existing VRINGH infrastructure | ||
22 | in the kernel is used to access virtio rings from the host. The card | ||
23 | VOP driver allows card virtio drivers to communicate with their user | ||
24 | space backends on the host via a device page. Ring 3 apps on the host | ||
25 | can add, remove and configure virtio devices. A thin MIC specific | ||
26 | virtio_config_ops is implemented which is borrowed heavily from | ||
27 | previous similar implementations in lguest and s390. | ||
19 | 28 | ||
20 | MIC PCIe card has a dma controller with 8 channels. These channels are | 29 | MIC PCIe card has a dma controller with 8 channels. These channels are |
21 | shared between the host s/w and the card s/w. 0 to 3 are used by host | 30 | shared between the host s/w and the card s/w. 0 to 3 are used by host |
@@ -38,7 +47,6 @@ single threaded performance for the host compared to MIC, the ability of | |||
38 | the host to initiate DMA's to/from the card using the MIC DMA engine and | 47 | the host to initiate DMA's to/from the card using the MIC DMA engine and |
39 | the fact that the virtio block storage backend can only be on the host. | 48 | the fact that the virtio block storage backend can only be on the host. |
40 | 49 | ||
41 | | | ||
42 | +----------+ | +----------+ | 50 | +----------+ | +----------+ |
43 | | Card OS | | | Host OS | | 51 | | Card OS | | | Host OS | |
44 | +----------+ | +----------+ | 52 | +----------+ | +----------+ |
@@ -47,27 +55,25 @@ the fact that the virtio block storage backend can only be on the host. | |||
47 | | Virtio| |Virtio | |Virtio| | |Virtio | |Virtio | |Virtio | | 55 | | Virtio| |Virtio | |Virtio| | |Virtio | |Virtio | |Virtio | |
48 | | Net | |Console | |Block | | |Net | |Console | |Block | | 56 | | Net | |Console | |Block | | |Net | |Console | |Block | |
49 | | Driver| |Driver | |Driver| | |backend | |backend | |backend | | 57 | | Driver| |Driver | |Driver| | |backend | |backend | |backend | |
50 | +-------+ +--------+ +------+ | +---------+ +--------+ +--------+ | 58 | +---+---+ +---+----+ +--+---+ | +---------+ +----+---+ +--------+ |
51 | | | | | | | | | 59 | | | | | | | | |
52 | | | | |User | | | | 60 | | | | |User | | | |
53 | | | | |------|------------|---------|------- | 61 | | | | |------|------------|--+------|------- |
54 | +-------------------+ |Kernel +--------------------------+ | 62 | +---------+---------+ |Kernel | |
55 | | | | Virtio over PCIe IOCTLs | | 63 | | | | |
56 | | | +--------------------------+ | 64 | +---------+ +---+----+ +------+ | +------+ +------+ +--+---+ +-------+ |
57 | +-----------+ | | | +-----------+ | 65 | |MIC DMA | | VOP | | SCIF | | | SCIF | | COSM | | VOP | |MIC DMA| |
58 | | MIC DMA | | +------+ | +------+ +------+ | | MIC DMA | | 66 | +---+-----+ +---+----+ +--+---+ | +--+---+ +--+---+ +------+ +----+--+ |
59 | | Driver | | | SCIF | | | SCIF | | COSM | | | Driver | | 67 | | | | | | | | |
60 | +-----------+ | +------+ | +------+ +--+---+ | +-----------+ | 68 | +---+-----+ +---+----+ +--+---+ | +--+---+ +--+---+ +------+ +----+--+ |
61 | | | | | | | | | | 69 | |MIC | | VOP | |SCIF | | |SCIF | | COSM | | VOP | | MIC | |
62 | +---------------+ | +------+ | +--+---+ +--+---+ | +----------------+ | 70 | |HW Bus | | HW Bus| |HW Bus| | |HW Bus| | Bus | |HW Bus| |HW Bus | |
63 | |MIC virtual Bus| | |SCIF | | |SCIF | | COSM | | |MIC virtual Bus | | 71 | +---------+ +--------+ +--+---+ | +--+---+ +------+ +------+ +-------+ |
64 | +---------------+ | |HW Bus| | |HW Bus| | Bus | | +----------------+ | 72 | | | | | | | | |
65 | | | +------+ | +--+---+ +------+ | | | 73 | | +-----------+--+ | | | +---------------+ | |
66 | | | | | | | | | | 74 | | |Intel MIC | | | | |Intel MIC | | |
67 | | +-----------+---+ | | | +---------------+ | | 75 | | |Card Driver | | | | |Host Driver | | |
68 | | |Intel MIC | | | | |Intel MIC | | | 76 | +---+--------------+------+ | +----+---------------+-----+ |
69 | +---|Card Driver | | | | |Host Driver | | | ||
70 | +------------+--------+ | +----+---------------+-----+ | ||
71 | | | | | 77 | | | | |
72 | +-------------------------------------------------------------+ | 78 | +-------------------------------------------------------------+ |
73 | | | | 79 | | | |
diff --git a/Documentation/mic/mpssd/mpss b/Documentation/mic/mpssd/mpss index 09ea90931649..5fcf9fa4b082 100755 --- a/Documentation/mic/mpssd/mpss +++ b/Documentation/mic/mpssd/mpss | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | exec=/usr/sbin/mpssd | 36 | exec=/usr/sbin/mpssd |
37 | sysfs="/sys/class/mic" | 37 | sysfs="/sys/class/mic" |
38 | mic_modules="mic_host mic_x100_dma scif" | 38 | mic_modules="mic_host mic_x100_dma scif vop" |
39 | 39 | ||
40 | start() | 40 | start() |
41 | { | 41 | { |
diff --git a/Documentation/mic/mpssd/mpssd.c b/Documentation/mic/mpssd/mpssd.c index aaeafa18d99b..518dece71578 100644 --- a/Documentation/mic/mpssd/mpssd.c +++ b/Documentation/mic/mpssd/mpssd.c | |||
@@ -926,7 +926,7 @@ add_virtio_device(struct mic_info *mic, struct mic_device_desc *dd) | |||
926 | char path[PATH_MAX]; | 926 | char path[PATH_MAX]; |
927 | int fd, err; | 927 | int fd, err; |
928 | 928 | ||
929 | snprintf(path, PATH_MAX, "/dev/mic%d", mic->id); | 929 | snprintf(path, PATH_MAX, "/dev/vop_virtio%d", mic->id); |
930 | fd = open(path, O_RDWR); | 930 | fd = open(path, O_RDWR); |
931 | if (fd < 0) { | 931 | if (fd < 0) { |
932 | mpsslog("Could not open %s %s\n", path, strerror(errno)); | 932 | mpsslog("Could not open %s %s\n", path, strerror(errno)); |
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig index b03bb17cae77..2e4f3ba75c8e 100644 --- a/drivers/misc/mic/Kconfig +++ b/drivers/misc/mic/Kconfig | |||
@@ -53,8 +53,8 @@ comment "Intel MIC Host Driver" | |||
53 | 53 | ||
54 | config INTEL_MIC_HOST | 54 | config INTEL_MIC_HOST |
55 | tristate "Intel MIC Host Driver" | 55 | tristate "Intel MIC Host Driver" |
56 | depends on 64BIT && PCI && X86 && INTEL_MIC_BUS && SCIF_BUS && MIC_COSM | 56 | depends on 64BIT && PCI && X86 |
57 | select VHOST_RING | 57 | depends on INTEL_MIC_BUS && SCIF_BUS && MIC_COSM && VOP_BUS |
58 | help | 58 | help |
59 | This enables Host Driver support for the Intel Many Integrated | 59 | This enables Host Driver support for the Intel Many Integrated |
60 | Core (MIC) family of PCIe form factor coprocessor devices that | 60 | Core (MIC) family of PCIe form factor coprocessor devices that |
@@ -73,7 +73,8 @@ comment "Intel MIC Card Driver" | |||
73 | 73 | ||
74 | config INTEL_MIC_CARD | 74 | config INTEL_MIC_CARD |
75 | tristate "Intel MIC Card Driver" | 75 | tristate "Intel MIC Card Driver" |
76 | depends on 64BIT && X86 && INTEL_MIC_BUS && SCIF_BUS && MIC_COSM | 76 | depends on 64BIT && X86 |
77 | depends on INTEL_MIC_BUS && SCIF_BUS && MIC_COSM && VOP_BUS | ||
77 | select VIRTIO | 78 | select VIRTIO |
78 | help | 79 | help |
79 | This enables card driver support for the Intel Many Integrated | 80 | This enables card driver support for the Intel Many Integrated |
diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c index ff03c633541c..e749af48f736 100644 --- a/drivers/misc/mic/card/mic_device.c +++ b/drivers/misc/mic/card/mic_device.c | |||
@@ -249,12 +249,82 @@ static struct scif_hw_ops scif_hw_ops = { | |||
249 | .iounmap = ___mic_iounmap, | 249 | .iounmap = ___mic_iounmap, |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static inline struct mic_driver *vpdev_to_mdrv(struct vop_device *vpdev) | ||
253 | { | ||
254 | return dev_get_drvdata(vpdev->dev.parent); | ||
255 | } | ||
256 | |||
257 | static struct mic_irq * | ||
258 | __mic_request_irq(struct vop_device *vpdev, | ||
259 | irqreturn_t (*func)(int irq, void *data), | ||
260 | const char *name, void *data, int intr_src) | ||
261 | { | ||
262 | return mic_request_card_irq(func, NULL, name, data, intr_src); | ||
263 | } | ||
264 | |||
265 | static void __mic_free_irq(struct vop_device *vpdev, | ||
266 | struct mic_irq *cookie, void *data) | ||
267 | { | ||
268 | return mic_free_card_irq(cookie, data); | ||
269 | } | ||
270 | |||
271 | static void __mic_ack_interrupt(struct vop_device *vpdev, int num) | ||
272 | { | ||
273 | struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); | ||
274 | |||
275 | mic_ack_interrupt(&mdrv->mdev); | ||
276 | } | ||
277 | |||
278 | static int __mic_next_db(struct vop_device *vpdev) | ||
279 | { | ||
280 | return mic_next_card_db(); | ||
281 | } | ||
282 | |||
283 | static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev) | ||
284 | { | ||
285 | struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); | ||
286 | |||
287 | return mdrv->dp; | ||
288 | } | ||
289 | |||
290 | static void __mic_send_intr(struct vop_device *vpdev, int db) | ||
291 | { | ||
292 | struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); | ||
293 | |||
294 | mic_send_intr(&mdrv->mdev, db); | ||
295 | } | ||
296 | |||
297 | static void __iomem *__mic_ioremap(struct vop_device *vpdev, | ||
298 | dma_addr_t pa, size_t len) | ||
299 | { | ||
300 | struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); | ||
301 | |||
302 | return mic_card_map(&mdrv->mdev, pa, len); | ||
303 | } | ||
304 | |||
305 | static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va) | ||
306 | { | ||
307 | struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); | ||
308 | |||
309 | mic_card_unmap(&mdrv->mdev, va); | ||
310 | } | ||
311 | |||
312 | static struct vop_hw_ops vop_hw_ops = { | ||
313 | .request_irq = __mic_request_irq, | ||
314 | .free_irq = __mic_free_irq, | ||
315 | .ack_interrupt = __mic_ack_interrupt, | ||
316 | .next_db = __mic_next_db, | ||
317 | .get_remote_dp = __mic_get_remote_dp, | ||
318 | .send_intr = __mic_send_intr, | ||
319 | .ioremap = __mic_ioremap, | ||
320 | .iounmap = __mic_iounmap, | ||
321 | }; | ||
322 | |||
252 | static int mic_request_dma_chans(struct mic_driver *mdrv) | 323 | static int mic_request_dma_chans(struct mic_driver *mdrv) |
253 | { | 324 | { |
254 | dma_cap_mask_t mask; | 325 | dma_cap_mask_t mask; |
255 | struct dma_chan *chan; | 326 | struct dma_chan *chan; |
256 | 327 | ||
257 | request_module("mic_x100_dma"); | ||
258 | dma_cap_zero(mask); | 328 | dma_cap_zero(mask); |
259 | dma_cap_set(DMA_MEMCPY, mask); | 329 | dma_cap_set(DMA_MEMCPY, mask); |
260 | 330 | ||
@@ -308,6 +378,13 @@ int __init mic_driver_init(struct mic_driver *mdrv) | |||
308 | rc = -ENODEV; | 378 | rc = -ENODEV; |
309 | goto irq_uninit; | 379 | goto irq_uninit; |
310 | } | 380 | } |
381 | mdrv->vpdev = vop_register_device(mdrv->dev, VOP_DEV_TRNSP, | ||
382 | NULL, &vop_hw_ops, 0, | ||
383 | NULL, mdrv->dma_ch[0]); | ||
384 | if (IS_ERR(mdrv->vpdev)) { | ||
385 | rc = PTR_ERR(mdrv->vpdev); | ||
386 | goto dma_free; | ||
387 | } | ||
311 | bootparam = mdrv->dp; | 388 | bootparam = mdrv->dp; |
312 | node_id = ioread8(&bootparam->node_id); | 389 | node_id = ioread8(&bootparam->node_id); |
313 | mdrv->scdev = scif_register_device(mdrv->dev, MIC_SCIF_DEV, | 390 | mdrv->scdev = scif_register_device(mdrv->dev, MIC_SCIF_DEV, |
@@ -317,11 +394,13 @@ int __init mic_driver_init(struct mic_driver *mdrv) | |||
317 | mdrv->num_dma_ch, true); | 394 | mdrv->num_dma_ch, true); |
318 | if (IS_ERR(mdrv->scdev)) { | 395 | if (IS_ERR(mdrv->scdev)) { |
319 | rc = PTR_ERR(mdrv->scdev); | 396 | rc = PTR_ERR(mdrv->scdev); |
320 | goto dma_free; | 397 | goto vop_remove; |
321 | } | 398 | } |
322 | mic_create_card_debug_dir(mdrv); | 399 | mic_create_card_debug_dir(mdrv); |
323 | done: | 400 | done: |
324 | return rc; | 401 | return rc; |
402 | vop_remove: | ||
403 | vop_unregister_device(mdrv->vpdev); | ||
325 | dma_free: | 404 | dma_free: |
326 | mic_free_dma_chans(mdrv); | 405 | mic_free_dma_chans(mdrv); |
327 | irq_uninit: | 406 | irq_uninit: |
@@ -342,6 +421,7 @@ void mic_driver_uninit(struct mic_driver *mdrv) | |||
342 | { | 421 | { |
343 | mic_delete_card_debug_dir(mdrv); | 422 | mic_delete_card_debug_dir(mdrv); |
344 | scif_unregister_device(mdrv->scdev); | 423 | scif_unregister_device(mdrv->scdev); |
424 | vop_unregister_device(mdrv->vpdev); | ||
345 | mic_free_dma_chans(mdrv); | 425 | mic_free_dma_chans(mdrv); |
346 | mic_uninit_irq(); | 426 | mic_uninit_irq(); |
347 | mic_dp_uninit(); | 427 | mic_dp_uninit(); |
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h index 1dbf83c41289..333dbed972f6 100644 --- a/drivers/misc/mic/card/mic_device.h +++ b/drivers/misc/mic/card/mic_device.h | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/mic_bus.h> | 33 | #include <linux/mic_bus.h> |
34 | #include "../bus/scif_bus.h" | 34 | #include "../bus/scif_bus.h" |
35 | #include "../bus/vop_bus.h" | ||
35 | 36 | ||
36 | /** | 37 | /** |
37 | * struct mic_intr_info - Contains h/w specific interrupt sources info | 38 | * struct mic_intr_info - Contains h/w specific interrupt sources info |
@@ -76,6 +77,7 @@ struct mic_device { | |||
76 | * @dma_ch - Array of DMA channels | 77 | * @dma_ch - Array of DMA channels |
77 | * @num_dma_ch - Number of DMA channels available | 78 | * @num_dma_ch - Number of DMA channels available |
78 | * @scdev: SCIF device on the SCIF virtual bus. | 79 | * @scdev: SCIF device on the SCIF virtual bus. |
80 | * @vpdev: Virtio over PCIe device on the VOP virtual bus. | ||
79 | */ | 81 | */ |
80 | struct mic_driver { | 82 | struct mic_driver { |
81 | char name[20]; | 83 | char name[20]; |
@@ -90,6 +92,7 @@ struct mic_driver { | |||
90 | struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; | 92 | struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; |
91 | int num_dma_ch; | 93 | int num_dma_ch; |
92 | struct scif_hw_dev *scdev; | 94 | struct scif_hw_dev *scdev; |
95 | struct vop_device *vpdev; | ||
93 | }; | 96 | }; |
94 | 97 | ||
95 | /** | 98 | /** |
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c index b2958ce2368c..b9f0710ffa6b 100644 --- a/drivers/misc/mic/card/mic_x100.c +++ b/drivers/misc/mic/card/mic_x100.c | |||
@@ -326,6 +326,7 @@ static int __init mic_init(void) | |||
326 | goto done; | 326 | goto done; |
327 | } | 327 | } |
328 | 328 | ||
329 | request_module("mic_x100_dma"); | ||
329 | mic_init_card_debugfs(); | 330 | mic_init_card_debugfs(); |
330 | ret = platform_device_register(&mic_platform_dev); | 331 | ret = platform_device_register(&mic_platform_dev); |
331 | if (ret) { | 332 | if (ret) { |
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c index 3df305f6282c..8c91c9950b54 100644 --- a/drivers/misc/mic/host/mic_boot.c +++ b/drivers/misc/mic/host/mic_boot.c | |||
@@ -25,10 +25,118 @@ | |||
25 | #include <linux/mic_common.h> | 25 | #include <linux/mic_common.h> |
26 | #include <linux/mic_bus.h> | 26 | #include <linux/mic_bus.h> |
27 | #include "../bus/scif_bus.h" | 27 | #include "../bus/scif_bus.h" |
28 | #include "../bus/vop_bus.h" | ||
28 | #include "../common/mic_dev.h" | 29 | #include "../common/mic_dev.h" |
29 | #include "mic_device.h" | 30 | #include "mic_device.h" |
30 | #include "mic_smpt.h" | 31 | #include "mic_smpt.h" |
31 | 32 | ||
33 | static inline struct mic_device *vpdev_to_mdev(struct device *dev) | ||
34 | { | ||
35 | return dev_get_drvdata(dev->parent); | ||
36 | } | ||
37 | |||
38 | static dma_addr_t | ||
39 | _mic_dma_map_page(struct device *dev, struct page *page, | ||
40 | unsigned long offset, size_t size, | ||
41 | enum dma_data_direction dir, struct dma_attrs *attrs) | ||
42 | { | ||
43 | void *va = phys_to_virt(page_to_phys(page)) + offset; | ||
44 | struct mic_device *mdev = vpdev_to_mdev(dev); | ||
45 | |||
46 | return mic_map_single(mdev, va, size); | ||
47 | } | ||
48 | |||
49 | static void _mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, | ||
50 | size_t size, enum dma_data_direction dir, | ||
51 | struct dma_attrs *attrs) | ||
52 | { | ||
53 | struct mic_device *mdev = vpdev_to_mdev(dev); | ||
54 | |||
55 | mic_unmap_single(mdev, dma_addr, size); | ||
56 | } | ||
57 | |||
58 | static const struct dma_map_ops _mic_dma_ops = { | ||
59 | .map_page = _mic_dma_map_page, | ||
60 | .unmap_page = _mic_dma_unmap_page, | ||
61 | }; | ||
62 | |||
63 | static struct mic_irq * | ||
64 | __mic_request_irq(struct vop_device *vpdev, | ||
65 | irqreturn_t (*func)(int irq, void *data), | ||
66 | const char *name, void *data, int intr_src) | ||
67 | { | ||
68 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
69 | |||
70 | return mic_request_threaded_irq(mdev, func, NULL, name, data, | ||
71 | intr_src, MIC_INTR_DB); | ||
72 | } | ||
73 | |||
74 | static void __mic_free_irq(struct vop_device *vpdev, | ||
75 | struct mic_irq *cookie, void *data) | ||
76 | { | ||
77 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
78 | |||
79 | return mic_free_irq(mdev, cookie, data); | ||
80 | } | ||
81 | |||
82 | static void __mic_ack_interrupt(struct vop_device *vpdev, int num) | ||
83 | { | ||
84 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
85 | |||
86 | mdev->ops->intr_workarounds(mdev); | ||
87 | } | ||
88 | |||
89 | static int __mic_next_db(struct vop_device *vpdev) | ||
90 | { | ||
91 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
92 | |||
93 | return mic_next_db(mdev); | ||
94 | } | ||
95 | |||
96 | static void *__mic_get_dp(struct vop_device *vpdev) | ||
97 | { | ||
98 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
99 | |||
100 | return mdev->dp; | ||
101 | } | ||
102 | |||
103 | static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev) | ||
104 | { | ||
105 | return NULL; | ||
106 | } | ||
107 | |||
108 | static void __mic_send_intr(struct vop_device *vpdev, int db) | ||
109 | { | ||
110 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
111 | |||
112 | mdev->ops->send_intr(mdev, db); | ||
113 | } | ||
114 | |||
115 | static void __iomem *__mic_ioremap(struct vop_device *vpdev, | ||
116 | dma_addr_t pa, size_t len) | ||
117 | { | ||
118 | struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); | ||
119 | |||
120 | return mdev->aper.va + pa; | ||
121 | } | ||
122 | |||
123 | static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va) | ||
124 | { | ||
125 | /* nothing to do */ | ||
126 | } | ||
127 | |||
128 | static struct vop_hw_ops vop_hw_ops = { | ||
129 | .request_irq = __mic_request_irq, | ||
130 | .free_irq = __mic_free_irq, | ||
131 | .ack_interrupt = __mic_ack_interrupt, | ||
132 | .next_db = __mic_next_db, | ||
133 | .get_dp = __mic_get_dp, | ||
134 | .get_remote_dp = __mic_get_remote_dp, | ||
135 | .send_intr = __mic_send_intr, | ||
136 | .ioremap = __mic_ioremap, | ||
137 | .iounmap = __mic_iounmap, | ||
138 | }; | ||
139 | |||
32 | static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev) | 140 | static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev) |
33 | { | 141 | { |
34 | return dev_get_drvdata(scdev->dev.parent); | 142 | return dev_get_drvdata(scdev->dev.parent); |
@@ -314,7 +422,6 @@ static int mic_request_dma_chans(struct mic_device *mdev) | |||
314 | dma_cap_mask_t mask; | 422 | dma_cap_mask_t mask; |
315 | struct dma_chan *chan; | 423 | struct dma_chan *chan; |
316 | 424 | ||
317 | request_module("mic_x100_dma"); | ||
318 | dma_cap_zero(mask); | 425 | dma_cap_zero(mask); |
319 | dma_cap_set(DMA_MEMCPY, mask); | 426 | dma_cap_set(DMA_MEMCPY, mask); |
320 | 427 | ||
@@ -386,9 +493,18 @@ static int _mic_start(struct cosm_device *cdev, int id) | |||
386 | goto dma_free; | 493 | goto dma_free; |
387 | } | 494 | } |
388 | 495 | ||
496 | mdev->vpdev = vop_register_device(&mdev->pdev->dev, | ||
497 | VOP_DEV_TRNSP, &_mic_dma_ops, | ||
498 | &vop_hw_ops, id + 1, &mdev->aper, | ||
499 | mdev->dma_ch[0]); | ||
500 | if (IS_ERR(mdev->vpdev)) { | ||
501 | rc = PTR_ERR(mdev->vpdev); | ||
502 | goto scif_remove; | ||
503 | } | ||
504 | |||
389 | rc = mdev->ops->load_mic_fw(mdev, NULL); | 505 | rc = mdev->ops->load_mic_fw(mdev, NULL); |
390 | if (rc) | 506 | if (rc) |
391 | goto scif_remove; | 507 | goto vop_remove; |
392 | mic_smpt_restore(mdev); | 508 | mic_smpt_restore(mdev); |
393 | mic_intr_restore(mdev); | 509 | mic_intr_restore(mdev); |
394 | mdev->intr_ops->enable_interrupts(mdev); | 510 | mdev->intr_ops->enable_interrupts(mdev); |
@@ -396,6 +512,8 @@ static int _mic_start(struct cosm_device *cdev, int id) | |||
396 | mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); | 512 | mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); |
397 | mdev->ops->send_firmware_intr(mdev); | 513 | mdev->ops->send_firmware_intr(mdev); |
398 | goto unlock_ret; | 514 | goto unlock_ret; |
515 | vop_remove: | ||
516 | vop_unregister_device(mdev->vpdev); | ||
399 | scif_remove: | 517 | scif_remove: |
400 | scif_unregister_device(mdev->scdev); | 518 | scif_unregister_device(mdev->scdev); |
401 | dma_free: | 519 | dma_free: |
@@ -422,6 +540,7 @@ static void _mic_stop(struct cosm_device *cdev, bool force) | |||
422 | * will be the first to be registered and the last to be | 540 | * will be the first to be registered and the last to be |
423 | * unregistered. | 541 | * unregistered. |
424 | */ | 542 | */ |
543 | vop_unregister_device(mdev->vpdev); | ||
425 | scif_unregister_device(mdev->scdev); | 544 | scif_unregister_device(mdev->scdev); |
426 | mic_free_dma_chans(mdev); | 545 | mic_free_dma_chans(mdev); |
427 | mbus_unregister_device(mdev->dma_mbdev); | 546 | mbus_unregister_device(mdev->dma_mbdev); |
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index 8460de122929..52b12b22f4ae 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/miscdevice.h> | 29 | #include <linux/miscdevice.h> |
30 | #include <linux/mic_bus.h> | 30 | #include <linux/mic_bus.h> |
31 | #include "../bus/scif_bus.h" | 31 | #include "../bus/scif_bus.h" |
32 | #include "../bus/vop_bus.h" | ||
32 | #include "../bus/cosm_bus.h" | 33 | #include "../bus/cosm_bus.h" |
33 | #include "mic_intr.h" | 34 | #include "mic_intr.h" |
34 | 35 | ||
@@ -68,6 +69,7 @@ extern struct cosm_hw_ops cosm_hw_ops; | |||
68 | * @dma_ch - Array of DMA channels | 69 | * @dma_ch - Array of DMA channels |
69 | * @num_dma_ch - Number of DMA channels available | 70 | * @num_dma_ch - Number of DMA channels available |
70 | * @scdev: SCIF device on the SCIF virtual bus. | 71 | * @scdev: SCIF device on the SCIF virtual bus. |
72 | * @vpdev: Virtio over PCIe device on the VOP virtual bus. | ||
71 | * @cosm_dev: COSM device | 73 | * @cosm_dev: COSM device |
72 | */ | 74 | */ |
73 | struct mic_device { | 75 | struct mic_device { |
@@ -92,6 +94,7 @@ struct mic_device { | |||
92 | struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; | 94 | struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; |
93 | int num_dma_ch; | 95 | int num_dma_ch; |
94 | struct scif_hw_dev *scdev; | 96 | struct scif_hw_dev *scdev; |
97 | struct vop_device *vpdev; | ||
95 | struct cosm_device *cosm_dev; | 98 | struct cosm_device *cosm_dev; |
96 | }; | 99 | }; |
97 | 100 | ||
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c index 400def2106e7..035be3e9ceba 100644 --- a/drivers/misc/mic/host/mic_main.c +++ b/drivers/misc/mic/host/mic_main.c | |||
@@ -317,6 +317,7 @@ static int __init mic_init(void) | |||
317 | { | 317 | { |
318 | int ret; | 318 | int ret; |
319 | 319 | ||
320 | request_module("mic_x100_dma"); | ||
320 | mic_init_debugfs(); | 321 | mic_init_debugfs(); |
321 | ida_init(&g_mic_ida); | 322 | ida_init(&g_mic_ida); |
322 | ret = pci_register_driver(&mic_driver); | 323 | ret = pci_register_driver(&mic_driver); |