| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * IOSF-SB MailBox Interface Driver |
|---|
| 3 | 4 | * Copyright (c) 2013, Intel Corporation. |
|---|
| 4 | 5 | * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | | - * |
|---|
| 14 | | - * |
|---|
| 15 | 6 | * The IOSF-SB is a fabric bus available on Atom based SOC's that uses a |
|---|
| 16 | | - * mailbox interface (MBI) to communicate with mutiple devices. This |
|---|
| 7 | + * mailbox interface (MBI) to communicate with multiple devices. This |
|---|
| 17 | 8 | * driver implements access to this interface for those platforms that can |
|---|
| 18 | 9 | * enumerate the device using PCI. |
|---|
| 19 | 10 | */ |
|---|
| 20 | 11 | |
|---|
| 12 | +#include <linux/delay.h> |
|---|
| 21 | 13 | #include <linux/module.h> |
|---|
| 22 | 14 | #include <linux/init.h> |
|---|
| 23 | 15 | #include <linux/spinlock.h> |
|---|
| 24 | 16 | #include <linux/pci.h> |
|---|
| 25 | 17 | #include <linux/debugfs.h> |
|---|
| 26 | 18 | #include <linux/capability.h> |
|---|
| 19 | +#include <linux/pm_qos.h> |
|---|
| 20 | +#include <linux/wait.h> |
|---|
| 27 | 21 | |
|---|
| 28 | 22 | #include <asm/iosf_mbi.h> |
|---|
| 29 | 23 | |
|---|
| 30 | | -#define PCI_DEVICE_ID_BAYTRAIL 0x0F00 |
|---|
| 31 | | -#define PCI_DEVICE_ID_BRASWELL 0x2280 |
|---|
| 32 | | -#define PCI_DEVICE_ID_QUARK_X1000 0x0958 |
|---|
| 33 | | -#define PCI_DEVICE_ID_TANGIER 0x1170 |
|---|
| 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 |
|---|
| 34 | 28 | |
|---|
| 35 | 29 | static struct pci_dev *mbi_pdev; |
|---|
| 36 | 30 | static DEFINE_SPINLOCK(iosf_mbi_lock); |
|---|
| 37 | | -static DEFINE_MUTEX(iosf_mbi_punit_mutex); |
|---|
| 38 | | -static BLOCKING_NOTIFIER_HEAD(iosf_mbi_pmic_bus_access_notifier); |
|---|
| 31 | + |
|---|
| 32 | +/**************** Generic iosf_mbi access helpers ****************/ |
|---|
| 39 | 33 | |
|---|
| 40 | 34 | static inline u32 iosf_mbi_form_mcr(u8 op, u8 port, u8 offset) |
|---|
| 41 | 35 | { |
|---|
| .. | .. |
|---|
| 192 | 186 | } |
|---|
| 193 | 187 | EXPORT_SYMBOL(iosf_mbi_available); |
|---|
| 194 | 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 | + |
|---|
| 195 | 214 | void iosf_mbi_punit_acquire(void) |
|---|
| 196 | 215 | { |
|---|
| 197 | | - mutex_lock(&iosf_mbi_punit_mutex); |
|---|
| 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); |
|---|
| 198 | 230 | } |
|---|
| 199 | 231 | EXPORT_SYMBOL(iosf_mbi_punit_acquire); |
|---|
| 200 | 232 | |
|---|
| 201 | 233 | void iosf_mbi_punit_release(void) |
|---|
| 202 | 234 | { |
|---|
| 203 | | - mutex_unlock(&iosf_mbi_punit_mutex); |
|---|
| 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); |
|---|
| 204 | 244 | } |
|---|
| 205 | 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 | + cpu_latency_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 cpu_latency_qos_update_request() to disallow the |
|---|
| 305 | + * CPU 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 | + cpu_latency_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); |
|---|
| 206 | 400 | |
|---|
| 207 | 401 | int iosf_mbi_register_pmic_bus_access_notifier(struct notifier_block *nb) |
|---|
| 208 | 402 | { |
|---|
| 209 | 403 | int ret; |
|---|
| 210 | 404 | |
|---|
| 211 | 405 | /* Wait for the bus to go inactive before registering */ |
|---|
| 212 | | - mutex_lock(&iosf_mbi_punit_mutex); |
|---|
| 406 | + iosf_mbi_punit_acquire(); |
|---|
| 213 | 407 | ret = blocking_notifier_chain_register( |
|---|
| 214 | 408 | &iosf_mbi_pmic_bus_access_notifier, nb); |
|---|
| 215 | | - mutex_unlock(&iosf_mbi_punit_mutex); |
|---|
| 409 | + iosf_mbi_punit_release(); |
|---|
| 216 | 410 | |
|---|
| 217 | 411 | return ret; |
|---|
| 218 | 412 | } |
|---|
| .. | .. |
|---|
| 233 | 427 | int ret; |
|---|
| 234 | 428 | |
|---|
| 235 | 429 | /* Wait for the bus to go inactive before unregistering */ |
|---|
| 236 | | - mutex_lock(&iosf_mbi_punit_mutex); |
|---|
| 430 | + iosf_mbi_punit_acquire(); |
|---|
| 237 | 431 | ret = iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(nb); |
|---|
| 238 | | - mutex_unlock(&iosf_mbi_punit_mutex); |
|---|
| 432 | + iosf_mbi_punit_release(); |
|---|
| 239 | 433 | |
|---|
| 240 | 434 | return ret; |
|---|
| 241 | 435 | } |
|---|
| 242 | 436 | EXPORT_SYMBOL(iosf_mbi_unregister_pmic_bus_access_notifier); |
|---|
| 243 | 437 | |
|---|
| 244 | | -int iosf_mbi_call_pmic_bus_access_notifier_chain(unsigned long val, void *v) |
|---|
| 245 | | -{ |
|---|
| 246 | | - return blocking_notifier_call_chain( |
|---|
| 247 | | - &iosf_mbi_pmic_bus_access_notifier, val, v); |
|---|
| 248 | | -} |
|---|
| 249 | | -EXPORT_SYMBOL(iosf_mbi_call_pmic_bus_access_notifier_chain); |
|---|
| 250 | | - |
|---|
| 251 | 438 | void iosf_mbi_assert_punit_acquired(void) |
|---|
| 252 | 439 | { |
|---|
| 253 | | - WARN_ON(!mutex_is_locked(&iosf_mbi_punit_mutex)); |
|---|
| 440 | + WARN_ON(iosf_mbi_pmic_punit_access_count == 0); |
|---|
| 254 | 441 | } |
|---|
| 255 | 442 | EXPORT_SYMBOL(iosf_mbi_assert_punit_acquired); |
|---|
| 443 | + |
|---|
| 444 | +/**************** iosf_mbi debug code ****************/ |
|---|
| 256 | 445 | |
|---|
| 257 | 446 | #ifdef CONFIG_IOSF_MBI_DEBUG |
|---|
| 258 | 447 | static u32 dbg_mdr; |
|---|
| .. | .. |
|---|
| 296 | 485 | |
|---|
| 297 | 486 | static void iosf_sideband_debug_init(void) |
|---|
| 298 | 487 | { |
|---|
| 299 | | - struct dentry *d; |
|---|
| 300 | | - |
|---|
| 301 | 488 | iosf_dbg = debugfs_create_dir("iosf_sb", NULL); |
|---|
| 302 | | - if (IS_ERR_OR_NULL(iosf_dbg)) |
|---|
| 303 | | - return; |
|---|
| 304 | 489 | |
|---|
| 305 | 490 | /* mdr */ |
|---|
| 306 | | - d = debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); |
|---|
| 307 | | - if (!d) |
|---|
| 308 | | - goto cleanup; |
|---|
| 491 | + debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); |
|---|
| 309 | 492 | |
|---|
| 310 | 493 | /* mcrx */ |
|---|
| 311 | | - d = debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); |
|---|
| 312 | | - if (!d) |
|---|
| 313 | | - goto cleanup; |
|---|
| 494 | + debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); |
|---|
| 314 | 495 | |
|---|
| 315 | 496 | /* mcr - initiates mailbox tranaction */ |
|---|
| 316 | | - d = debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); |
|---|
| 317 | | - if (!d) |
|---|
| 318 | | - goto cleanup; |
|---|
| 319 | | - |
|---|
| 320 | | - return; |
|---|
| 321 | | - |
|---|
| 322 | | -cleanup: |
|---|
| 323 | | - debugfs_remove_recursive(d); |
|---|
| 497 | + debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); |
|---|
| 324 | 498 | } |
|---|
| 325 | 499 | |
|---|
| 326 | 500 | static void iosf_debugfs_init(void) |
|---|
| .. | .. |
|---|
| 338 | 512 | #endif /* CONFIG_IOSF_MBI_DEBUG */ |
|---|
| 339 | 513 | |
|---|
| 340 | 514 | static int iosf_mbi_probe(struct pci_dev *pdev, |
|---|
| 341 | | - const struct pci_device_id *unused) |
|---|
| 515 | + const struct pci_device_id *dev_id) |
|---|
| 342 | 516 | { |
|---|
| 343 | 517 | int ret; |
|---|
| 344 | 518 | |
|---|
| .. | .. |
|---|
| 349 | 523 | } |
|---|
| 350 | 524 | |
|---|
| 351 | 525 | mbi_pdev = pci_dev_get(pdev); |
|---|
| 526 | + iosf_mbi_sem_address = dev_id->driver_data; |
|---|
| 527 | + |
|---|
| 352 | 528 | return 0; |
|---|
| 353 | 529 | } |
|---|
| 354 | 530 | |
|---|
| 355 | 531 | static const struct pci_device_id iosf_mbi_pci_ids[] = { |
|---|
| 356 | | - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BAYTRAIL) }, |
|---|
| 357 | | - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRASWELL) }, |
|---|
| 358 | | - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_QUARK_X1000) }, |
|---|
| 359 | | - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_TANGIER) }, |
|---|
| 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) }, |
|---|
| 360 | 536 | { 0, }, |
|---|
| 361 | 537 | }; |
|---|
| 362 | 538 | MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids); |
|---|
| .. | .. |
|---|
| 371 | 547 | { |
|---|
| 372 | 548 | iosf_debugfs_init(); |
|---|
| 373 | 549 | |
|---|
| 550 | + cpu_latency_qos_add_request(&iosf_mbi_pm_qos, PM_QOS_DEFAULT_VALUE); |
|---|
| 551 | + |
|---|
| 374 | 552 | return pci_register_driver(&iosf_mbi_pci_driver); |
|---|
| 375 | 553 | } |
|---|
| 376 | 554 | |
|---|
| .. | .. |
|---|
| 381 | 559 | pci_unregister_driver(&iosf_mbi_pci_driver); |
|---|
| 382 | 560 | pci_dev_put(mbi_pdev); |
|---|
| 383 | 561 | mbi_pdev = NULL; |
|---|
| 562 | + |
|---|
| 563 | + cpu_latency_qos_remove_request(&iosf_mbi_pm_qos); |
|---|
| 384 | 564 | } |
|---|
| 385 | 565 | |
|---|
| 386 | 566 | module_init(iosf_mbi_init); |
|---|