diff options
Diffstat (limited to 'drivers')
72 files changed, 581 insertions, 314 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index b811f2173f6f..88681aca88c5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -105,7 +105,7 @@ config ACPI_EC_DEBUGFS | |||
105 | 105 | ||
106 | Be aware that using this interface can confuse your Embedded | 106 | Be aware that using this interface can confuse your Embedded |
107 | Controller in a way that a normal reboot is not enough. You then | 107 | Controller in a way that a normal reboot is not enough. You then |
108 | have to power of your system, and remove the laptop battery for | 108 | have to power off your system, and remove the laptop battery for |
109 | some seconds. | 109 | some seconds. |
110 | An Embedded Controller typically is available on laptops and reads | 110 | An Embedded Controller typically is available on laptops and reads |
111 | sensor values like battery state and temperature. | 111 | sensor values like battery state and temperature. |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b76848c80be3..6b115f6c4313 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -382,31 +382,32 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device) | |||
382 | device_remove_file(&device->dev, &dev_attr_rrtime); | 382 | device_remove_file(&device->dev, &dev_attr_rrtime); |
383 | } | 383 | } |
384 | 384 | ||
385 | /* Query firmware how many CPUs should be idle */ | 385 | /* |
386 | static int acpi_pad_pur(acpi_handle handle, int *num_cpus) | 386 | * Query firmware how many CPUs should be idle |
387 | * return -1 on failure | ||
388 | */ | ||
389 | static int acpi_pad_pur(acpi_handle handle) | ||
387 | { | 390 | { |
388 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 391 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
389 | union acpi_object *package; | 392 | union acpi_object *package; |
390 | int rev, num, ret = -EINVAL; | 393 | int num = -1; |
391 | 394 | ||
392 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) | 395 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer))) |
393 | return -EINVAL; | 396 | return num; |
394 | 397 | ||
395 | if (!buffer.length || !buffer.pointer) | 398 | if (!buffer.length || !buffer.pointer) |
396 | return -EINVAL; | 399 | return num; |
397 | 400 | ||
398 | package = buffer.pointer; | 401 | package = buffer.pointer; |
399 | if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2) | 402 | |
400 | goto out; | 403 | if (package->type == ACPI_TYPE_PACKAGE && |
401 | rev = package->package.elements[0].integer.value; | 404 | package->package.count == 2 && |
402 | num = package->package.elements[1].integer.value; | 405 | package->package.elements[0].integer.value == 1) /* rev 1 */ |
403 | if (rev != 1 || num < 0) | 406 | |
404 | goto out; | 407 | num = package->package.elements[1].integer.value; |
405 | *num_cpus = num; | 408 | |
406 | ret = 0; | ||
407 | out: | ||
408 | kfree(buffer.pointer); | 409 | kfree(buffer.pointer); |
409 | return ret; | 410 | return num; |
410 | } | 411 | } |
411 | 412 | ||
412 | /* Notify firmware how many CPUs are idle */ | 413 | /* Notify firmware how many CPUs are idle */ |
@@ -433,7 +434,8 @@ static void acpi_pad_handle_notify(acpi_handle handle) | |||
433 | uint32_t idle_cpus; | 434 | uint32_t idle_cpus; |
434 | 435 | ||
435 | mutex_lock(&isolated_cpus_lock); | 436 | mutex_lock(&isolated_cpus_lock); |
436 | if (acpi_pad_pur(handle, &num_cpus)) { | 437 | num_cpus = acpi_pad_pur(handle); |
438 | if (num_cpus < 0) { | ||
437 | mutex_unlock(&isolated_cpus_lock); | 439 | mutex_unlock(&isolated_cpus_lock); |
438 | return; | 440 | return; |
439 | } | 441 | } |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index df85b53a674f..7dad9160f209 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -854,6 +854,7 @@ struct acpi_bit_register_info { | |||
854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ | 854 | ACPI_BITMASK_POWER_BUTTON_STATUS | \ |
855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ | 855 | ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ |
856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ | 856 | ACPI_BITMASK_RT_CLOCK_STATUS | \ |
857 | ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ | ||
857 | ACPI_BITMASK_WAKE_STATUS) | 858 | ACPI_BITMASK_WAKE_STATUS) |
858 | 859 | ||
859 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 | 860 | #define ACPI_BITMASK_TIMER_ENABLE 0x0001 |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 74c24d517f81..4093522eed45 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -109,7 +109,7 @@ void acpi_ex_enter_interpreter(void) | |||
109 | * | 109 | * |
110 | * DESCRIPTION: Reacquire the interpreter execution region from within the | 110 | * DESCRIPTION: Reacquire the interpreter execution region from within the |
111 | * interpreter code. Failure to enter the interpreter region is a | 111 | * interpreter code. Failure to enter the interpreter region is a |
112 | * fatal system error. Used in conjuction with | 112 | * fatal system error. Used in conjunction with |
113 | * relinquish_interpreter | 113 | * relinquish_interpreter |
114 | * | 114 | * |
115 | ******************************************************************************/ | 115 | ******************************************************************************/ |
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 22cfcfbd9fff..491191e6cf69 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -149,7 +149,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type) | |||
149 | 149 | ||
150 | /* | 150 | /* |
151 | * 16-, 32-, and 64-bit cases must use the move macros that perform | 151 | * 16-, 32-, and 64-bit cases must use the move macros that perform |
152 | * endian conversion and/or accomodate hardware that cannot perform | 152 | * endian conversion and/or accommodate hardware that cannot perform |
153 | * misaligned memory transfers | 153 | * misaligned memory transfers |
154 | */ | 154 | */ |
155 | case ACPI_RSC_MOVE16: | 155 | case ACPI_RSC_MOVE16: |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index 907e350f1c7d..fca34ccfd294 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -34,6 +34,6 @@ config ACPI_APEI_ERST_DEBUG | |||
34 | depends on ACPI_APEI | 34 | depends on ACPI_APEI |
35 | help | 35 | help |
36 | ERST is a way provided by APEI to save and retrieve hardware | 36 | ERST is a way provided by APEI to save and retrieve hardware |
37 | error infomation to and from a persistent store. Enable this | 37 | error information to and from a persistent store. Enable this |
38 | if you want to debugging and testing the ERST kernel support | 38 | if you want to debugging and testing the ERST kernel support |
39 | and firmware implementation. | 39 | and firmware implementation. |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 73fd0c7487c1..4a904a4bf05f 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -445,11 +445,15 @@ EXPORT_SYMBOL_GPL(apei_resources_sub); | |||
445 | int apei_resources_request(struct apei_resources *resources, | 445 | int apei_resources_request(struct apei_resources *resources, |
446 | const char *desc) | 446 | const char *desc) |
447 | { | 447 | { |
448 | struct apei_res *res, *res_bak; | 448 | struct apei_res *res, *res_bak = NULL; |
449 | struct resource *r; | 449 | struct resource *r; |
450 | int rc; | ||
450 | 451 | ||
451 | apei_resources_sub(resources, &apei_resources_all); | 452 | rc = apei_resources_sub(resources, &apei_resources_all); |
453 | if (rc) | ||
454 | return rc; | ||
452 | 455 | ||
456 | rc = -EINVAL; | ||
453 | list_for_each_entry(res, &resources->iomem, list) { | 457 | list_for_each_entry(res, &resources->iomem, list) { |
454 | r = request_mem_region(res->start, res->end - res->start, | 458 | r = request_mem_region(res->start, res->end - res->start, |
455 | desc); | 459 | desc); |
@@ -475,7 +479,11 @@ int apei_resources_request(struct apei_resources *resources, | |||
475 | } | 479 | } |
476 | } | 480 | } |
477 | 481 | ||
478 | apei_resources_merge(&apei_resources_all, resources); | 482 | rc = apei_resources_merge(&apei_resources_all, resources); |
483 | if (rc) { | ||
484 | pr_err(APEI_PFX "Fail to merge resources!\n"); | ||
485 | goto err_unmap_ioport; | ||
486 | } | ||
479 | 487 | ||
480 | return 0; | 488 | return 0; |
481 | err_unmap_ioport: | 489 | err_unmap_ioport: |
@@ -491,12 +499,13 @@ err_unmap_iomem: | |||
491 | break; | 499 | break; |
492 | release_mem_region(res->start, res->end - res->start); | 500 | release_mem_region(res->start, res->end - res->start); |
493 | } | 501 | } |
494 | return -EINVAL; | 502 | return rc; |
495 | } | 503 | } |
496 | EXPORT_SYMBOL_GPL(apei_resources_request); | 504 | EXPORT_SYMBOL_GPL(apei_resources_request); |
497 | 505 | ||
498 | void apei_resources_release(struct apei_resources *resources) | 506 | void apei_resources_release(struct apei_resources *resources) |
499 | { | 507 | { |
508 | int rc; | ||
500 | struct apei_res *res; | 509 | struct apei_res *res; |
501 | 510 | ||
502 | list_for_each_entry(res, &resources->iomem, list) | 511 | list_for_each_entry(res, &resources->iomem, list) |
@@ -504,7 +513,9 @@ void apei_resources_release(struct apei_resources *resources) | |||
504 | list_for_each_entry(res, &resources->ioport, list) | 513 | list_for_each_entry(res, &resources->ioport, list) |
505 | release_region(res->start, res->end - res->start); | 514 | release_region(res->start, res->end - res->start); |
506 | 515 | ||
507 | apei_resources_sub(&apei_resources_all, resources); | 516 | rc = apei_resources_sub(&apei_resources_all, resources); |
517 | if (rc) | ||
518 | pr_err(APEI_PFX "Fail to sub resources!\n"); | ||
508 | } | 519 | } |
509 | EXPORT_SYMBOL_GPL(apei_resources_release); | 520 | EXPORT_SYMBOL_GPL(apei_resources_release); |
510 | 521 | ||
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index 465c885938ee..cf29df69380b 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c | |||
@@ -426,7 +426,9 @@ DEFINE_SIMPLE_ATTRIBUTE(error_inject_fops, NULL, | |||
426 | 426 | ||
427 | static int einj_check_table(struct acpi_table_einj *einj_tab) | 427 | static int einj_check_table(struct acpi_table_einj *einj_tab) |
428 | { | 428 | { |
429 | if (einj_tab->header_length != sizeof(struct acpi_table_einj)) | 429 | if ((einj_tab->header_length != |
430 | (sizeof(struct acpi_table_einj) - sizeof(einj_tab->header))) | ||
431 | && (einj_tab->header_length != sizeof(struct acpi_table_einj))) | ||
430 | return -EINVAL; | 432 | return -EINVAL; |
431 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) | 433 | if (einj_tab->header.length < sizeof(struct acpi_table_einj)) |
432 | return -EINVAL; | 434 | return -EINVAL; |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index 5281ddda2777..da1228a9a544 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table debug support | 2 | * APEI Error Record Serialization Table debug support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. This file provide the | 5 | * information to and from a persistent store. This file provide the |
6 | * debugging/testing support for ERST kernel support and firmware | 6 | * debugging/testing support for ERST kernel support and firmware |
7 | * implementation. | 7 | * implementation. |
8 | * | 8 | * |
@@ -111,11 +111,13 @@ retry: | |||
111 | goto out; | 111 | goto out; |
112 | } | 112 | } |
113 | if (len > erst_dbg_buf_len) { | 113 | if (len > erst_dbg_buf_len) { |
114 | kfree(erst_dbg_buf); | 114 | void *p; |
115 | rc = -ENOMEM; | 115 | rc = -ENOMEM; |
116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | 116 | p = kmalloc(len, GFP_KERNEL); |
117 | if (!erst_dbg_buf) | 117 | if (!p) |
118 | goto out; | 118 | goto out; |
119 | kfree(erst_dbg_buf); | ||
120 | erst_dbg_buf = p; | ||
119 | erst_dbg_buf_len = len; | 121 | erst_dbg_buf_len = len; |
120 | goto retry; | 122 | goto retry; |
121 | } | 123 | } |
@@ -150,11 +152,13 @@ static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | |||
150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | 152 | if (mutex_lock_interruptible(&erst_dbg_mutex)) |
151 | return -EINTR; | 153 | return -EINTR; |
152 | if (usize > erst_dbg_buf_len) { | 154 | if (usize > erst_dbg_buf_len) { |
153 | kfree(erst_dbg_buf); | 155 | void *p; |
154 | rc = -ENOMEM; | 156 | rc = -ENOMEM; |
155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | 157 | p = kmalloc(usize, GFP_KERNEL); |
156 | if (!erst_dbg_buf) | 158 | if (!p) |
157 | goto out; | 159 | goto out; |
160 | kfree(erst_dbg_buf); | ||
161 | erst_dbg_buf = p; | ||
158 | erst_dbg_buf_len = usize; | 162 | erst_dbg_buf_len = usize; |
159 | } | 163 | } |
160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | 164 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); |
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 18645f4e83cd..1211c03149e8 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * APEI Error Record Serialization Table support | 2 | * APEI Error Record Serialization Table support |
3 | * | 3 | * |
4 | * ERST is a way provided by APEI to save and retrieve hardware error | 4 | * ERST is a way provided by APEI to save and retrieve hardware error |
5 | * infomation to and from a persistent store. | 5 | * information to and from a persistent store. |
6 | * | 6 | * |
7 | * For more information about ERST, please refer to ACPI Specification | 7 | * For more information about ERST, please refer to ACPI Specification |
8 | * version 4.0, section 17.4. | 8 | * version 4.0, section 17.4. |
@@ -266,13 +266,30 @@ static int erst_exec_move_data(struct apei_exec_context *ctx, | |||
266 | { | 266 | { |
267 | int rc; | 267 | int rc; |
268 | u64 offset; | 268 | u64 offset; |
269 | void *src, *dst; | ||
270 | |||
271 | /* ioremap does not work in interrupt context */ | ||
272 | if (in_interrupt()) { | ||
273 | pr_warning(ERST_PFX | ||
274 | "MOVE_DATA can not be used in interrupt context"); | ||
275 | return -EBUSY; | ||
276 | } | ||
269 | 277 | ||
270 | rc = __apei_exec_read_register(entry, &offset); | 278 | rc = __apei_exec_read_register(entry, &offset); |
271 | if (rc) | 279 | if (rc) |
272 | return rc; | 280 | return rc; |
273 | memmove((void *)ctx->dst_base + offset, | 281 | |
274 | (void *)ctx->src_base + offset, | 282 | src = ioremap(ctx->src_base + offset, ctx->var2); |
275 | ctx->var2); | 283 | if (!src) |
284 | return -ENOMEM; | ||
285 | dst = ioremap(ctx->dst_base + offset, ctx->var2); | ||
286 | if (!dst) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | memmove(dst, src, ctx->var2); | ||
290 | |||
291 | iounmap(src); | ||
292 | iounmap(dst); | ||
276 | 293 | ||
277 | return 0; | 294 | return 0; |
278 | } | 295 | } |
@@ -750,7 +767,9 @@ __setup("erst_disable", setup_erst_disable); | |||
750 | 767 | ||
751 | static int erst_check_table(struct acpi_table_erst *erst_tab) | 768 | static int erst_check_table(struct acpi_table_erst *erst_tab) |
752 | { | 769 | { |
753 | if (erst_tab->header_length != sizeof(struct acpi_table_erst)) | 770 | if ((erst_tab->header_length != |
771 | (sizeof(struct acpi_table_erst) - sizeof(erst_tab->header))) | ||
772 | && (erst_tab->header_length != sizeof(struct acpi_table_einj))) | ||
754 | return -EINVAL; | 773 | return -EINVAL; |
755 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) | 774 | if (erst_tab->header.length < sizeof(struct acpi_table_erst)) |
756 | return -EINVAL; | 775 | return -EINVAL; |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 385a6059714a..0d505e59214d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -302,7 +302,7 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) | |||
302 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
303 | int rc = -EINVAL; | 303 | int rc = -EINVAL; |
304 | 304 | ||
305 | generic = ghes_dev->dev.platform_data; | 305 | generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; |
306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
307 | return -ENODEV; | 307 | return -ENODEV; |
308 | 308 | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 343168d18266..1a3508a7fe03 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -137,20 +137,23 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct acpi_hest_generic *generic; | ||
141 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
142 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
143 | int rc; | 142 | int rc; |
144 | 143 | ||
145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
146 | return 0; | 145 | return 0; |
147 | generic = (struct acpi_hest_generic *)hest_hdr; | 146 | |
148 | if (!generic->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
149 | return 0; | 148 | return 0; |
150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
151 | if (!ghes_dev) | 150 | if (!ghes_dev) |
152 | return -ENOMEM; | 151 | return -ENOMEM; |
153 | ghes_dev->dev.platform_data = generic; | 152 | |
153 | rc = platform_device_add_data(ghes_dev, &hest_hdr, sizeof(void *)); | ||
154 | if (rc) | ||
155 | goto err; | ||
156 | |||
154 | rc = platform_device_add(ghes_dev); | 157 | rc = platform_device_add(ghes_dev); |
155 | if (rc) | 158 | if (rc) |
156 | goto err; | 159 | goto err; |
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 8f8bd736d4ff..542e53903891 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c | |||
@@ -142,7 +142,7 @@ static void __iomem *acpi_pre_map(phys_addr_t paddr, | |||
142 | list_add_tail_rcu(&map->list, &acpi_iomaps); | 142 | list_add_tail_rcu(&map->list, &acpi_iomaps); |
143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); | 143 | spin_unlock_irqrestore(&acpi_iomaps_lock, flags); |
144 | 144 | ||
145 | return vaddr + (paddr - pg_off); | 145 | return map->vaddr + (paddr - map->paddr); |
146 | err_unmap: | 146 | err_unmap: |
147 | iounmap(vaddr); | 147 | iounmap(vaddr); |
148 | return NULL; | 148 | return NULL; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index dc58402b0a17..98417201e9ce 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -273,7 +273,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
273 | POWER_SUPPLY_PROP_CYCLE_COUNT, | 273 | POWER_SUPPLY_PROP_CYCLE_COUNT, |
274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 274 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 275 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
276 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
277 | POWER_SUPPLY_PROP_POWER_NOW, | 276 | POWER_SUPPLY_PROP_POWER_NOW, |
278 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 277 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
279 | POWER_SUPPLY_PROP_ENERGY_FULL, | 278 | POWER_SUPPLY_PROP_ENERGY_FULL, |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2bb28b9d91c4..f7619600270a 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -183,6 +183,8 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | |||
183 | { | 183 | { |
184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 184 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
185 | acpi_osi_setup("!Windows 2006"); | 185 | acpi_osi_setup("!Windows 2006"); |
186 | acpi_osi_setup("!Windows 2006 SP1"); | ||
187 | acpi_osi_setup("!Windows 2006 SP2"); | ||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | 190 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) |
@@ -226,6 +228,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
226 | }, | 228 | }, |
227 | }, | 229 | }, |
228 | { | 230 | { |
231 | .callback = dmi_disable_osi_vista, | ||
232 | .ident = "Toshiba Satellite L355", | ||
233 | .matches = { | ||
234 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
235 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
236 | }, | ||
237 | }, | ||
238 | { | ||
229 | .callback = dmi_disable_osi_win7, | 239 | .callback = dmi_disable_osi_win7, |
230 | .ident = "ASUS K50IJ", | 240 | .ident = "ASUS K50IJ", |
231 | .matches = { | 241 | .matches = { |
@@ -233,6 +243,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
233 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | 243 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), |
234 | }, | 244 | }, |
235 | }, | 245 | }, |
246 | { | ||
247 | .callback = dmi_disable_osi_vista, | ||
248 | .ident = "Toshiba P305D", | ||
249 | .matches = { | ||
250 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
251 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
252 | }, | ||
253 | }, | ||
236 | 254 | ||
237 | /* | 255 | /* |
238 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 256 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 5c221ab535d5..310e3b9749cb 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | 55 | static int set_power_nocheck(const struct dmi_system_id *id) |
56 | { | 56 | { |
57 | printk(KERN_NOTICE PREFIX "%s detected - " | 57 | printk(KERN_NOTICE PREFIX "%s detected - " |
58 | "disable power check in power transistion\n", id->ident); | 58 | "disable power check in power transition\n", id->ident); |
59 | acpi_power_nocheck = 1; | 59 | acpi_power_nocheck = 1; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
@@ -80,23 +80,15 @@ static int set_copy_dsdt(const struct dmi_system_id *id) | |||
80 | 80 | ||
81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { | 81 | static struct dmi_system_id dsdt_dmi_table[] __initdata = { |
82 | /* | 82 | /* |
83 | * Insyde BIOS on some TOSHIBA machines corrupt the DSDT. | 83 | * Invoke DSDT corruption work-around on all Toshiba Satellite. |
84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 | 84 | * https://bugzilla.kernel.org/show_bug.cgi?id=14679 |
85 | */ | 85 | */ |
86 | { | 86 | { |
87 | .callback = set_copy_dsdt, | 87 | .callback = set_copy_dsdt, |
88 | .ident = "TOSHIBA Satellite A505", | 88 | .ident = "TOSHIBA Satellite", |
89 | .matches = { | 89 | .matches = { |
90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 90 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A505"), | 91 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"), |
92 | }, | ||
93 | }, | ||
94 | { | ||
95 | .callback = set_copy_dsdt, | ||
96 | .ident = "TOSHIBA Satellite L505D", | ||
97 | .matches = { | ||
98 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
99 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L505D"), | ||
100 | }, | 92 | }, |
101 | }, | 93 | }, |
102 | {} | 94 | {} |
@@ -1027,7 +1019,7 @@ static int __init acpi_init(void) | |||
1027 | 1019 | ||
1028 | /* | 1020 | /* |
1029 | * If the laptop falls into the DMI check table, the power state check | 1021 | * If the laptop falls into the DMI check table, the power state check |
1030 | * will be disabled in the course of device power transistion. | 1022 | * will be disabled in the course of device power transition. |
1031 | */ | 1023 | */ |
1032 | dmi_check_system(power_nocheck_dmi_table); | 1024 | dmi_check_system(power_nocheck_dmi_table); |
1033 | 1025 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 8a3b840c0bb2..d94d2953c974 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -369,7 +369,9 @@ static void __exit acpi_fan_exit(void) | |||
369 | 369 | ||
370 | acpi_bus_unregister_driver(&acpi_fan_driver); | 370 | acpi_bus_unregister_driver(&acpi_fan_driver); |
371 | 371 | ||
372 | #ifdef CONFIG_ACPI_PROCFS | ||
372 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | 373 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); |
374 | #endif | ||
373 | 375 | ||
374 | return; | 376 | return; |
375 | } | 377 | } |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index df6e1676a6f3..bec561c14beb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -29,12 +29,6 @@ static int set_no_mwait(const struct dmi_system_id *id) | |||
29 | 29 | ||
30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { | 30 | static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { |
31 | { | 31 | { |
32 | set_no_mwait, "IFL91 board", { | ||
33 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
34 | DMI_MATCH(DMI_SYS_VENDOR, "ZEPTO"), | ||
35 | DMI_MATCH(DMI_PRODUCT_VERSION, "3215W"), | ||
36 | DMI_MATCH(DMI_BOARD_NAME, "IFL91") }, NULL}, | ||
37 | { | ||
38 | set_no_mwait, "Extensa 5220", { | 32 | set_no_mwait, "Extensa 5220", { |
39 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | 33 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
40 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | 34 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 156021892389..347eb21b2353 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -850,7 +850,7 @@ static int __init acpi_processor_init(void) | |||
850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
851 | acpi_idle_driver.name); | 851 | acpi_idle_driver.name); |
852 | } else { | 852 | } else { |
853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s", | 853 | printk(KERN_DEBUG "ACPI: acpi_idle yielding to %s\n", |
854 | cpuidle_get_driver()->name); | 854 | cpuidle_get_driver()->name); |
855 | } | 855 | } |
856 | 856 | ||
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index ba1bd263d903..3a73a93596e8 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -447,8 +447,8 @@ int acpi_processor_notify_smm(struct module *calling_module) | |||
447 | if (!try_module_get(calling_module)) | 447 | if (!try_module_get(calling_module)) |
448 | return -EINVAL; | 448 | return -EINVAL; |
449 | 449 | ||
450 | /* is_done is set to negative if an error occured, | 450 | /* is_done is set to negative if an error occurred, |
451 | * and to postitive if _no_ error occured, but SMM | 451 | * and to postitive if _no_ error occurred, but SMM |
452 | * was already notified. This avoids double notification | 452 | * was already notified. This avoids double notification |
453 | * which might lead to unexpected results... | 453 | * which might lead to unexpected results... |
454 | */ | 454 | */ |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index cf82989ae756..4754ff6e70e6 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -363,6 +363,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
363 | return 0; | 363 | return 0; |
364 | } | 364 | } |
365 | 365 | ||
366 | static int __init init_nvs_nosave(const struct dmi_system_id *d) | ||
367 | { | ||
368 | acpi_nvs_nosave(); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
366 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 372 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
367 | { | 373 | { |
368 | .callback = init_old_suspend_ordering, | 374 | .callback = init_old_suspend_ordering, |
@@ -397,6 +403,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
397 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), | 403 | DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"), |
398 | }, | 404 | }, |
399 | }, | 405 | }, |
406 | { | ||
407 | .callback = init_nvs_nosave, | ||
408 | .ident = "Sony Vaio VGN-SR11M", | ||
409 | .matches = { | ||
410 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
411 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"), | ||
412 | }, | ||
413 | }, | ||
414 | { | ||
415 | .callback = init_nvs_nosave, | ||
416 | .ident = "Everex StepNote Series", | ||
417 | .matches = { | ||
418 | DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."), | ||
419 | DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), | ||
420 | }, | ||
421 | }, | ||
400 | {}, | 422 | {}, |
401 | }; | 423 | }; |
402 | #endif /* CONFIG_SUSPEND */ | 424 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 68e2e4582fa2..f8588f81048a 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -100,7 +100,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = { | |||
100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | 100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | 103 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) |
104 | { | 104 | { |
105 | int result = 0; | 105 | int result = 0; |
106 | int i; | 106 | int i; |
@@ -128,7 +128,7 @@ static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | |||
128 | return result; | 128 | return result; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | 131 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) |
132 | { | 132 | { |
133 | int result = 0; | 133 | int result = 0; |
134 | int i; | 134 | int i; |
@@ -149,10 +149,18 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) | |||
149 | return result; | 149 | return result; |
150 | } | 150 | } |
151 | 151 | ||
152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | 152 | static struct kernel_param_ops param_ops_debug_layer = { |
153 | &acpi_dbg_layer, 0644); | 153 | .set = param_set_uint, |
154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | 154 | .get = param_get_debug_layer, |
155 | &acpi_dbg_level, 0644); | 155 | }; |
156 | |||
157 | static struct kernel_param_ops param_ops_debug_level = { | ||
158 | .set = param_set_uint, | ||
159 | .get = param_get_debug_level, | ||
160 | }; | ||
161 | |||
162 | module_param_cb(debug_layer, ¶m_ops_debug_layer, &acpi_dbg_layer, 0644); | ||
163 | module_param_cb(debug_level, ¶m_ops_debug_level, &acpi_dbg_level, 0644); | ||
156 | 164 | ||
157 | static char trace_method_name[6]; | 165 | static char trace_method_name[6]; |
158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | 166 | module_param_string(trace_method_name, trace_method_name, 6, 0644); |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index c5fef01b3c95..b83676126598 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -59,8 +59,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
59 | "support\n")); | 59 | "support\n")); |
60 | *cap |= ACPI_VIDEO_BACKLIGHT; | 60 | *cap |= ACPI_VIDEO_BACKLIGHT; |
61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | 61 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) |
62 | printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " | 62 | printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, " |
63 | "control misses _BQC function\n"); | 63 | "cannot determine initial brightness\n"); |
64 | /* We have backlight support, no need to scan further */ | 64 | /* We have backlight support, no need to scan further */ |
65 | return AE_CTRL_TERMINATE; | 65 | return AE_CTRL_TERMINATE; |
66 | } | 66 | } |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c2408bbe9c2e..f508690eb958 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -80,7 +80,7 @@ | |||
80 | * Limiting Performance Impact | 80 | * Limiting Performance Impact |
81 | * --------------------------- | 81 | * --------------------------- |
82 | * C states, especially those with large exit latencies, can have a real | 82 | * C states, especially those with large exit latencies, can have a real |
83 | * noticable impact on workloads, which is not acceptable for most sysadmins, | 83 | * noticeable impact on workloads, which is not acceptable for most sysadmins, |
84 | * and in addition, less performance has a power price of its own. | 84 | * and in addition, less performance has a power price of its own. |
85 | * | 85 | * |
86 | * As a general rule of thumb, menu assumes that the following heuristic | 86 | * As a general rule of thumb, menu assumes that the following heuristic |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index fb64cf36ba61..eb6b54dbb806 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -580,7 +580,6 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
580 | 580 | ||
581 | sh_chan = to_sh_chan(chan); | 581 | sh_chan = to_sh_chan(chan); |
582 | param = chan->private; | 582 | param = chan->private; |
583 | slave_addr = param->config->addr; | ||
584 | 583 | ||
585 | /* Someone calling slave DMA on a public channel? */ | 584 | /* Someone calling slave DMA on a public channel? */ |
586 | if (!param || !sg_len) { | 585 | if (!param || !sg_len) { |
@@ -589,6 +588,8 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_slave_sg( | |||
589 | return NULL; | 588 | return NULL; |
590 | } | 589 | } |
591 | 590 | ||
591 | slave_addr = param->config->addr; | ||
592 | |||
592 | /* | 593 | /* |
593 | * if (param != NULL), this is a successfully requested slave channel, | 594 | * if (param != NULL), this is a successfully requested slave channel, |
594 | * therefore param->config != NULL too. | 595 | * therefore param->config != NULL too. |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index e0187d16dd7c..0fd5b85a0f75 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1140,6 +1140,7 @@ static struct mcidev_sysfs_attribute i7core_udimm_counters_attrs[] = { | |||
1140 | ATTR_COUNTER(0), | 1140 | ATTR_COUNTER(0), |
1141 | ATTR_COUNTER(1), | 1141 | ATTR_COUNTER(1), |
1142 | ATTR_COUNTER(2), | 1142 | ATTR_COUNTER(2), |
1143 | { .attr = { .name = NULL } } | ||
1143 | }; | 1144 | }; |
1144 | 1145 | ||
1145 | static struct mcidev_sysfs_group i7core_udimm_counters = { | 1146 | static struct mcidev_sysfs_group i7core_udimm_counters = { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index bf92d07510df..5663d2719063 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -148,7 +148,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | 149 | ||
150 | kref_init(&obj->refcount); | 150 | kref_init(&obj->refcount); |
151 | kref_init(&obj->handlecount); | 151 | atomic_set(&obj->handle_count, 0); |
152 | obj->size = size; | 152 | obj->size = size; |
153 | 153 | ||
154 | atomic_inc(&dev->object_count); | 154 | atomic_inc(&dev->object_count); |
@@ -462,28 +462,6 @@ drm_gem_object_free(struct kref *kref) | |||
462 | } | 462 | } |
463 | EXPORT_SYMBOL(drm_gem_object_free); | 463 | EXPORT_SYMBOL(drm_gem_object_free); |
464 | 464 | ||
465 | /** | ||
466 | * Called after the last reference to the object has been lost. | ||
467 | * Must be called without holding struct_mutex | ||
468 | * | ||
469 | * Frees the object | ||
470 | */ | ||
471 | void | ||
472 | drm_gem_object_free_unlocked(struct kref *kref) | ||
473 | { | ||
474 | struct drm_gem_object *obj = (struct drm_gem_object *) kref; | ||
475 | struct drm_device *dev = obj->dev; | ||
476 | |||
477 | if (dev->driver->gem_free_object_unlocked != NULL) | ||
478 | dev->driver->gem_free_object_unlocked(obj); | ||
479 | else if (dev->driver->gem_free_object != NULL) { | ||
480 | mutex_lock(&dev->struct_mutex); | ||
481 | dev->driver->gem_free_object(obj); | ||
482 | mutex_unlock(&dev->struct_mutex); | ||
483 | } | ||
484 | } | ||
485 | EXPORT_SYMBOL(drm_gem_object_free_unlocked); | ||
486 | |||
487 | static void drm_gem_object_ref_bug(struct kref *list_kref) | 465 | static void drm_gem_object_ref_bug(struct kref *list_kref) |
488 | { | 466 | { |
489 | BUG(); | 467 | BUG(); |
@@ -496,12 +474,8 @@ static void drm_gem_object_ref_bug(struct kref *list_kref) | |||
496 | * called before drm_gem_object_free or we'll be touching | 474 | * called before drm_gem_object_free or we'll be touching |
497 | * freed memory | 475 | * freed memory |
498 | */ | 476 | */ |
499 | void | 477 | void drm_gem_object_handle_free(struct drm_gem_object *obj) |
500 | drm_gem_object_handle_free(struct kref *kref) | ||
501 | { | 478 | { |
502 | struct drm_gem_object *obj = container_of(kref, | ||
503 | struct drm_gem_object, | ||
504 | handlecount); | ||
505 | struct drm_device *dev = obj->dev; | 479 | struct drm_device *dev = obj->dev; |
506 | 480 | ||
507 | /* Remove any name for this object */ | 481 | /* Remove any name for this object */ |
@@ -528,6 +502,10 @@ void drm_gem_vm_open(struct vm_area_struct *vma) | |||
528 | struct drm_gem_object *obj = vma->vm_private_data; | 502 | struct drm_gem_object *obj = vma->vm_private_data; |
529 | 503 | ||
530 | drm_gem_object_reference(obj); | 504 | drm_gem_object_reference(obj); |
505 | |||
506 | mutex_lock(&obj->dev->struct_mutex); | ||
507 | drm_vm_open_locked(vma); | ||
508 | mutex_unlock(&obj->dev->struct_mutex); | ||
531 | } | 509 | } |
532 | EXPORT_SYMBOL(drm_gem_vm_open); | 510 | EXPORT_SYMBOL(drm_gem_vm_open); |
533 | 511 | ||
@@ -535,7 +513,10 @@ void drm_gem_vm_close(struct vm_area_struct *vma) | |||
535 | { | 513 | { |
536 | struct drm_gem_object *obj = vma->vm_private_data; | 514 | struct drm_gem_object *obj = vma->vm_private_data; |
537 | 515 | ||
538 | drm_gem_object_unreference_unlocked(obj); | 516 | mutex_lock(&obj->dev->struct_mutex); |
517 | drm_vm_close_locked(vma); | ||
518 | drm_gem_object_unreference(obj); | ||
519 | mutex_unlock(&obj->dev->struct_mutex); | ||
539 | } | 520 | } |
540 | EXPORT_SYMBOL(drm_gem_vm_close); | 521 | EXPORT_SYMBOL(drm_gem_vm_close); |
541 | 522 | ||
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c index 2ef2c7827243..974e970ce3f8 100644 --- a/drivers/gpu/drm/drm_info.c +++ b/drivers/gpu/drm/drm_info.c | |||
@@ -255,7 +255,7 @@ int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
255 | 255 | ||
256 | seq_printf(m, "%6d %8zd %7d %8d\n", | 256 | seq_printf(m, "%6d %8zd %7d %8d\n", |
257 | obj->name, obj->size, | 257 | obj->name, obj->size, |
258 | atomic_read(&obj->handlecount.refcount), | 258 | atomic_read(&obj->handle_count), |
259 | atomic_read(&obj->refcount.refcount)); | 259 | atomic_read(&obj->refcount.refcount)); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index fda67468e603..5df450683aab 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -433,15 +433,7 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
433 | mutex_unlock(&dev->struct_mutex); | 433 | mutex_unlock(&dev->struct_mutex); |
434 | } | 434 | } |
435 | 435 | ||
436 | /** | 436 | void drm_vm_close_locked(struct vm_area_struct *vma) |
437 | * \c close method for all virtual memory types. | ||
438 | * | ||
439 | * \param vma virtual memory area. | ||
440 | * | ||
441 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
442 | * free it. | ||
443 | */ | ||
444 | static void drm_vm_close(struct vm_area_struct *vma) | ||
445 | { | 437 | { |
446 | struct drm_file *priv = vma->vm_file->private_data; | 438 | struct drm_file *priv = vma->vm_file->private_data; |
447 | struct drm_device *dev = priv->minor->dev; | 439 | struct drm_device *dev = priv->minor->dev; |
@@ -451,7 +443,6 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
451 | vma->vm_start, vma->vm_end - vma->vm_start); | 443 | vma->vm_start, vma->vm_end - vma->vm_start); |
452 | atomic_dec(&dev->vma_count); | 444 | atomic_dec(&dev->vma_count); |
453 | 445 | ||
454 | mutex_lock(&dev->struct_mutex); | ||
455 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { | 446 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { |
456 | if (pt->vma == vma) { | 447 | if (pt->vma == vma) { |
457 | list_del(&pt->head); | 448 | list_del(&pt->head); |
@@ -459,6 +450,23 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
459 | break; | 450 | break; |
460 | } | 451 | } |
461 | } | 452 | } |
453 | } | ||
454 | |||
455 | /** | ||
456 | * \c close method for all virtual memory types. | ||
457 | * | ||
458 | * \param vma virtual memory area. | ||
459 | * | ||
460 | * Search the \p vma private data entry in drm_device::vmalist, unlink it, and | ||
461 | * free it. | ||
462 | */ | ||
463 | static void drm_vm_close(struct vm_area_struct *vma) | ||
464 | { | ||
465 | struct drm_file *priv = vma->vm_file->private_data; | ||
466 | struct drm_device *dev = priv->minor->dev; | ||
467 | |||
468 | mutex_lock(&dev->struct_mutex); | ||
469 | drm_vm_close_locked(vma); | ||
462 | mutex_unlock(&dev->struct_mutex); | 470 | mutex_unlock(&dev->struct_mutex); |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 61b4caf220fa..fb07e73581e8 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -116,7 +116,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
116 | static const struct file_operations i810_buffer_fops = { | 116 | static const struct file_operations i810_buffer_fops = { |
117 | .open = drm_open, | 117 | .open = drm_open, |
118 | .release = drm_release, | 118 | .release = drm_release, |
119 | .unlocked_ioctl = drm_ioctl, | 119 | .unlocked_ioctl = i810_ioctl, |
120 | .mmap = i810_mmap_buffers, | 120 | .mmap = i810_mmap_buffers, |
121 | .fasync = drm_fasync, | 121 | .fasync = drm_fasync, |
122 | }; | 122 | }; |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 671aa18415ac..cc92c7e6236f 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -118,7 +118,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) | |||
118 | static const struct file_operations i830_buffer_fops = { | 118 | static const struct file_operations i830_buffer_fops = { |
119 | .open = drm_open, | 119 | .open = drm_open, |
120 | .release = drm_release, | 120 | .release = drm_release, |
121 | .unlocked_ioctl = drm_ioctl, | 121 | .unlocked_ioctl = i830_ioctl, |
122 | .mmap = i830_mmap_buffers, | 122 | .mmap = i830_mmap_buffers, |
123 | .fasync = drm_fasync, | 123 | .fasync = drm_fasync, |
124 | }; | 124 | }; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9d67b4853030..c74e4e8006d4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1787,9 +1787,9 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
1787 | } | 1787 | } |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | div_u64(diff, diff1); | 1790 | diff = div_u64(diff, diff1); |
1791 | ret = ((m * diff) + c); | 1791 | ret = ((m * diff) + c); |
1792 | div_u64(ret, 10); | 1792 | ret = div_u64(ret, 10); |
1793 | 1793 | ||
1794 | dev_priv->last_count1 = total_count; | 1794 | dev_priv->last_count1 = total_count; |
1795 | dev_priv->last_time1 = now; | 1795 | dev_priv->last_time1 = now; |
@@ -1858,7 +1858,7 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) | |||
1858 | 1858 | ||
1859 | /* More magic constants... */ | 1859 | /* More magic constants... */ |
1860 | diff = diff * 1181; | 1860 | diff = diff * 1181; |
1861 | div_u64(diff, diffms * 10); | 1861 | diff = div_u64(diff, diffms * 10); |
1862 | dev_priv->gfx_power = diff; | 1862 | dev_priv->gfx_power = diff; |
1863 | } | 1863 | } |
1864 | 1864 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bced9b25c71e..90b1d6753b9d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -136,14 +136,12 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
136 | return -ENOMEM; | 136 | return -ENOMEM; |
137 | 137 | ||
138 | ret = drm_gem_handle_create(file_priv, obj, &handle); | 138 | ret = drm_gem_handle_create(file_priv, obj, &handle); |
139 | /* drop reference from allocate - handle holds it now */ | ||
140 | drm_gem_object_unreference_unlocked(obj); | ||
139 | if (ret) { | 141 | if (ret) { |
140 | drm_gem_object_unreference_unlocked(obj); | ||
141 | return ret; | 142 | return ret; |
142 | } | 143 | } |
143 | 144 | ||
144 | /* Sink the floating reference from kref_init(handlecount) */ | ||
145 | drm_gem_object_handle_unreference_unlocked(obj); | ||
146 | |||
147 | args->handle = handle; | 145 | args->handle = handle; |
148 | return 0; | 146 | return 0; |
149 | } | 147 | } |
@@ -471,14 +469,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
471 | return -ENOENT; | 469 | return -ENOENT; |
472 | obj_priv = to_intel_bo(obj); | 470 | obj_priv = to_intel_bo(obj); |
473 | 471 | ||
474 | /* Bounds check source. | 472 | /* Bounds check source. */ |
475 | * | 473 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
476 | * XXX: This could use review for overflow issues... | 474 | ret = -EINVAL; |
477 | */ | 475 | goto err; |
478 | if (args->offset > obj->size || args->size > obj->size || | 476 | } |
479 | args->offset + args->size > obj->size) { | 477 | |
480 | drm_gem_object_unreference_unlocked(obj); | 478 | if (!access_ok(VERIFY_WRITE, |
481 | return -EINVAL; | 479 | (char __user *)(uintptr_t)args->data_ptr, |
480 | args->size)) { | ||
481 | ret = -EFAULT; | ||
482 | goto err; | ||
482 | } | 483 | } |
483 | 484 | ||
484 | if (i915_gem_object_needs_bit17_swizzle(obj)) { | 485 | if (i915_gem_object_needs_bit17_swizzle(obj)) { |
@@ -490,8 +491,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
490 | file_priv); | 491 | file_priv); |
491 | } | 492 | } |
492 | 493 | ||
494 | err: | ||
493 | drm_gem_object_unreference_unlocked(obj); | 495 | drm_gem_object_unreference_unlocked(obj); |
494 | |||
495 | return ret; | 496 | return ret; |
496 | } | 497 | } |
497 | 498 | ||
@@ -580,8 +581,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, | |||
580 | 581 | ||
581 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 582 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
582 | remain = args->size; | 583 | remain = args->size; |
583 | if (!access_ok(VERIFY_READ, user_data, remain)) | ||
584 | return -EFAULT; | ||
585 | 584 | ||
586 | 585 | ||
587 | mutex_lock(&dev->struct_mutex); | 586 | mutex_lock(&dev->struct_mutex); |
@@ -934,14 +933,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
934 | return -ENOENT; | 933 | return -ENOENT; |
935 | obj_priv = to_intel_bo(obj); | 934 | obj_priv = to_intel_bo(obj); |
936 | 935 | ||
937 | /* Bounds check destination. | 936 | /* Bounds check destination. */ |
938 | * | 937 | if (args->offset > obj->size || args->size > obj->size - args->offset) { |
939 | * XXX: This could use review for overflow issues... | 938 | ret = -EINVAL; |
940 | */ | 939 | goto err; |
941 | if (args->offset > obj->size || args->size > obj->size || | 940 | } |
942 | args->offset + args->size > obj->size) { | 941 | |
943 | drm_gem_object_unreference_unlocked(obj); | 942 | if (!access_ok(VERIFY_READ, |
944 | return -EINVAL; | 943 | (char __user *)(uintptr_t)args->data_ptr, |
944 | args->size)) { | ||
945 | ret = -EFAULT; | ||
946 | goto err; | ||
945 | } | 947 | } |
946 | 948 | ||
947 | /* We can only do the GTT pwrite on untiled buffers, as otherwise | 949 | /* We can only do the GTT pwrite on untiled buffers, as otherwise |
@@ -975,8 +977,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
975 | DRM_INFO("pwrite failed %d\n", ret); | 977 | DRM_INFO("pwrite failed %d\n", ret); |
976 | #endif | 978 | #endif |
977 | 979 | ||
980 | err: | ||
978 | drm_gem_object_unreference_unlocked(obj); | 981 | drm_gem_object_unreference_unlocked(obj); |
979 | |||
980 | return ret; | 982 | return ret; |
981 | } | 983 | } |
982 | 984 | ||
@@ -3258,6 +3260,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, | |||
3258 | (int) reloc->offset, | 3260 | (int) reloc->offset, |
3259 | reloc->read_domains, | 3261 | reloc->read_domains, |
3260 | reloc->write_domain); | 3262 | reloc->write_domain); |
3263 | drm_gem_object_unreference(target_obj); | ||
3264 | i915_gem_object_unpin(obj); | ||
3261 | return -EINVAL; | 3265 | return -EINVAL; |
3262 | } | 3266 | } |
3263 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || | 3267 | if (reloc->write_domain & I915_GEM_DOMAIN_CPU || |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index e85246ef691c..5c428fa3e0b3 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -93,7 +93,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
93 | { | 93 | { |
94 | drm_i915_private_t *dev_priv = dev->dev_private; | 94 | drm_i915_private_t *dev_priv = dev->dev_private; |
95 | struct list_head eviction_list, unwind_list; | 95 | struct list_head eviction_list, unwind_list; |
96 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | 96 | struct drm_i915_gem_object *obj_priv; |
97 | struct list_head *render_iter, *bsd_iter; | 97 | struct list_head *render_iter, *bsd_iter; |
98 | int ret = 0; | 98 | int ret = 0; |
99 | 99 | ||
@@ -175,39 +175,34 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen | |||
175 | return -ENOSPC; | 175 | return -ENOSPC; |
176 | 176 | ||
177 | found: | 177 | found: |
178 | /* drm_mm doesn't allow any other other operations while | ||
179 | * scanning, therefore store to be evicted objects on a | ||
180 | * temporary list. */ | ||
178 | INIT_LIST_HEAD(&eviction_list); | 181 | INIT_LIST_HEAD(&eviction_list); |
179 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 182 | while (!list_empty(&unwind_list)) { |
180 | &unwind_list, evict_list) { | 183 | obj_priv = list_first_entry(&unwind_list, |
184 | struct drm_i915_gem_object, | ||
185 | evict_list); | ||
181 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | 186 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { |
182 | /* drm_mm doesn't allow any other other operations while | ||
183 | * scanning, therefore store to be evicted objects on a | ||
184 | * temporary list. */ | ||
185 | list_move(&obj_priv->evict_list, &eviction_list); | 187 | list_move(&obj_priv->evict_list, &eviction_list); |
186 | } else | 188 | continue; |
187 | drm_gem_object_unreference(&obj_priv->base); | 189 | } |
190 | list_del(&obj_priv->evict_list); | ||
191 | drm_gem_object_unreference(&obj_priv->base); | ||
188 | } | 192 | } |
189 | 193 | ||
190 | /* Unbinding will emit any required flushes */ | 194 | /* Unbinding will emit any required flushes */ |
191 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | 195 | while (!list_empty(&eviction_list)) { |
192 | &eviction_list, evict_list) { | 196 | obj_priv = list_first_entry(&eviction_list, |
193 | #if WATCH_LRU | 197 | struct drm_i915_gem_object, |
194 | DRM_INFO("%s: evicting %p\n", __func__, &obj_priv->base); | 198 | evict_list); |
195 | #endif | 199 | if (ret == 0) |
196 | ret = i915_gem_object_unbind(&obj_priv->base); | 200 | ret = i915_gem_object_unbind(&obj_priv->base); |
197 | if (ret) | 201 | list_del(&obj_priv->evict_list); |
198 | return ret; | ||
199 | |||
200 | drm_gem_object_unreference(&obj_priv->base); | 202 | drm_gem_object_unreference(&obj_priv->base); |
201 | } | 203 | } |
202 | 204 | ||
203 | /* The just created free hole should be on the top of the free stack | 205 | return ret; |
204 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
205 | * Furthermore all accessed data has just recently been used, so it | ||
206 | * should be really fast, too. */ | ||
207 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
208 | alignment, 0)); | ||
209 | |||
210 | return 0; | ||
211 | } | 206 | } |
212 | 207 | ||
213 | int | 208 | int |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b5bf51a4502d..979228594599 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1013,8 +1013,8 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1013 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | /** | 1016 | /* |
1017 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | 1017 | * intel_wait_for_pipe_off - wait for pipe to turn off |
1018 | * @dev: drm device | 1018 | * @dev: drm device |
1019 | * @pipe: pipe to wait for | 1019 | * @pipe: pipe to wait for |
1020 | * | 1020 | * |
@@ -1022,25 +1022,39 @@ void intel_wait_for_vblank(struct drm_device *dev, int pipe) | |||
1022 | * spinning on the vblank interrupt status bit, since we won't actually | 1022 | * spinning on the vblank interrupt status bit, since we won't actually |
1023 | * see an interrupt when the pipe is disabled. | 1023 | * see an interrupt when the pipe is disabled. |
1024 | * | 1024 | * |
1025 | * So this function waits for the display line value to settle (it | 1025 | * On Gen4 and above: |
1026 | * usually ends up stopping at the start of the next frame). | 1026 | * wait for the pipe register state bit to turn off |
1027 | * | ||
1028 | * Otherwise: | ||
1029 | * wait for the display line value to settle (it usually | ||
1030 | * ends up stopping at the start of the next frame). | ||
1031 | * | ||
1027 | */ | 1032 | */ |
1028 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | 1033 | static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) |
1029 | { | 1034 | { |
1030 | struct drm_i915_private *dev_priv = dev->dev_private; | 1035 | struct drm_i915_private *dev_priv = dev->dev_private; |
1031 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | 1036 | |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | 1037 | if (INTEL_INFO(dev)->gen >= 4) { |
1033 | u32 last_line; | 1038 | int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF); |
1034 | 1039 | ||
1035 | /* Wait for the display line to settle */ | 1040 | /* Wait for the Pipe State to go off */ |
1036 | do { | 1041 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, |
1037 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | 1042 | 100, 0)) |
1038 | mdelay(5); | 1043 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); |
1039 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | 1044 | } else { |
1040 | time_after(timeout, jiffies)); | 1045 | u32 last_line; |
1041 | 1046 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | |
1042 | if (time_after(jiffies, timeout)) | 1047 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1043 | DRM_DEBUG_KMS("vblank wait timed out\n"); | 1048 | |
1049 | /* Wait for the display line to settle */ | ||
1050 | do { | ||
1051 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1052 | mdelay(5); | ||
1053 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1054 | time_after(timeout, jiffies)); | ||
1055 | if (time_after(jiffies, timeout)) | ||
1056 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | ||
1057 | } | ||
1044 | } | 1058 | } |
1045 | 1059 | ||
1046 | /* Parameters have changed, update FBC info */ | 1060 | /* Parameters have changed, update FBC info */ |
@@ -2328,13 +2342,13 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2328 | I915_READ(dspbase_reg); | 2342 | I915_READ(dspbase_reg); |
2329 | } | 2343 | } |
2330 | 2344 | ||
2331 | /* Wait for vblank for the disable to take effect */ | ||
2332 | intel_wait_for_vblank_off(dev, pipe); | ||
2333 | |||
2334 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2345 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2335 | if (pipeconf_reg == PIPEACONF && | 2346 | if (pipeconf_reg == PIPEACONF && |
2336 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | 2347 | (dev_priv->quirks & QUIRK_PIPEA_FORCE)) { |
2348 | /* Wait for vblank for the disable to take effect */ | ||
2349 | intel_wait_for_vblank(dev, pipe); | ||
2337 | goto skip_pipe_off; | 2350 | goto skip_pipe_off; |
2351 | } | ||
2338 | 2352 | ||
2339 | /* Next, disable display pipes */ | 2353 | /* Next, disable display pipes */ |
2340 | temp = I915_READ(pipeconf_reg); | 2354 | temp = I915_READ(pipeconf_reg); |
@@ -2343,8 +2357,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2343 | I915_READ(pipeconf_reg); | 2357 | I915_READ(pipeconf_reg); |
2344 | } | 2358 | } |
2345 | 2359 | ||
2346 | /* Wait for vblank for the disable to take effect. */ | 2360 | /* Wait for the pipe to turn off */ |
2347 | intel_wait_for_vblank_off(dev, pipe); | 2361 | intel_wait_for_pipe_off(dev, pipe); |
2348 | 2362 | ||
2349 | temp = I915_READ(dpll_reg); | 2363 | temp = I915_READ(dpll_reg); |
2350 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2364 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1a51ee07de3e..9ab8708ac6ba 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1138,18 +1138,14 @@ static bool | |||
1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, | 1138 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1139 | uint32_t dp_reg_value, | 1139 | uint32_t dp_reg_value, |
1140 | uint8_t dp_train_pat, | 1140 | uint8_t dp_train_pat, |
1141 | uint8_t train_set[4], | 1141 | uint8_t train_set[4]) |
1142 | bool first) | ||
1143 | { | 1142 | { |
1144 | struct drm_device *dev = intel_dp->base.enc.dev; | 1143 | struct drm_device *dev = intel_dp->base.enc.dev; |
1145 | struct drm_i915_private *dev_priv = dev->dev_private; | 1144 | struct drm_i915_private *dev_priv = dev->dev_private; |
1146 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1147 | int ret; | 1145 | int ret; |
1148 | 1146 | ||
1149 | I915_WRITE(intel_dp->output_reg, dp_reg_value); | 1147 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1150 | POSTING_READ(intel_dp->output_reg); | 1148 | POSTING_READ(intel_dp->output_reg); |
1151 | if (first) | ||
1152 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1153 | 1149 | ||
1154 | intel_dp_aux_native_write_1(intel_dp, | 1150 | intel_dp_aux_native_write_1(intel_dp, |
1155 | DP_TRAINING_PATTERN_SET, | 1151 | DP_TRAINING_PATTERN_SET, |
@@ -1174,10 +1170,15 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1174 | uint8_t voltage; | 1170 | uint8_t voltage; |
1175 | bool clock_recovery = false; | 1171 | bool clock_recovery = false; |
1176 | bool channel_eq = false; | 1172 | bool channel_eq = false; |
1177 | bool first = true; | ||
1178 | int tries; | 1173 | int tries; |
1179 | u32 reg; | 1174 | u32 reg; |
1180 | uint32_t DP = intel_dp->DP; | 1175 | uint32_t DP = intel_dp->DP; |
1176 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); | ||
1177 | |||
1178 | /* Enable output, wait for it to become active */ | ||
1179 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
1180 | POSTING_READ(intel_dp->output_reg); | ||
1181 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
1181 | 1182 | ||
1182 | /* Write the link configuration data */ | 1183 | /* Write the link configuration data */ |
1183 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, | 1184 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
@@ -1210,9 +1211,8 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1210 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1211 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1211 | 1212 | ||
1212 | if (!intel_dp_set_link_train(intel_dp, reg, | 1213 | if (!intel_dp_set_link_train(intel_dp, reg, |
1213 | DP_TRAINING_PATTERN_1, train_set, first)) | 1214 | DP_TRAINING_PATTERN_1, train_set)) |
1214 | break; | 1215 | break; |
1215 | first = false; | ||
1216 | /* Set training pattern 1 */ | 1216 | /* Set training pattern 1 */ |
1217 | 1217 | ||
1218 | udelay(100); | 1218 | udelay(100); |
@@ -1266,8 +1266,7 @@ intel_dp_link_train(struct intel_dp *intel_dp) | |||
1266 | 1266 | ||
1267 | /* channel eq pattern */ | 1267 | /* channel eq pattern */ |
1268 | if (!intel_dp_set_link_train(intel_dp, reg, | 1268 | if (!intel_dp_set_link_train(intel_dp, reg, |
1269 | DP_TRAINING_PATTERN_2, train_set, | 1269 | DP_TRAINING_PATTERN_2, train_set)) |
1270 | false)) | ||
1271 | break; | 1270 | break; |
1272 | 1271 | ||
1273 | udelay(400); | 1272 | udelay(400); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ad312ca6b3e5..8828b3ac6414 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -229,7 +229,6 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
229 | struct drm_crtc *crtc); | 229 | struct drm_crtc *crtc); |
230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 230 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
231 | struct drm_file *file_priv); | 231 | struct drm_file *file_priv); |
232 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); | ||
233 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | 232 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); |
234 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 233 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
235 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 234 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7bdc96256bf5..56ad9df2ccb5 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -237,8 +237,10 @@ int intel_fbdev_destroy(struct drm_device *dev, | |||
237 | drm_fb_helper_fini(&ifbdev->helper); | 237 | drm_fb_helper_fini(&ifbdev->helper); |
238 | 238 | ||
239 | drm_framebuffer_cleanup(&ifb->base); | 239 | drm_framebuffer_cleanup(&ifb->base); |
240 | if (ifb->obj) | 240 | if (ifb->obj) { |
241 | drm_gem_object_handle_unreference(ifb->obj); | ||
241 | drm_gem_object_unreference(ifb->obj); | 242 | drm_gem_object_unreference(ifb->obj); |
243 | } | ||
242 | 244 | ||
243 | return 0; | 245 | return 0; |
244 | } | 246 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index dbd30b2e43fd..d2047713dc59 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -352,6 +352,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *nfbdev) | |||
352 | 352 | ||
353 | if (nouveau_fb->nvbo) { | 353 | if (nouveau_fb->nvbo) { |
354 | nouveau_bo_unmap(nouveau_fb->nvbo); | 354 | nouveau_bo_unmap(nouveau_fb->nvbo); |
355 | drm_gem_object_handle_unreference_unlocked(nouveau_fb->nvbo->gem); | ||
355 | drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); | 356 | drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); |
356 | nouveau_fb->nvbo = NULL; | 357 | nouveau_fb->nvbo = NULL; |
357 | } | 358 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index ead7b8fc53fc..19620a6709f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -167,11 +167,9 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, | |||
167 | goto out; | 167 | goto out; |
168 | 168 | ||
169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); | 169 | ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); |
170 | /* drop reference from allocate - handle holds it now */ | ||
171 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
170 | out: | 172 | out: |
171 | drm_gem_object_handle_unreference_unlocked(nvbo->gem); | ||
172 | |||
173 | if (ret) | ||
174 | drm_gem_object_unreference_unlocked(nvbo->gem); | ||
175 | return ret; | 173 | return ret; |
176 | } | 174 | } |
177 | 175 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 3ec181ff50ce..3c9964a8fbad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -79,6 +79,7 @@ nouveau_notifier_takedown_channel(struct nouveau_channel *chan) | |||
79 | mutex_lock(&dev->struct_mutex); | 79 | mutex_lock(&dev->struct_mutex); |
80 | nouveau_bo_unpin(chan->notifier_bo); | 80 | nouveau_bo_unpin(chan->notifier_bo); |
81 | mutex_unlock(&dev->struct_mutex); | 81 | mutex_unlock(&dev->struct_mutex); |
82 | drm_gem_object_handle_unreference_unlocked(chan->notifier_bo->gem); | ||
82 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); | 83 | drm_gem_object_unreference_unlocked(chan->notifier_bo->gem); |
83 | drm_mm_takedown(&chan->notifier_heap); | 84 | drm_mm_takedown(&chan->notifier_heap); |
84 | } | 85 | } |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ddc3adea1dda..7a04959ba0ee 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3528,7 +3528,8 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3528 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3528 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3529 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
3530 | */ | 3530 | */ |
3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 3531 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3532 | rdev->vram_scratch.ptr) { | ||
3532 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3533 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3533 | u32 tmp; | 3534 | u32 tmp; |
3534 | 3535 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index ebae14c4b768..68932ba7b8a4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -317,6 +317,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
317 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 317 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
318 | } | 318 | } |
319 | 319 | ||
320 | /* MSI K9A2GM V2/V3 board has no HDMI or DVI */ | ||
321 | if ((dev->pdev->device == 0x796e) && | ||
322 | (dev->pdev->subsystem_vendor == 0x1462) && | ||
323 | (dev->pdev->subsystem_device == 0x7302)) { | ||
324 | if ((supported_device == ATOM_DEVICE_DFP2_SUPPORT) || | ||
325 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
326 | return false; | ||
327 | } | ||
328 | |||
320 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 329 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
321 | if ((dev->pdev->device == 0x7941) && | 330 | if ((dev->pdev->device == 0x7941) && |
322 | (dev->pdev->subsystem_vendor == 0x147b) && | 331 | (dev->pdev->subsystem_vendor == 0x147b) && |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 127a395f70fb..b92d2f2fcbed 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -349,6 +349,8 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); | 349 | DRM_INFO(" DFP4: %s\n", encoder_names[radeon_encoder->encoder_id]); |
350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) | 350 | if (devices & ATOM_DEVICE_DFP5_SUPPORT) |
351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); | 351 | DRM_INFO(" DFP5: %s\n", encoder_names[radeon_encoder->encoder_id]); |
352 | if (devices & ATOM_DEVICE_DFP6_SUPPORT) | ||
353 | DRM_INFO(" DFP6: %s\n", encoder_names[radeon_encoder->encoder_id]); | ||
352 | if (devices & ATOM_DEVICE_TV1_SUPPORT) | 354 | if (devices & ATOM_DEVICE_TV1_SUPPORT) |
353 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); | 355 | DRM_INFO(" TV1: %s\n", encoder_names[radeon_encoder->encoder_id]); |
354 | if (devices & ATOM_DEVICE_CV_SUPPORT) | 356 | if (devices & ATOM_DEVICE_CV_SUPPORT) |
@@ -841,8 +843,9 @@ static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) | |||
841 | { | 843 | { |
842 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); | 844 | struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); |
843 | 845 | ||
844 | if (radeon_fb->obj) | 846 | if (radeon_fb->obj) { |
845 | drm_gem_object_unreference_unlocked(radeon_fb->obj); | 847 | drm_gem_object_unreference_unlocked(radeon_fb->obj); |
848 | } | ||
846 | drm_framebuffer_cleanup(fb); | 849 | drm_framebuffer_cleanup(fb); |
847 | kfree(radeon_fb); | 850 | kfree(radeon_fb); |
848 | } | 851 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index c74a8b20d941..9cdf6a35bc2c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -94,8 +94,10 @@ static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) | |||
94 | ret = radeon_bo_reserve(rbo, false); | 94 | ret = radeon_bo_reserve(rbo, false); |
95 | if (likely(ret == 0)) { | 95 | if (likely(ret == 0)) { |
96 | radeon_bo_kunmap(rbo); | 96 | radeon_bo_kunmap(rbo); |
97 | radeon_bo_unpin(rbo); | ||
97 | radeon_bo_unreserve(rbo); | 98 | radeon_bo_unreserve(rbo); |
98 | } | 99 | } |
100 | drm_gem_object_handle_unreference(gobj); | ||
99 | drm_gem_object_unreference_unlocked(gobj); | 101 | drm_gem_object_unreference_unlocked(gobj); |
100 | } | 102 | } |
101 | 103 | ||
@@ -325,8 +327,6 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
325 | { | 327 | { |
326 | struct fb_info *info; | 328 | struct fb_info *info; |
327 | struct radeon_framebuffer *rfb = &rfbdev->rfb; | 329 | struct radeon_framebuffer *rfb = &rfbdev->rfb; |
328 | struct radeon_bo *rbo; | ||
329 | int r; | ||
330 | 330 | ||
331 | if (rfbdev->helper.fbdev) { | 331 | if (rfbdev->helper.fbdev) { |
332 | info = rfbdev->helper.fbdev; | 332 | info = rfbdev->helper.fbdev; |
@@ -338,14 +338,8 @@ static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfb | |||
338 | } | 338 | } |
339 | 339 | ||
340 | if (rfb->obj) { | 340 | if (rfb->obj) { |
341 | rbo = rfb->obj->driver_private; | 341 | radeonfb_destroy_pinned_object(rfb->obj); |
342 | r = radeon_bo_reserve(rbo, false); | 342 | rfb->obj = NULL; |
343 | if (likely(r == 0)) { | ||
344 | radeon_bo_kunmap(rbo); | ||
345 | radeon_bo_unpin(rbo); | ||
346 | radeon_bo_unreserve(rbo); | ||
347 | } | ||
348 | drm_gem_object_unreference_unlocked(rfb->obj); | ||
349 | } | 343 | } |
350 | drm_fb_helper_fini(&rfbdev->helper); | 344 | drm_fb_helper_fini(&rfbdev->helper); |
351 | drm_framebuffer_cleanup(&rfb->base); | 345 | drm_framebuffer_cleanup(&rfb->base); |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index c578f265b24c..d1e595d91723 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -201,11 +201,11 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, | |||
201 | return r; | 201 | return r; |
202 | } | 202 | } |
203 | r = drm_gem_handle_create(filp, gobj, &handle); | 203 | r = drm_gem_handle_create(filp, gobj, &handle); |
204 | /* drop reference from allocate - handle holds it now */ | ||
205 | drm_gem_object_unreference_unlocked(gobj); | ||
204 | if (r) { | 206 | if (r) { |
205 | drm_gem_object_unreference_unlocked(gobj); | ||
206 | return r; | 207 | return r; |
207 | } | 208 | } |
208 | drm_gem_object_handle_unreference_unlocked(gobj); | ||
209 | args->handle = handle; | 209 | args->handle = handle; |
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 72ec2e2b6e97..a96ed6d9d010 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -148,13 +148,16 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
148 | {0, 0, 0} | 148 | {0, 0, 0} |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static char *vmw_devname = "vmwgfx"; | 151 | static int enable_fbdev; |
152 | 152 | ||
153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 153 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
154 | static void vmw_master_init(struct vmw_master *); | 154 | static void vmw_master_init(struct vmw_master *); |
155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, | 155 | static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, |
156 | void *ptr); | 156 | void *ptr); |
157 | 157 | ||
158 | MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); | ||
159 | module_param_named(enable_fbdev, enable_fbdev, int, 0600); | ||
160 | |||
158 | static void vmw_print_capabilities(uint32_t capabilities) | 161 | static void vmw_print_capabilities(uint32_t capabilities) |
159 | { | 162 | { |
160 | DRM_INFO("Capabilities:\n"); | 163 | DRM_INFO("Capabilities:\n"); |
@@ -192,8 +195,6 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
192 | { | 195 | { |
193 | int ret; | 196 | int ret; |
194 | 197 | ||
195 | vmw_kms_save_vga(dev_priv); | ||
196 | |||
197 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); | 198 | ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); |
198 | if (unlikely(ret != 0)) { | 199 | if (unlikely(ret != 0)) { |
199 | DRM_ERROR("Unable to initialize FIFO.\n"); | 200 | DRM_ERROR("Unable to initialize FIFO.\n"); |
@@ -206,9 +207,35 @@ static int vmw_request_device(struct vmw_private *dev_priv) | |||
206 | static void vmw_release_device(struct vmw_private *dev_priv) | 207 | static void vmw_release_device(struct vmw_private *dev_priv) |
207 | { | 208 | { |
208 | vmw_fifo_release(dev_priv, &dev_priv->fifo); | 209 | vmw_fifo_release(dev_priv, &dev_priv->fifo); |
209 | vmw_kms_restore_vga(dev_priv); | ||
210 | } | 210 | } |
211 | 211 | ||
212 | int vmw_3d_resource_inc(struct vmw_private *dev_priv) | ||
213 | { | ||
214 | int ret = 0; | ||
215 | |||
216 | mutex_lock(&dev_priv->release_mutex); | ||
217 | if (unlikely(dev_priv->num_3d_resources++ == 0)) { | ||
218 | ret = vmw_request_device(dev_priv); | ||
219 | if (unlikely(ret != 0)) | ||
220 | --dev_priv->num_3d_resources; | ||
221 | } | ||
222 | mutex_unlock(&dev_priv->release_mutex); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | |||
227 | void vmw_3d_resource_dec(struct vmw_private *dev_priv) | ||
228 | { | ||
229 | int32_t n3d; | ||
230 | |||
231 | mutex_lock(&dev_priv->release_mutex); | ||
232 | if (unlikely(--dev_priv->num_3d_resources == 0)) | ||
233 | vmw_release_device(dev_priv); | ||
234 | n3d = (int32_t) dev_priv->num_3d_resources; | ||
235 | mutex_unlock(&dev_priv->release_mutex); | ||
236 | |||
237 | BUG_ON(n3d < 0); | ||
238 | } | ||
212 | 239 | ||
213 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | 240 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
214 | { | 241 | { |
@@ -228,6 +255,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
228 | dev_priv->last_read_sequence = (uint32_t) -100; | 255 | dev_priv->last_read_sequence = (uint32_t) -100; |
229 | mutex_init(&dev_priv->hw_mutex); | 256 | mutex_init(&dev_priv->hw_mutex); |
230 | mutex_init(&dev_priv->cmdbuf_mutex); | 257 | mutex_init(&dev_priv->cmdbuf_mutex); |
258 | mutex_init(&dev_priv->release_mutex); | ||
231 | rwlock_init(&dev_priv->resource_lock); | 259 | rwlock_init(&dev_priv->resource_lock); |
232 | idr_init(&dev_priv->context_idr); | 260 | idr_init(&dev_priv->context_idr); |
233 | idr_init(&dev_priv->surface_idr); | 261 | idr_init(&dev_priv->surface_idr); |
@@ -244,6 +272,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
244 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); | 272 | dev_priv->vram_start = pci_resource_start(dev->pdev, 1); |
245 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); | 273 | dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); |
246 | 274 | ||
275 | dev_priv->enable_fb = enable_fbdev; | ||
276 | |||
247 | mutex_lock(&dev_priv->hw_mutex); | 277 | mutex_lock(&dev_priv->hw_mutex); |
248 | 278 | ||
249 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 279 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
@@ -343,17 +373,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
343 | 373 | ||
344 | dev->dev_private = dev_priv; | 374 | dev->dev_private = dev_priv; |
345 | 375 | ||
346 | if (!dev->devname) | ||
347 | dev->devname = vmw_devname; | ||
348 | |||
349 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
350 | ret = drm_irq_install(dev); | ||
351 | if (unlikely(ret != 0)) { | ||
352 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
353 | goto out_no_irq; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); | 376 | ret = pci_request_regions(dev->pdev, "vmwgfx probe"); |
358 | dev_priv->stealth = (ret != 0); | 377 | dev_priv->stealth = (ret != 0); |
359 | if (dev_priv->stealth) { | 378 | if (dev_priv->stealth) { |
@@ -369,26 +388,52 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
369 | goto out_no_device; | 388 | goto out_no_device; |
370 | } | 389 | } |
371 | } | 390 | } |
372 | ret = vmw_request_device(dev_priv); | 391 | ret = vmw_kms_init(dev_priv); |
373 | if (unlikely(ret != 0)) | 392 | if (unlikely(ret != 0)) |
374 | goto out_no_device; | 393 | goto out_no_kms; |
375 | vmw_kms_init(dev_priv); | ||
376 | vmw_overlay_init(dev_priv); | 394 | vmw_overlay_init(dev_priv); |
377 | vmw_fb_init(dev_priv); | 395 | if (dev_priv->enable_fb) { |
396 | ret = vmw_3d_resource_inc(dev_priv); | ||
397 | if (unlikely(ret != 0)) | ||
398 | goto out_no_fifo; | ||
399 | vmw_kms_save_vga(dev_priv); | ||
400 | vmw_fb_init(dev_priv); | ||
401 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? | ||
402 | "Detected device 3D availability.\n" : | ||
403 | "Detected no device 3D availability.\n"); | ||
404 | } else { | ||
405 | DRM_INFO("Delayed 3D detection since we're not " | ||
406 | "running the device in SVGA mode yet.\n"); | ||
407 | } | ||
408 | |||
409 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { | ||
410 | ret = drm_irq_install(dev); | ||
411 | if (unlikely(ret != 0)) { | ||
412 | DRM_ERROR("Failed installing irq: %d\n", ret); | ||
413 | goto out_no_irq; | ||
414 | } | ||
415 | } | ||
378 | 416 | ||
379 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 417 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
380 | register_pm_notifier(&dev_priv->pm_nb); | 418 | register_pm_notifier(&dev_priv->pm_nb); |
381 | 419 | ||
382 | DRM_INFO("%s", vmw_fifo_have_3d(dev_priv) ? "Have 3D\n" : "No 3D\n"); | ||
383 | |||
384 | return 0; | 420 | return 0; |
385 | 421 | ||
386 | out_no_device: | ||
387 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
388 | drm_irq_uninstall(dev_priv->dev); | ||
389 | if (dev->devname == vmw_devname) | ||
390 | dev->devname = NULL; | ||
391 | out_no_irq: | 422 | out_no_irq: |
423 | if (dev_priv->enable_fb) { | ||
424 | vmw_fb_close(dev_priv); | ||
425 | vmw_kms_restore_vga(dev_priv); | ||
426 | vmw_3d_resource_dec(dev_priv); | ||
427 | } | ||
428 | out_no_fifo: | ||
429 | vmw_overlay_close(dev_priv); | ||
430 | vmw_kms_close(dev_priv); | ||
431 | out_no_kms: | ||
432 | if (dev_priv->stealth) | ||
433 | pci_release_region(dev->pdev, 2); | ||
434 | else | ||
435 | pci_release_regions(dev->pdev); | ||
436 | out_no_device: | ||
392 | ttm_object_device_release(&dev_priv->tdev); | 437 | ttm_object_device_release(&dev_priv->tdev); |
393 | out_err4: | 438 | out_err4: |
394 | iounmap(dev_priv->mmio_virt); | 439 | iounmap(dev_priv->mmio_virt); |
@@ -415,19 +460,20 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
415 | 460 | ||
416 | unregister_pm_notifier(&dev_priv->pm_nb); | 461 | unregister_pm_notifier(&dev_priv->pm_nb); |
417 | 462 | ||
418 | vmw_fb_close(dev_priv); | 463 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
464 | drm_irq_uninstall(dev_priv->dev); | ||
465 | if (dev_priv->enable_fb) { | ||
466 | vmw_fb_close(dev_priv); | ||
467 | vmw_kms_restore_vga(dev_priv); | ||
468 | vmw_3d_resource_dec(dev_priv); | ||
469 | } | ||
419 | vmw_kms_close(dev_priv); | 470 | vmw_kms_close(dev_priv); |
420 | vmw_overlay_close(dev_priv); | 471 | vmw_overlay_close(dev_priv); |
421 | vmw_release_device(dev_priv); | ||
422 | if (dev_priv->stealth) | 472 | if (dev_priv->stealth) |
423 | pci_release_region(dev->pdev, 2); | 473 | pci_release_region(dev->pdev, 2); |
424 | else | 474 | else |
425 | pci_release_regions(dev->pdev); | 475 | pci_release_regions(dev->pdev); |
426 | 476 | ||
427 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | ||
428 | drm_irq_uninstall(dev_priv->dev); | ||
429 | if (dev->devname == vmw_devname) | ||
430 | dev->devname = NULL; | ||
431 | ttm_object_device_release(&dev_priv->tdev); | 477 | ttm_object_device_release(&dev_priv->tdev); |
432 | iounmap(dev_priv->mmio_virt); | 478 | iounmap(dev_priv->mmio_virt); |
433 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, | 479 | drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, |
@@ -500,7 +546,7 @@ static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
500 | struct drm_ioctl_desc *ioctl = | 546 | struct drm_ioctl_desc *ioctl = |
501 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; | 547 | &vmw_ioctls[nr - DRM_COMMAND_BASE]; |
502 | 548 | ||
503 | if (unlikely(ioctl->cmd != cmd)) { | 549 | if (unlikely(ioctl->cmd_drv != cmd)) { |
504 | DRM_ERROR("Invalid command format, ioctl %d\n", | 550 | DRM_ERROR("Invalid command format, ioctl %d\n", |
505 | nr - DRM_COMMAND_BASE); | 551 | nr - DRM_COMMAND_BASE); |
506 | return -EINVAL; | 552 | return -EINVAL; |
@@ -589,6 +635,16 @@ static int vmw_master_set(struct drm_device *dev, | |||
589 | struct vmw_master *vmaster = vmw_master(file_priv->master); | 635 | struct vmw_master *vmaster = vmw_master(file_priv->master); |
590 | int ret = 0; | 636 | int ret = 0; |
591 | 637 | ||
638 | if (!dev_priv->enable_fb) { | ||
639 | ret = vmw_3d_resource_inc(dev_priv); | ||
640 | if (unlikely(ret != 0)) | ||
641 | return ret; | ||
642 | vmw_kms_save_vga(dev_priv); | ||
643 | mutex_lock(&dev_priv->hw_mutex); | ||
644 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | ||
645 | mutex_unlock(&dev_priv->hw_mutex); | ||
646 | } | ||
647 | |||
592 | if (active) { | 648 | if (active) { |
593 | BUG_ON(active != &dev_priv->fbdev_master); | 649 | BUG_ON(active != &dev_priv->fbdev_master); |
594 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); | 650 | ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); |
@@ -617,7 +673,13 @@ static int vmw_master_set(struct drm_device *dev, | |||
617 | return 0; | 673 | return 0; |
618 | 674 | ||
619 | out_no_active_lock: | 675 | out_no_active_lock: |
620 | vmw_release_device(dev_priv); | 676 | if (!dev_priv->enable_fb) { |
677 | mutex_lock(&dev_priv->hw_mutex); | ||
678 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
679 | mutex_unlock(&dev_priv->hw_mutex); | ||
680 | vmw_kms_restore_vga(dev_priv); | ||
681 | vmw_3d_resource_dec(dev_priv); | ||
682 | } | ||
621 | return ret; | 683 | return ret; |
622 | } | 684 | } |
623 | 685 | ||
@@ -645,11 +707,23 @@ static void vmw_master_drop(struct drm_device *dev, | |||
645 | 707 | ||
646 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 708 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
647 | 709 | ||
710 | if (!dev_priv->enable_fb) { | ||
711 | ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); | ||
712 | if (unlikely(ret != 0)) | ||
713 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | ||
714 | mutex_lock(&dev_priv->hw_mutex); | ||
715 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | ||
716 | mutex_unlock(&dev_priv->hw_mutex); | ||
717 | vmw_kms_restore_vga(dev_priv); | ||
718 | vmw_3d_resource_dec(dev_priv); | ||
719 | } | ||
720 | |||
648 | dev_priv->active_master = &dev_priv->fbdev_master; | 721 | dev_priv->active_master = &dev_priv->fbdev_master; |
649 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 722 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
650 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 723 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
651 | 724 | ||
652 | vmw_fb_on(dev_priv); | 725 | if (dev_priv->enable_fb) |
726 | vmw_fb_on(dev_priv); | ||
653 | } | 727 | } |
654 | 728 | ||
655 | 729 | ||
@@ -722,6 +796,7 @@ static struct drm_driver driver = { | |||
722 | .irq_postinstall = vmw_irq_postinstall, | 796 | .irq_postinstall = vmw_irq_postinstall, |
723 | .irq_uninstall = vmw_irq_uninstall, | 797 | .irq_uninstall = vmw_irq_uninstall, |
724 | .irq_handler = vmw_irq_handler, | 798 | .irq_handler = vmw_irq_handler, |
799 | .get_vblank_counter = vmw_get_vblank_counter, | ||
725 | .reclaim_buffers_locked = NULL, | 800 | .reclaim_buffers_locked = NULL, |
726 | .get_map_ofs = drm_core_get_map_ofs, | 801 | .get_map_ofs = drm_core_get_map_ofs, |
727 | .get_reg_ofs = drm_core_get_reg_ofs, | 802 | .get_reg_ofs = drm_core_get_reg_ofs, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 429f917b60bf..58de6393f611 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -277,6 +277,7 @@ struct vmw_private { | |||
277 | 277 | ||
278 | bool stealth; | 278 | bool stealth; |
279 | bool is_opened; | 279 | bool is_opened; |
280 | bool enable_fb; | ||
280 | 281 | ||
281 | /** | 282 | /** |
282 | * Master management. | 283 | * Master management. |
@@ -285,6 +286,9 @@ struct vmw_private { | |||
285 | struct vmw_master *active_master; | 286 | struct vmw_master *active_master; |
286 | struct vmw_master fbdev_master; | 287 | struct vmw_master fbdev_master; |
287 | struct notifier_block pm_nb; | 288 | struct notifier_block pm_nb; |
289 | |||
290 | struct mutex release_mutex; | ||
291 | uint32_t num_3d_resources; | ||
288 | }; | 292 | }; |
289 | 293 | ||
290 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) | 294 | static inline struct vmw_private *vmw_priv(struct drm_device *dev) |
@@ -319,6 +323,9 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, | |||
319 | return val; | 323 | return val; |
320 | } | 324 | } |
321 | 325 | ||
326 | int vmw_3d_resource_inc(struct vmw_private *dev_priv); | ||
327 | void vmw_3d_resource_dec(struct vmw_private *dev_priv); | ||
328 | |||
322 | /** | 329 | /** |
323 | * GMR utilities - vmwgfx_gmr.c | 330 | * GMR utilities - vmwgfx_gmr.c |
324 | */ | 331 | */ |
@@ -511,6 +518,7 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
511 | unsigned bbp, unsigned depth); | 518 | unsigned bbp, unsigned depth); |
512 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 519 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
513 | struct drm_file *file_priv); | 520 | struct drm_file *file_priv); |
521 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc); | ||
514 | 522 | ||
515 | /** | 523 | /** |
516 | * Overlay control - vmwgfx_overlay.c | 524 | * Overlay control - vmwgfx_overlay.c |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 870967a97c15..409e172f4abf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -615,6 +615,11 @@ int vmw_dmabuf_to_start_of_vram(struct vmw_private *vmw_priv, | |||
615 | if (unlikely(ret != 0)) | 615 | if (unlikely(ret != 0)) |
616 | goto err_unlock; | 616 | goto err_unlock; |
617 | 617 | ||
618 | if (bo->mem.mem_type == TTM_PL_VRAM && | ||
619 | bo->mem.mm_node->start < bo->num_pages) | ||
620 | (void) ttm_bo_validate(bo, &vmw_sys_placement, false, | ||
621 | false, false); | ||
622 | |||
618 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); | 623 | ret = ttm_bo_validate(bo, &ne_placement, false, false, false); |
619 | 624 | ||
620 | /* Could probably bug on */ | 625 | /* Could probably bug on */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index e6a1eb7ea954..0fe31766e4cf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -106,6 +106,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
106 | mutex_lock(&dev_priv->hw_mutex); | 106 | mutex_lock(&dev_priv->hw_mutex); |
107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 107 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 108 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
109 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | ||
109 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); | 110 | vmw_write(dev_priv, SVGA_REG_ENABLE, 1); |
110 | 111 | ||
111 | min = 4; | 112 | min = 4; |
@@ -175,6 +176,8 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
175 | dev_priv->config_done_state); | 176 | dev_priv->config_done_state); |
176 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 177 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
177 | dev_priv->enable_state); | 178 | dev_priv->enable_state); |
179 | vmw_write(dev_priv, SVGA_REG_TRACES, | ||
180 | dev_priv->traces_state); | ||
178 | 181 | ||
179 | mutex_unlock(&dev_priv->hw_mutex); | 182 | mutex_unlock(&dev_priv->hw_mutex); |
180 | vmw_fence_queue_takedown(&fifo->fence_queue); | 183 | vmw_fence_queue_takedown(&fifo->fence_queue); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 64d7f47df868..e882ba099f0c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -898,7 +898,19 @@ int vmw_kms_save_vga(struct vmw_private *vmw_priv) | |||
898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); | 898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); |
899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); | 899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); |
900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | 900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); |
901 | if (i == 0 && vmw_priv->num_displays == 1 && | ||
902 | save->width == 0 && save->height == 0) { | ||
903 | |||
904 | /* | ||
905 | * It should be fairly safe to assume that these | ||
906 | * values are uninitialized. | ||
907 | */ | ||
908 | |||
909 | save->width = vmw_priv->vga_width - save->pos_x; | ||
910 | save->height = vmw_priv->vga_height - save->pos_y; | ||
911 | } | ||
901 | } | 912 | } |
913 | |||
902 | return 0; | 914 | return 0; |
903 | } | 915 | } |
904 | 916 | ||
@@ -984,3 +996,8 @@ out_unlock: | |||
984 | ttm_read_unlock(&vmaster->lock); | 996 | ttm_read_unlock(&vmaster->lock); |
985 | return ret; | 997 | return ret; |
986 | } | 998 | } |
999 | |||
1000 | u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc) | ||
1001 | { | ||
1002 | return 0; | ||
1003 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 7083b1a24df3..11cb39e3accb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include "vmwgfx_kms.h" | 28 | #include "vmwgfx_kms.h" |
29 | 29 | ||
30 | #define VMWGFX_LDU_NUM_DU 8 | ||
31 | |||
30 | #define vmw_crtc_to_ldu(x) \ | 32 | #define vmw_crtc_to_ldu(x) \ |
31 | container_of(x, struct vmw_legacy_display_unit, base.crtc) | 33 | container_of(x, struct vmw_legacy_display_unit, base.crtc) |
32 | #define vmw_encoder_to_ldu(x) \ | 34 | #define vmw_encoder_to_ldu(x) \ |
@@ -536,6 +538,10 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
536 | 538 | ||
537 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | 539 | int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) |
538 | { | 540 | { |
541 | struct drm_device *dev = dev_priv->dev; | ||
542 | int i; | ||
543 | int ret; | ||
544 | |||
539 | if (dev_priv->ldu_priv) { | 545 | if (dev_priv->ldu_priv) { |
540 | DRM_INFO("ldu system already on\n"); | 546 | DRM_INFO("ldu system already on\n"); |
541 | return -EINVAL; | 547 | return -EINVAL; |
@@ -553,23 +559,24 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv) | |||
553 | 559 | ||
554 | drm_mode_create_dirty_info_property(dev_priv->dev); | 560 | drm_mode_create_dirty_info_property(dev_priv->dev); |
555 | 561 | ||
556 | vmw_ldu_init(dev_priv, 0); | ||
557 | /* for old hardware without multimon only enable one display */ | ||
558 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { | 562 | if (dev_priv->capabilities & SVGA_CAP_MULTIMON) { |
559 | vmw_ldu_init(dev_priv, 1); | 563 | for (i = 0; i < VMWGFX_LDU_NUM_DU; ++i) |
560 | vmw_ldu_init(dev_priv, 2); | 564 | vmw_ldu_init(dev_priv, i); |
561 | vmw_ldu_init(dev_priv, 3); | 565 | ret = drm_vblank_init(dev, VMWGFX_LDU_NUM_DU); |
562 | vmw_ldu_init(dev_priv, 4); | 566 | } else { |
563 | vmw_ldu_init(dev_priv, 5); | 567 | /* for old hardware without multimon only enable one display */ |
564 | vmw_ldu_init(dev_priv, 6); | 568 | vmw_ldu_init(dev_priv, 0); |
565 | vmw_ldu_init(dev_priv, 7); | 569 | ret = drm_vblank_init(dev, 1); |
566 | } | 570 | } |
567 | 571 | ||
568 | return 0; | 572 | return ret; |
569 | } | 573 | } |
570 | 574 | ||
571 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) | 575 | int vmw_kms_close_legacy_display_system(struct vmw_private *dev_priv) |
572 | { | 576 | { |
577 | struct drm_device *dev = dev_priv->dev; | ||
578 | |||
579 | drm_vblank_cleanup(dev); | ||
573 | if (!dev_priv->ldu_priv) | 580 | if (!dev_priv->ldu_priv) |
574 | return -ENOSYS; | 581 | return -ENOSYS; |
575 | 582 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 5f2d5df01e5c..c8c40e9979db 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -211,6 +211,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
211 | cmd->body.cid = cpu_to_le32(res->id); | 211 | cmd->body.cid = cpu_to_le32(res->id); |
212 | 212 | ||
213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 213 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
214 | vmw_3d_resource_dec(dev_priv); | ||
214 | } | 215 | } |
215 | 216 | ||
216 | static int vmw_context_init(struct vmw_private *dev_priv, | 217 | static int vmw_context_init(struct vmw_private *dev_priv, |
@@ -247,6 +248,7 @@ static int vmw_context_init(struct vmw_private *dev_priv, | |||
247 | cmd->body.cid = cpu_to_le32(res->id); | 248 | cmd->body.cid = cpu_to_le32(res->id); |
248 | 249 | ||
249 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 250 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
251 | (void) vmw_3d_resource_inc(dev_priv); | ||
250 | vmw_resource_activate(res, vmw_hw_context_destroy); | 252 | vmw_resource_activate(res, vmw_hw_context_destroy); |
251 | return 0; | 253 | return 0; |
252 | } | 254 | } |
@@ -406,6 +408,7 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res) | |||
406 | cmd->body.sid = cpu_to_le32(res->id); | 408 | cmd->body.sid = cpu_to_le32(res->id); |
407 | 409 | ||
408 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 410 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
411 | vmw_3d_resource_dec(dev_priv); | ||
409 | } | 412 | } |
410 | 413 | ||
411 | void vmw_surface_res_free(struct vmw_resource *res) | 414 | void vmw_surface_res_free(struct vmw_resource *res) |
@@ -473,6 +476,7 @@ int vmw_surface_init(struct vmw_private *dev_priv, | |||
473 | } | 476 | } |
474 | 477 | ||
475 | vmw_fifo_commit(dev_priv, submit_size); | 478 | vmw_fifo_commit(dev_priv, submit_size); |
479 | (void) vmw_3d_resource_inc(dev_priv); | ||
476 | vmw_resource_activate(res, vmw_hw_surface_destroy); | 480 | vmw_resource_activate(res, vmw_hw_surface_destroy); |
477 | return 0; | 481 | return 0; |
478 | } | 482 | } |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b9..75afb3b0e076 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; | |||
111 | /* Super-I/O Function prototypes */ | 111 | /* Super-I/O Function prototypes */ |
112 | static inline int superio_inb(int base, int reg); | 112 | static inline int superio_inb(int base, int reg); |
113 | static inline int superio_inw(int base, int reg); | 113 | static inline int superio_inw(int base, int reg); |
114 | static inline void superio_enter(int base); | 114 | static inline int superio_enter(int base); |
115 | static inline void superio_select(int base, int ld); | 115 | static inline void superio_select(int base, int ld); |
116 | static inline void superio_exit(int base); | 116 | static inline void superio_exit(int base); |
117 | 117 | ||
@@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) | |||
861 | return val; | 861 | return val; |
862 | } | 862 | } |
863 | 863 | ||
864 | static inline void superio_enter(int base) | 864 | static inline int superio_enter(int base) |
865 | { | 865 | { |
866 | /* Don't step on other drivers' I/O space by accident */ | ||
867 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
868 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
869 | base); | ||
870 | return -EBUSY; | ||
871 | } | ||
872 | |||
866 | /* according to the datasheet the key must be send twice! */ | 873 | /* according to the datasheet the key must be send twice! */ |
867 | outb(SIO_UNLOCK_KEY, base); | 874 | outb(SIO_UNLOCK_KEY, base); |
868 | outb(SIO_UNLOCK_KEY, base); | 875 | outb(SIO_UNLOCK_KEY, base); |
876 | |||
877 | return 0; | ||
869 | } | 878 | } |
870 | 879 | ||
871 | static inline void superio_select(int base, int ld) | 880 | static inline void superio_select(int base, int ld) |
@@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) | |||
877 | static inline void superio_exit(int base) | 886 | static inline void superio_exit(int base) |
878 | { | 887 | { |
879 | outb(SIO_LOCK_KEY, base); | 888 | outb(SIO_LOCK_KEY, base); |
889 | release_region(base, 2); | ||
880 | } | 890 | } |
881 | 891 | ||
882 | static inline int fan_from_reg(u16 reg) | 892 | static inline int fan_from_reg(u16 reg) |
@@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2175 | static int __init f71882fg_find(int sioaddr, unsigned short *address, | 2185 | static int __init f71882fg_find(int sioaddr, unsigned short *address, |
2176 | struct f71882fg_sio_data *sio_data) | 2186 | struct f71882fg_sio_data *sio_data) |
2177 | { | 2187 | { |
2178 | int err = -ENODEV; | ||
2179 | u16 devid; | 2188 | u16 devid; |
2180 | 2189 | int err = superio_enter(sioaddr); | |
2181 | /* Don't step on other drivers' I/O space by accident */ | 2190 | if (err) |
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | 2191 | return err; |
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2188 | superio_enter(sioaddr); | ||
2189 | 2192 | ||
2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2193 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
2191 | if (devid != SIO_FINTEK_ID) { | 2194 | if (devid != SIO_FINTEK_ID) { |
2192 | pr_debug(DRVNAME ": Not a Fintek device\n"); | 2195 | pr_debug(DRVNAME ": Not a Fintek device\n"); |
2196 | err = -ENODEV; | ||
2193 | goto exit; | 2197 | goto exit; |
2194 | } | 2198 | } |
2195 | 2199 | ||
@@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2213 | default: | 2217 | default: |
2214 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", | 2218 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", |
2215 | (unsigned int)devid); | 2219 | (unsigned int)devid); |
2220 | err = -ENODEV; | ||
2216 | goto exit; | 2221 | goto exit; |
2217 | } | 2222 | } |
2218 | 2223 | ||
@@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2223 | 2228 | ||
2224 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2229 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
2225 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2230 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
2231 | err = -ENODEV; | ||
2226 | goto exit; | 2232 | goto exit; |
2227 | } | 2233 | } |
2228 | 2234 | ||
2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2235 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2230 | if (*address == 0) { | 2236 | if (*address == 0) { |
2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2237 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2238 | err = -ENODEV; | ||
2232 | goto exit; | 2239 | goto exit; |
2233 | } | 2240 | } |
2234 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | 2241 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ |
@@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2246 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2240 | exit: | 2247 | exit: |
2241 | superio_exit(sioaddr); | 2248 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2243 | return err; | 2249 | return err; |
2244 | } | 2250 | } |
2245 | 2251 | ||
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 2222c87876b9..b8feac5f2ef4 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -357,9 +357,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
357 | 357 | ||
358 | dev->terminate = 0; | 358 | dev->terminate = 0; |
359 | 359 | ||
360 | /* write the data into mode register */ | ||
361 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
362 | |||
363 | /* | 360 | /* |
364 | * First byte should be set here, not after interrupt, | 361 | * First byte should be set here, not after interrupt, |
365 | * because transmit-data-ready interrupt can come before | 362 | * because transmit-data-ready interrupt can come before |
@@ -371,6 +368,9 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) | |||
371 | dev->buf_len--; | 368 | dev->buf_len--; |
372 | } | 369 | } |
373 | 370 | ||
371 | /* write the data into mode register; start transmitting */ | ||
372 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); | ||
373 | |||
374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, | 374 | r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, |
375 | dev->adapter.timeout); | 375 | dev->adapter.timeout); |
376 | if (r == 0) { | 376 | if (r == 0) { |
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 0e9f85d0a835..56dbe54e8811 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c | |||
@@ -218,7 +218,7 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) | |||
218 | return result; | 218 | return result; |
219 | } else if (result == 0) { | 219 | } else if (result == 0) { |
220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); | 220 | dev_dbg(i2c->dev, "%s: timeout\n", __func__); |
221 | result = -ETIMEDOUT; | 221 | return -ETIMEDOUT; |
222 | } | 222 | } |
223 | 223 | ||
224 | return 0; | 224 | return 0; |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 72902e0bbfa7..bf831bf81587 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -662,8 +662,8 @@ static int s3c24xx_i2c_clockrate(struct s3c24xx_i2c *i2c, unsigned int *got) | |||
662 | unsigned long sda_delay; | 662 | unsigned long sda_delay; |
663 | 663 | ||
664 | if (pdata->sda_delay) { | 664 | if (pdata->sda_delay) { |
665 | sda_delay = (freq / 1000) * pdata->sda_delay; | 665 | sda_delay = clkin * pdata->sda_delay; |
666 | sda_delay /= 1000000; | 666 | sda_delay = DIV_ROUND_UP(sda_delay, 1000000); |
667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); | 667 | sda_delay = DIV_ROUND_UP(sda_delay, 5); |
668 | if (sda_delay > 3) | 668 | if (sda_delay > 3) |
669 | sda_delay = 3; | 669 | sda_delay = 3; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a10152bb1427..0906fc5b69b9 100755..100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -83,7 +83,7 @@ static unsigned int mwait_substates; | |||
83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ | 83 | /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ |
84 | static unsigned int lapic_timer_reliable_states; | 84 | static unsigned int lapic_timer_reliable_states; |
85 | 85 | ||
86 | static struct cpuidle_device *intel_idle_cpuidle_devices; | 86 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); | 87 | static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); |
88 | 88 | ||
89 | static struct cpuidle_state *cpuidle_state_table; | 89 | static struct cpuidle_state *cpuidle_state_table; |
@@ -108,7 +108,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
108 | .name = "NHM-C3", | 108 | .name = "NHM-C3", |
109 | .desc = "MWAIT 0x10", | 109 | .desc = "MWAIT 0x10", |
110 | .driver_data = (void *) 0x10, | 110 | .driver_data = (void *) 0x10, |
111 | .flags = CPUIDLE_FLAG_TIME_VALID, | 111 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
112 | .exit_latency = 20, | 112 | .exit_latency = 20, |
113 | .power_usage = 500, | 113 | .power_usage = 500, |
114 | .target_residency = 80, | 114 | .target_residency = 80, |
@@ -117,7 +117,7 @@ static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
117 | .name = "NHM-C6", | 117 | .name = "NHM-C6", |
118 | .desc = "MWAIT 0x20", | 118 | .desc = "MWAIT 0x20", |
119 | .driver_data = (void *) 0x20, | 119 | .driver_data = (void *) 0x20, |
120 | .flags = CPUIDLE_FLAG_TIME_VALID, | 120 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
121 | .exit_latency = 200, | 121 | .exit_latency = 200, |
122 | .power_usage = 350, | 122 | .power_usage = 350, |
123 | .target_residency = 800, | 123 | .target_residency = 800, |
@@ -149,7 +149,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
149 | .name = "ATM-C4", | 149 | .name = "ATM-C4", |
150 | .desc = "MWAIT 0x30", | 150 | .desc = "MWAIT 0x30", |
151 | .driver_data = (void *) 0x30, | 151 | .driver_data = (void *) 0x30, |
152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 152 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
153 | .exit_latency = 100, | 153 | .exit_latency = 100, |
154 | .power_usage = 250, | 154 | .power_usage = 250, |
155 | .target_residency = 400, | 155 | .target_residency = 400, |
@@ -159,7 +159,7 @@ static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { | |||
159 | .name = "ATM-C6", | 159 | .name = "ATM-C6", |
160 | .desc = "MWAIT 0x40", | 160 | .desc = "MWAIT 0x40", |
161 | .driver_data = (void *) 0x40, | 161 | .driver_data = (void *) 0x40, |
162 | .flags = CPUIDLE_FLAG_TIME_VALID, | 162 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, |
163 | .exit_latency = 200, | 163 | .exit_latency = 200, |
164 | .power_usage = 150, | 164 | .power_usage = 150, |
165 | .target_residency = 800, | 165 | .target_residency = 800, |
@@ -185,6 +185,16 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state) | |||
185 | 185 | ||
186 | local_irq_disable(); | 186 | local_irq_disable(); |
187 | 187 | ||
188 | /* | ||
189 | * If the state flag indicates that the TLB will be flushed or if this | ||
190 | * is the deepest c-state supported, do a voluntary leave mm to avoid | ||
191 | * costly and mostly unnecessary wakeups for flushing the user TLB's | ||
192 | * associated with the active mm. | ||
193 | */ | ||
194 | if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || | ||
195 | (&dev->states[dev->state_count - 1] == state)) | ||
196 | leave_mm(cpu); | ||
197 | |||
188 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) | 198 | if (!(lapic_timer_reliable_states & (1 << (cstate)))) |
189 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | 199 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); |
190 | 200 | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 04028a9ee082..428377a5a6f5 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -429,24 +429,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) | |||
429 | irq_tsc = cache_tsc; | 429 | irq_tsc = cache_tsc; |
430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { | 430 | for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) { |
431 | irq_data = &max8925_irqs[i]; | 431 | irq_data = &max8925_irqs[i]; |
432 | /* 1 -- disable, 0 -- enable */ | ||
432 | switch (irq_data->mask_reg) { | 433 | switch (irq_data->mask_reg) { |
433 | case MAX8925_CHG_IRQ1_MASK: | 434 | case MAX8925_CHG_IRQ1_MASK: |
434 | irq_chg[0] &= irq_data->enable; | 435 | irq_chg[0] &= ~irq_data->enable; |
435 | break; | 436 | break; |
436 | case MAX8925_CHG_IRQ2_MASK: | 437 | case MAX8925_CHG_IRQ2_MASK: |
437 | irq_chg[1] &= irq_data->enable; | 438 | irq_chg[1] &= ~irq_data->enable; |
438 | break; | 439 | break; |
439 | case MAX8925_ON_OFF_IRQ1_MASK: | 440 | case MAX8925_ON_OFF_IRQ1_MASK: |
440 | irq_on[0] &= irq_data->enable; | 441 | irq_on[0] &= ~irq_data->enable; |
441 | break; | 442 | break; |
442 | case MAX8925_ON_OFF_IRQ2_MASK: | 443 | case MAX8925_ON_OFF_IRQ2_MASK: |
443 | irq_on[1] &= irq_data->enable; | 444 | irq_on[1] &= ~irq_data->enable; |
444 | break; | 445 | break; |
445 | case MAX8925_RTC_IRQ_MASK: | 446 | case MAX8925_RTC_IRQ_MASK: |
446 | irq_rtc &= irq_data->enable; | 447 | irq_rtc &= ~irq_data->enable; |
447 | break; | 448 | break; |
448 | case MAX8925_TSC_IRQ_MASK: | 449 | case MAX8925_TSC_IRQ_MASK: |
449 | irq_tsc &= irq_data->enable; | 450 | irq_tsc &= ~irq_data->enable; |
450 | break; | 451 | break; |
451 | default: | 452 | default: |
452 | dev_err(chip->dev, "wrong IRQ\n"); | 453 | dev_err(chip->dev, "wrong IRQ\n"); |
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 7dabe4dbd373..294183b6260b 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -394,8 +394,13 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | |||
394 | 394 | ||
395 | irq = irq - wm831x->irq_base; | 395 | irq = irq - wm831x->irq_base; |
396 | 396 | ||
397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) | 397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
398 | return -EINVAL; | 398 | /* Ignore internal-only IRQs */ |
399 | if (irq >= 0 && irq < WM831X_NUM_IRQS) | ||
400 | return 0; | ||
401 | else | ||
402 | return -EINVAL; | ||
403 | } | ||
399 | 404 | ||
400 | switch (type) { | 405 | switch (type) { |
401 | case IRQ_TYPE_EDGE_BOTH: | 406 | case IRQ_TYPE_EDGE_BOTH: |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 133d51528f8d..513e0a76a4a7 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -413,7 +413,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); | 413 | prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); |
414 | } while (prefetch_status); | 414 | } while (prefetch_status); |
415 | /* disable and stop the PFPW engine */ | 415 | /* disable and stop the PFPW engine */ |
416 | gpmc_prefetch_reset(); | 416 | gpmc_prefetch_reset(info->gpmc_cs); |
417 | 417 | ||
418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); | 418 | dma_unmap_single(&info->pdev->dev, dma_addr, len, dir); |
419 | return 0; | 419 | return 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 9dd9e64c2b0b..8fd00a6e5120 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1411,7 +1411,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
1411 | clear_bit(STATUS_SCAN_HW, &priv->status); | 1411 | clear_bit(STATUS_SCAN_HW, &priv->status); |
1412 | clear_bit(STATUS_SCANNING, &priv->status); | 1412 | clear_bit(STATUS_SCANNING, &priv->status); |
1413 | /* inform mac80211 scan aborted */ | 1413 | /* inform mac80211 scan aborted */ |
1414 | queue_work(priv->workqueue, &priv->scan_completed); | 1414 | queue_work(priv->workqueue, &priv->abort_scan); |
1415 | } | 1415 | } |
1416 | 1416 | ||
1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, | 1417 | int iwlagn_manage_ibss_station(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 59a308b02f95..d31661c1ce77 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3018,7 +3018,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3018 | clear_bit(STATUS_SCANNING, &priv->status); | 3018 | clear_bit(STATUS_SCANNING, &priv->status); |
3019 | 3019 | ||
3020 | /* inform mac80211 scan aborted */ | 3020 | /* inform mac80211 scan aborted */ |
3021 | queue_work(priv->workqueue, &priv->scan_completed); | 3021 | queue_work(priv->workqueue, &priv->abort_scan); |
3022 | } | 3022 | } |
3023 | 3023 | ||
3024 | static void iwl3945_bg_restart(struct work_struct *data) | 3024 | static void iwl3945_bg_restart(struct work_struct *data) |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 89ed181cd90c..857ae01734a6 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -163,6 +163,26 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_d | |||
163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); | 163 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * Intel NM10 "TigerPoint" LPC PM1a_STS.BM_STS must be clear | ||
167 | * for some HT machines to use C4 w/o hanging. | ||
168 | */ | ||
169 | static void __devinit quirk_tigerpoint_bm_sts(struct pci_dev *dev) | ||
170 | { | ||
171 | u32 pmbase; | ||
172 | u16 pm1a; | ||
173 | |||
174 | pci_read_config_dword(dev, 0x40, &pmbase); | ||
175 | pmbase = pmbase & 0xff80; | ||
176 | pm1a = inw(pmbase); | ||
177 | |||
178 | if (pm1a & 0x10) { | ||
179 | dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n"); | ||
180 | outw(0x10, pmbase); | ||
181 | } | ||
182 | } | ||
183 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk_tigerpoint_bm_sts); | ||
184 | |||
185 | /* | ||
166 | * Chipsets where PCI->PCI transfers vanish or hang | 186 | * Chipsets where PCI->PCI transfers vanish or hang |
167 | */ | 187 | */ |
168 | static void __devinit quirk_nopcipci(struct pci_dev *dev) | 188 | static void __devinit quirk_nopcipci(struct pci_dev *dev) |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 422a709d271d..cc8b337b9119 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -700,7 +700,7 @@ static void print_constraints(struct regulator_dev *rdev) | |||
700 | constraints->min_uA != constraints->max_uA) { | 700 | constraints->min_uA != constraints->max_uA) { |
701 | ret = _regulator_get_current_limit(rdev); | 701 | ret = _regulator_get_current_limit(rdev); |
702 | if (ret > 0) | 702 | if (ret > 0) |
703 | count += sprintf(buf + count, "at %d uA ", ret / 1000); | 703 | count += sprintf(buf + count, "at %d mA ", ret / 1000); |
704 | } | 704 | } |
705 | 705 | ||
706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) | 706 | if (constraints->valid_modes_mask & REGULATOR_MODE_FAST) |
@@ -2302,8 +2302,10 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2302 | dev_set_name(&rdev->dev, "regulator.%d", | 2302 | dev_set_name(&rdev->dev, "regulator.%d", |
2303 | atomic_inc_return(®ulator_no) - 1); | 2303 | atomic_inc_return(®ulator_no) - 1); |
2304 | ret = device_register(&rdev->dev); | 2304 | ret = device_register(&rdev->dev); |
2305 | if (ret != 0) | 2305 | if (ret != 0) { |
2306 | put_device(&rdev->dev); | ||
2306 | goto clean; | 2307 | goto clean; |
2308 | } | ||
2307 | 2309 | ||
2308 | dev_set_drvdata(&rdev->dev, rdev); | 2310 | dev_set_drvdata(&rdev->dev, rdev); |
2309 | 2311 | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index 4520ace3f7e7..6b60a9c0366b 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -330,7 +330,7 @@ static int __devinit max8649_regulator_probe(struct i2c_client *client, | |||
330 | /* set external clock frequency */ | 330 | /* set external clock frequency */ |
331 | info->extclk_freq = pdata->extclk_freq; | 331 | info->extclk_freq = pdata->extclk_freq; |
332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, | 332 | max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, |
333 | info->extclk_freq); | 333 | info->extclk_freq << 6); |
334 | } | 334 | } |
335 | 335 | ||
336 | if (pdata->ramp_timing) { | 336 | if (pdata->ramp_timing) { |
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c index 324c385a653d..5dff45c76d32 100644 --- a/drivers/serial/mfd.c +++ b/drivers/serial/mfd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/console.h> | 28 | #include <linux/console.h> |
29 | #include <linux/sysrq.h> | 29 | #include <linux/sysrq.h> |
30 | #include <linux/slab.h> | ||
30 | #include <linux/serial_reg.h> | 31 | #include <linux/serial_reg.h> |
31 | #include <linux/circ_buf.h> | 32 | #include <linux/circ_buf.h> |
32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
diff --git a/drivers/serial/mrst_max3110.c b/drivers/serial/mrst_max3110.c index f6ad1ecbff79..51c15f58e01e 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/serial/mrst_max3110.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/ioport.h> | 31 | #include <linux/ioport.h> |
32 | #include <linux/irq.h> | ||
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/console.h> | 34 | #include <linux/console.h> |
34 | #include <linux/sysrq.h> | 35 | #include <linux/sysrq.h> |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 0bcf4c1601a2..b5a78a1f4421 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/cache.h> | 24 | #include <linux/cache.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/of_device.h> | ||
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <linux/mod_devicetable.h> | 28 | #include <linux/mod_devicetable.h> |
28 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
@@ -86,6 +87,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv) | |||
86 | const struct spi_device *spi = to_spi_device(dev); | 87 | const struct spi_device *spi = to_spi_device(dev); |
87 | const struct spi_driver *sdrv = to_spi_driver(drv); | 88 | const struct spi_driver *sdrv = to_spi_driver(drv); |
88 | 89 | ||
90 | /* Attempt an OF style match */ | ||
91 | if (of_driver_match_device(dev, drv)) | ||
92 | return 1; | ||
93 | |||
89 | if (sdrv->id_table) | 94 | if (sdrv->id_table) |
90 | return !!spi_match_id(sdrv->id_table, spi); | 95 | return !!spi_match_id(sdrv->id_table, spi); |
91 | 96 | ||
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c index e24a63498acb..63e51b011d50 100644 --- a/drivers/spi/spi_gpio.c +++ b/drivers/spi/spi_gpio.c | |||
@@ -350,7 +350,7 @@ static int __init spi_gpio_probe(struct platform_device *pdev) | |||
350 | spi_gpio->bitbang.master = spi_master_get(master); | 350 | spi_gpio->bitbang.master = spi_master_get(master); |
351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 351 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
352 | 352 | ||
353 | if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) { | 353 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { |
354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | 354 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; |
355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; | 355 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; |
356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; | 356 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; |
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index d31b57f7baaf..1dd86b835cd8 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c | |||
@@ -408,11 +408,17 @@ static void mpc8xxx_spi_cpm_bufs_start(struct mpc8xxx_spi *mspi) | |||
408 | 408 | ||
409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; | 409 | xfer_ofs = mspi->xfer_in_progress->len - mspi->count; |
410 | 410 | ||
411 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | 411 | if (mspi->rx_dma == mspi->dma_dummy_rx) |
412 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma); | ||
413 | else | ||
414 | out_be32(&rx_bd->cbd_bufaddr, mspi->rx_dma + xfer_ofs); | ||
412 | out_be16(&rx_bd->cbd_datlen, 0); | 415 | out_be16(&rx_bd->cbd_datlen, 0); |
413 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); | 416 | out_be16(&rx_bd->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT | BD_SC_WRAP); |
414 | 417 | ||
415 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | 418 | if (mspi->tx_dma == mspi->dma_dummy_tx) |
419 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma); | ||
420 | else | ||
421 | out_be32(&tx_bd->cbd_bufaddr, mspi->tx_dma + xfer_ofs); | ||
416 | out_be16(&tx_bd->cbd_datlen, xfer_len); | 422 | out_be16(&tx_bd->cbd_datlen, xfer_len); |
417 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | | 423 | out_be16(&tx_bd->cbd_sc, BD_SC_READY | BD_SC_INTRPT | BD_SC_WRAP | |
418 | BD_SC_LAST); | 424 | BD_SC_LAST); |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 29bac5118877..d409495876f1 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -755,7 +755,10 @@ int register_xenstore_notifier(struct notifier_block *nb) | |||
755 | { | 755 | { |
756 | int ret = 0; | 756 | int ret = 0; |
757 | 757 | ||
758 | blocking_notifier_chain_register(&xenstore_chain, nb); | 758 | if (xenstored_ready > 0) |
759 | ret = nb->notifier_call(nb, 0, NULL); | ||
760 | else | ||
761 | blocking_notifier_chain_register(&xenstore_chain, nb); | ||
759 | 762 | ||
760 | return ret; | 763 | return ret; |
761 | } | 764 | } |
@@ -769,7 +772,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_notifier); | |||
769 | 772 | ||
770 | void xenbus_probe(struct work_struct *unused) | 773 | void xenbus_probe(struct work_struct *unused) |
771 | { | 774 | { |
772 | BUG_ON((xenstored_ready <= 0)); | 775 | xenstored_ready = 1; |
773 | 776 | ||
774 | /* Enumerate devices in xenstore and watch for changes. */ | 777 | /* Enumerate devices in xenstore and watch for changes. */ |
775 | xenbus_probe_devices(&xenbus_frontend); | 778 | xenbus_probe_devices(&xenbus_frontend); |
@@ -835,8 +838,8 @@ static int __init xenbus_init(void) | |||
835 | xen_store_evtchn = xen_start_info->store_evtchn; | 838 | xen_store_evtchn = xen_start_info->store_evtchn; |
836 | xen_store_mfn = xen_start_info->store_mfn; | 839 | xen_store_mfn = xen_start_info->store_mfn; |
837 | xen_store_interface = mfn_to_virt(xen_store_mfn); | 840 | xen_store_interface = mfn_to_virt(xen_store_mfn); |
841 | xenstored_ready = 1; | ||
838 | } | 842 | } |
839 | xenstored_ready = 1; | ||
840 | } | 843 | } |
841 | 844 | ||
842 | /* Initialize the interface to xenstore. */ | 845 | /* Initialize the interface to xenstore. */ |