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.c305
-rw-r--r--drivers/misc/mic/card/mic_device.h133
-rw-r--r--drivers/misc/mic/card/mic_virtio.c630
-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_dev.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.c491
-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.c630
-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.c452
-rw-r--r--drivers/misc/mic/host/mic_virtio.c700
-rw-r--r--drivers/misc/mic/host/mic_virtio.h138
-rw-r--r--drivers/misc/mic/host/mic_x100.c570
-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, 6905 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 f6ff711aa5bb..226c3f3cd3e8 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -313,13 +313,13 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
313 mei_hdr.me_addr = dev->iamthif_cl.me_client_id; 313 mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
314 mei_hdr.reserved = 0; 314 mei_hdr.reserved = 0;
315 dev->iamthif_msg_buf_index += mei_hdr.length; 315 dev->iamthif_msg_buf_index += mei_hdr.length;
316 if (mei_write_message(dev, &mei_hdr, 316 ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
317 (unsigned char *)dev->iamthif_msg_buf)) 317 if (ret)
318 return -ENODEV; 318 return ret;
319 319
320 if (mei_hdr.msg_complete) { 320 if (mei_hdr.msg_complete) {
321 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl)) 321 if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
322 return -ENODEV; 322 return -EIO;
323 dev->iamthif_flow_control_pending = true; 323 dev->iamthif_flow_control_pending = true;
324 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; 324 dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
325 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n"); 325 dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
@@ -459,6 +459,16 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
459 struct mei_msg_hdr mei_hdr; 459 struct mei_msg_hdr mei_hdr;
460 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; 460 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
461 u32 msg_slots = mei_data2slots(len); 461 u32 msg_slots = mei_data2slots(len);
462 int rets;
463
464 rets = mei_cl_flow_ctrl_creds(cl);
465 if (rets < 0)
466 return rets;
467
468 if (rets == 0) {
469 cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
470 return 0;
471 }
462 472
463 mei_hdr.host_addr = cl->host_client_id; 473 mei_hdr.host_addr = cl->host_client_id;
464 mei_hdr.me_addr = cl->me_client_id; 474 mei_hdr.me_addr = cl->me_client_id;
@@ -481,16 +491,17 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
481 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr)); 491 dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
482 492
483 *slots -= msg_slots; 493 *slots -= msg_slots;
484 if (mei_write_message(dev, &mei_hdr, 494 rets = mei_write_message(dev, &mei_hdr,
485 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) { 495 dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
486 dev->iamthif_state = MEI_IAMTHIF_IDLE; 496 if (rets) {
487 cl->status = -ENODEV; 497 dev->iamthif_state = MEI_IAMTHIF_IDLE;
488 list_del(&cb->list); 498 cl->status = rets;
489 return -ENODEV; 499 list_del(&cb->list);
500 return rets;
490 } 501 }
491 502
492 if (mei_cl_flow_ctrl_reduce(cl)) 503 if (mei_cl_flow_ctrl_reduce(cl))
493 return -ENODEV; 504 return -EIO;
494 505
495 dev->iamthif_msg_buf_index += mei_hdr.length; 506 dev->iamthif_msg_buf_index += mei_hdr.length;
496 cl->status = 0; 507 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 892cc4207fa2..c8396e582f1c 100644
--- a/drivers/misc/mei/client.h
+++ b/drivers/misc/mei/client.h
@@ -115,4 +115,13 @@ void mei_cl_all_disconnect(struct mei_device *dev);
115void mei_cl_all_wakeup(struct mei_device *dev); 115void mei_cl_all_wakeup(struct mei_device *dev);
116void mei_cl_all_write_clear(struct mei_device *dev); 116void mei_cl_all_write_clear(struct mei_device *dev);
117 117
118#define MEI_CL_FMT "cl:host=%02d me=%02d "
119#define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id
120
121#define cl_dbg(dev, cl, format, arg...) \
122 dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
123
124#define cl_err(dev, cl, format, arg...) \
125 dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
126
118#endif /* _MEI_CLIENT_H_ */ 127#endif /* _MEI_CLIENT_H_ */
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 0a0448326e9d..9b3a0fb7f265 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -49,7 +49,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
49 kfree(dev->me_clients); 49 kfree(dev->me_clients);
50 dev->me_clients = NULL; 50 dev->me_clients = NULL;
51 51
52 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n", 52 dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
53 dev->me_clients_num * sizeof(struct mei_me_client)); 53 dev->me_clients_num * sizeof(struct mei_me_client));
54 /* allocate storage for ME clients representation */ 54 /* allocate storage for ME clients representation */
55 clients = kcalloc(dev->me_clients_num, 55 clients = kcalloc(dev->me_clients_num,
@@ -174,7 +174,7 @@ int mei_hbm_start_req(struct mei_device *dev)
174 dev_err(&dev->pdev->dev, "version message write failed\n"); 174 dev_err(&dev->pdev->dev, "version message write failed\n");
175 dev->dev_state = MEI_DEV_RESETTING; 175 dev->dev_state = MEI_DEV_RESETTING;
176 mei_reset(dev, 1); 176 mei_reset(dev, 1);
177 return -ENODEV; 177 return -EIO;
178 } 178 }
179 dev->hbm_state = MEI_HBM_START; 179 dev->hbm_state = MEI_HBM_START;
180 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; 180 dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
@@ -677,7 +677,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
677 677
678 case HOST_ENUM_RES_CMD: 678 case HOST_ENUM_RES_CMD:
679 enum_res = (struct hbm_host_enum_response *) mei_msg; 679 enum_res = (struct hbm_host_enum_response *) mei_msg;
680 memcpy(dev->me_clients_map, enum_res->valid_addresses, 32); 680 BUILD_BUG_ON(sizeof(dev->me_clients_map)
681 < sizeof(enum_res->valid_addresses));
682 memcpy(dev->me_clients_map, enum_res->valid_addresses,
683 sizeof(enum_res->valid_addresses));
681 if (dev->dev_state == MEI_DEV_INIT_CLIENTS && 684 if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
682 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) { 685 dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
683 dev->init_clients_timer = 0; 686 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 cabeddd66c1f..c71420ef1e37 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;
@@ -347,8 +350,14 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
347 rets = -ENODEV; 350 rets = -ENODEV;
348 goto out; 351 goto out;
349 } 352 }
350 if (length > dev->me_clients[id].props.max_msg_length || length <= 0) { 353
351 rets = -EMSGSIZE; 354 if (length == 0) {
355 rets = 0;
356 goto out;
357 }
358
359 if (length > dev->me_clients[id].props.max_msg_length) {
360 rets = -EFBIG;
352 goto out; 361 goto out;
353 } 362 }
354 363
@@ -401,8 +410,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
401 goto out; 410 goto out;
402 411
403 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); 412 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length);
404 if (rets) 413 if (rets) {
414 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
415 rets = -EFAULT;
405 goto out; 416 goto out;
417 }
406 418
407 if (cl == &dev->iamthif_cl) { 419 if (cl == &dev->iamthif_cl) {
408 rets = mei_amthif_write(dev, write_cb); 420 rets = mei_amthif_write(dev, write_cb);
@@ -564,7 +576,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
564 dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); 576 dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
565 if (copy_from_user(connect_data, (char __user *)data, 577 if (copy_from_user(connect_data, (char __user *)data,
566 sizeof(struct mei_connect_client_data))) { 578 sizeof(struct mei_connect_client_data))) {
567 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); 579 dev_err(&dev->pdev->dev, "failed to copy data from userland\n");
568 rets = -EFAULT; 580 rets = -EFAULT;
569 goto out; 581 goto out;
570 } 582 }
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..e42b331edbc6
--- /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 && X86
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 && X86
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..421b3d7911df
--- /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_dev.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..d0980ff96833
--- /dev/null
+++ b/drivers/misc/mic/card/mic_device.c
@@ -0,0 +1,305 @@
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_dev.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 * mic_free_card_irq - free irq.
174 *
175 * @cookie: cookie obtained during a successful call to mic_request_irq
176 * @data: private data specified by the calling function during the
177 * mic_request_irq
178 *
179 * returns: none.
180 */
181void mic_free_card_irq(struct mic_irq *cookie, void *data)
182{
183 int index;
184 struct mic_driver *mdrv = g_drv;
185
186 index = (unsigned long)cookie & 0xFFFFU;
187 free_irq(mic_db_to_irq(mdrv, index), data);
188 mdrv->irq_info.irq_usage_count[index]--;
189}
190
191/**
192 * mic_next_card_db - Get the doorbell with minimum usage count.
193 *
194 * Returns the irq index.
195 */
196int mic_next_card_db(void)
197{
198 int i;
199 int index = 0;
200 struct mic_driver *mdrv = g_drv;
201
202 for (i = 0; i < mdrv->intr_info.num_intr; i++) {
203 if (mdrv->irq_info.irq_usage_count[i] <
204 mdrv->irq_info.irq_usage_count[index])
205 index = i;
206 }
207
208 return index;
209}
210
211/**
212 * mic_init_irq - Initialize irq information.
213 *
214 * Returns 0 in success. Appropriate error code on failure.
215 */
216static int mic_init_irq(void)
217{
218 struct mic_driver *mdrv = g_drv;
219
220 mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) *
221 mdrv->intr_info.num_intr),
222 GFP_KERNEL);
223 if (!mdrv->irq_info.irq_usage_count)
224 return -ENOMEM;
225 return 0;
226}
227
228/**
229 * mic_uninit_irq - Uninitialize irq information.
230 *
231 * None.
232 */
233static void mic_uninit_irq(void)
234{
235 struct mic_driver *mdrv = g_drv;
236
237 kfree(mdrv->irq_info.irq_usage_count);
238}
239
240/*
241 * mic_driver_init - MIC driver initialization tasks.
242 *
243 * Returns 0 in success. Appropriate error code on failure.
244 */
245int __init mic_driver_init(struct mic_driver *mdrv)
246{
247 int rc;
248
249 g_drv = mdrv;
250 /*
251 * Unloading the card module is not supported. The MIC card module
252 * handles fundamental operations like host/card initiated shutdowns
253 * and informing the host about card crashes and cannot be unloaded.
254 */
255 if (!try_module_get(mdrv->dev->driver->owner)) {
256 rc = -ENODEV;
257 goto done;
258 }
259 rc = mic_dp_init();
260 if (rc)
261 goto put;
262 rc = mic_init_irq();
263 if (rc)
264 goto dp_uninit;
265 rc = mic_shutdown_init();
266 if (rc)
267 goto irq_uninit;
268 rc = mic_devices_init(mdrv);
269 if (rc)
270 goto shutdown_uninit;
271 mic_create_card_debug_dir(mdrv);
272 atomic_notifier_chain_register(&panic_notifier_list, &mic_panic);
273done:
274 return rc;
275shutdown_uninit:
276 mic_shutdown_uninit();
277irq_uninit:
278 mic_uninit_irq();
279dp_uninit:
280 mic_dp_uninit();
281put:
282 module_put(mdrv->dev->driver->owner);
283 return rc;
284}
285
286/*
287 * mic_driver_uninit - MIC driver uninitialization tasks.
288 *
289 * Returns None
290 */
291void mic_driver_uninit(struct mic_driver *mdrv)
292{
293 mic_delete_card_debug_dir(mdrv);
294 mic_devices_uninit(mdrv);
295 /*
296 * Inform the host about the shutdown status i.e. poweroff/restart etc.
297 * The module cannot be unloaded so the only code path to call
298 * mic_devices_uninit(..) is the shutdown callback.
299 */
300 mic_notify_host(system_state);
301 mic_shutdown_uninit();
302 mic_uninit_irq();
303 mic_dp_uninit();
304 module_put(mdrv->dev->driver->owner);
305}
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..914cc9b2caad
--- /dev/null
+++ b/drivers/misc/mic/card/mic_virtio.c
@@ -0,0 +1,630 @@
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_dev.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, get_order(mvdev->used_size[n]));
203 vring_del_virtqueue(vq);
204 mic_card_unmap(mvdev->mdev, mvdev->vr[n]);
205 mvdev->vr[n] = NULL;
206}
207
208static void mic_del_vqs(struct virtio_device *vdev)
209{
210 struct mic_vdev *mvdev = to_micvdev(vdev);
211 struct virtqueue *vq, *n;
212 int idx = 0;
213
214 dev_dbg(mic_dev(mvdev), "%s\n", __func__);
215
216 list_for_each_entry_safe(vq, n, &vdev->vqs, list)
217 mic_del_vq(vq, idx++);
218}
219
220/*
221 * This routine will assign vring's allocated in host/io memory. Code in
222 * virtio_ring.c however continues to access this io memory as if it were local
223 * memory without io accessors.
224 */
225static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
226 unsigned index,
227 void (*callback)(struct virtqueue *vq),
228 const char *name)
229{
230 struct mic_vdev *mvdev = to_micvdev(vdev);
231 struct mic_vqconfig __iomem *vqconfig;
232 struct mic_vqconfig config;
233 struct virtqueue *vq;
234 void __iomem *va;
235 struct _mic_vring_info __iomem *info;
236 void *used;
237 int vr_size, _vr_size, err, magic;
238 struct vring *vr;
239 u8 type = ioread8(&mvdev->desc->type);
240
241 if (index >= ioread8(&mvdev->desc->num_vq))
242 return ERR_PTR(-ENOENT);
243
244 if (!name)
245 return ERR_PTR(-ENOENT);
246
247 /* First assign the vring's allocated in host memory */
248 vqconfig = mic_vq_config(mvdev->desc) + index;
249 memcpy_fromio(&config, vqconfig, sizeof(config));
250 _vr_size = vring_size(config.num, MIC_VIRTIO_RING_ALIGN);
251 vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
252 va = mic_card_map(mvdev->mdev, config.address, vr_size);
253 if (!va)
254 return ERR_PTR(-ENOMEM);
255 mvdev->vr[index] = va;
256 memset_io(va, 0x0, _vr_size);
257 vq = vring_new_virtqueue(index,
258 config.num, MIC_VIRTIO_RING_ALIGN, vdev,
259 false,
260 va, mic_notify, callback, name);
261 if (!vq) {
262 err = -ENOMEM;
263 goto unmap;
264 }
265 info = va + _vr_size;
266 magic = ioread32(&info->magic);
267
268 if (WARN(magic != MIC_MAGIC + type + index, "magic mismatch")) {
269 err = -EIO;
270 goto unmap;
271 }
272
273 /* Allocate and reassign used ring now */
274 mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
275 sizeof(struct vring_used_elem) * config.num);
276 used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
277 get_order(mvdev->used_size[index]));
278 if (!used) {
279 err = -ENOMEM;
280 dev_err(mic_dev(mvdev), "%s %d err %d\n",
281 __func__, __LINE__, err);
282 goto del_vq;
283 }
284 iowrite64(virt_to_phys(used), &vqconfig->used_address);
285
286 /*
287 * To reassign the used ring here we are directly accessing
288 * struct vring_virtqueue which is a private data structure
289 * in virtio_ring.c. At the minimum, a BUILD_BUG_ON() in
290 * vring_new_virtqueue() would ensure that
291 * (&vq->vring == (struct vring *) (&vq->vq + 1));
292 */
293 vr = (struct vring *)(vq + 1);
294 vr->used = used;
295
296 vq->priv = mvdev;
297 return vq;
298del_vq:
299 vring_del_virtqueue(vq);
300unmap:
301 mic_card_unmap(mvdev->mdev, mvdev->vr[index]);
302 return ERR_PTR(err);
303}
304
305static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
306 struct virtqueue *vqs[],
307 vq_callback_t *callbacks[],
308 const char *names[])
309{
310 struct mic_vdev *mvdev = to_micvdev(vdev);
311 struct mic_device_ctrl __iomem *dc = mvdev->dc;
312 int i, err, retry = 100;
313
314 /* We must have this many virtqueues. */
315 if (nvqs > ioread8(&mvdev->desc->num_vq))
316 return -ENOENT;
317
318 for (i = 0; i < nvqs; ++i) {
319 dev_dbg(mic_dev(mvdev), "%s: %d: %s\n",
320 __func__, i, names[i]);
321 vqs[i] = mic_find_vq(vdev, i, callbacks[i], names[i]);
322 if (IS_ERR(vqs[i])) {
323 err = PTR_ERR(vqs[i]);
324 goto error;
325 }
326 }
327
328 iowrite8(1, &dc->used_address_updated);
329 /*
330 * Send an interrupt to the host to inform it that used
331 * rings have been re-assigned.
332 */
333 mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
334 for (i = retry; i--;) {
335 if (!ioread8(&dc->used_address_updated))
336 break;
337 msleep(100);
338 };
339
340 dev_dbg(mic_dev(mvdev), "%s: retry: %d\n", __func__, retry);
341 if (!retry) {
342 err = -ENODEV;
343 goto error;
344 }
345
346 return 0;
347error:
348 mic_del_vqs(vdev);
349 return err;
350}
351
352/*
353 * The config ops structure as defined by virtio config
354 */
355static struct virtio_config_ops mic_vq_config_ops = {
356 .get_features = mic_get_features,
357 .finalize_features = mic_finalize_features,
358 .get = mic_get,
359 .set = mic_set,
360 .get_status = mic_get_status,
361 .set_status = mic_set_status,
362 .reset = mic_reset,
363 .find_vqs = mic_find_vqs,
364 .del_vqs = mic_del_vqs,
365};
366
367static irqreturn_t
368mic_virtio_intr_handler(int irq, void *data)
369{
370 struct mic_vdev *mvdev = data;
371 struct virtqueue *vq;
372
373 mic_ack_interrupt(mvdev->mdev);
374 list_for_each_entry(vq, &mvdev->vdev.vqs, list)
375 vring_interrupt(0, vq);
376
377 return IRQ_HANDLED;
378}
379
380static void mic_virtio_release_dev(struct device *_d)
381{
382 /*
383 * No need for a release method similar to virtio PCI.
384 * Provide an empty one to avoid getting a warning from core.
385 */
386}
387
388/*
389 * adds a new device and register it with virtio
390 * appropriate drivers are loaded by the device model
391 */
392static int mic_add_device(struct mic_device_desc __iomem *d,
393 unsigned int offset, struct mic_driver *mdrv)
394{
395 struct mic_vdev *mvdev;
396 int ret;
397 int virtio_db;
398 u8 type = ioread8(&d->type);
399
400 mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
401 if (!mvdev) {
402 dev_err(mdrv->dev, "Cannot allocate mic dev %u type %u\n",
403 offset, type);
404 return -ENOMEM;
405 }
406
407 mvdev->mdev = &mdrv->mdev;
408 mvdev->vdev.dev.parent = mdrv->dev;
409 mvdev->vdev.dev.release = mic_virtio_release_dev;
410 mvdev->vdev.id.device = type;
411 mvdev->vdev.config = &mic_vq_config_ops;
412 mvdev->desc = d;
413 mvdev->dc = (void __iomem *)d + mic_aligned_desc_size(d);
414 init_completion(&mvdev->reset_done);
415
416 virtio_db = mic_next_card_db();
417 mvdev->virtio_cookie = mic_request_card_irq(mic_virtio_intr_handler,
418 "virtio intr", mvdev, virtio_db);
419 if (IS_ERR(mvdev->virtio_cookie)) {
420 ret = PTR_ERR(mvdev->virtio_cookie);
421 goto kfree;
422 }
423 iowrite8((u8)virtio_db, &mvdev->dc->h2c_vdev_db);
424 mvdev->c2h_vdev_db = ioread8(&mvdev->dc->c2h_vdev_db);
425
426 ret = register_virtio_device(&mvdev->vdev);
427 if (ret) {
428 dev_err(mic_dev(mvdev),
429 "Failed to register mic device %u type %u\n",
430 offset, type);
431 goto free_irq;
432 }
433 iowrite64((u64)mvdev, &mvdev->dc->vdev);
434 dev_dbg(mic_dev(mvdev), "%s: registered mic device %u type %u mvdev %p\n",
435 __func__, offset, type, mvdev);
436
437 return 0;
438
439free_irq:
440 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
441kfree:
442 kfree(mvdev);
443 return ret;
444}
445
446/*
447 * match for a mic device with a specific desc pointer
448 */
449static int mic_match_desc(struct device *dev, void *data)
450{
451 struct virtio_device *vdev = dev_to_virtio(dev);
452 struct mic_vdev *mvdev = to_micvdev(vdev);
453
454 return mvdev->desc == (void __iomem *)data;
455}
456
457static void mic_handle_config_change(struct mic_device_desc __iomem *d,
458 unsigned int offset, struct mic_driver *mdrv)
459{
460 struct mic_device_ctrl __iomem *dc
461 = (void __iomem *)d + mic_aligned_desc_size(d);
462 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
463 struct virtio_driver *drv;
464
465 if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED)
466 return;
467
468 dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__);
469 drv = container_of(mvdev->vdev.dev.driver,
470 struct virtio_driver, driver);
471 if (drv->config_changed)
472 drv->config_changed(&mvdev->vdev);
473 iowrite8(1, &dc->guest_ack);
474}
475
476/*
477 * removes a virtio device if a hot remove event has been
478 * requested by the host.
479 */
480static int mic_remove_device(struct mic_device_desc __iomem *d,
481 unsigned int offset, struct mic_driver *mdrv)
482{
483 struct mic_device_ctrl __iomem *dc
484 = (void __iomem *)d + mic_aligned_desc_size(d);
485 struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
486 u8 status;
487 int ret = -1;
488
489 if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) {
490 dev_dbg(mdrv->dev,
491 "%s %d config_change %d type %d mvdev %p\n",
492 __func__, __LINE__,
493 ioread8(&dc->config_change), ioread8(&d->type), mvdev);
494
495 status = ioread8(&d->status);
496 INIT_COMPLETION(mvdev->reset_done);
497 unregister_virtio_device(&mvdev->vdev);
498 mic_free_card_irq(mvdev->virtio_cookie, mvdev);
499 if (status & VIRTIO_CONFIG_S_DRIVER_OK)
500 wait_for_completion(&mvdev->reset_done);
501 kfree(mvdev);
502 iowrite8(1, &dc->guest_ack);
503 dev_dbg(mdrv->dev, "%s %d guest_ack %d\n",
504 __func__, __LINE__, ioread8(&dc->guest_ack));
505 ret = 0;
506 }
507
508 return ret;
509}
510
511#define REMOVE_DEVICES true
512
513static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
514{
515 s8 type;
516 unsigned int i;
517 struct mic_device_desc __iomem *d;
518 struct mic_device_ctrl __iomem *dc;
519 struct device *dev;
520 int ret;
521
522 for (i = mic_aligned_size(struct mic_bootparam);
523 i < MIC_DP_SIZE; i += mic_total_desc_size(d)) {
524 d = mdrv->dp + i;
525 dc = (void __iomem *)d + mic_aligned_desc_size(d);
526 /*
527 * This read barrier is paired with the corresponding write
528 * barrier on the host which is inserted before adding or
529 * removing a virtio device descriptor, by updating the type.
530 */
531 rmb();
532 type = ioread8(&d->type);
533
534 /* end of list */
535 if (type == 0)
536 break;
537
538 if (type == -1)
539 continue;
540
541 /* device already exists */
542 dev = device_find_child(mdrv->dev, d, mic_match_desc);
543 if (dev) {
544 if (remove)
545 iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
546 &dc->config_change);
547 put_device(dev);
548 mic_handle_config_change(d, i, mdrv);
549 ret = mic_remove_device(d, i, mdrv);
550 if (!ret && !remove)
551 iowrite8(-1, &d->type);
552 if (remove) {
553 iowrite8(0, &dc->config_change);
554 iowrite8(0, &dc->guest_ack);
555 }
556 continue;
557 }
558
559 /* new device */
560 dev_dbg(mdrv->dev, "%s %d Adding new virtio device %p\n",
561 __func__, __LINE__, d);
562 if (!remove)
563 mic_add_device(d, i, mdrv);
564 }
565}
566
567/*
568 * mic_hotplug_device tries to find changes in the device page.
569 */
570static void mic_hotplug_devices(struct work_struct *work)
571{
572 struct mic_driver *mdrv = container_of(work,
573 struct mic_driver, hotplug_work);
574
575 mic_scan_devices(mdrv, !REMOVE_DEVICES);
576}
577
578/*
579 * Interrupt handler for hot plug/config changes etc.
580 */
581static irqreturn_t
582mic_extint_handler(int irq, void *data)
583{
584 struct mic_driver *mdrv = (struct mic_driver *)data;
585
586 dev_dbg(mdrv->dev, "%s %d hotplug work\n",
587 __func__, __LINE__);
588 mic_ack_interrupt(&mdrv->mdev);
589 schedule_work(&mdrv->hotplug_work);
590 return IRQ_HANDLED;
591}
592
593/*
594 * Init function for virtio
595 */
596int mic_devices_init(struct mic_driver *mdrv)
597{
598 int rc;
599 struct mic_bootparam __iomem *bootparam;
600 int config_db;
601
602 INIT_WORK(&mdrv->hotplug_work, mic_hotplug_devices);
603 mic_scan_devices(mdrv, !REMOVE_DEVICES);
604
605 config_db = mic_next_card_db();
606 virtio_config_cookie = mic_request_card_irq(mic_extint_handler,
607 "virtio_config_intr", mdrv, config_db);
608 if (IS_ERR(virtio_config_cookie)) {
609 rc = PTR_ERR(virtio_config_cookie);
610 goto exit;
611 }
612
613 bootparam = mdrv->dp;
614 iowrite8(config_db, &bootparam->h2c_config_db);
615 return 0;
616exit:
617 return rc;
618}
619
620/*
621 * Uninit function for virtio
622 */
623void mic_devices_uninit(struct mic_driver *mdrv)
624{
625 struct mic_bootparam __iomem *bootparam = mdrv->dp;
626 iowrite8(-1, &bootparam->h2c_config_db);
627 mic_free_card_irq(virtio_config_cookie, mdrv);
628 flush_work(&mdrv->hotplug_work);
629 mic_scan_devices(mdrv, REMOVE_DEVICES);
630}
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..2868945c9a4d
--- /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_dev.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_dev.h b/drivers/misc/mic/common/mic_dev.h
new file mode 100644
index 000000000000..92999c2bbf82
--- /dev/null
+++ b/drivers/misc/mic/common/mic_dev.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_DEV_H__
22#define __MIC_DEV_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..60c54d5c43c2
--- /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_dev.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..028ba5d6fd1c
--- /dev/null
+++ b/drivers/misc/mic/host/mic_debugfs.c
@@ -0,0 +1,491 @@
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_dev.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, desc->next);
325 desc++;
326 }
327 avail = vrh->vring.avail;
328 seq_printf(s, "avail flags 0x%x idx %d\n",
329 avail->flags, avail->idx & (num - 1));
330 seq_printf(s, "avail flags 0x%x idx %d\n",
331 avail->flags, avail->idx);
332 for (j = 0; j < num; j++)
333 seq_printf(s, "avail ring[%d] %d\n",
334 j, avail->ring[j]);
335 used = vrh->vring.used;
336 seq_printf(s, "used flags 0x%x idx %d\n",
337 used->flags, used->idx & (num - 1));
338 seq_printf(s, "used flags 0x%x idx %d\n",
339 used->flags, used->idx);
340 for (j = 0; j < num; j++)
341 seq_printf(s, "used ring[%d] id %d len %d\n",
342 j, used->ring[j].id,
343 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] &
404 BIT(j)) ? 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
414static int mic_msi_irq_info_debug_open(struct inode *inode, struct file *file)
415{
416 return single_open(file, mic_msi_irq_info_show, inode->i_private);
417}
418
419static int
420mic_msi_irq_info_debug_release(struct inode *inode, struct file *file)
421{
422 return single_release(inode, file);
423}
424
425static const struct file_operations msi_irq_info_ops = {
426 .owner = THIS_MODULE,
427 .open = mic_msi_irq_info_debug_open,
428 .read = seq_read,
429 .llseek = seq_lseek,
430 .release = mic_msi_irq_info_debug_release
431};
432
433/**
434 * mic_create_debug_dir - Initialize MIC debugfs entries.
435 */
436void mic_create_debug_dir(struct mic_device *mdev)
437{
438 if (!mic_dbg)
439 return;
440
441 mdev->dbg_dir = debugfs_create_dir(dev_name(mdev->sdev), mic_dbg);
442 if (!mdev->dbg_dir)
443 return;
444
445 debugfs_create_file("log_buf", 0444, mdev->dbg_dir, mdev, &log_buf_ops);
446
447 debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, &smpt_file_ops);
448
449 debugfs_create_file("soft_reset", 0444, mdev->dbg_dir, mdev,
450 &soft_reset_ops);
451
452 debugfs_create_file("post_code", 0444, mdev->dbg_dir, mdev,
453 &post_code_ops);
454
455 debugfs_create_file("dp", 0444, mdev->dbg_dir, mdev, &dp_ops);
456
457 debugfs_create_file("vdev_info", 0444, mdev->dbg_dir, mdev,
458 &vdev_info_ops);
459
460 debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, mdev,
461 &msi_irq_info_ops);
462}
463
464/**
465 * mic_delete_debug_dir - Uninitialize MIC debugfs entries.
466 */
467void mic_delete_debug_dir(struct mic_device *mdev)
468{
469 if (!mdev->dbg_dir)
470 return;
471
472 debugfs_remove_recursive(mdev->dbg_dir);
473}
474
475/**
476 * mic_init_debugfs - Initialize global debugfs entry.
477 */
478void __init mic_init_debugfs(void)
479{
480 mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL);
481 if (!mic_dbg)
482 pr_err("can't create debugfs dir\n");
483}
484
485/**
486 * mic_exit_debugfs - Uninitialize global debugfs entry
487 */
488void mic_exit_debugfs(void)
489{
490 debugfs_remove(mic_dbg);
491}
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..8dc6ff16845a
--- /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_dev.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..f9c29bc918bc
--- /dev/null
+++ b/drivers/misc/mic/host/mic_intr.c
@@ -0,0 +1,630 @@
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_dev.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(*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 int entry_size = sizeof(*mdev->irq_info.msix_entries);
186
187 mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX,
188 entry_size, GFP_KERNEL);
189 if (!mdev->irq_info.msix_entries) {
190 rc = -ENOMEM;
191 goto err_nomem1;
192 }
193
194 for (i = 0; i < MIC_MIN_MSIX; i++)
195 mdev->irq_info.msix_entries[i].entry = i;
196
197 rc = pci_enable_msix(pdev, mdev->irq_info.msix_entries,
198 MIC_MIN_MSIX);
199 if (rc) {
200 dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc);
201 goto err_enable_msix;
202 }
203
204 mdev->irq_info.num_vectors = MIC_MIN_MSIX;
205 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
206 mdev->irq_info.num_vectors), GFP_KERNEL);
207
208 if (!mdev->irq_info.mic_msi_map) {
209 rc = -ENOMEM;
210 goto err_nomem2;
211 }
212
213 dev_dbg(mdev->sdev->parent,
214 "%d MSIx irqs setup\n", mdev->irq_info.num_vectors);
215 return 0;
216err_nomem2:
217 pci_disable_msix(pdev);
218err_enable_msix:
219 kfree(mdev->irq_info.msix_entries);
220err_nomem1:
221 mdev->irq_info.num_vectors = 0;
222 return rc;
223}
224
225/**
226 * mic_setup_callbacks - Initialize data structures needed
227 * to handle callbacks.
228 *
229 * @mdev: pointer to mic_device instance
230 */
231static int mic_setup_callbacks(struct mic_device *mdev)
232{
233 int i;
234
235 mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS,
236 sizeof(*mdev->irq_info.cb_list),
237 GFP_KERNEL);
238 if (!mdev->irq_info.cb_list)
239 return -ENOMEM;
240
241 for (i = 0; i < MIC_NUM_OFFSETS; i++)
242 INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]);
243 ida_init(&mdev->irq_info.cb_ida);
244 spin_lock_init(&mdev->irq_info.mic_intr_lock);
245 return 0;
246}
247
248/**
249 * mic_release_callbacks - Uninitialize data structures needed
250 * to handle callbacks.
251 *
252 * @mdev: pointer to mic_device instance
253 */
254static void mic_release_callbacks(struct mic_device *mdev)
255{
256 unsigned long flags;
257 struct list_head *pos, *tmp;
258 struct mic_intr_cb *intr_cb;
259 int i;
260
261 for (i = 0; i < MIC_NUM_OFFSETS; i++) {
262 spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags);
263
264 if (list_empty(&mdev->irq_info.cb_list[i])) {
265 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock,
266 flags);
267 break;
268 }
269
270 list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) {
271 intr_cb = list_entry(pos, struct mic_intr_cb, list);
272 list_del(pos);
273 ida_simple_remove(&mdev->irq_info.cb_ida,
274 intr_cb->cb_id);
275 kfree(intr_cb);
276 }
277 spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags);
278 }
279 ida_destroy(&mdev->irq_info.cb_ida);
280 kfree(mdev->irq_info.cb_list);
281}
282
283/**
284 * mic_setup_msi - Initializes MSI interrupts.
285 *
286 * @mdev: pointer to mic_device instance
287 * @pdev: PCI device structure
288 *
289 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
290 */
291static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev)
292{
293 int rc;
294
295 rc = pci_enable_msi(pdev);
296 if (rc) {
297 dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc);
298 return rc;
299 }
300
301 mdev->irq_info.num_vectors = 1;
302 mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) *
303 mdev->irq_info.num_vectors), GFP_KERNEL);
304
305 if (!mdev->irq_info.mic_msi_map) {
306 rc = -ENOMEM;
307 goto err_nomem1;
308 }
309
310 rc = mic_setup_callbacks(mdev);
311 if (rc) {
312 dev_err(&pdev->dev, "Error setting up callbacks\n");
313 goto err_nomem2;
314 }
315
316 rc = request_irq(pdev->irq, mic_interrupt, 0 , "mic-msi", mdev);
317 if (rc) {
318 dev_err(&pdev->dev, "Error allocating MSI interrupt\n");
319 goto err_irq_req_fail;
320 }
321
322 dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors);
323 return 0;
324err_irq_req_fail:
325 mic_release_callbacks(mdev);
326err_nomem2:
327 kfree(mdev->irq_info.mic_msi_map);
328err_nomem1:
329 pci_disable_msi(pdev);
330 mdev->irq_info.num_vectors = 0;
331 return rc;
332}
333
334/**
335 * mic_setup_intx - Initializes legacy interrupts.
336 *
337 * @mdev: pointer to mic_device instance
338 * @pdev: PCI device structure
339 *
340 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
341 */
342static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev)
343{
344 int rc;
345
346 pci_msi_off(pdev);
347
348 /* Enable intx */
349 pci_intx(pdev, 1);
350 rc = mic_setup_callbacks(mdev);
351 if (rc) {
352 dev_err(&pdev->dev, "Error setting up callbacks\n");
353 goto err_nomem;
354 }
355
356 rc = request_irq(pdev->irq, mic_interrupt,
357 IRQF_SHARED, "mic-intx", mdev);
358 if (rc)
359 goto err;
360
361 dev_dbg(&pdev->dev, "intx irq setup\n");
362 return 0;
363err:
364 mic_release_callbacks(mdev);
365err_nomem:
366 return rc;
367}
368
369/**
370 * mic_next_db - Retrieve the next doorbell interrupt source id.
371 * The id is picked sequentially from the available pool of
372 * doorlbell ids.
373 *
374 * @mdev: pointer to the mic_device instance.
375 *
376 * Returns the next doorbell interrupt source.
377 */
378int mic_next_db(struct mic_device *mdev)
379{
380 int next_db;
381
382 next_db = mdev->irq_info.next_avail_src %
383 mdev->intr_info->intr_len[MIC_INTR_DB];
384 mdev->irq_info.next_avail_src++;
385 return next_db;
386}
387
388#define COOKIE_ID_SHIFT 16
389#define GET_ENTRY(cookie) ((cookie) & 0xFFFF)
390#define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT)
391#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT)
392
393/**
394 * mic_request_irq - request an irq. mic_mutex needs
395 * to be held before calling this function.
396 *
397 * @mdev: pointer to mic_device instance
398 * @func: The callback function that handles the interrupt.
399 * The function needs to call ack_interrupts
400 * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts.
401 * @name: The ASCII name of the callee requesting the irq.
402 * @data: private data that is returned back when calling the
403 * function handler.
404 * @intr_src: The source id of the requester. Its the doorbell id
405 * for Doorbell interrupts and DMA channel id for DMA interrupts.
406 * @type: The type of interrupt. Values defined in mic_intr_type
407 *
408 * returns: The cookie that is transparent to the caller. Passed
409 * back when calling mic_free_irq. An appropriate error code
410 * is returned on failure. Caller needs to use IS_ERR(return_val)
411 * to check for failure and PTR_ERR(return_val) to obtained the
412 * error code.
413 *
414 */
415struct mic_irq *mic_request_irq(struct mic_device *mdev,
416 irqreturn_t (*func)(int irq, void *dev),
417 const char *name, void *data, int intr_src,
418 enum mic_intr_type type)
419{
420 u16 offset;
421 int rc = 0;
422 struct msix_entry *msix = NULL;
423 unsigned long cookie = 0;
424 u16 entry;
425 struct mic_intr_cb *intr_cb;
426 struct pci_dev *pdev = container_of(mdev->sdev->parent,
427 struct pci_dev, dev);
428
429 offset = mic_map_src_to_offset(mdev, intr_src, type);
430 if (offset >= MIC_NUM_OFFSETS) {
431 dev_err(mdev->sdev->parent,
432 "Error mapping index %d to a valid source id.\n",
433 intr_src);
434 rc = -EINVAL;
435 goto err;
436 }
437
438 if (mdev->irq_info.num_vectors > 1) {
439 msix = mic_get_available_vector(mdev);
440 if (!msix) {
441 dev_err(mdev->sdev->parent,
442 "No MSIx vectors available for use.\n");
443 rc = -ENOSPC;
444 goto err;
445 }
446
447 rc = request_irq(msix->vector, func, 0, name, data);
448 if (rc) {
449 dev_dbg(mdev->sdev->parent,
450 "request irq failed rc = %d\n", rc);
451 goto err;
452 }
453 entry = msix->entry;
454 mdev->irq_info.mic_msi_map[entry] |= BIT(offset);
455 mdev->intr_ops->program_msi_to_src_map(mdev,
456 entry, offset, true);
457 cookie = MK_COOKIE(entry, offset);
458 dev_dbg(mdev->sdev->parent, "irq: %d assigned for src: %d\n",
459 msix->vector, intr_src);
460 } else {
461 intr_cb = mic_register_intr_callback(mdev,
462 offset, func, data);
463 if (IS_ERR(intr_cb)) {
464 dev_err(mdev->sdev->parent,
465 "No available callback entries for use\n");
466 rc = PTR_ERR(intr_cb);
467 goto err;
468 }
469
470 entry = 0;
471 if (pci_dev_msi_enabled(pdev)) {
472 mdev->irq_info.mic_msi_map[entry] |= (1 << offset);
473 mdev->intr_ops->program_msi_to_src_map(mdev,
474 entry, offset, true);
475 }
476 cookie = MK_COOKIE(entry, intr_cb->cb_id);
477 dev_dbg(mdev->sdev->parent, "callback %d registered for src: %d\n",
478 intr_cb->cb_id, intr_src);
479 }
480 return (struct mic_irq *)cookie;
481err:
482 return ERR_PTR(rc);
483}
484
485/**
486 * mic_free_irq - free irq. mic_mutex
487 * needs to be held before calling this function.
488 *
489 * @mdev: pointer to mic_device instance
490 * @cookie: cookie obtained during a successful call to mic_request_irq
491 * @data: private data specified by the calling function during the
492 * mic_request_irq
493 *
494 * returns: none.
495 */
496void mic_free_irq(struct mic_device *mdev,
497 struct mic_irq *cookie, void *data)
498{
499 u32 offset;
500 u32 entry;
501 u8 src_id;
502 unsigned int irq;
503 struct pci_dev *pdev = container_of(mdev->sdev->parent,
504 struct pci_dev, dev);
505
506 entry = GET_ENTRY((unsigned long)cookie);
507 offset = GET_OFFSET((unsigned long)cookie);
508 if (mdev->irq_info.num_vectors > 1) {
509 if (entry >= mdev->irq_info.num_vectors) {
510 dev_warn(mdev->sdev->parent,
511 "entry %d should be < num_irq %d\n",
512 entry, mdev->irq_info.num_vectors);
513 return;
514 }
515 irq = mdev->irq_info.msix_entries[entry].vector;
516 free_irq(irq, data);
517 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset));
518 mdev->intr_ops->program_msi_to_src_map(mdev,
519 entry, offset, false);
520
521 dev_dbg(mdev->sdev->parent, "irq: %d freed\n", irq);
522 } else {
523 irq = pdev->irq;
524 src_id = mic_unregister_intr_callback(mdev, offset);
525 if (src_id >= MIC_NUM_OFFSETS) {
526 dev_warn(mdev->sdev->parent, "Error unregistering callback\n");
527 return;
528 }
529 if (pci_dev_msi_enabled(pdev)) {
530 mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id));
531 mdev->intr_ops->program_msi_to_src_map(mdev,
532 entry, src_id, false);
533 }
534 dev_dbg(mdev->sdev->parent, "callback %d unregistered for src: %d\n",
535 offset, src_id);
536 }
537}
538
539/**
540 * mic_setup_interrupts - Initializes interrupts.
541 *
542 * @mdev: pointer to mic_device instance
543 * @pdev: PCI device structure
544 *
545 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
546 */
547int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
548{
549 int rc;
550
551 rc = mic_setup_msix(mdev, pdev);
552 if (!rc)
553 goto done;
554
555 rc = mic_setup_msi(mdev, pdev);
556 if (!rc)
557 goto done;
558
559 rc = mic_setup_intx(mdev, pdev);
560 if (rc) {
561 dev_err(mdev->sdev->parent, "no usable interrupts\n");
562 return rc;
563 }
564done:
565 mdev->intr_ops->enable_interrupts(mdev);
566 return 0;
567}
568
569/**
570 * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts
571 *
572 * @mdev: pointer to mic_device instance
573 * @pdev: PCI device structure
574 *
575 * returns none.
576 */
577void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev)
578{
579 int i;
580
581 mdev->intr_ops->disable_interrupts(mdev);
582 if (mdev->irq_info.num_vectors > 1) {
583 for (i = 0; i < mdev->irq_info.num_vectors; i++) {
584 if (mdev->irq_info.mic_msi_map[i])
585 dev_warn(&pdev->dev, "irq %d may still be in use.\n",
586 mdev->irq_info.msix_entries[i].vector);
587 }
588 kfree(mdev->irq_info.mic_msi_map);
589 kfree(mdev->irq_info.msix_entries);
590 pci_disable_msix(pdev);
591 } else {
592 if (pci_dev_msi_enabled(pdev)) {
593 free_irq(pdev->irq, mdev);
594 kfree(mdev->irq_info.mic_msi_map);
595 pci_disable_msi(pdev);
596 } else {
597 free_irq(pdev->irq, mdev);
598 }
599 mic_release_callbacks(mdev);
600 }
601}
602
603/**
604 * mic_intr_restore - Restore MIC interrupt registers.
605 *
606 * @mdev: pointer to mic_device instance.
607 *
608 * Restore the interrupt registers to values previously
609 * stored in the SW data structures. mic_mutex needs to
610 * be held before calling this function.
611 *
612 * returns None.
613 */
614void mic_intr_restore(struct mic_device *mdev)
615{
616 int entry, offset;
617 struct pci_dev *pdev = container_of(mdev->sdev->parent,
618 struct pci_dev, dev);
619
620 if (!pci_dev_msi_enabled(pdev))
621 return;
622
623 for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) {
624 for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) {
625 if (mdev->irq_info.mic_msi_map[entry] & BIT(offset))
626 mdev->intr_ops->program_msi_to_src_map(mdev,
627 entry, offset, true);
628 }
629 }
630}
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..ca06aa9b7114
--- /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_dev.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..fae474c4899e
--- /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_dev.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_array(smpt_info->info.num_reg,
370 sizeof(*smpt_info->entry), 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..75746adfb155
--- /dev/null
+++ b/drivers/misc/mic/host/mic_sysfs.c
@@ -0,0 +1,452 @@
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_dev.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
68family_show(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_RO(family);
89
90static ssize_t
91stepping_show(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_RO(stepping);
118
119static ssize_t
120state_show(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
132state_store(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_RW(state);
164
165static ssize_t shutdown_status_show(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_RO(shutdown_status);
177
178static ssize_t
179cmdline_show(struct device *dev, struct device_attribute *attr, char *buf)
180{
181 struct mic_device *mdev = dev_get_drvdata(dev->parent);
182 char *cmdline;
183
184 if (!mdev)
185 return -EINVAL;
186
187 cmdline = mdev->cmdline;
188
189 if (cmdline)
190 return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline);
191 return 0;
192}
193
194static ssize_t
195cmdline_store(struct device *dev, struct device_attribute *attr,
196 const char *buf, size_t count)
197{
198 struct mic_device *mdev = dev_get_drvdata(dev->parent);
199
200 if (!mdev)
201 return -EINVAL;
202
203 mutex_lock(&mdev->mic_mutex);
204 kfree(mdev->cmdline);
205
206 mdev->cmdline = kmalloc(count + 1, GFP_KERNEL);
207 if (!mdev->cmdline) {
208 count = -ENOMEM;
209 goto unlock;
210 }
211
212 strncpy(mdev->cmdline, buf, count);
213
214 if (mdev->cmdline[count - 1] == '\n')
215 mdev->cmdline[count - 1] = '\0';
216 else
217 mdev->cmdline[count] = '\0';
218unlock:
219 mutex_unlock(&mdev->mic_mutex);
220 return count;
221}
222static DEVICE_ATTR_RW(cmdline);
223
224static ssize_t
225firmware_show(struct device *dev, struct device_attribute *attr, char *buf)
226{
227 struct mic_device *mdev = dev_get_drvdata(dev->parent);
228 char *firmware;
229
230 if (!mdev)
231 return -EINVAL;
232
233 firmware = mdev->firmware;
234
235 if (firmware)
236 return scnprintf(buf, PAGE_SIZE, "%s\n", firmware);
237 return 0;
238}
239
240static ssize_t
241firmware_store(struct device *dev, struct device_attribute *attr,
242 const char *buf, size_t count)
243{
244 struct mic_device *mdev = dev_get_drvdata(dev->parent);
245
246 if (!mdev)
247 return -EINVAL;
248
249 mutex_lock(&mdev->mic_mutex);
250 kfree(mdev->firmware);
251
252 mdev->firmware = kmalloc(count + 1, GFP_KERNEL);
253 if (!mdev->firmware) {
254 count = -ENOMEM;
255 goto unlock;
256 }
257 strncpy(mdev->firmware, buf, count);
258
259 if (mdev->firmware[count - 1] == '\n')
260 mdev->firmware[count - 1] = '\0';
261 else
262 mdev->firmware[count] = '\0';
263unlock:
264 mutex_unlock(&mdev->mic_mutex);
265 return count;
266}
267static DEVICE_ATTR_RW(firmware);
268
269static ssize_t
270ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf)
271{
272 struct mic_device *mdev = dev_get_drvdata(dev->parent);
273 char *ramdisk;
274
275 if (!mdev)
276 return -EINVAL;
277
278 ramdisk = mdev->ramdisk;
279
280 if (ramdisk)
281 return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk);
282 return 0;
283}
284
285static ssize_t
286ramdisk_store(struct device *dev, struct device_attribute *attr,
287 const char *buf, size_t count)
288{
289 struct mic_device *mdev = dev_get_drvdata(dev->parent);
290
291 if (!mdev)
292 return -EINVAL;
293
294 mutex_lock(&mdev->mic_mutex);
295 kfree(mdev->ramdisk);
296
297 mdev->ramdisk = kmalloc(count + 1, GFP_KERNEL);
298 if (!mdev->ramdisk) {
299 count = -ENOMEM;
300 goto unlock;
301 }
302
303 strncpy(mdev->ramdisk, buf, count);
304
305 if (mdev->ramdisk[count - 1] == '\n')
306 mdev->ramdisk[count - 1] = '\0';
307 else
308 mdev->ramdisk[count] = '\0';
309unlock:
310 mutex_unlock(&mdev->mic_mutex);
311 return count;
312}
313static DEVICE_ATTR_RW(ramdisk);
314
315static ssize_t
316bootmode_show(struct device *dev, struct device_attribute *attr, char *buf)
317{
318 struct mic_device *mdev = dev_get_drvdata(dev->parent);
319 char *bootmode;
320
321 if (!mdev)
322 return -EINVAL;
323
324 bootmode = mdev->bootmode;
325
326 if (bootmode)
327 return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode);
328 return 0;
329}
330
331static ssize_t
332bootmode_store(struct device *dev, struct device_attribute *attr,
333 const char *buf, size_t count)
334{
335 struct mic_device *mdev = dev_get_drvdata(dev->parent);
336
337 if (!mdev)
338 return -EINVAL;
339
340 if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "elf"))
341 return -EINVAL;
342
343 mutex_lock(&mdev->mic_mutex);
344 kfree(mdev->bootmode);
345
346 mdev->bootmode = kmalloc(count + 1, GFP_KERNEL);
347 if (!mdev->bootmode) {
348 count = -ENOMEM;
349 goto unlock;
350 }
351
352 strncpy(mdev->bootmode, buf, count);
353
354 if (mdev->bootmode[count - 1] == '\n')
355 mdev->bootmode[count - 1] = '\0';
356 else
357 mdev->bootmode[count] = '\0';
358unlock:
359 mutex_unlock(&mdev->mic_mutex);
360 return count;
361}
362static DEVICE_ATTR_RW(bootmode);
363
364static ssize_t
365log_buf_addr_show(struct device *dev, struct device_attribute *attr,
366 char *buf)
367{
368 struct mic_device *mdev = dev_get_drvdata(dev->parent);
369
370 if (!mdev)
371 return -EINVAL;
372
373 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_addr);
374}
375
376static ssize_t
377log_buf_addr_store(struct device *dev, struct device_attribute *attr,
378 const char *buf, size_t count)
379{
380 struct mic_device *mdev = dev_get_drvdata(dev->parent);
381 int ret;
382 unsigned long addr;
383
384 if (!mdev)
385 return -EINVAL;
386
387 ret = kstrtoul(buf, 16, &addr);
388 if (ret)
389 goto exit;
390
391 mdev->log_buf_addr = (void *)addr;
392 ret = count;
393exit:
394 return ret;
395}
396static DEVICE_ATTR_RW(log_buf_addr);
397
398static ssize_t
399log_buf_len_show(struct device *dev, struct device_attribute *attr,
400 char *buf)
401{
402 struct mic_device *mdev = dev_get_drvdata(dev->parent);
403
404 if (!mdev)
405 return -EINVAL;
406
407 return scnprintf(buf, PAGE_SIZE, "%p\n", mdev->log_buf_len);
408}
409
410static ssize_t
411log_buf_len_store(struct device *dev, struct device_attribute *attr,
412 const char *buf, size_t count)
413{
414 struct mic_device *mdev = dev_get_drvdata(dev->parent);
415 int ret;
416 unsigned long addr;
417
418 if (!mdev)
419 return -EINVAL;
420
421 ret = kstrtoul(buf, 16, &addr);
422 if (ret)
423 goto exit;
424
425 mdev->log_buf_len = (int *)addr;
426 ret = count;
427exit:
428 return ret;
429}
430static DEVICE_ATTR_RW(log_buf_len);
431
432static struct attribute *mic_default_attrs[] = {
433 &dev_attr_family.attr,
434 &dev_attr_stepping.attr,
435 &dev_attr_state.attr,
436 &dev_attr_shutdown_status.attr,
437 &dev_attr_cmdline.attr,
438 &dev_attr_firmware.attr,
439 &dev_attr_ramdisk.attr,
440 &dev_attr_bootmode.attr,
441 &dev_attr_log_buf_addr.attr,
442 &dev_attr_log_buf_len.attr,
443
444 NULL
445};
446
447ATTRIBUTE_GROUPS(mic_default);
448
449void mic_sysfs_init(struct mic_device *mdev)
450{
451 mdev->attr_group = mic_default_groups;
452}
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
new file mode 100644
index 000000000000..0c883cd4f1d1
--- /dev/null
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -0,0 +1,700 @@
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_dev.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 && copy->update_used) {
229 u32 total = 0;
230
231 /* Determine the total data consumed */
232 total += mic_vringh_iov_consumed(riov);
233 total += mic_vringh_iov_consumed(wiov);
234 vringh_complete_kern(vrh, *head, total);
235 *head = USHRT_MAX;
236 if (vringh_need_notify_kern(vrh) > 0)
237 vringh_notify(vrh);
238 vringh_kiov_cleanup(riov);
239 vringh_kiov_cleanup(wiov);
240 /* Update avail idx for user space */
241 vr->info->avail_idx = vrh->last_avail_idx;
242 }
243 return ret;
244}
245
246static inline int mic_verify_copy_args(struct mic_vdev *mvdev,
247 struct mic_copy_desc *copy)
248{
249 if (copy->vr_idx >= mvdev->dd->num_vq) {
250 dev_err(mic_dev(mvdev), "%s %d err %d\n",
251 __func__, __LINE__, -EINVAL);
252 return -EINVAL;
253 }
254 return 0;
255}
256
257/* Copy a specified number of virtio descriptors in a chain */
258int mic_virtio_copy_desc(struct mic_vdev *mvdev,
259 struct mic_copy_desc *copy)
260{
261 int err;
262 struct mic_vringh *mvr = &mvdev->mvr[copy->vr_idx];
263
264 err = mic_verify_copy_args(mvdev, copy);
265 if (err)
266 return err;
267
268 mutex_lock(&mvr->vr_mutex);
269 if (!mic_vdevup(mvdev)) {
270 err = -ENODEV;
271 dev_err(mic_dev(mvdev), "%s %d err %d\n",
272 __func__, __LINE__, err);
273 goto err;
274 }
275 err = _mic_virtio_copy(mvdev, copy);
276 if (err) {
277 dev_err(mic_dev(mvdev), "%s %d err %d\n",
278 __func__, __LINE__, err);
279 }
280err:
281 mutex_unlock(&mvr->vr_mutex);
282 return err;
283}
284
285static void mic_virtio_init_post(struct mic_vdev *mvdev)
286{
287 struct mic_vqconfig *vqconfig = mic_vq_config(mvdev->dd);
288 int i;
289
290 for (i = 0; i < mvdev->dd->num_vq; i++) {
291 if (!le64_to_cpu(vqconfig[i].used_address)) {
292 dev_warn(mic_dev(mvdev), "used_address zero??\n");
293 continue;
294 }
295 mvdev->mvr[i].vrh.vring.used =
296 mvdev->mdev->aper.va +
297 le64_to_cpu(vqconfig[i].used_address);
298 }
299
300 mvdev->dc->used_address_updated = 0;
301
302 dev_dbg(mic_dev(mvdev), "%s: device type %d LINKUP\n",
303 __func__, mvdev->virtio_id);
304}
305
306static inline void mic_virtio_device_reset(struct mic_vdev *mvdev)
307{
308 int i;
309
310 dev_dbg(mic_dev(mvdev), "%s: status %d device type %d RESET\n",
311 __func__, mvdev->dd->status, mvdev->virtio_id);
312
313 for (i = 0; i < mvdev->dd->num_vq; i++)
314 /*
315 * Avoid lockdep false positive. The + 1 is for the mic
316 * mutex which is held in the reset devices code path.
317 */
318 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
319
320 /* 0 status means "reset" */
321 mvdev->dd->status = 0;
322 mvdev->dc->vdev_reset = 0;
323 mvdev->dc->host_ack = 1;
324
325 for (i = 0; i < mvdev->dd->num_vq; i++) {
326 struct vringh *vrh = &mvdev->mvr[i].vrh;
327 mvdev->mvr[i].vring.info->avail_idx = 0;
328 vrh->completed = 0;
329 vrh->last_avail_idx = 0;
330 vrh->last_used_idx = 0;
331 }
332
333 for (i = 0; i < mvdev->dd->num_vq; i++)
334 mutex_unlock(&mvdev->mvr[i].vr_mutex);
335}
336
337void mic_virtio_reset_devices(struct mic_device *mdev)
338{
339 struct list_head *pos, *tmp;
340 struct mic_vdev *mvdev;
341
342 dev_dbg(mdev->sdev->parent, "%s\n", __func__);
343
344 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
345 mvdev = list_entry(pos, struct mic_vdev, list);
346 mic_virtio_device_reset(mvdev);
347 mvdev->poll_wake = 1;
348 wake_up(&mvdev->waitq);
349 }
350}
351
352void mic_bh_handler(struct work_struct *work)
353{
354 struct mic_vdev *mvdev = container_of(work, struct mic_vdev,
355 virtio_bh_work);
356
357 if (mvdev->dc->used_address_updated)
358 mic_virtio_init_post(mvdev);
359
360 if (mvdev->dc->vdev_reset)
361 mic_virtio_device_reset(mvdev);
362
363 mvdev->poll_wake = 1;
364 wake_up(&mvdev->waitq);
365}
366
367static irqreturn_t mic_virtio_intr_handler(int irq, void *data)
368{
369 struct mic_vdev *mvdev = data;
370 struct mic_device *mdev = mvdev->mdev;
371
372 mdev->ops->ack_interrupt(mdev);
373 schedule_work(&mvdev->virtio_bh_work);
374 return IRQ_HANDLED;
375}
376
377int mic_virtio_config_change(struct mic_vdev *mvdev,
378 void __user *argp)
379{
380 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
381 int ret = 0, retry = 100, i;
382 struct mic_bootparam *bootparam = mvdev->mdev->dp;
383 s8 db = bootparam->h2c_config_db;
384
385 mutex_lock(&mvdev->mdev->mic_mutex);
386 for (i = 0; i < mvdev->dd->num_vq; i++)
387 mutex_lock_nested(&mvdev->mvr[i].vr_mutex, i + 1);
388
389 if (db == -1 || mvdev->dd->type == -1) {
390 ret = -EIO;
391 goto exit;
392 }
393
394 if (copy_from_user(mic_vq_configspace(mvdev->dd),
395 argp, mvdev->dd->config_len)) {
396 dev_err(mic_dev(mvdev), "%s %d err %d\n",
397 __func__, __LINE__, -EFAULT);
398 ret = -EFAULT;
399 goto exit;
400 }
401 mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
402 mvdev->mdev->ops->send_intr(mvdev->mdev, db);
403
404 for (i = retry; i--;) {
405 ret = wait_event_timeout(wake,
406 mvdev->dc->guest_ack, msecs_to_jiffies(100));
407 if (ret)
408 break;
409 }
410
411 dev_dbg(mic_dev(mvdev),
412 "%s %d retry: %d\n", __func__, __LINE__, retry);
413 mvdev->dc->config_change = 0;
414 mvdev->dc->guest_ack = 0;
415exit:
416 for (i = 0; i < mvdev->dd->num_vq; i++)
417 mutex_unlock(&mvdev->mvr[i].vr_mutex);
418 mutex_unlock(&mvdev->mdev->mic_mutex);
419 return ret;
420}
421
422static int mic_copy_dp_entry(struct mic_vdev *mvdev,
423 void __user *argp,
424 __u8 *type,
425 struct mic_device_desc **devpage)
426{
427 struct mic_device *mdev = mvdev->mdev;
428 struct mic_device_desc dd, *dd_config, *devp;
429 struct mic_vqconfig *vqconfig;
430 int ret = 0, i;
431 bool slot_found = false;
432
433 if (copy_from_user(&dd, argp, sizeof(dd))) {
434 dev_err(mic_dev(mvdev), "%s %d err %d\n",
435 __func__, __LINE__, -EFAULT);
436 return -EFAULT;
437 }
438
439 if (mic_aligned_desc_size(&dd) > MIC_MAX_DESC_BLK_SIZE ||
440 dd.num_vq > MIC_MAX_VRINGS) {
441 dev_err(mic_dev(mvdev), "%s %d err %d\n",
442 __func__, __LINE__, -EINVAL);
443 return -EINVAL;
444 }
445
446 dd_config = kmalloc(mic_desc_size(&dd), GFP_KERNEL);
447 if (dd_config == NULL) {
448 dev_err(mic_dev(mvdev), "%s %d err %d\n",
449 __func__, __LINE__, -ENOMEM);
450 return -ENOMEM;
451 }
452 if (copy_from_user(dd_config, argp, mic_desc_size(&dd))) {
453 ret = -EFAULT;
454 dev_err(mic_dev(mvdev), "%s %d err %d\n",
455 __func__, __LINE__, ret);
456 goto exit;
457 }
458
459 vqconfig = mic_vq_config(dd_config);
460 for (i = 0; i < dd.num_vq; i++) {
461 if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) {
462 ret = -EINVAL;
463 dev_err(mic_dev(mvdev), "%s %d err %d\n",
464 __func__, __LINE__, ret);
465 goto exit;
466 }
467 }
468
469 /* Find the first free device page entry */
470 for (i = mic_aligned_size(struct mic_bootparam);
471 i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
472 i += mic_total_desc_size(devp)) {
473 devp = mdev->dp + i;
474 if (devp->type == 0 || devp->type == -1) {
475 slot_found = true;
476 break;
477 }
478 }
479 if (!slot_found) {
480 ret = -EINVAL;
481 dev_err(mic_dev(mvdev), "%s %d err %d\n",
482 __func__, __LINE__, ret);
483 goto exit;
484 }
485 /*
486 * Save off the type before doing the memcpy. Type will be set in the
487 * end after completing all initialization for the new device.
488 */
489 *type = dd_config->type;
490 dd_config->type = 0;
491 memcpy(devp, dd_config, mic_desc_size(dd_config));
492
493 *devpage = devp;
494exit:
495 kfree(dd_config);
496 return ret;
497}
498
499static void mic_init_device_ctrl(struct mic_vdev *mvdev,
500 struct mic_device_desc *devpage)
501{
502 struct mic_device_ctrl *dc;
503
504 dc = (void *)devpage + mic_aligned_desc_size(devpage);
505
506 dc->config_change = 0;
507 dc->guest_ack = 0;
508 dc->vdev_reset = 0;
509 dc->host_ack = 0;
510 dc->used_address_updated = 0;
511 dc->c2h_vdev_db = -1;
512 dc->h2c_vdev_db = -1;
513 mvdev->dc = dc;
514}
515
516int mic_virtio_add_device(struct mic_vdev *mvdev,
517 void __user *argp)
518{
519 struct mic_device *mdev = mvdev->mdev;
520 struct mic_device_desc *dd;
521 struct mic_vqconfig *vqconfig;
522 int vr_size, i, j, ret;
523 u8 type;
524 s8 db;
525 char irqname[10];
526 struct mic_bootparam *bootparam = mdev->dp;
527 u16 num;
528
529 mutex_lock(&mdev->mic_mutex);
530
531 ret = mic_copy_dp_entry(mvdev, argp, &type, &dd);
532 if (ret) {
533 mutex_unlock(&mdev->mic_mutex);
534 return ret;
535 }
536
537 mic_init_device_ctrl(mvdev, dd);
538
539 mvdev->dd = dd;
540 mvdev->virtio_id = type;
541 vqconfig = mic_vq_config(dd);
542 INIT_WORK(&mvdev->virtio_bh_work, mic_bh_handler);
543
544 for (i = 0; i < dd->num_vq; i++) {
545 struct mic_vringh *mvr = &mvdev->mvr[i];
546 struct mic_vring *vr = &mvdev->mvr[i].vring;
547 num = le16_to_cpu(vqconfig[i].num);
548 mutex_init(&mvr->vr_mutex);
549 vr_size = PAGE_ALIGN(vring_size(num, MIC_VIRTIO_RING_ALIGN) +
550 sizeof(struct _mic_vring_info));
551 vr->va = (void *)
552 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
553 get_order(vr_size));
554 if (!vr->va) {
555 ret = -ENOMEM;
556 dev_err(mic_dev(mvdev), "%s %d err %d\n",
557 __func__, __LINE__, ret);
558 goto err;
559 }
560 vr->len = vr_size;
561 vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
562 vr->info->magic = MIC_MAGIC + mvdev->virtio_id + i;
563 vqconfig[i].address = mic_map_single(mdev,
564 vr->va, vr_size);
565 if (mic_map_error(vqconfig[i].address)) {
566 free_pages((unsigned long)vr->va, get_order(vr_size));
567 ret = -ENOMEM;
568 dev_err(mic_dev(mvdev), "%s %d err %d\n",
569 __func__, __LINE__, ret);
570 goto err;
571 }
572 vqconfig[i].address = cpu_to_le64(vqconfig[i].address);
573
574 vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
575 ret = vringh_init_kern(&mvr->vrh,
576 *(u32 *)mic_vq_features(mvdev->dd), num, false,
577 vr->vr.desc, vr->vr.avail, vr->vr.used);
578 if (ret) {
579 dev_err(mic_dev(mvdev), "%s %d err %d\n",
580 __func__, __LINE__, ret);
581 goto err;
582 }
583 vringh_kiov_init(&mvr->riov, NULL, 0);
584 vringh_kiov_init(&mvr->wiov, NULL, 0);
585 mvr->head = USHRT_MAX;
586 mvr->mvdev = mvdev;
587 mvr->vrh.notify = mic_notify;
588 dev_dbg(mdev->sdev->parent,
589 "%s %d index %d va %p info %p vr_size 0x%x\n",
590 __func__, __LINE__, i, vr->va, vr->info, vr_size);
591 }
592
593 snprintf(irqname, sizeof(irqname), "mic%dvirtio%d", mdev->id,
594 mvdev->virtio_id);
595 mvdev->virtio_db = mic_next_db(mdev);
596 mvdev->virtio_cookie = mic_request_irq(mdev, mic_virtio_intr_handler,
597 irqname, mvdev, mvdev->virtio_db, MIC_INTR_DB);
598 if (IS_ERR(mvdev->virtio_cookie)) {
599 ret = PTR_ERR(mvdev->virtio_cookie);
600 dev_dbg(mdev->sdev->parent, "request irq failed\n");
601 goto err;
602 }
603
604 mvdev->dc->c2h_vdev_db = mvdev->virtio_db;
605
606 list_add_tail(&mvdev->list, &mdev->vdev_list);
607 /*
608 * Order the type update with previous stores. This write barrier
609 * is paired with the corresponding read barrier before the uncached
610 * system memory read of the type, on the card while scanning the
611 * device page.
612 */
613 smp_wmb();
614 dd->type = type;
615
616 dev_dbg(mdev->sdev->parent, "Added virtio device id %d\n", dd->type);
617
618 db = bootparam->h2c_config_db;
619 if (db != -1)
620 mdev->ops->send_intr(mdev, db);
621 mutex_unlock(&mdev->mic_mutex);
622 return 0;
623err:
624 vqconfig = mic_vq_config(dd);
625 for (j = 0; j < i; j++) {
626 struct mic_vringh *mvr = &mvdev->mvr[j];
627 mic_unmap_single(mdev, le64_to_cpu(vqconfig[j].address),
628 mvr->vring.len);
629 free_pages((unsigned long)mvr->vring.va,
630 get_order(mvr->vring.len));
631 }
632 mutex_unlock(&mdev->mic_mutex);
633 return ret;
634}
635
636void mic_virtio_del_device(struct mic_vdev *mvdev)
637{
638 struct list_head *pos, *tmp;
639 struct mic_vdev *tmp_mvdev;
640 struct mic_device *mdev = mvdev->mdev;
641 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
642 int i, ret, retry = 100;
643 struct mic_vqconfig *vqconfig;
644 struct mic_bootparam *bootparam = mdev->dp;
645 s8 db;
646
647 mutex_lock(&mdev->mic_mutex);
648 db = bootparam->h2c_config_db;
649 if (db == -1)
650 goto skip_hot_remove;
651 dev_dbg(mdev->sdev->parent,
652 "Requesting hot remove id %d\n", mvdev->virtio_id);
653 mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
654 mdev->ops->send_intr(mdev, db);
655 for (i = retry; i--;) {
656 ret = wait_event_timeout(wake,
657 mvdev->dc->guest_ack, msecs_to_jiffies(100));
658 if (ret)
659 break;
660 }
661 dev_dbg(mdev->sdev->parent,
662 "Device id %d config_change %d guest_ack %d\n",
663 mvdev->virtio_id, mvdev->dc->config_change,
664 mvdev->dc->guest_ack);
665 mvdev->dc->config_change = 0;
666 mvdev->dc->guest_ack = 0;
667skip_hot_remove:
668 mic_free_irq(mdev, mvdev->virtio_cookie, mvdev);
669 flush_work(&mvdev->virtio_bh_work);
670 vqconfig = mic_vq_config(mvdev->dd);
671 for (i = 0; i < mvdev->dd->num_vq; i++) {
672 struct mic_vringh *mvr = &mvdev->mvr[i];
673 vringh_kiov_cleanup(&mvr->riov);
674 vringh_kiov_cleanup(&mvr->wiov);
675 mic_unmap_single(mdev, le64_to_cpu(vqconfig[i].address),
676 mvr->vring.len);
677 free_pages((unsigned long)mvr->vring.va,
678 get_order(mvr->vring.len));
679 }
680
681 list_for_each_safe(pos, tmp, &mdev->vdev_list) {
682 tmp_mvdev = list_entry(pos, struct mic_vdev, list);
683 if (tmp_mvdev == mvdev) {
684 list_del(pos);
685 dev_dbg(mdev->sdev->parent,
686 "Removing virtio device id %d\n",
687 mvdev->virtio_id);
688 break;
689 }
690 }
691 /*
692 * Order the type update with previous stores. This write barrier
693 * is paired with the corresponding read barrier before the uncached
694 * system memory read of the type, on the card while scanning the
695 * device page.
696 */
697 smp_wmb();
698 mvdev->dd->type = -1;
699 mutex_unlock(&mdev->mic_mutex);
700}
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..81e9541b784c
--- /dev/null
+++ b/drivers/misc/mic/host/mic_x100.c
@@ -0,0 +1,570 @@
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_dev.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, MIC_X100_SBOX_BASE_ADDRESS +
134 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, " %s", mdev->cmdline);
369 memcpy_toio(cmd_line_va, buf, strlen(buf) + 1);
370 kfree(buf);
371 return 0;
372}
373
374/**
375 * mic_x100_load_ramdisk - Load ramdisk to MIC.
376 * @mdev: pointer to mic_device instance
377 *
378 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
379 */
380static int
381mic_x100_load_ramdisk(struct mic_device *mdev)
382{
383 const struct firmware *fw;
384 int rc;
385 struct boot_params __iomem *bp = mdev->aper.va + mdev->bootaddr;
386
387 rc = request_firmware(&fw,
388 mdev->ramdisk, mdev->sdev->parent);
389 if (rc < 0) {
390 dev_err(mdev->sdev->parent,
391 "ramdisk request_firmware failed: %d %s\n",
392 rc, mdev->ramdisk);
393 goto error;
394 }
395 /*
396 * Typically the bootaddr for card OS is 64M
397 * so copy over the ramdisk @ 128M.
398 */
399 memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size);
400 iowrite32(cpu_to_le32(mdev->bootaddr << 1), &bp->hdr.ramdisk_image);
401 iowrite32(cpu_to_le32(fw->size), &bp->hdr.ramdisk_size);
402 release_firmware(fw);
403error:
404 return rc;
405}
406
407/**
408 * mic_x100_get_boot_addr - Get MIC boot address.
409 * @mdev: pointer to mic_device instance
410 *
411 * This function is called during firmware load to determine
412 * the address at which the OS should be downloaded in card
413 * memory i.e. GDDR.
414 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
415 */
416static int
417mic_x100_get_boot_addr(struct mic_device *mdev)
418{
419 u32 scratch2, boot_addr;
420 int rc = 0;
421
422 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO);
423 boot_addr = MIC_X100_SPAD2_DOWNLOAD_ADDR(scratch2);
424 dev_dbg(mdev->sdev->parent, "%s %d boot_addr 0x%x\n",
425 __func__, __LINE__, boot_addr);
426 if (boot_addr > (1 << 31)) {
427 dev_err(mdev->sdev->parent,
428 "incorrect bootaddr 0x%x\n",
429 boot_addr);
430 rc = -EINVAL;
431 goto error;
432 }
433 mdev->bootaddr = boot_addr;
434error:
435 return rc;
436}
437
438/**
439 * mic_x100_load_firmware - Load firmware to MIC.
440 * @mdev: pointer to mic_device instance
441 * @buf: buffer containing boot string including firmware/ramdisk path.
442 *
443 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
444 */
445static int
446mic_x100_load_firmware(struct mic_device *mdev, const char *buf)
447{
448 int rc;
449 const struct firmware *fw;
450
451 rc = mic_x100_get_boot_addr(mdev);
452 if (rc)
453 goto error;
454 /* load OS */
455 rc = request_firmware(&fw, mdev->firmware, mdev->sdev->parent);
456 if (rc < 0) {
457 dev_err(mdev->sdev->parent,
458 "ramdisk request_firmware failed: %d %s\n",
459 rc, mdev->firmware);
460 goto error;
461 }
462 if (mdev->bootaddr > mdev->aper.len - fw->size) {
463 rc = -EINVAL;
464 dev_err(mdev->sdev->parent, "%s %d rc %d bootaddr 0x%x\n",
465 __func__, __LINE__, rc, mdev->bootaddr);
466 release_firmware(fw);
467 goto error;
468 }
469 memcpy_toio(mdev->aper.va + mdev->bootaddr, fw->data, fw->size);
470 mdev->ops->write_spad(mdev, MIC_X100_FW_SIZE, fw->size);
471 if (!strcmp(mdev->bootmode, "elf"))
472 goto done;
473 /* load command line */
474 rc = mic_x100_load_command_line(mdev, fw);
475 if (rc) {
476 dev_err(mdev->sdev->parent, "%s %d rc %d\n",
477 __func__, __LINE__, rc);
478 goto error;
479 }
480 release_firmware(fw);
481 /* load ramdisk */
482 if (mdev->ramdisk)
483 rc = mic_x100_load_ramdisk(mdev);
484error:
485 dev_dbg(mdev->sdev->parent, "%s %d rc %d\n", __func__, __LINE__, rc);
486done:
487 return rc;
488}
489
490/**
491 * mic_x100_get_postcode - Get postcode status from firmware.
492 * @mdev: pointer to mic_device instance
493 *
494 * RETURNS: postcode.
495 */
496static u32 mic_x100_get_postcode(struct mic_device *mdev)
497{
498 return mic_mmio_read(&mdev->mmio, MIC_X100_POSTCODE);
499}
500
501/**
502 * mic_x100_smpt_set - Update an SMPT entry with a DMA address.
503 * @mdev: pointer to mic_device instance
504 *
505 * RETURNS: none.
506 */
507static void
508mic_x100_smpt_set(struct mic_device *mdev, dma_addr_t dma_addr, u8 index)
509{
510#define SNOOP_ON (0 << 0)
511#define SNOOP_OFF (1 << 0)
512/*
513 * Sbox Smpt Reg Bits:
514 * Bits 31:2 Host address
515 * Bits 1 RSVD
516 * Bits 0 No snoop
517 */
518#define BUILD_SMPT(NO_SNOOP, HOST_ADDR) \
519 (u32)(((HOST_ADDR) << 2) | ((NO_SNOOP) & 0x01))
520
521 uint32_t smpt_reg_val = BUILD_SMPT(SNOOP_ON,
522 dma_addr >> mdev->smpt->info.page_shift);
523 mic_mmio_write(&mdev->mmio, smpt_reg_val,
524 MIC_X100_SBOX_BASE_ADDRESS +
525 MIC_X100_SBOX_SMPT00 + (4 * index));
526}
527
528/**
529 * mic_x100_smpt_hw_init - Initialize SMPT X100 specific fields.
530 * @mdev: pointer to mic_device instance
531 *
532 * RETURNS: none.
533 */
534static void mic_x100_smpt_hw_init(struct mic_device *mdev)
535{
536 struct mic_smpt_hw_info *info = &mdev->smpt->info;
537
538 info->num_reg = 32;
539 info->page_shift = 34;
540 info->page_size = (1ULL << info->page_shift);
541 info->base = 0x8000000000ULL;
542}
543
544struct mic_smpt_ops mic_x100_smpt_ops = {
545 .init = mic_x100_smpt_hw_init,
546 .set = mic_x100_smpt_set,
547};
548
549struct mic_hw_ops mic_x100_ops = {
550 .aper_bar = MIC_X100_APER_BAR,
551 .mmio_bar = MIC_X100_MMIO_BAR,
552 .read_spad = mic_x100_read_spad,
553 .write_spad = mic_x100_write_spad,
554 .send_intr = mic_x100_send_intr,
555 .ack_interrupt = mic_x100_ack_interrupt,
556 .reset = mic_x100_hw_reset,
557 .reset_fw_ready = mic_x100_reset_fw_ready,
558 .is_fw_ready = mic_x100_is_fw_ready,
559 .send_firmware_intr = mic_x100_send_firmware_intr,
560 .load_mic_fw = mic_x100_load_firmware,
561 .get_postcode = mic_x100_get_postcode,
562};
563
564struct mic_hw_intr_ops mic_x100_intr_ops = {
565 .intr_init = mic_x100_hw_intr_init,
566 .enable_interrupts = mic_x100_enable_interrupts,
567 .disable_interrupts = mic_x100_disable_interrupts,
568 .program_msi_to_src_map = mic_x100_program_msi_to_src_map,
569 .read_msi_to_src_map = mic_x100_read_msi_to_src_map,
570};
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