root/arch/x86/platform/intel/iosf_mbi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iosf_mbi_form_mcr
  2. iosf_mbi_pci_read_mdr
  3. iosf_mbi_pci_write_mdr
  4. iosf_mbi_read
  5. iosf_mbi_write
  6. iosf_mbi_modify
  7. iosf_mbi_available
  8. iosf_mbi_punit_acquire
  9. iosf_mbi_punit_release
  10. iosf_mbi_get_sem
  11. iosf_mbi_reset_semaphore
  12. iosf_mbi_block_punit_i2c_access
  13. iosf_mbi_unblock_punit_i2c_access
  14. iosf_mbi_register_pmic_bus_access_notifier
  15. iosf_mbi_unregister_pmic_bus_access_notifier_unlocked
  16. iosf_mbi_unregister_pmic_bus_access_notifier
  17. iosf_mbi_assert_punit_acquired
  18. mcr_get
  19. mcr_set
  20. iosf_sideband_debug_init
  21. iosf_debugfs_init
  22. iosf_debugfs_remove
  23. iosf_debugfs_init
  24. iosf_debugfs_remove
  25. iosf_mbi_probe
  26. iosf_mbi_init
  27. iosf_mbi_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * IOSF-SB MailBox Interface Driver
   4  * Copyright (c) 2013, Intel Corporation.
   5  *
   6  * The IOSF-SB is a fabric bus available on Atom based SOC's that uses a
   7  * mailbox interface (MBI) to communicate with multiple devices. This
   8  * driver implements access to this interface for those platforms that can
   9  * enumerate the device using PCI.
  10  */
  11 
  12 #include <linux/delay.h>
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 #include <linux/spinlock.h>
  16 #include <linux/pci.h>
  17 #include <linux/debugfs.h>
  18 #include <linux/capability.h>
  19 #include <linux/pm_qos.h>
  20 #include <linux/wait.h>
  21 
  22 #include <asm/iosf_mbi.h>
  23 
  24 #define PCI_DEVICE_ID_INTEL_BAYTRAIL            0x0F00
  25 #define PCI_DEVICE_ID_INTEL_BRASWELL            0x2280
  26 #define PCI_DEVICE_ID_INTEL_QUARK_X1000         0x0958
  27 #define PCI_DEVICE_ID_INTEL_TANGIER             0x1170
  28 
  29 static struct pci_dev *mbi_pdev;
  30 static DEFINE_SPINLOCK(iosf_mbi_lock);
  31 
  32 /**************** Generic iosf_mbi access helpers ****************/
  33 
  34 static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset)
  35 {
  36         return (op << 24) | (port << 16) | (offset << 8) | MBI_ENABLE;
  37 }
  38 
  39 static int iosf_mbi_pci_read_mdr(u32 mcrx, u32 mcr, u32 *mdr)
  40 {
  41         int result;
  42 
  43         if (!mbi_pdev)
  44                 return -ENODEV;
  45 
  46         if (mcrx) {
  47                 result = pci_write_config_dword(mbi_pdev, MBI_MCRX_OFFSET,
  48                                                 mcrx);
  49                 if (result < 0)
  50                         goto fail_read;
  51         }
  52 
  53         result = pci_write_config_dword(mbi_pdev, MBI_MCR_OFFSET, mcr);
  54         if (result < 0)
  55                 goto fail_read;
  56 
  57         result = pci_read_config_dword(mbi_pdev, MBI_MDR_OFFSET, mdr);
  58         if (result < 0)
  59                 goto fail_read;
  60 
  61         return 0;
  62 
  63 fail_read:
  64         dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
  65         return result;
  66 }
  67 
  68 static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
  69 {
  70         int result;
  71 
  72         if (!mbi_pdev)
  73                 return -ENODEV;
  74 
  75         result = pci_write_config_dword(mbi_pdev, MBI_MDR_OFFSET, mdr);
  76         if (result < 0)
  77                 goto fail_write;
  78 
  79         if (mcrx) {
  80                 result = pci_write_config_dword(mbi_pdev, MBI_MCRX_OFFSET,
  81                                                 mcrx);
  82                 if (result < 0)
  83                         goto fail_write;
  84         }
  85 
  86         result = pci_write_config_dword(mbi_pdev, MBI_MCR_OFFSET, mcr);
  87         if (result < 0)
  88                 goto fail_write;
  89 
  90         return 0;
  91 
  92 fail_write:
  93         dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
  94         return result;
  95 }
  96 
  97 int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
  98 {
  99         u32 mcr, mcrx;
 100         unsigned long flags;
 101         int ret;
 102 
 103         /* Access to the GFX unit is handled by GPU code */
 104         if (port == BT_MBI_UNIT_GFX) {
 105                 WARN_ON(1);
 106                 return -EPERM;
 107         }
 108 
 109         mcr = iosf_mbi_form_mcr(opcode, port, offset & MBI_MASK_LO);
 110         mcrx = offset & MBI_MASK_HI;
 111 
 112         spin_lock_irqsave(&iosf_mbi_lock, flags);
 113         ret = iosf_mbi_pci_read_mdr(mcrx, mcr, mdr);
 114         spin_unlock_irqrestore(&iosf_mbi_lock, flags);
 115 
 116         return ret;
 117 }
 118 EXPORT_SYMBOL(iosf_mbi_read);
 119 
 120 int iosf_mbi_write(u8 port, u8 opcode, u32 offset, u32 mdr)
 121 {
 122         u32 mcr, mcrx;
 123         unsigned long flags;
 124         int ret;
 125 
 126         /* Access to the GFX unit is handled by GPU code */
 127         if (port == BT_MBI_UNIT_GFX) {
 128                 WARN_ON(1);
 129                 return -EPERM;
 130         }
 131 
 132         mcr = iosf_mbi_form_mcr(opcode, port, offset & MBI_MASK_LO);
 133         mcrx = offset & MBI_MASK_HI;
 134 
 135         spin_lock_irqsave(&iosf_mbi_lock, flags);
 136         ret = iosf_mbi_pci_write_mdr(mcrx, mcr, mdr);
 137         spin_unlock_irqrestore(&iosf_mbi_lock, flags);
 138 
 139         return ret;
 140 }
 141 EXPORT_SYMBOL(iosf_mbi_write);
 142 
 143 int iosf_mbi_modify(u8 port, u8 opcode, u32 offset, u32 mdr, u32 mask)
 144 {
 145         u32 mcr, mcrx;
 146         u32 value;
 147         unsigned long flags;
 148         int ret;
 149 
 150         /* Access to the GFX unit is handled by GPU code */
 151         if (port == BT_MBI_UNIT_GFX) {
 152                 WARN_ON(1);
 153                 return -EPERM;
 154         }
 155 
 156         mcr = iosf_mbi_form_mcr(opcode, port, offset & MBI_MASK_LO);
 157         mcrx = offset & MBI_MASK_HI;
 158 
 159         spin_lock_irqsave(&iosf_mbi_lock, flags);
 160 
 161         /* Read current mdr value */
 162         ret = iosf_mbi_pci_read_mdr(mcrx, mcr & MBI_RD_MASK, &value);
 163         if (ret < 0) {
 164                 spin_unlock_irqrestore(&iosf_mbi_lock, flags);
 165                 return ret;
 166         }
 167 
 168         /* Apply mask */
 169         value &= ~mask;
 170         mdr &= mask;
 171         value |= mdr;
 172 
 173         /* Write back */
 174         ret = iosf_mbi_pci_write_mdr(mcrx, mcr | MBI_WR_MASK, value);
 175 
 176         spin_unlock_irqrestore(&iosf_mbi_lock, flags);
 177 
 178         return ret;
 179 }
 180 EXPORT_SYMBOL(iosf_mbi_modify);
 181 
 182 bool iosf_mbi_available(void)
 183 {
 184         /* Mbi isn't hot-pluggable. No remove routine is provided */
 185         return mbi_pdev;
 186 }
 187 EXPORT_SYMBOL(iosf_mbi_available);
 188 
 189 /*
 190  **************** P-Unit/kernel shared I2C bus arbritration ****************
 191  *
 192  * Some Bay Trail and Cherry Trail devices have the P-Unit and us (the kernel)
 193  * share a single I2C bus to the PMIC. Below are helpers to arbitrate the
 194  * accesses between the kernel and the P-Unit.
 195  *
 196  * See arch/x86/include/asm/iosf_mbi.h for kernel-doc text for each function.
 197  */
 198 
 199 #define SEMAPHORE_TIMEOUT               500
 200 #define PUNIT_SEMAPHORE_BYT             0x7
 201 #define PUNIT_SEMAPHORE_CHT             0x10e
 202 #define PUNIT_SEMAPHORE_BIT             BIT(0)
 203 #define PUNIT_SEMAPHORE_ACQUIRE         BIT(1)
 204 
 205 static DEFINE_MUTEX(iosf_mbi_pmic_access_mutex);
 206 static BLOCKING_NOTIFIER_HEAD(iosf_mbi_pmic_bus_access_notifier);
 207 static DECLARE_WAIT_QUEUE_HEAD(iosf_mbi_pmic_access_waitq);
 208 static u32 iosf_mbi_pmic_punit_access_count;
 209 static u32 iosf_mbi_pmic_i2c_access_count;
 210 static u32 iosf_mbi_sem_address;
 211 static unsigned long iosf_mbi_sem_acquired;
 212 static struct pm_qos_request iosf_mbi_pm_qos;
 213 
 214 void iosf_mbi_punit_acquire(void)
 215 {
 216         /* Wait for any I2C PMIC accesses from in kernel drivers to finish. */
 217         mutex_lock(&iosf_mbi_pmic_access_mutex);
 218         while (iosf_mbi_pmic_i2c_access_count != 0) {
 219                 mutex_unlock(&iosf_mbi_pmic_access_mutex);
 220                 wait_event(iosf_mbi_pmic_access_waitq,
 221                            iosf_mbi_pmic_i2c_access_count == 0);
 222                 mutex_lock(&iosf_mbi_pmic_access_mutex);
 223         }
 224         /*
 225          * We do not need to do anything to allow the PUNIT to safely access
 226          * the PMIC, other then block in kernel accesses to the PMIC.
 227          */
 228         iosf_mbi_pmic_punit_access_count++;
 229         mutex_unlock(&iosf_mbi_pmic_access_mutex);
 230 }
 231 EXPORT_SYMBOL(iosf_mbi_punit_acquire);
 232 
 233 void iosf_mbi_punit_release(void)
 234 {
 235         bool do_wakeup;
 236 
 237         mutex_lock(&iosf_mbi_pmic_access_mutex);
 238         iosf_mbi_pmic_punit_access_count--;
 239         do_wakeup = iosf_mbi_pmic_punit_access_count == 0;
 240         mutex_unlock(&iosf_mbi_pmic_access_mutex);
 241 
 242         if (do_wakeup)
 243                 wake_up(&iosf_mbi_pmic_access_waitq);
 244 }
 245 EXPORT_SYMBOL(iosf_mbi_punit_release);
 246 
 247 static int iosf_mbi_get_sem(u32 *sem)
 248 {
 249         int ret;
 250 
 251         ret = iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ,
 252                             iosf_mbi_sem_address, sem);
 253         if (ret) {
 254                 dev_err(&mbi_pdev->dev, "Error P-Unit semaphore read failed\n");
 255                 return ret;
 256         }
 257 
 258         *sem &= PUNIT_SEMAPHORE_BIT;
 259         return 0;
 260 }
 261 
 262 static void iosf_mbi_reset_semaphore(void)
 263 {
 264         if (iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ,
 265                             iosf_mbi_sem_address, 0, PUNIT_SEMAPHORE_BIT))
 266                 dev_err(&mbi_pdev->dev, "Error P-Unit semaphore reset failed\n");
 267 
 268         pm_qos_update_request(&iosf_mbi_pm_qos, PM_QOS_DEFAULT_VALUE);
 269 
 270         blocking_notifier_call_chain(&iosf_mbi_pmic_bus_access_notifier,
 271                                      MBI_PMIC_BUS_ACCESS_END, NULL);
 272 }
 273 
 274 /*
 275  * This function blocks P-Unit accesses to the PMIC I2C bus, so that kernel
 276  * I2C code, such as e.g. a fuel-gauge driver, can access it safely.
 277  *
 278  * This function may be called by I2C controller code while an I2C driver has
 279  * already blocked P-Unit accesses because it wants them blocked over multiple
 280  * i2c-transfers, for e.g. read-modify-write of an I2C client register.
 281  *
 282  * To allow safe PMIC i2c bus accesses this function takes the following steps:
 283  *
 284  * 1) Some code sends request to the P-Unit which make it access the PMIC
 285  *    I2C bus. Testing has shown that the P-Unit does not check its internal
 286  *    PMIC bus semaphore for these requests. Callers of these requests call
 287  *    iosf_mbi_punit_acquire()/_release() around their P-Unit accesses, these
 288  *    functions increase/decrease iosf_mbi_pmic_punit_access_count, so first
 289  *    we wait for iosf_mbi_pmic_punit_access_count to become 0.
 290  *
 291  * 2) Check iosf_mbi_pmic_i2c_access_count, if access has already
 292  *    been blocked by another caller, we only need to increment
 293  *    iosf_mbi_pmic_i2c_access_count and we can skip the other steps.
 294  *
 295  * 3) Some code makes such P-Unit requests from atomic contexts where it
 296  *    cannot call iosf_mbi_punit_acquire() as that may sleep.
 297  *    As the second step we call a notifier chain which allows any code
 298  *    needing P-Unit resources from atomic context to acquire them before
 299  *    we take control over the PMIC I2C bus.
 300  *
 301  * 4) When CPU cores enter C6 or C7 the P-Unit needs to talk to the PMIC
 302  *    if this happens while the kernel itself is accessing the PMIC I2C bus
 303  *    the SoC hangs.
 304  *    As the third step we call pm_qos_update_request() to disallow the CPU
 305  *    to enter C6 or C7.
 306  *
 307  * 5) The P-Unit has a PMIC bus semaphore which we can request to stop
 308  *    autonomous P-Unit tasks from accessing the PMIC I2C bus while we hold it.
 309  *    As the fourth and final step we request this semaphore and wait for our
 310  *    request to be acknowledged.
 311  */
 312 int iosf_mbi_block_punit_i2c_access(void)
 313 {
 314         unsigned long start, end;
 315         int ret = 0;
 316         u32 sem;
 317 
 318         if (WARN_ON(!mbi_pdev || !iosf_mbi_sem_address))
 319                 return -ENXIO;
 320 
 321         mutex_lock(&iosf_mbi_pmic_access_mutex);
 322 
 323         while (iosf_mbi_pmic_punit_access_count != 0) {
 324                 mutex_unlock(&iosf_mbi_pmic_access_mutex);
 325                 wait_event(iosf_mbi_pmic_access_waitq,
 326                            iosf_mbi_pmic_punit_access_count == 0);
 327                 mutex_lock(&iosf_mbi_pmic_access_mutex);
 328         }
 329 
 330         if (iosf_mbi_pmic_i2c_access_count > 0)
 331                 goto success;
 332 
 333         blocking_notifier_call_chain(&iosf_mbi_pmic_bus_access_notifier,
 334                                      MBI_PMIC_BUS_ACCESS_BEGIN, NULL);
 335 
 336         /*
 337          * Disallow the CPU to enter C6 or C7 state, entering these states
 338          * requires the P-Unit to talk to the PMIC and if this happens while
 339          * we're holding the semaphore, the SoC hangs.
 340          */
 341         pm_qos_update_request(&iosf_mbi_pm_qos, 0);
 342 
 343         /* host driver writes to side band semaphore register */
 344         ret = iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_REG_WRITE,
 345                              iosf_mbi_sem_address, PUNIT_SEMAPHORE_ACQUIRE);
 346         if (ret) {
 347                 dev_err(&mbi_pdev->dev, "Error P-Unit semaphore request failed\n");
 348                 goto error;
 349         }
 350 
 351         /* host driver waits for bit 0 to be set in semaphore register */
 352         start = jiffies;
 353         end = start + msecs_to_jiffies(SEMAPHORE_TIMEOUT);
 354         do {
 355                 ret = iosf_mbi_get_sem(&sem);
 356                 if (!ret && sem) {
 357                         iosf_mbi_sem_acquired = jiffies;
 358                         dev_dbg(&mbi_pdev->dev, "P-Unit semaphore acquired after %ums\n",
 359                                 jiffies_to_msecs(jiffies - start));
 360                         goto success;
 361                 }
 362 
 363                 usleep_range(1000, 2000);
 364         } while (time_before(jiffies, end));
 365 
 366         ret = -ETIMEDOUT;
 367         dev_err(&mbi_pdev->dev, "Error P-Unit semaphore timed out, resetting\n");
 368 error:
 369         iosf_mbi_reset_semaphore();
 370         if (!iosf_mbi_get_sem(&sem))
 371                 dev_err(&mbi_pdev->dev, "P-Unit semaphore: %d\n", sem);
 372 success:
 373         if (!WARN_ON(ret))
 374                 iosf_mbi_pmic_i2c_access_count++;
 375 
 376         mutex_unlock(&iosf_mbi_pmic_access_mutex);
 377 
 378         return ret;
 379 }
 380 EXPORT_SYMBOL(iosf_mbi_block_punit_i2c_access);
 381 
 382 void iosf_mbi_unblock_punit_i2c_access(void)
 383 {
 384         bool do_wakeup = false;
 385 
 386         mutex_lock(&iosf_mbi_pmic_access_mutex);
 387         iosf_mbi_pmic_i2c_access_count--;
 388         if (iosf_mbi_pmic_i2c_access_count == 0) {
 389                 iosf_mbi_reset_semaphore();
 390                 dev_dbg(&mbi_pdev->dev, "punit semaphore held for %ums\n",
 391                         jiffies_to_msecs(jiffies - iosf_mbi_sem_acquired));
 392                 do_wakeup = true;
 393         }
 394         mutex_unlock(&iosf_mbi_pmic_access_mutex);
 395 
 396         if (do_wakeup)
 397                 wake_up(&iosf_mbi_pmic_access_waitq);
 398 }
 399 EXPORT_SYMBOL(iosf_mbi_unblock_punit_i2c_access);
 400 
 401 int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb)
 402 {
 403         int ret;
 404 
 405         /* Wait for the bus to go inactive before registering */
 406         iosf_mbi_punit_acquire();
 407         ret = blocking_notifier_chain_register(
 408                                 &iosf_mbi_pmic_bus_access_notifier, nb);
 409         iosf_mbi_punit_release();
 410 
 411         return ret;
 412 }
 413 EXPORT_SYMBOL(iosf_mbi_register_pmic_bus_access_notifier);
 414 
 415 int iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(
 416         struct notifier_block *nb)
 417 {
 418         iosf_mbi_assert_punit_acquired();
 419 
 420         return blocking_notifier_chain_unregister(
 421                                 &iosf_mbi_pmic_bus_access_notifier, nb);
 422 }
 423 EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier_unlocked);
 424 
 425 int iosf_mbi_unregister_pmic_bus_access_notifier(struct notifier_block *nb)
 426 {
 427         int ret;
 428 
 429         /* Wait for the bus to go inactive before unregistering */
 430         iosf_mbi_punit_acquire();
 431         ret = iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(nb);
 432         iosf_mbi_punit_release();
 433 
 434         return ret;
 435 }
 436 EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier);
 437 
 438 void iosf_mbi_assert_punit_acquired(void)
 439 {
 440         WARN_ON(iosf_mbi_pmic_punit_access_count == 0);
 441 }
 442 EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired);
 443 
 444 /**************** iosf_mbi debug code ****************/
 445 
 446 #ifdef CONFIG_IOSF_MBI_DEBUG
 447 static u32      dbg_mdr;
 448 static u32      dbg_mcr;
 449 static u32      dbg_mcrx;
 450 
 451 static int mcr_get(void *data, u64 *val)
 452 {
 453         *val = *(u32 *)data;
 454         return 0;
 455 }
 456 
 457 static int mcr_set(void *data, u64 val)
 458 {
 459         u8 command = ((u32)val & 0xFF000000) >> 24,
 460            port    = ((u32)val & 0x00FF0000) >> 16,
 461            offset  = ((u32)val & 0x0000FF00) >> 8;
 462         int err;
 463 
 464         *(u32 *)data = val;
 465 
 466         if (!capable(CAP_SYS_RAWIO))
 467                 return -EACCES;
 468 
 469         if (command & 1u)
 470                 err = iosf_mbi_write(port,
 471                                command,
 472                                dbg_mcrx | offset,
 473                                dbg_mdr);
 474         else
 475                 err = iosf_mbi_read(port,
 476                               command,
 477                               dbg_mcrx | offset,
 478                               &dbg_mdr);
 479 
 480         return err;
 481 }
 482 DEFINE_SIMPLE_ATTRIBUTE(iosf_mcr_fops, mcr_get, mcr_set , "%llx\n");
 483 
 484 static struct dentry *iosf_dbg;
 485 
 486 static void iosf_sideband_debug_init(void)
 487 {
 488         iosf_dbg = debugfs_create_dir("iosf_sb", NULL);
 489 
 490         /* mdr */
 491         debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr);
 492 
 493         /* mcrx */
 494         debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx);
 495 
 496         /* mcr - initiates mailbox tranaction */
 497         debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops);
 498 }
 499 
 500 static void iosf_debugfs_init(void)
 501 {
 502         iosf_sideband_debug_init();
 503 }
 504 
 505 static void iosf_debugfs_remove(void)
 506 {
 507         debugfs_remove_recursive(iosf_dbg);
 508 }
 509 #else
 510 static inline void iosf_debugfs_init(void) { }
 511 static inline void iosf_debugfs_remove(void) { }
 512 #endif /* CONFIG_IOSF_MBI_DEBUG */
 513 
 514 static int iosf_mbi_probe(struct pci_dev *pdev,
 515                           const struct pci_device_id *dev_id)
 516 {
 517         int ret;
 518 
 519         ret = pci_enable_device(pdev);
 520         if (ret < 0) {
 521                 dev_err(&pdev->dev, "error: could not enable device\n");
 522                 return ret;
 523         }
 524 
 525         mbi_pdev = pci_dev_get(pdev);
 526         iosf_mbi_sem_address = dev_id->driver_data;
 527 
 528         return 0;
 529 }
 530 
 531 static const struct pci_device_id iosf_mbi_pci_ids[] = {
 532         { PCI_DEVICE_DATA(INTEL, BAYTRAIL, PUNIT_SEMAPHORE_BYT) },
 533         { PCI_DEVICE_DATA(INTEL, BRASWELL, PUNIT_SEMAPHORE_CHT) },
 534         { PCI_DEVICE_DATA(INTEL, QUARK_X1000, 0) },
 535         { PCI_DEVICE_DATA(INTEL, TANGIER, 0) },
 536         { 0, },
 537 };
 538 MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids);
 539 
 540 static struct pci_driver iosf_mbi_pci_driver = {
 541         .name           = "iosf_mbi_pci",
 542         .probe          = iosf_mbi_probe,
 543         .id_table       = iosf_mbi_pci_ids,
 544 };
 545 
 546 static int __init iosf_mbi_init(void)
 547 {
 548         iosf_debugfs_init();
 549 
 550         pm_qos_add_request(&iosf_mbi_pm_qos, PM_QOS_CPU_DMA_LATENCY,
 551                            PM_QOS_DEFAULT_VALUE);
 552 
 553         return pci_register_driver(&iosf_mbi_pci_driver);
 554 }
 555 
 556 static void __exit iosf_mbi_exit(void)
 557 {
 558         iosf_debugfs_remove();
 559 
 560         pci_unregister_driver(&iosf_mbi_pci_driver);
 561         pci_dev_put(mbi_pdev);
 562         mbi_pdev = NULL;
 563 
 564         pm_qos_remove_request(&iosf_mbi_pm_qos);
 565 }
 566 
 567 module_init(iosf_mbi_init);
 568 module_exit(iosf_mbi_exit);
 569 
 570 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
 571 MODULE_DESCRIPTION("IOSF Mailbox Interface accessor");
 572 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */