Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.3-rc6 543 lines 14 kB view raw
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#include <linux/suspend.h> 30 31#include <linux/mic_common.h> 32#include "../common/mic_dev.h" 33#include "mic_device.h" 34#include "mic_x100.h" 35#include "mic_smpt.h" 36#include "mic_fops.h" 37#include "mic_virtio.h" 38 39static const char mic_driver_name[] = "mic"; 40 41static const struct pci_device_id mic_pci_tbl[] = { 42 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)}, 43 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)}, 44 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)}, 45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)}, 46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)}, 47 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)}, 48 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)}, 49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)}, 50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)}, 51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)}, 52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)}, 53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)}, 54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)}, 55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)}, 56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)}, 57 58 /* required last entry */ 59 { 0, } 60}; 61 62MODULE_DEVICE_TABLE(pci, mic_pci_tbl); 63 64/* ID allocator for MIC devices */ 65static struct ida g_mic_ida; 66/* Class of MIC devices for sysfs accessibility. */ 67static struct class *g_mic_class; 68/* Base device node number for MIC devices */ 69static dev_t g_mic_devno; 70/* Track the total number of MIC devices */ 71atomic_t g_num_mics; 72 73static const struct file_operations mic_fops = { 74 .open = mic_open, 75 .release = mic_release, 76 .unlocked_ioctl = mic_ioctl, 77 .poll = mic_poll, 78 .mmap = mic_mmap, 79 .owner = THIS_MODULE, 80}; 81 82/* Initialize the device page */ 83static int mic_dp_init(struct mic_device *mdev) 84{ 85 mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL); 86 if (!mdev->dp) { 87 dev_err(mdev->sdev->parent, "%s %d err %d\n", 88 __func__, __LINE__, -ENOMEM); 89 return -ENOMEM; 90 } 91 92 mdev->dp_dma_addr = mic_map_single(mdev, 93 mdev->dp, MIC_DP_SIZE); 94 if (mic_map_error(mdev->dp_dma_addr)) { 95 kfree(mdev->dp); 96 dev_err(mdev->sdev->parent, "%s %d err %d\n", 97 __func__, __LINE__, -ENOMEM); 98 return -ENOMEM; 99 } 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 return 0; 103} 104 105/* Uninitialize the device page */ 106static void mic_dp_uninit(struct mic_device *mdev) 107{ 108 mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE); 109 kfree(mdev->dp); 110} 111 112/** 113 * mic_shutdown_db - Shutdown doorbell interrupt handler. 114 */ 115static irqreturn_t mic_shutdown_db(int irq, void *data) 116{ 117 struct mic_device *mdev = data; 118 struct mic_bootparam *bootparam = mdev->dp; 119 120 mdev->ops->intr_workarounds(mdev); 121 122 switch (bootparam->shutdown_status) { 123 case MIC_HALTED: 124 case MIC_POWER_OFF: 125 case MIC_RESTART: 126 /* Fall through */ 127 case MIC_CRASHED: 128 schedule_work(&mdev->shutdown_work); 129 break; 130 default: 131 break; 132 }; 133 return IRQ_HANDLED; 134} 135 136/** 137 * mic_ops_init: Initialize HW specific operation tables. 138 * 139 * @mdev: pointer to mic_device instance 140 * 141 * returns none. 142 */ 143static void mic_ops_init(struct mic_device *mdev) 144{ 145 switch (mdev->family) { 146 case MIC_FAMILY_X100: 147 mdev->ops = &mic_x100_ops; 148 mdev->intr_ops = &mic_x100_intr_ops; 149 mdev->smpt_ops = &mic_x100_smpt_ops; 150 break; 151 default: 152 break; 153 } 154} 155 156/** 157 * mic_get_family - Determine hardware family to which this MIC belongs. 158 * 159 * @pdev: The pci device structure 160 * 161 * returns family. 162 */ 163static enum mic_hw_family mic_get_family(struct pci_dev *pdev) 164{ 165 enum mic_hw_family family; 166 167 switch (pdev->device) { 168 case MIC_X100_PCI_DEVICE_2250: 169 case MIC_X100_PCI_DEVICE_2251: 170 case MIC_X100_PCI_DEVICE_2252: 171 case MIC_X100_PCI_DEVICE_2253: 172 case MIC_X100_PCI_DEVICE_2254: 173 case MIC_X100_PCI_DEVICE_2255: 174 case MIC_X100_PCI_DEVICE_2256: 175 case MIC_X100_PCI_DEVICE_2257: 176 case MIC_X100_PCI_DEVICE_2258: 177 case MIC_X100_PCI_DEVICE_2259: 178 case MIC_X100_PCI_DEVICE_225a: 179 case MIC_X100_PCI_DEVICE_225b: 180 case MIC_X100_PCI_DEVICE_225c: 181 case MIC_X100_PCI_DEVICE_225d: 182 case MIC_X100_PCI_DEVICE_225e: 183 family = MIC_FAMILY_X100; 184 break; 185 default: 186 family = MIC_FAMILY_UNKNOWN; 187 break; 188 } 189 return family; 190} 191 192/** 193* mic_pm_notifier: Notifier callback function that handles 194* PM notifications. 195* 196* @notifier_block: The notifier structure. 197* @pm_event: The event for which the driver was notified. 198* @unused: Meaningless. Always NULL. 199* 200* returns NOTIFY_DONE 201*/ 202static int mic_pm_notifier(struct notifier_block *notifier, 203 unsigned long pm_event, void *unused) 204{ 205 struct mic_device *mdev = container_of(notifier, 206 struct mic_device, pm_notifier); 207 208 switch (pm_event) { 209 case PM_HIBERNATION_PREPARE: 210 /* Fall through */ 211 case PM_SUSPEND_PREPARE: 212 mic_prepare_suspend(mdev); 213 break; 214 case PM_POST_HIBERNATION: 215 /* Fall through */ 216 case PM_POST_SUSPEND: 217 /* Fall through */ 218 case PM_POST_RESTORE: 219 mic_complete_resume(mdev); 220 break; 221 case PM_RESTORE_PREPARE: 222 break; 223 default: 224 break; 225 } 226 return NOTIFY_DONE; 227} 228 229/** 230 * mic_device_init - Allocates and initializes the MIC device structure 231 * 232 * @mdev: pointer to mic_device instance 233 * @pdev: The pci device structure 234 * 235 * returns none. 236 */ 237static int 238mic_device_init(struct mic_device *mdev, struct pci_dev *pdev) 239{ 240 int rc; 241 242 mdev->family = mic_get_family(pdev); 243 mdev->stepping = pdev->revision; 244 mic_ops_init(mdev); 245 mic_sysfs_init(mdev); 246 mutex_init(&mdev->mic_mutex); 247 mdev->irq_info.next_avail_src = 0; 248 INIT_WORK(&mdev->reset_trigger_work, mic_reset_trigger_work); 249 INIT_WORK(&mdev->shutdown_work, mic_shutdown_work); 250 init_completion(&mdev->reset_wait); 251 INIT_LIST_HEAD(&mdev->vdev_list); 252 mdev->pm_notifier.notifier_call = mic_pm_notifier; 253 rc = register_pm_notifier(&mdev->pm_notifier); 254 if (rc) { 255 dev_err(&pdev->dev, "register_pm_notifier failed rc %d\n", 256 rc); 257 goto register_pm_notifier_fail; 258 } 259 return 0; 260register_pm_notifier_fail: 261 flush_work(&mdev->shutdown_work); 262 flush_work(&mdev->reset_trigger_work); 263 return rc; 264} 265 266/** 267 * mic_device_uninit - Frees resources allocated during mic_device_init(..) 268 * 269 * @mdev: pointer to mic_device instance 270 * 271 * returns none 272 */ 273static void mic_device_uninit(struct mic_device *mdev) 274{ 275 /* The cmdline sysfs entry might have allocated cmdline */ 276 kfree(mdev->cmdline); 277 kfree(mdev->firmware); 278 kfree(mdev->ramdisk); 279 kfree(mdev->bootmode); 280 flush_work(&mdev->reset_trigger_work); 281 flush_work(&mdev->shutdown_work); 282 unregister_pm_notifier(&mdev->pm_notifier); 283} 284 285/** 286 * mic_probe - Device Initialization Routine 287 * 288 * @pdev: PCI device structure 289 * @ent: entry in mic_pci_tbl 290 * 291 * returns 0 on success, < 0 on failure. 292 */ 293static int mic_probe(struct pci_dev *pdev, 294 const struct pci_device_id *ent) 295{ 296 int rc; 297 struct mic_device *mdev; 298 299 mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); 300 if (!mdev) { 301 rc = -ENOMEM; 302 dev_err(&pdev->dev, "mdev kmalloc failed rc %d\n", rc); 303 goto mdev_alloc_fail; 304 } 305 mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); 306 if (mdev->id < 0) { 307 rc = mdev->id; 308 dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc); 309 goto ida_fail; 310 } 311 312 rc = mic_device_init(mdev, pdev); 313 if (rc) { 314 dev_err(&pdev->dev, "mic_device_init failed rc %d\n", rc); 315 goto device_init_fail; 316 } 317 318 rc = pci_enable_device(pdev); 319 if (rc) { 320 dev_err(&pdev->dev, "failed to enable pci device.\n"); 321 goto uninit_device; 322 } 323 324 pci_set_master(pdev); 325 326 rc = pci_request_regions(pdev, mic_driver_name); 327 if (rc) { 328 dev_err(&pdev->dev, "failed to get pci regions.\n"); 329 goto disable_device; 330 } 331 332 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); 333 if (rc) { 334 dev_err(&pdev->dev, "Cannot set DMA mask\n"); 335 goto release_regions; 336 } 337 338 mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar); 339 mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar); 340 mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar); 341 if (!mdev->mmio.va) { 342 dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); 343 rc = -EIO; 344 goto release_regions; 345 } 346 347 mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar); 348 mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar); 349 mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len); 350 if (!mdev->aper.va) { 351 dev_err(&pdev->dev, "Cannot remap Aperture BAR\n"); 352 rc = -EIO; 353 goto unmap_mmio; 354 } 355 356 mdev->intr_ops->intr_init(mdev); 357 rc = mic_setup_interrupts(mdev, pdev); 358 if (rc) { 359 dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc); 360 goto unmap_aper; 361 } 362 rc = mic_smpt_init(mdev); 363 if (rc) { 364 dev_err(&pdev->dev, "smpt_init failed %d\n", rc); 365 goto free_interrupts; 366 } 367 368 pci_set_drvdata(pdev, mdev); 369 370 mdev->sdev = device_create_with_groups(g_mic_class, &pdev->dev, 371 MKDEV(MAJOR(g_mic_devno), mdev->id), NULL, 372 mdev->attr_group, "mic%d", mdev->id); 373 if (IS_ERR(mdev->sdev)) { 374 rc = PTR_ERR(mdev->sdev); 375 dev_err(&pdev->dev, 376 "device_create_with_groups failed rc %d\n", rc); 377 goto smpt_uninit; 378 } 379 mdev->state_sysfs = sysfs_get_dirent(mdev->sdev->kobj.sd, "state"); 380 if (!mdev->state_sysfs) { 381 rc = -ENODEV; 382 dev_err(&pdev->dev, "sysfs_get_dirent failed rc %d\n", rc); 383 goto destroy_device; 384 } 385 386 rc = mic_dp_init(mdev); 387 if (rc) { 388 dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc); 389 goto sysfs_put; 390 } 391 mutex_lock(&mdev->mic_mutex); 392 393 mdev->shutdown_db = mic_next_db(mdev); 394 mdev->shutdown_cookie = mic_request_threaded_irq(mdev, mic_shutdown_db, 395 NULL, "shutdown-interrupt", mdev, 396 mdev->shutdown_db, MIC_INTR_DB); 397 if (IS_ERR(mdev->shutdown_cookie)) { 398 rc = PTR_ERR(mdev->shutdown_cookie); 399 mutex_unlock(&mdev->mic_mutex); 400 goto dp_uninit; 401 } 402 mutex_unlock(&mdev->mic_mutex); 403 mic_bootparam_init(mdev); 404 405 mic_create_debug_dir(mdev); 406 cdev_init(&mdev->cdev, &mic_fops); 407 mdev->cdev.owner = THIS_MODULE; 408 rc = cdev_add(&mdev->cdev, MKDEV(MAJOR(g_mic_devno), mdev->id), 1); 409 if (rc) { 410 dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc); 411 goto cleanup_debug_dir; 412 } 413 atomic_inc(&g_num_mics); 414 return 0; 415cleanup_debug_dir: 416 mic_delete_debug_dir(mdev); 417 mutex_lock(&mdev->mic_mutex); 418 mic_free_irq(mdev, mdev->shutdown_cookie, mdev); 419 mutex_unlock(&mdev->mic_mutex); 420dp_uninit: 421 mic_dp_uninit(mdev); 422sysfs_put: 423 sysfs_put(mdev->state_sysfs); 424destroy_device: 425 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id)); 426smpt_uninit: 427 mic_smpt_uninit(mdev); 428free_interrupts: 429 mic_free_interrupts(mdev, pdev); 430unmap_aper: 431 iounmap(mdev->aper.va); 432unmap_mmio: 433 iounmap(mdev->mmio.va); 434release_regions: 435 pci_release_regions(pdev); 436disable_device: 437 pci_disable_device(pdev); 438uninit_device: 439 mic_device_uninit(mdev); 440device_init_fail: 441 ida_simple_remove(&g_mic_ida, mdev->id); 442ida_fail: 443 kfree(mdev); 444mdev_alloc_fail: 445 dev_err(&pdev->dev, "Probe failed rc %d\n", rc); 446 return rc; 447} 448 449/** 450 * mic_remove - Device Removal Routine 451 * mic_remove is called by the PCI subsystem to alert the driver 452 * that it should release a PCI device. 453 * 454 * @pdev: PCI device structure 455 */ 456static void mic_remove(struct pci_dev *pdev) 457{ 458 struct mic_device *mdev; 459 460 mdev = pci_get_drvdata(pdev); 461 if (!mdev) 462 return; 463 464 mic_stop(mdev, false); 465 atomic_dec(&g_num_mics); 466 cdev_del(&mdev->cdev); 467 mic_delete_debug_dir(mdev); 468 mutex_lock(&mdev->mic_mutex); 469 mic_free_irq(mdev, mdev->shutdown_cookie, mdev); 470 mutex_unlock(&mdev->mic_mutex); 471 flush_work(&mdev->shutdown_work); 472 mic_dp_uninit(mdev); 473 sysfs_put(mdev->state_sysfs); 474 device_destroy(g_mic_class, MKDEV(MAJOR(g_mic_devno), mdev->id)); 475 mic_smpt_uninit(mdev); 476 mic_free_interrupts(mdev, pdev); 477 iounmap(mdev->mmio.va); 478 iounmap(mdev->aper.va); 479 mic_device_uninit(mdev); 480 pci_release_regions(pdev); 481 pci_disable_device(pdev); 482 ida_simple_remove(&g_mic_ida, mdev->id); 483 kfree(mdev); 484} 485 486static struct pci_driver mic_driver = { 487 .name = mic_driver_name, 488 .id_table = mic_pci_tbl, 489 .probe = mic_probe, 490 .remove = mic_remove 491}; 492 493static int __init mic_init(void) 494{ 495 int ret; 496 497 ret = alloc_chrdev_region(&g_mic_devno, 0, 498 MIC_MAX_NUM_DEVS, mic_driver_name); 499 if (ret) { 500 pr_err("alloc_chrdev_region failed ret %d\n", ret); 501 goto error; 502 } 503 504 g_mic_class = class_create(THIS_MODULE, mic_driver_name); 505 if (IS_ERR(g_mic_class)) { 506 ret = PTR_ERR(g_mic_class); 507 pr_err("class_create failed ret %d\n", ret); 508 goto cleanup_chrdev; 509 } 510 511 mic_init_debugfs(); 512 ida_init(&g_mic_ida); 513 ret = pci_register_driver(&mic_driver); 514 if (ret) { 515 pr_err("pci_register_driver failed ret %d\n", ret); 516 goto cleanup_debugfs; 517 } 518 return ret; 519cleanup_debugfs: 520 ida_destroy(&g_mic_ida); 521 mic_exit_debugfs(); 522 class_destroy(g_mic_class); 523cleanup_chrdev: 524 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS); 525error: 526 return ret; 527} 528 529static void __exit mic_exit(void) 530{ 531 pci_unregister_driver(&mic_driver); 532 ida_destroy(&g_mic_ida); 533 mic_exit_debugfs(); 534 class_destroy(g_mic_class); 535 unregister_chrdev_region(g_mic_devno, MIC_MAX_NUM_DEVS); 536} 537 538module_init(mic_init); 539module_exit(mic_exit); 540 541MODULE_AUTHOR("Intel Corporation"); 542MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver"); 543MODULE_LICENSE("GPL v2");