aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/bmp085.c2
-rw-r--r--drivers/misc/cb710/core.c2
-rw-r--r--drivers/misc/eeprom/Kconfig13
-rw-r--r--drivers/misc/eeprom/Makefile1
-rw-r--r--drivers/misc/eeprom/sunxi_sid.c158
-rw-r--r--drivers/misc/ibmasm/module.c4
-rw-r--r--drivers/misc/mei/amthif.c33
-rw-r--r--drivers/misc/mei/client.c103
-rw-r--r--drivers/misc/mei/client.h9
-rw-r--r--drivers/misc/mei/hbm.c9
-rw-r--r--drivers/misc/mei/interrupt.c47
-rw-r--r--drivers/misc/mei/main.c28
-rw-r--r--drivers/misc/mei/pci-me.c1
-rw-r--r--drivers/misc/mic/Kconfig39
-rw-r--r--drivers/misc/mic/Makefile6
-rw-r--r--drivers/misc/mic/card/Makefile11
-rw-r--r--drivers/misc/mic/card/mic_debugfs.c130
-rw-r--r--drivers/misc/mic/card/mic_device.c306
-rw-r--r--drivers/misc/mic/card/mic_device.h133
-rw-r--r--drivers/misc/mic/card/mic_virtio.c631
-rw-r--r--drivers/misc/mic/card/mic_virtio.h77
-rw-r--r--drivers/misc/mic/card/mic_x100.c256
-rw-r--r--drivers/misc/mic/card/mic_x100.h48
-rw-r--r--drivers/misc/mic/common/mic_device.h51
-rw-r--r--drivers/misc/mic/host/Makefile14
-rw-r--r--drivers/misc/mic/host/mic_boot.c185
-rw-r--r--drivers/misc/mic/host/mic_debugfs.c495
-rw-r--r--drivers/misc/mic/host/mic_device.h195
-rw-r--r--drivers/misc/mic/host/mic_fops.c221
-rw-r--r--drivers/misc/mic/host/mic_fops.h32
-rw-r--r--drivers/misc/mic/host/mic_intr.c628
-rw-r--r--drivers/misc/mic/host/mic_intr.h137
-rw-r--r--drivers/misc/mic/host/mic_main.c478
-rw-r--r--drivers/misc/mic/host/mic_smpt.c442
-rw-r--r--drivers/misc/mic/host/mic_smpt.h98
-rw-r--r--drivers/misc/mic/host/mic_sysfs.c466
-rw-r--r--drivers/misc/mic/host/mic_virtio.c703
-rw-r--r--drivers/misc/mic/host/mic_virtio.h138
-rw-r--r--drivers/misc/mic/host/mic_x100.c573
-rw-r--r--drivers/misc/mic/host/mic_x100.h98
-rw-r--r--drivers/misc/pti.c1
-rw-r--r--drivers/misc/ti_dac7512.c23
-rw-r--r--drivers/misc/tifm_7xx1.c3
-rw-r--r--drivers/misc/vmw_vmci/vmci_guest.c2
46 files changed, 6929 insertions, 103 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"
537source "drivers/misc/altera-stapl/Kconfig" 537source "drivers/misc/altera-stapl/Kconfig"
538source "drivers/misc/mei/Kconfig" 538source "drivers/misc/mei/Kconfig"
539source "drivers/misc/vmw_vmci/Kconfig" 539source "drivers/misc/vmw_vmci/Kconfig"
540source "drivers/misc/mic/Kconfig"
540endmenu 541endmenu
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/
53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ 53obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o 54obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
55obj-$(CONFIG_SRAM) += sram.o 55obj-$(CONFIG_SRAM) += sram.o
56obj-y += mic/
diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c
index 849e2fed4da2..2704d885a9b3 100644
--- a/drivers/misc/bmp085.c
+++ b/drivers/misc/bmp085.c
@@ -374,7 +374,7 @@ int bmp085_detect(struct device *dev)
374} 374}
375EXPORT_SYMBOL_GPL(bmp085_detect); 375EXPORT_SYMBOL_GPL(bmp085_detect);
376 376
377static void __init bmp085_get_of_properties(struct bmp085_data *data) 377static void bmp085_get_of_properties(struct bmp085_data *data)
378{ 378{
379#ifdef CONFIG_OF 379#ifdef CONFIG_OF
380 struct device_node *np = data->dev->of_node; 380 struct device_node *np = data->dev->of_node;
diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c
index 2e50f811ff59..fb397e7d1cce 100644
--- a/drivers/misc/cb710/core.c
+++ b/drivers/misc/cb710/core.c
@@ -176,7 +176,7 @@ static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
176{ 176{
177 struct cb710_chip *chip = pci_get_drvdata(pdev); 177 struct cb710_chip *chip = pci_get_drvdata(pdev);
178 178
179 free_irq(pdev->irq, chip); 179 devm_free_irq(&pdev->dev, pdev->irq, chip);
180 pci_save_state(pdev); 180 pci_save_state(pdev);
181 pci_disable_device(pdev); 181 pci_disable_device(pdev);
182 if (state.event & PM_EVENT_SLEEP) 182 if (state.event & PM_EVENT_SLEEP)
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index 04f2e1fa9dd1..9536852fd4c6 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -96,4 +96,17 @@ config EEPROM_DIGSY_MTC_CFG
96 96
97 If unsure, say N. 97 If unsure, say N.
98 98
99config EEPROM_SUNXI_SID
100 tristate "Allwinner sunxi security ID support"
101 depends on ARCH_SUNXI && SYSFS
102 help
103 This is a driver for the 'security ID' available on various Allwinner
104 devices.
105
106 Due to the potential risks involved with changing e-fuses,
107 this driver is read-only.
108
109 This driver can also be built as a module. If so, the module
110 will be called sunxi_sid.
111
99endmenu 112endmenu
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
index fc1e81d29267..9507aec95e94 100644
--- a/drivers/misc/eeprom/Makefile
+++ b/drivers/misc/eeprom/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
4obj-$(CONFIG_EEPROM_MAX6875) += max6875.o 4obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
5obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o 5obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
6obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o 6obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o
7obj-$(CONFIG_EEPROM_SUNXI_SID) += sunxi_sid.o
7obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o 8obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
diff --git a/drivers/misc/eeprom/sunxi_sid.c b/drivers/misc/eeprom/sunxi_sid.c
new file mode 100644
index 000000000000..9c34e5704304
--- /dev/null
+++ b/drivers/misc/eeprom/sunxi_sid.c
@@ -0,0 +1,158 @@
1/*
2 * Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl>
3 * http://www.linux-sunxi.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * This driver exposes the Allwinner security ID, efuses exported in byte-
16 * sized chunks.
17 */
18
19#include <linux/compiler.h>
20#include <linux/device.h>
21#include <linux/err.h>
22#include <linux/export.h>
23#include <linux/fs.h>
24#include <linux/init.h>
25#include <linux/io.h>
26#include <linux/kernel.h>
27#include <linux/kobject.h>
28#include <linux/module.h>
29#include <linux/of_device.h>
30#include <linux/platform_device.h>
31#include <linux/random.h>
32#include <linux/slab.h>
33#include <linux/stat.h>
34#include <linux/sysfs.h>
35#include <linux/types.h>
36
37#define DRV_NAME "sunxi-sid"
38
39struct sunxi_sid_data {
40 void __iomem *reg_base;
41 unsigned int keysize;
42};
43
44/* We read the entire key, due to a 32 bit read alignment requirement. Since we
45 * want to return the requested byte, this results in somewhat slower code and
46 * uses 4 times more reads as needed but keeps code simpler. Since the SID is
47 * only very rarely probed, this is not really an issue.
48 */
49static u8 sunxi_sid_read_byte(const struct sunxi_sid_data *sid_data,
50 const unsigned int offset)
51{
52 u32 sid_key;
53
54 if (offset >= sid_data->keysize)
55 return 0;
56
57 sid_key = ioread32be(sid_data->reg_base + round_down(offset, 4));
58 sid_key >>= (offset % 4) * 8;
59
60 return sid_key; /* Only return the last byte */
61}
62
63static ssize_t sid_read(struct file *fd, struct kobject *kobj,
64 struct bin_attribute *attr, char *buf,
65 loff_t pos, size_t size)
66{
67 struct platform_device *pdev;
68 struct sunxi_sid_data *sid_data;
69 int i;
70
71 pdev = to_platform_device(kobj_to_dev(kobj));
72 sid_data = platform_get_drvdata(pdev);
73
74 if (pos < 0 || pos >= sid_data->keysize)
75 return 0;
76 if (size > sid_data->keysize - pos)
77 size = sid_data->keysize - pos;
78
79 for (i = 0; i < size; i++)
80 buf[i] = sunxi_sid_read_byte(sid_data, pos + i);
81
82 return i;
83}
84
85static struct bin_attribute sid_bin_attr = {
86 .attr = { .name = "eeprom", .mode = S_IRUGO, },
87 .read = sid_read,
88};
89
90static int sunxi_sid_remove(struct platform_device *pdev)
91{
92 device_remove_bin_file(&pdev->dev, &sid_bin_attr);
93 dev_dbg(&pdev->dev, "driver unloaded\n");
94
95 return 0;
96}
97
98static const struct of_device_id sunxi_sid_of_match[] = {
99 { .compatible = "allwinner,sun4i-sid", .data = (void *)16},
100 { .compatible = "allwinner,sun7i-a20-sid", .data = (void *)512},
101 {/* sentinel */},
102};
103MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
104
105static int sunxi_sid_probe(struct platform_device *pdev)
106{
107 struct sunxi_sid_data *sid_data;
108 struct resource *res;
109 const struct of_device_id *of_dev_id;
110 u8 *entropy;
111 unsigned int i;
112
113 sid_data = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_sid_data),
114 GFP_KERNEL);
115 if (!sid_data)
116 return -ENOMEM;
117
118 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
119 sid_data->reg_base = devm_ioremap_resource(&pdev->dev, res);
120 if (IS_ERR(sid_data->reg_base))
121 return PTR_ERR(sid_data->reg_base);
122
123 of_dev_id = of_match_device(sunxi_sid_of_match, &pdev->dev);
124 if (!of_dev_id)
125 return -ENODEV;
126 sid_data->keysize = (int)of_dev_id->data;
127
128 platform_set_drvdata(pdev, sid_data);
129
130 sid_bin_attr.size = sid_data->keysize;
131 if (device_create_bin_file(&pdev->dev, &sid_bin_attr))
132 return -ENODEV;
133
134 entropy = kzalloc(sizeof(u8) * sid_data->keysize, GFP_KERNEL);
135 for (i = 0; i < sid_data->keysize; i++)
136 entropy[i] = sunxi_sid_read_byte(sid_data, i);
137 add_device_randomness(entropy, sid_data->keysize);
138 kfree(entropy);
139
140 dev_dbg(&pdev->dev, "loaded\n");
141
142 return 0;
143}
144
145static struct platform_driver sunxi_sid_driver = {
146 .probe = sunxi_sid_probe,
147 .remove = sunxi_sid_remove,
148 .driver = {
149 .name = DRV_NAME,
150 .owner = THIS_MODULE,
151 .of_match_table = sunxi_sid_of_match,
152 },
153};
154module_platform_driver(sunxi_sid_driver);
155
156MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>");
157MODULE_DESCRIPTION("Allwinner sunxi security id driver");
158MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index 0346d87c5fed..6b3bf9ab051d 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -153,7 +153,6 @@ error_ioremap:
153error_heartbeat: 153error_heartbeat:
154 ibmasm_event_buffer_exit(sp); 154 ibmasm_event_buffer_exit(sp);
155error_eventbuffer: 155error_eventbuffer:
156 pci_set_drvdata(pdev, NULL);
157 kfree(sp); 156 kfree(sp);
158error_kmalloc: 157error_kmalloc:
159 pci_release_regions(pdev); 158 pci_release_regions(pdev);
@@ -165,7 +164,7 @@ error_resources:
165 164
166static void ibmasm_remove_one(struct pci_dev *pdev) 165static void ibmasm_remove_one(struct pci_dev *pdev)
167{ 166{
168 struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); 167 struct service_processor *sp = pci_get_drvdata(pdev);
169 168
170 dbg("Unregistering UART\n"); 169 dbg("Unregistering UART\n");
171 ibmasm_unregister_uart(sp); 170 ibmasm_unregister_uart(sp);
@@ -182,7 +181,6 @@ static void ibmasm_remove_one(struct pci_dev *pdev)
182 ibmasm_free_remote_input_dev(sp); 181 ibmasm_free_remote_input_dev(sp);
183 iounmap(sp->base_address); 182 iounmap(sp->base_address);
184 ibmasm_event_buffer_exit(sp); 183 ibmasm_event_buffer_exit(sp);
185 pci_set_drvdata(pdev, NULL);
186 kfree(sp); 184 kfree(sp);
187 pci_release_regions(pdev); 185 pci_release_regions(pdev);
188 pci_disable_device(pdev); 186 pci_disable_device(pdev);
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index d0fdc134068a..04fd38567729 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -312,13 +312,13 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
312 mei_hdr.me_addr = dev->iamthif_cl.me_client_id; 312 mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
313 mei_hdr.reserved = 0; 313 mei_hdr.reserved = 0;
314 dev->iamthif_msg_buf_index += mei_hdr.length; 314 dev->iamthif_msg_buf_index += mei_hdr.length;
315 if (mei_write_message(dev, &mei_hdr, 315 ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
316 (unsigned char *)dev->iamthif_msg_buf)) 316 if (ret)
317 return -ENODEV; 317 return ret;
318 318
319 if (mei_hdr.msg_complete) { 319 if (mei_hdr.msg_complete) {
320 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) 320 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
321 return -ENODEV; 321 return -EIO;
322 dev->iamthif_flow_control_pending = true; 322 dev->iamthif_flow_control_pending = true;
323 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 323 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
324 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n"); 324 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
@@ -458,6 +458,16 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
458 struct mei_msg_hdr mei_hdr; 458 struct mei_msg_hdr mei_hdr;
459 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; 459 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
460 u32 msg_slots = mei_data2slots(len); 460 u32 msg_slots = mei_data2slots(len);
461 int rets;
462
463 rets = mei_cl_flow_ctrl_creds(cl);
464 if (rets < 0)
465 return rets;
466
467 if (rets == 0) {
468 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
469 return 0;
470 }
461 471
462 mei_hdr.host_addr = cl->host_client_id; 472 mei_hdr.host_addr = cl->host_client_id;
463 mei_hdr.me_addr = cl->me_client_id; 473 mei_hdr.me_addr = cl->me_client_id;
@@ -480,16 +490,17 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
480 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); 490 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
481 491
482 *slots -= msg_slots; 492 *slots -= msg_slots;
483 if (mei_write_message(dev, &mei_hdr, 493 rets = mei_write_message(dev, &mei_hdr,
484 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) { 494 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
485 dev->iamthif_state = MEI_IAMTHIF_IDLE; 495 if (rets) {
486 cl->status = -ENODEV; 496 dev->iamthif_state = MEI_IAMTHIF_IDLE;
487 list_del(&cb->list); 497 cl->status = rets;
488 return -ENODEV; 498 list_del(&cb->list);
499 return rets;
489 } 500 }
490 501
491 if (mei_cl_flow_ctrl_reduce(cl)) 502 if (mei_cl_flow_ctrl_reduce(cl))
492 return -ENODEV; 503 return -EIO;
493 504
494 dev->iamthif_msg_buf_index += mei_hdr.length; 505 dev->iamthif_msg_buf_index += mei_hdr.length;
495 cl->status = 0; 506 cl->status = 0;
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index e0684b4d9a08..fbd319c506e6 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -187,10 +187,14 @@ int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
187 */ 187 */
188int mei_cl_flush_queues(struct mei_cl *cl) 188int mei_cl_flush_queues(struct mei_cl *cl)
189{ 189{
190 struct mei_device *dev;
191
190 if (WARN_ON(!cl || !cl->dev)) 192 if (WARN_ON(!cl || !cl->dev))
191 return -EINVAL; 193 return -EINVAL;
192 194
193 dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n"); 195 dev = cl->dev;
196
197 cl_dbg(dev, cl, "remove list entry belonging to cl\n");
194 mei_io_list_flush(&cl->dev->read_list, cl); 198 mei_io_list_flush(&cl->dev->read_list, cl);
195 mei_io_list_flush(&cl->dev->write_list, cl); 199 mei_io_list_flush(&cl->dev->write_list, cl);
196 mei_io_list_flush(&cl->dev->write_waiting_list, cl); 200 mei_io_list_flush(&cl->dev->write_waiting_list, cl);
@@ -287,6 +291,12 @@ int mei_cl_link(struct mei_cl *cl, int id)
287 return -ENOENT; 291 return -ENOENT;
288 } 292 }
289 293
294 if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
295 dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
296 MEI_MAX_OPEN_HANDLE_COUNT);
297 return -ENOENT;
298 }
299
290 dev->open_handle_count++; 300 dev->open_handle_count++;
291 301
292 cl->host_client_id = id; 302 cl->host_client_id = id;
@@ -296,7 +306,7 @@ int mei_cl_link(struct mei_cl *cl, int id)
296 306
297 cl->state = MEI_FILE_INITIALIZING; 307 cl->state = MEI_FILE_INITIALIZING;
298 308
299 dev_dbg(&dev->pdev->dev, "link cl host id = %d\n", cl->host_client_id); 309 cl_dbg(dev, cl, "link cl\n");
300 return 0; 310 return 0;
301} 311}
302 312
@@ -308,7 +318,6 @@ int mei_cl_link(struct mei_cl *cl, int id)
308int mei_cl_unlink(struct mei_cl *cl) 318int mei_cl_unlink(struct mei_cl *cl)
309{ 319{
310 struct mei_device *dev; 320 struct mei_device *dev;
311 struct mei_cl *pos, *next;
312 321
313 /* don't shout on error exit path */ 322 /* don't shout on error exit path */
314 if (!cl) 323 if (!cl)
@@ -320,14 +329,10 @@ int mei_cl_unlink(struct mei_cl *cl)
320 329
321 dev = cl->dev; 330 dev = cl->dev;
322 331
323 list_for_each_entry_safe(pos, next, &dev->file_list, link) { 332 cl_dbg(dev, cl, "unlink client");
324 if (cl->host_client_id == pos->host_client_id) { 333
325 dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", 334 list_del_init(&cl->link);
326 pos->host_client_id, pos->me_client_id); 335
327 list_del_init(&pos->link);
328 break;
329 }
330 }
331 return 0; 336 return 0;
332} 337}
333 338
@@ -390,6 +395,8 @@ int mei_cl_disconnect(struct mei_cl *cl)
390 395
391 dev = cl->dev; 396 dev = cl->dev;
392 397
398 cl_dbg(dev, cl, "disconnecting");
399
393 if (cl->state != MEI_FILE_DISCONNECTING) 400 if (cl->state != MEI_FILE_DISCONNECTING)
394 return 0; 401 return 0;
395 402
@@ -402,13 +409,13 @@ int mei_cl_disconnect(struct mei_cl *cl)
402 dev->hbuf_is_ready = false; 409 dev->hbuf_is_ready = false;
403 if (mei_hbm_cl_disconnect_req(dev, cl)) { 410 if (mei_hbm_cl_disconnect_req(dev, cl)) {
404 rets = -ENODEV; 411 rets = -ENODEV;
405 dev_err(&dev->pdev->dev, "failed to disconnect.\n"); 412 cl_err(dev, cl, "failed to disconnect.\n");
406 goto free; 413 goto free;
407 } 414 }
408 mdelay(10); /* Wait for hardware disconnection ready */ 415 mdelay(10); /* Wait for hardware disconnection ready */
409 list_add_tail(&cb->list, &dev->ctrl_rd_list.list); 416 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
410 } else { 417 } else {
411 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); 418 cl_dbg(dev, cl, "add disconnect cb to control write list\n");
412 list_add_tail(&cb->list, &dev->ctrl_wr_list.list); 419 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
413 420
414 } 421 }
@@ -421,18 +428,17 @@ int mei_cl_disconnect(struct mei_cl *cl)
421 mutex_lock(&dev->device_lock); 428 mutex_lock(&dev->device_lock);
422 if (MEI_FILE_DISCONNECTED == cl->state) { 429 if (MEI_FILE_DISCONNECTED == cl->state) {
423 rets = 0; 430 rets = 0;
424 dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n"); 431 cl_dbg(dev, cl, "successfully disconnected from FW client.\n");
425 } else { 432 } else {
426 rets = -ENODEV; 433 rets = -ENODEV;
427 if (MEI_FILE_DISCONNECTED != cl->state) 434 if (MEI_FILE_DISCONNECTED != cl->state)
428 dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n"); 435 cl_err(dev, cl, "wrong status client disconnect.\n");
429 436
430 if (err) 437 if (err)
431 dev_dbg(&dev->pdev->dev, 438 cl_dbg(dev, cl, "wait failed disconnect err=%08x\n",
432 "wait failed disconnect err=%08x\n",
433 err); 439 err);
434 440
435 dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n"); 441 cl_err(dev, cl, "failed to disconnect from FW client.\n");
436 } 442 }
437 443
438 mei_io_list_flush(&dev->ctrl_rd_list, cl); 444 mei_io_list_flush(&dev->ctrl_rd_list, cl);
@@ -639,13 +645,12 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
639 return -ENODEV; 645 return -ENODEV;
640 646
641 if (cl->read_cb) { 647 if (cl->read_cb) {
642 dev_dbg(&dev->pdev->dev, "read is pending.\n"); 648 cl_dbg(dev, cl, "read is pending.\n");
643 return -EBUSY; 649 return -EBUSY;
644 } 650 }
645 i = mei_me_cl_by_id(dev, cl->me_client_id); 651 i = mei_me_cl_by_id(dev, cl->me_client_id);
646 if (i < 0) { 652 if (i < 0) {
647 dev_err(&dev->pdev->dev, "no such me client %d\n", 653 cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
648 cl->me_client_id);
649 return -ENODEV; 654 return -ENODEV;
650 } 655 }
651 656
@@ -664,6 +669,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
664 if (dev->hbuf_is_ready) { 669 if (dev->hbuf_is_ready) {
665 dev->hbuf_is_ready = false; 670 dev->hbuf_is_ready = false;
666 if (mei_hbm_cl_flow_control_req(dev, cl)) { 671 if (mei_hbm_cl_flow_control_req(dev, cl)) {
672 cl_err(dev, cl, "flow control send failed\n");
667 rets = -ENODEV; 673 rets = -ENODEV;
668 goto err; 674 goto err;
669 } 675 }
@@ -691,10 +697,32 @@ err:
691int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb, 697int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
692 s32 *slots, struct mei_cl_cb *cmpl_list) 698 s32 *slots, struct mei_cl_cb *cmpl_list)
693{ 699{
694 struct mei_device *dev = cl->dev; 700 struct mei_device *dev;
701 struct mei_msg_data *buf;
695 struct mei_msg_hdr mei_hdr; 702 struct mei_msg_hdr mei_hdr;
696 size_t len = cb->request_buffer.size - cb->buf_idx; 703 size_t len;
697 u32 msg_slots = mei_data2slots(len); 704 u32 msg_slots;
705 int rets;
706
707
708 if (WARN_ON(!cl || !cl->dev))
709 return -ENODEV;
710
711 dev = cl->dev;
712
713 buf = &cb->request_buffer;
714
715 rets = mei_cl_flow_ctrl_creds(cl);
716 if (rets < 0)
717 return rets;
718
719 if (rets == 0) {
720 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
721 return 0;
722 }
723
724 len = buf->size - cb->buf_idx;
725 msg_slots = mei_data2slots(len);
698 726
699 mei_hdr.host_addr = cl->host_client_id; 727 mei_hdr.host_addr = cl->host_client_id;
700 mei_hdr.me_addr = cl->me_client_id; 728 mei_hdr.me_addr = cl->me_client_id;
@@ -714,16 +742,15 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
714 return 0; 742 return 0;
715 } 743 }
716 744
717 dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", 745 cl_dbg(dev, cl, "buf: size = %d idx = %lu\n",
718 cb->request_buffer.size, cb->buf_idx); 746 cb->request_buffer.size, cb->buf_idx);
719 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
720 747
721 *slots -= msg_slots; 748 *slots -= msg_slots;
722 if (mei_write_message(dev, &mei_hdr, 749 rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
723 cb->request_buffer.data + cb->buf_idx)) { 750 if (rets) {
724 cl->status = -ENODEV; 751 cl->status = rets;
725 list_move_tail(&cb->list, &cmpl_list->list); 752 list_move_tail(&cb->list, &cmpl_list->list);
726 return -ENODEV; 753 return rets;
727 } 754 }
728 755
729 cl->status = 0; 756 cl->status = 0;
@@ -732,7 +759,7 @@ int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
732 759
733 if (mei_hdr.msg_complete) { 760 if (mei_hdr.msg_complete) {
734 if (mei_cl_flow_ctrl_reduce(cl)) 761 if (mei_cl_flow_ctrl_reduce(cl))
735 return -ENODEV; 762 return -EIO;
736 list_move_tail(&cb->list, &dev->write_waiting_list.list); 763 list_move_tail(&cb->list, &dev->write_waiting_list.list);
737 } 764 }
738 765
@@ -767,7 +794,7 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
767 794
768 buf = &cb->request_buffer; 795 buf = &cb->request_buffer;
769 796
770 dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size); 797 cl_dbg(dev, cl, "mei_cl_write %d\n", buf->size);
771 798
772 799
773 cb->fop_type = MEI_FOP_WRITE; 800 cb->fop_type = MEI_FOP_WRITE;
@@ -800,14 +827,10 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
800 mei_hdr.me_addr = cl->me_client_id; 827 mei_hdr.me_addr = cl->me_client_id;
801 mei_hdr.reserved = 0; 828 mei_hdr.reserved = 0;
802 829
803 dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
804 MEI_HDR_PRM(&mei_hdr));
805
806 830
807 if (mei_write_message(dev, &mei_hdr, buf->data)) { 831 rets = mei_write_message(dev, &mei_hdr, buf->data);
808 rets = -EIO; 832 if (rets)
809 goto err; 833 goto err;
810 }
811 834
812 cl->writing_state = MEI_WRITING; 835 cl->writing_state = MEI_WRITING;
813 cb->buf_idx = mei_hdr.length; 836 cb->buf_idx = mei_hdr.length;
@@ -898,11 +921,11 @@ void mei_cl_all_wakeup(struct mei_device *dev)
898 struct mei_cl *cl, *next; 921 struct mei_cl *cl, *next;
899 list_for_each_entry_safe(cl, next, &dev->file_list, link) { 922 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
900 if (waitqueue_active(&cl->rx_wait)) { 923 if (waitqueue_active(&cl->rx_wait)) {
901 dev_dbg(&dev->pdev->dev, "Waking up reading client!\n"); 924 cl_dbg(dev, cl, "Waking up reading client!\n");
902 wake_up_interruptible(&cl->rx_wait); 925 wake_up_interruptible(&cl->rx_wait);
903 } 926 }
904 if (waitqueue_active(&cl->tx_wait)) { 927 if (waitqueue_active(&cl->tx_wait)) {
905 dev_dbg(&dev->pdev->dev, "Waking up writing client!\n"); 928 cl_dbg(dev, cl, "Waking up writing client!\n");
906 wake_up_interruptible(&cl->tx_wait); 929 wake_up_interruptible(&cl->tx_wait);
907 } 930 }
908 } 931 }
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
index 9eb031e92070..6374ed99e233 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -109,4 +109,13 @@ void mei_cl_all_disconnect(struct mei_device *dev);
109void mei_cl_all_wakeup(struct mei_device *dev); 109void mei_cl_all_wakeup(struct mei_device *dev);
110void mei_cl_all_write_clear(struct mei_device *dev); 110void mei_cl_all_write_clear(struct mei_device *dev);
111 111
112#define MEI_CL_FMT "cl:host=%02d me=%02d "
113#define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id
114
115#define cl_dbg(dev, cl, format, arg...) \
116 dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
117
118#define cl_err(dev, cl, format, arg...) \
119 dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
120
112#endif /* _MEI_CLIENT_H_ */ 121#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 6127ab64bb39..f1c974a0bc0d 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -45,7 +45,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
45 kfree(dev->me_clients); 45 kfree(dev->me_clients);
46 dev->me_clients = NULL; 46 dev->me_clients = NULL;
47 47
48 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", 48 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
49 dev->me_clients_num * sizeof(struct mei_me_client)); 49 dev->me_clients_num * sizeof(struct mei_me_client));
50 /* allocate storage for ME clients representation */ 50 /* allocate storage for ME clients representation */
51 clients = kcalloc(dev->me_clients_num, 51 clients = kcalloc(dev->me_clients_num,
@@ -170,7 +170,7 @@ int mei_hbm_start_req(struct mei_device *dev)
170 dev_err(&dev->pdev->dev, "version message write failed\n"); 170 dev_err(&dev->pdev->dev, "version message write failed\n");
171 dev->dev_state = MEI_DEV_RESETTING; 171 dev->dev_state = MEI_DEV_RESETTING;
172 mei_reset(dev, 1); 172 mei_reset(dev, 1);
173 return -ENODEV; 173 return -EIO;
174 } 174 }
175 dev->hbm_state = MEI_HBM_START; 175 dev->hbm_state = MEI_HBM_START;
176 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 176 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
@@ -673,7 +673,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
673 673
674 case HOST_ENUM_RES_CMD: 674 case HOST_ENUM_RES_CMD:
675 enum_res = (struct hbm_host_enum_response *) mei_msg; 675 enum_res = (struct hbm_host_enum_response *) mei_msg;
676 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 676 BUILD_BUG_ON(sizeof(dev->me_clients_map)
677 < sizeof(enum_res->valid_addresses));
678 memcpy(dev->me_clients_map, enum_res->valid_addresses,
679 sizeof(enum_res->valid_addresses));
677 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 680 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
678 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { 681 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
679 dev->init_clients_timer = 0; 682 dev->init_clients_timer = 0;
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 4b59cb742dee..7a95c07e59a6 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -113,13 +113,13 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
113 113
114 if (cb->response_buffer.size == 0 || 114 if (cb->response_buffer.size == 0 ||
115 cb->response_buffer.data == NULL) { 115 cb->response_buffer.data == NULL) {
116 dev_err(&dev->pdev->dev, "response buffer is not allocated.\n"); 116 cl_err(dev, cl, "response buffer is not allocated.\n");
117 list_del(&cb->list); 117 list_del(&cb->list);
118 return -ENOMEM; 118 return -ENOMEM;
119 } 119 }
120 120
121 if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) { 121 if (cb->response_buffer.size < mei_hdr->length + cb->buf_idx) {
122 dev_dbg(&dev->pdev->dev, "message overflow. size %d len %d idx %ld\n", 122 cl_dbg(dev, cl, "message overflow. size %d len %d idx %ld\n",
123 cb->response_buffer.size, 123 cb->response_buffer.size,
124 mei_hdr->length, cb->buf_idx); 124 mei_hdr->length, cb->buf_idx);
125 buffer = krealloc(cb->response_buffer.data, 125 buffer = krealloc(cb->response_buffer.data,
@@ -127,7 +127,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
127 GFP_KERNEL); 127 GFP_KERNEL);
128 128
129 if (!buffer) { 129 if (!buffer) {
130 dev_err(&dev->pdev->dev, "allocation failed.\n"); 130 cl_err(dev, cl, "allocation failed.\n");
131 list_del(&cb->list); 131 list_del(&cb->list);
132 return -ENOMEM; 132 return -ENOMEM;
133 } 133 }
@@ -143,9 +143,7 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
143 if (mei_hdr->msg_complete) { 143 if (mei_hdr->msg_complete) {
144 cl->status = 0; 144 cl->status = 0;
145 list_del(&cb->list); 145 list_del(&cb->list);
146 dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", 146 cl_dbg(dev, cl, "completed read length = %lu\n",
147 cl->host_client_id,
148 cl->me_client_id,
149 cb->buf_idx); 147 cb->buf_idx);
150 list_add_tail(&cb->list, &complete_list->list); 148 list_add_tail(&cb->list, &complete_list->list);
151 } 149 }
@@ -218,9 +216,11 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
218 s32 *slots, struct mei_cl_cb *cmpl_list) 216 s32 *slots, struct mei_cl_cb *cmpl_list)
219{ 217{
220 struct mei_device *dev = cl->dev; 218 struct mei_device *dev = cl->dev;
221
222 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control)); 219 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
223 220
221 int ret;
222
223
224 if (*slots < msg_slots) { 224 if (*slots < msg_slots) {
225 /* return the cancel routine */ 225 /* return the cancel routine */
226 list_del(&cb->list); 226 list_del(&cb->list);
@@ -229,12 +229,14 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
229 229
230 *slots -= msg_slots; 230 *slots -= msg_slots;
231 231
232 if (mei_hbm_cl_flow_control_req(dev, cl)) { 232 ret = mei_hbm_cl_flow_control_req(dev, cl);
233 cl->status = -ENODEV; 233 if (ret) {
234 cl->status = ret;
234 cb->buf_idx = 0; 235 cb->buf_idx = 0;
235 list_move_tail(&cb->list, &cmpl_list->list); 236 list_move_tail(&cb->list, &cmpl_list->list);
236 return -ENODEV; 237 return ret;
237 } 238 }
239
238 list_move_tail(&cb->list, &dev->read_list.list); 240 list_move_tail(&cb->list, &dev->read_list.list);
239 241
240 return 0; 242 return 0;
@@ -256,6 +258,7 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
256 s32 *slots, struct mei_cl_cb *cmpl_list) 258 s32 *slots, struct mei_cl_cb *cmpl_list)
257{ 259{
258 struct mei_device *dev = cl->dev; 260 struct mei_device *dev = cl->dev;
261 int ret;
259 262
260 u32 msg_slots = 263 u32 msg_slots =
261 mei_data2slots(sizeof(struct hbm_client_connect_request)); 264 mei_data2slots(sizeof(struct hbm_client_connect_request));
@@ -270,11 +273,12 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
270 273
271 cl->state = MEI_FILE_CONNECTING; 274 cl->state = MEI_FILE_CONNECTING;
272 275
273 if (mei_hbm_cl_connect_req(dev, cl)) { 276 ret = mei_hbm_cl_connect_req(dev, cl);
274 cl->status = -ENODEV; 277 if (ret) {
278 cl->status = ret;
275 cb->buf_idx = 0; 279 cb->buf_idx = 0;
276 list_del(&cb->list); 280 list_del(&cb->list);
277 return -ENODEV; 281 return ret;
278 } 282 }
279 283
280 list_move_tail(&cb->list, &dev->ctrl_rd_list.list); 284 list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
@@ -345,14 +349,14 @@ int mei_irq_read_handler(struct mei_device *dev,
345 349
346 /* decide where to read the message too */ 350 /* decide where to read the message too */
347 if (!mei_hdr->host_addr) { 351 if (!mei_hdr->host_addr) {
348 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n"); 352 dev_dbg(&dev->pdev->dev, "call mei_hbm_dispatch.\n");
349 mei_hbm_dispatch(dev, mei_hdr); 353 mei_hbm_dispatch(dev, mei_hdr);
350 dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n"); 354 dev_dbg(&dev->pdev->dev, "end mei_hbm_dispatch.\n");
351 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id && 355 } else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
352 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) && 356 (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
353 (dev->iamthif_state == MEI_IAMTHIF_READING)) { 357 (dev->iamthif_state == MEI_IAMTHIF_READING)) {
354 358
355 dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); 359 dev_dbg(&dev->pdev->dev, "call mei_amthif_irq_read_msg.\n");
356 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr)); 360 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(mei_hdr));
357 361
358 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list); 362 ret = mei_amthif_irq_read_msg(dev, mei_hdr, cmpl_list);
@@ -423,12 +427,12 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
423 if (MEI_WRITING == cl->writing_state && 427 if (MEI_WRITING == cl->writing_state &&
424 cb->fop_type == MEI_FOP_WRITE && 428 cb->fop_type == MEI_FOP_WRITE &&
425 cl != &dev->iamthif_cl) { 429 cl != &dev->iamthif_cl) {
426 dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); 430 cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
427 cl->writing_state = MEI_WRITE_COMPLETE; 431 cl->writing_state = MEI_WRITE_COMPLETE;
428 list_add_tail(&cb->list, &cmpl_list->list); 432 list_add_tail(&cb->list, &cmpl_list->list);
429 } 433 }
430 if (cl == &dev->iamthif_cl) { 434 if (cl == &dev->iamthif_cl) {
431 dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); 435 cl_dbg(dev, cl, "check iamthif flow control.\n");
432 if (dev->iamthif_flow_control_pending) { 436 if (dev->iamthif_flow_control_pending) {
433 ret = mei_amthif_irq_read(dev, &slots); 437 ret = mei_amthif_irq_read(dev, &slots);
434 if (ret) 438 if (ret)
@@ -509,13 +513,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
509 cl = cb->cl; 513 cl = cb->cl;
510 if (cl == NULL) 514 if (cl == NULL)
511 continue; 515 continue;
512 if (mei_cl_flow_ctrl_creds(cl) <= 0) {
513 dev_dbg(&dev->pdev->dev,
514 "No flow control credentials for client %d, not sending.\n",
515 cl->host_client_id);
516 continue;
517 }
518
519 if (cl == &dev->iamthif_cl) 516 if (cl == &dev->iamthif_cl)
520 ret = mei_amthif_irq_write_complete(cl, cb, 517 ret = mei_amthif_irq_write_complete(cl, cb,
521 &slots, cmpl_list); 518 &slots, cmpl_list);
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 173ff095be0d..9aa3b78067d3 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -165,10 +165,7 @@ static int mei_release(struct inode *inode, struct file *file)
165 165
166 file->private_data = NULL; 166 file->private_data = NULL;
167 167
168 if (cb) { 168 mei_io_cb_free(cb);
169 mei_io_cb_free(cb);
170 cb = NULL;
171 }
172 169
173 kfree(cl); 170 kfree(cl);
174out: 171out:
@@ -203,12 +200,18 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
203 200
204 dev = cl->dev; 201 dev = cl->dev;
205 202
203
206 mutex_lock(&dev->device_lock); 204 mutex_lock(&dev->device_lock);
207 if (dev->dev_state != MEI_DEV_ENABLED) { 205 if (dev->dev_state != MEI_DEV_ENABLED) {
208 rets = -ENODEV; 206 rets = -ENODEV;
209 goto out; 207 goto out;
210 } 208 }
211 209
210 if (length == 0) {
211 rets = 0;
212 goto out;
213 }
214
212 if (cl == &dev->iamthif_cl) { 215 if (cl == &dev->iamthif_cl) {
213 rets = mei_amthif_read(dev, file, ubuf, length, offset); 216 rets = mei_amthif_read(dev, file, ubuf, length, offset);
214 goto out; 217 goto out;
@@ -350,8 +353,14 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
350 rets = -ENODEV; 353 rets = -ENODEV;
351 goto out; 354 goto out;
352 } 355 }
353 if (length > dev->me_clients[id].props.max_msg_length || length <= 0) { 356
354 rets = -EMSGSIZE; 357 if (length == 0) {
358 rets = 0;
359 goto out;
360 }
361
362 if (length > dev->me_clients[id].props.max_msg_length) {
363 rets = -EFBIG;
355 goto out; 364 goto out;
356 } 365 }
357 366
@@ -404,8 +413,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
404 goto out; 413 goto out;
405 414
406 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); 415 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
407 if (rets) 416 if (rets) {
417 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
418 rets = -EFAULT;
408 goto out; 419 goto out;
420 }
409 421
410 if (cl == &dev->iamthif_cl) { 422 if (cl == &dev->iamthif_cl) {
411 rets = mei_amthif_write(dev, write_cb); 423 rets = mei_amthif_write(dev, write_cb);
@@ -567,7 +579,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
567 dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); 579 dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
568 if (copy_from_user(connect_data, (char __user *)data, 580 if (copy_from_user(connect_data, (char __user *)data,
569 sizeof(struct mei_connect_client_data))) { 581 sizeof(struct mei_connect_client_data))) {
570 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); 582 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
571 rets = -EFAULT; 583 rets = -EFAULT;
572 goto out; 584 goto out;
573 } 585 }
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 1b3844e82379..1b8a4c6d0cf8 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -239,7 +239,6 @@ static void mei_me_remove(struct pci_dev *pdev)
239 239
240 free_irq(pdev->irq, dev); 240 free_irq(pdev->irq, dev);
241 pci_disable_msi(pdev); 241 pci_disable_msi(pdev);
242 pci_set_drvdata(pdev, NULL);
243 242
244 if (hw->mem_addr) 243 if (hw->mem_addr)
245 pci_iounmap(pdev, hw->mem_addr); 244 pci_iounmap(pdev, hw->mem_addr);
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig
new file mode 100644
index 000000000000..d453768e9cee
--- /dev/null
+++ b/drivers/misc/mic/Kconfig
@@ -0,0 +1,39 @@
1comment "Intel MIC Host Driver"
2
3config INTEL_MIC_HOST
4 tristate "Intel MIC Host Driver"
5 depends on 64BIT && PCI
6 select VHOST_RING
7 default N
8 help
9 This enables Host Driver support for the Intel Many Integrated
10 Core (MIC) family of PCIe form factor coprocessor devices that
11 run a 64 bit Linux OS. The driver manages card OS state and
12 enables communication between host and card. Intel MIC X100
13 devices are currently supported.
14
15 If you are building a host kernel with an Intel MIC device then
16 say M (recommended) or Y, else say N. If unsure say N.
17
18 More information about the Intel MIC family as well as the Linux
19 OS and tools for MIC to use with this driver are available from
20 <http://software.intel.com/en-us/mic-developer>.
21
22comment "Intel MIC Card Driver"
23
24config INTEL_MIC_CARD
25 tristate "Intel MIC Card Driver"
26 depends on 64BIT
27 select VIRTIO
28 default N
29 help
30 This enables card driver support for the Intel Many Integrated
31 Core (MIC) device family. The card driver communicates shutdown/
32 crash events to the host and allows registration/configuration of
33 virtio devices. Intel MIC X100 devices are currently supported.
34
35 If you are building a card kernel for an Intel MIC device then
36 say M (recommended) or Y, else say N. If unsure say N.
37
38 For more information see
39 <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..05b34d683a58
--- /dev/null
+++ b/drivers/misc/mic/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5obj-$(CONFIG_INTEL_MIC_HOST) += host/
6obj-$(CONFIG_INTEL_MIC_CARD) += card/
diff --git a/drivers/misc/mic/card/Makefile b/drivers/misc/mic/card/Makefile
new file mode 100644
index 000000000000..69d58bef92ce
--- /dev/null
+++ b/drivers/misc/mic/card/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5ccflags-y += -DINTEL_MIC_CARD
6
7obj-$(CONFIG_INTEL_MIC_CARD) += mic_card.o
8mic_card-y += mic_x100.o
9mic_card-y += mic_device.o
10mic_card-y += mic_debugfs.o
11mic_card-y += mic_virtio.o
diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c
new file mode 100644
index 000000000000..95cf186ff73a
--- /dev/null
+++ b/drivers/misc/mic/card/mic_debugfs.c
@@ -0,0 +1,130 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/debugfs.h>
28#include <linux/delay.h>
29#include <linux/seq_file.h>
30#include <linux/interrupt.h>
31#include <linux/device.h>
32
33#include "../common/mic_device.h"
34#include "mic_device.h"
35
36/* Debugfs parent dir */
37static struct dentry *mic_dbg;
38
39/**
40 * mic_intr_test - Send interrupts to host.
41 */
42static int mic_intr_test(struct seq_file *s, void *unused)
43{
44 struct mic_driver *mdrv = s->private;
45 struct mic_device *mdev = &mdrv->mdev;
46
47 mic_send_intr(mdev, 0);
48 msleep(1000);
49 mic_send_intr(mdev, 1);
50 msleep(1000);
51 mic_send_intr(mdev, 2);
52 msleep(1000);
53 mic_send_intr(mdev, 3);
54 msleep(1000);
55
56 return 0;
57}
58
59static int mic_intr_test_open(struct inode *inode, struct file *file)
60{
61 return single_open(file, mic_intr_test, inode->i_private);
62}
63
64static int mic_intr_test_release(struct inode *inode, struct file *file)
65{
66 return single_release(inode, file);
67}
68
69static const struct file_operations intr_test_ops = {
70 .owner = THIS_MODULE,
71 .open = mic_intr_test_open,
72 .read = seq_read,
73 .llseek = seq_lseek,
74 .release = mic_intr_test_release
75};
76
77/**
78 * mic_create_card_debug_dir - Initialize MIC debugfs entries.
79 */
80void __init mic_create_card_debug_dir(struct mic_driver *mdrv)
81{
82 struct dentry *d;
83
84 if (!mic_dbg)
85 return;
86
87 mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg);
88 if (!mdrv->dbg_dir) {
89 dev_err(mdrv->dev, "Cant create dbg_dir %s\n", mdrv->name);
90 return;
91 }
92
93 d = debugfs_create_file("intr_test", 0444, mdrv->dbg_dir,
94 mdrv, &intr_test_ops);
95
96 if (!d) {
97 dev_err(mdrv->dev,
98 "Cant create dbg intr_test %s\n", mdrv->name);
99 return;
100 }
101}
102
103/**
104 * mic_delete_card_debug_dir - Uninitialize MIC debugfs entries.
105 */
106void mic_delete_card_debug_dir(struct mic_driver *mdrv)
107{
108 if (!mdrv->dbg_dir)
109 return;
110
111 debugfs_remove_recursive(mdrv->dbg_dir);
112}
113
114/**
115 * mic_init_card_debugfs - Initialize global debugfs entry.
116 */
117void __init mic_init_card_debugfs(void)
118{
119 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
120 if (!mic_dbg)
121 pr_err("can't create debugfs dir\n");
122}
123
124/**
125 * mic_exit_card_debugfs - Uninitialize global debugfs entry
126 */
127void mic_exit_card_debugfs(void)
128{
129 debugfs_remove(mic_dbg);
130}
diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c
new file mode 100644
index 000000000000..4125217579af
--- /dev/null
+++ b/drivers/misc/mic/card/mic_device.c
@@ -0,0 +1,306 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/interrupt.h>
30#include <linux/reboot.h>
31
32#include <linux/mic_common.h>
33#include "../common/mic_device.h"
34#include "mic_device.h"
35#include "mic_virtio.h"
36
37static struct mic_driver *g_drv;
38static struct mic_irq *shutdown_cookie;
39
40static void mic_notify_host(u8 state)
41{
42 struct mic_driver *mdrv = g_drv;
43 struct mic_bootparam __iomem *bootparam = mdrv->dp;
44
45 iowrite8(state, &bootparam->shutdown_status);
46 dev_dbg(mdrv->dev, "%s %d system_state %d\n",
47 __func__, __LINE__, state);
48 mic_send_intr(&mdrv->mdev, ioread8(&bootparam->c2h_shutdown_db));
49}
50
51static int mic_panic_event(struct notifier_block *this, unsigned long event,
52 void *ptr)
53{
54 struct mic_driver *mdrv = g_drv;
55 struct mic_bootparam __iomem *bootparam = mdrv->dp;
56
57 iowrite8(-1, &bootparam->h2c_config_db);
58 iowrite8(-1, &bootparam->h2c_shutdown_db);
59 mic_notify_host(MIC_CRASHED);
60 return NOTIFY_DONE;
61}
62
63static struct notifier_block mic_panic = {
64 .notifier_call = mic_panic_event,
65};
66
67static irqreturn_t mic_shutdown_isr(int irq, void *data)
68{
69 struct mic_driver *mdrv = g_drv;
70 struct mic_bootparam __iomem *bootparam = mdrv->dp;
71
72 mic_ack_interrupt(&g_drv->mdev);
73 if (ioread8(&bootparam->shutdown_card))
74 orderly_poweroff(true);
75 return IRQ_HANDLED;
76}
77
78static int mic_shutdown_init(void)
79{
80 int rc = 0;
81 struct mic_driver *mdrv = g_drv;
82 struct mic_bootparam __iomem *bootparam = mdrv->dp;
83 int shutdown_db;
84
85 shutdown_db = mic_next_card_db();
86 shutdown_cookie = mic_request_card_irq(mic_shutdown_isr,
87 "Shutdown", mdrv, shutdown_db);
88 if (IS_ERR(shutdown_cookie))
89 rc = PTR_ERR(shutdown_cookie);
90 else
91 iowrite8(shutdown_db, &bootparam->h2c_shutdown_db);
92 return rc;
93}
94
95static void mic_shutdown_uninit(void)
96{
97 struct mic_driver *mdrv = g_drv;
98 struct mic_bootparam __iomem *bootparam = mdrv->dp;
99
100 iowrite8(-1, &bootparam->h2c_shutdown_db);
101 mic_free_card_irq(shutdown_cookie, mdrv);
102}
103
104static int __init mic_dp_init(void)
105{
106 struct mic_driver *mdrv = g_drv;
107 struct mic_device *mdev = &mdrv->mdev;
108 struct mic_bootparam __iomem *bootparam;
109 u64 lo, hi, dp_dma_addr;
110 u32 magic;
111
112 lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD);
113 hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD);
114
115 dp_dma_addr = lo | (hi << 32);
116 mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE);
117 if (!mdrv->dp) {
118 dev_err(mdrv->dev, "Cannot remap Aperture BAR\n");
119 return -ENOMEM;
120 }
121 bootparam = mdrv->dp;
122 magic = ioread32(&bootparam->magic);
123 if (MIC_MAGIC != magic) {
124 dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic);
125 return -EIO;
126 }
127 return 0;
128}
129
130/* Uninitialize the device page */
131static void mic_dp_uninit(void)
132{
133 mic_card_unmap(&g_drv->mdev, g_drv->dp);
134}
135
136/**
137 * mic_request_card_irq - request an irq.
138 *
139 * @func: The callback function that handles the interrupt.
140 * @name: The ASCII name of the callee requesting the irq.
141 * @data: private data that is returned back when calling the
142 * function handler.
143 * @index: The doorbell index of the requester.
144 *
145 * returns: The cookie that is transparent to the caller. Passed
146 * back when calling mic_free_irq. An appropriate error code
147 * is returned on failure. Caller needs to use IS_ERR(return_val)
148 * to check for failure and PTR_ERR(return_val) to obtained the
149 * error code.
150 *
151 */
152struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
153 const char *name, void *data, int index)
154{
155 int rc = 0;
156 unsigned long cookie;
157 struct mic_driver *mdrv = g_drv;
158
159 rc = request_irq(mic_db_to_irq(mdrv, index), func,
160 0, name, data);
161 if (rc) {
162 dev_err(mdrv->dev, "request_irq failed rc = %d\n", rc);
163 goto err;
164 }
165 mdrv->irq_info.irq_usage_count[index]++;
166 cookie = index;
167 return (struct mic_irq *)cookie;
168err:
169 return ERR_PTR(rc);
170
171}
172
173/**
174 * mic_free_card_irq - free irq.
175 *
176 * @cookie: cookie obtained during a successful call to mic_request_irq
177 * @data: private data specified by the calling function during the
178 * mic_request_irq
179 *
180 * returns: none.
181 */
182void mic_free_card_irq(struct mic_irq *cookie, void *data)
183{
184 int index;
185 struct mic_driver *mdrv = g_drv;
186
187 index = (unsigned long)cookie & 0xFFFFU;
188 free_irq(mic_db_to_irq(mdrv, index), data);
189 mdrv->irq_info.irq_usage_count[index]--;
190}
191
192/**
193 * mic_next_card_db - Get the doorbell with minimum usage count.
194 *
195 * Returns the irq index.
196 */
197int mic_next_card_db(void)
198{
199 int i;
200 int index = 0;
201 struct mic_driver *mdrv = g_drv;
202
203 for (i = 0; i < mdrv->intr_info.num_intr; i++) {
204 if (mdrv->irq_info.irq_usage_count[i] <
205 mdrv->irq_info.irq_usage_count[index])
206 index = i;
207 }
208
209 return index;
210}
211
212/**
213 * mic_init_irq - Initialize irq information.
214 *
215 * Returns 0 in success. Appropriate error code on failure.
216 */
217static int mic_init_irq(void)
218{
219 struct mic_driver *mdrv = g_drv;
220
221 mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
222 mdrv->intr_info.num_intr),
223 GFP_KERNEL);
224 if (!mdrv->irq_info.irq_usage_count)
225 return -ENOMEM;
226 return 0;
227}
228
229/**
230 * mic_uninit_irq - Uninitialize irq information.
231 *
232 * None.
233 */
234static void mic_uninit_irq(void)
235{
236 struct mic_driver *mdrv = g_drv;
237
238 kfree(mdrv->irq_info.irq_usage_count);
239}
240
241/*
242 * mic_driver_init - MIC driver initialization tasks.
243 *
244 * Returns 0 in success. Appropriate error code on failure.
245 */
246int __init mic_driver_init(struct mic_driver *mdrv)
247{
248 int rc;
249
250 g_drv = mdrv;
251 /*
252 * Unloading the card module is not supported. The MIC card module
253 * handles fundamental operations like host/card initiated shutdowns
254 * and informing the host about card crashes and cannot be unloaded.
255 */
256 if (!try_module_get(mdrv->dev->driver->owner)) {
257 rc = -ENODEV;
258 goto done;
259 }
260 rc = mic_dp_init();
261 if (rc)
262 goto put;
263 rc = mic_init_irq();
264 if (rc)
265 goto dp_uninit;
266 rc = mic_shutdown_init();
267 if (rc)
268 goto irq_uninit;
269 rc = mic_devices_init(mdrv);
270 if (rc)
271 goto shutdown_uninit;
272 mic_create_card_debug_dir(mdrv);
273 atomic_notifier_chain_register(&panic_notifier_list, &mic_panic);
274done:
275 return rc;
276shutdown_uninit:
277 mic_shutdown_uninit();
278irq_uninit:
279 mic_uninit_irq();
280dp_uninit:
281 mic_dp_uninit();
282put:
283 module_put(mdrv->dev->driver->owner);
284 return rc;
285}
286
287/*
288 * mic_driver_uninit - MIC driver uninitialization tasks.
289 *
290 * Returns None
291 */
292void mic_driver_uninit(struct mic_driver *mdrv)
293{
294 mic_delete_card_debug_dir(mdrv);
295 mic_devices_uninit(mdrv);
296 /*
297 * Inform the host about the shutdown status i.e. poweroff/restart etc.
298 * The module cannot be unloaded so the only code path to call
299 * mic_devices_uninit(..) is the shutdown callback.
300 */
301 mic_notify_host(system_state);
302 mic_shutdown_uninit();
303 mic_uninit_irq();
304 mic_dp_uninit();
305 module_put(mdrv->dev->driver->owner);
306}
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h
new file mode 100644
index 000000000000..347b9b3b7916
--- /dev/null
+++ b/drivers/misc/mic/card/mic_device.h
@@ -0,0 +1,133 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef _MIC_CARD_DEVICE_H_
28#define _MIC_CARD_DEVICE_H_
29
30#include <linux/workqueue.h>
31#include <linux/io.h>
32
33/**
34 * struct mic_intr_info - Contains h/w specific interrupt sources info
35 *
36 * @num_intr: The number of irqs available
37 */
38struct mic_intr_info {
39 u32 num_intr;
40};
41
42/**
43 * struct mic_irq_info - OS specific irq information
44 *
45 * @irq_usage_count: usage count array tracking the number of sources
46 * assigned for each irq.
47 */
48struct mic_irq_info {
49 int *irq_usage_count;
50};
51
52/**
53 * struct mic_device - MIC device information.
54 *
55 * @mmio: MMIO bar information.
56 */
57struct mic_device {
58 struct mic_mw mmio;
59};
60
61/**
62 * struct mic_driver - MIC card driver information.
63 *
64 * @name: Name for MIC driver.
65 * @dbg_dir: debugfs directory of this MIC device.
66 * @dev: The device backing this MIC.
67 * @dp: The pointer to the virtio device page.
68 * @mdev: MIC device information for the host.
69 * @hotplug_work: Hot plug work for adding/removing virtio devices.
70 * @irq_info: The OS specific irq information
71 * @intr_info: H/W specific interrupt information.
72 */
73struct mic_driver {
74 char name[20];
75 struct dentry *dbg_dir;
76 struct device *dev;
77 void __iomem *dp;
78 struct mic_device mdev;
79 struct work_struct hotplug_work;
80 struct mic_irq_info irq_info;
81 struct mic_intr_info intr_info;
82};
83
84/**
85 * struct mic_irq - opaque pointer used as cookie
86 */
87struct mic_irq;
88
89/**
90 * mic_mmio_read - read from an MMIO register.
91 * @mw: MMIO register base virtual address.
92 * @offset: register offset.
93 *
94 * RETURNS: register value.
95 */
96static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
97{
98 return ioread32(mw->va + offset);
99}
100
101/**
102 * mic_mmio_write - write to an MMIO register.
103 * @mw: MMIO register base virtual address.
104 * @val: the data value to put into the register
105 * @offset: register offset.
106 *
107 * RETURNS: none.
108 */
109static inline void
110mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
111{
112 iowrite32(val, mw->va + offset);
113}
114
115int mic_driver_init(struct mic_driver *mdrv);
116void mic_driver_uninit(struct mic_driver *mdrv);
117int mic_next_card_db(void);
118struct mic_irq *mic_request_card_irq(irqreturn_t (*func)(int irq, void *data),
119 const char *name, void *data, int intr_src);
120void mic_free_card_irq(struct mic_irq *cookie, void *data);
121u32 mic_read_spad(struct mic_device *mdev, unsigned int idx);
122void mic_send_intr(struct mic_device *mdev, int doorbell);
123int mic_db_to_irq(struct mic_driver *mdrv, int db);
124u32 mic_ack_interrupt(struct mic_device *mdev);
125void mic_hw_intr_init(struct mic_driver *mdrv);
126void __iomem *
127mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size);
128void mic_card_unmap(struct mic_device *mdev, void __iomem *addr);
129void __init mic_create_card_debug_dir(struct mic_driver *mdrv);
130void mic_delete_card_debug_dir(struct mic_driver *mdrv);
131void __init mic_init_card_debugfs(void);
132void mic_exit_card_debugfs(void);
133#endif
diff --git a/drivers/misc/mic/card/mic_virtio.c b/drivers/misc/mic/card/mic_virtio.c
new file mode 100644
index 000000000000..38275c1b9e03
--- /dev/null
+++ b/drivers/misc/mic/card/mic_virtio.c
@@ -0,0 +1,631 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Adapted from:
25 *
26 * virtio for kvm on s390
27 *
28 * Copyright IBM Corp. 2008
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License (version 2 only)
32 * as published by the Free Software Foundation.
33 *
34 * Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
35 *
36 * Intel MIC Card driver.
37 *
38 */
39#include <linux/delay.h>
40#include <linux/slab.h>
41#include <linux/virtio_config.h>
42
43#include "../common/mic_device.h"
44#include "mic_virtio.h"
45
46#define VIRTIO_SUBCODE_64 0x0D00
47
48#define MIC_MAX_VRINGS 4
49struct mic_vdev {
50 struct virtio_device vdev;
51 struct mic_device_desc __iomem *desc;
52 struct mic_device_ctrl __iomem *dc;
53 struct mic_device *mdev;
54 void __iomem *vr[MIC_MAX_VRINGS];
55 int used_size[MIC_MAX_VRINGS];
56 struct completion reset_done;
57 struct mic_irq *virtio_cookie;
58 int c2h_vdev_db;
59};
60
61static struct mic_irq *virtio_config_cookie;
62#define to_micvdev(vd) container_of(vd, struct mic_vdev, vdev)
63
64/* Helper API to obtain the parent of the virtio device */
65static inline struct device *mic_dev(struct mic_vdev *mvdev)
66{
67 return mvdev->vdev.dev.parent;
68}
69
70/* This gets the device's feature bits. */
71static u32 mic_get_features(struct virtio_device *vdev)
72{
73 unsigned int i, bits;
74 u32 features = 0;
75 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
76 u8 __iomem *in_features = mic_vq_features(desc);
77 int feature_len = ioread8(&desc->feature_len);
78
79 bits = min_t(unsigned, feature_len,
80 sizeof(vdev->features)) * 8;
81 for (i = 0; i < bits; i++)
82 if (ioread8(&in_features[i / 8]) & (BIT(i % 8)))
83 features |= BIT(i);
84
85 return features;
86}
87
88static void mic_finalize_features(struct virtio_device *vdev)
89{
90 unsigned int i, bits;
91 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
92 u8 feature_len = ioread8(&desc->feature_len);
93 /* Second half of bitmap is features we accept. */
94 u8 __iomem *out_features =
95 mic_vq_features(desc) + feature_len;
96
97 /* Give virtio_ring a chance to accept features. */
98 vring_transport_features(vdev);
99
100 memset_io(out_features, 0, feature_len);
101 bits = min_t(unsigned, feature_len,
102 sizeof(vdev->features)) * 8;
103 for (i = 0; i < bits; i++) {
104 if (test_bit(i, vdev->features))
105 iowrite8(ioread8(&out_features[i / 8]) | (1 << (i % 8)),
106 &out_features[i / 8]);
107 }
108}
109
110/*
111 * Reading and writing elements in config space
112 */
113static void mic_get(struct virtio_device *vdev, unsigned int offset,
114 void *buf, unsigned len)
115{
116 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
117
118 if (offset + len > ioread8(&desc->config_len))
119 return;
120 memcpy_fromio(buf, mic_vq_configspace(desc) + offset, len);
121}
122
123static void mic_set(struct virtio_device *vdev, unsigned int offset,
124 const void *buf, unsigned len)
125{
126 struct mic_device_desc __iomem *desc = to_micvdev(vdev)->desc;
127
128 if (offset + len > ioread8(&desc->config_len))
129 return;
130 memcpy_toio(mic_vq_configspace(desc) + offset, buf, len);
131}
132
133/*
134 * The operations to get and set the status word just access the status
135 * field of the device descriptor. set_status also interrupts the host
136 * to tell about status changes.
137 */
138static u8 mic_get_status(struct virtio_device *vdev)
139{
140 return ioread8(&to_micvdev(vdev)->desc->status);
141}
142
143static void mic_set_status(struct virtio_device *vdev, u8 status)
144{
145 struct mic_vdev *mvdev = to_micvdev(vdev);
146 if (!status)
147 return;
148 iowrite8(status, &mvdev->desc->status);
149 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
150}
151
152/* Inform host on a virtio device reset and wait for ack from host */
153static void mic_reset_inform_host(struct virtio_device *vdev)
154{
155 struct mic_vdev *mvdev = to_micvdev(vdev);
156 struct mic_device_ctrl __iomem *dc = mvdev->dc;
157 int retry = 100, i;
158
159 iowrite8(0, &dc->host_ack);
160 iowrite8(1, &dc->vdev_reset);
161 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
162
163 /* Wait till host completes all card accesses and acks the reset */
164 for (i = retry; i--;) {
165 if (ioread8(&dc->host_ack))
166 break;
167 msleep(100);
168 };
169
170 dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
171
172 /* Reset status to 0 in case we timed out */
173 iowrite8(0, &mvdev->desc->status);
174}
175
176static void mic_reset(struct virtio_device *vdev)
177{
178 struct mic_vdev *mvdev = to_micvdev(vdev);
179
180 dev_dbg(mic_dev(mvdev), "%s: virtio id %d\n",
181 __func__, vdev->id.device);
182
183 mic_reset_inform_host(vdev);
184 complete_all(&mvdev->reset_done);
185}
186
187/*
188 * The virtio_ring code calls this API when it wants to notify the Host.
189 */
190static void mic_notify(struct virtqueue *vq)
191{
192 struct mic_vdev *mvdev = vq->priv;
193
194 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
195}
196
197static void mic_del_vq(struct virtqueue *vq, int n)
198{
199 struct mic_vdev *mvdev = to_micvdev(vq->vdev);
200 struct vring *vr = (struct vring *) (vq + 1);
201
202 free_pages((unsigned long) vr->used,
203 get_order(mvdev->used_size[n]));
204 vring_del_virtqueue(vq);
205 mic_card_unmap(mvdev->mdev, mvdev->vr[n]);
206 mvdev->vr[n] = NULL;
207}
208
209static void mic_del_vqs(struct virtio_device *vdev)
210{
211 struct mic_vdev *mvdev = to_micvdev(vdev);
212 struct virtqueue *vq, *n;
213 int idx = 0;
214
215 dev_dbg(mic_dev(mvdev), "%s\n", __func__);
216
217 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
218 mic_del_vq(vq, idx++);
219}
220
221/*
222 * This routine will assign vring's allocated in host/io memory. Code in
223 * virtio_ring.c however continues to access this io memory as if it were local
224 * memory without io accessors.
225 */
226static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
227 unsigned index,
228 void (*callback)(struct virtqueue *vq),
229 const char *name)
230{
231 struct mic_vdev *mvdev = to_micvdev(vdev);
232 struct mic_vqconfig __iomem *vqconfig;
233 struct mic_vqconfig config;
234 struct virtqueue *vq;
235 void __iomem *va;
236 struct _mic_vring_info __iomem *info;
237 void *used;
238 int vr_size, _vr_size, err, magic;
239 struct vring *vr;
240 u8 type = ioread8(&mvdev->desc->type);
241
242 if (index >= ioread8(&mvdev->desc->num_vq))
243 return ERR_PTR(-ENOENT);
244
245 if (!name)
246 return ERR_PTR(-ENOENT);
247
248 /* First assign the vring's allocated in host memory */
249 vqconfig = mic_vq_config(mvdev->desc) + index;
250 memcpy_fromio(&config, vqconfig, sizeof(config));
251 _vr_size = vring_size(config.num, MIC_VIRTIO_RING_ALIGN);
252 vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
253 va = mic_card_map(mvdev->mdev, config.address, vr_size);
254 if (!va)
255 return ERR_PTR(-ENOMEM);
256 mvdev->vr[index] = va;
257 memset_io(va, 0x0, _vr_size);
258 vq = vring_new_virtqueue(index,
259 config.num, MIC_VIRTIO_RING_ALIGN, vdev,
260 false,
261 va, mic_notify, callback, name);
262 if (!vq) {
263 err = -ENOMEM;
264 goto unmap;
265 }
266 info = va + _vr_size;
267 magic = ioread32(&info->magic);
268
269 if (WARN(magic != MIC_MAGIC + type + index, "magic mismatch")) {
270 err = -EIO;
271 goto unmap;
272 }
273
274 /* Allocate and reassign used ring now */
275 mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
276 sizeof(struct vring_used_elem) * config.num);
277 used = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
278 get_order(mvdev->used_size[index]));
279 if (!used) {
280 err = -ENOMEM;
281 dev_err(mic_dev(mvdev), "%s %d err %d\n",
282 __func__, __LINE__, err);
283 goto del_vq;
284 }
285 iowrite64(virt_to_phys(used), &vqconfig->used_address);
286
287 /*
288 * To reassign the used ring here we are directly accessing
289 * struct vring_virtqueue which is a private data structure
290 * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
291 * vring_new_virtqueue() would ensure that
292 * (&vq->vring == (struct vring *) (&vq->vq + 1));
293 */
294 vr = (struct vring *) (vq + 1);
295 vr->used = used;
296
297 vq->priv = mvdev;
298 return vq;
299del_vq:
300 vring_del_virtqueue(vq);
301unmap:
302 mic_card_unmap(mvdev->mdev, mvdev->vr[index]);
303 return ERR_PTR(err);
304}
305
306static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
307 struct virtqueue *vqs[],
308 vq_callback_t *callbacks[],
309 const char *names[])
310{
311 struct mic_vdev *mvdev = to_micvdev(vdev);
312 struct mic_device_ctrl __iomem *dc = mvdev->dc;
313 int i, err, retry = 100;
314
315 /* We must have this many virtqueues. */
316 if (nvqs > ioread8(&mvdev->desc->num_vq))
317 return -ENOENT;
318
319 for (i = 0; i < nvqs; ++i) {
320 dev_dbg(mic_dev(mvdev), "%s: %d: %s\n",
321 __func__, i, names[i]);
322 vqs[i] = mic_find_vq(vdev, i, callbacks[i], names[i]);
323 if (IS_ERR(vqs[i])) {
324 err = PTR_ERR(vqs[i]);
325 goto error;
326 }
327 }
328
329 iowrite8(1, &dc->used_address_updated);
330 /*
331 * Send an interrupt to the host to inform it that used
332 * rings have been re-assigned.
333 */
334 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
335 for (i = retry; i--;) {
336 if (!ioread8(&dc->used_address_updated))
337 break;
338 msleep(100);
339 };
340
341 dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
342 if (!retry) {
343 err = -ENODEV;
344 goto error;
345 }
346
347 return 0;
348error:
349 mic_del_vqs(vdev);
350 return err;
351}
352
353/*
354 * The config ops structure as defined by virtio config
355 */
356static struct virtio_config_ops mic_vq_config_ops = {
357 .get_features = mic_get_features,
358 .finalize_features = mic_finalize_features,
359 .get = mic_get,
360 .set = mic_set,
361 .get_status = mic_get_status,
362 .set_status = mic_set_status,
363 .reset = mic_reset,
364 .find_vqs = mic_find_vqs,
365 .del_vqs = mic_del_vqs,
366};
367
368static irqreturn_t
369mic_virtio_intr_handler(int irq, void *data)
370{
371 struct mic_vdev *mvdev = data;
372 struct virtqueue *vq;
373
374 mic_ack_interrupt(mvdev->mdev);
375 list_for_each_entry(vq, &mvdev->vdev.vqs, list)
376 vring_interrupt(0, vq);
377
378 return IRQ_HANDLED;
379}
380
381static void mic_virtio_release_dev(struct device *_d)
382{
383 /*
384 * No need for a release method similar to virtio PCI.
385 * Provide an empty one to avoid getting a warning from core.
386 */
387}
388
389/*
390 * adds a new device and register it with virtio
391 * appropriate drivers are loaded by the device model
392 */
393static int mic_add_device(struct mic_device_desc __iomem *d,
394 unsigned int offset, struct mic_driver *mdrv)
395{
396 struct mic_vdev *mvdev;
397 int ret;
398 int virtio_db;
399 u8 type = ioread8(&d->type);
400
401 mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
402 if (!mvdev) {
403 dev_err(mdrv->dev, "Cannot allocate mic dev %u type %u\n",
404 offset, type);
405 return -ENOMEM;
406 }
407
408 mvdev->mdev = &mdrv->mdev;
409 mvdev->vdev.dev.parent = mdrv->dev;
410 mvdev->vdev.dev.release = mic_virtio_release_dev;
411 mvdev->vdev.id.device = type;
412 mvdev->vdev.config = &mic_vq_config_ops;
413 mvdev->desc = d;
414 mvdev->dc = (void __iomem *)d + mic_aligned_desc_size(d);
415 init_completion(&mvdev->reset_done);
416
417 virtio_db = mic_next_card_db();
418 mvdev->virtio_cookie = mic_request_card_irq(mic_virtio_intr_handler,
419 "virtio intr", mvdev, virtio_db);
420 if (IS_ERR(mvdev->virtio_cookie)) {
421 ret = PTR_ERR(mvdev->virtio_cookie);
422 goto kfree;
423 }
424 iowrite8((u8)virtio_db, &mvdev->dc->h2c_vdev_db);
425 mvdev->c2h_vdev_db = ioread8(&mvdev->dc->c2h_vdev_db);
426
427 ret = register_virtio_device(&mvdev->vdev);
428 if (ret) {
429 dev_err(mic_dev(mvdev),
430 "Failed to register mic device %u type %u\n",
431 offset, type);
432 goto free_irq;
433 }
434 iowrite64((u64)mvdev, &mvdev->dc->vdev);
435 dev_dbg(mic_dev(mvdev), "%s: registered mic device %u type %u mvdev %p\n",
436 __func__, offset, type, mvdev);
437
438 return 0;
439
440free_irq:
441 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
442kfree:
443 kfree(mvdev);
444 return ret;
445}
446
447/*
448 * match for a mic device with a specific desc pointer
449 */
450static int mic_match_desc(struct device *dev, void *data)
451{
452 struct virtio_device *vdev = dev_to_virtio(dev);
453 struct mic_vdev *mvdev = to_micvdev(vdev);
454
455 return mvdev->desc == (void __iomem *)data;
456}
457
458static void mic_handle_config_change(struct mic_device_desc __iomem *d,
459 unsigned int offset, struct mic_driver *mdrv)
460{
461 struct mic_device_ctrl __iomem *dc
462 = (void __iomem *)d + mic_aligned_desc_size(d);
463 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
464 struct virtio_driver *drv;
465
466 if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED)
467 return;
468
469 dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__);
470 drv = container_of(mvdev->vdev.dev.driver,
471 struct virtio_driver, driver);
472 if (drv->config_changed)
473 drv->config_changed(&mvdev->vdev);
474 iowrite8(1, &dc->guest_ack);
475}
476
477/*
478 * removes a virtio device if a hot remove event has been
479 * requested by the host.
480 */
481static int mic_remove_device(struct mic_device_desc __iomem *d,
482 unsigned int offset, struct mic_driver *mdrv)
483{
484 struct mic_device_ctrl __iomem *dc
485 = (void __iomem *)d + mic_aligned_desc_size(d);
486 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
487 u8 status;
488 int ret = -1;
489
490 if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) {
491 dev_dbg(mdrv->dev,
492 "%s %d config_change %d type %d mvdev %p\n",
493 __func__, __LINE__,
494 ioread8(&dc->config_change), ioread8(&d->type), mvdev);
495
496 status = ioread8(&d->status);
497 INIT_COMPLETION(mvdev->reset_done);
498 unregister_virtio_device(&mvdev->vdev);
499 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
500 if (status & VIRTIO_CONFIG_S_DRIVER_OK)
501 wait_for_completion(&mvdev->reset_done);
502 kfree(mvdev);
503 iowrite8(1, &dc->guest_ack);
504 dev_dbg(mdrv->dev, "%s %d guest_ack %d\n",
505 __func__, __LINE__, ioread8(&dc->guest_ack));
506 ret = 0;
507 }
508
509 return ret;
510}
511
512#define REMOVE_DEVICES true
513
514static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
515{
516 s8 type;
517 unsigned int i;
518 struct mic_device_desc __iomem *d;
519 struct mic_device_ctrl __iomem *dc;
520 struct device *dev;
521 int ret;
522
523 for (i = mic_aligned_size(struct mic_bootparam);
524 i < MIC_DP_SIZE; i += mic_total_desc_size(d)) {
525 d = mdrv->dp + i;
526 dc = (void __iomem *)d + mic_aligned_desc_size(d);
527 /*
528 * This read barrier is paired with the corresponding write
529 * barrier on the host which is inserted before adding or
530 * removing a virtio device descriptor, by updating the type.
531 */
532 rmb();
533 type = ioread8(&d->type);
534
535 /* end of list */
536 if (type == 0)
537 break;
538
539 if (type == -1)
540 continue;
541
542 /* device already exists */
543 dev = device_find_child(mdrv->dev, d, mic_match_desc);
544 if (dev) {
545 if (remove)
546 iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
547 &dc->config_change);
548 put_device(dev);
549 mic_handle_config_change(d, i, mdrv);
550 ret = mic_remove_device(d, i, mdrv);
551 if (!ret && !remove)
552 iowrite8(-1, &d->type);
553 if (remove) {
554 iowrite8(0, &dc->config_change);
555 iowrite8(0, &dc->guest_ack);
556 }
557 continue;
558 }
559
560 /* new device */
561 dev_dbg(mdrv->dev, "%s %d Adding new virtio device %p\n",
562 __func__, __LINE__, d);
563 if (!remove)
564 mic_add_device(d, i, mdrv);
565 }
566}
567
568/*
569 * mic_hotplug_device tries to find changes in the device page.
570 */
571static void mic_hotplug_devices(struct work_struct *work)
572{
573 struct mic_driver *mdrv = container_of(work,
574 struct mic_driver, hotplug_work);
575
576 mic_scan_devices(mdrv, !REMOVE_DEVICES);
577}
578
579/*
580 * Interrupt handler for hot plug/config changes etc.
581 */
582static irqreturn_t
583mic_extint_handler(int irq, void *data)
584{
585 struct mic_driver *mdrv = (struct mic_driver *)data;
586
587 dev_dbg(mdrv->dev, "%s %d hotplug work\n",
588 __func__, __LINE__);
589 mic_ack_interrupt(&mdrv->mdev);
590 schedule_work(&mdrv->hotplug_work);
591 return IRQ_HANDLED;
592}
593
594/*
595 * Init function for virtio
596 */
597int mic_devices_init(struct mic_driver *mdrv)
598{
599 int rc;
600 struct mic_bootparam __iomem *bootparam;
601 int config_db;
602
603 INIT_WORK(&mdrv->hotplug_work, mic_hotplug_devices);
604 mic_scan_devices(mdrv, !REMOVE_DEVICES);
605
606 config_db = mic_next_card_db();
607 virtio_config_cookie = mic_request_card_irq(mic_extint_handler,
608 "virtio_config_intr", mdrv, config_db);
609 if (IS_ERR(virtio_config_cookie)) {
610 rc = PTR_ERR(virtio_config_cookie);
611 goto exit;
612 }
613
614 bootparam = mdrv->dp;
615 iowrite8(config_db, &bootparam->h2c_config_db);
616 return 0;
617exit:
618 return rc;
619}
620
621/*
622 * Uninit function for virtio
623 */
624void mic_devices_uninit(struct mic_driver *mdrv)
625{
626 struct mic_bootparam __iomem *bootparam = mdrv->dp;
627 iowrite8(-1, &bootparam->h2c_config_db);
628 mic_free_card_irq(virtio_config_cookie, mdrv);
629 flush_work(&mdrv->hotplug_work);
630 mic_scan_devices(mdrv, REMOVE_DEVICES);
631}
diff --git a/drivers/misc/mic/card/mic_virtio.h b/drivers/misc/mic/card/mic_virtio.h
new file mode 100644
index 000000000000..2c5c22c93ba8
--- /dev/null
+++ b/drivers/misc/mic/card/mic_virtio.h
@@ -0,0 +1,77 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef __MIC_CARD_VIRTIO_H
28#define __MIC_CARD_VIRTIO_H
29
30#include <linux/mic_common.h>
31#include "mic_device.h"
32
33/*
34 * 64 bit I/O access
35 */
36#ifndef ioread64
37#define ioread64 readq
38#endif
39#ifndef iowrite64
40#define iowrite64 writeq
41#endif
42
43static inline unsigned mic_desc_size(struct mic_device_desc __iomem *desc)
44{
45 return mic_aligned_size(*desc)
46 + ioread8(&desc->num_vq) * mic_aligned_size(struct mic_vqconfig)
47 + ioread8(&desc->feature_len) * 2
48 + ioread8(&desc->config_len);
49}
50
51static inline struct mic_vqconfig __iomem *
52mic_vq_config(struct mic_device_desc __iomem *desc)
53{
54 return (struct mic_vqconfig __iomem *)(desc + 1);
55}
56
57static inline __u8 __iomem *
58mic_vq_features(struct mic_device_desc __iomem *desc)
59{
60 return (__u8 __iomem *)(mic_vq_config(desc) + ioread8(&desc->num_vq));
61}
62
63static inline __u8 __iomem *
64mic_vq_configspace(struct mic_device_desc __iomem *desc)
65{
66 return mic_vq_features(desc) + ioread8(&desc->feature_len) * 2;
67}
68static inline unsigned mic_total_desc_size(struct mic_device_desc __iomem *desc)
69{
70 return mic_aligned_desc_size(desc) +
71 mic_aligned_size(struct mic_device_ctrl);
72}
73
74int mic_devices_init(struct mic_driver *mdrv);
75void mic_devices_uninit(struct mic_driver *mdrv);
76
77#endif
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c
new file mode 100644
index 000000000000..7cb3469cf684
--- /dev/null
+++ b/drivers/misc/mic/card/mic_x100.c
@@ -0,0 +1,256 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/platform_device.h>
30
31#include "../common/mic_device.h"
32#include "mic_device.h"
33#include "mic_x100.h"
34
35static const char mic_driver_name[] = "mic";
36
37static struct mic_driver g_drv;
38
39/**
40 * mic_read_spad - read from the scratchpad register
41 * @mdev: pointer to mic_device instance
42 * @idx: index to scratchpad register, 0 based
43 *
44 * This function allows reading of the 32bit scratchpad register.
45 *
46 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
47 */
48u32 mic_read_spad(struct mic_device *mdev, unsigned int idx)
49{
50 return mic_mmio_read(&mdev->mmio,
51 MIC_X100_SBOX_BASE_ADDRESS +
52 MIC_X100_SBOX_SPAD0 + idx * 4);
53}
54
55/**
56 * __mic_send_intr - Send interrupt to Host.
57 * @mdev: pointer to mic_device instance
58 * @doorbell: Doorbell number.
59 */
60void mic_send_intr(struct mic_device *mdev, int doorbell)
61{
62 struct mic_mw *mw = &mdev->mmio;
63
64 if (doorbell > MIC_X100_MAX_DOORBELL_IDX)
65 return;
66 /* Ensure that the interrupt is ordered w.r.t previous stores. */
67 wmb();
68 mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT,
69 MIC_X100_SBOX_BASE_ADDRESS +
70 (MIC_X100_SBOX_SDBIC0 + (4 * doorbell)));
71}
72
73/**
74 * mic_ack_interrupt - Device specific interrupt handling.
75 * @mdev: pointer to mic_device instance
76 *
77 * Returns: bitmask of doorbell events triggered.
78 */
79u32 mic_ack_interrupt(struct mic_device *mdev)
80{
81 return 0;
82}
83
84static inline int mic_get_sbox_irq(int db)
85{
86 return MIC_X100_IRQ_BASE + db;
87}
88
89static inline int mic_get_rdmasr_irq(int index)
90{
91 return MIC_X100_RDMASR_IRQ_BASE + index;
92}
93
94/**
95 * mic_hw_intr_init - Initialize h/w specific interrupt
96 * information.
97 * @mdrv: pointer to mic_driver
98 */
99void mic_hw_intr_init(struct mic_driver *mdrv)
100{
101 mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ +
102 MIC_X100_NUM_RDMASR_IRQ;
103}
104
105/**
106 * mic_db_to_irq - Retrieve irq number corresponding to a doorbell.
107 * @mdrv: pointer to mic_driver
108 * @db: The doorbell obtained for which the irq is needed. Doorbell
109 * may correspond to an sbox doorbell or an rdmasr index.
110 *
111 * Returns the irq corresponding to the doorbell.
112 */
113int mic_db_to_irq(struct mic_driver *mdrv, int db)
114{
115 int rdmasr_index;
116 if (db < MIC_X100_NUM_SBOX_IRQ) {
117 return mic_get_sbox_irq(db);
118 } else {
119 rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ +
120 MIC_X100_RDMASR_IRQ_BASE;
121 return mic_get_rdmasr_irq(rdmasr_index);
122 }
123}
124
125/*
126 * mic_card_map - Allocate virtual address for a remote memory region.
127 * @mdev: pointer to mic_device instance.
128 * @addr: Remote DMA address.
129 * @size: Size of the region.
130 *
131 * Returns: Virtual address backing the remote memory region.
132 */
133void __iomem *
134mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size)
135{
136 return ioremap(addr, size);
137}
138
139/*
140 * mic_card_unmap - Unmap the virtual address for a remote memory region.
141 * @mdev: pointer to mic_device instance.
142 * @addr: Virtual address for remote memory region.
143 *
144 * Returns: None.
145 */
146void mic_card_unmap(struct mic_device *mdev, void __iomem *addr)
147{
148 iounmap(addr);
149}
150
151static int __init mic_probe(struct platform_device *pdev)
152{
153 struct mic_driver *mdrv = &g_drv;
154 struct mic_device *mdev = &mdrv->mdev;
155 int rc = 0;
156
157 mdrv->dev = &pdev->dev;
158 snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name);
159
160 mdev->mmio.pa = MIC_X100_MMIO_BASE;
161 mdev->mmio.len = MIC_X100_MMIO_LEN;
162 mdev->mmio.va = ioremap(MIC_X100_MMIO_BASE, MIC_X100_MMIO_LEN);
163 if (!mdev->mmio.va) {
164 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
165 rc = -EIO;
166 goto done;
167 }
168 mic_hw_intr_init(mdrv);
169 rc = mic_driver_init(mdrv);
170 if (rc) {
171 dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc);
172 goto iounmap;
173 }
174done:
175 return rc;
176iounmap:
177 iounmap(mdev->mmio.va);
178 return rc;
179}
180
181static int mic_remove(struct platform_device *pdev)
182{
183 struct mic_driver *mdrv = &g_drv;
184 struct mic_device *mdev = &mdrv->mdev;
185
186 mic_driver_uninit(mdrv);
187 iounmap(mdev->mmio.va);
188 return 0;
189}
190
191static void mic_platform_shutdown(struct platform_device *pdev)
192{
193 mic_remove(pdev);
194}
195
196static struct platform_device mic_platform_dev = {
197 .name = mic_driver_name,
198 .id = 0,
199 .num_resources = 0,
200};
201
202static struct platform_driver __refdata mic_platform_driver = {
203 .probe = mic_probe,
204 .remove = mic_remove,
205 .shutdown = mic_platform_shutdown,
206 .driver = {
207 .name = mic_driver_name,
208 .owner = THIS_MODULE,
209 },
210};
211
212static int __init mic_init(void)
213{
214 int ret;
215 struct cpuinfo_x86 *c = &cpu_data(0);
216
217 if (!(c->x86 == 11 && c->x86_model == 1)) {
218 ret = -ENODEV;
219 pr_err("%s not running on X100 ret %d\n", __func__, ret);
220 goto done;
221 }
222
223 mic_init_card_debugfs();
224 ret = platform_device_register(&mic_platform_dev);
225 if (ret) {
226 pr_err("platform_device_register ret %d\n", ret);
227 goto cleanup_debugfs;
228 }
229 ret = platform_driver_register(&mic_platform_driver);
230 if (ret) {
231 pr_err("platform_driver_register ret %d\n", ret);
232 goto device_unregister;
233 }
234 return ret;
235
236device_unregister:
237 platform_device_unregister(&mic_platform_dev);
238cleanup_debugfs:
239 mic_exit_card_debugfs();
240done:
241 return ret;
242}
243
244static void __exit mic_exit(void)
245{
246 platform_driver_unregister(&mic_platform_driver);
247 platform_device_unregister(&mic_platform_dev);
248 mic_exit_card_debugfs();
249}
250
251module_init(mic_init);
252module_exit(mic_exit);
253
254MODULE_AUTHOR("Intel Corporation");
255MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver");
256MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/card/mic_x100.h b/drivers/misc/mic/card/mic_x100.h
new file mode 100644
index 000000000000..d66ea55639c3
--- /dev/null
+++ b/drivers/misc/mic/card/mic_x100.h
@@ -0,0 +1,48 @@
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 * Disclaimer: The codes contained in these modules may be specific to
19 * the Intel Software Development Platform codenamed: Knights Ferry, and
20 * the Intel product codenamed: Knights Corner, and are not backward
21 * compatible with other Intel products. Additionally, Intel will NOT
22 * support the codes or instruction set in future products.
23 *
24 * Intel MIC Card driver.
25 *
26 */
27#ifndef _MIC_X100_CARD_H_
28#define _MIC_X100_CARD_H_
29
30#define MIC_X100_MMIO_BASE 0x08007C0000ULL
31#define MIC_X100_MMIO_LEN 0x00020000ULL
32#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000ULL
33
34#define MIC_X100_SBOX_SPAD0 0x0000AB20
35#define MIC_X100_SBOX_SDBIC0 0x0000CC90
36#define MIC_X100_SBOX_SDBIC0_DBREQ_BIT 0x80000000
37#define MIC_X100_SBOX_RDMASR0 0x0000B180
38
39#define MIC_X100_MAX_DOORBELL_IDX 8
40
41#define MIC_X100_NUM_SBOX_IRQ 8
42#define MIC_X100_NUM_RDMASR_IRQ 8
43#define MIC_X100_SBOX_IRQ_BASE 0
44#define MIC_X100_RDMASR_IRQ_BASE 17
45
46#define MIC_X100_IRQ_BASE 26
47
48#endif
diff --git a/drivers/misc/mic/common/mic_device.h b/drivers/misc/mic/common/mic_device.h
new file mode 100644
index 000000000000..01eb74faae6b
--- /dev/null
+++ b/drivers/misc/mic/common/mic_device.h
@@ -0,0 +1,51 @@
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 */
31struct mic_mw {
32 phys_addr_t pa;
33 void __iomem *va;
34 resource_size_t len;
35};
36
37/*
38 * Scratch pad register offsets used by the host to communicate
39 * device page DMA address to the card.
40 */
41#define MIC_DPLO_SPAD 14
42#define MIC_DPHI_SPAD 15
43
44/*
45 * These values are supposed to be in the config_change field of the
46 * device page when the host sends a config change interrupt to the card.
47 */
48#define MIC_VIRTIO_PARAM_DEV_REMOVE 0x1
49#define MIC_VIRTIO_PARAM_CONFIG_CHANGED 0x2
50
51#endif
diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile
new file mode 100644
index 000000000000..c2197f999394
--- /dev/null
+++ b/drivers/misc/mic/host/Makefile
@@ -0,0 +1,14 @@
1#
2# Makefile - Intel MIC Linux driver.
3# Copyright(c) 2013, Intel Corporation.
4#
5obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o
6mic_host-objs := mic_main.o
7mic_host-objs += mic_x100.o
8mic_host-objs += mic_sysfs.o
9mic_host-objs += mic_smpt.o
10mic_host-objs += mic_intr.o
11mic_host-objs += mic_boot.o
12mic_host-objs += mic_debugfs.o
13mic_host-objs += mic_fops.o
14mic_host-objs += mic_virtio.o
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c
new file mode 100644
index 000000000000..fd9ff6d3784e
--- /dev/null
+++ b/drivers/misc/mic/host/mic_boot.c
@@ -0,0 +1,185 @@
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/delay.h>
22#include <linux/firmware.h>
23
24#include <linux/mic_common.h>
25#include "../common/mic_device.h"
26#include "mic_device.h"
27#include "mic_smpt.h"
28#include "mic_virtio.h"
29
30/**
31 * mic_reset - Reset the MIC device.
32 * @mdev: pointer to mic_device instance
33 */
34static void mic_reset(struct mic_device *mdev)
35{
36 int i;
37
38#define MIC_RESET_TO (45)
39
40 mdev->ops->reset_fw_ready(mdev);
41 mdev->ops->reset(mdev);
42
43 for (i = 0; i < MIC_RESET_TO; i++) {
44 if (mdev->ops->is_fw_ready(mdev))
45 return;
46 /*
47 * Resets typically take 10s of seconds to complete.
48 * Since an MMIO read is required to check if the
49 * firmware is ready or not, a 1 second delay works nicely.
50 */
51 msleep(1000);
52 }
53 mic_set_state(mdev, MIC_RESET_FAILED);
54}
55
56/* Initialize the MIC bootparams */
57void mic_bootparam_init(struct mic_device *mdev)
58{
59 struct mic_bootparam *bootparam = mdev->dp;
60
61 bootparam->magic = MIC_MAGIC;
62 bootparam->c2h_shutdown_db = mdev->shutdown_db;
63 bootparam->h2c_shutdown_db = -1;
64 bootparam->h2c_config_db = -1;
65 bootparam->shutdown_status = 0;
66 bootparam->shutdown_card = 0;
67}
68
69/**
70 * mic_start - Start the MIC.
71 * @mdev: pointer to mic_device instance
72 * @buf: buffer containing boot string including firmware/ramdisk path.
73 *
74 * This function prepares an MIC for boot and initiates boot.
75 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
76 */
77int mic_start(struct mic_device *mdev, const char *buf)
78{
79 int rc;
80 mutex_lock(&mdev->mic_mutex);
81retry:
82 if (MIC_OFFLINE != mdev->state) {
83 rc = -EINVAL;
84 goto unlock_ret;
85 }
86 if (!mdev->ops->is_fw_ready(mdev)) {
87 mic_reset(mdev);
88 /*
89 * The state will either be MIC_OFFLINE if the reset succeeded
90 * or MIC_RESET_FAILED if the firmware reset failed.
91 */
92 goto retry;
93 }
94 rc = mdev->ops->load_mic_fw(mdev, buf);
95 if (rc)
96 goto unlock_ret;
97 mic_smpt_restore(mdev);
98 mic_intr_restore(mdev);
99 mdev->intr_ops->enable_interrupts(mdev);
100 mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
101 mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
102 mdev->ops->send_firmware_intr(mdev);
103 mic_set_state(mdev, MIC_ONLINE);
104unlock_ret:
105 mutex_unlock(&mdev->mic_mutex);
106 return rc;
107}
108
109/**
110 * mic_stop - Prepare the MIC for reset and trigger reset.
111 * @mdev: pointer to mic_device instance
112 * @force: force a MIC to reset even if it is already offline.
113 *
114 * RETURNS: None.
115 */
116void mic_stop(struct mic_device *mdev, bool force)
117{
118 mutex_lock(&mdev->mic_mutex);
119 if (MIC_OFFLINE != mdev->state || force) {
120 mic_virtio_reset_devices(mdev);
121 mic_bootparam_init(mdev);
122 mic_reset(mdev);
123 if (MIC_RESET_FAILED == mdev->state)
124 goto unlock;
125 mic_set_shutdown_status(mdev, MIC_NOP);
126 mic_set_state(mdev, MIC_OFFLINE);
127 }
128unlock:
129 mutex_unlock(&mdev->mic_mutex);
130}
131
132/**
133 * mic_shutdown - Initiate MIC shutdown.
134 * @mdev: pointer to mic_device instance
135 *
136 * RETURNS: None.
137 */
138void mic_shutdown(struct mic_device *mdev)
139{
140 struct mic_bootparam *bootparam = mdev->dp;
141 s8 db = bootparam->h2c_shutdown_db;
142
143 mutex_lock(&mdev->mic_mutex);
144 if (MIC_ONLINE == mdev->state && db != -1) {
145 bootparam->shutdown_card = 1;
146 mdev->ops->send_intr(mdev, db);
147 mic_set_state(mdev, MIC_SHUTTING_DOWN);
148 }
149 mutex_unlock(&mdev->mic_mutex);
150}
151
152/**
153 * mic_shutdown_work - Handle shutdown interrupt from MIC.
154 * @work: The work structure.
155 *
156 * This work is scheduled whenever the host has received a shutdown
157 * interrupt from the MIC.
158 */
159void mic_shutdown_work(struct work_struct *work)
160{
161 struct mic_device *mdev = container_of(work, struct mic_device,
162 shutdown_work);
163 struct mic_bootparam *bootparam = mdev->dp;
164
165 mutex_lock(&mdev->mic_mutex);
166 mic_set_shutdown_status(mdev, bootparam->shutdown_status);
167 bootparam->shutdown_status = 0;
168 if (MIC_SHUTTING_DOWN != mdev->state)
169 mic_set_state(mdev, MIC_SHUTTING_DOWN);
170 mutex_unlock(&mdev->mic_mutex);
171}
172
173/**
174 * mic_reset_trigger_work - Trigger MIC reset.
175 * @work: The work structure.
176 *
177 * This work is scheduled whenever the host wants to reset the MIC.
178 */
179void mic_reset_trigger_work(struct work_struct *work)
180{
181 struct mic_device *mdev = container_of(work, struct mic_device,
182 reset_trigger_work);
183
184 mic_stop(mdev, false);
185}
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c
new file mode 100644
index 000000000000..e22fb7bbbb98
--- /dev/null
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -0,0 +1,495 @@
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/debugfs.h>
22#include <linux/pci.h>
23#include <linux/seq_file.h>
24
25#include <linux/mic_common.h>
26#include "../common/mic_device.h"
27#include "mic_device.h"
28#include "mic_smpt.h"
29#include "mic_virtio.h"
30
31/* Debugfs parent dir */
32static struct dentry *mic_dbg;
33
34/**
35 * mic_log_buf_show - Display MIC kernel log buffer.
36 *
37 * log_buf addr/len is read from System.map by user space
38 * and populated in sysfs entries.
39 */
40static int mic_log_buf_show(struct seq_file *s, void *unused)
41{
42 void __iomem *log_buf_va;
43 int __iomem *log_buf_len_va;
44 struct mic_device *mdev = s->private;
45 void *kva;
46 int size;
47 unsigned long aper_offset;
48
49 if (!mdev || !mdev->log_buf_addr || !mdev->log_buf_len)
50 goto done;
51 /*
52 * Card kernel will never be relocated and any kernel text/data mapping
53 * can be translated to phys address by subtracting __START_KERNEL_map.
54 */
55 aper_offset = (unsigned long)mdev->log_buf_len - __START_KERNEL_map;
56 log_buf_len_va = mdev->aper.va + aper_offset;
57 aper_offset = (unsigned long)mdev->log_buf_addr - __START_KERNEL_map;
58 log_buf_va = mdev->aper.va + aper_offset;
59 size = ioread32(log_buf_len_va);
60
61 kva = kmalloc(size, GFP_KERNEL);
62 if (!kva)
63 goto done;
64 mutex_lock(&mdev->mic_mutex);
65 memcpy_fromio(kva, log_buf_va, size);
66 switch (mdev->state) {
67 case MIC_ONLINE:
68 /* Fall through */
69 case MIC_SHUTTING_DOWN:
70 seq_write(s, kva, size);
71 break;
72 default:
73 break;
74 }
75 mutex_unlock(&mdev->mic_mutex);
76 kfree(kva);
77done:
78 return 0;
79}
80
81static int mic_log_buf_open(struct inode *inode, struct file *file)
82{
83 return single_open(file, mic_log_buf_show, inode->i_private);
84}
85
86static int mic_log_buf_release(struct inode *inode, struct file *file)
87{
88 return single_release(inode, file);
89}
90
91static const struct file_operations log_buf_ops = {
92 .owner = THIS_MODULE,
93 .open = mic_log_buf_open,
94 .read = seq_read,
95 .llseek = seq_lseek,
96 .release = mic_log_buf_release
97};
98
99static int mic_smpt_show(struct seq_file *s, void *pos)
100{
101 int i;
102 struct mic_device *mdev = s->private;
103 unsigned long flags;
104
105 seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n",
106 mdev->id, "SMPT entry", "SW DMA addr", "RefCount");
107 seq_puts(s, "====================================================\n");
108
109 if (mdev->smpt) {
110 struct mic_smpt_info *smpt_info = mdev->smpt;
111 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
112 for (i = 0; i < smpt_info->info.num_reg; i++) {
113 seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n",
114 " ", i, smpt_info->entry[i].dma_addr,
115 smpt_info->entry[i].ref_count);
116 }
117 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
118 }
119 seq_puts(s, "====================================================\n");
120 return 0;
121}
122
123static int mic_smpt_debug_open(struct inode *inode, struct file *file)
124{
125 return single_open(file, mic_smpt_show, inode->i_private);
126}
127
128static int mic_smpt_debug_release(struct inode *inode, struct file *file)
129{
130 return single_release(inode, file);
131}
132
133static const struct file_operations smpt_file_ops = {
134 .owner = THIS_MODULE,
135 .open = mic_smpt_debug_open,
136 .read = seq_read,
137 .llseek = seq_lseek,
138 .release = mic_smpt_debug_release
139};
140
141static int mic_soft_reset_show(struct seq_file *s, void *pos)
142{
143 struct mic_device *mdev = s->private;
144
145 mic_stop(mdev, true);
146 return 0;
147}
148
149static int mic_soft_reset_debug_open(struct inode *inode, struct file *file)
150{
151 return single_open(file, mic_soft_reset_show, inode->i_private);
152}
153
154static int mic_soft_reset_debug_release(struct inode *inode, struct file *file)
155{
156 return single_release(inode, file);
157}
158
159static const struct file_operations soft_reset_ops = {
160 .owner = THIS_MODULE,
161 .open = mic_soft_reset_debug_open,
162 .read = seq_read,
163 .llseek = seq_lseek,
164 .release = mic_soft_reset_debug_release
165};
166
167static int mic_post_code_show(struct seq_file *s, void *pos)
168{
169 struct mic_device *mdev = s->private;
170 u32 reg = mdev->ops->get_postcode(mdev);
171
172 seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff);
173 return 0;
174}
175
176static int mic_post_code_debug_open(struct inode *inode, struct file *file)
177{
178 return single_open(file, mic_post_code_show, inode->i_private);
179}
180
181static int mic_post_code_debug_release(struct inode *inode, struct file *file)
182{
183 return single_release(inode, file);
184}
185
186static const struct file_operations post_code_ops = {
187 .owner = THIS_MODULE,
188 .open = mic_post_code_debug_open,
189 .read = seq_read,
190 .llseek = seq_lseek,
191 .release = mic_post_code_debug_release
192};
193
194static int mic_dp_show(struct seq_file *s, void *pos)
195{
196 struct mic_device *mdev = s->private;
197 struct mic_device_desc *d;
198 struct mic_device_ctrl *dc;
199 struct mic_vqconfig *vqconfig;
200 __u32 *features;
201 __u8 *config;
202 struct mic_bootparam *bootparam = mdev->dp;
203 int i, j;
204
205 seq_printf(s, "Bootparam: magic 0x%x\n",
206 bootparam->magic);
207 seq_printf(s, "Bootparam: h2c_shutdown_db %d\n",
208 bootparam->h2c_shutdown_db);
209 seq_printf(s, "Bootparam: h2c_config_db %d\n",
210 bootparam->h2c_config_db);
211 seq_printf(s, "Bootparam: c2h_shutdown_db %d\n",
212 bootparam->c2h_shutdown_db);
213 seq_printf(s, "Bootparam: shutdown_status %d\n",
214 bootparam->shutdown_status);
215 seq_printf(s, "Bootparam: shutdown_card %d\n",
216 bootparam->shutdown_card);
217
218 for (i = sizeof(*bootparam); i < MIC_DP_SIZE;
219 i += mic_total_desc_size(d)) {
220 d = mdev->dp + i;
221 dc = (void *)d + mic_aligned_desc_size(d);
222
223 /* end of list */
224 if (d->type == 0)
225 break;
226
227 if (d->type == -1)
228 continue;
229
230 seq_printf(s, "Type %d ", d->type);
231 seq_printf(s, "Num VQ %d ", d->num_vq);
232 seq_printf(s, "Feature Len %d\n", d->feature_len);
233 seq_printf(s, "Config Len %d ", d->config_len);
234 seq_printf(s, "Shutdown Status %d\n", d->status);
235
236 for (j = 0; j < d->num_vq; j++) {
237 vqconfig = mic_vq_config(d) + j;
238 seq_printf(s, "vqconfig[%d]: ", j);
239 seq_printf(s, "address 0x%llx ", vqconfig->address);
240 seq_printf(s, "num %d ", vqconfig->num);
241 seq_printf(s, "used address 0x%llx\n",
242 vqconfig->used_address);
243 }
244
245 features = (__u32 *) mic_vq_features(d);
246 seq_printf(s, "Features: Host 0x%x ", features[0]);
247 seq_printf(s, "Guest 0x%x\n", features[1]);
248
249 config = mic_vq_configspace(d);
250 for (j = 0; j < d->config_len; j++)
251 seq_printf(s, "config[%d]=%d\n", j, config[j]);
252
253 seq_puts(s, "Device control:\n");
254 seq_printf(s, "Config Change %d ", dc->config_change);
255 seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
256 seq_printf(s, "Guest Ack %d ", dc->guest_ack);
257 seq_printf(s, "Host ack %d\n", dc->host_ack);
258 seq_printf(s, "Used address updated %d ",
259 dc->used_address_updated);
260 seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
261 seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
262 seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
263 }
264
265 return 0;
266}
267
268static int mic_dp_debug_open(struct inode *inode, struct file *file)
269{
270 return single_open(file, mic_dp_show, inode->i_private);
271}
272
273static int mic_dp_debug_release(struct inode *inode, struct file *file)
274{
275 return single_release(inode, file);
276}
277
278static const struct file_operations dp_ops = {
279 .owner = THIS_MODULE,
280 .open = mic_dp_debug_open,
281 .read = seq_read,
282 .llseek = seq_lseek,
283 .release = mic_dp_debug_release
284};
285
286static int mic_vdev_info_show(struct seq_file *s, void *unused)
287{
288 struct mic_device *mdev = s->private;
289 struct list_head *pos, *tmp;
290 struct mic_vdev *mvdev;
291 int i, j;
292
293 mutex_lock(&mdev->mic_mutex);
294 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
295 mvdev = list_entry(pos, struct mic_vdev, list);
296 seq_printf(s, "VDEV type %d state %s in %ld out %ld\n",
297 mvdev->virtio_id,
298 mic_vdevup(mvdev) ? "UP" : "DOWN",
299 mvdev->in_bytes,
300 mvdev->out_bytes);
301 for (i = 0; i < MIC_MAX_VRINGS; i++) {
302 struct vring_desc *desc;
303 struct vring_avail *avail;
304 struct vring_used *used;
305 struct mic_vringh *mvr = &mvdev->mvr[i];
306 struct vringh *vrh = &mvr->vrh;
307 int num = vrh->vring.num;
308 if (!num)
309 continue;
310 desc = vrh->vring.desc;
311 seq_printf(s, "vring i %d avail_idx %d",
312 i, mvr->vring.info->avail_idx & (num - 1));
313 seq_printf(s, " vring i %d avail_idx %d\n",
314 i, mvr->vring.info->avail_idx);
315 seq_printf(s, "vrh i %d weak_barriers %d",
316 i, vrh->weak_barriers);
317 seq_printf(s, " last_avail_idx %d last_used_idx %d",
318 vrh->last_avail_idx, vrh->last_used_idx);
319 seq_printf(s, " completed %d\n", vrh->completed);
320 for (j = 0; j < num; j++) {
321 seq_printf(s, "desc[%d] addr 0x%llx len %d",
322 j, desc->addr, desc->len);
323 seq_printf(s, " flags 0x%x next %d\n",
324 desc->flags,
325 desc->next);
326 desc++;
327 }
328 avail = vrh->vring.avail;
329 seq_printf(s, "avail flags 0x%x idx %d\n",
330 avail->flags, avail->idx & (num - 1));
331 seq_printf(s, "avail flags 0x%x idx %d\n",
332 avail->flags, avail->idx);
333 for (j = 0; j < num; j++)
334 seq_printf(s, "avail ring[%d] %d\n",
335 j, avail->ring[j]);
336 used = vrh->vring.used;
337 seq_printf(s, "used flags 0x%x idx %d\n",
338 used->flags, used->idx & (num - 1));
339 seq_printf(s, "used flags 0x%x idx %d\n",
340 used->flags, used->idx);
341 for (j = 0; j < num; j++)
342 seq_printf(s, "used ring[%d] id %d len %d\n",
343 j, used->ring[j].id, used->ring[j].len);
344 }
345 }
346 mutex_unlock(&mdev->mic_mutex);
347
348 return 0;
349}
350
351static int mic_vdev_info_debug_open(struct inode *inode, struct file *file)
352{
353 return single_open(file, mic_vdev_info_show, inode->i_private);
354}
355
356static int mic_vdev_info_debug_release(struct inode *inode, struct file *file)
357{
358 return single_release(inode, file);
359}
360
361static const struct file_operations vdev_info_ops = {
362 .owner = THIS_MODULE,
363 .open = mic_vdev_info_debug_open,
364 .read = seq_read,
365 .llseek = seq_lseek,
366 .release = mic_vdev_info_debug_release
367};
368
369static int mic_msi_irq_info_show(struct seq_file *s, void *pos)
370{
371 struct mic_device *mdev = s->private;
372 int reg;
373 int i, j;
374 u16 entry;
375 u16 vector;
376 struct pci_dev *pdev = container_of(mdev->sdev->parent,
377 struct pci_dev, dev);
378
379 if (pci_dev_msi_enabled(pdev)) {
380 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
381 if (pdev->msix_enabled) {
382 entry = mdev->irq_info.msix_entries[i].entry;
383 vector = mdev->irq_info.msix_entries[i].vector;
384 } else {
385 entry = 0;
386 vector = pdev->irq;
387 }
388
389 reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry);
390
391 seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n",
392 "IRQ:", vector, "Entry:", entry, i, reg);
393
394 seq_printf(s, "%-10s", "offset:");
395 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
396 seq_printf(s, "%4d ", j);
397 seq_puts(s, "\n");
398
399
400 seq_printf(s, "%-10s", "count:");
401 for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--)
402 seq_printf(s, "%4d ",
403 (mdev->irq_info.mic_msi_map[i] & BIT(j)) ?
404 1 : 0);
405 seq_puts(s, "\n\n");
406 }
407 } else {
408 seq_puts(s, "MSI/MSIx interrupts not enabled\n");
409 }
410
411 return 0;
412
413}
414
415static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
416{
417 return single_open(file, mic_msi_irq_info_show, inode->i_private);
418}
419
420static int
421mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
422{
423 return single_release(inode, file);
424}
425
426static const struct file_operations msi_irq_info_ops = {
427 .owner = THIS_MODULE,
428 .open = mic_msi_irq_info_debug_open,
429 .read = seq_read,
430 .llseek = seq_lseek,
431 .release = mic_msi_irq_info_debug_release
432};
433
434/**
435 * mic_create_debug_dir - Initialize MIC debugfs entries.
436 */
437void mic_create_debug_dir(struct mic_device *mdev)
438{
439 if (!mic_dbg)
440 return;
441
442 mdev->dbg_dir = debugfs_create_dir(dev_name(mdev->sdev), mic_dbg);
443 if (!mdev->dbg_dir)
444 return;
445
446 debugfs_create_file("log_buf", 0444, mdev->dbg_dir,
447 mdev, &log_buf_ops);
448
449 debugfs_create_file("smpt", 0444, mdev->dbg_dir,
450 mdev, &smpt_file_ops);
451
452 debugfs_create_file("soft_reset", 0444, mdev->dbg_dir,
453 mdev, &soft_reset_ops);
454
455 debugfs_create_file("post_code", 0444, mdev->dbg_dir,
456 mdev, &post_code_ops);
457
458 debugfs_create_file("dp", 0444, mdev->dbg_dir,
459 mdev, &dp_ops);
460
461 debugfs_create_file("vdev_info", 0444, mdev->dbg_dir,
462 mdev, &vdev_info_ops);
463
464 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir,
465 mdev, &msi_irq_info_ops);
466}
467
468/**
469 * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
470 */
471void mic_delete_debug_dir(struct mic_device *mdev)
472{
473 if (!mdev->dbg_dir)
474 return;
475
476 debugfs_remove_recursive(mdev->dbg_dir);
477}
478
479/**
480 * mic_init_debugfs - Initialize global debugfs entry.
481 */
482void __init mic_init_debugfs(void)
483{
484 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
485 if (!mic_dbg)
486 pr_err("can't create debugfs dir\n");
487}
488
489/**
490 * mic_exit_debugfs - Uninitialize global debugfs entry
491 */
492void mic_exit_debugfs(void)
493{
494 debugfs_remove(mic_dbg);
495}
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h
new file mode 100644
index 000000000000..dcba2a59e77f
--- /dev/null
+++ b/drivers/misc/mic/host/mic_device.h
@@ -0,0 +1,195 @@
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#include <linux/cdev.h>
25#include <linux/idr.h>
26
27#include "mic_intr.h"
28
29/* The maximum number of MIC devices supported in a single host system. */
30#define MIC_MAX_NUM_DEVS 256
31
32/**
33 * enum mic_hw_family - The hardware family to which a device belongs.
34 */
35enum mic_hw_family {
36 MIC_FAMILY_X100 = 0,
37 MIC_FAMILY_UNKNOWN
38};
39
40/**
41 * enum mic_stepping - MIC stepping ids.
42 */
43enum mic_stepping {
44 MIC_A0_STEP = 0x0,
45 MIC_B0_STEP = 0x10,
46 MIC_B1_STEP = 0x11,
47 MIC_C0_STEP = 0x20,
48};
49
50/**
51 * struct mic_device - MIC device information for each card.
52 *
53 * @mmio: MMIO bar information.
54 * @aper: Aperture bar information.
55 * @family: The MIC family to which this device belongs.
56 * @ops: MIC HW specific operations.
57 * @id: The unique device id for this MIC device.
58 * @stepping: Stepping ID.
59 * @attr_group: Pointer to list of sysfs attribute groups.
60 * @sdev: Device for sysfs entries.
61 * @mic_mutex: Mutex for synchronizing access to mic_device.
62 * @intr_ops: HW specific interrupt operations.
63 * @smpt_ops: Hardware specific SMPT operations.
64 * @smpt: MIC SMPT information.
65 * @intr_info: H/W specific interrupt information.
66 * @irq_info: The OS specific irq information
67 * @dbg_dir: debugfs directory of this MIC device.
68 * @cmdline: Kernel command line.
69 * @firmware: Firmware file name.
70 * @ramdisk: Ramdisk file name.
71 * @bootmode: Boot mode i.e. "linux" or "elf" for flash updates.
72 * @bootaddr: MIC boot address.
73 * @reset_trigger_work: Work for triggering reset requests.
74 * @shutdown_work: Work for handling shutdown interrupts.
75 * @state: MIC state.
76 * @shutdown_status: MIC status reported by card for shutdown/crashes.
77 * @state_sysfs: Sysfs dirent for notifying ring 3 about MIC state changes.
78 * @log_buf_addr: Log buffer address for MIC.
79 * @log_buf_len: Log buffer length address for MIC.
80 * @dp: virtio device page
81 * @dp_dma_addr: virtio device page DMA address.
82 * @shutdown_db: shutdown doorbell.
83 * @shutdown_cookie: shutdown cookie.
84 * @cdev: Character device for MIC.
85 * @vdev_list: list of virtio devices.
86 */
87struct mic_device {
88 struct mic_mw mmio;
89 struct mic_mw aper;
90 enum mic_hw_family family;
91 struct mic_hw_ops *ops;
92 int id;
93 enum mic_stepping stepping;
94 const struct attribute_group **attr_group;
95 struct device *sdev;
96 struct mutex mic_mutex;
97 struct mic_hw_intr_ops *intr_ops;
98 struct mic_smpt_ops *smpt_ops;
99 struct mic_smpt_info *smpt;
100 struct mic_intr_info *intr_info;
101 struct mic_irq_info irq_info;
102 struct dentry *dbg_dir;
103 char *cmdline;
104 char *firmware;
105 char *ramdisk;
106 char *bootmode;
107 u32 bootaddr;
108 struct work_struct reset_trigger_work;
109 struct work_struct shutdown_work;
110 u8 state;
111 u8 shutdown_status;
112 struct sysfs_dirent *state_sysfs;
113 void *log_buf_addr;
114 int *log_buf_len;
115 void *dp;
116 dma_addr_t dp_dma_addr;
117 int shutdown_db;
118 struct mic_irq *shutdown_cookie;
119 struct cdev cdev;
120 struct list_head vdev_list;
121};
122
123/**
124 * struct mic_hw_ops - MIC HW specific operations.
125 * @aper_bar: Aperture bar resource number.
126 * @mmio_bar: MMIO bar resource number.
127 * @read_spad: Read from scratch pad register.
128 * @write_spad: Write to scratch pad register.
129 * @send_intr: Send an interrupt for a particular doorbell on the card.
130 * @ack_interrupt: Hardware specific operations to ack the h/w on
131 * receipt of an interrupt.
132 * @reset: Reset the remote processor.
133 * @reset_fw_ready: Reset firmware ready field.
134 * @is_fw_ready: Check if firmware is ready for OS download.
135 * @send_firmware_intr: Send an interrupt to the card firmware.
136 * @load_mic_fw: Load firmware segments required to boot the card
137 * into card memory. This includes the kernel, command line, ramdisk etc.
138 * @get_postcode: Get post code status from firmware.
139 */
140struct mic_hw_ops {
141 u8 aper_bar;
142 u8 mmio_bar;
143 u32 (*read_spad)(struct mic_device *mdev, unsigned int idx);
144 void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val);
145 void (*send_intr)(struct mic_device *mdev, int doorbell);
146 u32 (*ack_interrupt)(struct mic_device *mdev);
147 void (*reset)(struct mic_device *mdev);
148 void (*reset_fw_ready)(struct mic_device *mdev);
149 bool (*is_fw_ready)(struct mic_device *mdev);
150 void (*send_firmware_intr)(struct mic_device *mdev);
151 int (*load_mic_fw)(struct mic_device *mdev, const char *buf);
152 u32 (*get_postcode)(struct mic_device *mdev);
153};
154
155/**
156 * mic_mmio_read - read from an MMIO register.
157 * @mw: MMIO register base virtual address.
158 * @offset: register offset.
159 *
160 * RETURNS: register value.
161 */
162static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset)
163{
164 return ioread32(mw->va + offset);
165}
166
167/**
168 * mic_mmio_write - write to an MMIO register.
169 * @mw: MMIO register base virtual address.
170 * @val: the data value to put into the register
171 * @offset: register offset.
172 *
173 * RETURNS: none.
174 */
175static inline void
176mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset)
177{
178 iowrite32(val, mw->va + offset);
179}
180
181void mic_sysfs_init(struct mic_device *mdev);
182int mic_start(struct mic_device *mdev, const char *buf);
183void mic_stop(struct mic_device *mdev, bool force);
184void mic_shutdown(struct mic_device *mdev);
185void mic_reset_delayed_work(struct work_struct *work);
186void mic_reset_trigger_work(struct work_struct *work);
187void mic_shutdown_work(struct work_struct *work);
188void mic_bootparam_init(struct mic_device *mdev);
189void mic_set_state(struct mic_device *mdev, u8 state);
190void mic_set_shutdown_status(struct mic_device *mdev, u8 status);
191void mic_create_debug_dir(struct mic_device *dev);
192void mic_delete_debug_dir(struct mic_device *dev);
193void __init mic_init_debugfs(void);
194void mic_exit_debugfs(void);
195#endif
diff --git a/drivers/misc/mic/host/mic_fops.c b/drivers/misc/mic/host/mic_fops.c
new file mode 100644
index 000000000000..661469ad339d
--- /dev/null
+++ b/drivers/misc/mic/host/mic_fops.c
@@ -0,0 +1,221 @@
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/poll.h>
22
23#include <linux/mic_common.h>
24#include "../common/mic_device.h"
25#include "mic_device.h"
26#include "mic_fops.h"
27#include "mic_virtio.h"
28
29int mic_open(struct inode *inode, struct file *f)
30{
31 struct mic_vdev *mvdev;
32 struct mic_device *mdev = container_of(inode->i_cdev,
33 struct mic_device, cdev);
34
35 mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
36 if (!mvdev)
37 return -ENOMEM;
38
39 init_waitqueue_head(&mvdev->waitq);
40 INIT_LIST_HEAD(&mvdev->list);
41 mvdev->mdev = mdev;
42 mvdev->virtio_id = -1;
43
44 f->private_data = mvdev;
45 return 0;
46}
47
48int mic_release(struct inode *inode, struct file *f)
49{
50 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
51
52 if (-1 != mvdev->virtio_id)
53 mic_virtio_del_device(mvdev);
54 f->private_data = NULL;
55 kfree(mvdev);
56 return 0;
57}
58
59long mic_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
60{
61 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
62 void __user *argp = (void __user *)arg;
63 int ret;
64
65 switch (cmd) {
66 case MIC_VIRTIO_ADD_DEVICE:
67 {
68 ret = mic_virtio_add_device(mvdev, argp);
69 if (ret < 0) {
70 dev_err(mic_dev(mvdev),
71 "%s %d errno ret %d\n",
72 __func__, __LINE__, ret);
73 return ret;
74 }
75 break;
76 }
77 case MIC_VIRTIO_COPY_DESC:
78 {
79 struct mic_copy_desc copy;
80
81 ret = mic_vdev_inited(mvdev);
82 if (ret)
83 return ret;
84
85 if (copy_from_user(&copy, argp, sizeof(copy)))
86 return -EFAULT;
87
88 dev_dbg(mic_dev(mvdev),
89 "%s %d === iovcnt 0x%x vr_idx 0x%x update_used %d\n",
90 __func__, __LINE__, copy.iovcnt, copy.vr_idx,
91 copy.update_used);
92
93 ret = mic_virtio_copy_desc(mvdev, &copy);
94 if (ret < 0) {
95 dev_err(mic_dev(mvdev),
96 "%s %d errno ret %d\n",
97 __func__, __LINE__, ret);
98 return ret;
99 }
100 if (copy_to_user(
101 &((struct mic_copy_desc __user *)argp)->out_len,
102 &copy.out_len, sizeof(copy.out_len))) {
103 dev_err(mic_dev(mvdev), "%s %d errno ret %d\n",
104 __func__, __LINE__, -EFAULT);
105 return -EFAULT;
106 }
107 break;
108 }
109 case MIC_VIRTIO_CONFIG_CHANGE:
110 {
111 ret = mic_vdev_inited(mvdev);
112 if (ret)
113 return ret;
114
115 ret = mic_virtio_config_change(mvdev, argp);
116 if (ret < 0) {
117 dev_err(mic_dev(mvdev),
118 "%s %d errno ret %d\n",
119 __func__, __LINE__, ret);
120 return ret;
121 }
122 break;
123 }
124 default:
125 return -ENOIOCTLCMD;
126 };
127 return 0;
128}
129
130/*
131 * We return POLLIN | POLLOUT from poll when new buffers are enqueued, and
132 * not when previously enqueued buffers may be available. This means that
133 * in the card->host (TX) path, when userspace is unblocked by poll it
134 * must drain all available descriptors or it can stall.
135 */
136unsigned int mic_poll(struct file *f, poll_table *wait)
137{
138 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
139 int mask = 0;
140
141 poll_wait(f, &mvdev->waitq, wait);
142
143 if (mic_vdev_inited(mvdev))
144 mask = POLLERR;
145 else if (mvdev->poll_wake) {
146 mvdev->poll_wake = 0;
147 mask = POLLIN | POLLOUT;
148 }
149
150 return mask;
151}
152
153static inline int
154mic_query_offset(struct mic_vdev *mvdev, unsigned long offset,
155 unsigned long *size, unsigned long *pa)
156{
157 struct mic_device *mdev = mvdev->mdev;
158 unsigned long start = MIC_DP_SIZE;
159 int i;
160
161 /*
162 * MMAP interface is as follows:
163 * offset region
164 * 0x0 virtio device_page
165 * 0x1000 first vring
166 * 0x1000 + size of 1st vring second vring
167 * ....
168 */
169 if (!offset) {
170 *pa = virt_to_phys(mdev->dp);
171 *size = MIC_DP_SIZE;
172 return 0;
173 }
174
175 for (i = 0; i < mvdev->dd->num_vq; i++) {
176 struct mic_vringh *mvr = &mvdev->mvr[i];
177 if (offset == start) {
178 *pa = virt_to_phys(mvr->vring.va);
179 *size = mvr->vring.len;
180 return 0;
181 }
182 start += mvr->vring.len;
183 }
184 return -1;
185}
186
187/*
188 * Maps the device page and virtio rings to user space for readonly access.
189 */
190int
191mic_mmap(struct file *f, struct vm_area_struct *vma)
192{
193 struct mic_vdev *mvdev = (struct mic_vdev *)f->private_data;
194 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
195 unsigned long pa, size = vma->vm_end - vma->vm_start, size_rem = size;
196 int i, err;
197
198 err = mic_vdev_inited(mvdev);
199 if (err)
200 return err;
201
202 if (vma->vm_flags & VM_WRITE)
203 return -EACCES;
204
205 while (size_rem) {
206 i = mic_query_offset(mvdev, offset, &size, &pa);
207 if (i < 0)
208 return -EINVAL;
209 err = remap_pfn_range(vma, vma->vm_start + offset,
210 pa >> PAGE_SHIFT, size, vma->vm_page_prot);
211 if (err)
212 return err;
213 dev_dbg(mic_dev(mvdev),
214 "%s %d type %d size 0x%lx off 0x%lx pa 0x%lx vma 0x%lx\n",
215 __func__, __LINE__, mvdev->virtio_id, size, offset,
216 pa, vma->vm_start + offset);
217 size_rem -= size;
218 offset += size;
219 }
220 return 0;
221}
diff --git a/drivers/misc/mic/host/mic_fops.h b/drivers/misc/mic/host/mic_fops.h
new file mode 100644
index 000000000000..dc3893dff667
--- /dev/null
+++ b/drivers/misc/mic/host/mic_fops.h
@@ -0,0 +1,32 @@
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_FOPS_H_
22#define _MIC_FOPS_H_
23
24int mic_open(struct inode *inode, struct file *filp);
25int mic_release(struct inode *inode, struct file *filp);
26ssize_t mic_read(struct file *filp, char __user *buf,
27 size_t count, loff_t *pos);
28long mic_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
29int mic_mmap(struct file *f, struct vm_area_struct *vma);
30unsigned int mic_poll(struct file *f, poll_table *wait);
31
32#endif
diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c
new file mode 100644
index 000000000000..cdae3141dbb9
--- /dev/null
+++ b/drivers/misc/mic/host/mic_intr.c
@@ -0,0 +1,628 @@
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#include <linux/interrupt.h>
23
24#include "../common/mic_device.h"
25#include "mic_device.h"
26
27/*
28 * mic_invoke_callback - Invoke callback functions registered for
29 * the corresponding source id.
30 *
31 * @mdev: pointer to the mic_device instance
32 * @idx: The interrupt source id.
33 *
34 * Returns none.
35 */
36static inline void mic_invoke_callback(struct mic_device *mdev, int idx)
37{
38 struct mic_intr_cb *intr_cb;
39 struct pci_dev *pdev = container_of(mdev->sdev->parent,
40 struct pci_dev, dev);
41
42 spin_lock(&mdev->irq_info.mic_intr_lock);
43 list_for_each_entry(intr_cb, &mdev->irq_info.cb_list[idx], list)
44 if (intr_cb->func)
45 intr_cb->func(pdev->irq, intr_cb->data);
46 spin_unlock(&mdev->irq_info.mic_intr_lock);
47}
48
49/**
50 * mic_interrupt - Generic interrupt handler for
51 * MSI and INTx based interrupts.
52 */
53static irqreturn_t mic_interrupt(int irq, void *dev)
54{
55 struct mic_device *mdev = dev;
56 struct mic_intr_info *info = mdev->intr_info;
57 u32 mask;
58 int i;
59
60 mask = mdev->ops->ack_interrupt(mdev);
61 if (!mask)
62 return IRQ_NONE;
63
64 for (i = info->intr_start_idx[MIC_INTR_DB];
65 i < info->intr_len[MIC_INTR_DB]; i++)
66 if (mask & BIT(i))
67 mic_invoke_callback(mdev, i);
68
69 return IRQ_HANDLED;
70}
71
72/* Return the interrupt offset from the index. Index is 0 based. */
73static u16 mic_map_src_to_offset(struct mic_device *mdev,
74 int intr_src, enum mic_intr_type type) {
75
76 if (type >= MIC_NUM_INTR_TYPES)
77 return MIC_NUM_OFFSETS;
78 if (intr_src >= mdev->intr_info->intr_len[type])
79 return MIC_NUM_OFFSETS;
80
81 return mdev->intr_info->intr_start_idx[type] + intr_src;
82}
83
84/* Return next available msix_entry. */
85static struct msix_entry *mic_get_available_vector(struct mic_device *mdev)
86{
87 int i;
88 struct mic_irq_info *info = &mdev->irq_info;
89
90 for (i = 0; i < info->num_vectors; i++)
91 if (!info->mic_msi_map[i])
92 return &info->msix_entries[i];
93 return NULL;
94}
95
96/**
97 * mic_register_intr_callback - Register a callback handler for the
98 * given source id.
99 *
100 * @mdev: pointer to the mic_device instance
101 * @idx: The source id to be registered.
102 * @func: The function to be called when the source id receives
103 * the interrupt.
104 * @data: Private data of the requester.
105 * Return the callback structure that was registered or an
106 * appropriate error on failure.
107 */
108static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev,
109 u8 idx, irqreturn_t (*func) (int irq, void *dev),
110 void *data)
111{
112 struct mic_intr_cb *intr_cb;
113 unsigned long flags;
114 int rc;
115 intr_cb = kmalloc(sizeof(struct mic_intr_cb), GFP_KERNEL);
116
117 if (!intr_cb)
118 return ERR_PTR(-ENOMEM);
119
120 intr_cb->func = func;
121 intr_cb->data = data;
122 intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida,
123 0, 0, GFP_KERNEL);
124 if (intr_cb->cb_id < 0) {
125 rc = intr_cb->cb_id;
126 goto ida_fail;
127 }
128
129 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
130 list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]);
131 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
132
133 return intr_cb;
134ida_fail:
135 kfree(intr_cb);
136 return ERR_PTR(rc);
137}
138
139/**
140 * mic_unregister_intr_callback - Unregister the callback handler
141 * identified by its callback id.
142 *
143 * @mdev: pointer to the mic_device instance
144 * @idx: The callback structure id to be unregistered.
145 * Return the source id that was unregistered or MIC_NUM_OFFSETS if no
146 * such callback handler was found.
147 */
148static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx)
149{
150 struct list_head *pos, *tmp;
151 struct mic_intr_cb *intr_cb;
152 unsigned long flags;
153 int i;
154
155 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
156 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
157 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
158 intr_cb = list_entry(pos, struct mic_intr_cb, list);
159 if (intr_cb->cb_id == idx) {
160 list_del(pos);
161 ida_simple_remove(&mdev->irq_info.cb_ida,
162 intr_cb->cb_id);
163 kfree(intr_cb);
164 spin_unlock_irqrestore(
165 &mdev->irq_info.mic_intr_lock, flags);
166 return i;
167 }
168 }
169 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
170 }
171 return MIC_NUM_OFFSETS;
172}
173
174/**
175 * mic_setup_msix - Initializes MSIx interrupts.
176 *
177 * @mdev: pointer to mic_device instance
178 *
179 *
180 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
181 */
182static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev)
183{
184 int rc, i;
185
186 mdev->irq_info.msix_entries = kmalloc(sizeof(struct msix_entry) *
187 MIC_MIN_MSIX, GFP_KERNEL);
188 if (!mdev->irq_info.msix_entries) {
189 rc = -ENOMEM;
190 goto err_nomem1;
191 }
192
193 for (i = 0; i < MIC_MIN_MSIX; i++)
194 mdev->irq_info.msix_entries[i].entry = i;
195
196 rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
197 MIC_MIN_MSIX);
198 if (rc) {
199 dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
200 goto err_enable_msix;
201 }
202
203 mdev->irq_info.num_vectors = MIC_MIN_MSIX;
204 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
205 mdev->irq_info.num_vectors), GFP_KERNEL);
206
207 if (!mdev->irq_info.mic_msi_map) {
208 rc = -ENOMEM;
209 goto err_nomem2;
210 }
211
212 dev_dbg(mdev->sdev->parent,
213 "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
214 return 0;
215err_nomem2:
216 pci_disable_msix(pdev);
217err_enable_msix:
218 kfree(mdev->irq_info.msix_entries);
219err_nomem1:
220 mdev->irq_info.num_vectors = 0;
221 return rc;
222}
223
224/**
225 * mic_setup_callbacks - Initialize data structures needed
226 * to handle callbacks.
227 *
228 * @mdev: pointer to mic_device instance
229 */
230static int mic_setup_callbacks(struct mic_device *mdev)
231{
232 int i;
233
234 mdev->irq_info.cb_list = kmalloc(sizeof(struct list_head) *
235 MIC_NUM_OFFSETS, GFP_KERNEL);
236 if (!mdev->irq_info.cb_list)
237 return -ENOMEM;
238
239 for (i = 0; i < MIC_NUM_OFFSETS; i++)
240 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
241 ida_init(&mdev->irq_info.cb_ida);
242 spin_lock_init(&mdev->irq_info.mic_intr_lock);
243 return 0;
244}
245
246/**
247 * mic_release_callbacks - Uninitialize data structures needed
248 * to handle callbacks.
249 *
250 * @mdev: pointer to mic_device instance
251 */
252static void mic_release_callbacks(struct mic_device *mdev)
253{
254 unsigned long flags;
255 struct list_head *pos, *tmp;
256 struct mic_intr_cb *intr_cb;
257 int i;
258
259 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
260 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
261
262 if (list_empty(&mdev->irq_info.cb_list[i])) {
263 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
264 flags);
265 break;
266 }
267
268 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
269 intr_cb = list_entry(pos, struct mic_intr_cb, list);
270 list_del(pos);
271 ida_simple_remove(&mdev->irq_info.cb_ida,
272 intr_cb->cb_id);
273 kfree(intr_cb);
274 }
275 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
276 }
277 ida_destroy(&mdev->irq_info.cb_ida);
278 kfree(mdev->irq_info.cb_list);
279}
280
281/**
282 * mic_setup_msi - Initializes MSI interrupts.
283 *
284 * @mdev: pointer to mic_device instance
285 * @pdev: PCI device structure
286 *
287 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
288 */
289static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
290{
291 int rc;
292
293 rc = pci_enable_msi(pdev);
294 if (rc) {
295 dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
296 return rc;
297 }
298
299 mdev->irq_info.num_vectors = 1;
300 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
301 mdev->irq_info.num_vectors), GFP_KERNEL);
302
303 if (!mdev->irq_info.mic_msi_map) {
304 rc = -ENOMEM;
305 goto err_nomem1;
306 }
307
308 rc = mic_setup_callbacks(mdev);
309 if (rc) {
310 dev_err(&pdev->dev, "Error setting up callbacks\n");
311 goto err_nomem2;
312 }
313
314 rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
315 if (rc) {
316 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
317 goto err_irq_req_fail;
318 }
319
320 dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
321 return 0;
322err_irq_req_fail:
323 mic_release_callbacks(mdev);
324err_nomem2:
325 kfree(mdev->irq_info.mic_msi_map);
326err_nomem1:
327 pci_disable_msi(pdev);
328 mdev->irq_info.num_vectors = 0;
329 return rc;
330}
331
332/**
333 * mic_setup_intx - Initializes legacy interrupts.
334 *
335 * @mdev: pointer to mic_device instance
336 * @pdev: PCI device structure
337 *
338 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
339 */
340static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
341{
342 int rc;
343
344 pci_msi_off(pdev);
345
346 /* Enable intx */
347 pci_intx(pdev, 1);
348 rc = mic_setup_callbacks(mdev);
349 if (rc) {
350 dev_err(&pdev->dev, "Error setting up callbacks\n");
351 goto err_nomem;
352 }
353
354 rc = request_irq(pdev->irq, mic_interrupt,
355 IRQF_SHARED, "mic-intx", mdev);
356 if (rc)
357 goto err;
358
359 dev_dbg(&pdev->dev, "intx irq setup\n");
360 return 0;
361err:
362 mic_release_callbacks(mdev);
363err_nomem:
364 return rc;
365}
366
367/**
368 * mic_next_db - Retrieve the next doorbell interrupt source id.
369 * The id is picked sequentially from the available pool of
370 * doorlbell ids.
371 *
372 * @mdev: pointer to the mic_device instance.
373 *
374 * Returns the next doorbell interrupt source.
375 */
376int mic_next_db(struct mic_device *mdev)
377{
378 int next_db;
379
380 next_db = mdev->irq_info.next_avail_src %
381 mdev->intr_info->intr_len[MIC_INTR_DB];
382 mdev->irq_info.next_avail_src++;
383 return next_db;
384}
385
386#define COOKIE_ID_SHIFT 16
387#define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
388#define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
389#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
390
391/**
392 * mic_request_irq - request an irq. mic_mutex needs
393 * to be held before calling this function.
394 *
395 * @mdev: pointer to mic_device instance
396 * @func: The callback function that handles the interrupt.
397 * The function needs to call ack_interrupts
398 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
399 * @name: The ASCII name of the callee requesting the irq.
400 * @data: private data that is returned back when calling the
401 * function handler.
402 * @intr_src: The source id of the requester. Its the doorbell id
403 * for Doorbell interrupts and DMA channel id for DMA interrupts.
404 * @type: The type of interrupt. Values defined in mic_intr_type
405 *
406 * returns: The cookie that is transparent to the caller. Passed
407 * back when calling mic_free_irq. An appropriate error code
408 * is returned on failure. Caller needs to use IS_ERR(return_val)
409 * to check for failure and PTR_ERR(return_val) to obtained the
410 * error code.
411 *
412 */
413struct mic_irq *mic_request_irq(struct mic_device *mdev,
414 irqreturn_t (*func)(int irq, void *dev),
415 const char *name, void *data, int intr_src,
416 enum mic_intr_type type)
417{
418 u16 offset;
419 int rc = 0;
420 struct msix_entry *msix = NULL;
421 unsigned long cookie = 0;
422 u16 entry;
423 struct mic_intr_cb *intr_cb;
424 struct pci_dev *pdev = container_of(mdev->sdev->parent,
425 struct pci_dev, dev);
426
427 offset = mic_map_src_to_offset(mdev, intr_src, type);
428 if (offset >= MIC_NUM_OFFSETS) {
429 dev_err(mdev->sdev->parent,
430 "Error mapping index %d to a valid source id.\n",
431 intr_src);
432 rc = -EINVAL;
433 goto err;
434 }
435
436 if (mdev->irq_info.num_vectors > 1) {
437 msix = mic_get_available_vector(mdev);
438 if (!msix) {
439 dev_err(mdev->sdev->parent,
440 "No MSIx vectors available for use.\n");
441 rc = -ENOSPC;
442 goto err;
443 }
444
445 rc = request_irq(msix->vector, func, 0, name, data);
446 if (rc) {
447 dev_dbg(mdev->sdev->parent,
448 "request irq failed rc = %d\n", rc);
449 goto err;
450 }
451 entry = msix->entry;
452 mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
453 mdev->intr_ops->program_msi_to_src_map(mdev,
454 entry, offset, true);
455 cookie = MK_COOKIE(entry, offset);
456 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
457 msix->vector, intr_src);
458 } else {
459 intr_cb = mic_register_intr_callback(mdev,
460 offset, func, data);
461 if (IS_ERR(intr_cb)) {
462 dev_err(mdev->sdev->parent,
463 "No available callback entries for use\n");
464 rc = PTR_ERR(intr_cb);
465 goto err;
466 }
467
468 entry = 0;
469 if (pci_dev_msi_enabled(pdev)) {
470 mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
471 mdev->intr_ops->program_msi_to_src_map(mdev,
472 entry, offset, true);
473 }
474 cookie = MK_COOKIE(entry, intr_cb->cb_id);
475 dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
476 intr_cb->cb_id, intr_src);
477 }
478 return (struct mic_irq *)cookie;
479err:
480 return ERR_PTR(rc);
481}
482
483/**
484 * mic_free_irq - free irq. mic_mutex
485 * needs to be held before calling this function.
486 *
487 * @mdev: pointer to mic_device instance
488 * @cookie: cookie obtained during a successful call to mic_request_irq
489 * @data: private data specified by the calling function during the
490 * mic_request_irq
491 *
492 * returns: none.
493 */
494void mic_free_irq(struct mic_device *mdev,
495 struct mic_irq *cookie, void *data)
496{
497 u32 offset;
498 u32 entry;
499 u8 src_id;
500 unsigned int irq;
501 struct pci_dev *pdev = container_of(mdev->sdev->parent,
502 struct pci_dev, dev);
503
504 entry = GET_ENTRY((unsigned long)cookie);
505 offset = GET_OFFSET((unsigned long)cookie);
506 if (mdev->irq_info.num_vectors > 1) {
507 if (entry >= mdev->irq_info.num_vectors) {
508 dev_warn(mdev->sdev->parent,
509 "entry %d should be < num_irq %d\n",
510 entry, mdev->irq_info.num_vectors);
511 return;
512 }
513 irq = mdev->irq_info.msix_entries[entry].vector;
514 free_irq(irq, data);
515 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
516 mdev->intr_ops->program_msi_to_src_map(mdev,
517 entry, offset, false);
518
519 dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
520 } else {
521 irq = pdev->irq;
522 src_id = mic_unregister_intr_callback(mdev, offset);
523 if (src_id >= MIC_NUM_OFFSETS) {
524 dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
525 return;
526 }
527 if (pci_dev_msi_enabled(pdev)) {
528 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
529 mdev->intr_ops->program_msi_to_src_map(mdev,
530 entry, src_id, false);
531 }
532 dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
533 offset, src_id);
534 }
535}
536
537/**
538 * mic_setup_interrupts - Initializes interrupts.
539 *
540 * @mdev: pointer to mic_device instance
541 * @pdev: PCI device structure
542 *
543 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
544 */
545int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
546{
547 int rc;
548
549 rc = mic_setup_msix(mdev, pdev);
550 if (!rc)
551 goto done;
552
553 rc = mic_setup_msi(mdev, pdev);
554 if (!rc)
555 goto done;
556
557 rc = mic_setup_intx(mdev, pdev);
558 if (rc) {
559 dev_err(mdev->sdev->parent, "no usable interrupts\n");
560 return rc;
561 }
562done:
563 mdev->intr_ops->enable_interrupts(mdev);
564 return 0;
565}
566
567/**
568 * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
569 *
570 * @mdev: pointer to mic_device instance
571 * @pdev: PCI device structure
572 *
573 * returns none.
574 */
575void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
576{
577 int i;
578
579 mdev->intr_ops->disable_interrupts(mdev);
580 if (mdev->irq_info.num_vectors > 1) {
581 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
582 if (mdev->irq_info.mic_msi_map[i])
583 dev_warn(&pdev->dev, "irq %d may still be in use.\n",
584 mdev->irq_info.msix_entries[i].vector);
585 }
586 kfree(mdev->irq_info.mic_msi_map);
587 kfree(mdev->irq_info.msix_entries);
588 pci_disable_msix(pdev);
589 } else {
590 if (pci_dev_msi_enabled(pdev)) {
591 free_irq(pdev->irq, mdev);
592 kfree(mdev->irq_info.mic_msi_map);
593 pci_disable_msi(pdev);
594 } else {
595 free_irq(pdev->irq, mdev);
596 }
597 mic_release_callbacks(mdev);
598 }
599}
600
601/**
602 * mic_intr_restore - Restore MIC interrupt registers.
603 *
604 * @mdev: pointer to mic_device instance.
605 *
606 * Restore the interrupt registers to values previously
607 * stored in the SW data structures. mic_mutex needs to
608 * be held before calling this function.
609 *
610 * returns None.
611 */
612void mic_intr_restore(struct mic_device *mdev)
613{
614 int entry, offset;
615 struct pci_dev *pdev = container_of(mdev->sdev->parent,
616 struct pci_dev, dev);
617
618 if (!pci_dev_msi_enabled(pdev))
619 return;
620
621 for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
622 for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
623 if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
624 mdev->intr_ops->program_msi_to_src_map(mdev,
625 entry, offset, true);
626 }
627 }
628}
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h
new file mode 100644
index 000000000000..6091aa97e116
--- /dev/null
+++ b/drivers/misc/mic/host/mic_intr.h
@@ -0,0 +1,137 @@
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_INTR_H_
22#define _MIC_INTR_H_
23
24/*
25 * The minimum number of msix vectors required for normal operation.
26 * 3 for virtio network, console and block devices.
27 * 1 for card shutdown notifications.
28 */
29#define MIC_MIN_MSIX 4
30#define MIC_NUM_OFFSETS 32
31
32/**
33 * mic_intr_source - The type of source that will generate
34 * the interrupt.The number of types needs to be in sync with
35 * MIC_NUM_INTR_TYPES
36 *
37 * MIC_INTR_DB: The source is a doorbell
38 * MIC_INTR_DMA: The source is a DMA channel
39 * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR
40 * MIC_NUM_INTR_TYPES: Total number of interrupt sources.
41 */
42enum mic_intr_type {
43 MIC_INTR_DB = 0,
44 MIC_INTR_DMA,
45 MIC_INTR_ERR,
46 MIC_NUM_INTR_TYPES
47};
48
49/**
50 * struct mic_intr_info - Contains h/w specific interrupt sources
51 * information.
52 *
53 * @intr_start_idx: Contains the starting indexes of the
54 * interrupt types.
55 * @intr_len: Contains the length of the interrupt types.
56 */
57struct mic_intr_info {
58 u16 intr_start_idx[MIC_NUM_INTR_TYPES];
59 u16 intr_len[MIC_NUM_INTR_TYPES];
60};
61
62/**
63 * struct mic_irq_info - OS specific irq information
64 *
65 * @next_avail_src: next available doorbell that can be assigned.
66 * @msix_entries: msix entries allocated while setting up MSI-x
67 * @mic_msi_map: The MSI/MSI-x mapping information.
68 * @num_vectors: The number of MSI/MSI-x vectors that have been allocated.
69 * @cb_ida: callback ID allocator to track the callbacks registered.
70 * @mic_intr_lock: spinlock to protect the interrupt callback list.
71 * @cb_list: Array of callback lists one for each source.
72 */
73struct mic_irq_info {
74 int next_avail_src;
75 struct msix_entry *msix_entries;
76 u32 *mic_msi_map;
77 u16 num_vectors;
78 struct ida cb_ida;
79 spinlock_t mic_intr_lock;
80 struct list_head *cb_list;
81};
82
83/**
84 * struct mic_intr_cb - Interrupt callback structure.
85 *
86 * @func: The callback function
87 * @data: Private data of the requester.
88 * @cb_id: The callback id. Identifies this callback.
89 * @list: list head pointing to the next callback structure.
90 */
91struct mic_intr_cb {
92 irqreturn_t (*func) (int irq, void *data);
93 void *data;
94 int cb_id;
95 struct list_head list;
96};
97
98/**
99 * struct mic_irq - opaque pointer used as cookie
100 */
101struct mic_irq;
102
103/* Forward declaration */
104struct mic_device;
105
106/**
107 * struct mic_hw_intr_ops: MIC HW specific interrupt operations
108 * @intr_init: Initialize H/W specific interrupt information.
109 * @enable_interrupts: Enable interrupts from the hardware.
110 * @disable_interrupts: Disable interrupts from the hardware.
111 * @program_msi_to_src_map: Update MSI mapping registers with
112 * irq information.
113 * @read_msi_to_src_map: Read MSI mapping registers containing
114 * irq information.
115 */
116struct mic_hw_intr_ops {
117 void (*intr_init)(struct mic_device *mdev);
118 void (*enable_interrupts)(struct mic_device *mdev);
119 void (*disable_interrupts)(struct mic_device *mdev);
120 void (*program_msi_to_src_map) (struct mic_device *mdev,
121 int idx, int intr_src, bool set);
122 u32 (*read_msi_to_src_map) (struct mic_device *mdev,
123 int idx);
124};
125
126int mic_next_db(struct mic_device *mdev);
127struct mic_irq *mic_request_irq(struct mic_device *mdev,
128 irqreturn_t (*func)(int irq, void *data),
129 const char *name, void *data, int intr_src,
130 enum mic_intr_type type);
131
132void mic_free_irq(struct mic_device *mdev,
133 struct mic_irq *cookie, void *data);
134int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
135void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev);
136void mic_intr_restore(struct mic_device *mdev);
137#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..a8965d496e84
--- /dev/null
+++ b/drivers/misc/mic/host/mic_main.c
@@ -0,0 +1,478 @@
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/module.h>
27#include <linux/pci.h>
28#include <linux/poll.h>
29
30#include <linux/mic_common.h>
31#include "../common/mic_device.h"
32#include "mic_device.h"
33#include "mic_x100.h"
34#include "mic_smpt.h"
35#include "mic_fops.h"
36#include "mic_virtio.h"
37
38static const char mic_driver_name[] = "mic";
39
40static DEFINE_PCI_DEVICE_TABLE(mic_pci_tbl) = {
41 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)},
42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)},
43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)},
44 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)},
45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)},
46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)},
47 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)},
48 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)},
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)},
56
57 /* required last entry */
58 { 0, }
59};
60
61MODULE_DEVICE_TABLE(pci, mic_pci_tbl);
62
63/* ID allocator for MIC devices */
64static struct ida g_mic_ida;
65/* Class of MIC devices for sysfs accessibility. */
66static struct class *g_mic_class;
67/* Base device node number for MIC devices */
68static dev_t g_mic_devno;
69
70static const struct file_operations mic_fops = {
71 .open = mic_open,
72 .release = mic_release,
73 .unlocked_ioctl = mic_ioctl,
74 .poll = mic_poll,
75 .mmap = mic_mmap,
76 .owner = THIS_MODULE,
77};
78
79/* Initialize the device page */
80static int mic_dp_init(struct mic_device *mdev)
81{
82 mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL);
83 if (!mdev->dp) {
84 dev_err(mdev->sdev->parent, "%s %d err %d\n",
85 __func__, __LINE__, -ENOMEM);
86 return -ENOMEM;
87 }
88
89 mdev->dp_dma_addr = mic_map_single(mdev,
90 mdev->dp, MIC_DP_SIZE);
91 if (mic_map_error(mdev->dp_dma_addr)) {
92 kfree(mdev->dp);
93 dev_err(mdev->sdev->parent, "%s %d err %d\n",
94 __func__, __LINE__, -ENOMEM);
95 return -ENOMEM;
96 }
97 mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
98 mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
99 return 0;
100}
101
102/* Uninitialize the device page */
103static void mic_dp_uninit(struct mic_device *mdev)
104{
105 mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE);
106 kfree(mdev->dp);
107}
108
109/**
110 * mic_shutdown_db - Shutdown doorbell interrupt handler.
111 */
112static irqreturn_t mic_shutdown_db(int irq, void *data)
113{
114 struct mic_device *mdev = data;
115 struct mic_bootparam *bootparam = mdev->dp;
116
117 mdev->ops->ack_interrupt(mdev);
118
119 switch (bootparam->shutdown_status) {
120 case MIC_HALTED:
121 case MIC_POWER_OFF:
122 case MIC_RESTART:
123 /* Fall through */
124 case MIC_CRASHED:
125 schedule_work(&mdev->shutdown_work);
126 break;
127 default:
128 break;
129 };
130 return IRQ_HANDLED;
131}
132
133/**
134 * mic_ops_init: Initialize HW specific operation tables.
135 *
136 * @mdev: pointer to mic_device instance
137 *
138 * returns none.
139 */
140static void mic_ops_init(struct mic_device *mdev)
141{
142 switch (mdev->family) {
143 case MIC_FAMILY_X100:
144 mdev->ops = &mic_x100_ops;
145 mdev->intr_ops = &mic_x100_intr_ops;
146 mdev->smpt_ops = &mic_x100_smpt_ops;
147 break;
148 default:
149 break;
150 }
151}
152
153/**
154 * mic_get_family - Determine hardware family to which this MIC belongs.
155 *
156 * @pdev: The pci device structure
157 *
158 * returns family.
159 */
160static enum mic_hw_family mic_get_family(struct pci_dev *pdev)
161{
162 enum mic_hw_family family;
163
164 switch (pdev->device) {
165 case MIC_X100_PCI_DEVICE_2250:
166 case MIC_X100_PCI_DEVICE_2251:
167 case MIC_X100_PCI_DEVICE_2252:
168 case MIC_X100_PCI_DEVICE_2253:
169 case MIC_X100_PCI_DEVICE_2254:
170 case MIC_X100_PCI_DEVICE_2255:
171 case MIC_X100_PCI_DEVICE_2256:
172 case MIC_X100_PCI_DEVICE_2257:
173 case MIC_X100_PCI_DEVICE_2258:
174 case MIC_X100_PCI_DEVICE_2259:
175 case MIC_X100_PCI_DEVICE_225a:
176 case MIC_X100_PCI_DEVICE_225b:
177 case MIC_X100_PCI_DEVICE_225c:
178 case MIC_X100_PCI_DEVICE_225d:
179 case MIC_X100_PCI_DEVICE_225e:
180 family = MIC_FAMILY_X100;
181 break;
182 default:
183 family = MIC_FAMILY_UNKNOWN;
184 break;
185 }
186 return family;
187}
188
189/**
190 * mic_device_init - Allocates and initializes the MIC device structure
191 *
192 * @mdev: pointer to mic_device instance
193 * @pdev: The pci device structure
194 *
195 * returns none.
196 */
197static void
198mic_device_init(struct mic_device *mdev, struct pci_dev *pdev)
199{
200 mdev->family = mic_get_family(pdev);
201 mdev->stepping = pdev->revision;
202 mic_ops_init(mdev);
203 mic_sysfs_init(mdev);
204 mutex_init(&mdev->mic_mutex);
205 mdev->irq_info.next_avail_src = 0;
206 INIT_WORK(&mdev->reset_trigger_work, mic_reset_trigger_work);
207 INIT_WORK(&mdev->shutdown_work, mic_shutdown_work);
208 INIT_LIST_HEAD(&mdev->vdev_list);
209}
210
211/**
212 * mic_device_uninit - Frees resources allocated during mic_device_init(..)
213 *
214 * @mdev: pointer to mic_device instance
215 *
216 * returns none
217 */
218static void mic_device_uninit(struct mic_device *mdev)
219{
220 /* The cmdline sysfs entry might have allocated cmdline */
221 kfree(mdev->cmdline);
222 kfree(mdev->firmware);
223 kfree(mdev->ramdisk);
224 kfree(mdev->bootmode);
225 flush_work(&mdev->reset_trigger_work);
226 flush_work(&mdev->shutdown_work);
227}
228
229/**
230 * mic_probe - Device Initialization Routine
231 *
232 * @pdev: PCI device structure
233 * @ent: entry in mic_pci_tbl
234 *
235 * returns 0 on success, < 0 on failure.
236 */
237static int mic_probe(struct pci_dev *pdev,
238 const struct pci_device_id *ent)
239{
240 int rc;
241 struct mic_device *mdev;
242
243 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
244 if (!mdev) {
245 rc = -ENOMEM;
246 dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc);
247 goto mdev_alloc_fail;
248 }
249 mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL);
250 if (mdev->id < 0) {
251 rc = mdev->id;
252 dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc);
253 goto ida_fail;
254 }
255
256 mic_device_init(mdev, pdev);
257
258 rc = pci_enable_device(pdev);
259 if (rc) {
260 dev_err(&pdev->dev, "failed to enable pci device.\n");
261 goto uninit_device;
262 }
263
264 pci_set_master(pdev);
265
266 rc = pci_request_regions(pdev, mic_driver_name);
267 if (rc) {
268 dev_err(&pdev->dev, "failed to get pci regions.\n");
269 goto disable_device;
270 }
271
272 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
273 if (rc) {
274 dev_err(&pdev->dev, "Cannot set DMA mask\n");
275 goto release_regions;
276 }
277
278 mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar);
279 mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar);
280 mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar);
281 if (!mdev->mmio.va) {
282 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n");
283 rc = -EIO;
284 goto release_regions;
285 }
286
287 mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar);
288 mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar);
289 mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len);
290 if (!mdev->aper.va) {
291 dev_err(&pdev->dev, "Cannot remap Aperture BAR\n");
292 rc = -EIO;
293 goto unmap_mmio;
294 }
295
296 mdev->intr_ops->intr_init(mdev);
297 rc = mic_setup_interrupts(mdev, pdev);
298 if (rc) {
299 dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc);
300 goto unmap_aper;
301 }
302 rc = mic_smpt_init(mdev);
303 if (rc) {
304 dev_err(&pdev->dev, "smpt_init failed %d\n", rc);
305 goto free_interrupts;
306 }
307
308 pci_set_drvdata(pdev, mdev);
309
310 mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev,
311 MKDEV(MAJOR(g_mic_devno), mdev->id), NULL,
312 mdev->attr_group, "mic%d", mdev->id);
313 if (IS_ERR(mdev->sdev)) {
314 rc = PTR_ERR(mdev->sdev);
315 dev_err(&pdev->dev,
316 "device_create_with_groups failed rc %d\n", rc);
317 goto smpt_uninit;
318 }
319 mdev->state_sysfs = sysfs_get_dirent(mdev->sdev->kobj.sd,
320 NULL, "state");
321 if (!mdev->state_sysfs) {
322 rc = -ENODEV;
323 dev_err(&pdev->dev, "sysfs_get_dirent failed rc %d\n", rc);
324 goto destroy_device;
325 }
326
327 rc = mic_dp_init(mdev);
328 if (rc) {
329 dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc);
330 goto sysfs_put;
331 }
332 mutex_lock(&mdev->mic_mutex);
333
334 mdev->shutdown_db = mic_next_db(mdev);
335 mdev->shutdown_cookie = mic_request_irq(mdev, mic_shutdown_db,
336 "shutdown-interrupt", mdev, mdev->shutdown_db, MIC_INTR_DB);
337 if (IS_ERR(mdev->shutdown_cookie)) {
338 rc = PTR_ERR(mdev->shutdown_cookie);
339 mutex_unlock(&mdev->mic_mutex);
340 goto dp_uninit;
341 }
342 mutex_unlock(&mdev->mic_mutex);
343 mic_bootparam_init(mdev);
344
345 mic_create_debug_dir(mdev);
346 cdev_init(&mdev->cdev, &mic_fops);
347 mdev->cdev.owner = THIS_MODULE;
348 rc = cdev_add(&mdev->cdev, MKDEV(MAJOR(g_mic_devno), mdev->id), 1);
349 if (rc) {
350 dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc);
351 goto cleanup_debug_dir;
352 }
353 return 0;
354cleanup_debug_dir:
355 mic_delete_debug_dir(mdev);
356 mutex_lock(&mdev->mic_mutex);
357 mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
358 mutex_unlock(&mdev->mic_mutex);
359dp_uninit:
360 mic_dp_uninit(mdev);
361sysfs_put:
362 sysfs_put(mdev->state_sysfs);
363destroy_device:
364 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
365smpt_uninit:
366 mic_smpt_uninit(mdev);
367free_interrupts:
368 mic_free_interrupts(mdev, pdev);
369unmap_aper:
370 iounmap(mdev->aper.va);
371unmap_mmio:
372 iounmap(mdev->mmio.va);
373release_regions:
374 pci_release_regions(pdev);
375disable_device:
376 pci_disable_device(pdev);
377uninit_device:
378 mic_device_uninit(mdev);
379 ida_simple_remove(&g_mic_ida, mdev->id);
380ida_fail:
381 kfree(mdev);
382mdev_alloc_fail:
383 dev_err(&pdev->dev, "Probe failed rc %d\n", rc);
384 return rc;
385}
386
387/**
388 * mic_remove - Device Removal Routine
389 * mic_remove is called by the PCI subsystem to alert the driver
390 * that it should release a PCI device.
391 *
392 * @pdev: PCI device structure
393 */
394static void mic_remove(struct pci_dev *pdev)
395{
396 struct mic_device *mdev;
397
398 mdev = pci_get_drvdata(pdev);
399 if (!mdev)
400 return;
401
402 mic_stop(mdev, false);
403 cdev_del(&mdev->cdev);
404 mic_delete_debug_dir(mdev);
405 mutex_lock(&mdev->mic_mutex);
406 mic_free_irq(mdev, mdev->shutdown_cookie, mdev);
407 mutex_unlock(&mdev->mic_mutex);
408 flush_work(&mdev->shutdown_work);
409 mic_dp_uninit(mdev);
410 sysfs_put(mdev->state_sysfs);
411 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id));
412 mic_smpt_uninit(mdev);
413 mic_free_interrupts(mdev, pdev);
414 iounmap(mdev->mmio.va);
415 iounmap(mdev->aper.va);
416 mic_device_uninit(mdev);
417 pci_release_regions(pdev);
418 pci_disable_device(pdev);
419 ida_simple_remove(&g_mic_ida, mdev->id);
420 kfree(mdev);
421}
422static struct pci_driver mic_driver = {
423 .name = mic_driver_name,
424 .id_table = mic_pci_tbl,
425 .probe = mic_probe,
426 .remove = mic_remove
427};
428
429static int __init mic_init(void)
430{
431 int ret;
432
433 ret = alloc_chrdev_region(&g_mic_devno, 0,
434 MIC_MAX_NUM_DEVS, mic_driver_name);
435 if (ret) {
436 pr_err("alloc_chrdev_region failed ret %d\n", ret);
437 goto error;
438 }
439
440 g_mic_class = class_create(THIS_MODULE, mic_driver_name);
441 if (IS_ERR(g_mic_class)) {
442 ret = PTR_ERR(g_mic_class);
443 pr_err("class_create failed ret %d\n", ret);
444 goto cleanup_chrdev;
445 }
446
447 mic_init_debugfs();
448 ida_init(&g_mic_ida);
449 ret = pci_register_driver(&mic_driver);
450 if (ret) {
451 pr_err("pci_register_driver failed ret %d\n", ret);
452 goto cleanup_debugfs;
453 }
454 return ret;
455cleanup_debugfs:
456 mic_exit_debugfs();
457 class_destroy(g_mic_class);
458cleanup_chrdev:
459 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
460error:
461 return ret;
462}
463
464static void __exit mic_exit(void)
465{
466 pci_unregister_driver(&mic_driver);
467 ida_destroy(&g_mic_ida);
468 mic_exit_debugfs();
469 class_destroy(g_mic_class);
470 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS);
471}
472
473module_init(mic_init);
474module_exit(mic_exit);
475
476MODULE_AUTHOR("Intel Corporation");
477MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver");
478MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/mic/host/mic_smpt.c b/drivers/misc/mic/host/mic_smpt.c
new file mode 100644
index 000000000000..a3462076bc57
--- /dev/null
+++ b/drivers/misc/mic/host/mic_smpt.c
@@ -0,0 +1,442 @@
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#include "mic_smpt.h"
26
27static inline u64 mic_system_page_mask(struct mic_device *mdev)
28{
29 return (1ULL << mdev->smpt->info.page_shift) - 1ULL;
30}
31
32static inline u8 mic_sys_addr_to_smpt(struct mic_device *mdev, dma_addr_t pa)
33{
34 return (pa - mdev->smpt->info.base) >> mdev->smpt->info.page_shift;
35}
36
37static inline u64 mic_smpt_to_pa(struct mic_device *mdev, u8 index)
38{
39 return mdev->smpt->info.base + (index * mdev->smpt->info.page_size);
40}
41
42static inline u64 mic_smpt_offset(struct mic_device *mdev, dma_addr_t pa)
43{
44 return pa & mic_system_page_mask(mdev);
45}
46
47static inline u64 mic_smpt_align_low(struct mic_device *mdev, dma_addr_t pa)
48{
49 return ALIGN(pa - mic_system_page_mask(mdev),
50 mdev->smpt->info.page_size);
51}
52
53static inline u64 mic_smpt_align_high(struct mic_device *mdev, dma_addr_t pa)
54{
55 return ALIGN(pa, mdev->smpt->info.page_size);
56}
57
58/* Total Cumulative system memory accessible by MIC across all SMPT entries */
59static inline u64 mic_max_system_memory(struct mic_device *mdev)
60{
61 return mdev->smpt->info.num_reg * mdev->smpt->info.page_size;
62}
63
64/* Maximum system memory address accessible by MIC */
65static inline u64 mic_max_system_addr(struct mic_device *mdev)
66{
67 return mdev->smpt->info.base + mic_max_system_memory(mdev) - 1ULL;
68}
69
70/* Check if the DMA address is a MIC system memory address */
71static inline bool
72mic_is_system_addr(struct mic_device *mdev, dma_addr_t pa)
73{
74 return pa >= mdev->smpt->info.base && pa <= mic_max_system_addr(mdev);
75}
76
77/* Populate an SMPT entry and update the reference counts. */
78static void mic_add_smpt_entry(int spt, s64 *ref, u64 addr,
79 int entries, struct mic_device *mdev)
80{
81 struct mic_smpt_info *smpt_info = mdev->smpt;
82 int i;
83
84 for (i = spt; i < spt + entries; i++,
85 addr += smpt_info->info.page_size) {
86 if (!smpt_info->entry[i].ref_count &&
87 (smpt_info->entry[i].dma_addr != addr)) {
88 mdev->smpt_ops->set(mdev, addr, i);
89 smpt_info->entry[i].dma_addr = addr;
90 }
91 smpt_info->entry[i].ref_count += ref[i - spt];
92 }
93}
94
95/*
96 * Find an available MIC address in MIC SMPT address space
97 * for a given DMA address and size.
98 */
99static dma_addr_t mic_smpt_op(struct mic_device *mdev, u64 dma_addr,
100 int entries, s64 *ref, size_t size)
101{
102 int spt;
103 int ae = 0;
104 int i;
105 unsigned long flags;
106 dma_addr_t mic_addr = 0;
107 dma_addr_t addr = dma_addr;
108 struct mic_smpt_info *smpt_info = mdev->smpt;
109
110 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
111
112 /* find existing entries */
113 for (i = 0; i < smpt_info->info.num_reg; i++) {
114 if (smpt_info->entry[i].dma_addr == addr) {
115 ae++;
116 addr += smpt_info->info.page_size;
117 } else if (ae) /* cannot find contiguous entries */
118 goto not_found;
119
120 if (ae == entries)
121 goto found;
122 }
123
124 /* find free entry */
125 for (ae = 0, i = 0; i < smpt_info->info.num_reg; i++) {
126 ae = (smpt_info->entry[i].ref_count == 0) ? ae + 1 : 0;
127 if (ae == entries)
128 goto found;
129 }
130
131not_found:
132 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
133 return mic_addr;
134
135found:
136 spt = i - entries + 1;
137 mic_addr = mic_smpt_to_pa(mdev, spt);
138 mic_add_smpt_entry(spt, ref, dma_addr, entries, mdev);
139 smpt_info->map_count++;
140 smpt_info->ref_count += (s64)size;
141 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
142 return mic_addr;
143}
144
145/*
146 * Returns number of smpt entries needed for dma_addr to dma_addr + size
147 * also returns the reference count array for each of those entries
148 * and the starting smpt address
149 */
150static int mic_get_smpt_ref_count(struct mic_device *mdev, dma_addr_t dma_addr,
151 size_t size, s64 *ref, u64 *smpt_start)
152{
153 u64 start = dma_addr;
154 u64 end = dma_addr + size;
155 int i = 0;
156
157 while (start < end) {
158 ref[i++] = min(mic_smpt_align_high(mdev, start + 1),
159 end) - start;
160 start = mic_smpt_align_high(mdev, start + 1);
161 }
162
163 if (smpt_start)
164 *smpt_start = mic_smpt_align_low(mdev, dma_addr);
165
166 return i;
167}
168
169/*
170 * mic_to_dma_addr - Converts a MIC address to a DMA address.
171 *
172 * @mdev: pointer to mic_device instance.
173 * @mic_addr: MIC address.
174 *
175 * returns a DMA address.
176 */
177static dma_addr_t
178mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr)
179{
180 struct mic_smpt_info *smpt_info = mdev->smpt;
181 int spt;
182 dma_addr_t dma_addr;
183
184 if (!mic_is_system_addr(mdev, mic_addr)) {
185 dev_err(mdev->sdev->parent,
186 "mic_addr is invalid. mic_addr = 0x%llx\n", mic_addr);
187 return -EINVAL;
188 }
189 spt = mic_sys_addr_to_smpt(mdev, mic_addr);
190 dma_addr = smpt_info->entry[spt].dma_addr +
191 mic_smpt_offset(mdev, mic_addr);
192 return dma_addr;
193}
194
195/**
196 * mic_map - Maps a DMA address to a MIC physical address.
197 *
198 * @mdev: pointer to mic_device instance.
199 * @dma_addr: DMA address.
200 * @size: Size of the region to be mapped.
201 *
202 * This API converts the DMA address provided to a DMA address understood
203 * by MIC. Caller should check for errors by calling mic_map_error(..).
204 *
205 * returns DMA address as required by MIC.
206 */
207dma_addr_t mic_map(struct mic_device *mdev, dma_addr_t dma_addr, size_t size)
208{
209 dma_addr_t mic_addr = 0;
210 int num_entries;
211 s64 *ref;
212 u64 smpt_start;
213
214 if (!size || size > mic_max_system_memory(mdev))
215 return mic_addr;
216
217 ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
218 if (!ref)
219 return mic_addr;
220
221 num_entries = mic_get_smpt_ref_count(mdev, dma_addr, size,
222 ref, &smpt_start);
223
224 /* Set the smpt table appropriately and get 16G aligned mic address */
225 mic_addr = mic_smpt_op(mdev, smpt_start, num_entries, ref, size);
226
227 kfree(ref);
228
229 /*
230 * If mic_addr is zero then its an error case
231 * since mic_addr can never be zero.
232 * else generate mic_addr by adding the 16G offset in dma_addr
233 */
234 if (!mic_addr && MIC_FAMILY_X100 == mdev->family) {
235 dev_err(mdev->sdev->parent,
236 "mic_map failed dma_addr 0x%llx size 0x%lx\n",
237 dma_addr, size);
238 return mic_addr;
239 } else {
240 return mic_addr + mic_smpt_offset(mdev, dma_addr);
241 }
242}
243
244/**
245 * mic_unmap - Unmaps a MIC physical address.
246 *
247 * @mdev: pointer to mic_device instance.
248 * @mic_addr: MIC physical address.
249 * @size: Size of the region to be unmapped.
250 *
251 * This API unmaps the mappings created by mic_map(..).
252 *
253 * returns None.
254 */
255void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
256{
257 struct mic_smpt_info *smpt_info = mdev->smpt;
258 s64 *ref;
259 int num_smpt;
260 int spt;
261 int i;
262 unsigned long flags;
263
264 if (!size)
265 return;
266
267 if (!mic_is_system_addr(mdev, mic_addr)) {
268 dev_err(mdev->sdev->parent,
269 "invalid address: 0x%llx\n", mic_addr);
270 return;
271 }
272
273 spt = mic_sys_addr_to_smpt(mdev, mic_addr);
274 ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL);
275 if (!ref)
276 return;
277
278 /* Get number of smpt entries to be mapped, ref count array */
279 num_smpt = mic_get_smpt_ref_count(mdev, mic_addr, size, ref, NULL);
280
281 spin_lock_irqsave(&smpt_info->smpt_lock, flags);
282 smpt_info->unmap_count++;
283 smpt_info->ref_count -= (s64)size;
284
285 for (i = spt; i < spt + num_smpt; i++) {
286 smpt_info->entry[i].ref_count -= ref[i - spt];
287 if (smpt_info->entry[i].ref_count < 0)
288 dev_warn(mdev->sdev->parent,
289 "ref count for entry %d is negative\n", i);
290 }
291 spin_unlock_irqrestore(&smpt_info->smpt_lock, flags);
292 kfree(ref);
293}
294
295/**
296 * mic_map_single - Maps a virtual address to a MIC physical address.
297 *
298 * @mdev: pointer to mic_device instance.
299 * @va: Kernel direct mapped virtual address.
300 * @size: Size of the region to be mapped.
301 *
302 * This API calls pci_map_single(..) for the direct mapped virtual address
303 * and then converts the DMA address provided to a DMA address understood
304 * by MIC. Caller should check for errors by calling mic_map_error(..).
305 *
306 * returns DMA address as required by MIC.
307 */
308dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size)
309{
310 dma_addr_t mic_addr = 0;
311 struct pci_dev *pdev = container_of(mdev->sdev->parent,
312 struct pci_dev, dev);
313 dma_addr_t dma_addr =
314 pci_map_single(pdev, va, size, PCI_DMA_BIDIRECTIONAL);
315
316 if (!pci_dma_mapping_error(pdev, dma_addr)) {
317 mic_addr = mic_map(mdev, dma_addr, size);
318 if (!mic_addr) {
319 dev_err(mdev->sdev->parent,
320 "mic_map failed dma_addr 0x%llx size 0x%lx\n",
321 dma_addr, size);
322 pci_unmap_single(pdev, dma_addr,
323 size, PCI_DMA_BIDIRECTIONAL);
324 }
325 }
326 return mic_addr;
327}
328
329/**
330 * mic_unmap_single - Unmaps a MIC physical address.
331 *
332 * @mdev: pointer to mic_device instance.
333 * @mic_addr: MIC physical address.
334 * @size: Size of the region to be unmapped.
335 *
336 * This API unmaps the mappings created by mic_map_single(..).
337 *
338 * returns None.
339 */
340void
341mic_unmap_single(struct mic_device *mdev, dma_addr_t mic_addr, size_t size)
342{
343 struct pci_dev *pdev = container_of(mdev->sdev->parent,
344 struct pci_dev, dev);
345 dma_addr_t dma_addr = mic_to_dma_addr(mdev, mic_addr);
346 mic_unmap(mdev, mic_addr, size);
347 pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL);
348}
349
350/**
351 * mic_smpt_init - Initialize MIC System Memory Page Tables.
352 *
353 * @mdev: pointer to mic_device instance.
354 *
355 * returns 0 for success and -errno for error.
356 */
357int mic_smpt_init(struct mic_device *mdev)
358{
359 int i, err = 0;
360 dma_addr_t dma_addr;
361 struct mic_smpt_info *smpt_info;
362
363 mdev->smpt = kmalloc(sizeof(*mdev->smpt), GFP_KERNEL);
364 if (!mdev->smpt)
365 return -ENOMEM;
366
367 smpt_info = mdev->smpt;
368 mdev->smpt_ops->init(mdev);
369 smpt_info->entry = kmalloc(sizeof(struct mic_smpt)
370 * smpt_info->info.num_reg, GFP_KERNEL);
371 if (!smpt_info->entry) {
372 err = -ENOMEM;
373 goto free_smpt;
374 }
375 spin_lock_init(&smpt_info->smpt_lock);
376 for (i = 0; i < smpt_info->info.num_reg; i++) {
377 dma_addr = i * smpt_info->info.page_size;
378 smpt_info->entry[i].dma_addr = dma_addr;
379 smpt_info->entry[i].ref_count = 0;
380 mdev->smpt_ops->set(mdev, dma_addr, i);
381 }
382 smpt_info->ref_count = 0;
383 smpt_info->map_count = 0;
384 smpt_info->unmap_count = 0;
385 return 0;
386free_smpt:
387 kfree(smpt_info);
388 return err;
389}
390
391/**
392 * mic_smpt_uninit - UnInitialize MIC System Memory Page Tables.
393 *
394 * @mdev: pointer to mic_device instance.
395 *
396 * returns None.
397 */
398void mic_smpt_uninit(struct mic_device *mdev)
399{
400 struct mic_smpt_info *smpt_info = mdev->smpt;
401 int i;
402
403 dev_dbg(mdev->sdev->parent,
404 "nodeid %d SMPT ref count %lld map %lld unmap %lld\n",
405 mdev->id, smpt_info->ref_count,
406 smpt_info->map_count, smpt_info->unmap_count);
407
408 for (i = 0; i < smpt_info->info.num_reg; i++) {
409 dev_dbg(mdev->sdev->parent,
410 "SMPT entry[%d] dma_addr = 0x%llx ref_count = %lld\n",
411 i, smpt_info->entry[i].dma_addr,
412 smpt_info->entry[i].ref_count);
413 if (smpt_info->entry[i].ref_count)
414 dev_warn(mdev->sdev->parent,
415 "ref count for entry %d is not zero\n", i);
416 }
417 kfree(smpt_info->entry);
418 kfree(smpt_info);
419}
420
421/**
422 * mic_smpt_restore - Restore MIC System Memory Page Tables.
423 *
424 * @mdev: pointer to mic_device instance.
425 *
426 * Restore the SMPT registers to values previously stored in the
427 * SW data structures. Some MIC steppings lose register state
428 * across resets and this API should be called for performing
429 * a restore operation if required.
430 *
431 * returns None.
432 */
433void mic_smpt_restore(struct mic_device *mdev)
434{
435 int i;
436 dma_addr_t dma_addr;
437
438 for (i = 0; i < mdev->smpt->info.num_reg; i++) {
439 dma_addr = mdev->smpt->entry[i].dma_addr;
440 mdev->smpt_ops->set(mdev, dma_addr, i);
441 }
442}
diff --git a/drivers/misc/mic/host/mic_smpt.h b/drivers/misc/mic/host/mic_smpt.h
new file mode 100644
index 000000000000..51970abfe7df
--- /dev/null
+++ b/drivers/misc/mic/host/mic_smpt.h
@@ -0,0 +1,98 @@
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_SMPT_H
22#define MIC_SMPT_H
23/**
24 * struct mic_smpt_ops - MIC HW specific SMPT operations.
25 * @init: Initialize hardware specific SMPT information in mic_smpt_hw_info.
26 * @set: Set the value for a particular SMPT entry.
27 */
28struct mic_smpt_ops {
29 void (*init)(struct mic_device *mdev);
30 void (*set)(struct mic_device *mdev, dma_addr_t dma_addr, u8 index);
31};
32
33/**
34 * struct mic_smpt - MIC SMPT entry information.
35 * @dma_addr: Base DMA address for this SMPT entry.
36 * @ref_count: Number of active mappings for this SMPT entry in bytes.
37 */
38struct mic_smpt {
39 dma_addr_t dma_addr;
40 s64 ref_count;
41};
42
43/**
44 * struct mic_smpt_hw_info - MIC SMPT hardware specific information.
45 * @num_reg: Number of SMPT registers.
46 * @page_shift: System memory page shift.
47 * @page_size: System memory page size.
48 * @base: System address base.
49 */
50struct mic_smpt_hw_info {
51 u8 num_reg;
52 u8 page_shift;
53 u64 page_size;
54 u64 base;
55};
56
57/**
58 * struct mic_smpt_info - MIC SMPT information.
59 * @entry: Array of SMPT entries.
60 * @smpt_lock: Spin lock protecting access to SMPT data structures.
61 * @info: Hardware specific SMPT information.
62 * @ref_count: Number of active SMPT mappings (for debug).
63 * @map_count: Number of SMPT mappings created (for debug).
64 * @unmap_count: Number of SMPT mappings destroyed (for debug).
65 */
66struct mic_smpt_info {
67 struct mic_smpt *entry;
68 spinlock_t smpt_lock;
69 struct mic_smpt_hw_info info;
70 s64 ref_count;
71 s64 map_count;
72 s64 unmap_count;
73};
74
75dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size);
76void mic_unmap_single(struct mic_device *mdev,
77 dma_addr_t mic_addr, size_t size);
78dma_addr_t mic_map(struct mic_device *mdev,
79 dma_addr_t dma_addr, size_t size);
80void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size);
81
82/**
83 * mic_map_error - Check a MIC address for errors.
84 *
85 * @mdev: pointer to mic_device instance.
86 *
87 * returns Whether there was an error during mic_map..(..) APIs.
88 */
89static inline bool mic_map_error(dma_addr_t mic_addr)
90{
91 return !mic_addr;
92}
93
94int mic_smpt_init(struct mic_device *mdev);
95void mic_smpt_uninit(struct mic_device *mdev);
96void mic_smpt_restore(struct mic_device *mdev);
97
98#endif
diff --git a/drivers/misc/mic/host/mic_sysfs.c b/drivers/misc/mic/host/mic_sysfs.c
new file mode 100644
index 000000000000..aaf849945111
--- /dev/null
+++ b/drivers/misc/mic/host/mic_sysfs.c
@@ -0,0 +1,466 @@
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 <linux/mic_common.h>
24#include "../common/mic_device.h"
25#include "mic_device.h"
26
27/*
28 * A state-to-string lookup table, for exposing a human readable state
29 * via sysfs. Always keep in sync with enum mic_states
30 */
31static const char * const mic_state_string[] = {
32 [MIC_OFFLINE] = "offline",
33 [MIC_ONLINE] = "online",
34 [MIC_SHUTTING_DOWN] = "shutting_down",
35 [MIC_RESET_FAILED] = "reset_failed",
36};
37
38/*
39 * A shutdown-status-to-string lookup table, for exposing a human
40 * readable state via sysfs. Always keep in sync with enum mic_shutdown_status
41 */
42static const char * const mic_shutdown_status_string[] = {
43 [MIC_NOP] = "nop",
44 [MIC_CRASHED] = "crashed",
45 [MIC_HALTED] = "halted",
46 [MIC_POWER_OFF] = "poweroff",
47 [MIC_RESTART] = "restart",
48};
49
50void mic_set_shutdown_status(struct mic_device *mdev, u8 shutdown_status)
51{
52 dev_dbg(mdev->sdev->parent, "Shutdown Status %s -> %s\n",
53 mic_shutdown_status_string[mdev->shutdown_status],
54 mic_shutdown_status_string[shutdown_status]);
55 mdev->shutdown_status = shutdown_status;
56}
57
58void mic_set_state(struct mic_device *mdev, u8 state)
59{
60 dev_dbg(mdev->sdev->parent, "State %s -> %s\n",
61 mic_state_string[mdev->state],
62 mic_state_string[state]);
63 mdev->state = state;
64 sysfs_notify_dirent(mdev->state_sysfs);
65}
66
67static ssize_t
68mic_show_family(struct device *dev, struct device_attribute *attr, char *buf)
69{
70 static const char x100[] = "x100";
71 static const char unknown[] = "Unknown";
72 const char *card = NULL;
73 struct mic_device *mdev = dev_get_drvdata(dev->parent);
74
75 if (!mdev)
76 return -EINVAL;
77
78 switch (mdev->family) {
79 case MIC_FAMILY_X100:
80 card = x100;
81 break;
82 default:
83 card = unknown;
84 break;
85 }
86 return scnprintf(buf, PAGE_SIZE, "%s\n", card);
87}
88static DEVICE_ATTR(family, S_IRUGO, mic_show_family, NULL);
89
90static ssize_t
91mic_show_stepping(struct device *dev, struct device_attribute *attr, char *buf)
92{
93 struct mic_device *mdev = dev_get_drvdata(dev->parent);
94 char *string = "??";
95
96 if (!mdev)
97 return -EINVAL;
98
99 switch (mdev->stepping) {
100 case MIC_A0_STEP:
101 string = "A0";
102 break;
103 case MIC_B0_STEP:
104 string = "B0";
105 break;
106 case MIC_B1_STEP:
107 string = "B1";
108 break;
109 case MIC_C0_STEP:
110 string = "C0";
111 break;
112 default:
113 break;
114 }
115 return scnprintf(buf, PAGE_SIZE, "%s\n", string);
116}
117static DEVICE_ATTR(stepping, S_IRUGO, mic_show_stepping, NULL);
118
119static ssize_t
120mic_show_state(struct device *dev, struct device_attribute *attr, char *buf)
121{
122 struct mic_device *mdev = dev_get_drvdata(dev->parent);
123
124 if (!mdev || mdev->state >= MIC_LAST)
125 return -EINVAL;
126
127 return scnprintf(buf, PAGE_SIZE, "%s\n",
128 mic_state_string[mdev->state]);
129}
130
131static ssize_t
132mic_store_state(struct device *dev, struct device_attribute *attr,
133 const char *buf, size_t count)
134{
135 int rc = 0;
136 struct mic_device *mdev = dev_get_drvdata(dev->parent);
137 if (!mdev)
138 return -EINVAL;
139 if (sysfs_streq(buf, "boot")) {
140 rc = mic_start(mdev, buf);
141 if (rc) {
142 dev_err(mdev->sdev->parent,
143 "mic_boot failed rc %d\n", rc);
144 count = rc;
145 }
146 goto done;
147 }
148
149 if (sysfs_streq(buf, "reset")) {
150 schedule_work(&mdev->reset_trigger_work);
151 goto done;
152 }
153
154 if (sysfs_streq(buf, "shutdown")) {
155 mic_shutdown(mdev);
156 goto done;
157 }
158
159 count = -EINVAL;
160done:
161 return count;
162}
163static DEVICE_ATTR(state, S_IRUGO|S_IWUSR, mic_show_state, mic_store_state);
164
165static ssize_t mic_show_shutdown_status(struct device *dev,
166 struct device_attribute *attr, char *buf)
167{
168 struct mic_device *mdev = dev_get_drvdata(dev->parent);
169
170 if (!mdev || mdev->shutdown_status >= MIC_STATUS_LAST)
171 return -EINVAL;
172
173 return scnprintf(buf, PAGE_SIZE, "%s\n",
174 mic_shutdown_status_string[mdev->shutdown_status]);
175}
176static DEVICE_ATTR(shutdown_status, S_IRUGO|S_IWUSR,
177 mic_show_shutdown_status, NULL);
178
179static ssize_t
180mic_show_cmdline(struct device *dev, struct device_attribute *attr, char *buf)
181{
182 struct mic_device *mdev = dev_get_drvdata(dev->parent);
183 char *cmdline;
184
185 if (!mdev)
186 return -EINVAL;
187
188 cmdline = mdev->cmdline;
189
190 if (cmdline)
191 return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
192 return 0;
193}
194
195static ssize_t
196mic_store_cmdline(struct device *dev, struct device_attribute *attr,
197 const char *buf, size_t count)
198{
199 struct mic_device *mdev = dev_get_drvdata(dev->parent);
200
201 if (!mdev)
202 return -EINVAL;
203
204 mutex_lock(&mdev->mic_mutex);
205 kfree(mdev->cmdline);
206
207 mdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
208 if (!mdev->cmdline) {
209 count = -ENOMEM;
210 goto unlock;
211 }
212
213 strncpy(mdev->cmdline, buf, count);
214
215 if (mdev->cmdline[count - 1] == '\n')
216 mdev->cmdline[count - 1] = '\0';
217 else
218 mdev->cmdline[count] = '\0';
219unlock:
220 mutex_unlock(&mdev->mic_mutex);
221 return count;
222}
223static DEVICE_ATTR(cmdline, S_IRUGO | S_IWUSR,
224 mic_show_cmdline, mic_store_cmdline);
225
226static ssize_t
227mic_show_firmware(struct device *dev, struct device_attribute *attr, char *buf)
228{
229 struct mic_device *mdev = dev_get_drvdata(dev->parent);
230 char *firmware;
231
232 if (!mdev)
233 return -EINVAL;
234
235 firmware = mdev->firmware;
236
237 if (firmware)
238 return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
239 return 0;
240}
241
242static ssize_t
243mic_store_firmware(struct device *dev, struct device_attribute *attr,
244 const char *buf, size_t count)
245{
246 struct mic_device *mdev = dev_get_drvdata(dev->parent);
247
248 if (!mdev)
249 return -EINVAL;
250
251 mutex_lock(&mdev->mic_mutex);
252 kfree(mdev->firmware);
253
254 mdev->firmware = kmalloc(count + 1, GFP_KERNEL);
255 if (!mdev->firmware) {
256 count = -ENOMEM;
257 goto unlock;
258 }
259 strncpy(mdev->firmware, buf, count);
260
261 if (mdev->firmware[count - 1] == '\n')
262 mdev->firmware[count - 1] = '\0';
263 else
264 mdev->firmware[count] = '\0';
265unlock:
266 mutex_unlock(&mdev->mic_mutex);
267 return count;
268}
269static DEVICE_ATTR(firmware, S_IRUGO | S_IWUSR,
270 mic_show_firmware, mic_store_firmware);
271
272static ssize_t
273mic_show_ramdisk(struct device *dev, struct device_attribute *attr, char *buf)
274{
275 struct mic_device *mdev = dev_get_drvdata(dev->parent);
276 char *ramdisk;
277
278 if (!mdev)
279 return -EINVAL;
280
281 ramdisk = mdev->ramdisk;
282
283 if (ramdisk)
284 return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
285 return 0;
286}
287
288static ssize_t
289mic_store_ramdisk(struct device *dev, struct device_attribute *attr,
290 const char *buf, size_t count)
291{
292 struct mic_device *mdev = dev_get_drvdata(dev->parent);
293
294 if (!mdev)
295 return -EINVAL;
296
297 mutex_lock(&mdev->mic_mutex);
298 kfree(mdev->ramdisk);
299
300 mdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
301 if (!mdev->ramdisk) {
302 count = -ENOMEM;
303 goto unlock;
304 }
305
306 strncpy(mdev->ramdisk, buf, count);
307
308 if (mdev->ramdisk[count - 1] == '\n')
309 mdev->ramdisk[count - 1] = '\0';
310 else
311 mdev->ramdisk[count] = '\0';
312unlock:
313 mutex_unlock(&mdev->mic_mutex);
314 return count;
315}
316static DEVICE_ATTR(ramdisk, S_IRUGO | S_IWUSR,
317 mic_show_ramdisk, mic_store_ramdisk);
318
319static ssize_t
320mic_show_bootmode(struct device *dev, struct device_attribute *attr, char *buf)
321{
322 struct mic_device *mdev = dev_get_drvdata(dev->parent);
323 char *bootmode;
324
325 if (!mdev)
326 return -EINVAL;
327
328 bootmode = mdev->bootmode;
329
330 if (bootmode)
331 return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
332 return 0;
333}
334
335static ssize_t
336mic_store_bootmode(struct device *dev, struct device_attribute *attr,
337 const char *buf, size_t count)
338{
339 struct mic_device *mdev = dev_get_drvdata(dev->parent);
340
341 if (!mdev)
342 return -EINVAL;
343
344 if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "elf"))
345 return -EINVAL;
346
347 mutex_lock(&mdev->mic_mutex);
348 kfree(mdev->bootmode);
349
350 mdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
351 if (!mdev->bootmode) {
352 count = -ENOMEM;
353 goto unlock;
354 }
355
356 strncpy(mdev->bootmode, buf, count);
357
358 if (mdev->bootmode[count - 1] == '\n')
359 mdev->bootmode[count - 1] = '\0';
360 else
361 mdev->bootmode[count] = '\0';
362unlock:
363 mutex_unlock(&mdev->mic_mutex);
364 return count;
365}
366static DEVICE_ATTR(bootmode, S_IRUGO | S_IWUSR,
367 mic_show_bootmode, mic_store_bootmode);
368
369static ssize_t
370mic_show_log_buf_addr(struct device *dev, struct device_attribute *attr,
371 char *buf)
372{
373 struct mic_device *mdev = dev_get_drvdata(dev->parent);
374
375 if (!mdev)
376 return -EINVAL;
377
378 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_addr);
379}
380
381static ssize_t
382mic_store_log_buf_addr(struct device *dev, struct device_attribute *attr,
383 const char *buf, size_t count)
384{
385 struct mic_device *mdev = dev_get_drvdata(dev->parent);
386 int ret;
387 unsigned long addr;
388
389 if (!mdev)
390 return -EINVAL;
391
392 ret = kstrtoul(buf, 16, &addr);
393 if (ret)
394 goto exit;
395
396 mdev->log_buf_addr = (void *)addr;
397 ret = count;
398exit:
399 return ret;
400}
401static DEVICE_ATTR(log_buf_addr, S_IRUGO | S_IWUSR,
402 mic_show_log_buf_addr, mic_store_log_buf_addr);
403
404static ssize_t
405mic_show_log_buf_len(struct device *dev, struct device_attribute *attr,
406 char *buf)
407{
408 struct mic_device *mdev = dev_get_drvdata(dev->parent);
409
410 if (!mdev)
411 return -EINVAL;
412
413 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_len);
414}
415
416static ssize_t
417mic_store_log_buf_len(struct device *dev, struct device_attribute *attr,
418 const char *buf, size_t count)
419{
420 struct mic_device *mdev = dev_get_drvdata(dev->parent);
421 int ret;
422 unsigned long addr;
423
424 if (!mdev)
425 return -EINVAL;
426
427 ret = kstrtoul(buf, 16, &addr);
428 if (ret)
429 goto exit;
430
431 mdev->log_buf_len = (int *)addr;
432 ret = count;
433exit:
434 return ret;
435}
436static DEVICE_ATTR(log_buf_len, S_IRUGO | S_IWUSR,
437 mic_show_log_buf_len, mic_store_log_buf_len);
438
439static struct attribute *mic_default_attrs[] = {
440 &dev_attr_family.attr,
441 &dev_attr_stepping.attr,
442 &dev_attr_state.attr,
443 &dev_attr_shutdown_status.attr,
444 &dev_attr_cmdline.attr,
445 &dev_attr_firmware.attr,
446 &dev_attr_ramdisk.attr,
447 &dev_attr_bootmode.attr,
448 &dev_attr_log_buf_addr.attr,
449 &dev_attr_log_buf_len.attr,
450
451 NULL
452};
453
454static struct attribute_group mic_attr_group = {
455 .attrs = mic_default_attrs,
456};
457
458static const struct attribute_group *__mic_attr_group[] = {
459 &mic_attr_group,
460 NULL
461};
462
463void mic_sysfs_init(struct mic_device *mdev)
464{
465 mdev->attr_group = __mic_attr_group;
466}
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
new file mode 100644
index 000000000000..be2a1f06c4ca
--- /dev/null
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -0,0 +1,703 @@
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#include <linux/sched.h>
23#include <linux/uaccess.h>
24
25#include <linux/mic_common.h>
26#include "../common/mic_device.h"
27#include "mic_device.h"
28#include "mic_smpt.h"
29#include "mic_virtio.h"
30
31/*
32 * Initiates the copies across the PCIe bus from card memory to
33 * a user space buffer.
34 */
35static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
36 void __user *ubuf, size_t len, u64 addr)
37{
38 int err;
39 void __iomem *dbuf = mvdev->mdev->aper.va + addr;
40 /*
41 * We are copying from IO below an should ideally use something
42 * like copy_to_user_fromio(..) if it existed.
43 */
44 if (copy_to_user(ubuf, dbuf, len)) {
45 err = -EFAULT;
46 dev_err(mic_dev(mvdev), "%s %d err %d\n",
47 __func__, __LINE__, err);
48 goto err;
49 }
50 mvdev->in_bytes += len;
51 err = 0;
52err:
53 return err;
54}
55
56/*
57 * Initiates copies across the PCIe bus from a user space
58 * buffer to card memory.
59 */
60static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
61 void __user *ubuf, size_t len, u64 addr)
62{
63 int err;
64 void __iomem *dbuf = mvdev->mdev->aper.va + addr;
65 /*
66 * We are copying to IO below and should ideally use something
67 * like copy_from_user_toio(..) if it existed.
68 */
69 if (copy_from_user(dbuf, ubuf, len)) {
70 err = -EFAULT;
71 dev_err(mic_dev(mvdev), "%s %d err %d\n",
72 __func__, __LINE__, err);
73 goto err;
74 }
75 mvdev->out_bytes += len;
76 err = 0;
77err:
78 return err;
79}
80
81#define MIC_VRINGH_READ true
82
83/* The function to call to notify the card about added buffers */
84static void mic_notify(struct vringh *vrh)
85{
86 struct mic_vringh *mvrh = container_of(vrh, struct mic_vringh, vrh);
87 struct mic_vdev *mvdev = mvrh->mvdev;
88 s8 db = mvdev->dc->h2c_vdev_db;
89
90 if (db != -1)
91 mvdev->mdev->ops->send_intr(mvdev->mdev, db);
92}
93
94/* Determine the total number of bytes consumed in a VRINGH KIOV */
95static inline u32 mic_vringh_iov_consumed(struct vringh_kiov *iov)
96{
97 int i;
98 u32 total = iov->consumed;
99
100 for (i = 0; i < iov->i; i++)
101 total += iov->iov[i].iov_len;
102 return total;
103}
104
105/*
106 * Traverse the VRINGH KIOV and issue the APIs to trigger the copies.
107 * This API is heavily based on the vringh_iov_xfer(..) implementation
108 * in vringh.c. The reason we cannot reuse vringh_iov_pull_kern(..)
109 * and vringh_iov_push_kern(..) directly is because there is no
110 * way to override the VRINGH xfer(..) routines as of v3.10.
111 */
112static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
113 void __user *ubuf, size_t len, bool read, size_t *out_len)
114{
115 int ret = 0;
116 size_t partlen, tot_len = 0;
117
118 while (len && iov->i < iov->used) {
119 partlen = min(iov->iov[iov->i].iov_len, len);
120 if (read)
121 ret = mic_virtio_copy_to_user(mvdev,
122 ubuf, partlen,
123 (u64)iov->iov[iov->i].iov_base);
124 else
125 ret = mic_virtio_copy_from_user(mvdev,
126 ubuf, partlen,
127 (u64)iov->iov[iov->i].iov_base);
128 if (ret) {
129 dev_err(mic_dev(mvdev), "%s %d err %d\n",
130 __func__, __LINE__, ret);
131 break;
132 }
133 len -= partlen;
134 ubuf += partlen;
135 tot_len += partlen;
136 iov->consumed += partlen;
137 iov->iov[iov->i].iov_len -= partlen;
138 iov->iov[iov->i].iov_base += partlen;
139 if (!iov->iov[iov->i].iov_len) {
140 /* Fix up old iov element then increment. */
141 iov->iov[iov->i].iov_len = iov->consumed;
142 iov->iov[iov->i].iov_base -= iov->consumed;
143
144 iov->consumed = 0;
145 iov->i++;
146 }
147 }
148 *out_len = tot_len;
149 return ret;
150}
151
152/*
153 * Use the standard VRINGH infrastructure in the kernel to fetch new
154 * descriptors, initiate the copies and update the used ring.
155 */
156static int _mic_virtio_copy(struct mic_vdev *mvdev,
157 struct mic_copy_desc *copy)
158{
159 int ret = 0, iovcnt = copy->iovcnt;
160 struct iovec iov;
161 struct iovec __user *u_iov = copy->iov;
162 void __user *ubuf = NULL;
163 struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
164 struct vringh_kiov *riov = &mvr->riov;
165 struct vringh_kiov *wiov = &mvr->wiov;
166 struct vringh *vrh = &mvr->vrh;
167 u16 *head = &mvr->head;
168 struct mic_vring *vr = &mvr->vring;
169 size_t len = 0, out_len;
170
171 copy->out_len = 0;
172 /* Fetch a new IOVEC if all previous elements have been processed */
173 if (riov->i == riov->used && wiov->i == wiov->used) {
174 ret = vringh_getdesc_kern(vrh, riov, wiov,
175 head, GFP_KERNEL);
176 /* Check if there are available descriptors */
177 if (ret <= 0)
178 return ret;
179 }
180 while (iovcnt) {
181 if (!len) {
182 /* Copy over a new iovec from user space. */
183 ret = copy_from_user(&iov, u_iov, sizeof(*u_iov));
184 if (ret) {
185 ret = -EINVAL;
186 dev_err(mic_dev(mvdev), "%s %d err %d\n",
187 __func__, __LINE__, ret);
188 break;
189 }
190 len = iov.iov_len;
191 ubuf = iov.iov_base;
192 }
193 /* Issue all the read descriptors first */
194 ret = mic_vringh_copy(mvdev, riov, ubuf, len,
195 MIC_VRINGH_READ, &out_len);
196 if (ret) {
197 dev_err(mic_dev(mvdev), "%s %d err %d\n",
198 __func__, __LINE__, ret);
199 break;
200 }
201 len -= out_len;
202 ubuf += out_len;
203 copy->out_len += out_len;
204 /* Issue the write descriptors next */
205 ret = mic_vringh_copy(mvdev, wiov, ubuf, len,
206 !MIC_VRINGH_READ, &out_len);
207 if (ret) {
208 dev_err(mic_dev(mvdev), "%s %d err %d\n",
209 __func__, __LINE__, ret);
210 break;
211 }
212 len -= out_len;
213 ubuf += out_len;
214 copy->out_len += out_len;
215 if (!len) {
216 /* One user space iovec is now completed */
217 iovcnt--;
218 u_iov++;
219 }
220 /* Exit loop if all elements in KIOVs have been processed. */
221 if (riov->i == riov->used && wiov->i == wiov->used)
222 break;
223 }
224 /*
225 * Update the used ring if a descriptor was available and some data was
226 * copied in/out and the user asked for a used ring update.
227 */
228 if (*head != USHRT_MAX && copy->out_len &&
229 copy->update_used) {
230 u32 total = 0;
231
232 /* Determine the total data consumed */
233 total += mic_vringh_iov_consumed(riov);
234 total += mic_vringh_iov_consumed(wiov);
235 vringh_complete_kern(vrh, *head, total);
236 *head = USHRT_MAX;
237 if (vringh_need_notify_kern(vrh) > 0)
238 vringh_notify(vrh);
239 vringh_kiov_cleanup(riov);
240 vringh_kiov_cleanup(wiov);
241 /* Update avail idx for user space */
242 vr->info->avail_idx = vrh->last_avail_idx;
243 }
244 return ret;
245}
246
247static inline int mic_verify_copy_args(struct mic_vdev *mvdev,
248 struct mic_copy_desc *copy)
249{
250 if (copy->vr_idx >= mvdev->dd->num_vq) {
251 dev_err(mic_dev(mvdev), "%s %d err %d\n",
252 __func__, __LINE__, -EINVAL);
253 return -EINVAL;
254 }
255 return 0;
256}
257
258/* Copy a specified number of virtio descriptors in a chain */
259int mic_virtio_copy_desc(struct mic_vdev *mvdev,
260 struct mic_copy_desc *copy)
261{
262 int err;
263 struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
264
265 err = mic_verify_copy_args(mvdev, copy);
266 if (err)
267 return err;
268
269 mutex_lock(&mvr->vr_mutex);
270 if (!mic_vdevup(mvdev)) {
271 err = -ENODEV;
272 dev_err(mic_dev(mvdev), "%s %d err %d\n",
273 __func__, __LINE__, err);
274 goto err;
275 }
276 err = _mic_virtio_copy(mvdev, copy);
277 if (err) {
278 dev_err(mic_dev(mvdev), "%s %d err %d\n",
279 __func__, __LINE__, err);
280 }
281err:
282 mutex_unlock(&mvr->vr_mutex);
283 return err;
284}
285
286static void mic_virtio_init_post(struct mic_vdev *mvdev)
287{
288 struct mic_vqconfig *vqconfig = mic_vq_config(mvdev->dd);
289 int i;
290
291 for (i = 0; i < mvdev->dd->num_vq; i++) {
292 if (!le64_to_cpu(vqconfig[i].used_address)) {
293 dev_warn(mic_dev(mvdev), "used_address zero??\n");
294 continue;
295 }
296 mvdev->mvr[i].vrh.vring.used =
297 mvdev->mdev->aper.va +
298 le64_to_cpu(vqconfig[i].used_address);
299 }
300
301 mvdev->dc->used_address_updated = 0;
302
303 dev_dbg(mic_dev(mvdev), "%s: device type %d LINKUP\n",
304 __func__, mvdev->virtio_id);
305}
306
307static inline void mic_virtio_device_reset(struct mic_vdev *mvdev)
308{
309 int i;
310
311 dev_dbg(mic_dev(mvdev), "%s: status %d device type %d RESET\n",
312 __func__, mvdev->dd->status, mvdev->virtio_id);
313
314 for (i = 0; i < mvdev->dd->num_vq; i++)
315 /*
316 * Avoid lockdep false positive. The + 1 is for the mic
317 * mutex which is held in the reset devices code path.
318 */
319 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
320
321 /* 0 status means "reset" */
322 mvdev->dd->status = 0;
323 mvdev->dc->vdev_reset = 0;
324 mvdev->dc->host_ack = 1;
325
326 for (i = 0; i < mvdev->dd->num_vq; i++) {
327 struct vringh *vrh = &mvdev->mvr[i].vrh;
328 mvdev->mvr[i].vring.info->avail_idx = 0;
329 vrh->completed = 0;
330 vrh->last_avail_idx = 0;
331 vrh->last_used_idx = 0;
332 }
333
334 for (i = 0; i < mvdev->dd->num_vq; i++)
335 mutex_unlock(&mvdev->mvr[i].vr_mutex);
336}
337
338void mic_virtio_reset_devices(struct mic_device *mdev)
339{
340 struct list_head *pos, *tmp;
341 struct mic_vdev *mvdev;
342
343 dev_dbg(mdev->sdev->parent, "%s\n", __func__);
344
345 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
346 mvdev = list_entry(pos, struct mic_vdev, list);
347 mic_virtio_device_reset(mvdev);
348 mvdev->poll_wake = 1;
349 wake_up(&mvdev->waitq);
350 }
351}
352
353void mic_bh_handler(struct work_struct *work)
354{
355 struct mic_vdev *mvdev = container_of(work, struct mic_vdev,
356 virtio_bh_work);
357
358 if (mvdev->dc->used_address_updated)
359 mic_virtio_init_post(mvdev);
360
361 if (mvdev->dc->vdev_reset)
362 mic_virtio_device_reset(mvdev);
363
364 mvdev->poll_wake = 1;
365 wake_up(&mvdev->waitq);
366}
367
368static irqreturn_t mic_virtio_intr_handler(int irq, void *data)
369{
370
371 struct mic_vdev *mvdev = data;
372 struct mic_device *mdev = mvdev->mdev;
373
374 mdev->ops->ack_interrupt(mdev);
375 schedule_work(&mvdev->virtio_bh_work);
376 return IRQ_HANDLED;
377}
378
379int mic_virtio_config_change(struct mic_vdev *mvdev,
380 void __user *argp)
381{
382 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
383 int ret = 0, retry = 100, i;
384 struct mic_bootparam *bootparam = mvdev->mdev->dp;
385 s8 db = bootparam->h2c_config_db;
386
387 mutex_lock(&mvdev->mdev->mic_mutex);
388 for (i = 0; i < mvdev->dd->num_vq; i++)
389 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
390
391 if (db == -1 || mvdev->dd->type == -1) {
392 ret = -EIO;
393 goto exit;
394 }
395
396 if (copy_from_user(mic_vq_configspace(mvdev->dd),
397 argp, mvdev->dd->config_len)) {
398 dev_err(mic_dev(mvdev), "%s %d err %d\n",
399 __func__, __LINE__, -EFAULT);
400 ret = -EFAULT;
401 goto exit;
402 }
403 mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
404 mvdev->mdev->ops->send_intr(mvdev->mdev, db);
405
406 for (i = retry; i--;) {
407 ret = wait_event_timeout(wake,
408 mvdev->dc->guest_ack, msecs_to_jiffies(100));
409 if (ret)
410 break;
411 }
412
413 dev_dbg(mic_dev(mvdev),
414 "%s %d retry: %d\n", __func__, __LINE__, retry);
415 mvdev->dc->config_change = 0;
416 mvdev->dc->guest_ack = 0;
417exit:
418 for (i = 0; i < mvdev->dd->num_vq; i++)
419 mutex_unlock(&mvdev->mvr[i].vr_mutex);
420 mutex_unlock(&mvdev->mdev->mic_mutex);
421 return ret;
422}
423
424static int mic_copy_dp_entry(struct mic_vdev *mvdev,
425 void __user *argp,
426 __u8 *type,
427 struct mic_device_desc **devpage)
428{
429 struct mic_device *mdev = mvdev->mdev;
430 struct mic_device_desc dd, *dd_config, *devp;
431 struct mic_vqconfig *vqconfig;
432 int ret = 0, i;
433 bool slot_found = false;
434
435 if (copy_from_user(&dd, argp, sizeof(dd))) {
436 dev_err(mic_dev(mvdev), "%s %d err %d\n",
437 __func__, __LINE__, -EFAULT);
438 return -EFAULT;
439 }
440
441 if (mic_aligned_desc_size(&dd) > MIC_MAX_DESC_BLK_SIZE
442 || dd.num_vq > MIC_MAX_VRINGS) {
443 dev_err(mic_dev(mvdev), "%s %d err %d\n",
444 __func__, __LINE__, -EINVAL);
445 return -EINVAL;
446 }
447
448 dd_config = kmalloc(mic_desc_size(&dd), GFP_KERNEL);
449 if (dd_config == NULL) {
450 dev_err(mic_dev(mvdev), "%s %d err %d\n",
451 __func__, __LINE__, -ENOMEM);
452 return -ENOMEM;
453 }
454 if (copy_from_user(dd_config, argp, mic_desc_size(&dd))) {
455 ret = -EFAULT;
456 dev_err(mic_dev(mvdev), "%s %d err %d\n",
457 __func__, __LINE__, ret);
458 goto exit;
459 }
460
461 vqconfig = mic_vq_config(dd_config);
462 for (i = 0; i < dd.num_vq; i++) {
463 if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) {
464 ret = -EINVAL;
465 dev_err(mic_dev(mvdev), "%s %d err %d\n",
466 __func__, __LINE__, ret);
467 goto exit;
468 }
469 }
470
471 /* Find the first free device page entry */
472 for (i = mic_aligned_size(struct mic_bootparam);
473 i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
474 i += mic_total_desc_size(devp)) {
475 devp = mdev->dp + i;
476 if (devp->type == 0 || devp->type == -1) {
477 slot_found = true;
478 break;
479 }
480 }
481 if (!slot_found) {
482 ret = -EINVAL;
483 dev_err(mic_dev(mvdev), "%s %d err %d\n",
484 __func__, __LINE__, ret);
485 goto exit;
486 }
487 /*
488 * Save off the type before doing the memcpy. Type will be set in the
489 * end after completing all initialization for the new device.
490 */
491 *type = dd_config->type;
492 dd_config->type = 0;
493 memcpy(devp, dd_config, mic_desc_size(dd_config));
494
495 *devpage = devp;
496exit:
497 kfree(dd_config);
498 return ret;
499}
500
501static void mic_init_device_ctrl(struct mic_vdev *mvdev,
502 struct mic_device_desc *devpage)
503{
504 struct mic_device_ctrl *dc;
505
506 dc = mvdev->dc = (void *)devpage + mic_aligned_desc_size(devpage);
507
508 dc->config_change = 0;
509 dc->guest_ack = 0;
510 dc->vdev_reset = 0;
511 dc->host_ack = 0;
512 dc->used_address_updated = 0;
513 dc->c2h_vdev_db = -1;
514 dc->h2c_vdev_db = -1;
515}
516
517int mic_virtio_add_device(struct mic_vdev *mvdev,
518 void __user *argp)
519{
520 struct mic_device *mdev = mvdev->mdev;
521 struct mic_device_desc *dd;
522 struct mic_vqconfig *vqconfig;
523 int vr_size, i, j, ret;
524 u8 type;
525 s8 db;
526 char irqname[10];
527 struct mic_bootparam *bootparam = mdev->dp;
528 u16 num;
529
530 mutex_lock(&mdev->mic_mutex);
531
532 ret = mic_copy_dp_entry(mvdev, argp, &type, &dd);
533 if (ret) {
534 mutex_unlock(&mdev->mic_mutex);
535 return ret;
536 }
537
538 mic_init_device_ctrl(mvdev, dd);
539
540 mvdev->dd = dd;
541 mvdev->virtio_id = type;
542 vqconfig = mic_vq_config(dd);
543 INIT_WORK(&mvdev->virtio_bh_work, mic_bh_handler);
544
545 for (i = 0; i < dd->num_vq; i++) {
546 struct mic_vringh *mvr = &mvdev->mvr[i];
547 struct mic_vring *vr = &mvdev->mvr[i].vring;
548 num = le16_to_cpu(vqconfig[i].num);
549 mutex_init(&mvr->vr_mutex);
550 vr_size = PAGE_ALIGN(vring_size(num, MIC_VIRTIO_RING_ALIGN) +
551 sizeof(struct _mic_vring_info));
552 vr->va = (void *)
553 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
554 get_order(vr_size));
555 if (!vr->va) {
556 ret = -ENOMEM;
557 dev_err(mic_dev(mvdev), "%s %d err %d\n",
558 __func__, __LINE__, ret);
559 goto err;
560 }
561 vr->len = vr_size;
562 vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
563 vr->info->magic = MIC_MAGIC + mvdev->virtio_id + i;
564 vqconfig[i].address = mic_map_single(mdev,
565 vr->va, vr_size);
566 if (mic_map_error(vqconfig[i].address)) {
567 free_pages((unsigned long)vr->va,
568 get_order(vr_size));
569 ret = -ENOMEM;
570 dev_err(mic_dev(mvdev), "%s %d err %d\n",
571 __func__, __LINE__, ret);
572 goto err;
573 }
574 vqconfig[i].address = cpu_to_le64(vqconfig[i].address);
575
576 vring_init(&vr->vr, num,
577 vr->va, MIC_VIRTIO_RING_ALIGN);
578 ret = vringh_init_kern(&mvr->vrh,
579 *(u32 *)mic_vq_features(mvdev->dd), num, false,
580 vr->vr.desc, vr->vr.avail, vr->vr.used);
581 if (ret) {
582 dev_err(mic_dev(mvdev), "%s %d err %d\n",
583 __func__, __LINE__, ret);
584 goto err;
585 }
586 vringh_kiov_init(&mvr->riov, NULL, 0);
587 vringh_kiov_init(&mvr->wiov, NULL, 0);
588 mvr->head = USHRT_MAX;
589 mvr->mvdev = mvdev;
590 mvr->vrh.notify = mic_notify;
591 dev_dbg(mdev->sdev->parent,
592 "%s %d index %d va %p info %p vr_size 0x%x\n",
593 __func__, __LINE__, i, vr->va, vr->info, vr_size);
594 }
595
596 snprintf(irqname, sizeof(irqname),
597 "mic%dvirtio%d", mdev->id, mvdev->virtio_id);
598 mvdev->virtio_db = mic_next_db(mdev);
599 mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler,
600 irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB);
601 if (IS_ERR(mvdev->virtio_cookie)) {
602 ret = PTR_ERR(mvdev->virtio_cookie);
603 dev_dbg(mdev->sdev->parent, "request irq failed\n");
604 goto err;
605 }
606
607 mvdev->dc->c2h_vdev_db = mvdev->virtio_db;
608
609 list_add_tail(&mvdev->list, &mdev->vdev_list);
610 /*
611 * Order the type update with previous stores. This write barrier
612 * is paired with the corresponding read barrier before the uncached
613 * system memory read of the type, on the card while scanning the
614 * device page.
615 */
616 smp_wmb();
617 dd->type = type;
618
619 dev_dbg(mdev->sdev->parent, "Added virtio device id %d\n", dd->type);
620
621 db = bootparam->h2c_config_db;
622 if (db != -1)
623 mdev->ops->send_intr(mdev, db);
624 mutex_unlock(&mdev->mic_mutex);
625 return 0;
626err:
627 vqconfig = mic_vq_config(dd);
628 for (j = 0; j < i; j++) {
629 struct mic_vringh *mvr = &mvdev->mvr[j];
630 mic_unmap_single(mdev, le64_to_cpu(vqconfig[j].address),
631 mvr->vring.len);
632 free_pages((unsigned long)mvr->vring.va,
633 get_order(mvr->vring.len));
634 }
635 mutex_unlock(&mdev->mic_mutex);
636 return ret;
637}
638
639void mic_virtio_del_device(struct mic_vdev *mvdev)
640{
641 struct list_head *pos, *tmp;
642 struct mic_vdev *tmp_mvdev;
643 struct mic_device *mdev = mvdev->mdev;
644 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
645 int i, ret, retry = 100;
646 struct mic_vqconfig *vqconfig;
647 struct mic_bootparam *bootparam = mdev->dp;
648 s8 db;
649
650 mutex_lock(&mdev->mic_mutex);
651 db = bootparam->h2c_config_db;
652 if (db == -1)
653 goto skip_hot_remove;
654 dev_dbg(mdev->sdev->parent,
655 "Requesting hot remove id %d\n", mvdev->virtio_id);
656 mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
657 mdev->ops->send_intr(mdev, db);
658 for (i = retry; i--;) {
659 ret = wait_event_timeout(wake,
660 mvdev->dc->guest_ack, msecs_to_jiffies(100));
661 if (ret)
662 break;
663 }
664 dev_dbg(mdev->sdev->parent,
665 "Device id %d config_change %d guest_ack %d\n",
666 mvdev->virtio_id, mvdev->dc->config_change,
667 mvdev->dc->guest_ack);
668 mvdev->dc->config_change = 0;
669 mvdev->dc->guest_ack = 0;
670skip_hot_remove:
671 mic_free_irq(mdev, mvdev->virtio_cookie, mvdev);
672 flush_work(&mvdev->virtio_bh_work);
673 vqconfig = mic_vq_config(mvdev->dd);
674 for (i = 0; i < mvdev->dd->num_vq; i++) {
675 struct mic_vringh *mvr = &mvdev->mvr[i];
676 vringh_kiov_cleanup(&mvr->riov);
677 vringh_kiov_cleanup(&mvr->wiov);
678 mic_unmap_single(mdev, le64_to_cpu(vqconfig[i].address),
679 mvr->vring.len);
680 free_pages((unsigned long)mvr->vring.va,
681 get_order(mvr->vring.len));
682 }
683
684 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
685 tmp_mvdev = list_entry(pos, struct mic_vdev, list);
686 if (tmp_mvdev == mvdev) {
687 list_del(pos);
688 dev_dbg(mdev->sdev->parent,
689 "Removing virtio device id %d\n",
690 mvdev->virtio_id);
691 break;
692 }
693 }
694 /*
695 * Order the type update with previous stores. This write barrier
696 * is paired with the corresponding read barrier before the uncached
697 * system memory read of the type, on the card while scanning the
698 * device page.
699 */
700 smp_wmb();
701 mvdev->dd->type = -1;
702 mutex_unlock(&mdev->mic_mutex);
703}
diff --git a/drivers/misc/mic/host/mic_virtio.h b/drivers/misc/mic/host/mic_virtio.h
new file mode 100644
index 000000000000..184f3c84805b
--- /dev/null
+++ b/drivers/misc/mic/host/mic_virtio.h
@@ -0,0 +1,138 @@
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_VIRTIO_H
22#define MIC_VIRTIO_H
23
24#include <linux/virtio_config.h>
25#include <linux/mic_ioctl.h>
26
27/*
28 * Note on endianness.
29 * 1. Host can be both BE or LE
30 * 2. Guest/card is LE. Host uses le_to_cpu to access desc/avail
31 * rings and ioreadXX/iowriteXX to access used ring.
32 * 3. Device page exposed by host to guest contains LE values. Guest
33 * accesses these using ioreadXX/iowriteXX etc. This way in general we
34 * obey the virtio spec according to which guest works with native
35 * endianness and host is aware of guest endianness and does all
36 * required endianness conversion.
37 * 4. Data provided from user space to guest (in ADD_DEVICE and
38 * CONFIG_CHANGE ioctl's) is not interpreted by the driver and should be
39 * in guest endianness.
40 */
41
42/**
43 * struct mic_vringh - Virtio ring host information.
44 *
45 * @vring: The MIC vring used for setting up user space mappings.
46 * @vrh: The host VRINGH used for accessing the card vrings.
47 * @riov: The VRINGH read kernel IOV.
48 * @wiov: The VRINGH write kernel IOV.
49 * @head: The VRINGH head index address passed to vringh_getdesc_kern(..).
50 * @vr_mutex: Mutex for synchronizing access to the VRING.
51 * @mvdev: Back pointer to MIC virtio device for vringh_notify(..).
52 */
53struct mic_vringh {
54 struct mic_vring vring;
55 struct vringh vrh;
56 struct vringh_kiov riov;
57 struct vringh_kiov wiov;
58 u16 head;
59 struct mutex vr_mutex;
60 struct mic_vdev *mvdev;
61};
62
63/**
64 * struct mic_vdev - Host information for a card Virtio device.
65 *
66 * @virtio_id - Virtio device id.
67 * @waitq - Waitqueue to allow ring3 apps to poll.
68 * @mdev - Back pointer to host MIC device.
69 * @poll_wake - Used for waking up threads blocked in poll.
70 * @out_bytes - Debug stats for number of bytes copied from host to card.
71 * @in_bytes - Debug stats for number of bytes copied from card to host.
72 * @mvr - Store per VRING data structures.
73 * @virtio_bh_work - Work struct used to schedule virtio bottom half handling.
74 * @dd - Virtio device descriptor.
75 * @dc - Virtio device control fields.
76 * @list - List of Virtio devices.
77 * @virtio_db - The doorbell used by the card to interrupt the host.
78 * @virtio_cookie - The cookie returned while requesting interrupts.
79 */
80struct mic_vdev {
81 int virtio_id;
82 wait_queue_head_t waitq;
83 struct mic_device *mdev;
84 int poll_wake;
85 unsigned long out_bytes;
86 unsigned long in_bytes;
87 struct mic_vringh mvr[MIC_MAX_VRINGS];
88 struct work_struct virtio_bh_work;
89 struct mic_device_desc *dd;
90 struct mic_device_ctrl *dc;
91 struct list_head list;
92 int virtio_db;
93 struct mic_irq *virtio_cookie;
94};
95
96void mic_virtio_uninit(struct mic_device *mdev);
97int mic_virtio_add_device(struct mic_vdev *mvdev,
98 void __user *argp);
99void mic_virtio_del_device(struct mic_vdev *mvdev);
100int mic_virtio_config_change(struct mic_vdev *mvdev,
101 void __user *argp);
102int mic_virtio_copy_desc(struct mic_vdev *mvdev,
103 struct mic_copy_desc *request);
104void mic_virtio_reset_devices(struct mic_device *mdev);
105void mic_bh_handler(struct work_struct *work);
106
107/* Helper API to obtain the MIC PCIe device */
108static inline struct device *mic_dev(struct mic_vdev *mvdev)
109{
110 return mvdev->mdev->sdev->parent;
111}
112
113/* Helper API to check if a virtio device is initialized */
114static inline int mic_vdev_inited(struct mic_vdev *mvdev)
115{
116 /* Device has not been created yet */
117 if (!mvdev->dd || !mvdev->dd->type) {
118 dev_err(mic_dev(mvdev), "%s %d err %d\n",
119 __func__, __LINE__, -EINVAL);
120 return -EINVAL;
121 }
122
123 /* Device has been removed/deleted */
124 if (mvdev->dd->type == -1) {
125 dev_err(mic_dev(mvdev), "%s %d err %d\n",
126 __func__, __LINE__, -ENODEV);
127 return -ENODEV;
128 }
129
130 return 0;
131}
132
133/* Helper API to check if a virtio device is running */
134static inline bool mic_vdevup(struct mic_vdev *mvdev)
135{
136 return !!mvdev->dd->status;
137}
138#endif
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c
new file mode 100644
index 000000000000..a12ae5c8844d
--- /dev/null
+++ b/drivers/misc/mic/host/mic_x100.c
@@ -0,0 +1,573 @@
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#include <linux/sched.h>
24#include <linux/firmware.h>
25#include <linux/delay.h>
26
27#include "../common/mic_device.h"
28#include "mic_device.h"
29#include "mic_x100.h"
30#include "mic_smpt.h"
31
32/**
33 * mic_x100_write_spad - write to the scratchpad register
34 * @mdev: pointer to mic_device instance
35 * @idx: index to the scratchpad register, 0 based
36 * @val: the data value to put into the register
37 *
38 * This function allows writing of a 32bit value to the indexed scratchpad
39 * register.
40 *
41 * RETURNS: none.
42 */
43static void
44mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val)
45{
46 dev_dbg(mdev->sdev->parent, "Writing 0x%x to scratch pad index %d\n",
47 val, idx);
48 mic_mmio_write(&mdev->mmio, val,
49 MIC_X100_SBOX_BASE_ADDRESS +
50 MIC_X100_SBOX_SPAD0 + idx * 4);
51}
52
53/**
54 * mic_x100_read_spad - read from the scratchpad register
55 * @mdev: pointer to mic_device instance
56 * @idx: index to scratchpad register, 0 based
57 *
58 * This function allows reading of the 32bit scratchpad register.
59 *
60 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
61 */
62static u32
63mic_x100_read_spad(struct mic_device *mdev, unsigned int idx)
64{
65 u32 val = mic_mmio_read(&mdev->mmio,
66 MIC_X100_SBOX_BASE_ADDRESS +
67 MIC_X100_SBOX_SPAD0 + idx * 4);
68
69 dev_dbg(mdev->sdev->parent,
70 "Reading 0x%x from scratch pad index %d\n", val, idx);
71 return val;
72}
73
74/**
75 * mic_x100_enable_interrupts - Enable interrupts.
76 * @mdev: pointer to mic_device instance
77 */
78static void mic_x100_enable_interrupts(struct mic_device *mdev)
79{
80 u32 reg;
81 struct mic_mw *mw = &mdev->mmio;
82 u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
83 u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
84
85 reg = mic_mmio_read(mw, sice0);
86 reg |= MIC_X100_SBOX_DBR_BITS(0xf) | MIC_X100_SBOX_DMA_BITS(0xff);
87 mic_mmio_write(mw, reg, sice0);
88
89 /*
90 * Enable auto-clear when enabling interrupts. Applicable only for
91 * MSI-x. Legacy and MSI mode cannot have auto-clear enabled.
92 */
93 if (mdev->irq_info.num_vectors > 1) {
94 reg = mic_mmio_read(mw, siac0);
95 reg |= MIC_X100_SBOX_DBR_BITS(0xf) |
96 MIC_X100_SBOX_DMA_BITS(0xff);
97 mic_mmio_write(mw, reg, siac0);
98 }
99}
100
101/**
102 * mic_x100_disable_interrupts - Disable interrupts.
103 * @mdev: pointer to mic_device instance
104 */
105static void mic_x100_disable_interrupts(struct mic_device *mdev)
106{
107 u32 reg;
108 struct mic_mw *mw = &mdev->mmio;
109 u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0;
110 u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0;
111 u32 sicc0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICC0;
112
113 reg = mic_mmio_read(mw, sice0);
114 mic_mmio_write(mw, reg, sicc0);
115
116 if (mdev->irq_info.num_vectors > 1) {
117 reg = mic_mmio_read(mw, siac0);
118 reg &= ~(MIC_X100_SBOX_DBR_BITS(0xf) |
119 MIC_X100_SBOX_DMA_BITS(0xff));
120 mic_mmio_write(mw, reg, siac0);
121 }
122}
123
124/**
125 * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC.
126 * @mdev: pointer to mic_device instance
127 */
128static void mic_x100_send_sbox_intr(struct mic_device *mdev,
129 int doorbell)
130{
131 struct mic_mw *mw = &mdev->mmio;
132 u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8;
133 u32 apicicr_low = mic_mmio_read(mw,
134 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
135
136 /* for MIC we need to make sure we "hit" the send_icr bit (13) */
137 apicicr_low = (apicicr_low | (1 << 13));
138
139 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
140 wmb();
141 mic_mmio_write(mw, apicicr_low,
142 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
143}
144
145/**
146 * mic_x100_send_rdmasr_intr - Send an RDMASR interrupt to MIC.
147 * @mdev: pointer to mic_device instance
148 */
149static void mic_x100_send_rdmasr_intr(struct mic_device *mdev,
150 int doorbell)
151{
152 int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2);
153 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
154 wmb();
155 mic_mmio_write(&mdev->mmio, 0,
156 MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset);
157}
158
159/**
160 * __mic_x100_send_intr - Send interrupt to MIC.
161 * @mdev: pointer to mic_device instance
162 * @doorbell: doorbell number.
163 */
164static void mic_x100_send_intr(struct mic_device *mdev, int doorbell)
165{
166 int rdmasr_db;
167 if (doorbell < MIC_X100_NUM_SBOX_IRQ) {
168 mic_x100_send_sbox_intr(mdev, doorbell);
169 } else {
170 rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ +
171 MIC_X100_RDMASR_IRQ_BASE;
172 mic_x100_send_rdmasr_intr(mdev, rdmasr_db);
173 }
174}
175
176/**
177 * mic_ack_interrupt - Device specific interrupt handling.
178 * @mdev: pointer to mic_device instance
179 *
180 * Returns: bitmask of doorbell events triggered.
181 */
182static u32 mic_x100_ack_interrupt(struct mic_device *mdev)
183{
184 u32 reg = 0;
185 struct mic_mw *mw = &mdev->mmio;
186 u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0;
187
188 /* Clear pending bit array. */
189 if (MIC_A0_STEP == mdev->stepping)
190 mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS +
191 MIC_X100_SBOX_MSIXPBACR);
192
193 if (mdev->irq_info.num_vectors <= 1) {
194 reg = mic_mmio_read(mw, sicr0);
195
196 if (unlikely(!reg))
197 goto done;
198
199 mic_mmio_write(mw, reg, sicr0);
200 }
201
202 if (mdev->stepping >= MIC_B0_STEP)
203 mdev->intr_ops->enable_interrupts(mdev);
204done:
205 return reg;
206}
207
208/**
209 * mic_x100_hw_intr_init - Initialize h/w specific interrupt
210 * information.
211 * @mdev: pointer to mic_device instance
212 */
213static void mic_x100_hw_intr_init(struct mic_device *mdev)
214{
215 mdev->intr_info = (struct mic_intr_info *) mic_x100_intr_init;
216}
217
218/**
219 * mic_x100_read_msi_to_src_map - read from the MSI mapping registers
220 * @mdev: pointer to mic_device instance
221 * @idx: index to the mapping register, 0 based
222 *
223 * This function allows reading of the 32bit MSI mapping register.
224 *
225 * RETURNS: The value in the register.
226 */
227static u32
228mic_x100_read_msi_to_src_map(struct mic_device *mdev, int idx)
229{
230 return mic_mmio_read(&mdev->mmio,
231 MIC_X100_SBOX_BASE_ADDRESS +
232 MIC_X100_SBOX_MXAR0 + idx * 4);
233}
234
235/**
236 * mic_x100_program_msi_to_src_map - program the MSI mapping registers
237 * @mdev: pointer to mic_device instance
238 * @idx: index to the mapping register, 0 based
239 * @offset: The bit offset in the register that needs to be updated.
240 * @set: boolean specifying if the bit in the specified offset needs
241 * to be set or cleared.
242 *
243 * RETURNS: None.
244 */
245static void
246mic_x100_program_msi_to_src_map(struct mic_device *mdev,
247 int idx, int offset, bool set)
248{
249 unsigned long reg;
250 struct mic_mw *mw = &mdev->mmio;
251 u32 mxar = MIC_X100_SBOX_BASE_ADDRESS +
252 MIC_X100_SBOX_MXAR0 + idx * 4;
253
254 reg = mic_mmio_read(mw, mxar);
255 if (set)
256 __set_bit(offset, &reg);
257 else
258 __clear_bit(offset, &reg);
259 mic_mmio_write(mw, reg, mxar);
260}
261
262/*
263 * mic_x100_reset_fw_ready - Reset Firmware ready status field.
264 * @mdev: pointer to mic_device instance
265 */
266static void mic_x100_reset_fw_ready(struct mic_device *mdev)
267{
268 mdev->ops->write_spad(mdev, MIC_X100_DOWNLOAD_INFO, 0);
269}
270
271/*
272 * mic_x100_is_fw_ready - Check if firmware is ready.
273 * @mdev: pointer to mic_device instance
274 */
275static bool mic_x100_is_fw_ready(struct mic_device *mdev)
276{
277 u32 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
278 return MIC_X100_SPAD2_DOWNLOAD_STATUS(scratch2) ? true : false;
279}
280
281/**
282 * mic_x100_get_apic_id - Get bootstrap APIC ID.
283 * @mdev: pointer to mic_device instance
284 */
285static u32 mic_x100_get_apic_id(struct mic_device *mdev)
286{
287 u32 scratch2 = 0;
288
289 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
290 return MIC_X100_SPAD2_APIC_ID(scratch2);
291}
292
293/**
294 * mic_x100_send_firmware_intr - Send an interrupt to the firmware on MIC.
295 * @mdev: pointer to mic_device instance
296 */
297static void mic_x100_send_firmware_intr(struct mic_device *mdev)
298{
299 u32 apicicr_low;
300 u64 apic_icr_offset = MIC_X100_SBOX_APICICR7;
301 int vector = MIC_X100_BSP_INTERRUPT_VECTOR;
302 struct mic_mw *mw = &mdev->mmio;
303
304 /*
305 * For MIC we need to make sure we "hit"
306 * the send_icr bit (13).
307 */
308 apicicr_low = (vector | (1 << 13));
309
310 mic_mmio_write(mw, mic_x100_get_apic_id(mdev),
311 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset + 4);
312
313 /* Ensure that the interrupt is ordered w.r.t. previous stores. */
314 wmb();
315 mic_mmio_write(mw, apicicr_low,
316 MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset);
317}
318
319/**
320 * mic_x100_hw_reset - Reset the MIC device.
321 * @mdev: pointer to mic_device instance
322 */
323static void mic_x100_hw_reset(struct mic_device *mdev)
324{
325 u32 reset_reg;
326 u32 rgcr = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_RGCR;
327 struct mic_mw *mw = &mdev->mmio;
328
329 /* Ensure that the reset is ordered w.r.t. previous loads and stores */
330 mb();
331 /* Trigger reset */
332 reset_reg = mic_mmio_read(mw, rgcr);
333 reset_reg |= 0x1;
334 mic_mmio_write(mw, reset_reg, rgcr);
335 /*
336 * It seems we really want to delay at least 1 second
337 * after touching reset to prevent a lot of problems.
338 */
339 msleep(1000);
340}
341
342/**
343 * mic_x100_load_command_line - Load command line to MIC.
344 * @mdev: pointer to mic_device instance
345 * @fw: the firmware image
346 *
347 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
348 */
349static int
350mic_x100_load_command_line(struct mic_device *mdev, const struct firmware *fw)
351{
352 u32 len = 0;
353 u32 boot_mem;
354 char *buf;
355 void __iomem *cmd_line_va = mdev->aper.va + mdev->bootaddr + fw->size;
356#define CMDLINE_SIZE 2048
357
358 boot_mem = mdev->aper.len >> 20;
359 buf = kzalloc(CMDLINE_SIZE, GFP_KERNEL);
360 if (!buf) {
361 dev_err(mdev->sdev->parent,
362 "%s %d allocation failed\n", __func__, __LINE__);
363 return -ENOMEM;
364 }
365 len += snprintf(buf, CMDLINE_SIZE - len,
366 " mem=%dM", boot_mem);
367 if (mdev->cmdline)
368 snprintf(buf + len, CMDLINE_SIZE - len,
369 " %s", mdev->cmdline);
370 memcpy_toio(cmd_line_va, buf, strlen(buf) + 1);
371 kfree(buf);
372 return 0;
373}
374
375/**
376 * mic_x100_load_ramdisk - Load ramdisk to MIC.
377 * @mdev: pointer to mic_device instance
378 *
379 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
380 */
381static int
382mic_x100_load_ramdisk(struct mic_device *mdev)
383{
384 const struct firmware *fw;
385 int rc;
386 struct boot_params __iomem *bp = mdev->aper.va + mdev->bootaddr;
387
388 rc = request_firmware(&fw,
389 mdev->ramdisk, mdev->sdev->parent);
390 if (rc < 0) {
391 dev_err(mdev->sdev->parent,
392 "ramdisk request_firmware failed: %d %s\n",
393 rc, mdev->ramdisk);
394 goto error;
395 }
396 /*
397 * Typically the bootaddr for card OS is 64M
398 * so copy over the ramdisk @ 128M.
399 */
400 memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1),
401 fw->data, fw->size);
402 iowrite32(cpu_to_le32(mdev->bootaddr << 1), &bp->hdr.ramdisk_image);
403 iowrite32(cpu_to_le32(fw->size), &bp->hdr.ramdisk_size);
404 release_firmware(fw);
405error:
406 return rc;
407}
408
409/**
410 * mic_x100_get_boot_addr - Get MIC boot address.
411 * @mdev: pointer to mic_device instance
412 *
413 * This function is called during firmware load to determine
414 * the address at which the OS should be downloaded in card
415 * memory i.e. GDDR.
416 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
417 */
418static int
419mic_x100_get_boot_addr(struct mic_device *mdev)
420{
421 u32 scratch2, boot_addr;
422 int rc = 0;
423
424 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
425 boot_addr = MIC_X100_SPAD2_DOWNLOAD_ADDR(scratch2);
426 dev_dbg(mdev->sdev->parent, "%s %d boot_addr 0x%x\n",
427 __func__, __LINE__, boot_addr);
428 if (boot_addr > (1 << 31)) {
429 dev_err(mdev->sdev->parent,
430 "incorrect bootaddr 0x%x\n",
431 boot_addr);
432 rc = -EINVAL;
433 goto error;
434 }
435 mdev->bootaddr = boot_addr;
436error:
437 return rc;
438}
439
440/**
441 * mic_x100_load_firmware - Load firmware to MIC.
442 * @mdev: pointer to mic_device instance
443 * @buf: buffer containing boot string including firmware/ramdisk path.
444 *
445 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
446 */
447static int
448mic_x100_load_firmware(struct mic_device *mdev, const char *buf)
449{
450 int rc;
451 const struct firmware *fw;
452
453 rc = mic_x100_get_boot_addr(mdev);
454 if (rc)
455 goto error;
456 /* load OS */
457 rc = request_firmware(&fw, mdev->firmware, mdev->sdev->parent);
458 if (rc < 0) {
459 dev_err(mdev->sdev->parent,
460 "ramdisk request_firmware failed: %d %s\n",
461 rc, mdev->firmware);
462 goto error;
463 }
464 if (mdev->bootaddr > mdev->aper.len - fw->size) {
465 rc = -EINVAL;
466 dev_err(mdev->sdev->parent, "%s %d rc %d bootaddr 0x%x\n",
467 __func__, __LINE__, rc, mdev->bootaddr);
468 release_firmware(fw);
469 goto error;
470 }
471 memcpy_toio(mdev->aper.va + mdev->bootaddr, fw->data, fw->size);
472 mdev->ops->write_spad(mdev, MIC_X100_FW_SIZE, fw->size);
473 if (!strcmp(mdev->bootmode, "elf"))
474 goto done;
475 /* load command line */
476 rc = mic_x100_load_command_line(mdev, fw);
477 if (rc) {
478 dev_err(mdev->sdev->parent, "%s %d rc %d\n",
479 __func__, __LINE__, rc);
480 goto error;
481 }
482 release_firmware(fw);
483 /* load ramdisk */
484 if (mdev->ramdisk)
485 rc = mic_x100_load_ramdisk(mdev);
486error:
487 dev_dbg(mdev->sdev->parent, "%s %d rc %d\n",
488 __func__, __LINE__, rc);
489done:
490 return rc;
491}
492
493/**
494 * mic_x100_get_postcode - Get postcode status from firmware.
495 * @mdev: pointer to mic_device instance
496 *
497 * RETURNS: postcode.
498 */
499static u32 mic_x100_get_postcode(struct mic_device *mdev)
500{
501 return mic_mmio_read(&mdev->mmio, MIC_X100_POSTCODE);
502}
503
504/**
505 * mic_x100_smpt_set - Update an SMPT entry with a DMA address.
506 * @mdev: pointer to mic_device instance
507 *
508 * RETURNS: none.
509 */
510static void
511mic_x100_smpt_set(struct mic_device *mdev, dma_addr_t dma_addr, u8 index)
512{
513#define SNOOP_ON (0 << 0)
514#define SNOOP_OFF (1 << 0)
515/*
516 * Sbox Smpt Reg Bits:
517 * Bits 31:2 Host address
518 * Bits 1 RSVD
519 * Bits 0 No snoop
520 */
521#define BUILD_SMPT(NO_SNOOP, HOST_ADDR) \
522 (u32)(((HOST_ADDR) << 2) | ((NO_SNOOP) & 0x01))
523
524 uint32_t smpt_reg_val = BUILD_SMPT(SNOOP_ON,
525 dma_addr >> mdev->smpt->info.page_shift);
526 mic_mmio_write(&mdev->mmio, smpt_reg_val,
527 MIC_X100_SBOX_BASE_ADDRESS +
528 MIC_X100_SBOX_SMPT00 + (4 * index));
529}
530
531/**
532 * mic_x100_smpt_hw_init - Initialize SMPT X100 specific fields.
533 * @mdev: pointer to mic_device instance
534 *
535 * RETURNS: none.
536 */
537static void mic_x100_smpt_hw_init(struct mic_device *mdev)
538{
539 struct mic_smpt_hw_info *info = &mdev->smpt->info;
540
541 info->num_reg = 32;
542 info->page_shift = 34;
543 info->page_size = (1ULL << info->page_shift);
544 info->base = 0x8000000000ULL;
545}
546
547struct mic_smpt_ops mic_x100_smpt_ops = {
548 .init = mic_x100_smpt_hw_init,
549 .set = mic_x100_smpt_set,
550};
551
552struct mic_hw_ops mic_x100_ops = {
553 .aper_bar = MIC_X100_APER_BAR,
554 .mmio_bar = MIC_X100_MMIO_BAR,
555 .read_spad = mic_x100_read_spad,
556 .write_spad = mic_x100_write_spad,
557 .send_intr = mic_x100_send_intr,
558 .ack_interrupt = mic_x100_ack_interrupt,
559 .reset = mic_x100_hw_reset,
560 .reset_fw_ready = mic_x100_reset_fw_ready,
561 .is_fw_ready = mic_x100_is_fw_ready,
562 .send_firmware_intr = mic_x100_send_firmware_intr,
563 .load_mic_fw = mic_x100_load_firmware,
564 .get_postcode = mic_x100_get_postcode,
565};
566
567struct mic_hw_intr_ops mic_x100_intr_ops = {
568 .intr_init = mic_x100_hw_intr_init,
569 .enable_interrupts = mic_x100_enable_interrupts,
570 .disable_interrupts = mic_x100_disable_interrupts,
571 .program_msi_to_src_map = mic_x100_program_msi_to_src_map,
572 .read_msi_to_src_map = mic_x100_read_msi_to_src_map,
573};
diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h
new file mode 100644
index 000000000000..8b7daa182e54
--- /dev/null
+++ b/drivers/misc/mic/host/mic_x100.h
@@ -0,0 +1,98 @@
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#define MIC_X100_SBOX_SICR0_DBR(x) ((x) & 0xf)
46#define MIC_X100_SBOX_SICR0_DMA(x) (((x) >> 8) & 0xff)
47#define MIC_X100_SBOX_SICE0_DBR(x) ((x) & 0xf)
48#define MIC_X100_SBOX_DBR_BITS(x) ((x) & 0xf)
49#define MIC_X100_SBOX_SICE0_DMA(x) (((x) >> 8) & 0xff)
50#define MIC_X100_SBOX_DMA_BITS(x) (((x) & 0xff) << 8)
51
52#define MIC_X100_SBOX_APICICR0 0x0000A9D0
53#define MIC_X100_SBOX_SICR0 0x00009004
54#define MIC_X100_SBOX_SICE0 0x0000900C
55#define MIC_X100_SBOX_SICC0 0x00009010
56#define MIC_X100_SBOX_SIAC0 0x00009014
57#define MIC_X100_SBOX_MSIXPBACR 0x00009084
58#define MIC_X100_SBOX_MXAR0 0x00009044
59#define MIC_X100_SBOX_SMPT00 0x00003100
60#define MIC_X100_SBOX_RDMASR0 0x0000B180
61
62#define MIC_X100_DOORBELL_IDX_START 0
63#define MIC_X100_NUM_DOORBELL 4
64#define MIC_X100_DMA_IDX_START 8
65#define MIC_X100_NUM_DMA 8
66#define MIC_X100_ERR_IDX_START 30
67#define MIC_X100_NUM_ERR 1
68
69#define MIC_X100_NUM_SBOX_IRQ 8
70#define MIC_X100_NUM_RDMASR_IRQ 8
71#define MIC_X100_RDMASR_IRQ_BASE 17
72#define MIC_X100_SPAD2_DOWNLOAD_STATUS(x) ((x) & 0x1)
73#define MIC_X100_SPAD2_APIC_ID(x) (((x) >> 1) & 0x1ff)
74#define MIC_X100_SPAD2_DOWNLOAD_ADDR(x) ((x) & 0xfffff000)
75#define MIC_X100_SBOX_APICICR7 0x0000AA08
76#define MIC_X100_SBOX_RGCR 0x00004010
77#define MIC_X100_SBOX_SDBIC0 0x0000CC90
78#define MIC_X100_DOWNLOAD_INFO 2
79#define MIC_X100_FW_SIZE 5
80#define MIC_X100_POSTCODE 0x242c
81
82static const u16 mic_x100_intr_init[] = {
83 MIC_X100_DOORBELL_IDX_START,
84 MIC_X100_DMA_IDX_START,
85 MIC_X100_ERR_IDX_START,
86 MIC_X100_NUM_DOORBELL,
87 MIC_X100_NUM_DMA,
88 MIC_X100_NUM_ERR,
89};
90
91/* Host->Card(bootstrap) Interrupt Vector */
92#define MIC_X100_BSP_INTERRUPT_VECTOR 229
93
94extern struct mic_hw_ops mic_x100_ops;
95extern struct mic_smpt_ops mic_x100_smpt_ops;
96extern struct mic_hw_intr_ops mic_x100_intr_ops;
97
98#endif
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index f84ff0c06035..eda38cbe8530 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -892,7 +892,6 @@ static void pti_pci_remove(struct pci_dev *pdev)
892 } 892 }
893 893
894 iounmap(drv_data->pti_ioaddr); 894 iounmap(drv_data->pti_ioaddr);
895 pci_set_drvdata(pdev, NULL);
896 kfree(drv_data); 895 kfree(drv_data);
897 pci_release_region(pdev, 1); 896 pci_release_region(pdev, 1);
898 pci_disable_device(pdev); 897 pci_disable_device(pdev);
diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c
index 9b237221bc4e..83da711ce9f1 100644
--- a/drivers/misc/ti_dac7512.c
+++ b/drivers/misc/ti_dac7512.c
@@ -22,9 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/spi/spi.h> 24#include <linux/spi/spi.h>
25 25#include <linux/of.h>
26#define DAC7512_DRV_NAME "dac7512"
27#define DRIVER_VERSION "1.0"
28 26
29static ssize_t dac7512_store_val(struct device *dev, 27static ssize_t dac7512_store_val(struct device *dev,
30 struct device_attribute *attr, 28 struct device_attribute *attr,
@@ -75,13 +73,29 @@ static int dac7512_remove(struct spi_device *spi)
75 return 0; 73 return 0;
76} 74}
77 75
76static const struct spi_device_id dac7512_id_table[] = {
77 { "dac7512", 0 },
78 { }
79};
80MODULE_DEVICE_TABLE(spi, dac7512_id_table);
81
82#ifdef CONFIG_OF
83static const struct of_device_id dac7512_of_match[] = {
84 { .compatible = "ti,dac7512", },
85 { }
86};
87MODULE_DEVICE_TABLE(of, dac7512_of_match);
88#endif
89
78static struct spi_driver dac7512_driver = { 90static struct spi_driver dac7512_driver = {
79 .driver = { 91 .driver = {
80 .name = DAC7512_DRV_NAME, 92 .name = "dac7512",
81 .owner = THIS_MODULE, 93 .owner = THIS_MODULE,
94 .of_match_table = of_match_ptr(dac7512_of_match),
82 }, 95 },
83 .probe = dac7512_probe, 96 .probe = dac7512_probe,
84 .remove = dac7512_remove, 97 .remove = dac7512_remove,
98 .id_table = dac7512_id_table,
85}; 99};
86 100
87module_spi_driver(dac7512_driver); 101module_spi_driver(dac7512_driver);
@@ -89,4 +103,3 @@ module_spi_driver(dac7512_driver);
89MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 103MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
90MODULE_DESCRIPTION("DAC7512 16-bit DAC"); 104MODULE_DESCRIPTION("DAC7512 16-bit DAC");
91MODULE_LICENSE("GPL v2"); 105MODULE_LICENSE("GPL v2");
92MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c
index f8d6654391e5..ae282a100429 100644
--- a/drivers/misc/tifm_7xx1.c
+++ b/drivers/misc/tifm_7xx1.c
@@ -378,7 +378,6 @@ err_out_irq:
378err_out_unmap: 378err_out_unmap:
379 iounmap(fm->addr); 379 iounmap(fm->addr);
380err_out_free: 380err_out_free:
381 pci_set_drvdata(dev, NULL);
382 tifm_free_adapter(fm); 381 tifm_free_adapter(fm);
383err_out_int: 382err_out_int:
384 pci_intx(dev, 0); 383 pci_intx(dev, 0);
@@ -405,8 +404,6 @@ static void tifm_7xx1_remove(struct pci_dev *dev)
405 for (cnt = 0; cnt < fm->num_sockets; cnt++) 404 for (cnt = 0; cnt < fm->num_sockets; cnt++)
406 tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt)); 405 tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
407 406
408 pci_set_drvdata(dev, NULL);
409
410 iounmap(fm->addr); 407 iounmap(fm->addr);
411 pci_intx(dev, 0); 408 pci_intx(dev, 0);
412 pci_release_regions(dev); 409 pci_release_regions(dev);
diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c
index b3a2b763ecf2..c98b03b99353 100644
--- a/drivers/misc/vmw_vmci/vmci_guest.c
+++ b/drivers/misc/vmw_vmci/vmci_guest.c
@@ -649,7 +649,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
649 return 0; 649 return 0;
650 650
651err_free_irq: 651err_free_irq:
652 free_irq(vmci_dev->irq, &vmci_dev); 652 free_irq(vmci_dev->irq, vmci_dev);
653 tasklet_kill(&vmci_dev->datagram_tasklet); 653 tasklet_kill(&vmci_dev->datagram_tasklet);
654 tasklet_kill(&vmci_dev->bm_tasklet); 654 tasklet_kill(&vmci_dev->bm_tasklet);
655 655