diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-03-04 05:47:50 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-03-04 05:47:52 -0500 |
commit | 4f16d4e0c9a4b20d9f0db365587b96d6001efd7d (patch) | |
tree | fa25dcf285b26f1fac2bf267d0d1cd2c4eba90b8 /drivers | |
parent | 1e259e0a9982078896f3404240096cbea01daca4 (diff) | |
parent | 6630125419ef37ff8781713c5e9d416f2a4ba357 (diff) |
Merge branch 'perf/core' into perf/urgent
Merge reason: Switch from pre-merge topical split to the post-merge urgent track
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
208 files changed, 2067 insertions, 1094 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index bbc2c1315c47..b2586f57e1f5 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -935,6 +935,7 @@ static int dock_add(acpi_handle handle) | |||
935 | struct platform_device *dd; | 935 | struct platform_device *dd; |
936 | 936 | ||
937 | id = dock_station_count; | 937 | id = dock_station_count; |
938 | memset(&ds, 0, sizeof(ds)); | ||
938 | dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); | 939 | dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); |
939 | if (IS_ERR(dd)) | 940 | if (IS_ERR(dd)) |
940 | return PTR_ERR(dd); | 941 | return PTR_ERR(dd); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 7c0441f63b39..cc978a8c00b7 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -110,6 +110,14 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { | |||
110 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | 110 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
111 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, | 111 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, |
112 | (void *)2}, | 112 | (void *)2}, |
113 | { set_max_cstate, "Pavilion zv5000", { | ||
114 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
115 | DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")}, | ||
116 | (void *)1}, | ||
117 | { set_max_cstate, "Asus L8400B", { | ||
118 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
119 | DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, | ||
120 | (void *)1}, | ||
113 | {}, | 121 | {}, |
114 | }; | 122 | }; |
115 | 123 | ||
@@ -872,12 +880,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
872 | return(acpi_idle_enter_c1(dev, state)); | 880 | return(acpi_idle_enter_c1(dev, state)); |
873 | 881 | ||
874 | local_irq_disable(); | 882 | local_irq_disable(); |
875 | current_thread_info()->status &= ~TS_POLLING; | 883 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
876 | /* | 884 | current_thread_info()->status &= ~TS_POLLING; |
877 | * TS_POLLING-cleared state must be visible before we test | 885 | /* |
878 | * NEED_RESCHED: | 886 | * TS_POLLING-cleared state must be visible before we test |
879 | */ | 887 | * NEED_RESCHED: |
880 | smp_mb(); | 888 | */ |
889 | smp_mb(); | ||
890 | } | ||
881 | 891 | ||
882 | if (unlikely(need_resched())) { | 892 | if (unlikely(need_resched())) { |
883 | current_thread_info()->status |= TS_POLLING; | 893 | current_thread_info()->status |= TS_POLLING; |
@@ -957,12 +967,14 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
957 | } | 967 | } |
958 | 968 | ||
959 | local_irq_disable(); | 969 | local_irq_disable(); |
960 | current_thread_info()->status &= ~TS_POLLING; | 970 | if (cx->entry_method != ACPI_CSTATE_FFH) { |
961 | /* | 971 | current_thread_info()->status &= ~TS_POLLING; |
962 | * TS_POLLING-cleared state must be visible before we test | 972 | /* |
963 | * NEED_RESCHED: | 973 | * TS_POLLING-cleared state must be visible before we test |
964 | */ | 974 | * NEED_RESCHED: |
965 | smp_mb(); | 975 | */ |
976 | smp_mb(); | ||
977 | } | ||
966 | 978 | ||
967 | if (unlikely(need_resched())) { | 979 | if (unlikely(need_resched())) { |
968 | current_thread_info()->status |= TS_POLLING; | 980 | current_thread_info()->status |= TS_POLLING; |
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 7247819dbd80..e306ba9aa34e 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c | |||
@@ -125,6 +125,8 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) | |||
125 | return status; | 125 | return status; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int early_pdc_done; | ||
129 | |||
128 | void acpi_processor_set_pdc(acpi_handle handle) | 130 | void acpi_processor_set_pdc(acpi_handle handle) |
129 | { | 131 | { |
130 | struct acpi_object_list *obj_list; | 132 | struct acpi_object_list *obj_list; |
@@ -132,6 +134,9 @@ void acpi_processor_set_pdc(acpi_handle handle) | |||
132 | if (arch_has_acpi_pdc() == false) | 134 | if (arch_has_acpi_pdc() == false) |
133 | return; | 135 | return; |
134 | 136 | ||
137 | if (early_pdc_done) | ||
138 | return; | ||
139 | |||
135 | obj_list = acpi_processor_alloc_pdc(); | 140 | obj_list = acpi_processor_alloc_pdc(); |
136 | if (!obj_list) | 141 | if (!obj_list) |
137 | return; | 142 | return; |
@@ -151,6 +156,13 @@ static int set_early_pdc_optin(const struct dmi_system_id *id) | |||
151 | return 0; | 156 | return 0; |
152 | } | 157 | } |
153 | 158 | ||
159 | static int param_early_pdc_optin(char *s) | ||
160 | { | ||
161 | early_pdc_optin = 1; | ||
162 | return 1; | ||
163 | } | ||
164 | __setup("acpi_early_pdc_eval", param_early_pdc_optin); | ||
165 | |||
154 | static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { | 166 | static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { |
155 | { | 167 | { |
156 | set_early_pdc_optin, "HP Envy", { | 168 | set_early_pdc_optin, "HP Envy", { |
@@ -192,4 +204,6 @@ void __init acpi_early_processor_set_pdc(void) | |||
192 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, | 204 | acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, |
193 | ACPI_UINT32_MAX, | 205 | ACPI_UINT32_MAX, |
194 | early_init_pdc, NULL, NULL, NULL); | 206 | early_init_pdc, NULL, NULL, NULL); |
207 | |||
208 | early_pdc_done = 1; | ||
195 | } | 209 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 2cabadcc4d8c..a959f6a07508 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -413,7 +413,11 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) | |||
413 | if (result) | 413 | if (result) |
414 | goto update_bios; | 414 | goto update_bios; |
415 | 415 | ||
416 | return 0; | 416 | /* We need to call _PPC once when cpufreq starts */ |
417 | if (ignore_ppc != 1) | ||
418 | result = acpi_processor_get_platform_limit(pr); | ||
419 | |||
420 | return result; | ||
417 | 421 | ||
418 | /* | 422 | /* |
419 | * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that | 423 | * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ff9f6226085d..3e009674f333 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1336,9 +1336,25 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, | |||
1336 | 1336 | ||
1337 | if (child) | 1337 | if (child) |
1338 | *child = device; | 1338 | *child = device; |
1339 | return 0; | 1339 | |
1340 | if (device) | ||
1341 | return 0; | ||
1342 | else | ||
1343 | return -ENODEV; | ||
1340 | } | 1344 | } |
1341 | 1345 | ||
1346 | /* | ||
1347 | * acpi_bus_add and acpi_bus_start | ||
1348 | * | ||
1349 | * scan a given ACPI tree and (probably recently hot-plugged) | ||
1350 | * create and add or starts found devices. | ||
1351 | * | ||
1352 | * If no devices were found -ENODEV is returned which does not | ||
1353 | * mean that this is a real error, there just have been no suitable | ||
1354 | * ACPI objects in the table trunk from which the kernel could create | ||
1355 | * a device and add/start an appropriate driver. | ||
1356 | */ | ||
1357 | |||
1342 | int | 1358 | int |
1343 | acpi_bus_add(struct acpi_device **child, | 1359 | acpi_bus_add(struct acpi_device **child, |
1344 | struct acpi_device *parent, acpi_handle handle, int type) | 1360 | struct acpi_device *parent, acpi_handle handle, int type) |
@@ -1348,8 +1364,7 @@ acpi_bus_add(struct acpi_device **child, | |||
1348 | memset(&ops, 0, sizeof(ops)); | 1364 | memset(&ops, 0, sizeof(ops)); |
1349 | ops.acpi_op_add = 1; | 1365 | ops.acpi_op_add = 1; |
1350 | 1366 | ||
1351 | acpi_bus_scan(handle, &ops, child); | 1367 | return acpi_bus_scan(handle, &ops, child); |
1352 | return 0; | ||
1353 | } | 1368 | } |
1354 | EXPORT_SYMBOL(acpi_bus_add); | 1369 | EXPORT_SYMBOL(acpi_bus_add); |
1355 | 1370 | ||
@@ -1357,11 +1372,13 @@ int acpi_bus_start(struct acpi_device *device) | |||
1357 | { | 1372 | { |
1358 | struct acpi_bus_ops ops; | 1373 | struct acpi_bus_ops ops; |
1359 | 1374 | ||
1375 | if (!device) | ||
1376 | return -EINVAL; | ||
1377 | |||
1360 | memset(&ops, 0, sizeof(ops)); | 1378 | memset(&ops, 0, sizeof(ops)); |
1361 | ops.acpi_op_start = 1; | 1379 | ops.acpi_op_start = 1; |
1362 | 1380 | ||
1363 | acpi_bus_scan(device->handle, &ops, NULL); | 1381 | return acpi_bus_scan(device->handle, &ops, NULL); |
1364 | return 0; | ||
1365 | } | 1382 | } |
1366 | EXPORT_SYMBOL(acpi_bus_start); | 1383 | EXPORT_SYMBOL(acpi_bus_start); |
1367 | 1384 | ||
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f336bca7c450..8a0ed2800e63 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id, | |||
213 | unsigned long table_end; | 213 | unsigned long table_end; |
214 | acpi_size tbl_size; | 214 | acpi_size tbl_size; |
215 | 215 | ||
216 | if (acpi_disabled) | 216 | if (acpi_disabled && !acpi_ht) |
217 | return -ENODEV; | 217 | return -ENODEV; |
218 | 218 | ||
219 | if (!handler) | 219 | if (!handler) |
@@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
280 | struct acpi_table_header *table = NULL; | 280 | struct acpi_table_header *table = NULL; |
281 | acpi_size tbl_size; | 281 | acpi_size tbl_size; |
282 | 282 | ||
283 | if (acpi_disabled) | 283 | if (acpi_disabled && !acpi_ht) |
284 | return -ENODEV; | 284 | return -ENODEV; |
285 | 285 | ||
286 | if (!handler) | 286 | if (!handler) |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b8bea100a160..b34390347c16 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -2868,6 +2868,21 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) | |||
2868 | }, | 2868 | }, |
2869 | .driver_data = "F.23", /* cutoff BIOS version */ | 2869 | .driver_data = "F.23", /* cutoff BIOS version */ |
2870 | }, | 2870 | }, |
2871 | /* | ||
2872 | * Acer eMachines G725 has the same problem. BIOS | ||
2873 | * V1.03 is known to be broken. V3.04 is known to | ||
2874 | * work. Inbetween, there are V1.06, V2.06 and V3.03 | ||
2875 | * that we don't have much idea about. For now, | ||
2876 | * blacklist anything older than V3.04. | ||
2877 | */ | ||
2878 | { | ||
2879 | .ident = "G725", | ||
2880 | .matches = { | ||
2881 | DMI_MATCH(DMI_SYS_VENDOR, "eMachines"), | ||
2882 | DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"), | ||
2883 | }, | ||
2884 | .driver_data = "V3.04", /* cutoff BIOS version */ | ||
2885 | }, | ||
2871 | { } /* terminate list */ | 2886 | { } /* terminate list */ |
2872 | }; | 2887 | }; |
2873 | const struct dmi_system_id *dmi = dmi_first_match(sysids); | 2888 | const struct dmi_system_id *dmi = dmi_first_match(sysids); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index f4ea5a8c325b..d096fbcbc771 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2875,7 +2875,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
2875 | * write indication (used for PIO/DMA setup), result TF is | 2875 | * write indication (used for PIO/DMA setup), result TF is |
2876 | * copied back and we don't whine too much about its failure. | 2876 | * copied back and we don't whine too much about its failure. |
2877 | */ | 2877 | */ |
2878 | tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 2878 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
2879 | if (scmd->sc_data_direction == DMA_TO_DEVICE) | 2879 | if (scmd->sc_data_direction == DMA_TO_DEVICE) |
2880 | tf->flags |= ATA_TFLAG_WRITE; | 2880 | tf->flags |= ATA_TFLAG_WRITE; |
2881 | 2881 | ||
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 741065c9da67..730ef3c384ca 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -893,6 +893,9 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) | |||
893 | do_write); | 893 | do_write); |
894 | } | 894 | } |
895 | 895 | ||
896 | if (!do_write) | ||
897 | flush_dcache_page(page); | ||
898 | |||
896 | qc->curbytes += qc->sect_size; | 899 | qc->curbytes += qc->sect_size; |
897 | qc->cursg_ofs += qc->sect_size; | 900 | qc->cursg_ofs += qc->sect_size; |
898 | 901 | ||
diff --git a/drivers/base/class.c b/drivers/base/class.c index 161746deab4b..6e2c3b064f53 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -59,6 +59,8 @@ static void class_release(struct kobject *kobj) | |||
59 | else | 59 | else |
60 | pr_debug("class '%s' does not have a release() function, " | 60 | pr_debug("class '%s' does not have a release() function, " |
61 | "be careful\n", class->name); | 61 | "be careful\n", class->name); |
62 | |||
63 | kfree(cp); | ||
62 | } | 64 | } |
63 | 65 | ||
64 | static struct sysfs_ops class_sysfs_ops = { | 66 | static struct sysfs_ops class_sysfs_ops = { |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 873e594860d3..9291614ac6b7 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -337,6 +337,9 @@ static int cciss_seq_show(struct seq_file *seq, void *v) | |||
337 | if (*pos > h->highest_lun) | 337 | if (*pos > h->highest_lun) |
338 | return 0; | 338 | return 0; |
339 | 339 | ||
340 | if (drv == NULL) /* it's possible for h->drv[] to have holes. */ | ||
341 | return 0; | ||
342 | |||
340 | if (drv->heads == 0) | 343 | if (drv->heads == 0) |
341 | return 0; | 344 | return 0; |
342 | 345 | ||
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index f36defa37764..57d965b7f521 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -808,6 +808,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv, | |||
808 | 808 | ||
809 | exit: | 809 | exit: |
810 | sdio_release_host(card->func); | 810 | sdio_release_host(card->func); |
811 | kfree(tmpbuf); | ||
811 | 812 | ||
812 | return ret; | 813 | return ret; |
813 | } | 814 | } |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 34cf04e21795..fd50ead59c79 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -767,16 +767,19 @@ int __init agp_amd64_init(void) | |||
767 | 767 | ||
768 | static int __init agp_amd64_mod_init(void) | 768 | static int __init agp_amd64_mod_init(void) |
769 | { | 769 | { |
770 | #ifndef MODULE | ||
770 | if (gart_iommu_aperture) | 771 | if (gart_iommu_aperture) |
771 | return agp_bridges_found ? 0 : -ENODEV; | 772 | return agp_bridges_found ? 0 : -ENODEV; |
772 | 773 | #endif | |
773 | return agp_amd64_init(); | 774 | return agp_amd64_init(); |
774 | } | 775 | } |
775 | 776 | ||
776 | static void __exit agp_amd64_cleanup(void) | 777 | static void __exit agp_amd64_cleanup(void) |
777 | { | 778 | { |
779 | #ifndef MODULE | ||
778 | if (gart_iommu_aperture) | 780 | if (gart_iommu_aperture) |
779 | return; | 781 | return; |
782 | #endif | ||
780 | if (aperture_resource) | 783 | if (aperture_resource) |
781 | release_resource(aperture_resource); | 784 | release_resource(aperture_resource); |
782 | pci_unregister_driver(&agp_amd64_pci_driver); | 785 | pci_unregister_driver(&agp_amd64_pci_driver); |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index ecba4942fc8e..f58440791e65 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -39,12 +39,12 @@ | |||
39 | struct tpm_inf_dev { | 39 | struct tpm_inf_dev { |
40 | int iotype; | 40 | int iotype; |
41 | 41 | ||
42 | void __iomem *mem_base; /* MMIO ioremap'd addr */ | 42 | void __iomem *mem_base; /* MMIO ioremap'd addr */ |
43 | unsigned long map_base; /* phys MMIO base */ | 43 | unsigned long map_base; /* phys MMIO base */ |
44 | unsigned long map_size; /* MMIO region size */ | 44 | unsigned long map_size; /* MMIO region size */ |
45 | unsigned int index_off; /* index register offset */ | 45 | unsigned int index_off; /* index register offset */ |
46 | 46 | ||
47 | unsigned int data_regs; /* Data registers */ | 47 | unsigned int data_regs; /* Data registers */ |
48 | unsigned int data_size; | 48 | unsigned int data_size; |
49 | 49 | ||
50 | unsigned int config_port; /* IO Port config index reg */ | 50 | unsigned int config_port; /* IO Port config index reg */ |
@@ -406,14 +406,14 @@ static const struct tpm_vendor_specific tpm_inf = { | |||
406 | .miscdev = {.fops = &inf_ops,}, | 406 | .miscdev = {.fops = &inf_ops,}, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | static const struct pnp_device_id tpm_pnp_tbl[] = { | 409 | static const struct pnp_device_id tpm_inf_pnp_tbl[] = { |
410 | /* Infineon TPMs */ | 410 | /* Infineon TPMs */ |
411 | {"IFX0101", 0}, | 411 | {"IFX0101", 0}, |
412 | {"IFX0102", 0}, | 412 | {"IFX0102", 0}, |
413 | {"", 0} | 413 | {"", 0} |
414 | }; | 414 | }; |
415 | 415 | ||
416 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | 416 | MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl); |
417 | 417 | ||
418 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | 418 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, |
419 | const struct pnp_device_id *dev_id) | 419 | const struct pnp_device_id *dev_id) |
@@ -430,7 +430,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
430 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 430 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
431 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { | 431 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
432 | 432 | ||
433 | tpm_dev.iotype = TPM_INF_IO_PORT; | 433 | tpm_dev.iotype = TPM_INF_IO_PORT; |
434 | 434 | ||
435 | tpm_dev.config_port = pnp_port_start(dev, 0); | 435 | tpm_dev.config_port = pnp_port_start(dev, 0); |
436 | tpm_dev.config_size = pnp_port_len(dev, 0); | 436 | tpm_dev.config_size = pnp_port_len(dev, 0); |
@@ -459,9 +459,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
459 | goto err_last; | 459 | goto err_last; |
460 | } | 460 | } |
461 | } else if (pnp_mem_valid(dev, 0) && | 461 | } else if (pnp_mem_valid(dev, 0) && |
462 | !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) { | 462 | !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) { |
463 | 463 | ||
464 | tpm_dev.iotype = TPM_INF_IO_MEM; | 464 | tpm_dev.iotype = TPM_INF_IO_MEM; |
465 | 465 | ||
466 | tpm_dev.map_base = pnp_mem_start(dev, 0); | 466 | tpm_dev.map_base = pnp_mem_start(dev, 0); |
467 | tpm_dev.map_size = pnp_mem_len(dev, 0); | 467 | tpm_dev.map_size = pnp_mem_len(dev, 0); |
@@ -563,11 +563,11 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
563 | "product id 0x%02x%02x" | 563 | "product id 0x%02x%02x" |
564 | "%s\n", | 564 | "%s\n", |
565 | tpm_dev.iotype == TPM_INF_IO_PORT ? | 565 | tpm_dev.iotype == TPM_INF_IO_PORT ? |
566 | tpm_dev.config_port : | 566 | tpm_dev.config_port : |
567 | tpm_dev.map_base + tpm_dev.index_off, | 567 | tpm_dev.map_base + tpm_dev.index_off, |
568 | tpm_dev.iotype == TPM_INF_IO_PORT ? | 568 | tpm_dev.iotype == TPM_INF_IO_PORT ? |
569 | tpm_dev.data_regs : | 569 | tpm_dev.data_regs : |
570 | tpm_dev.map_base + tpm_dev.data_regs, | 570 | tpm_dev.map_base + tpm_dev.data_regs, |
571 | version[0], version[1], | 571 | version[0], version[1], |
572 | vendorid[0], vendorid[1], | 572 | vendorid[0], vendorid[1], |
573 | productid[0], productid[1], chipname); | 573 | productid[0], productid[1], chipname); |
@@ -607,20 +607,55 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
607 | iounmap(tpm_dev.mem_base); | 607 | iounmap(tpm_dev.mem_base); |
608 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | 608 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); |
609 | } | 609 | } |
610 | tpm_dev_vendor_release(chip); | ||
610 | tpm_remove_hardware(chip->dev); | 611 | tpm_remove_hardware(chip->dev); |
611 | } | 612 | } |
612 | } | 613 | } |
613 | 614 | ||
615 | static int tpm_inf_pnp_suspend(struct pnp_dev *dev, pm_message_t pm_state) | ||
616 | { | ||
617 | struct tpm_chip *chip = pnp_get_drvdata(dev); | ||
618 | int rc; | ||
619 | if (chip) { | ||
620 | u8 savestate[] = { | ||
621 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | ||
622 | 0, 0, 0, 10, /* blob length (in bytes) */ | ||
623 | 0, 0, 0, 152 /* TPM_ORD_SaveState */ | ||
624 | }; | ||
625 | dev_info(&dev->dev, "saving TPM state\n"); | ||
626 | rc = tpm_inf_send(chip, savestate, sizeof(savestate)); | ||
627 | if (rc < 0) { | ||
628 | dev_err(&dev->dev, "error while saving TPM state\n"); | ||
629 | return rc; | ||
630 | } | ||
631 | } | ||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int tpm_inf_pnp_resume(struct pnp_dev *dev) | ||
636 | { | ||
637 | /* Re-configure TPM after suspending */ | ||
638 | tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); | ||
639 | tpm_config_out(IOLIMH, TPM_INF_ADDR); | ||
640 | tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA); | ||
641 | tpm_config_out(IOLIML, TPM_INF_ADDR); | ||
642 | tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA); | ||
643 | /* activate register */ | ||
644 | tpm_config_out(TPM_DAR, TPM_INF_ADDR); | ||
645 | tpm_config_out(0x01, TPM_INF_DATA); | ||
646 | tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); | ||
647 | /* disable RESET, LP and IRQC */ | ||
648 | tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); | ||
649 | return tpm_pm_resume(&dev->dev); | ||
650 | } | ||
651 | |||
614 | static struct pnp_driver tpm_inf_pnp_driver = { | 652 | static struct pnp_driver tpm_inf_pnp_driver = { |
615 | .name = "tpm_inf_pnp", | 653 | .name = "tpm_inf_pnp", |
616 | .driver = { | 654 | .id_table = tpm_inf_pnp_tbl, |
617 | .owner = THIS_MODULE, | ||
618 | .suspend = tpm_pm_suspend, | ||
619 | .resume = tpm_pm_resume, | ||
620 | }, | ||
621 | .id_table = tpm_pnp_tbl, | ||
622 | .probe = tpm_inf_pnp_probe, | 655 | .probe = tpm_inf_pnp_probe, |
623 | .remove = __devexit_p(tpm_inf_pnp_remove), | 656 | .suspend = tpm_inf_pnp_suspend, |
657 | .resume = tpm_inf_pnp_resume, | ||
658 | .remove = __devexit_p(tpm_inf_pnp_remove) | ||
624 | }; | 659 | }; |
625 | 660 | ||
626 | static int __init init_inf(void) | 661 | static int __init init_inf(void) |
@@ -638,5 +673,5 @@ module_exit(cleanup_inf); | |||
638 | 673 | ||
639 | MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>"); | 674 | MODULE_AUTHOR("Marcel Selhorst <m.selhorst@sirrix.com>"); |
640 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 675 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
641 | MODULE_VERSION("1.9"); | 676 | MODULE_VERSION("1.9.2"); |
642 | MODULE_LICENSE("GPL"); | 677 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index c6f3b48be9dd..dcb9083ecde0 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1951,8 +1951,10 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
1951 | pid = task_pid(current); | 1951 | pid = task_pid(current); |
1952 | type = PIDTYPE_PID; | 1952 | type = PIDTYPE_PID; |
1953 | } | 1953 | } |
1954 | retval = __f_setown(filp, pid, type, 0); | 1954 | get_pid(pid); |
1955 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 1955 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
1956 | retval = __f_setown(filp, pid, type, 0); | ||
1957 | put_pid(pid); | ||
1956 | if (retval) | 1958 | if (retval) |
1957 | goto out; | 1959 | goto out; |
1958 | } else { | 1960 | } else { |
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index 27d20fac19d1..b314a999aabe 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #define DRV_NAME "cs5535-clockevt" | 22 | #define DRV_NAME "cs5535-clockevt" |
23 | 23 | ||
24 | static int timer_irq = CONFIG_CS5535_MFGPT_DEFAULT_IRQ; | 24 | static int timer_irq; |
25 | module_param_named(irq, timer_irq, int, 0644); | 25 | module_param_named(irq, timer_irq, int, 0644); |
26 | MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks."); | 26 | MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks."); |
27 | 27 | ||
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 4b34ade2332b..bd444dc93cf2 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -554,6 +554,9 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
554 | (dbs_tuners_ins.up_threshold - | 554 | (dbs_tuners_ins.up_threshold - |
555 | dbs_tuners_ins.down_differential); | 555 | dbs_tuners_ins.down_differential); |
556 | 556 | ||
557 | if (freq_next < policy->min) | ||
558 | freq_next = policy->min; | ||
559 | |||
557 | if (!dbs_tuners_ins.powersave_bias) { | 560 | if (!dbs_tuners_ins.powersave_bias) { |
558 | __cpufreq_driver_target(policy, freq_next, | 561 | __cpufreq_driver_target(policy, freq_next, |
559 | CPUFREQ_RELATION_L); | 562 | CPUFREQ_RELATION_L); |
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index b5f2ee0f8e2c..64a937262a40 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c | |||
@@ -613,8 +613,6 @@ static void dma_tasklet(unsigned long data) | |||
613 | cohd_fin->pending_irqs--; | 613 | cohd_fin->pending_irqs--; |
614 | cohc->completed = cohd_fin->desc.cookie; | 614 | cohc->completed = cohd_fin->desc.cookie; |
615 | 615 | ||
616 | BUG_ON(cohc->nbr_active_done && cohd_fin == NULL); | ||
617 | |||
618 | if (cohc->nbr_active_done == 0) | 616 | if (cohc->nbr_active_done == 0) |
619 | return; | 617 | return; |
620 | 618 | ||
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 6f51a0a7a8bb..e7a3230fb7d5 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -826,6 +826,7 @@ void dma_async_device_unregister(struct dma_device *device) | |||
826 | chan->dev->chan = NULL; | 826 | chan->dev->chan = NULL; |
827 | mutex_unlock(&dma_list_mutex); | 827 | mutex_unlock(&dma_list_mutex); |
828 | device_unregister(&chan->dev->device); | 828 | device_unregister(&chan->dev->device); |
829 | free_percpu(chan->local); | ||
829 | } | 830 | } |
830 | } | 831 | } |
831 | EXPORT_SYMBOL(dma_async_device_unregister); | 832 | EXPORT_SYMBOL(dma_async_device_unregister); |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 8b905161fbf4..948d563941c9 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -467,7 +467,7 @@ err_srcs: | |||
467 | 467 | ||
468 | if (iterations > 0) | 468 | if (iterations > 0) |
469 | while (!kthread_should_stop()) { | 469 | while (!kthread_should_stop()) { |
470 | DECLARE_WAIT_QUEUE_HEAD(wait_dmatest_exit); | 470 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit); |
471 | interruptible_sleep_on(&wait_dmatest_exit); | 471 | interruptible_sleep_on(&wait_dmatest_exit); |
472 | } | 472 | } |
473 | 473 | ||
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 5f7a500e18d0..5cc37afe2bc1 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -249,7 +249,7 @@ int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo) | |||
249 | if (is_ioat_active(status) || is_ioat_idle(status)) | 249 | if (is_ioat_active(status) || is_ioat_idle(status)) |
250 | ioat_suspend(chan); | 250 | ioat_suspend(chan); |
251 | while (is_ioat_active(status) || is_ioat_idle(status)) { | 251 | while (is_ioat_active(status) || is_ioat_idle(status)) { |
252 | if (end && time_after(jiffies, end)) { | 252 | if (tmo && time_after(jiffies, end)) { |
253 | err = -ETIMEDOUT; | 253 | err = -ETIMEDOUT; |
254 | break; | 254 | break; |
255 | } | 255 | } |
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index 9a5bc1a7389e..e80bae1673fa 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c | |||
@@ -761,12 +761,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n) | |||
761 | * @buffer_n: buffer number to update. | 761 | * @buffer_n: buffer number to update. |
762 | * 0 or 1 are the only valid values. | 762 | * 0 or 1 are the only valid values. |
763 | * @phyaddr: buffer physical address. | 763 | * @phyaddr: buffer physical address. |
764 | * @return: Returns 0 on success or negative error code on failure. This | ||
765 | * function will fail if the buffer is set to ready. | ||
766 | */ | 764 | */ |
767 | /* Called under spin_lock(_irqsave)(&ichan->lock) */ | 765 | /* Called under spin_lock(_irqsave)(&ichan->lock) */ |
768 | static int ipu_update_channel_buffer(struct idmac_channel *ichan, | 766 | static void ipu_update_channel_buffer(struct idmac_channel *ichan, |
769 | int buffer_n, dma_addr_t phyaddr) | 767 | int buffer_n, dma_addr_t phyaddr) |
770 | { | 768 | { |
771 | enum ipu_channel channel = ichan->dma_chan.chan_id; | 769 | enum ipu_channel channel = ichan->dma_chan.chan_id; |
772 | uint32_t reg; | 770 | uint32_t reg; |
@@ -806,8 +804,6 @@ static int ipu_update_channel_buffer(struct idmac_channel *ichan, | |||
806 | } | 804 | } |
807 | 805 | ||
808 | spin_unlock_irqrestore(&ipu_data.lock, flags); | 806 | spin_unlock_irqrestore(&ipu_data.lock, flags); |
809 | |||
810 | return 0; | ||
811 | } | 807 | } |
812 | 808 | ||
813 | /* Called under spin_lock_irqsave(&ichan->lock) */ | 809 | /* Called under spin_lock_irqsave(&ichan->lock) */ |
@@ -816,7 +812,6 @@ static int ipu_submit_buffer(struct idmac_channel *ichan, | |||
816 | { | 812 | { |
817 | unsigned int chan_id = ichan->dma_chan.chan_id; | 813 | unsigned int chan_id = ichan->dma_chan.chan_id; |
818 | struct device *dev = &ichan->dma_chan.dev->device; | 814 | struct device *dev = &ichan->dma_chan.dev->device; |
819 | int ret; | ||
820 | 815 | ||
821 | if (async_tx_test_ack(&desc->txd)) | 816 | if (async_tx_test_ack(&desc->txd)) |
822 | return -EINTR; | 817 | return -EINTR; |
@@ -827,14 +822,7 @@ static int ipu_submit_buffer(struct idmac_channel *ichan, | |||
827 | * could make it conditional on status >= IPU_CHANNEL_ENABLED, but | 822 | * could make it conditional on status >= IPU_CHANNEL_ENABLED, but |
828 | * doing it again shouldn't hurt either. | 823 | * doing it again shouldn't hurt either. |
829 | */ | 824 | */ |
830 | ret = ipu_update_channel_buffer(ichan, buf_idx, | 825 | ipu_update_channel_buffer(ichan, buf_idx, sg_dma_address(sg)); |
831 | sg_dma_address(sg)); | ||
832 | |||
833 | if (ret < 0) { | ||
834 | dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n", | ||
835 | sg, chan_id, buf_idx); | ||
836 | return ret; | ||
837 | } | ||
838 | 826 | ||
839 | ipu_select_buffer(chan_id, buf_idx); | 827 | ipu_select_buffer(chan_id, buf_idx); |
840 | dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n", | 828 | dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n", |
@@ -1379,10 +1367,11 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) | |||
1379 | 1367 | ||
1380 | if (likely(sgnew) && | 1368 | if (likely(sgnew) && |
1381 | ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) { | 1369 | ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) { |
1382 | callback = desc->txd.callback; | 1370 | callback = descnew->txd.callback; |
1383 | callback_param = desc->txd.callback_param; | 1371 | callback_param = descnew->txd.callback_param; |
1384 | spin_unlock(&ichan->lock); | 1372 | spin_unlock(&ichan->lock); |
1385 | callback(callback_param); | 1373 | if (callback) |
1374 | callback(callback_param); | ||
1386 | spin_lock(&ichan->lock); | 1375 | spin_lock(&ichan->lock); |
1387 | } | 1376 | } |
1388 | 1377 | ||
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 000dc67b85b7..3391e6739d06 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -2658,10 +2658,11 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt) | |||
2658 | * the memory system completely. A command line option allows to force-enable | 2658 | * the memory system completely. A command line option allows to force-enable |
2659 | * hardware ECC later in amd64_enable_ecc_error_reporting(). | 2659 | * hardware ECC later in amd64_enable_ecc_error_reporting(). |
2660 | */ | 2660 | */ |
2661 | static const char *ecc_warning = | 2661 | static const char *ecc_msg = |
2662 | "WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n" | 2662 | "ECC disabled in the BIOS or no ECC capability, module will not load.\n" |
2663 | " Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n" | 2663 | " Either enable ECC checking or force module loading by setting " |
2664 | " Also, use of the override can cause unknown side effects.\n"; | 2664 | "'ecc_enable_override'.\n" |
2665 | " (Note that use of the override may cause unknown side effects.)\n"; | ||
2665 | 2666 | ||
2666 | static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | 2667 | static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) |
2667 | { | 2668 | { |
@@ -2673,7 +2674,7 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | |||
2673 | 2674 | ||
2674 | ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE); | 2675 | ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE); |
2675 | if (!ecc_enabled) | 2676 | if (!ecc_enabled) |
2676 | amd64_printk(KERN_WARNING, "This node reports that Memory ECC " | 2677 | amd64_printk(KERN_NOTICE, "This node reports that Memory ECC " |
2677 | "is currently disabled, set F3x%x[22] (%s).\n", | 2678 | "is currently disabled, set F3x%x[22] (%s).\n", |
2678 | K8_NBCFG, pci_name(pvt->misc_f3_ctl)); | 2679 | K8_NBCFG, pci_name(pvt->misc_f3_ctl)); |
2679 | else | 2680 | else |
@@ -2681,13 +2682,13 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | |||
2681 | 2682 | ||
2682 | nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id); | 2683 | nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id); |
2683 | if (!nb_mce_en) | 2684 | if (!nb_mce_en) |
2684 | amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR " | 2685 | amd64_printk(KERN_NOTICE, "NB MCE bank disabled, set MSR " |
2685 | "0x%08x[4] on node %d to enable.\n", | 2686 | "0x%08x[4] on node %d to enable.\n", |
2686 | MSR_IA32_MCG_CTL, pvt->mc_node_id); | 2687 | MSR_IA32_MCG_CTL, pvt->mc_node_id); |
2687 | 2688 | ||
2688 | if (!ecc_enabled || !nb_mce_en) { | 2689 | if (!ecc_enabled || !nb_mce_en) { |
2689 | if (!ecc_enable_override) { | 2690 | if (!ecc_enable_override) { |
2690 | amd64_printk(KERN_WARNING, "%s", ecc_warning); | 2691 | amd64_printk(KERN_NOTICE, "%s", ecc_msg); |
2691 | return -ENODEV; | 2692 | return -ENODEV; |
2692 | } | 2693 | } |
2693 | ecc_enable_override = 0; | 2694 | ecc_enable_override = 0; |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index cf27402af97b..ecd5928d7110 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -804,8 +804,8 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) | |||
804 | end <<= (24 - PAGE_SHIFT); | 804 | end <<= (24 - PAGE_SHIFT); |
805 | end |= (1 << (24 - PAGE_SHIFT)) - 1; | 805 | end |= (1 << (24 - PAGE_SHIFT)) - 1; |
806 | 806 | ||
807 | csrow->first_page = start >> PAGE_SHIFT; | 807 | csrow->first_page = start; |
808 | csrow->last_page = end >> PAGE_SHIFT; | 808 | csrow->last_page = end; |
809 | csrow->nr_pages = end + 1 - start; | 809 | csrow->nr_pages = end + 1 - start; |
810 | csrow->grain = 8; | 810 | csrow->grain = 8; |
811 | csrow->mtype = mtype; | 811 | csrow->mtype = mtype; |
@@ -892,10 +892,6 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op, | |||
892 | 892 | ||
893 | mpc85xx_init_csrows(mci); | 893 | mpc85xx_init_csrows(mci); |
894 | 894 | ||
895 | #ifdef CONFIG_EDAC_DEBUG | ||
896 | edac_mc_register_mcidev_debug((struct attribute **)debug_attr); | ||
897 | #endif | ||
898 | |||
899 | /* store the original error disable bits */ | 895 | /* store the original error disable bits */ |
900 | orig_ddr_err_disable = | 896 | orig_ddr_err_disable = |
901 | in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE); | 897 | in_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE); |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index cbaf420c36c5..2d3dc7ded0a9 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -893,20 +893,31 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, | |||
893 | 893 | ||
894 | static struct kmem_cache *fwnet_packet_task_cache; | 894 | static struct kmem_cache *fwnet_packet_task_cache; |
895 | 895 | ||
896 | static void fwnet_free_ptask(struct fwnet_packet_task *ptask) | ||
897 | { | ||
898 | dev_kfree_skb_any(ptask->skb); | ||
899 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
900 | } | ||
901 | |||
896 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); | 902 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); |
897 | 903 | ||
898 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | 904 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) |
899 | { | 905 | { |
900 | struct fwnet_device *dev; | 906 | struct fwnet_device *dev = ptask->dev; |
901 | unsigned long flags; | 907 | unsigned long flags; |
902 | 908 | bool free; | |
903 | dev = ptask->dev; | ||
904 | 909 | ||
905 | spin_lock_irqsave(&dev->lock, flags); | 910 | spin_lock_irqsave(&dev->lock, flags); |
906 | list_del(&ptask->pt_link); | ||
907 | spin_unlock_irqrestore(&dev->lock, flags); | ||
908 | 911 | ||
909 | ptask->outstanding_pkts--; /* FIXME access inside lock */ | 912 | ptask->outstanding_pkts--; |
913 | |||
914 | /* Check whether we or the networking TX soft-IRQ is last user. */ | ||
915 | free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); | ||
916 | |||
917 | if (ptask->outstanding_pkts == 0) | ||
918 | list_del(&ptask->pt_link); | ||
919 | |||
920 | spin_unlock_irqrestore(&dev->lock, flags); | ||
910 | 921 | ||
911 | if (ptask->outstanding_pkts > 0) { | 922 | if (ptask->outstanding_pkts > 0) { |
912 | u16 dg_size; | 923 | u16 dg_size; |
@@ -951,10 +962,10 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
951 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; | 962 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; |
952 | } | 963 | } |
953 | fwnet_send_packet(ptask); | 964 | fwnet_send_packet(ptask); |
954 | } else { | ||
955 | dev_kfree_skb_any(ptask->skb); | ||
956 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
957 | } | 965 | } |
966 | |||
967 | if (free) | ||
968 | fwnet_free_ptask(ptask); | ||
958 | } | 969 | } |
959 | 970 | ||
960 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 971 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
@@ -977,6 +988,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
977 | unsigned tx_len; | 988 | unsigned tx_len; |
978 | struct rfc2734_header *bufhdr; | 989 | struct rfc2734_header *bufhdr; |
979 | unsigned long flags; | 990 | unsigned long flags; |
991 | bool free; | ||
980 | 992 | ||
981 | dev = ptask->dev; | 993 | dev = ptask->dev; |
982 | tx_len = ptask->max_payload; | 994 | tx_len = ptask->max_payload; |
@@ -1022,12 +1034,16 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1022 | generation, SCODE_100, 0ULL, ptask->skb->data, | 1034 | generation, SCODE_100, 0ULL, ptask->skb->data, |
1023 | tx_len + 8, fwnet_write_complete, ptask); | 1035 | tx_len + 8, fwnet_write_complete, ptask); |
1024 | 1036 | ||
1025 | /* FIXME race? */ | ||
1026 | spin_lock_irqsave(&dev->lock, flags); | 1037 | spin_lock_irqsave(&dev->lock, flags); |
1027 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | 1038 | |
1039 | /* If the AT tasklet already ran, we may be last user. */ | ||
1040 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
1041 | if (!free) | ||
1042 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | ||
1043 | |||
1028 | spin_unlock_irqrestore(&dev->lock, flags); | 1044 | spin_unlock_irqrestore(&dev->lock, flags); |
1029 | 1045 | ||
1030 | return 0; | 1046 | goto out; |
1031 | } | 1047 | } |
1032 | 1048 | ||
1033 | fw_send_request(dev->card, &ptask->transaction, | 1049 | fw_send_request(dev->card, &ptask->transaction, |
@@ -1035,12 +1051,19 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
1035 | ptask->generation, ptask->speed, ptask->fifo_addr, | 1051 | ptask->generation, ptask->speed, ptask->fifo_addr, |
1036 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); | 1052 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); |
1037 | 1053 | ||
1038 | /* FIXME race? */ | ||
1039 | spin_lock_irqsave(&dev->lock, flags); | 1054 | spin_lock_irqsave(&dev->lock, flags); |
1040 | list_add_tail(&ptask->pt_link, &dev->sent_list); | 1055 | |
1056 | /* If the AT tasklet already ran, we may be last user. */ | ||
1057 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
1058 | if (!free) | ||
1059 | list_add_tail(&ptask->pt_link, &dev->sent_list); | ||
1060 | |||
1041 | spin_unlock_irqrestore(&dev->lock, flags); | 1061 | spin_unlock_irqrestore(&dev->lock, flags); |
1042 | 1062 | ||
1043 | dev->netdev->trans_start = jiffies; | 1063 | dev->netdev->trans_start = jiffies; |
1064 | out: | ||
1065 | if (free) | ||
1066 | fwnet_free_ptask(ptask); | ||
1044 | 1067 | ||
1045 | return 0; | 1068 | return 0; |
1046 | } | 1069 | } |
@@ -1298,6 +1321,8 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
1298 | spin_unlock_irqrestore(&dev->lock, flags); | 1321 | spin_unlock_irqrestore(&dev->lock, flags); |
1299 | 1322 | ||
1300 | ptask->max_payload = max_payload; | 1323 | ptask->max_payload = max_payload; |
1324 | INIT_LIST_HEAD(&ptask->pt_link); | ||
1325 | |||
1301 | fwnet_send_packet(ptask); | 1326 | fwnet_send_packet(ptask); |
1302 | 1327 | ||
1303 | return NETDEV_TX_OK; | 1328 | return NETDEV_TX_OK; |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 2345d4103fe6..43ebf337b131 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -2101,11 +2101,6 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2101 | u32 payload_index, payload_end_index, next_page_index; | 2101 | u32 payload_index, payload_end_index, next_page_index; |
2102 | int page, end_page, i, length, offset; | 2102 | int page, end_page, i, length, offset; |
2103 | 2103 | ||
2104 | /* | ||
2105 | * FIXME: Cycle lost behavior should be configurable: lose | ||
2106 | * packet, retransmit or terminate.. | ||
2107 | */ | ||
2108 | |||
2109 | p = packet; | 2104 | p = packet; |
2110 | payload_index = payload; | 2105 | payload_index = payload; |
2111 | 2106 | ||
@@ -2135,6 +2130,14 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2135 | if (!p->skip) { | 2130 | if (!p->skip) { |
2136 | d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE); | 2131 | d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE); |
2137 | d[0].req_count = cpu_to_le16(8); | 2132 | d[0].req_count = cpu_to_le16(8); |
2133 | /* | ||
2134 | * Link the skip address to this descriptor itself. This causes | ||
2135 | * a context to skip a cycle whenever lost cycles or FIFO | ||
2136 | * overruns occur, without dropping the data. The application | ||
2137 | * should then decide whether this is an error condition or not. | ||
2138 | * FIXME: Make the context's cycle-lost behaviour configurable? | ||
2139 | */ | ||
2140 | d[0].branch_address = cpu_to_le32(d_bus | z); | ||
2138 | 2141 | ||
2139 | header = (__le32 *) &d[1]; | 2142 | header = (__le32 *) &d[1]; |
2140 | header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) | | 2143 | header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) | |
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index a1fce68e3bbe..17be051b7aa3 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c | |||
@@ -113,7 +113,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga | |||
113 | 113 | ||
114 | if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { | 114 | if (pci_set_dma_mask(dev->pdev, gart_info->table_mask)) { |
115 | DRM_ERROR("fail to set dma mask to 0x%Lx\n", | 115 | DRM_ERROR("fail to set dma mask to 0x%Lx\n", |
116 | gart_info->table_mask); | 116 | (unsigned long long)gart_info->table_mask); |
117 | ret = 1; | 117 | ret = 1; |
118 | goto done; | 118 | goto done; |
119 | } | 119 | } |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index f665b05592f3..ab6c97330412 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -598,6 +598,50 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, | |||
598 | return mode; | 598 | return mode; |
599 | } | 599 | } |
600 | 600 | ||
601 | /* | ||
602 | * EDID is delightfully ambiguous about how interlaced modes are to be | ||
603 | * encoded. Our internal representation is of frame height, but some | ||
604 | * HDTV detailed timings are encoded as field height. | ||
605 | * | ||
606 | * The format list here is from CEA, in frame size. Technically we | ||
607 | * should be checking refresh rate too. Whatever. | ||
608 | */ | ||
609 | static void | ||
610 | drm_mode_do_interlace_quirk(struct drm_display_mode *mode, | ||
611 | struct detailed_pixel_timing *pt) | ||
612 | { | ||
613 | int i; | ||
614 | static const struct { | ||
615 | int w, h; | ||
616 | } cea_interlaced[] = { | ||
617 | { 1920, 1080 }, | ||
618 | { 720, 480 }, | ||
619 | { 1440, 480 }, | ||
620 | { 2880, 480 }, | ||
621 | { 720, 576 }, | ||
622 | { 1440, 576 }, | ||
623 | { 2880, 576 }, | ||
624 | }; | ||
625 | static const int n_sizes = | ||
626 | sizeof(cea_interlaced)/sizeof(cea_interlaced[0]); | ||
627 | |||
628 | if (!(pt->misc & DRM_EDID_PT_INTERLACED)) | ||
629 | return; | ||
630 | |||
631 | for (i = 0; i < n_sizes; i++) { | ||
632 | if ((mode->hdisplay == cea_interlaced[i].w) && | ||
633 | (mode->vdisplay == cea_interlaced[i].h / 2)) { | ||
634 | mode->vdisplay *= 2; | ||
635 | mode->vsync_start *= 2; | ||
636 | mode->vsync_end *= 2; | ||
637 | mode->vtotal *= 2; | ||
638 | mode->vtotal |= 1; | ||
639 | } | ||
640 | } | ||
641 | |||
642 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
643 | } | ||
644 | |||
601 | /** | 645 | /** |
602 | * drm_mode_detailed - create a new mode from an EDID detailed timing section | 646 | * drm_mode_detailed - create a new mode from an EDID detailed timing section |
603 | * @dev: DRM device (needed to create new mode) | 647 | * @dev: DRM device (needed to create new mode) |
@@ -680,8 +724,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
680 | 724 | ||
681 | drm_mode_set_name(mode); | 725 | drm_mode_set_name(mode); |
682 | 726 | ||
683 | if (pt->misc & DRM_EDID_PT_INTERLACED) | 727 | drm_mode_do_interlace_quirk(mode, pt); |
684 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
685 | 728 | ||
686 | if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { | 729 | if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { |
687 | pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; | 730 | pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index cdec32977129..2ac074c8f5d2 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -405,7 +405,8 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
405 | wasted += alignment - tmp; | 405 | wasted += alignment - tmp; |
406 | } | 406 | } |
407 | 407 | ||
408 | if (entry->size >= size + wasted) { | 408 | if (entry->size >= size + wasted && |
409 | (entry->start + wasted + size) <= end) { | ||
409 | if (!best_match) | 410 | if (!best_match) |
410 | return entry; | 411 | return entry; |
411 | if (entry->size < best_size) { | 412 | if (entry->size < best_size) { |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e660ac07f3b2..2307f98349f7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -735,8 +735,10 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
735 | if (cmdbuf->num_cliprects) { | 735 | if (cmdbuf->num_cliprects) { |
736 | cliprects = kcalloc(cmdbuf->num_cliprects, | 736 | cliprects = kcalloc(cmdbuf->num_cliprects, |
737 | sizeof(struct drm_clip_rect), GFP_KERNEL); | 737 | sizeof(struct drm_clip_rect), GFP_KERNEL); |
738 | if (cliprects == NULL) | 738 | if (cliprects == NULL) { |
739 | ret = -ENOMEM; | ||
739 | goto fail_batch_free; | 740 | goto fail_batch_free; |
741 | } | ||
740 | 742 | ||
741 | ret = copy_from_user(cliprects, cmdbuf->cliprects, | 743 | ret = copy_from_user(cliprects, cmdbuf->cliprects, |
742 | cmdbuf->num_cliprects * | 744 | cmdbuf->num_cliprects * |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 46d88965852a..cf4cb3e9a0c2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -120,7 +120,7 @@ const static struct intel_device_info intel_gm45_info = { | |||
120 | 120 | ||
121 | const static struct intel_device_info intel_pineview_info = { | 121 | const static struct intel_device_info intel_pineview_info = { |
122 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, | 122 | .is_g33 = 1, .is_pineview = 1, .is_mobile = 1, .is_i9xx = 1, |
123 | .has_pipe_cxsr = 1, | 123 | .need_gfx_hws = 1, |
124 | .has_hotplug = 1, | 124 | .has_hotplug = 1, |
125 | }; | 125 | }; |
126 | 126 | ||
@@ -174,26 +174,20 @@ const static struct pci_device_id pciidlist[] = { | |||
174 | MODULE_DEVICE_TABLE(pci, pciidlist); | 174 | MODULE_DEVICE_TABLE(pci, pciidlist); |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | static int i915_suspend(struct drm_device *dev, pm_message_t state) | 177 | static int i915_drm_freeze(struct drm_device *dev) |
178 | { | 178 | { |
179 | struct drm_i915_private *dev_priv = dev->dev_private; | 179 | struct drm_i915_private *dev_priv = dev->dev_private; |
180 | 180 | ||
181 | if (!dev || !dev_priv) { | ||
182 | DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); | ||
183 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); | ||
184 | return -ENODEV; | ||
185 | } | ||
186 | |||
187 | if (state.event == PM_EVENT_PRETHAW) | ||
188 | return 0; | ||
189 | |||
190 | pci_save_state(dev->pdev); | 181 | pci_save_state(dev->pdev); |
191 | 182 | ||
192 | /* If KMS is active, we do the leavevt stuff here */ | 183 | /* If KMS is active, we do the leavevt stuff here */ |
193 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 184 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
194 | if (i915_gem_idle(dev)) | 185 | int error = i915_gem_idle(dev); |
186 | if (error) { | ||
195 | dev_err(&dev->pdev->dev, | 187 | dev_err(&dev->pdev->dev, |
196 | "GEM idle failed, resume may fail\n"); | 188 | "GEM idle failed, resume might fail\n"); |
189 | return error; | ||
190 | } | ||
197 | drm_irq_uninstall(dev); | 191 | drm_irq_uninstall(dev); |
198 | } | 192 | } |
199 | 193 | ||
@@ -201,26 +195,42 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
201 | 195 | ||
202 | intel_opregion_free(dev, 1); | 196 | intel_opregion_free(dev, 1); |
203 | 197 | ||
198 | /* Modeset on resume, not lid events */ | ||
199 | dev_priv->modeset_on_lid = 0; | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int i915_suspend(struct drm_device *dev, pm_message_t state) | ||
205 | { | ||
206 | int error; | ||
207 | |||
208 | if (!dev || !dev->dev_private) { | ||
209 | DRM_ERROR("dev: %p\n", dev); | ||
210 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); | ||
211 | return -ENODEV; | ||
212 | } | ||
213 | |||
214 | if (state.event == PM_EVENT_PRETHAW) | ||
215 | return 0; | ||
216 | |||
217 | error = i915_drm_freeze(dev); | ||
218 | if (error) | ||
219 | return error; | ||
220 | |||
204 | if (state.event == PM_EVENT_SUSPEND) { | 221 | if (state.event == PM_EVENT_SUSPEND) { |
205 | /* Shut down the device */ | 222 | /* Shut down the device */ |
206 | pci_disable_device(dev->pdev); | 223 | pci_disable_device(dev->pdev); |
207 | pci_set_power_state(dev->pdev, PCI_D3hot); | 224 | pci_set_power_state(dev->pdev, PCI_D3hot); |
208 | } | 225 | } |
209 | 226 | ||
210 | /* Modeset on resume, not lid events */ | ||
211 | dev_priv->modeset_on_lid = 0; | ||
212 | |||
213 | return 0; | 227 | return 0; |
214 | } | 228 | } |
215 | 229 | ||
216 | static int i915_resume(struct drm_device *dev) | 230 | static int i915_drm_thaw(struct drm_device *dev) |
217 | { | 231 | { |
218 | struct drm_i915_private *dev_priv = dev->dev_private; | 232 | struct drm_i915_private *dev_priv = dev->dev_private; |
219 | int ret = 0; | 233 | int error = 0; |
220 | |||
221 | if (pci_enable_device(dev->pdev)) | ||
222 | return -1; | ||
223 | pci_set_master(dev->pdev); | ||
224 | 234 | ||
225 | i915_restore_state(dev); | 235 | i915_restore_state(dev); |
226 | 236 | ||
@@ -231,21 +241,28 @@ static int i915_resume(struct drm_device *dev) | |||
231 | mutex_lock(&dev->struct_mutex); | 241 | mutex_lock(&dev->struct_mutex); |
232 | dev_priv->mm.suspended = 0; | 242 | dev_priv->mm.suspended = 0; |
233 | 243 | ||
234 | ret = i915_gem_init_ringbuffer(dev); | 244 | error = i915_gem_init_ringbuffer(dev); |
235 | if (ret != 0) | ||
236 | ret = -1; | ||
237 | mutex_unlock(&dev->struct_mutex); | 245 | mutex_unlock(&dev->struct_mutex); |
238 | 246 | ||
239 | drm_irq_install(dev); | 247 | drm_irq_install(dev); |
240 | } | 248 | |
241 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
242 | /* Resume the modeset for every activated CRTC */ | 249 | /* Resume the modeset for every activated CRTC */ |
243 | drm_helper_resume_force_mode(dev); | 250 | drm_helper_resume_force_mode(dev); |
244 | } | 251 | } |
245 | 252 | ||
246 | dev_priv->modeset_on_lid = 0; | 253 | dev_priv->modeset_on_lid = 0; |
247 | 254 | ||
248 | return ret; | 255 | return error; |
256 | } | ||
257 | |||
258 | static int i915_resume(struct drm_device *dev) | ||
259 | { | ||
260 | if (pci_enable_device(dev->pdev)) | ||
261 | return -EIO; | ||
262 | |||
263 | pci_set_master(dev->pdev); | ||
264 | |||
265 | return i915_drm_thaw(dev); | ||
249 | } | 266 | } |
250 | 267 | ||
251 | /** | 268 | /** |
@@ -386,57 +403,62 @@ i915_pci_remove(struct pci_dev *pdev) | |||
386 | drm_put_dev(dev); | 403 | drm_put_dev(dev); |
387 | } | 404 | } |
388 | 405 | ||
389 | static int | 406 | static int i915_pm_suspend(struct device *dev) |
390 | i915_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
391 | { | 407 | { |
392 | struct drm_device *dev = pci_get_drvdata(pdev); | 408 | struct pci_dev *pdev = to_pci_dev(dev); |
409 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
410 | int error; | ||
393 | 411 | ||
394 | return i915_suspend(dev, state); | 412 | if (!drm_dev || !drm_dev->dev_private) { |
395 | } | 413 | dev_err(dev, "DRM not initialized, aborting suspend.\n"); |
414 | return -ENODEV; | ||
415 | } | ||
396 | 416 | ||
397 | static int | 417 | error = i915_drm_freeze(drm_dev); |
398 | i915_pci_resume(struct pci_dev *pdev) | 418 | if (error) |
399 | { | 419 | return error; |
400 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
401 | 420 | ||
402 | return i915_resume(dev); | 421 | pci_disable_device(pdev); |
403 | } | 422 | pci_set_power_state(pdev, PCI_D3hot); |
404 | 423 | ||
405 | static int | 424 | return 0; |
406 | i915_pm_suspend(struct device *dev) | ||
407 | { | ||
408 | return i915_pci_suspend(to_pci_dev(dev), PMSG_SUSPEND); | ||
409 | } | 425 | } |
410 | 426 | ||
411 | static int | 427 | static int i915_pm_resume(struct device *dev) |
412 | i915_pm_resume(struct device *dev) | ||
413 | { | 428 | { |
414 | return i915_pci_resume(to_pci_dev(dev)); | 429 | struct pci_dev *pdev = to_pci_dev(dev); |
415 | } | 430 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
416 | 431 | ||
417 | static int | 432 | return i915_resume(drm_dev); |
418 | i915_pm_freeze(struct device *dev) | ||
419 | { | ||
420 | return i915_pci_suspend(to_pci_dev(dev), PMSG_FREEZE); | ||
421 | } | 433 | } |
422 | 434 | ||
423 | static int | 435 | static int i915_pm_freeze(struct device *dev) |
424 | i915_pm_thaw(struct device *dev) | ||
425 | { | 436 | { |
426 | /* thaw during hibernate, do nothing! */ | 437 | struct pci_dev *pdev = to_pci_dev(dev); |
427 | return 0; | 438 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
439 | |||
440 | if (!drm_dev || !drm_dev->dev_private) { | ||
441 | dev_err(dev, "DRM not initialized, aborting suspend.\n"); | ||
442 | return -ENODEV; | ||
443 | } | ||
444 | |||
445 | return i915_drm_freeze(drm_dev); | ||
428 | } | 446 | } |
429 | 447 | ||
430 | static int | 448 | static int i915_pm_thaw(struct device *dev) |
431 | i915_pm_poweroff(struct device *dev) | ||
432 | { | 449 | { |
433 | return i915_pci_suspend(to_pci_dev(dev), PMSG_HIBERNATE); | 450 | struct pci_dev *pdev = to_pci_dev(dev); |
451 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
452 | |||
453 | return i915_drm_thaw(drm_dev); | ||
434 | } | 454 | } |
435 | 455 | ||
436 | static int | 456 | static int i915_pm_poweroff(struct device *dev) |
437 | i915_pm_restore(struct device *dev) | ||
438 | { | 457 | { |
439 | return i915_pci_resume(to_pci_dev(dev)); | 458 | struct pci_dev *pdev = to_pci_dev(dev); |
459 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
460 | |||
461 | return i915_drm_freeze(drm_dev); | ||
440 | } | 462 | } |
441 | 463 | ||
442 | const struct dev_pm_ops i915_pm_ops = { | 464 | const struct dev_pm_ops i915_pm_ops = { |
@@ -445,7 +467,7 @@ const struct dev_pm_ops i915_pm_ops = { | |||
445 | .freeze = i915_pm_freeze, | 467 | .freeze = i915_pm_freeze, |
446 | .thaw = i915_pm_thaw, | 468 | .thaw = i915_pm_thaw, |
447 | .poweroff = i915_pm_poweroff, | 469 | .poweroff = i915_pm_poweroff, |
448 | .restore = i915_pm_restore, | 470 | .restore = i915_pm_resume, |
449 | }; | 471 | }; |
450 | 472 | ||
451 | static struct vm_operations_struct i915_gem_vm_ops = { | 473 | static struct vm_operations_struct i915_gem_vm_ops = { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index aaf934d96f21..b99b6a841d95 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -493,6 +493,15 @@ typedef struct drm_i915_private { | |||
493 | struct list_head flushing_list; | 493 | struct list_head flushing_list; |
494 | 494 | ||
495 | /** | 495 | /** |
496 | * List of objects currently pending a GPU write flush. | ||
497 | * | ||
498 | * All elements on this list will belong to either the | ||
499 | * active_list or flushing_list, last_rendering_seqno can | ||
500 | * be used to differentiate between the two elements. | ||
501 | */ | ||
502 | struct list_head gpu_write_list; | ||
503 | |||
504 | /** | ||
496 | * LRU list of objects which are not in the ringbuffer and | 505 | * LRU list of objects which are not in the ringbuffer and |
497 | * are ready to unbind, but are still in the GTT. | 506 | * are ready to unbind, but are still in the GTT. |
498 | * | 507 | * |
@@ -592,6 +601,8 @@ struct drm_i915_gem_object { | |||
592 | 601 | ||
593 | /** This object's place on the active/flushing/inactive lists */ | 602 | /** This object's place on the active/flushing/inactive lists */ |
594 | struct list_head list; | 603 | struct list_head list; |
604 | /** This object's place on GPU write list */ | ||
605 | struct list_head gpu_write_list; | ||
595 | 606 | ||
596 | /** This object's place on the fenced object LRU */ | 607 | /** This object's place on the fenced object LRU */ |
597 | struct list_head fence_list; | 608 | struct list_head fence_list; |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index dda787aafcc6..ec8a0d7ffa39 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1552,6 +1552,8 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj) | |||
1552 | else | 1552 | else |
1553 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | 1553 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); |
1554 | 1554 | ||
1555 | BUG_ON(!list_empty(&obj_priv->gpu_write_list)); | ||
1556 | |||
1555 | obj_priv->last_rendering_seqno = 0; | 1557 | obj_priv->last_rendering_seqno = 0; |
1556 | if (obj_priv->active) { | 1558 | if (obj_priv->active) { |
1557 | obj_priv->active = 0; | 1559 | obj_priv->active = 0; |
@@ -1622,7 +1624,8 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1622 | struct drm_i915_gem_object *obj_priv, *next; | 1624 | struct drm_i915_gem_object *obj_priv, *next; |
1623 | 1625 | ||
1624 | list_for_each_entry_safe(obj_priv, next, | 1626 | list_for_each_entry_safe(obj_priv, next, |
1625 | &dev_priv->mm.flushing_list, list) { | 1627 | &dev_priv->mm.gpu_write_list, |
1628 | gpu_write_list) { | ||
1626 | struct drm_gem_object *obj = obj_priv->obj; | 1629 | struct drm_gem_object *obj = obj_priv->obj; |
1627 | 1630 | ||
1628 | if ((obj->write_domain & flush_domains) == | 1631 | if ((obj->write_domain & flush_domains) == |
@@ -1630,6 +1633,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
1630 | uint32_t old_write_domain = obj->write_domain; | 1633 | uint32_t old_write_domain = obj->write_domain; |
1631 | 1634 | ||
1632 | obj->write_domain = 0; | 1635 | obj->write_domain = 0; |
1636 | list_del_init(&obj_priv->gpu_write_list); | ||
1633 | i915_gem_object_move_to_active(obj, seqno); | 1637 | i915_gem_object_move_to_active(obj, seqno); |
1634 | 1638 | ||
1635 | trace_i915_gem_object_change_domain(obj, | 1639 | trace_i915_gem_object_change_domain(obj, |
@@ -2084,8 +2088,8 @@ static int | |||
2084 | i915_gem_evict_everything(struct drm_device *dev) | 2088 | i915_gem_evict_everything(struct drm_device *dev) |
2085 | { | 2089 | { |
2086 | drm_i915_private_t *dev_priv = dev->dev_private; | 2090 | drm_i915_private_t *dev_priv = dev->dev_private; |
2087 | uint32_t seqno; | ||
2088 | int ret; | 2091 | int ret; |
2092 | uint32_t seqno; | ||
2089 | bool lists_empty; | 2093 | bool lists_empty; |
2090 | 2094 | ||
2091 | spin_lock(&dev_priv->mm.active_list_lock); | 2095 | spin_lock(&dev_priv->mm.active_list_lock); |
@@ -2107,6 +2111,8 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
2107 | if (ret) | 2111 | if (ret) |
2108 | return ret; | 2112 | return ret; |
2109 | 2113 | ||
2114 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2115 | |||
2110 | ret = i915_gem_evict_from_inactive_list(dev); | 2116 | ret = i915_gem_evict_from_inactive_list(dev); |
2111 | if (ret) | 2117 | if (ret) |
2112 | return ret; | 2118 | return ret; |
@@ -2701,7 +2707,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) | |||
2701 | old_write_domain = obj->write_domain; | 2707 | old_write_domain = obj->write_domain; |
2702 | i915_gem_flush(dev, 0, obj->write_domain); | 2708 | i915_gem_flush(dev, 0, obj->write_domain); |
2703 | seqno = i915_add_request(dev, NULL, obj->write_domain); | 2709 | seqno = i915_add_request(dev, NULL, obj->write_domain); |
2704 | obj->write_domain = 0; | 2710 | BUG_ON(obj->write_domain); |
2705 | i915_gem_object_move_to_active(obj, seqno); | 2711 | i915_gem_object_move_to_active(obj, seqno); |
2706 | 2712 | ||
2707 | trace_i915_gem_object_change_domain(obj, | 2713 | trace_i915_gem_object_change_domain(obj, |
@@ -3564,6 +3570,9 @@ i915_gem_put_relocs_to_user(struct drm_i915_gem_exec_object2 *exec_list, | |||
3564 | uint32_t reloc_count = 0, i; | 3570 | uint32_t reloc_count = 0, i; |
3565 | int ret = 0; | 3571 | int ret = 0; |
3566 | 3572 | ||
3573 | if (relocs == NULL) | ||
3574 | return 0; | ||
3575 | |||
3567 | for (i = 0; i < buffer_count; i++) { | 3576 | for (i = 0; i < buffer_count; i++) { |
3568 | struct drm_i915_gem_relocation_entry __user *user_relocs; | 3577 | struct drm_i915_gem_relocation_entry __user *user_relocs; |
3569 | int unwritten; | 3578 | int unwritten; |
@@ -3653,7 +3662,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3653 | struct drm_gem_object *batch_obj; | 3662 | struct drm_gem_object *batch_obj; |
3654 | struct drm_i915_gem_object *obj_priv; | 3663 | struct drm_i915_gem_object *obj_priv; |
3655 | struct drm_clip_rect *cliprects = NULL; | 3664 | struct drm_clip_rect *cliprects = NULL; |
3656 | struct drm_i915_gem_relocation_entry *relocs; | 3665 | struct drm_i915_gem_relocation_entry *relocs = NULL; |
3657 | int ret = 0, ret2, i, pinned = 0; | 3666 | int ret = 0, ret2, i, pinned = 0; |
3658 | uint64_t exec_offset; | 3667 | uint64_t exec_offset; |
3659 | uint32_t seqno, flush_domains, reloc_index; | 3668 | uint32_t seqno, flush_domains, reloc_index; |
@@ -3679,8 +3688,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3679 | if (args->num_cliprects != 0) { | 3688 | if (args->num_cliprects != 0) { |
3680 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), | 3689 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), |
3681 | GFP_KERNEL); | 3690 | GFP_KERNEL); |
3682 | if (cliprects == NULL) | 3691 | if (cliprects == NULL) { |
3692 | ret = -ENOMEM; | ||
3683 | goto pre_mutex_err; | 3693 | goto pre_mutex_err; |
3694 | } | ||
3684 | 3695 | ||
3685 | ret = copy_from_user(cliprects, | 3696 | ret = copy_from_user(cliprects, |
3686 | (struct drm_clip_rect __user *) | 3697 | (struct drm_clip_rect __user *) |
@@ -3722,6 +3733,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3722 | if (object_list[i] == NULL) { | 3733 | if (object_list[i] == NULL) { |
3723 | DRM_ERROR("Invalid object handle %d at index %d\n", | 3734 | DRM_ERROR("Invalid object handle %d at index %d\n", |
3724 | exec_list[i].handle, i); | 3735 | exec_list[i].handle, i); |
3736 | /* prevent error path from reading uninitialized data */ | ||
3737 | args->buffer_count = i + 1; | ||
3725 | ret = -EBADF; | 3738 | ret = -EBADF; |
3726 | goto err; | 3739 | goto err; |
3727 | } | 3740 | } |
@@ -3730,6 +3743,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3730 | if (obj_priv->in_execbuffer) { | 3743 | if (obj_priv->in_execbuffer) { |
3731 | DRM_ERROR("Object %p appears more than once in object list\n", | 3744 | DRM_ERROR("Object %p appears more than once in object list\n", |
3732 | object_list[i]); | 3745 | object_list[i]); |
3746 | /* prevent error path from reading uninitialized data */ | ||
3747 | args->buffer_count = i + 1; | ||
3733 | ret = -EBADF; | 3748 | ret = -EBADF; |
3734 | goto err; | 3749 | goto err; |
3735 | } | 3750 | } |
@@ -3843,16 +3858,23 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3843 | i915_gem_flush(dev, | 3858 | i915_gem_flush(dev, |
3844 | dev->invalidate_domains, | 3859 | dev->invalidate_domains, |
3845 | dev->flush_domains); | 3860 | dev->flush_domains); |
3846 | if (dev->flush_domains) | 3861 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) |
3847 | (void)i915_add_request(dev, file_priv, | 3862 | (void)i915_add_request(dev, file_priv, |
3848 | dev->flush_domains); | 3863 | dev->flush_domains); |
3849 | } | 3864 | } |
3850 | 3865 | ||
3851 | for (i = 0; i < args->buffer_count; i++) { | 3866 | for (i = 0; i < args->buffer_count; i++) { |
3852 | struct drm_gem_object *obj = object_list[i]; | 3867 | struct drm_gem_object *obj = object_list[i]; |
3868 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
3853 | uint32_t old_write_domain = obj->write_domain; | 3869 | uint32_t old_write_domain = obj->write_domain; |
3854 | 3870 | ||
3855 | obj->write_domain = obj->pending_write_domain; | 3871 | obj->write_domain = obj->pending_write_domain; |
3872 | if (obj->write_domain) | ||
3873 | list_move_tail(&obj_priv->gpu_write_list, | ||
3874 | &dev_priv->mm.gpu_write_list); | ||
3875 | else | ||
3876 | list_del_init(&obj_priv->gpu_write_list); | ||
3877 | |||
3856 | trace_i915_gem_object_change_domain(obj, | 3878 | trace_i915_gem_object_change_domain(obj, |
3857 | obj->read_domains, | 3879 | obj->read_domains, |
3858 | old_write_domain); | 3880 | old_write_domain); |
@@ -3926,6 +3948,7 @@ err: | |||
3926 | 3948 | ||
3927 | mutex_unlock(&dev->struct_mutex); | 3949 | mutex_unlock(&dev->struct_mutex); |
3928 | 3950 | ||
3951 | pre_mutex_err: | ||
3929 | /* Copy the updated relocations out regardless of current error | 3952 | /* Copy the updated relocations out regardless of current error |
3930 | * state. Failure to update the relocs would mean that the next | 3953 | * state. Failure to update the relocs would mean that the next |
3931 | * time userland calls execbuf, it would do so with presumed offset | 3954 | * time userland calls execbuf, it would do so with presumed offset |
@@ -3940,7 +3963,6 @@ err: | |||
3940 | ret = ret2; | 3963 | ret = ret2; |
3941 | } | 3964 | } |
3942 | 3965 | ||
3943 | pre_mutex_err: | ||
3944 | drm_free_large(object_list); | 3966 | drm_free_large(object_list); |
3945 | kfree(cliprects); | 3967 | kfree(cliprects); |
3946 | 3968 | ||
@@ -4363,6 +4385,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
4363 | obj_priv->obj = obj; | 4385 | obj_priv->obj = obj; |
4364 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 4386 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
4365 | INIT_LIST_HEAD(&obj_priv->list); | 4387 | INIT_LIST_HEAD(&obj_priv->list); |
4388 | INIT_LIST_HEAD(&obj_priv->gpu_write_list); | ||
4366 | INIT_LIST_HEAD(&obj_priv->fence_list); | 4389 | INIT_LIST_HEAD(&obj_priv->fence_list); |
4367 | obj_priv->madv = I915_MADV_WILLNEED; | 4390 | obj_priv->madv = I915_MADV_WILLNEED; |
4368 | 4391 | ||
@@ -4814,6 +4837,7 @@ i915_gem_load(struct drm_device *dev) | |||
4814 | spin_lock_init(&dev_priv->mm.active_list_lock); | 4837 | spin_lock_init(&dev_priv->mm.active_list_lock); |
4815 | INIT_LIST_HEAD(&dev_priv->mm.active_list); | 4838 | INIT_LIST_HEAD(&dev_priv->mm.active_list); |
4816 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); | 4839 | INIT_LIST_HEAD(&dev_priv->mm.flushing_list); |
4840 | INIT_LIST_HEAD(&dev_priv->mm.gpu_write_list); | ||
4817 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); | 4841 | INIT_LIST_HEAD(&dev_priv->mm.inactive_list); |
4818 | INIT_LIST_HEAD(&dev_priv->mm.request_list); | 4842 | INIT_LIST_HEAD(&dev_priv->mm.request_list); |
4819 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); | 4843 | INIT_LIST_HEAD(&dev_priv->mm.fence_list); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 89a071a3e6fb..a17d6bdfe63e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -309,6 +309,22 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev) | |||
309 | if (de_iir & DE_GSE) | 309 | if (de_iir & DE_GSE) |
310 | ironlake_opregion_gse_intr(dev); | 310 | ironlake_opregion_gse_intr(dev); |
311 | 311 | ||
312 | if (de_iir & DE_PLANEA_FLIP_DONE) { | ||
313 | intel_prepare_page_flip(dev, 0); | ||
314 | intel_finish_page_flip(dev, 0); | ||
315 | } | ||
316 | |||
317 | if (de_iir & DE_PLANEB_FLIP_DONE) { | ||
318 | intel_prepare_page_flip(dev, 1); | ||
319 | intel_finish_page_flip(dev, 1); | ||
320 | } | ||
321 | |||
322 | if (de_iir & DE_PIPEA_VBLANK) | ||
323 | drm_handle_vblank(dev, 0); | ||
324 | |||
325 | if (de_iir & DE_PIPEB_VBLANK) | ||
326 | drm_handle_vblank(dev, 1); | ||
327 | |||
312 | /* check event from PCH */ | 328 | /* check event from PCH */ |
313 | if ((de_iir & DE_PCH_EVENT) && | 329 | if ((de_iir & DE_PCH_EVENT) && |
314 | (pch_iir & SDE_HOTPLUG_MASK)) { | 330 | (pch_iir & SDE_HOTPLUG_MASK)) { |
@@ -844,11 +860,11 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
844 | if (!(pipeconf & PIPEACONF_ENABLE)) | 860 | if (!(pipeconf & PIPEACONF_ENABLE)) |
845 | return -EINVAL; | 861 | return -EINVAL; |
846 | 862 | ||
847 | if (IS_IRONLAKE(dev)) | ||
848 | return 0; | ||
849 | |||
850 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 863 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
851 | if (IS_I965G(dev)) | 864 | if (IS_IRONLAKE(dev)) |
865 | ironlake_enable_display_irq(dev_priv, (pipe == 0) ? | ||
866 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); | ||
867 | else if (IS_I965G(dev)) | ||
852 | i915_enable_pipestat(dev_priv, pipe, | 868 | i915_enable_pipestat(dev_priv, pipe, |
853 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 869 | PIPE_START_VBLANK_INTERRUPT_ENABLE); |
854 | else | 870 | else |
@@ -866,13 +882,14 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) | |||
866 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 882 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
867 | unsigned long irqflags; | 883 | unsigned long irqflags; |
868 | 884 | ||
869 | if (IS_IRONLAKE(dev)) | ||
870 | return; | ||
871 | |||
872 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); | 885 | spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); |
873 | i915_disable_pipestat(dev_priv, pipe, | 886 | if (IS_IRONLAKE(dev)) |
874 | PIPE_VBLANK_INTERRUPT_ENABLE | | 887 | ironlake_disable_display_irq(dev_priv, (pipe == 0) ? |
875 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | 888 | DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); |
889 | else | ||
890 | i915_disable_pipestat(dev_priv, pipe, | ||
891 | PIPE_VBLANK_INTERRUPT_ENABLE | | ||
892 | PIPE_START_VBLANK_INTERRUPT_ENABLE); | ||
876 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); | 893 | spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); |
877 | } | 894 | } |
878 | 895 | ||
@@ -1015,13 +1032,14 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1015 | { | 1032 | { |
1016 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1033 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1017 | /* enable kind of interrupts always enabled */ | 1034 | /* enable kind of interrupts always enabled */ |
1018 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT; | 1035 | u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
1036 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; | ||
1019 | u32 render_mask = GT_USER_INTERRUPT; | 1037 | u32 render_mask = GT_USER_INTERRUPT; |
1020 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | | 1038 | u32 hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG | |
1021 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; | 1039 | SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; |
1022 | 1040 | ||
1023 | dev_priv->irq_mask_reg = ~display_mask; | 1041 | dev_priv->irq_mask_reg = ~display_mask; |
1024 | dev_priv->de_irq_enable_reg = display_mask; | 1042 | dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK; |
1025 | 1043 | ||
1026 | /* should always can generate irq */ | 1044 | /* should always can generate irq */ |
1027 | I915_WRITE(DEIIR, I915_READ(DEIIR)); | 1045 | I915_WRITE(DEIIR, I915_READ(DEIIR)); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 847006c5218e..ab1bd2d3d3b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -338,6 +338,7 @@ | |||
338 | #define FBC_CTL_PERIODIC (1<<30) | 338 | #define FBC_CTL_PERIODIC (1<<30) |
339 | #define FBC_CTL_INTERVAL_SHIFT (16) | 339 | #define FBC_CTL_INTERVAL_SHIFT (16) |
340 | #define FBC_CTL_UNCOMPRESSIBLE (1<<14) | 340 | #define FBC_CTL_UNCOMPRESSIBLE (1<<14) |
341 | #define FBC_C3_IDLE (1<<13) | ||
341 | #define FBC_CTL_STRIDE_SHIFT (5) | 342 | #define FBC_CTL_STRIDE_SHIFT (5) |
342 | #define FBC_CTL_FENCENO (1<<0) | 343 | #define FBC_CTL_FENCENO (1<<0) |
343 | #define FBC_COMMAND 0x0320c | 344 | #define FBC_COMMAND 0x0320c |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ddefc871edfe..79dd4026586f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -157,6 +157,9 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
157 | adpa = I915_READ(PCH_ADPA); | 157 | adpa = I915_READ(PCH_ADPA); |
158 | 158 | ||
159 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 159 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
160 | /* disable HPD first */ | ||
161 | I915_WRITE(PCH_ADPA, adpa); | ||
162 | (void)I915_READ(PCH_ADPA); | ||
160 | 163 | ||
161 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 164 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
162 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 165 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 45da78ef4a92..b27202d23ebc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -240,33 +240,86 @@ struct intel_limit { | |||
240 | #define IRONLAKE_DOT_MAX 350000 | 240 | #define IRONLAKE_DOT_MAX 350000 |
241 | #define IRONLAKE_VCO_MIN 1760000 | 241 | #define IRONLAKE_VCO_MIN 1760000 |
242 | #define IRONLAKE_VCO_MAX 3510000 | 242 | #define IRONLAKE_VCO_MAX 3510000 |
243 | #define IRONLAKE_N_MIN 1 | ||
244 | #define IRONLAKE_N_MAX 6 | ||
245 | #define IRONLAKE_M_MIN 79 | ||
246 | #define IRONLAKE_M_MAX 127 | ||
247 | #define IRONLAKE_M1_MIN 12 | 243 | #define IRONLAKE_M1_MIN 12 |
248 | #define IRONLAKE_M1_MAX 22 | 244 | #define IRONLAKE_M1_MAX 22 |
249 | #define IRONLAKE_M2_MIN 5 | 245 | #define IRONLAKE_M2_MIN 5 |
250 | #define IRONLAKE_M2_MAX 9 | 246 | #define IRONLAKE_M2_MAX 9 |
251 | #define IRONLAKE_P_SDVO_DAC_MIN 5 | ||
252 | #define IRONLAKE_P_SDVO_DAC_MAX 80 | ||
253 | #define IRONLAKE_P_LVDS_MIN 28 | ||
254 | #define IRONLAKE_P_LVDS_MAX 112 | ||
255 | #define IRONLAKE_P1_MIN 1 | ||
256 | #define IRONLAKE_P1_MAX 8 | ||
257 | #define IRONLAKE_P2_SDVO_DAC_SLOW 10 | ||
258 | #define IRONLAKE_P2_SDVO_DAC_FAST 5 | ||
259 | #define IRONLAKE_P2_LVDS_SLOW 14 /* single channel */ | ||
260 | #define IRONLAKE_P2_LVDS_FAST 7 /* double channel */ | ||
261 | #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ | 247 | #define IRONLAKE_P2_DOT_LIMIT 225000 /* 225Mhz */ |
262 | 248 | ||
263 | #define IRONLAKE_P_DISPLAY_PORT_MIN 10 | 249 | /* We have parameter ranges for different type of outputs. */ |
264 | #define IRONLAKE_P_DISPLAY_PORT_MAX 20 | 250 | |
265 | #define IRONLAKE_P2_DISPLAY_PORT_FAST 10 | 251 | /* DAC & HDMI Refclk 120Mhz */ |
266 | #define IRONLAKE_P2_DISPLAY_PORT_SLOW 10 | 252 | #define IRONLAKE_DAC_N_MIN 1 |
267 | #define IRONLAKE_P2_DISPLAY_PORT_LIMIT 0 | 253 | #define IRONLAKE_DAC_N_MAX 5 |
268 | #define IRONLAKE_P1_DISPLAY_PORT_MIN 1 | 254 | #define IRONLAKE_DAC_M_MIN 79 |
269 | #define IRONLAKE_P1_DISPLAY_PORT_MAX 2 | 255 | #define IRONLAKE_DAC_M_MAX 127 |
256 | #define IRONLAKE_DAC_P_MIN 5 | ||
257 | #define IRONLAKE_DAC_P_MAX 80 | ||
258 | #define IRONLAKE_DAC_P1_MIN 1 | ||
259 | #define IRONLAKE_DAC_P1_MAX 8 | ||
260 | #define IRONLAKE_DAC_P2_SLOW 10 | ||
261 | #define IRONLAKE_DAC_P2_FAST 5 | ||
262 | |||
263 | /* LVDS single-channel 120Mhz refclk */ | ||
264 | #define IRONLAKE_LVDS_S_N_MIN 1 | ||
265 | #define IRONLAKE_LVDS_S_N_MAX 3 | ||
266 | #define IRONLAKE_LVDS_S_M_MIN 79 | ||
267 | #define IRONLAKE_LVDS_S_M_MAX 118 | ||
268 | #define IRONLAKE_LVDS_S_P_MIN 28 | ||
269 | #define IRONLAKE_LVDS_S_P_MAX 112 | ||
270 | #define IRONLAKE_LVDS_S_P1_MIN 2 | ||
271 | #define IRONLAKE_LVDS_S_P1_MAX 8 | ||
272 | #define IRONLAKE_LVDS_S_P2_SLOW 14 | ||
273 | #define IRONLAKE_LVDS_S_P2_FAST 14 | ||
274 | |||
275 | /* LVDS dual-channel 120Mhz refclk */ | ||
276 | #define IRONLAKE_LVDS_D_N_MIN 1 | ||
277 | #define IRONLAKE_LVDS_D_N_MAX 3 | ||
278 | #define IRONLAKE_LVDS_D_M_MIN 79 | ||
279 | #define IRONLAKE_LVDS_D_M_MAX 127 | ||
280 | #define IRONLAKE_LVDS_D_P_MIN 14 | ||
281 | #define IRONLAKE_LVDS_D_P_MAX 56 | ||
282 | #define IRONLAKE_LVDS_D_P1_MIN 2 | ||
283 | #define IRONLAKE_LVDS_D_P1_MAX 8 | ||
284 | #define IRONLAKE_LVDS_D_P2_SLOW 7 | ||
285 | #define IRONLAKE_LVDS_D_P2_FAST 7 | ||
286 | |||
287 | /* LVDS single-channel 100Mhz refclk */ | ||
288 | #define IRONLAKE_LVDS_S_SSC_N_MIN 1 | ||
289 | #define IRONLAKE_LVDS_S_SSC_N_MAX 2 | ||
290 | #define IRONLAKE_LVDS_S_SSC_M_MIN 79 | ||
291 | #define IRONLAKE_LVDS_S_SSC_M_MAX 126 | ||
292 | #define IRONLAKE_LVDS_S_SSC_P_MIN 28 | ||
293 | #define IRONLAKE_LVDS_S_SSC_P_MAX 112 | ||
294 | #define IRONLAKE_LVDS_S_SSC_P1_MIN 2 | ||
295 | #define IRONLAKE_LVDS_S_SSC_P1_MAX 8 | ||
296 | #define IRONLAKE_LVDS_S_SSC_P2_SLOW 14 | ||
297 | #define IRONLAKE_LVDS_S_SSC_P2_FAST 14 | ||
298 | |||
299 | /* LVDS dual-channel 100Mhz refclk */ | ||
300 | #define IRONLAKE_LVDS_D_SSC_N_MIN 1 | ||
301 | #define IRONLAKE_LVDS_D_SSC_N_MAX 3 | ||
302 | #define IRONLAKE_LVDS_D_SSC_M_MIN 79 | ||
303 | #define IRONLAKE_LVDS_D_SSC_M_MAX 126 | ||
304 | #define IRONLAKE_LVDS_D_SSC_P_MIN 14 | ||
305 | #define IRONLAKE_LVDS_D_SSC_P_MAX 42 | ||
306 | #define IRONLAKE_LVDS_D_SSC_P1_MIN 2 | ||
307 | #define IRONLAKE_LVDS_D_SSC_P1_MAX 6 | ||
308 | #define IRONLAKE_LVDS_D_SSC_P2_SLOW 7 | ||
309 | #define IRONLAKE_LVDS_D_SSC_P2_FAST 7 | ||
310 | |||
311 | /* DisplayPort */ | ||
312 | #define IRONLAKE_DP_N_MIN 1 | ||
313 | #define IRONLAKE_DP_N_MAX 2 | ||
314 | #define IRONLAKE_DP_M_MIN 81 | ||
315 | #define IRONLAKE_DP_M_MAX 90 | ||
316 | #define IRONLAKE_DP_P_MIN 10 | ||
317 | #define IRONLAKE_DP_P_MAX 20 | ||
318 | #define IRONLAKE_DP_P2_FAST 10 | ||
319 | #define IRONLAKE_DP_P2_SLOW 10 | ||
320 | #define IRONLAKE_DP_P2_LIMIT 0 | ||
321 | #define IRONLAKE_DP_P1_MIN 1 | ||
322 | #define IRONLAKE_DP_P1_MAX 2 | ||
270 | 323 | ||
271 | static bool | 324 | static bool |
272 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 325 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
@@ -474,33 +527,78 @@ static const intel_limit_t intel_limits_pineview_lvds = { | |||
474 | .find_pll = intel_find_best_PLL, | 527 | .find_pll = intel_find_best_PLL, |
475 | }; | 528 | }; |
476 | 529 | ||
477 | static const intel_limit_t intel_limits_ironlake_sdvo = { | 530 | static const intel_limit_t intel_limits_ironlake_dac = { |
478 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, | 531 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, |
479 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, | 532 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, |
480 | .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, | 533 | .n = { .min = IRONLAKE_DAC_N_MIN, .max = IRONLAKE_DAC_N_MAX }, |
481 | .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, | 534 | .m = { .min = IRONLAKE_DAC_M_MIN, .max = IRONLAKE_DAC_M_MAX }, |
482 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, | 535 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, |
483 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, | 536 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, |
484 | .p = { .min = IRONLAKE_P_SDVO_DAC_MIN, .max = IRONLAKE_P_SDVO_DAC_MAX }, | 537 | .p = { .min = IRONLAKE_DAC_P_MIN, .max = IRONLAKE_DAC_P_MAX }, |
485 | .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, | 538 | .p1 = { .min = IRONLAKE_DAC_P1_MIN, .max = IRONLAKE_DAC_P1_MAX }, |
486 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | 539 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, |
487 | .p2_slow = IRONLAKE_P2_SDVO_DAC_SLOW, | 540 | .p2_slow = IRONLAKE_DAC_P2_SLOW, |
488 | .p2_fast = IRONLAKE_P2_SDVO_DAC_FAST }, | 541 | .p2_fast = IRONLAKE_DAC_P2_FAST }, |
489 | .find_pll = intel_g4x_find_best_PLL, | 542 | .find_pll = intel_g4x_find_best_PLL, |
490 | }; | 543 | }; |
491 | 544 | ||
492 | static const intel_limit_t intel_limits_ironlake_lvds = { | 545 | static const intel_limit_t intel_limits_ironlake_single_lvds = { |
493 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, | 546 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, |
494 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, | 547 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, |
495 | .n = { .min = IRONLAKE_N_MIN, .max = IRONLAKE_N_MAX }, | 548 | .n = { .min = IRONLAKE_LVDS_S_N_MIN, .max = IRONLAKE_LVDS_S_N_MAX }, |
496 | .m = { .min = IRONLAKE_M_MIN, .max = IRONLAKE_M_MAX }, | 549 | .m = { .min = IRONLAKE_LVDS_S_M_MIN, .max = IRONLAKE_LVDS_S_M_MAX }, |
497 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, | 550 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, |
498 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, | 551 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, |
499 | .p = { .min = IRONLAKE_P_LVDS_MIN, .max = IRONLAKE_P_LVDS_MAX }, | 552 | .p = { .min = IRONLAKE_LVDS_S_P_MIN, .max = IRONLAKE_LVDS_S_P_MAX }, |
500 | .p1 = { .min = IRONLAKE_P1_MIN, .max = IRONLAKE_P1_MAX }, | 553 | .p1 = { .min = IRONLAKE_LVDS_S_P1_MIN, .max = IRONLAKE_LVDS_S_P1_MAX }, |
501 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | 554 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, |
502 | .p2_slow = IRONLAKE_P2_LVDS_SLOW, | 555 | .p2_slow = IRONLAKE_LVDS_S_P2_SLOW, |
503 | .p2_fast = IRONLAKE_P2_LVDS_FAST }, | 556 | .p2_fast = IRONLAKE_LVDS_S_P2_FAST }, |
557 | .find_pll = intel_g4x_find_best_PLL, | ||
558 | }; | ||
559 | |||
560 | static const intel_limit_t intel_limits_ironlake_dual_lvds = { | ||
561 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, | ||
562 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, | ||
563 | .n = { .min = IRONLAKE_LVDS_D_N_MIN, .max = IRONLAKE_LVDS_D_N_MAX }, | ||
564 | .m = { .min = IRONLAKE_LVDS_D_M_MIN, .max = IRONLAKE_LVDS_D_M_MAX }, | ||
565 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, | ||
566 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, | ||
567 | .p = { .min = IRONLAKE_LVDS_D_P_MIN, .max = IRONLAKE_LVDS_D_P_MAX }, | ||
568 | .p1 = { .min = IRONLAKE_LVDS_D_P1_MIN, .max = IRONLAKE_LVDS_D_P1_MAX }, | ||
569 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | ||
570 | .p2_slow = IRONLAKE_LVDS_D_P2_SLOW, | ||
571 | .p2_fast = IRONLAKE_LVDS_D_P2_FAST }, | ||
572 | .find_pll = intel_g4x_find_best_PLL, | ||
573 | }; | ||
574 | |||
575 | static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { | ||
576 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, | ||
577 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, | ||
578 | .n = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX }, | ||
579 | .m = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX }, | ||
580 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, | ||
581 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, | ||
582 | .p = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX }, | ||
583 | .p1 = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX }, | ||
584 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | ||
585 | .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW, | ||
586 | .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST }, | ||
587 | .find_pll = intel_g4x_find_best_PLL, | ||
588 | }; | ||
589 | |||
590 | static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { | ||
591 | .dot = { .min = IRONLAKE_DOT_MIN, .max = IRONLAKE_DOT_MAX }, | ||
592 | .vco = { .min = IRONLAKE_VCO_MIN, .max = IRONLAKE_VCO_MAX }, | ||
593 | .n = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX }, | ||
594 | .m = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX }, | ||
595 | .m1 = { .min = IRONLAKE_M1_MIN, .max = IRONLAKE_M1_MAX }, | ||
596 | .m2 = { .min = IRONLAKE_M2_MIN, .max = IRONLAKE_M2_MAX }, | ||
597 | .p = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX }, | ||
598 | .p1 = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX }, | ||
599 | .p2 = { .dot_limit = IRONLAKE_P2_DOT_LIMIT, | ||
600 | .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW, | ||
601 | .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST }, | ||
504 | .find_pll = intel_g4x_find_best_PLL, | 602 | .find_pll = intel_g4x_find_best_PLL, |
505 | }; | 603 | }; |
506 | 604 | ||
@@ -509,34 +607,53 @@ static const intel_limit_t intel_limits_ironlake_display_port = { | |||
509 | .max = IRONLAKE_DOT_MAX }, | 607 | .max = IRONLAKE_DOT_MAX }, |
510 | .vco = { .min = IRONLAKE_VCO_MIN, | 608 | .vco = { .min = IRONLAKE_VCO_MIN, |
511 | .max = IRONLAKE_VCO_MAX}, | 609 | .max = IRONLAKE_VCO_MAX}, |
512 | .n = { .min = IRONLAKE_N_MIN, | 610 | .n = { .min = IRONLAKE_DP_N_MIN, |
513 | .max = IRONLAKE_N_MAX }, | 611 | .max = IRONLAKE_DP_N_MAX }, |
514 | .m = { .min = IRONLAKE_M_MIN, | 612 | .m = { .min = IRONLAKE_DP_M_MIN, |
515 | .max = IRONLAKE_M_MAX }, | 613 | .max = IRONLAKE_DP_M_MAX }, |
516 | .m1 = { .min = IRONLAKE_M1_MIN, | 614 | .m1 = { .min = IRONLAKE_M1_MIN, |
517 | .max = IRONLAKE_M1_MAX }, | 615 | .max = IRONLAKE_M1_MAX }, |
518 | .m2 = { .min = IRONLAKE_M2_MIN, | 616 | .m2 = { .min = IRONLAKE_M2_MIN, |
519 | .max = IRONLAKE_M2_MAX }, | 617 | .max = IRONLAKE_M2_MAX }, |
520 | .p = { .min = IRONLAKE_P_DISPLAY_PORT_MIN, | 618 | .p = { .min = IRONLAKE_DP_P_MIN, |
521 | .max = IRONLAKE_P_DISPLAY_PORT_MAX }, | 619 | .max = IRONLAKE_DP_P_MAX }, |
522 | .p1 = { .min = IRONLAKE_P1_DISPLAY_PORT_MIN, | 620 | .p1 = { .min = IRONLAKE_DP_P1_MIN, |
523 | .max = IRONLAKE_P1_DISPLAY_PORT_MAX}, | 621 | .max = IRONLAKE_DP_P1_MAX}, |
524 | .p2 = { .dot_limit = IRONLAKE_P2_DISPLAY_PORT_LIMIT, | 622 | .p2 = { .dot_limit = IRONLAKE_DP_P2_LIMIT, |
525 | .p2_slow = IRONLAKE_P2_DISPLAY_PORT_SLOW, | 623 | .p2_slow = IRONLAKE_DP_P2_SLOW, |
526 | .p2_fast = IRONLAKE_P2_DISPLAY_PORT_FAST }, | 624 | .p2_fast = IRONLAKE_DP_P2_FAST }, |
527 | .find_pll = intel_find_pll_ironlake_dp, | 625 | .find_pll = intel_find_pll_ironlake_dp, |
528 | }; | 626 | }; |
529 | 627 | ||
530 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) | 628 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) |
531 | { | 629 | { |
630 | struct drm_device *dev = crtc->dev; | ||
631 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
532 | const intel_limit_t *limit; | 632 | const intel_limit_t *limit; |
533 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 633 | int refclk = 120; |
534 | limit = &intel_limits_ironlake_lvds; | 634 | |
535 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || | 635 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
636 | if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100) | ||
637 | refclk = 100; | ||
638 | |||
639 | if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == | ||
640 | LVDS_CLKB_POWER_UP) { | ||
641 | /* LVDS dual channel */ | ||
642 | if (refclk == 100) | ||
643 | limit = &intel_limits_ironlake_dual_lvds_100m; | ||
644 | else | ||
645 | limit = &intel_limits_ironlake_dual_lvds; | ||
646 | } else { | ||
647 | if (refclk == 100) | ||
648 | limit = &intel_limits_ironlake_single_lvds_100m; | ||
649 | else | ||
650 | limit = &intel_limits_ironlake_single_lvds; | ||
651 | } | ||
652 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || | ||
536 | HAS_eDP) | 653 | HAS_eDP) |
537 | limit = &intel_limits_ironlake_display_port; | 654 | limit = &intel_limits_ironlake_display_port; |
538 | else | 655 | else |
539 | limit = &intel_limits_ironlake_sdvo; | 656 | limit = &intel_limits_ironlake_dac; |
540 | 657 | ||
541 | return limit; | 658 | return limit; |
542 | } | 659 | } |
@@ -914,6 +1031,8 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
914 | 1031 | ||
915 | /* enable it... */ | 1032 | /* enable it... */ |
916 | fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; | 1033 | fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; |
1034 | if (IS_I945GM(dev)) | ||
1035 | fbc_ctl |= FBC_C3_IDLE; /* 945 needs special SR handling */ | ||
917 | fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; | 1036 | fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; |
918 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; | 1037 | fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; |
919 | if (obj_priv->tiling_mode != I915_TILING_NONE) | 1038 | if (obj_priv->tiling_mode != I915_TILING_NONE) |
@@ -1638,6 +1757,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1638 | case DRM_MODE_DPMS_OFF: | 1757 | case DRM_MODE_DPMS_OFF: |
1639 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 1758 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); |
1640 | 1759 | ||
1760 | drm_vblank_off(dev, pipe); | ||
1641 | /* Disable display plane */ | 1761 | /* Disable display plane */ |
1642 | temp = I915_READ(dspcntr_reg); | 1762 | temp = I915_READ(dspcntr_reg); |
1643 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 1763 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
@@ -2519,6 +2639,10 @@ static void g4x_update_wm(struct drm_device *dev, int planea_clock, | |||
2519 | sr_entries = roundup(sr_entries / cacheline_size, 1); | 2639 | sr_entries = roundup(sr_entries / cacheline_size, 1); |
2520 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); | 2640 | DRM_DEBUG("self-refresh entries: %d\n", sr_entries); |
2521 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 2641 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
2642 | } else { | ||
2643 | /* Turn off self refresh if both pipes are enabled */ | ||
2644 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | ||
2645 | & ~FW_BLC_SELF_EN); | ||
2522 | } | 2646 | } |
2523 | 2647 | ||
2524 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", | 2648 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, SR %d\n", |
@@ -2562,6 +2686,10 @@ static void i965_update_wm(struct drm_device *dev, int planea_clock, | |||
2562 | srwm = 1; | 2686 | srwm = 1; |
2563 | srwm &= 0x3f; | 2687 | srwm &= 0x3f; |
2564 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | 2688 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); |
2689 | } else { | ||
2690 | /* Turn off self refresh if both pipes are enabled */ | ||
2691 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | ||
2692 | & ~FW_BLC_SELF_EN); | ||
2565 | } | 2693 | } |
2566 | 2694 | ||
2567 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", | 2695 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", |
@@ -2630,6 +2758,10 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | |||
2630 | if (srwm < 0) | 2758 | if (srwm < 0) |
2631 | srwm = 1; | 2759 | srwm = 1; |
2632 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); | 2760 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); |
2761 | } else { | ||
2762 | /* Turn off self refresh if both pipes are enabled */ | ||
2763 | I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF) | ||
2764 | & ~FW_BLC_SELF_EN); | ||
2633 | } | 2765 | } |
2634 | 2766 | ||
2635 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | 2767 | DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", |
@@ -3949,7 +4081,8 @@ static void intel_crtc_destroy(struct drm_crtc *crtc) | |||
3949 | struct intel_unpin_work { | 4081 | struct intel_unpin_work { |
3950 | struct work_struct work; | 4082 | struct work_struct work; |
3951 | struct drm_device *dev; | 4083 | struct drm_device *dev; |
3952 | struct drm_gem_object *obj; | 4084 | struct drm_gem_object *old_fb_obj; |
4085 | struct drm_gem_object *pending_flip_obj; | ||
3953 | struct drm_pending_vblank_event *event; | 4086 | struct drm_pending_vblank_event *event; |
3954 | int pending; | 4087 | int pending; |
3955 | }; | 4088 | }; |
@@ -3960,8 +4093,9 @@ static void intel_unpin_work_fn(struct work_struct *__work) | |||
3960 | container_of(__work, struct intel_unpin_work, work); | 4093 | container_of(__work, struct intel_unpin_work, work); |
3961 | 4094 | ||
3962 | mutex_lock(&work->dev->struct_mutex); | 4095 | mutex_lock(&work->dev->struct_mutex); |
3963 | i915_gem_object_unpin(work->obj); | 4096 | i915_gem_object_unpin(work->old_fb_obj); |
3964 | drm_gem_object_unreference(work->obj); | 4097 | drm_gem_object_unreference(work->pending_flip_obj); |
4098 | drm_gem_object_unreference(work->old_fb_obj); | ||
3965 | mutex_unlock(&work->dev->struct_mutex); | 4099 | mutex_unlock(&work->dev->struct_mutex); |
3966 | kfree(work); | 4100 | kfree(work); |
3967 | } | 4101 | } |
@@ -3984,6 +4118,12 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
3984 | spin_lock_irqsave(&dev->event_lock, flags); | 4118 | spin_lock_irqsave(&dev->event_lock, flags); |
3985 | work = intel_crtc->unpin_work; | 4119 | work = intel_crtc->unpin_work; |
3986 | if (work == NULL || !work->pending) { | 4120 | if (work == NULL || !work->pending) { |
4121 | if (work && !work->pending) { | ||
4122 | obj_priv = work->pending_flip_obj->driver_private; | ||
4123 | DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n", | ||
4124 | obj_priv, | ||
4125 | atomic_read(&obj_priv->pending_flip)); | ||
4126 | } | ||
3987 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4127 | spin_unlock_irqrestore(&dev->event_lock, flags); |
3988 | return; | 4128 | return; |
3989 | } | 4129 | } |
@@ -4004,8 +4144,11 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) | |||
4004 | 4144 | ||
4005 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4145 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4006 | 4146 | ||
4007 | obj_priv = work->obj->driver_private; | 4147 | obj_priv = work->pending_flip_obj->driver_private; |
4008 | if (atomic_dec_and_test(&obj_priv->pending_flip)) | 4148 | |
4149 | /* Initial scanout buffer will have a 0 pending flip count */ | ||
4150 | if ((atomic_read(&obj_priv->pending_flip) == 0) || | ||
4151 | atomic_dec_and_test(&obj_priv->pending_flip)) | ||
4009 | DRM_WAKEUP(&dev_priv->pending_flip_queue); | 4152 | DRM_WAKEUP(&dev_priv->pending_flip_queue); |
4010 | schedule_work(&work->work); | 4153 | schedule_work(&work->work); |
4011 | } | 4154 | } |
@@ -4018,8 +4161,11 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) | |||
4018 | unsigned long flags; | 4161 | unsigned long flags; |
4019 | 4162 | ||
4020 | spin_lock_irqsave(&dev->event_lock, flags); | 4163 | spin_lock_irqsave(&dev->event_lock, flags); |
4021 | if (intel_crtc->unpin_work) | 4164 | if (intel_crtc->unpin_work) { |
4022 | intel_crtc->unpin_work->pending = 1; | 4165 | intel_crtc->unpin_work->pending = 1; |
4166 | } else { | ||
4167 | DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); | ||
4168 | } | ||
4023 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4169 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4024 | } | 4170 | } |
4025 | 4171 | ||
@@ -4035,7 +4181,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4035 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 4181 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
4036 | struct intel_unpin_work *work; | 4182 | struct intel_unpin_work *work; |
4037 | unsigned long flags; | 4183 | unsigned long flags; |
4038 | int ret; | 4184 | int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC; |
4185 | int ret, pipesrc; | ||
4039 | RING_LOCALS; | 4186 | RING_LOCALS; |
4040 | 4187 | ||
4041 | work = kzalloc(sizeof *work, GFP_KERNEL); | 4188 | work = kzalloc(sizeof *work, GFP_KERNEL); |
@@ -4047,12 +4194,13 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4047 | work->event = event; | 4194 | work->event = event; |
4048 | work->dev = crtc->dev; | 4195 | work->dev = crtc->dev; |
4049 | intel_fb = to_intel_framebuffer(crtc->fb); | 4196 | intel_fb = to_intel_framebuffer(crtc->fb); |
4050 | work->obj = intel_fb->obj; | 4197 | work->old_fb_obj = intel_fb->obj; |
4051 | INIT_WORK(&work->work, intel_unpin_work_fn); | 4198 | INIT_WORK(&work->work, intel_unpin_work_fn); |
4052 | 4199 | ||
4053 | /* We borrow the event spin lock for protecting unpin_work */ | 4200 | /* We borrow the event spin lock for protecting unpin_work */ |
4054 | spin_lock_irqsave(&dev->event_lock, flags); | 4201 | spin_lock_irqsave(&dev->event_lock, flags); |
4055 | if (intel_crtc->unpin_work) { | 4202 | if (intel_crtc->unpin_work) { |
4203 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | ||
4056 | spin_unlock_irqrestore(&dev->event_lock, flags); | 4204 | spin_unlock_irqrestore(&dev->event_lock, flags); |
4057 | kfree(work); | 4205 | kfree(work); |
4058 | mutex_unlock(&dev->struct_mutex); | 4206 | mutex_unlock(&dev->struct_mutex); |
@@ -4066,19 +4214,24 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4066 | 4214 | ||
4067 | ret = intel_pin_and_fence_fb_obj(dev, obj); | 4215 | ret = intel_pin_and_fence_fb_obj(dev, obj); |
4068 | if (ret != 0) { | 4216 | if (ret != 0) { |
4217 | DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n", | ||
4218 | obj->driver_private); | ||
4069 | kfree(work); | 4219 | kfree(work); |
4220 | intel_crtc->unpin_work = NULL; | ||
4070 | mutex_unlock(&dev->struct_mutex); | 4221 | mutex_unlock(&dev->struct_mutex); |
4071 | return ret; | 4222 | return ret; |
4072 | } | 4223 | } |
4073 | 4224 | ||
4074 | /* Reference the old fb object for the scheduled work. */ | 4225 | /* Reference the objects for the scheduled work. */ |
4075 | drm_gem_object_reference(work->obj); | 4226 | drm_gem_object_reference(work->old_fb_obj); |
4227 | drm_gem_object_reference(obj); | ||
4076 | 4228 | ||
4077 | crtc->fb = fb; | 4229 | crtc->fb = fb; |
4078 | i915_gem_object_flush_write_domain(obj); | 4230 | i915_gem_object_flush_write_domain(obj); |
4079 | drm_vblank_get(dev, intel_crtc->pipe); | 4231 | drm_vblank_get(dev, intel_crtc->pipe); |
4080 | obj_priv = obj->driver_private; | 4232 | obj_priv = obj->driver_private; |
4081 | atomic_inc(&obj_priv->pending_flip); | 4233 | atomic_inc(&obj_priv->pending_flip); |
4234 | work->pending_flip_obj = obj; | ||
4082 | 4235 | ||
4083 | BEGIN_LP_RING(4); | 4236 | BEGIN_LP_RING(4); |
4084 | OUT_RING(MI_DISPLAY_FLIP | | 4237 | OUT_RING(MI_DISPLAY_FLIP | |
@@ -4086,7 +4239,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
4086 | OUT_RING(fb->pitch); | 4239 | OUT_RING(fb->pitch); |
4087 | if (IS_I965G(dev)) { | 4240 | if (IS_I965G(dev)) { |
4088 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); | 4241 | OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); |
4089 | OUT_RING((fb->width << 16) | fb->height); | 4242 | pipesrc = I915_READ(pipesrc_reg); |
4243 | OUT_RING(pipesrc & 0x0fff0fff); | ||
4090 | } else { | 4244 | } else { |
4091 | OUT_RING(obj_priv->gtt_offset); | 4245 | OUT_RING(obj_priv->gtt_offset); |
4092 | OUT_RING(MI_NOOP); | 4246 | OUT_RING(MI_NOOP); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 371d753e362b..aaabbcbe5905 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -148,7 +148,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
148 | 148 | ||
149 | mutex_lock(&dev->struct_mutex); | 149 | mutex_lock(&dev->struct_mutex); |
150 | 150 | ||
151 | ret = i915_gem_object_pin(fbo, PAGE_SIZE); | 151 | ret = i915_gem_object_pin(fbo, 64*1024); |
152 | if (ret) { | 152 | if (ret) { |
153 | DRM_ERROR("failed to pin fb: %d\n", ret); | 153 | DRM_ERROR("failed to pin fb: %d\n", ret); |
154 | goto out_unref; | 154 | goto out_unref; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index aa74e59bec61..c2e8a45780d5 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -611,7 +611,7 @@ static const struct dmi_system_id bad_lid_status[] = { | |||
611 | { | 611 | { |
612 | .ident = "Samsung SX20S", | 612 | .ident = "Samsung SX20S", |
613 | .matches = { | 613 | .matches = { |
614 | DMI_MATCH(DMI_SYS_VENDOR, "Phoenix Technologies LTD"), | 614 | DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"), |
615 | DMI_MATCH(DMI_BOARD_NAME, "SX20S"), | 615 | DMI_MATCH(DMI_BOARD_NAME, "SX20S"), |
616 | }, | 616 | }, |
617 | }, | 617 | }, |
@@ -623,12 +623,26 @@ static const struct dmi_system_id bad_lid_status[] = { | |||
623 | }, | 623 | }, |
624 | }, | 624 | }, |
625 | { | 625 | { |
626 | .ident = "Aspire 1810T", | ||
627 | .matches = { | ||
628 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
629 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"), | ||
630 | }, | ||
631 | }, | ||
632 | { | ||
626 | .ident = "PC-81005", | 633 | .ident = "PC-81005", |
627 | .matches = { | 634 | .matches = { |
628 | DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), | 635 | DMI_MATCH(DMI_SYS_VENDOR, "MALATA"), |
629 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), | 636 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), |
630 | }, | 637 | }, |
631 | }, | 638 | }, |
639 | { | ||
640 | .ident = "Clevo M5x0N", | ||
641 | .matches = { | ||
642 | DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), | ||
643 | DMI_MATCH(DMI_BOARD_NAME, "M5x0N"), | ||
644 | }, | ||
645 | }, | ||
632 | { } | 646 | { } |
633 | }; | 647 | }; |
634 | 648 | ||
@@ -643,7 +657,7 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect | |||
643 | { | 657 | { |
644 | enum drm_connector_status status = connector_status_connected; | 658 | enum drm_connector_status status = connector_status_connected; |
645 | 659 | ||
646 | if (!acpi_lid_open() && !dmi_check_system(bad_lid_status)) | 660 | if (!dmi_check_system(bad_lid_status) && !acpi_lid_open()) |
647 | status = connector_status_disconnected; | 661 | status = connector_status_disconnected; |
648 | 662 | ||
649 | return status; | 663 | return status; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index eaacfd0920df..82678d30ab06 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2345,6 +2345,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2345 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2345 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2346 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2346 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2347 | (1 << INTEL_ANALOG_CLONE_BIT); | 2347 | (1 << INTEL_ANALOG_CLONE_BIT); |
2348 | } else if (flags & SDVO_OUTPUT_CVBS0) { | ||
2349 | |||
2350 | sdvo_priv->controlled_output = SDVO_OUTPUT_CVBS0; | ||
2351 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | ||
2352 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | ||
2353 | sdvo_priv->is_tv = true; | ||
2354 | intel_output->needs_tv_clock = true; | ||
2355 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
2348 | } else if (flags & SDVO_OUTPUT_LVDS0) { | 2356 | } else if (flags & SDVO_OUTPUT_LVDS0) { |
2349 | 2357 | ||
2350 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; | 2358 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 1cf488247a16..48227e744753 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -90,21 +90,21 @@ int nouveau_hybrid_setup(struct drm_device *dev) | |||
90 | { | 90 | { |
91 | int result; | 91 | int result; |
92 | 92 | ||
93 | if (nouveau_dsm(dev, NOUVEAU_DSM_ACTIVE, NOUVEAU_DSM_ACTIVE_QUERY, | 93 | if (nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STATE, |
94 | &result)) | 94 | &result)) |
95 | return -ENODEV; | 95 | return -ENODEV; |
96 | 96 | ||
97 | NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result); | 97 | NV_INFO(dev, "_DSM hardware status gave 0x%x\n", result); |
98 | 98 | ||
99 | if (result & 0x1) { /* Stamina mode - disable the external GPU */ | 99 | if (result) { /* Ensure that the external GPU is enabled */ |
100 | nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL); | ||
101 | nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED, | ||
102 | NULL); | ||
103 | } else { /* Stamina mode - disable the external GPU */ | ||
100 | nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA, | 104 | nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_STAMINA, |
101 | NULL); | 105 | NULL); |
102 | nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA, | 106 | nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_STAMINA, |
103 | NULL); | 107 | NULL); |
104 | } else { /* Ensure that the external GPU is enabled */ | ||
105 | nouveau_dsm(dev, NOUVEAU_DSM_LED, NOUVEAU_DSM_LED_SPEED, NULL); | ||
106 | nouveau_dsm(dev, NOUVEAU_DSM_POWER, NOUVEAU_DSM_POWER_SPEED, | ||
107 | NULL); | ||
108 | } | 108 | } |
109 | 109 | ||
110 | return 0; | 110 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index d7f8d8b4a4b8..0e9cd1d49130 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -1865,7 +1865,7 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
1865 | 1865 | ||
1866 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 1866 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
1867 | 1867 | ||
1868 | if (dev_priv->card_type >= NV_50) | 1868 | if (dev_priv->card_type >= NV_40) |
1869 | return 1; | 1869 | return 1; |
1870 | 1870 | ||
1871 | /* | 1871 | /* |
@@ -3765,7 +3765,6 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3765 | */ | 3765 | */ |
3766 | 3766 | ||
3767 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3767 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3768 | struct init_exec iexec = {true, false}; | ||
3769 | struct nvbios *bios = &dev_priv->VBIOS; | 3768 | struct nvbios *bios = &dev_priv->VBIOS; |
3770 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; | 3769 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; |
3771 | uint8_t *otable = NULL; | 3770 | uint8_t *otable = NULL; |
@@ -3845,8 +3844,6 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3845 | } | 3844 | } |
3846 | } | 3845 | } |
3847 | 3846 | ||
3848 | bios->display.output = dcbent; | ||
3849 | |||
3850 | if (pxclk == 0) { | 3847 | if (pxclk == 0) { |
3851 | script = ROM16(otable[6]); | 3848 | script = ROM16(otable[6]); |
3852 | if (!script) { | 3849 | if (!script) { |
@@ -3855,7 +3852,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3855 | } | 3852 | } |
3856 | 3853 | ||
3857 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); | 3854 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); |
3858 | parse_init_table(bios, script, &iexec); | 3855 | nouveau_bios_run_init_table(dev, script, dcbent); |
3859 | } else | 3856 | } else |
3860 | if (pxclk == -1) { | 3857 | if (pxclk == -1) { |
3861 | script = ROM16(otable[8]); | 3858 | script = ROM16(otable[8]); |
@@ -3865,7 +3862,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3865 | } | 3862 | } |
3866 | 3863 | ||
3867 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); | 3864 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); |
3868 | parse_init_table(bios, script, &iexec); | 3865 | nouveau_bios_run_init_table(dev, script, dcbent); |
3869 | } else | 3866 | } else |
3870 | if (pxclk == -2) { | 3867 | if (pxclk == -2) { |
3871 | if (table[4] >= 12) | 3868 | if (table[4] >= 12) |
@@ -3878,7 +3875,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3878 | } | 3875 | } |
3879 | 3876 | ||
3880 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); | 3877 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); |
3881 | parse_init_table(bios, script, &iexec); | 3878 | nouveau_bios_run_init_table(dev, script, dcbent); |
3882 | } else | 3879 | } else |
3883 | if (pxclk > 0) { | 3880 | if (pxclk > 0) { |
3884 | script = ROM16(otable[table[4] + i*6 + 2]); | 3881 | script = ROM16(otable[table[4] + i*6 + 2]); |
@@ -3890,7 +3887,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3890 | } | 3887 | } |
3891 | 3888 | ||
3892 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); | 3889 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); |
3893 | parse_init_table(bios, script, &iexec); | 3890 | nouveau_bios_run_init_table(dev, script, dcbent); |
3894 | } else | 3891 | } else |
3895 | if (pxclk < 0) { | 3892 | if (pxclk < 0) { |
3896 | script = ROM16(otable[table[4] + i*6 + 4]); | 3893 | script = ROM16(otable[table[4] + i*6 + 4]); |
@@ -3902,7 +3899,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3902 | } | 3899 | } |
3903 | 3900 | ||
3904 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); | 3901 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); |
3905 | parse_init_table(bios, script, &iexec); | 3902 | nouveau_bios_run_init_table(dev, script, dcbent); |
3906 | } | 3903 | } |
3907 | 3904 | ||
3908 | return 0; | 3905 | return 0; |
@@ -5865,9 +5862,11 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, | |||
5865 | struct nvbios *bios = &dev_priv->VBIOS; | 5862 | struct nvbios *bios = &dev_priv->VBIOS; |
5866 | struct init_exec iexec = { true, false }; | 5863 | struct init_exec iexec = { true, false }; |
5867 | 5864 | ||
5865 | mutex_lock(&bios->lock); | ||
5868 | bios->display.output = dcbent; | 5866 | bios->display.output = dcbent; |
5869 | parse_init_table(bios, table, &iexec); | 5867 | parse_init_table(bios, table, &iexec); |
5870 | bios->display.output = NULL; | 5868 | bios->display.output = NULL; |
5869 | mutex_unlock(&bios->lock); | ||
5871 | } | 5870 | } |
5872 | 5871 | ||
5873 | static bool NVInitVBIOS(struct drm_device *dev) | 5872 | static bool NVInitVBIOS(struct drm_device *dev) |
@@ -5876,6 +5875,7 @@ static bool NVInitVBIOS(struct drm_device *dev) | |||
5876 | struct nvbios *bios = &dev_priv->VBIOS; | 5875 | struct nvbios *bios = &dev_priv->VBIOS; |
5877 | 5876 | ||
5878 | memset(bios, 0, sizeof(struct nvbios)); | 5877 | memset(bios, 0, sizeof(struct nvbios)); |
5878 | mutex_init(&bios->lock); | ||
5879 | bios->dev = dev; | 5879 | bios->dev = dev; |
5880 | 5880 | ||
5881 | if (!NVShadowVBIOS(dev, bios->data)) | 5881 | if (!NVShadowVBIOS(dev, bios->data)) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 058e98c76d89..fd94bd6dc264 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -205,6 +205,8 @@ struct nvbios { | |||
205 | struct drm_device *dev; | 205 | struct drm_device *dev; |
206 | struct nouveau_bios_info pub; | 206 | struct nouveau_bios_info pub; |
207 | 207 | ||
208 | struct mutex lock; | ||
209 | |||
208 | uint8_t data[NV_PROM_SIZE]; | 210 | uint8_t data[NV_PROM_SIZE]; |
209 | unsigned int length; | 211 | unsigned int length; |
210 | bool execute; | 212 | bool execute; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index db0ed4c13f98..028719fddf76 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -65,8 +65,10 @@ nouveau_bo_fixup_align(struct drm_device *dev, | |||
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Some of the tile_flags have a periodic structure of N*4096 bytes, | 67 | * Some of the tile_flags have a periodic structure of N*4096 bytes, |
68 | * align to to that as well as the page size. Overallocate memory to | 68 | * align to to that as well as the page size. Align the size to the |
69 | * avoid corruption of other buffer objects. | 69 | * appropriate boundaries. This does imply that sizes are rounded up |
70 | * 3-7 pages, so be aware of this and do not waste memory by allocating | ||
71 | * many small buffers. | ||
70 | */ | 72 | */ |
71 | if (dev_priv->card_type == NV_50) { | 73 | if (dev_priv->card_type == NV_50) { |
72 | uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; | 74 | uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; |
@@ -77,22 +79,20 @@ nouveau_bo_fixup_align(struct drm_device *dev, | |||
77 | case 0x2800: | 79 | case 0x2800: |
78 | case 0x4800: | 80 | case 0x4800: |
79 | case 0x7a00: | 81 | case 0x7a00: |
80 | *size = roundup(*size, block_size); | ||
81 | if (is_power_of_2(block_size)) { | 82 | if (is_power_of_2(block_size)) { |
82 | *size += 3 * block_size; | ||
83 | for (i = 1; i < 10; i++) { | 83 | for (i = 1; i < 10; i++) { |
84 | *align = 12 * i * block_size; | 84 | *align = 12 * i * block_size; |
85 | if (!(*align % 65536)) | 85 | if (!(*align % 65536)) |
86 | break; | 86 | break; |
87 | } | 87 | } |
88 | } else { | 88 | } else { |
89 | *size += 6 * block_size; | ||
90 | for (i = 1; i < 10; i++) { | 89 | for (i = 1; i < 10; i++) { |
91 | *align = 8 * i * block_size; | 90 | *align = 8 * i * block_size; |
92 | if (!(*align % 65536)) | 91 | if (!(*align % 65536)) |
93 | break; | 92 | break; |
94 | } | 93 | } |
95 | } | 94 | } |
95 | *size = roundup(*size, *align); | ||
96 | break; | 96 | break; |
97 | default: | 97 | default: |
98 | break; | 98 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 343d718a9667..2281f99da7fc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -278,12 +278,11 @@ nouveau_channel_free(struct nouveau_channel *chan) | |||
278 | /* Ensure the channel is no longer active on the GPU */ | 278 | /* Ensure the channel is no longer active on the GPU */ |
279 | pfifo->reassign(dev, false); | 279 | pfifo->reassign(dev, false); |
280 | 280 | ||
281 | if (pgraph->channel(dev) == chan) { | 281 | pgraph->fifo_access(dev, false); |
282 | pgraph->fifo_access(dev, false); | 282 | if (pgraph->channel(dev) == chan) |
283 | pgraph->unload_context(dev); | 283 | pgraph->unload_context(dev); |
284 | pgraph->fifo_access(dev, true); | ||
285 | } | ||
286 | pgraph->destroy_context(chan); | 284 | pgraph->destroy_context(chan); |
285 | pgraph->fifo_access(dev, true); | ||
287 | 286 | ||
288 | if (pfifo->channel_id(dev) == chan->id) { | 287 | if (pfifo->channel_id(dev) == chan->id) { |
289 | pfifo->disable(dev); | 288 | pfifo->disable(dev); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 7e6d673f3a23..d2f63353ea97 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -88,13 +88,14 @@ nouveau_connector_destroy(struct drm_connector *drm_connector) | |||
88 | { | 88 | { |
89 | struct nouveau_connector *nv_connector = | 89 | struct nouveau_connector *nv_connector = |
90 | nouveau_connector(drm_connector); | 90 | nouveau_connector(drm_connector); |
91 | struct drm_device *dev = nv_connector->base.dev; | 91 | struct drm_device *dev; |
92 | |||
93 | NV_DEBUG_KMS(dev, "\n"); | ||
94 | 92 | ||
95 | if (!nv_connector) | 93 | if (!nv_connector) |
96 | return; | 94 | return; |
97 | 95 | ||
96 | dev = nv_connector->base.dev; | ||
97 | NV_DEBUG_KMS(dev, "\n"); | ||
98 | |||
98 | kfree(nv_connector->edid); | 99 | kfree(nv_connector->edid); |
99 | drm_sysfs_connector_remove(drm_connector); | 100 | drm_sysfs_connector_remove(drm_connector); |
100 | drm_connector_cleanup(drm_connector); | 101 | drm_connector_cleanup(drm_connector); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index dd4937224220..f954ad93e81f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -502,12 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr, | |||
502 | break; | 502 | break; |
503 | } | 503 | } |
504 | 504 | ||
505 | if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) { | ||
506 | ret = -EREMOTEIO; | ||
507 | goto out; | ||
508 | } | ||
509 | |||
510 | if (cmd & 1) { | 505 | if (cmd & 1) { |
506 | if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) { | ||
507 | ret = -EREMOTEIO; | ||
508 | goto out; | ||
509 | } | ||
510 | |||
511 | for (i = 0; i < 4; i++) { | 511 | for (i = 0; i < 4; i++) { |
512 | data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i)); | 512 | data32[i] = nv_rd32(dev, NV50_AUXCH_DATA_IN(index, i)); |
513 | NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]); | 513 | NV_DEBUG_KMS(dev, "rd %d: 0x%08x\n", i, data32[i]); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 343ab7f17ccc..da3b93b84502 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -56,7 +56,7 @@ int nouveau_vram_pushbuf; | |||
56 | module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); | 56 | module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); |
57 | 57 | ||
58 | MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); | 58 | MODULE_PARM_DESC(vram_notify, "Force DMA notifiers to be in VRAM"); |
59 | int nouveau_vram_notify; | 59 | int nouveau_vram_notify = 1; |
60 | module_param_named(vram_notify, nouveau_vram_notify, int, 0400); | 60 | module_param_named(vram_notify, nouveau_vram_notify, int, 0400); |
61 | 61 | ||
62 | MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); | 62 | MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (>=GeForce 8)"); |
@@ -75,6 +75,14 @@ MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status"); | |||
75 | int nouveau_ignorelid = 0; | 75 | int nouveau_ignorelid = 0; |
76 | module_param_named(ignorelid, nouveau_ignorelid, int, 0400); | 76 | module_param_named(ignorelid, nouveau_ignorelid, int, 0400); |
77 | 77 | ||
78 | MODULE_PARM_DESC(noagp, "Disable all acceleration"); | ||
79 | int nouveau_noaccel = 0; | ||
80 | module_param_named(noaccel, nouveau_noaccel, int, 0400); | ||
81 | |||
82 | MODULE_PARM_DESC(noagp, "Disable fbcon acceleration"); | ||
83 | int nouveau_nofbaccel = 0; | ||
84 | module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); | ||
85 | |||
78 | MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" | 86 | MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" |
79 | "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" | 87 | "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" |
80 | "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" | 88 | "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6b9690418bc7..1c15ef37b71c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -583,6 +583,7 @@ struct drm_nouveau_private { | |||
583 | uint64_t vm_end; | 583 | uint64_t vm_end; |
584 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; | 584 | struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; |
585 | int vm_vram_pt_nr; | 585 | int vm_vram_pt_nr; |
586 | uint64_t vram_sys_base; | ||
586 | 587 | ||
587 | /* the mtrr covering the FB */ | 588 | /* the mtrr covering the FB */ |
588 | int fb_mtrr; | 589 | int fb_mtrr; |
@@ -678,6 +679,8 @@ extern int nouveau_reg_debug; | |||
678 | extern char *nouveau_vbios; | 679 | extern char *nouveau_vbios; |
679 | extern int nouveau_ctxfw; | 680 | extern int nouveau_ctxfw; |
680 | extern int nouveau_ignorelid; | 681 | extern int nouveau_ignorelid; |
682 | extern int nouveau_nofbaccel; | ||
683 | extern int nouveau_noaccel; | ||
681 | 684 | ||
682 | /* nouveau_state.c */ | 685 | /* nouveau_state.c */ |
683 | extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); | 686 | extern void nouveau_preclose(struct drm_device *dev, struct drm_file *); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 0b05c869e0e7..ea879a2efef3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -107,6 +107,34 @@ static struct fb_ops nouveau_fbcon_ops = { | |||
107 | .fb_setcmap = drm_fb_helper_setcmap, | 107 | .fb_setcmap = drm_fb_helper_setcmap, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static struct fb_ops nv04_fbcon_ops = { | ||
111 | .owner = THIS_MODULE, | ||
112 | .fb_check_var = drm_fb_helper_check_var, | ||
113 | .fb_set_par = drm_fb_helper_set_par, | ||
114 | .fb_setcolreg = drm_fb_helper_setcolreg, | ||
115 | .fb_fillrect = nv04_fbcon_fillrect, | ||
116 | .fb_copyarea = nv04_fbcon_copyarea, | ||
117 | .fb_imageblit = nv04_fbcon_imageblit, | ||
118 | .fb_sync = nouveau_fbcon_sync, | ||
119 | .fb_pan_display = drm_fb_helper_pan_display, | ||
120 | .fb_blank = drm_fb_helper_blank, | ||
121 | .fb_setcmap = drm_fb_helper_setcmap, | ||
122 | }; | ||
123 | |||
124 | static struct fb_ops nv50_fbcon_ops = { | ||
125 | .owner = THIS_MODULE, | ||
126 | .fb_check_var = drm_fb_helper_check_var, | ||
127 | .fb_set_par = drm_fb_helper_set_par, | ||
128 | .fb_setcolreg = drm_fb_helper_setcolreg, | ||
129 | .fb_fillrect = nv50_fbcon_fillrect, | ||
130 | .fb_copyarea = nv50_fbcon_copyarea, | ||
131 | .fb_imageblit = nv50_fbcon_imageblit, | ||
132 | .fb_sync = nouveau_fbcon_sync, | ||
133 | .fb_pan_display = drm_fb_helper_pan_display, | ||
134 | .fb_blank = drm_fb_helper_blank, | ||
135 | .fb_setcmap = drm_fb_helper_setcmap, | ||
136 | }; | ||
137 | |||
110 | static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | 138 | static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
111 | u16 blue, int regno) | 139 | u16 blue, int regno) |
112 | { | 140 | { |
@@ -267,8 +295,12 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, | |||
267 | dev_priv->fbdev_info = info; | 295 | dev_priv->fbdev_info = info; |
268 | 296 | ||
269 | strcpy(info->fix.id, "nouveaufb"); | 297 | strcpy(info->fix.id, "nouveaufb"); |
270 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | | 298 | if (nouveau_nofbaccel) |
271 | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; | 299 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED; |
300 | else | ||
301 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | | ||
302 | FBINFO_HWACCEL_FILLRECT | | ||
303 | FBINFO_HWACCEL_IMAGEBLIT; | ||
272 | info->fbops = &nouveau_fbcon_ops; | 304 | info->fbops = &nouveau_fbcon_ops; |
273 | info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - | 305 | info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - |
274 | dev_priv->vm_vram_base; | 306 | dev_priv->vm_vram_base; |
@@ -316,13 +348,15 @@ nouveau_fbcon_create(struct drm_device *dev, uint32_t fb_width, | |||
316 | par->nouveau_fb = nouveau_fb; | 348 | par->nouveau_fb = nouveau_fb; |
317 | par->dev = dev; | 349 | par->dev = dev; |
318 | 350 | ||
319 | if (dev_priv->channel) { | 351 | if (dev_priv->channel && !nouveau_nofbaccel) { |
320 | switch (dev_priv->card_type) { | 352 | switch (dev_priv->card_type) { |
321 | case NV_50: | 353 | case NV_50: |
322 | nv50_fbcon_accel_init(info); | 354 | nv50_fbcon_accel_init(info); |
355 | info->fbops = &nv50_fbcon_ops; | ||
323 | break; | 356 | break; |
324 | default: | 357 | default: |
325 | nv04_fbcon_accel_init(info); | 358 | nv04_fbcon_accel_init(info); |
359 | info->fbops = &nv04_fbcon_ops; | ||
326 | break; | 360 | break; |
327 | }; | 361 | }; |
328 | } | 362 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 462e0b87b4bd..f9c34e1a8c11 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h | |||
@@ -40,7 +40,13 @@ int nouveau_fbcon_remove(struct drm_device *dev, struct drm_framebuffer *fb); | |||
40 | void nouveau_fbcon_restore(void); | 40 | void nouveau_fbcon_restore(void); |
41 | void nouveau_fbcon_zfill(struct drm_device *dev); | 41 | void nouveau_fbcon_zfill(struct drm_device *dev); |
42 | 42 | ||
43 | void nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); | ||
44 | void nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); | ||
45 | void nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); | ||
43 | int nv04_fbcon_accel_init(struct fb_info *info); | 46 | int nv04_fbcon_accel_init(struct fb_info *info); |
47 | void nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); | ||
48 | void nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); | ||
49 | void nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); | ||
44 | int nv50_fbcon_accel_init(struct fb_info *info); | 50 | int nv50_fbcon_accel_init(struct fb_info *info); |
45 | 51 | ||
46 | void nouveau_fbcon_gpu_lockup(struct fb_info *info); | 52 | void nouveau_fbcon_gpu_lockup(struct fb_info *info); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 6ac804b0c9f9..70cc30803e3b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -925,7 +925,9 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, | |||
925 | } | 925 | } |
926 | 926 | ||
927 | if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) { | 927 | if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) { |
928 | spin_lock(&nvbo->bo.lock); | ||
928 | ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); | 929 | ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); |
930 | spin_unlock(&nvbo->bo.lock); | ||
929 | } else { | 931 | } else { |
930 | ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); | 932 | ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); |
931 | if (ret == 0) | 933 | if (ret == 0) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_grctx.c b/drivers/gpu/drm/nouveau/nouveau_grctx.c index 419f4c2b3b89..c7ebec696747 100644 --- a/drivers/gpu/drm/nouveau/nouveau_grctx.c +++ b/drivers/gpu/drm/nouveau/nouveau_grctx.c | |||
@@ -97,8 +97,8 @@ nouveau_grctx_prog_load(struct drm_device *dev) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); | 99 | pgraph->ctxvals = kmalloc(fw->size, GFP_KERNEL); |
100 | if (!pgraph->ctxprog) { | 100 | if (!pgraph->ctxvals) { |
101 | NV_ERROR(dev, "OOM copying ctxprog\n"); | 101 | NV_ERROR(dev, "OOM copying ctxvals\n"); |
102 | release_firmware(fw); | 102 | release_firmware(fw); |
103 | nouveau_grctx_fini(dev); | 103 | nouveau_grctx_fini(dev); |
104 | return -ENOMEM; | 104 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 3b9bad66162a..447f9f69d6b1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -211,6 +211,20 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
211 | get + 4); | 211 | get + 4); |
212 | } | 212 | } |
213 | 213 | ||
214 | if (status & NV_PFIFO_INTR_SEMAPHORE) { | ||
215 | uint32_t sem; | ||
216 | |||
217 | status &= ~NV_PFIFO_INTR_SEMAPHORE; | ||
218 | nv_wr32(dev, NV03_PFIFO_INTR_0, | ||
219 | NV_PFIFO_INTR_SEMAPHORE); | ||
220 | |||
221 | sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE); | ||
222 | nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); | ||
223 | |||
224 | nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); | ||
225 | nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); | ||
226 | } | ||
227 | |||
214 | if (status) { | 228 | if (status) { |
215 | NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", | 229 | NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", |
216 | status, chid); | 230 | status, chid); |
@@ -566,86 +580,99 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) | |||
566 | static void | 580 | static void |
567 | nv50_pgraph_irq_handler(struct drm_device *dev) | 581 | nv50_pgraph_irq_handler(struct drm_device *dev) |
568 | { | 582 | { |
569 | uint32_t status, nsource; | 583 | uint32_t status; |
570 | 584 | ||
571 | status = nv_rd32(dev, NV03_PGRAPH_INTR); | 585 | while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { |
572 | nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); | 586 | uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); |
573 | 587 | ||
574 | if (status & 0x00000001) { | 588 | if (status & 0x00000001) { |
575 | nouveau_pgraph_intr_notify(dev, nsource); | 589 | nouveau_pgraph_intr_notify(dev, nsource); |
576 | status &= ~0x00000001; | 590 | status &= ~0x00000001; |
577 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); | 591 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); |
578 | } | 592 | } |
579 | 593 | ||
580 | if (status & 0x00000010) { | 594 | if (status & 0x00000010) { |
581 | nouveau_pgraph_intr_error(dev, nsource | | 595 | nouveau_pgraph_intr_error(dev, nsource | |
582 | NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); | 596 | NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); |
583 | 597 | ||
584 | status &= ~0x00000010; | 598 | status &= ~0x00000010; |
585 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); | 599 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); |
586 | } | 600 | } |
587 | 601 | ||
588 | if (status & 0x00001000) { | 602 | if (status & 0x00001000) { |
589 | nv_wr32(dev, 0x400500, 0x00000000); | 603 | nv_wr32(dev, 0x400500, 0x00000000); |
590 | nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); | 604 | nv_wr32(dev, NV03_PGRAPH_INTR, |
591 | nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, | 605 | NV_PGRAPH_INTR_CONTEXT_SWITCH); |
592 | NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH); | 606 | nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, |
593 | nv_wr32(dev, 0x400500, 0x00010001); | 607 | NV40_PGRAPH_INTR_EN) & |
608 | ~NV_PGRAPH_INTR_CONTEXT_SWITCH); | ||
609 | nv_wr32(dev, 0x400500, 0x00010001); | ||
594 | 610 | ||
595 | nv50_graph_context_switch(dev); | 611 | nv50_graph_context_switch(dev); |
596 | 612 | ||
597 | status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; | 613 | status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; |
598 | } | 614 | } |
599 | 615 | ||
600 | if (status & 0x00100000) { | 616 | if (status & 0x00100000) { |
601 | nouveau_pgraph_intr_error(dev, nsource | | 617 | nouveau_pgraph_intr_error(dev, nsource | |
602 | NV03_PGRAPH_NSOURCE_DATA_ERROR); | 618 | NV03_PGRAPH_NSOURCE_DATA_ERROR); |
603 | 619 | ||
604 | status &= ~0x00100000; | 620 | status &= ~0x00100000; |
605 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); | 621 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); |
606 | } | 622 | } |
607 | 623 | ||
608 | if (status & 0x00200000) { | 624 | if (status & 0x00200000) { |
609 | int r; | 625 | int r; |
610 | 626 | ||
611 | nouveau_pgraph_intr_error(dev, nsource | | 627 | nouveau_pgraph_intr_error(dev, nsource | |
612 | NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); | 628 | NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); |
613 | 629 | ||
614 | NV_ERROR(dev, "magic set 1:\n"); | 630 | NV_ERROR(dev, "magic set 1:\n"); |
615 | for (r = 0x408900; r <= 0x408910; r += 4) | 631 | for (r = 0x408900; r <= 0x408910; r += 4) |
616 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 632 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
617 | nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000); | 633 | nv_rd32(dev, r)); |
618 | for (r = 0x408e08; r <= 0x408e24; r += 4) | 634 | nv_wr32(dev, 0x408900, |
619 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 635 | nv_rd32(dev, 0x408904) | 0xc0000000); |
620 | nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000); | 636 | for (r = 0x408e08; r <= 0x408e24; r += 4) |
621 | 637 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, | |
622 | NV_ERROR(dev, "magic set 2:\n"); | 638 | nv_rd32(dev, r)); |
623 | for (r = 0x409900; r <= 0x409910; r += 4) | 639 | nv_wr32(dev, 0x408e08, |
624 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 640 | nv_rd32(dev, 0x408e08) | 0xc0000000); |
625 | nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000); | 641 | |
626 | for (r = 0x409e08; r <= 0x409e24; r += 4) | 642 | NV_ERROR(dev, "magic set 2:\n"); |
627 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 643 | for (r = 0x409900; r <= 0x409910; r += 4) |
628 | nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000); | 644 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
629 | 645 | nv_rd32(dev, r)); | |
630 | status &= ~0x00200000; | 646 | nv_wr32(dev, 0x409900, |
631 | nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); | 647 | nv_rd32(dev, 0x409904) | 0xc0000000); |
632 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); | 648 | for (r = 0x409e08; r <= 0x409e24; r += 4) |
633 | } | 649 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
650 | nv_rd32(dev, r)); | ||
651 | nv_wr32(dev, 0x409e08, | ||
652 | nv_rd32(dev, 0x409e08) | 0xc0000000); | ||
653 | |||
654 | status &= ~0x00200000; | ||
655 | nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); | ||
656 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); | ||
657 | } | ||
634 | 658 | ||
635 | if (status) { | 659 | if (status) { |
636 | NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); | 660 | NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", |
637 | nv_wr32(dev, NV03_PGRAPH_INTR, status); | 661 | status); |
638 | } | 662 | nv_wr32(dev, NV03_PGRAPH_INTR, status); |
663 | } | ||
639 | 664 | ||
640 | { | 665 | { |
641 | const int isb = (1 << 16) | (1 << 0); | 666 | const int isb = (1 << 16) | (1 << 0); |
642 | 667 | ||
643 | if ((nv_rd32(dev, 0x400500) & isb) != isb) | 668 | if ((nv_rd32(dev, 0x400500) & isb) != isb) |
644 | nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); | 669 | nv_wr32(dev, 0x400500, |
645 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); | 670 | nv_rd32(dev, 0x400500) | isb); |
671 | } | ||
646 | } | 672 | } |
647 | 673 | ||
648 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); | 674 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); |
675 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); | ||
649 | } | 676 | } |
650 | 677 | ||
651 | static void | 678 | static void |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 8f3a12f614ed..2dc09dbd817d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -285,53 +285,50 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
285 | uint32_t flags, uint64_t phys) | 285 | uint32_t flags, uint64_t phys) |
286 | { | 286 | { |
287 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 287 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
288 | struct nouveau_gpuobj **pgt; | 288 | struct nouveau_gpuobj *pgt; |
289 | unsigned psz, pfl, pages; | 289 | unsigned block; |
290 | 290 | int i; | |
291 | if (virt >= dev_priv->vm_gart_base && | ||
292 | (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) { | ||
293 | psz = 12; | ||
294 | pgt = &dev_priv->gart_info.sg_ctxdma; | ||
295 | pfl = 0x21; | ||
296 | virt -= dev_priv->vm_gart_base; | ||
297 | } else | ||
298 | if (virt >= dev_priv->vm_vram_base && | ||
299 | (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) { | ||
300 | psz = 16; | ||
301 | pgt = dev_priv->vm_vram_pt; | ||
302 | pfl = 0x01; | ||
303 | virt -= dev_priv->vm_vram_base; | ||
304 | } else { | ||
305 | NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n", | ||
306 | virt, virt + size - 1); | ||
307 | return -EINVAL; | ||
308 | } | ||
309 | 291 | ||
310 | pages = size >> psz; | 292 | virt = ((virt - dev_priv->vm_vram_base) >> 16) << 1; |
293 | size = (size >> 16) << 1; | ||
294 | |||
295 | phys |= ((uint64_t)flags << 32); | ||
296 | phys |= 1; | ||
297 | if (dev_priv->vram_sys_base) { | ||
298 | phys += dev_priv->vram_sys_base; | ||
299 | phys |= 0x30; | ||
300 | } | ||
311 | 301 | ||
312 | dev_priv->engine.instmem.prepare_access(dev, true); | 302 | dev_priv->engine.instmem.prepare_access(dev, true); |
313 | if (flags & 0x80000000) { | 303 | while (size) { |
314 | while (pages--) { | 304 | unsigned offset_h = upper_32_bits(phys); |
315 | struct nouveau_gpuobj *pt = pgt[virt >> 29]; | 305 | unsigned offset_l = lower_32_bits(phys); |
316 | unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; | 306 | unsigned pte, end; |
307 | |||
308 | for (i = 7; i >= 0; i--) { | ||
309 | block = 1 << (i + 1); | ||
310 | if (size >= block && !(virt & (block - 1))) | ||
311 | break; | ||
312 | } | ||
313 | offset_l |= (i << 7); | ||
317 | 314 | ||
318 | nv_wo32(dev, pt, pte++, 0x00000000); | 315 | phys += block << 15; |
319 | nv_wo32(dev, pt, pte++, 0x00000000); | 316 | size -= block; |
320 | 317 | ||
321 | virt += (1 << psz); | 318 | while (block) { |
322 | } | 319 | pgt = dev_priv->vm_vram_pt[virt >> 14]; |
323 | } else { | 320 | pte = virt & 0x3ffe; |
324 | while (pages--) { | ||
325 | struct nouveau_gpuobj *pt = pgt[virt >> 29]; | ||
326 | unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; | ||
327 | unsigned offset_h = upper_32_bits(phys) & 0xff; | ||
328 | unsigned offset_l = lower_32_bits(phys); | ||
329 | 321 | ||
330 | nv_wo32(dev, pt, pte++, offset_l | pfl); | 322 | end = pte + block; |
331 | nv_wo32(dev, pt, pte++, offset_h | flags); | 323 | if (end > 16384) |
324 | end = 16384; | ||
325 | block -= (end - pte); | ||
326 | virt += (end - pte); | ||
332 | 327 | ||
333 | phys += (1 << psz); | 328 | while (pte < end) { |
334 | virt += (1 << psz); | 329 | nv_wo32(dev, pgt, pte++, offset_l); |
330 | nv_wo32(dev, pgt, pte++, offset_h); | ||
331 | } | ||
335 | } | 332 | } |
336 | } | 333 | } |
337 | dev_priv->engine.instmem.finish_access(dev); | 334 | dev_priv->engine.instmem.finish_access(dev); |
@@ -356,7 +353,41 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
356 | void | 353 | void |
357 | nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | 354 | nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) |
358 | { | 355 | { |
359 | nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); | 356 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
357 | struct nouveau_gpuobj *pgt; | ||
358 | unsigned pages, pte, end; | ||
359 | |||
360 | virt -= dev_priv->vm_vram_base; | ||
361 | pages = (size >> 16) << 1; | ||
362 | |||
363 | dev_priv->engine.instmem.prepare_access(dev, true); | ||
364 | while (pages) { | ||
365 | pgt = dev_priv->vm_vram_pt[virt >> 29]; | ||
366 | pte = (virt & 0x1ffe0000ULL) >> 15; | ||
367 | |||
368 | end = pte + pages; | ||
369 | if (end > 16384) | ||
370 | end = 16384; | ||
371 | pages -= (end - pte); | ||
372 | virt += (end - pte) << 15; | ||
373 | |||
374 | while (pte < end) | ||
375 | nv_wo32(dev, pgt, pte++, 0); | ||
376 | } | ||
377 | dev_priv->engine.instmem.finish_access(dev); | ||
378 | |||
379 | nv_wr32(dev, 0x100c80, 0x00050001); | ||
380 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
381 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
382 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | nv_wr32(dev, 0x100c80, 0x00000001); | ||
387 | if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) { | ||
388 | NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n"); | ||
389 | NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80)); | ||
390 | } | ||
360 | } | 391 | } |
361 | 392 | ||
362 | /* | 393 | /* |
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 6c66a34b6345..d99dc087f9b1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -34,15 +34,20 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) | |||
34 | { | 34 | { |
35 | struct drm_device *dev = chan->dev; | 35 | struct drm_device *dev = chan->dev; |
36 | struct nouveau_bo *ntfy = NULL; | 36 | struct nouveau_bo *ntfy = NULL; |
37 | uint32_t flags; | ||
37 | int ret; | 38 | int ret; |
38 | 39 | ||
39 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, nouveau_vram_notify ? | 40 | if (nouveau_vram_notify) |
40 | TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT, | 41 | flags = TTM_PL_FLAG_VRAM; |
42 | else | ||
43 | flags = TTM_PL_FLAG_TT; | ||
44 | |||
45 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, | ||
41 | 0, 0x0000, false, true, &ntfy); | 46 | 0, 0x0000, false, true, &ntfy); |
42 | if (ret) | 47 | if (ret) |
43 | return ret; | 48 | return ret; |
44 | 49 | ||
45 | ret = nouveau_bo_pin(ntfy, TTM_PL_FLAG_VRAM); | 50 | ret = nouveau_bo_pin(ntfy, flags); |
46 | if (ret) | 51 | if (ret) |
47 | goto out_err; | 52 | goto out_err; |
48 | 53 | ||
@@ -128,6 +133,8 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
128 | target = NV_DMA_TARGET_PCI; | 133 | target = NV_DMA_TARGET_PCI; |
129 | } else { | 134 | } else { |
130 | target = NV_DMA_TARGET_AGP; | 135 | target = NV_DMA_TARGET_AGP; |
136 | if (dev_priv->card_type >= NV_50) | ||
137 | offset += dev_priv->vm_gart_base; | ||
131 | } | 138 | } |
132 | } else { | 139 | } else { |
133 | NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", | 140 | NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 6c2cf81716df..e7c100ba63a1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -885,11 +885,12 @@ int | |||
885 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, | 885 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, |
886 | struct nouveau_gpuobj **gpuobj_ret) | 886 | struct nouveau_gpuobj **gpuobj_ret) |
887 | { | 887 | { |
888 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; | 888 | struct drm_nouveau_private *dev_priv; |
889 | struct nouveau_gpuobj *gpuobj; | 889 | struct nouveau_gpuobj *gpuobj; |
890 | 890 | ||
891 | if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) | 891 | if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) |
892 | return -EINVAL; | 892 | return -EINVAL; |
893 | dev_priv = chan->dev->dev_private; | ||
893 | 894 | ||
894 | gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); | 895 | gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); |
895 | if (!gpuobj) | 896 | if (!gpuobj) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 251f1b3b38b9..aa9b310e41be 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -99,6 +99,7 @@ | |||
99 | * the card will hang early on in the X init process. | 99 | * the card will hang early on in the X init process. |
100 | */ | 100 | */ |
101 | # define NV_PMC_ENABLE_UNK13 (1<<13) | 101 | # define NV_PMC_ENABLE_UNK13 (1<<13) |
102 | #define NV40_PMC_GRAPH_UNITS 0x00001540 | ||
102 | #define NV40_PMC_BACKLIGHT 0x000015f0 | 103 | #define NV40_PMC_BACKLIGHT 0x000015f0 |
103 | # define NV40_PMC_BACKLIGHT_MASK 0x001f0000 | 104 | # define NV40_PMC_BACKLIGHT_MASK 0x001f0000 |
104 | #define NV40_PMC_1700 0x00001700 | 105 | #define NV40_PMC_1700 0x00001700 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 4c7f1e403e80..ed1590577b6c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -54,11 +54,12 @@ static void | |||
54 | nouveau_sgdma_clear(struct ttm_backend *be) | 54 | nouveau_sgdma_clear(struct ttm_backend *be) |
55 | { | 55 | { |
56 | struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; | 56 | struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; |
57 | struct drm_device *dev = nvbe->dev; | 57 | struct drm_device *dev; |
58 | |||
59 | NV_DEBUG(nvbe->dev, "\n"); | ||
60 | 58 | ||
61 | if (nvbe && nvbe->pages) { | 59 | if (nvbe && nvbe->pages) { |
60 | dev = nvbe->dev; | ||
61 | NV_DEBUG(dev, "\n"); | ||
62 | |||
62 | if (nvbe->bound) | 63 | if (nvbe->bound) |
63 | be->func->unbind(be); | 64 | be->func->unbind(be); |
64 | 65 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index f2d0187ba152..a4851af5b05e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -310,6 +310,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
310 | static unsigned int | 310 | static unsigned int |
311 | nouveau_vga_set_decode(void *priv, bool state) | 311 | nouveau_vga_set_decode(void *priv, bool state) |
312 | { | 312 | { |
313 | struct drm_device *dev = priv; | ||
314 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
315 | |||
316 | if (dev_priv->chipset >= 0x40) | ||
317 | nv_wr32(dev, 0x88054, state); | ||
318 | else | ||
319 | nv_wr32(dev, 0x1854, state); | ||
320 | |||
313 | if (state) | 321 | if (state) |
314 | return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | | 322 | return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | |
315 | VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; | 323 | VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
@@ -427,15 +435,19 @@ nouveau_card_init(struct drm_device *dev) | |||
427 | if (ret) | 435 | if (ret) |
428 | goto out_timer; | 436 | goto out_timer; |
429 | 437 | ||
430 | /* PGRAPH */ | 438 | if (nouveau_noaccel) |
431 | ret = engine->graph.init(dev); | 439 | engine->graph.accel_blocked = true; |
432 | if (ret) | 440 | else { |
433 | goto out_fb; | 441 | /* PGRAPH */ |
442 | ret = engine->graph.init(dev); | ||
443 | if (ret) | ||
444 | goto out_fb; | ||
434 | 445 | ||
435 | /* PFIFO */ | 446 | /* PFIFO */ |
436 | ret = engine->fifo.init(dev); | 447 | ret = engine->fifo.init(dev); |
437 | if (ret) | 448 | if (ret) |
438 | goto out_graph; | 449 | goto out_graph; |
450 | } | ||
439 | 451 | ||
440 | /* this call irq_preinstall, register irq handler and | 452 | /* this call irq_preinstall, register irq handler and |
441 | * call irq_postinstall | 453 | * call irq_postinstall |
@@ -479,9 +491,11 @@ nouveau_card_init(struct drm_device *dev) | |||
479 | out_irq: | 491 | out_irq: |
480 | drm_irq_uninstall(dev); | 492 | drm_irq_uninstall(dev); |
481 | out_fifo: | 493 | out_fifo: |
482 | engine->fifo.takedown(dev); | 494 | if (!nouveau_noaccel) |
495 | engine->fifo.takedown(dev); | ||
483 | out_graph: | 496 | out_graph: |
484 | engine->graph.takedown(dev); | 497 | if (!nouveau_noaccel) |
498 | engine->graph.takedown(dev); | ||
485 | out_fb: | 499 | out_fb: |
486 | engine->fb.takedown(dev); | 500 | engine->fb.takedown(dev); |
487 | out_timer: | 501 | out_timer: |
@@ -518,8 +532,10 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
518 | dev_priv->channel = NULL; | 532 | dev_priv->channel = NULL; |
519 | } | 533 | } |
520 | 534 | ||
521 | engine->fifo.takedown(dev); | 535 | if (!nouveau_noaccel) { |
522 | engine->graph.takedown(dev); | 536 | engine->fifo.takedown(dev); |
537 | engine->graph.takedown(dev); | ||
538 | } | ||
523 | engine->fb.takedown(dev); | 539 | engine->fb.takedown(dev); |
524 | engine->timer.takedown(dev); | 540 | engine->timer.takedown(dev); |
525 | engine->mc.takedown(dev); | 541 | engine->mc.takedown(dev); |
@@ -817,6 +833,15 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
817 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: | 833 | case NOUVEAU_GETPARAM_VM_VRAM_BASE: |
818 | getparam->value = dev_priv->vm_vram_base; | 834 | getparam->value = dev_priv->vm_vram_base; |
819 | break; | 835 | break; |
836 | case NOUVEAU_GETPARAM_GRAPH_UNITS: | ||
837 | /* NV40 and NV50 versions are quite different, but register | ||
838 | * address is the same. User is supposed to know the card | ||
839 | * family anyway... */ | ||
840 | if (dev_priv->chipset >= 0x40) { | ||
841 | getparam->value = nv_rd32(dev, NV40_PMC_GRAPH_UNITS); | ||
842 | break; | ||
843 | } | ||
844 | /* FALLTHRU */ | ||
820 | default: | 845 | default: |
821 | NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); | 846 | NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); |
822 | return -EINVAL; | 847 | return -EINVAL; |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index d0e038d28948..1d73b15d70da 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -119,7 +119,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
119 | struct drm_connector *connector) | 119 | struct drm_connector *connector) |
120 | { | 120 | { |
121 | struct drm_device *dev = encoder->dev; | 121 | struct drm_device *dev = encoder->dev; |
122 | uint8_t saved_seq1, saved_pi, saved_rpc1; | 122 | uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode; |
123 | uint8_t saved_palette0[3], saved_palette_mask; | 123 | uint8_t saved_palette0[3], saved_palette_mask; |
124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; | 124 | uint32_t saved_rtest_ctrl, saved_rgen_ctrl; |
125 | int i; | 125 | int i; |
@@ -135,6 +135,9 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, | |||
135 | /* only implemented for head A for now */ | 135 | /* only implemented for head A for now */ |
136 | NVSetOwner(dev, 0); | 136 | NVSetOwner(dev, 0); |
137 | 137 | ||
138 | saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX); | ||
139 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80); | ||
140 | |||
138 | saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); | 141 | saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); |
139 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); | 142 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); |
140 | 143 | ||
@@ -203,6 +206,7 @@ out: | |||
203 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); | 206 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); |
204 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); | 207 | NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); |
205 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); | 208 | NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); |
209 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); | ||
206 | 210 | ||
207 | if (blue == 0x18) { | 211 | if (blue == 0x18) { |
208 | NV_INFO(dev, "Load detected on head A\n"); | 212 | NV_INFO(dev, "Load detected on head A\n"); |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index d910873c1368..fd01caabd5c3 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "nouveau_dma.h" | 27 | #include "nouveau_dma.h" |
28 | #include "nouveau_fbcon.h" | 28 | #include "nouveau_fbcon.h" |
29 | 29 | ||
30 | static void | 30 | void |
31 | nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 31 | nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
32 | { | 32 | { |
33 | struct nouveau_fbcon_par *par = info->par; | 33 | struct nouveau_fbcon_par *par = info->par; |
@@ -54,7 +54,7 @@ nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
54 | FIRE_RING(chan); | 54 | FIRE_RING(chan); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void | 57 | void |
58 | nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 58 | nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
59 | { | 59 | { |
60 | struct nouveau_fbcon_par *par = info->par; | 60 | struct nouveau_fbcon_par *par = info->par; |
@@ -88,7 +88,7 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
88 | FIRE_RING(chan); | 88 | FIRE_RING(chan); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void | 91 | void |
92 | nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | 92 | nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) |
93 | { | 93 | { |
94 | struct nouveau_fbcon_par *par = info->par; | 94 | struct nouveau_fbcon_par *par = info->par; |
@@ -307,9 +307,6 @@ nv04_fbcon_accel_init(struct fb_info *info) | |||
307 | 307 | ||
308 | FIRE_RING(chan); | 308 | FIRE_RING(chan); |
309 | 309 | ||
310 | info->fbops->fb_fillrect = nv04_fbcon_fillrect; | ||
311 | info->fbops->fb_copyarea = nv04_fbcon_copyarea; | ||
312 | info->fbops->fb_imageblit = nv04_fbcon_imageblit; | ||
313 | return 0; | 310 | return 0; |
314 | } | 311 | } |
315 | 312 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 58b917c3341b..21ac6e49b6ee 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -579,6 +579,8 @@ static void nv17_tv_restore(struct drm_encoder *encoder) | |||
579 | nouveau_encoder(encoder)->restore.output); | 579 | nouveau_encoder(encoder)->restore.output); |
580 | 580 | ||
581 | nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state); | 581 | nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state); |
582 | |||
583 | nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED; | ||
582 | } | 584 | } |
583 | 585 | ||
584 | static int nv17_tv_create_resources(struct drm_encoder *encoder, | 586 | static int nv17_tv_create_resources(struct drm_encoder *encoder, |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 40b7360841f8..d1a651e3400c 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -298,14 +298,17 @@ nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) | |||
298 | static void | 298 | static void |
299 | nv50_crtc_destroy(struct drm_crtc *crtc) | 299 | nv50_crtc_destroy(struct drm_crtc *crtc) |
300 | { | 300 | { |
301 | struct drm_device *dev = crtc->dev; | 301 | struct drm_device *dev; |
302 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 302 | struct nouveau_crtc *nv_crtc; |
303 | |||
304 | NV_DEBUG_KMS(dev, "\n"); | ||
305 | 303 | ||
306 | if (!crtc) | 304 | if (!crtc) |
307 | return; | 305 | return; |
308 | 306 | ||
307 | dev = crtc->dev; | ||
308 | nv_crtc = nouveau_crtc(crtc); | ||
309 | |||
310 | NV_DEBUG_KMS(dev, "\n"); | ||
311 | |||
309 | drm_crtc_cleanup(&nv_crtc->base); | 312 | drm_crtc_cleanup(&nv_crtc->base); |
310 | 313 | ||
311 | nv50_cursor_fini(nv_crtc); | 314 | nv50_cursor_fini(nv_crtc); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index e4f279ee61cf..0f57cdf7ccb2 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
@@ -3,7 +3,7 @@ | |||
3 | #include "nouveau_dma.h" | 3 | #include "nouveau_dma.h" |
4 | #include "nouveau_fbcon.h" | 4 | #include "nouveau_fbcon.h" |
5 | 5 | ||
6 | static void | 6 | void |
7 | nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | 7 | nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
8 | { | 8 | { |
9 | struct nouveau_fbcon_par *par = info->par; | 9 | struct nouveau_fbcon_par *par = info->par; |
@@ -46,7 +46,7 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
46 | FIRE_RING(chan); | 46 | FIRE_RING(chan); |
47 | } | 47 | } |
48 | 48 | ||
49 | static void | 49 | void |
50 | nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | 50 | nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) |
51 | { | 51 | { |
52 | struct nouveau_fbcon_par *par = info->par; | 52 | struct nouveau_fbcon_par *par = info->par; |
@@ -81,7 +81,7 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
81 | FIRE_RING(chan); | 81 | FIRE_RING(chan); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void | 84 | void |
85 | nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | 85 | nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) |
86 | { | 86 | { |
87 | struct nouveau_fbcon_par *par = info->par; | 87 | struct nouveau_fbcon_par *par = info->par; |
@@ -262,9 +262,6 @@ nv50_fbcon_accel_init(struct fb_info *info) | |||
262 | OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + | 262 | OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys + |
263 | dev_priv->vm_vram_base); | 263 | dev_priv->vm_vram_base); |
264 | 264 | ||
265 | info->fbops->fb_fillrect = nv50_fbcon_fillrect; | ||
266 | info->fbops->fb_copyarea = nv50_fbcon_copyarea; | ||
267 | info->fbops->fb_imageblit = nv50_fbcon_imageblit; | ||
268 | return 0; | 265 | return 0; |
269 | } | 266 | } |
270 | 267 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 32b244bcb482..204a79ff10f4 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -317,17 +317,20 @@ void | |||
317 | nv50_fifo_destroy_context(struct nouveau_channel *chan) | 317 | nv50_fifo_destroy_context(struct nouveau_channel *chan) |
318 | { | 318 | { |
319 | struct drm_device *dev = chan->dev; | 319 | struct drm_device *dev = chan->dev; |
320 | struct nouveau_gpuobj_ref *ramfc = chan->ramfc; | ||
320 | 321 | ||
321 | NV_DEBUG(dev, "ch%d\n", chan->id); | 322 | NV_DEBUG(dev, "ch%d\n", chan->id); |
322 | 323 | ||
323 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); | 324 | /* This will ensure the channel is seen as disabled. */ |
324 | nouveau_gpuobj_ref_del(dev, &chan->cache); | 325 | chan->ramfc = NULL; |
325 | |||
326 | nv50_fifo_channel_disable(dev, chan->id, false); | 326 | nv50_fifo_channel_disable(dev, chan->id, false); |
327 | 327 | ||
328 | /* Dummy channel, also used on ch 127 */ | 328 | /* Dummy channel, also used on ch 127 */ |
329 | if (chan->id == 0) | 329 | if (chan->id == 0) |
330 | nv50_fifo_channel_disable(dev, 127, false); | 330 | nv50_fifo_channel_disable(dev, 127, false); |
331 | |||
332 | nouveau_gpuobj_ref_del(dev, &ramfc); | ||
333 | nouveau_gpuobj_ref_del(dev, &chan->cache); | ||
331 | } | 334 | } |
332 | 335 | ||
333 | int | 336 | int |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 20319e59d368..6d504801b514 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -165,6 +165,12 @@ nv50_graph_channel(struct drm_device *dev) | |||
165 | uint32_t inst; | 165 | uint32_t inst; |
166 | int i; | 166 | int i; |
167 | 167 | ||
168 | /* Be sure we're not in the middle of a context switch or bad things | ||
169 | * will happen, such as unloading the wrong pgraph context. | ||
170 | */ | ||
171 | if (!nv_wait(0x400300, 0x00000001, 0x00000000)) | ||
172 | NV_ERROR(dev, "Ctxprog is still running\n"); | ||
173 | |||
168 | inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); | 174 | inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); |
169 | if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) | 175 | if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) |
170 | return NULL; | 176 | return NULL; |
@@ -275,7 +281,7 @@ nv50_graph_load_context(struct nouveau_channel *chan) | |||
275 | int | 281 | int |
276 | nv50_graph_unload_context(struct drm_device *dev) | 282 | nv50_graph_unload_context(struct drm_device *dev) |
277 | { | 283 | { |
278 | uint32_t inst, fifo = nv_rd32(dev, 0x400500); | 284 | uint32_t inst; |
279 | 285 | ||
280 | inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); | 286 | inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR); |
281 | if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) | 287 | if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED)) |
@@ -283,12 +289,10 @@ nv50_graph_unload_context(struct drm_device *dev) | |||
283 | inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE; | 289 | inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE; |
284 | 290 | ||
285 | nouveau_wait_for_idle(dev); | 291 | nouveau_wait_for_idle(dev); |
286 | nv_wr32(dev, 0x400500, fifo & ~1); | ||
287 | nv_wr32(dev, 0x400784, inst); | 292 | nv_wr32(dev, 0x400784, inst); |
288 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20); | 293 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20); |
289 | nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01); | 294 | nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01); |
290 | nouveau_wait_for_idle(dev); | 295 | nouveau_wait_for_idle(dev); |
291 | nv_wr32(dev, 0x400500, fifo); | ||
292 | 296 | ||
293 | nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst); | 297 | nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst); |
294 | return 0; | 298 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 94400f777e7f..f0dc4e36ef05 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -76,6 +76,11 @@ nv50_instmem_init(struct drm_device *dev) | |||
76 | for (i = 0x1700; i <= 0x1710; i += 4) | 76 | for (i = 0x1700; i <= 0x1710; i += 4) |
77 | priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); | 77 | priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); |
78 | 78 | ||
79 | if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) | ||
80 | dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12; | ||
81 | else | ||
82 | dev_priv->vram_sys_base = 0; | ||
83 | |||
79 | /* Reserve the last MiB of VRAM, we should probably try to avoid | 84 | /* Reserve the last MiB of VRAM, we should probably try to avoid |
80 | * setting up the below tables over the top of the VBIOS image at | 85 | * setting up the below tables over the top of the VBIOS image at |
81 | * some point. | 86 | * some point. |
@@ -172,16 +177,28 @@ nv50_instmem_init(struct drm_device *dev) | |||
172 | * We map the entire fake channel into the start of the PRAMIN BAR | 177 | * We map the entire fake channel into the start of the PRAMIN BAR |
173 | */ | 178 | */ |
174 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, | 179 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, |
175 | 0, &priv->pramin_pt); | 180 | 0, &priv->pramin_pt); |
176 | if (ret) | 181 | if (ret) |
177 | return ret; | 182 | return ret; |
178 | 183 | ||
179 | for (i = 0, v = c_offset; i < pt_size; i += 8, v += 0x1000) { | 184 | v = c_offset | 1; |
180 | if (v < (c_offset + c_size)) | 185 | if (dev_priv->vram_sys_base) { |
181 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); | 186 | v += dev_priv->vram_sys_base; |
182 | else | 187 | v |= 0x30; |
183 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); | 188 | } |
189 | |||
190 | i = 0; | ||
191 | while (v < dev_priv->vram_sys_base + c_offset + c_size) { | ||
192 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v); | ||
193 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); | ||
194 | v += 0x1000; | ||
195 | i += 8; | ||
196 | } | ||
197 | |||
198 | while (i < pt_size) { | ||
199 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000000); | ||
184 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); | 200 | BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); |
201 | i += 8; | ||
185 | } | 202 | } |
186 | 203 | ||
187 | BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); | 204 | BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); |
@@ -416,7 +433,9 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
416 | { | 433 | { |
417 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 434 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
418 | struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; | 435 | struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; |
419 | uint32_t pte, pte_end, vram; | 436 | struct nouveau_gpuobj *pramin_pt = priv->pramin_pt->gpuobj; |
437 | uint32_t pte, pte_end; | ||
438 | uint64_t vram; | ||
420 | 439 | ||
421 | if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) | 440 | if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) |
422 | return -EINVAL; | 441 | return -EINVAL; |
@@ -424,20 +443,24 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
424 | NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", | 443 | NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", |
425 | gpuobj->im_pramin->start, gpuobj->im_pramin->size); | 444 | gpuobj->im_pramin->start, gpuobj->im_pramin->size); |
426 | 445 | ||
427 | pte = (gpuobj->im_pramin->start >> 12) << 3; | 446 | pte = (gpuobj->im_pramin->start >> 12) << 1; |
428 | pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; | 447 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; |
429 | vram = gpuobj->im_backing_start; | 448 | vram = gpuobj->im_backing_start; |
430 | 449 | ||
431 | NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", | 450 | NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", |
432 | gpuobj->im_pramin->start, pte, pte_end); | 451 | gpuobj->im_pramin->start, pte, pte_end); |
433 | NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); | 452 | NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); |
434 | 453 | ||
454 | vram |= 1; | ||
455 | if (dev_priv->vram_sys_base) { | ||
456 | vram += dev_priv->vram_sys_base; | ||
457 | vram |= 0x30; | ||
458 | } | ||
459 | |||
435 | dev_priv->engine.instmem.prepare_access(dev, true); | 460 | dev_priv->engine.instmem.prepare_access(dev, true); |
436 | while (pte < pte_end) { | 461 | while (pte < pte_end) { |
437 | nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); | 462 | nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram)); |
438 | nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); | 463 | nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram)); |
439 | |||
440 | pte += 8; | ||
441 | vram += NV50_INSTMEM_PAGE_SIZE; | 464 | vram += NV50_INSTMEM_PAGE_SIZE; |
442 | } | 465 | } |
443 | dev_priv->engine.instmem.finish_access(dev); | 466 | dev_priv->engine.instmem.finish_access(dev); |
@@ -470,14 +493,13 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
470 | if (gpuobj->im_bound == 0) | 493 | if (gpuobj->im_bound == 0) |
471 | return -EINVAL; | 494 | return -EINVAL; |
472 | 495 | ||
473 | pte = (gpuobj->im_pramin->start >> 12) << 3; | 496 | pte = (gpuobj->im_pramin->start >> 12) << 1; |
474 | pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; | 497 | pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; |
475 | 498 | ||
476 | dev_priv->engine.instmem.prepare_access(dev, true); | 499 | dev_priv->engine.instmem.prepare_access(dev, true); |
477 | while (pte < pte_end) { | 500 | while (pte < pte_end) { |
478 | nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); | 501 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); |
479 | nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); | 502 | nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000); |
480 | pte += 8; | ||
481 | } | 503 | } |
482 | dev_priv->engine.instmem.finish_access(dev); | 504 | dev_priv->engine.instmem.finish_access(dev); |
483 | 505 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index ecf1936b8224..c2fff543b06f 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -101,6 +101,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
101 | struct nouveau_encoder *nvenc = nouveau_encoder(enc); | 101 | struct nouveau_encoder *nvenc = nouveau_encoder(enc); |
102 | 102 | ||
103 | if (nvenc == nv_encoder || | 103 | if (nvenc == nv_encoder || |
104 | nvenc->disconnect != nv50_sor_disconnect || | ||
104 | nvenc->dcb->or != nv_encoder->dcb->or) | 105 | nvenc->dcb->or != nv_encoder->dcb->or) |
105 | continue; | 106 | continue; |
106 | 107 | ||
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig index 5982321be4d5..1c02d23f6fcc 100644 --- a/drivers/gpu/drm/radeon/Kconfig +++ b/drivers/gpu/drm/radeon/Kconfig | |||
@@ -1,10 +1,14 @@ | |||
1 | config DRM_RADEON_KMS | 1 | config DRM_RADEON_KMS |
2 | bool "Enable modesetting on radeon by default" | 2 | bool "Enable modesetting on radeon by default - NEW DRIVER" |
3 | depends on DRM_RADEON | 3 | depends on DRM_RADEON |
4 | help | 4 | help |
5 | Choose this option if you want kernel modesetting enabled by default, | 5 | Choose this option if you want kernel modesetting enabled by default. |
6 | and you have a new enough userspace to support this. Running old | 6 | |
7 | userspaces with this enabled will cause pain. | 7 | This is a completely new driver. It's only part of the existing drm |
8 | for compatibility reasons. It requires an entirely different graphics | ||
9 | stack above it and works very differently from the old drm stack. | ||
10 | i.e. don't enable this unless you know what you are doing it may | ||
11 | cause issues or bugs compared to the previous userspace driver stack. | ||
8 | 12 | ||
9 | When kernel modesetting is enabled the IOCTL of radeon/drm | 13 | When kernel modesetting is enabled the IOCTL of radeon/drm |
10 | driver are considered as invalid and an error message is printed | 14 | driver are considered as invalid and an error message is printed |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index e3b44562d265..7f152f66f196 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <asm/unaligned.h> | ||
27 | 28 | ||
28 | #define ATOM_DEBUG | 29 | #define ATOM_DEBUG |
29 | 30 | ||
@@ -212,7 +213,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, | |||
212 | case ATOM_ARG_PS: | 213 | case ATOM_ARG_PS: |
213 | idx = U8(*ptr); | 214 | idx = U8(*ptr); |
214 | (*ptr)++; | 215 | (*ptr)++; |
215 | val = le32_to_cpu(ctx->ps[idx]); | 216 | /* get_unaligned_le32 avoids unaligned accesses from atombios |
217 | * tables, noticed on a DEC Alpha. */ | ||
218 | val = get_unaligned_le32((u32 *)&ctx->ps[idx]); | ||
216 | if (print) | 219 | if (print) |
217 | DEBUG("PS[0x%02X,0x%04X]", idx, val); | 220 | DEBUG("PS[0x%02X,0x%04X]", idx, val); |
218 | break; | 221 | break; |
@@ -640,7 +643,7 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg) | |||
640 | uint8_t count = U8((*ptr)++); | 643 | uint8_t count = U8((*ptr)++); |
641 | SDEBUG(" count: %d\n", count); | 644 | SDEBUG(" count: %d\n", count); |
642 | if (arg == ATOM_UNIT_MICROSEC) | 645 | if (arg == ATOM_UNIT_MICROSEC) |
643 | schedule_timeout_uninterruptible(usecs_to_jiffies(count)); | 646 | udelay(count); |
644 | else | 647 | else |
645 | schedule_timeout_uninterruptible(msecs_to_jiffies(count)); | 648 | schedule_timeout_uninterruptible(msecs_to_jiffies(count)); |
646 | } | 649 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 71060114d5de..99915a682d59 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -332,11 +332,13 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; | 332 | PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); | 333 | int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction); |
334 | unsigned char *base; | 334 | unsigned char *base; |
335 | int retry_count = 0; | ||
335 | 336 | ||
336 | memset(&args, 0, sizeof(args)); | 337 | memset(&args, 0, sizeof(args)); |
337 | 338 | ||
338 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | 339 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
339 | 340 | ||
341 | retry: | ||
340 | memcpy(base, req_bytes, num_bytes); | 342 | memcpy(base, req_bytes, num_bytes); |
341 | 343 | ||
342 | args.lpAuxRequest = 0; | 344 | args.lpAuxRequest = 0; |
@@ -347,10 +349,12 @@ bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | |||
347 | 349 | ||
348 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 350 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
349 | 351 | ||
350 | if (args.ucReplyStatus) { | 352 | if (args.ucReplyStatus && !args.ucDataOutLen) { |
351 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x\n", | 353 | if (args.ucReplyStatus == 0x20 && retry_count++ < 10) |
354 | goto retry; | ||
355 | DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", | ||
352 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], | 356 | req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], |
353 | chan->rec.i2c_id, args.ucReplyStatus); | 357 | chan->rec.i2c_id, args.ucReplyStatus, retry_count); |
354 | return false; | 358 | return false; |
355 | } | 359 | } |
356 | 360 | ||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 11c9a3fe6810..c0d4650cdb79 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -354,11 +354,17 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | |||
354 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | 354 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
355 | } | 355 | } |
356 | 356 | ||
357 | /* Who ever call radeon_fence_emit should call ring_lock and ask | ||
358 | * for enough space (today caller are ib schedule and buffer move) */ | ||
357 | void r100_fence_ring_emit(struct radeon_device *rdev, | 359 | void r100_fence_ring_emit(struct radeon_device *rdev, |
358 | struct radeon_fence *fence) | 360 | struct radeon_fence *fence) |
359 | { | 361 | { |
360 | /* Who ever call radeon_fence_emit should call ring_lock and ask | 362 | /* We have to make sure that caches are flushed before |
361 | * for enough space (today caller are ib schedule and buffer move) */ | 363 | * CPU might read something from VRAM. */ |
364 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); | ||
365 | radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL); | ||
366 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); | ||
367 | radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL); | ||
362 | /* Wait until IDLE & CLEAN */ | 368 | /* Wait until IDLE & CLEAN */ |
363 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); | 369 | radeon_ring_write(rdev, PACKET0(0x1720, 0)); |
364 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); | 370 | radeon_ring_write(rdev, (1 << 16) | (1 << 17)); |
@@ -3369,7 +3375,6 @@ int r100_suspend(struct radeon_device *rdev) | |||
3369 | 3375 | ||
3370 | void r100_fini(struct radeon_device *rdev) | 3376 | void r100_fini(struct radeon_device *rdev) |
3371 | { | 3377 | { |
3372 | r100_suspend(rdev); | ||
3373 | r100_cp_fini(rdev); | 3378 | r100_cp_fini(rdev); |
3374 | r100_wb_fini(rdev); | 3379 | r100_wb_fini(rdev); |
3375 | r100_ib_fini(rdev); | 3380 | r100_ib_fini(rdev); |
@@ -3481,13 +3486,12 @@ int r100_init(struct radeon_device *rdev) | |||
3481 | if (r) { | 3486 | if (r) { |
3482 | /* Somethings want wront with the accel init stop accel */ | 3487 | /* Somethings want wront with the accel init stop accel */ |
3483 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 3488 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
3484 | r100_suspend(rdev); | ||
3485 | r100_cp_fini(rdev); | 3489 | r100_cp_fini(rdev); |
3486 | r100_wb_fini(rdev); | 3490 | r100_wb_fini(rdev); |
3487 | r100_ib_fini(rdev); | 3491 | r100_ib_fini(rdev); |
3492 | radeon_irq_kms_fini(rdev); | ||
3488 | if (rdev->flags & RADEON_IS_PCI) | 3493 | if (rdev->flags & RADEON_IS_PCI) |
3489 | r100_pci_gart_fini(rdev); | 3494 | r100_pci_gart_fini(rdev); |
3490 | radeon_irq_kms_fini(rdev); | ||
3491 | rdev->accel_working = false; | 3495 | rdev->accel_working = false; |
3492 | } | 3496 | } |
3493 | return 0; | 3497 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 0051d11b907c..43b55a030b4d 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -506,11 +506,14 @@ void r300_vram_info(struct radeon_device *rdev) | |||
506 | 506 | ||
507 | /* DDR for all card after R300 & IGP */ | 507 | /* DDR for all card after R300 & IGP */ |
508 | rdev->mc.vram_is_ddr = true; | 508 | rdev->mc.vram_is_ddr = true; |
509 | |||
509 | tmp = RREG32(RADEON_MEM_CNTL); | 510 | tmp = RREG32(RADEON_MEM_CNTL); |
510 | if (tmp & R300_MEM_NUM_CHANNELS_MASK) { | 511 | tmp &= R300_MEM_NUM_CHANNELS_MASK; |
511 | rdev->mc.vram_width = 128; | 512 | switch (tmp) { |
512 | } else { | 513 | case 0: rdev->mc.vram_width = 64; break; |
513 | rdev->mc.vram_width = 64; | 514 | case 1: rdev->mc.vram_width = 128; break; |
515 | case 2: rdev->mc.vram_width = 256; break; | ||
516 | default: rdev->mc.vram_width = 128; break; | ||
514 | } | 517 | } |
515 | 518 | ||
516 | r100_vram_init_sizes(rdev); | 519 | r100_vram_init_sizes(rdev); |
@@ -1327,7 +1330,6 @@ int r300_suspend(struct radeon_device *rdev) | |||
1327 | 1330 | ||
1328 | void r300_fini(struct radeon_device *rdev) | 1331 | void r300_fini(struct radeon_device *rdev) |
1329 | { | 1332 | { |
1330 | r300_suspend(rdev); | ||
1331 | r100_cp_fini(rdev); | 1333 | r100_cp_fini(rdev); |
1332 | r100_wb_fini(rdev); | 1334 | r100_wb_fini(rdev); |
1333 | r100_ib_fini(rdev); | 1335 | r100_ib_fini(rdev); |
@@ -1418,15 +1420,15 @@ int r300_init(struct radeon_device *rdev) | |||
1418 | if (r) { | 1420 | if (r) { |
1419 | /* Somethings want wront with the accel init stop accel */ | 1421 | /* Somethings want wront with the accel init stop accel */ |
1420 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 1422 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
1421 | r300_suspend(rdev); | ||
1422 | r100_cp_fini(rdev); | 1423 | r100_cp_fini(rdev); |
1423 | r100_wb_fini(rdev); | 1424 | r100_wb_fini(rdev); |
1424 | r100_ib_fini(rdev); | 1425 | r100_ib_fini(rdev); |
1426 | radeon_irq_kms_fini(rdev); | ||
1425 | if (rdev->flags & RADEON_IS_PCIE) | 1427 | if (rdev->flags & RADEON_IS_PCIE) |
1426 | rv370_pcie_gart_fini(rdev); | 1428 | rv370_pcie_gart_fini(rdev); |
1427 | if (rdev->flags & RADEON_IS_PCI) | 1429 | if (rdev->flags & RADEON_IS_PCI) |
1428 | r100_pci_gart_fini(rdev); | 1430 | r100_pci_gart_fini(rdev); |
1429 | radeon_irq_kms_fini(rdev); | 1431 | radeon_agp_fini(rdev); |
1430 | rdev->accel_working = false; | 1432 | rdev->accel_working = false; |
1431 | } | 1433 | } |
1432 | return 0; | 1434 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 4526faaacca8..d9373246c97f 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -389,16 +389,15 @@ int r420_init(struct radeon_device *rdev) | |||
389 | if (r) { | 389 | if (r) { |
390 | /* Somethings want wront with the accel init stop accel */ | 390 | /* Somethings want wront with the accel init stop accel */ |
391 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 391 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
392 | r420_suspend(rdev); | ||
393 | r100_cp_fini(rdev); | 392 | r100_cp_fini(rdev); |
394 | r100_wb_fini(rdev); | 393 | r100_wb_fini(rdev); |
395 | r100_ib_fini(rdev); | 394 | r100_ib_fini(rdev); |
395 | radeon_irq_kms_fini(rdev); | ||
396 | if (rdev->flags & RADEON_IS_PCIE) | 396 | if (rdev->flags & RADEON_IS_PCIE) |
397 | rv370_pcie_gart_fini(rdev); | 397 | rv370_pcie_gart_fini(rdev); |
398 | if (rdev->flags & RADEON_IS_PCI) | 398 | if (rdev->flags & RADEON_IS_PCI) |
399 | r100_pci_gart_fini(rdev); | 399 | r100_pci_gart_fini(rdev); |
400 | radeon_agp_fini(rdev); | 400 | radeon_agp_fini(rdev); |
401 | radeon_irq_kms_fini(rdev); | ||
402 | rdev->accel_working = false; | 401 | rdev->accel_working = false; |
403 | } | 402 | } |
404 | return 0; | 403 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 9a189072f2b9..ddf5731eba0d 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -294,13 +294,12 @@ int r520_init(struct radeon_device *rdev) | |||
294 | if (r) { | 294 | if (r) { |
295 | /* Somethings want wront with the accel init stop accel */ | 295 | /* Somethings want wront with the accel init stop accel */ |
296 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 296 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
297 | rv515_suspend(rdev); | ||
298 | r100_cp_fini(rdev); | 297 | r100_cp_fini(rdev); |
299 | r100_wb_fini(rdev); | 298 | r100_wb_fini(rdev); |
300 | r100_ib_fini(rdev); | 299 | r100_ib_fini(rdev); |
300 | radeon_irq_kms_fini(rdev); | ||
301 | rv370_pcie_gart_fini(rdev); | 301 | rv370_pcie_gart_fini(rdev); |
302 | radeon_agp_fini(rdev); | 302 | radeon_agp_fini(rdev); |
303 | radeon_irq_kms_fini(rdev); | ||
304 | rdev->accel_working = false; | 303 | rdev->accel_working = false; |
305 | } | 304 | } |
306 | return 0; | 305 | return 0; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1b6d0001b20e..2ffcf5a03551 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1654,6 +1654,12 @@ void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
1654 | rdev->cp.align_mask = 16 - 1; | 1654 | rdev->cp.align_mask = 16 - 1; |
1655 | } | 1655 | } |
1656 | 1656 | ||
1657 | void r600_cp_fini(struct radeon_device *rdev) | ||
1658 | { | ||
1659 | r600_cp_stop(rdev); | ||
1660 | radeon_ring_fini(rdev); | ||
1661 | } | ||
1662 | |||
1657 | 1663 | ||
1658 | /* | 1664 | /* |
1659 | * GPU scratch registers helpers function. | 1665 | * GPU scratch registers helpers function. |
@@ -1861,6 +1867,12 @@ int r600_startup(struct radeon_device *rdev) | |||
1861 | return r; | 1867 | return r; |
1862 | } | 1868 | } |
1863 | r600_gpu_init(rdev); | 1869 | r600_gpu_init(rdev); |
1870 | r = r600_blit_init(rdev); | ||
1871 | if (r) { | ||
1872 | r600_blit_fini(rdev); | ||
1873 | rdev->asic->copy = NULL; | ||
1874 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
1875 | } | ||
1864 | /* pin copy shader into vram */ | 1876 | /* pin copy shader into vram */ |
1865 | if (rdev->r600_blit.shader_obj) { | 1877 | if (rdev->r600_blit.shader_obj) { |
1866 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 1878 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
@@ -1938,6 +1950,13 @@ int r600_resume(struct radeon_device *rdev) | |||
1938 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 1950 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); |
1939 | return r; | 1951 | return r; |
1940 | } | 1952 | } |
1953 | |||
1954 | r = r600_audio_init(rdev); | ||
1955 | if (r) { | ||
1956 | DRM_ERROR("radeon: audio resume failed\n"); | ||
1957 | return r; | ||
1958 | } | ||
1959 | |||
1941 | return r; | 1960 | return r; |
1942 | } | 1961 | } |
1943 | 1962 | ||
@@ -1945,6 +1964,7 @@ int r600_suspend(struct radeon_device *rdev) | |||
1945 | { | 1964 | { |
1946 | int r; | 1965 | int r; |
1947 | 1966 | ||
1967 | r600_audio_fini(rdev); | ||
1948 | /* FIXME: we should wait for ring to be empty */ | 1968 | /* FIXME: we should wait for ring to be empty */ |
1949 | r600_cp_stop(rdev); | 1969 | r600_cp_stop(rdev); |
1950 | rdev->cp.ready = false; | 1970 | rdev->cp.ready = false; |
@@ -2045,19 +2065,15 @@ int r600_init(struct radeon_device *rdev) | |||
2045 | r = r600_pcie_gart_init(rdev); | 2065 | r = r600_pcie_gart_init(rdev); |
2046 | if (r) | 2066 | if (r) |
2047 | return r; | 2067 | return r; |
2048 | r = r600_blit_init(rdev); | ||
2049 | if (r) { | ||
2050 | r600_blit_fini(rdev); | ||
2051 | rdev->asic->copy = NULL; | ||
2052 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
2053 | } | ||
2054 | 2068 | ||
2055 | rdev->accel_working = true; | 2069 | rdev->accel_working = true; |
2056 | r = r600_startup(rdev); | 2070 | r = r600_startup(rdev); |
2057 | if (r) { | 2071 | if (r) { |
2058 | r600_suspend(rdev); | 2072 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2073 | r600_cp_fini(rdev); | ||
2059 | r600_wb_fini(rdev); | 2074 | r600_wb_fini(rdev); |
2060 | radeon_ring_fini(rdev); | 2075 | r600_irq_fini(rdev); |
2076 | radeon_irq_kms_fini(rdev); | ||
2061 | r600_pcie_gart_fini(rdev); | 2077 | r600_pcie_gart_fini(rdev); |
2062 | rdev->accel_working = false; | 2078 | rdev->accel_working = false; |
2063 | } | 2079 | } |
@@ -2083,20 +2099,17 @@ int r600_init(struct radeon_device *rdev) | |||
2083 | 2099 | ||
2084 | void r600_fini(struct radeon_device *rdev) | 2100 | void r600_fini(struct radeon_device *rdev) |
2085 | { | 2101 | { |
2086 | /* Suspend operations */ | ||
2087 | r600_suspend(rdev); | ||
2088 | |||
2089 | r600_audio_fini(rdev); | 2102 | r600_audio_fini(rdev); |
2090 | r600_blit_fini(rdev); | 2103 | r600_blit_fini(rdev); |
2104 | r600_cp_fini(rdev); | ||
2105 | r600_wb_fini(rdev); | ||
2091 | r600_irq_fini(rdev); | 2106 | r600_irq_fini(rdev); |
2092 | radeon_irq_kms_fini(rdev); | 2107 | radeon_irq_kms_fini(rdev); |
2093 | radeon_ring_fini(rdev); | ||
2094 | r600_wb_fini(rdev); | ||
2095 | r600_pcie_gart_fini(rdev); | 2108 | r600_pcie_gart_fini(rdev); |
2109 | radeon_agp_fini(rdev); | ||
2096 | radeon_gem_fini(rdev); | 2110 | radeon_gem_fini(rdev); |
2097 | radeon_fence_driver_fini(rdev); | 2111 | radeon_fence_driver_fini(rdev); |
2098 | radeon_clocks_fini(rdev); | 2112 | radeon_clocks_fini(rdev); |
2099 | radeon_agp_fini(rdev); | ||
2100 | radeon_bo_fini(rdev); | 2113 | radeon_bo_fini(rdev); |
2101 | radeon_atombios_fini(rdev); | 2114 | radeon_atombios_fini(rdev); |
2102 | kfree(rdev->bios); | 2115 | kfree(rdev->bios); |
@@ -2900,3 +2913,18 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
2900 | return 0; | 2913 | return 0; |
2901 | #endif | 2914 | #endif |
2902 | } | 2915 | } |
2916 | |||
2917 | /** | ||
2918 | * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl | ||
2919 | * rdev: radeon device structure | ||
2920 | * bo: buffer object struct which userspace is waiting for idle | ||
2921 | * | ||
2922 | * Some R6XX/R7XX doesn't seems to take into account HDP flush performed | ||
2923 | * through ring buffer, this leads to corruption in rendering, see | ||
2924 | * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we | ||
2925 | * directly perform HDP flush by writing register through MMIO. | ||
2926 | */ | ||
2927 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | ||
2928 | { | ||
2929 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
2930 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 99e2c3891a7d..0dcb6904c4ff 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 36 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
37 | { | 37 | { |
38 | return rdev->family >= CHIP_R600 | 38 | return (rdev->family >= CHIP_R600 && rdev->family < CHIP_RV710) |
39 | || rdev->family == CHIP_RS600 | 39 | || rdev->family == CHIP_RS600 |
40 | || rdev->family == CHIP_RS690 | 40 | || rdev->family == CHIP_RS690 |
41 | || rdev->family == CHIP_RS740; | 41 | || rdev->family == CHIP_RS740; |
@@ -261,7 +261,6 @@ void r600_audio_fini(struct radeon_device *rdev) | |||
261 | if (!r600_audio_chipset_supported(rdev)) | 261 | if (!r600_audio_chipset_supported(rdev)) |
262 | return; | 262 | return; |
263 | 263 | ||
264 | WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000); | ||
265 | |||
266 | del_timer(&rdev->audio_timer); | 264 | del_timer(&rdev->audio_timer); |
265 | WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000); | ||
267 | } | 266 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index af1c3ca8a4cb..446b765ac72a 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -543,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device *rdev) | |||
543 | void r600_vb_ib_put(struct radeon_device *rdev) | 543 | void r600_vb_ib_put(struct radeon_device *rdev) |
544 | { | 544 | { |
545 | radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); | 545 | radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); |
546 | mutex_lock(&rdev->ib_pool.mutex); | ||
547 | list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs); | ||
548 | mutex_unlock(&rdev->ib_pool.mutex); | ||
549 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | 546 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); |
550 | } | 547 | } |
551 | 548 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 6d5a711c2e91..75bcf35a0931 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c | |||
@@ -1428,9 +1428,12 @@ static void r700_gfx_init(struct drm_device *dev, | |||
1428 | 1428 | ||
1429 | gb_tiling_config |= R600_BANK_SWAPS(1); | 1429 | gb_tiling_config |= R600_BANK_SWAPS(1); |
1430 | 1430 | ||
1431 | backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, | 1431 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740) |
1432 | dev_priv->r600_max_backends, | 1432 | backend_map = 0x28; |
1433 | (0xff << dev_priv->r600_max_backends) & 0xff); | 1433 | else |
1434 | backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, | ||
1435 | dev_priv->r600_max_backends, | ||
1436 | (0xff << dev_priv->r600_max_backends) & 0xff); | ||
1434 | gb_tiling_config |= R600_BACKEND_MAP(backend_map); | 1437 | gb_tiling_config |= R600_BACKEND_MAP(backend_map); |
1435 | 1438 | ||
1436 | cc_gc_shader_pipe_config = | 1439 | cc_gc_shader_pipe_config = |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 2d5f2bfa7201..c0356bb193e5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -96,6 +96,7 @@ extern int radeon_audio; | |||
96 | * symbol; | 96 | * symbol; |
97 | */ | 97 | */ |
98 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ | 98 | #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ |
99 | /* RADEON_IB_POOL_SIZE must be a power of 2 */ | ||
99 | #define RADEON_IB_POOL_SIZE 16 | 100 | #define RADEON_IB_POOL_SIZE 16 |
100 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 | 101 | #define RADEON_DEBUGFS_MAX_NUM_FILES 32 |
101 | #define RADEONFB_CONN_LIMIT 4 | 102 | #define RADEONFB_CONN_LIMIT 4 |
@@ -363,11 +364,12 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); | |||
363 | */ | 364 | */ |
364 | struct radeon_ib { | 365 | struct radeon_ib { |
365 | struct list_head list; | 366 | struct list_head list; |
366 | unsigned long idx; | 367 | unsigned idx; |
367 | uint64_t gpu_addr; | 368 | uint64_t gpu_addr; |
368 | struct radeon_fence *fence; | 369 | struct radeon_fence *fence; |
369 | uint32_t *ptr; | 370 | uint32_t *ptr; |
370 | uint32_t length_dw; | 371 | uint32_t length_dw; |
372 | bool free; | ||
371 | }; | 373 | }; |
372 | 374 | ||
373 | /* | 375 | /* |
@@ -377,10 +379,9 @@ struct radeon_ib { | |||
377 | struct radeon_ib_pool { | 379 | struct radeon_ib_pool { |
378 | struct mutex mutex; | 380 | struct mutex mutex; |
379 | struct radeon_bo *robj; | 381 | struct radeon_bo *robj; |
380 | struct list_head scheduled_ibs; | ||
381 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 382 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
382 | bool ready; | 383 | bool ready; |
383 | DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE); | 384 | unsigned head_id; |
384 | }; | 385 | }; |
385 | 386 | ||
386 | struct radeon_cp { | 387 | struct radeon_cp { |
@@ -661,6 +662,13 @@ struct radeon_asic { | |||
661 | void (*hpd_fini)(struct radeon_device *rdev); | 662 | void (*hpd_fini)(struct radeon_device *rdev); |
662 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 663 | bool (*hpd_sense)(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
663 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 664 | void (*hpd_set_polarity)(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
665 | /* ioctl hw specific callback. Some hw might want to perform special | ||
666 | * operation on specific ioctl. For instance on wait idle some hw | ||
667 | * might want to perform and HDP flush through MMIO as it seems that | ||
668 | * some R6XX/R7XX hw doesn't take HDP flush into account if programmed | ||
669 | * through ring. | ||
670 | */ | ||
671 | void (*ioctl_wait_idle)(struct radeon_device *rdev, struct radeon_bo *bo); | ||
664 | }; | 672 | }; |
665 | 673 | ||
666 | /* | 674 | /* |
@@ -1143,6 +1151,7 @@ extern bool r600_card_posted(struct radeon_device *rdev); | |||
1143 | extern void r600_cp_stop(struct radeon_device *rdev); | 1151 | extern void r600_cp_stop(struct radeon_device *rdev); |
1144 | extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); | 1152 | extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); |
1145 | extern int r600_cp_resume(struct radeon_device *rdev); | 1153 | extern int r600_cp_resume(struct radeon_device *rdev); |
1154 | extern void r600_cp_fini(struct radeon_device *rdev); | ||
1146 | extern int r600_count_pipe_bits(uint32_t val); | 1155 | extern int r600_count_pipe_bits(uint32_t val); |
1147 | extern int r600_gart_clear_page(struct radeon_device *rdev, int i); | 1156 | extern int r600_gart_clear_page(struct radeon_device *rdev, int i); |
1148 | extern int r600_mc_wait_for_idle(struct radeon_device *rdev); | 1157 | extern int r600_mc_wait_for_idle(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f2fbd2e4e9df..05ee1aeac3fd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -117,6 +117,7 @@ static struct radeon_asic r100_asic = { | |||
117 | .hpd_fini = &r100_hpd_fini, | 117 | .hpd_fini = &r100_hpd_fini, |
118 | .hpd_sense = &r100_hpd_sense, | 118 | .hpd_sense = &r100_hpd_sense, |
119 | .hpd_set_polarity = &r100_hpd_set_polarity, | 119 | .hpd_set_polarity = &r100_hpd_set_polarity, |
120 | .ioctl_wait_idle = NULL, | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | 123 | ||
@@ -176,6 +177,7 @@ static struct radeon_asic r300_asic = { | |||
176 | .hpd_fini = &r100_hpd_fini, | 177 | .hpd_fini = &r100_hpd_fini, |
177 | .hpd_sense = &r100_hpd_sense, | 178 | .hpd_sense = &r100_hpd_sense, |
178 | .hpd_set_polarity = &r100_hpd_set_polarity, | 179 | .hpd_set_polarity = &r100_hpd_set_polarity, |
180 | .ioctl_wait_idle = NULL, | ||
179 | }; | 181 | }; |
180 | 182 | ||
181 | /* | 183 | /* |
@@ -219,6 +221,7 @@ static struct radeon_asic r420_asic = { | |||
219 | .hpd_fini = &r100_hpd_fini, | 221 | .hpd_fini = &r100_hpd_fini, |
220 | .hpd_sense = &r100_hpd_sense, | 222 | .hpd_sense = &r100_hpd_sense, |
221 | .hpd_set_polarity = &r100_hpd_set_polarity, | 223 | .hpd_set_polarity = &r100_hpd_set_polarity, |
224 | .ioctl_wait_idle = NULL, | ||
222 | }; | 225 | }; |
223 | 226 | ||
224 | 227 | ||
@@ -267,6 +270,7 @@ static struct radeon_asic rs400_asic = { | |||
267 | .hpd_fini = &r100_hpd_fini, | 270 | .hpd_fini = &r100_hpd_fini, |
268 | .hpd_sense = &r100_hpd_sense, | 271 | .hpd_sense = &r100_hpd_sense, |
269 | .hpd_set_polarity = &r100_hpd_set_polarity, | 272 | .hpd_set_polarity = &r100_hpd_set_polarity, |
273 | .ioctl_wait_idle = NULL, | ||
270 | }; | 274 | }; |
271 | 275 | ||
272 | 276 | ||
@@ -323,6 +327,7 @@ static struct radeon_asic rs600_asic = { | |||
323 | .hpd_fini = &rs600_hpd_fini, | 327 | .hpd_fini = &rs600_hpd_fini, |
324 | .hpd_sense = &rs600_hpd_sense, | 328 | .hpd_sense = &rs600_hpd_sense, |
325 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 329 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
330 | .ioctl_wait_idle = NULL, | ||
326 | }; | 331 | }; |
327 | 332 | ||
328 | 333 | ||
@@ -370,6 +375,7 @@ static struct radeon_asic rs690_asic = { | |||
370 | .hpd_fini = &rs600_hpd_fini, | 375 | .hpd_fini = &rs600_hpd_fini, |
371 | .hpd_sense = &rs600_hpd_sense, | 376 | .hpd_sense = &rs600_hpd_sense, |
372 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 377 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
378 | .ioctl_wait_idle = NULL, | ||
373 | }; | 379 | }; |
374 | 380 | ||
375 | 381 | ||
@@ -421,6 +427,7 @@ static struct radeon_asic rv515_asic = { | |||
421 | .hpd_fini = &rs600_hpd_fini, | 427 | .hpd_fini = &rs600_hpd_fini, |
422 | .hpd_sense = &rs600_hpd_sense, | 428 | .hpd_sense = &rs600_hpd_sense, |
423 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 429 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
430 | .ioctl_wait_idle = NULL, | ||
424 | }; | 431 | }; |
425 | 432 | ||
426 | 433 | ||
@@ -463,6 +470,7 @@ static struct radeon_asic r520_asic = { | |||
463 | .hpd_fini = &rs600_hpd_fini, | 470 | .hpd_fini = &rs600_hpd_fini, |
464 | .hpd_sense = &rs600_hpd_sense, | 471 | .hpd_sense = &rs600_hpd_sense, |
465 | .hpd_set_polarity = &rs600_hpd_set_polarity, | 472 | .hpd_set_polarity = &rs600_hpd_set_polarity, |
473 | .ioctl_wait_idle = NULL, | ||
466 | }; | 474 | }; |
467 | 475 | ||
468 | /* | 476 | /* |
@@ -504,6 +512,7 @@ void r600_hpd_fini(struct radeon_device *rdev); | |||
504 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); | 512 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); |
505 | void r600_hpd_set_polarity(struct radeon_device *rdev, | 513 | void r600_hpd_set_polarity(struct radeon_device *rdev, |
506 | enum radeon_hpd_id hpd); | 514 | enum radeon_hpd_id hpd); |
515 | extern void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo); | ||
507 | 516 | ||
508 | static struct radeon_asic r600_asic = { | 517 | static struct radeon_asic r600_asic = { |
509 | .init = &r600_init, | 518 | .init = &r600_init, |
@@ -538,6 +547,7 @@ static struct radeon_asic r600_asic = { | |||
538 | .hpd_fini = &r600_hpd_fini, | 547 | .hpd_fini = &r600_hpd_fini, |
539 | .hpd_sense = &r600_hpd_sense, | 548 | .hpd_sense = &r600_hpd_sense, |
540 | .hpd_set_polarity = &r600_hpd_set_polarity, | 549 | .hpd_set_polarity = &r600_hpd_set_polarity, |
550 | .ioctl_wait_idle = r600_ioctl_wait_idle, | ||
541 | }; | 551 | }; |
542 | 552 | ||
543 | /* | 553 | /* |
@@ -582,6 +592,7 @@ static struct radeon_asic rv770_asic = { | |||
582 | .hpd_fini = &r600_hpd_fini, | 592 | .hpd_fini = &r600_hpd_fini, |
583 | .hpd_sense = &r600_hpd_sense, | 593 | .hpd_sense = &r600_hpd_sense, |
584 | .hpd_set_polarity = &r600_hpd_set_polarity, | 594 | .hpd_set_polarity = &r600_hpd_set_polarity, |
595 | .ioctl_wait_idle = r600_ioctl_wait_idle, | ||
585 | }; | 596 | }; |
586 | 597 | ||
587 | #endif | 598 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index fa82ca74324e..4d8831548a5f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -206,6 +206,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
206 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 206 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
207 | } | 207 | } |
208 | 208 | ||
209 | /* Asrock RS600 board lists the DVI port as HDMI */ | ||
210 | if ((dev->pdev->device == 0x7941) && | ||
211 | (dev->pdev->subsystem_vendor == 0x1849) && | ||
212 | (dev->pdev->subsystem_device == 0x7941)) { | ||
213 | if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) && | ||
214 | (supported_device == ATOM_DEVICE_DFP3_SUPPORT)) | ||
215 | *connector_type = DRM_MODE_CONNECTOR_DVID; | ||
216 | } | ||
217 | |||
209 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ | 218 | /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ |
210 | if ((dev->pdev->device == 0x7941) && | 219 | if ((dev->pdev->device == 0x7941) && |
211 | (dev->pdev->subsystem_vendor == 0x147b) && | 220 | (dev->pdev->subsystem_vendor == 0x147b) && |
@@ -287,6 +296,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
287 | *connector_type = DRM_MODE_CONNECTOR_DVID; | 296 | *connector_type = DRM_MODE_CONNECTOR_DVID; |
288 | } | 297 | } |
289 | 298 | ||
299 | /* XFX Pine Group device rv730 reports no VGA DDC lines | ||
300 | * even though they are wired up to record 0x93 | ||
301 | */ | ||
302 | if ((dev->pdev->device == 0x9498) && | ||
303 | (dev->pdev->subsystem_vendor == 0x1682) && | ||
304 | (dev->pdev->subsystem_device == 0x2452)) { | ||
305 | struct radeon_device *rdev = dev->dev_private; | ||
306 | *i2c_bus = radeon_lookup_i2c_gpio(rdev, 0x93); | ||
307 | } | ||
290 | return true; | 308 | return true; |
291 | } | 309 | } |
292 | 310 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 4ddfd4b5bc51..7932dc4d6b90 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -65,31 +65,42 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, | |||
65 | if (r) { | 65 | if (r) { |
66 | goto out_cleanup; | 66 | goto out_cleanup; |
67 | } | 67 | } |
68 | start_jiffies = jiffies; | 68 | |
69 | for (i = 0; i < n; i++) { | 69 | /* r100 doesn't have dma engine so skip the test */ |
70 | r = radeon_fence_create(rdev, &fence); | 70 | if (rdev->asic->copy_dma) { |
71 | if (r) { | 71 | |
72 | goto out_cleanup; | 72 | start_jiffies = jiffies; |
73 | for (i = 0; i < n; i++) { | ||
74 | r = radeon_fence_create(rdev, &fence); | ||
75 | if (r) { | ||
76 | goto out_cleanup; | ||
77 | } | ||
78 | |||
79 | r = radeon_copy_dma(rdev, saddr, daddr, | ||
80 | size / RADEON_GPU_PAGE_SIZE, fence); | ||
81 | |||
82 | if (r) { | ||
83 | goto out_cleanup; | ||
84 | } | ||
85 | r = radeon_fence_wait(fence, false); | ||
86 | if (r) { | ||
87 | goto out_cleanup; | ||
88 | } | ||
89 | radeon_fence_unref(&fence); | ||
73 | } | 90 | } |
74 | r = radeon_copy_dma(rdev, saddr, daddr, size / RADEON_GPU_PAGE_SIZE, fence); | 91 | end_jiffies = jiffies; |
75 | if (r) { | 92 | time = end_jiffies - start_jiffies; |
76 | goto out_cleanup; | 93 | time = jiffies_to_msecs(time); |
94 | if (time > 0) { | ||
95 | i = ((n * size) >> 10) / time; | ||
96 | printk(KERN_INFO "radeon: dma %u bo moves of %ukb from" | ||
97 | " %d to %d in %lums (%ukb/ms %ukb/s %uM/s)\n", | ||
98 | n, size >> 10, | ||
99 | sdomain, ddomain, time, | ||
100 | i, i * 1000, (i * 1000) / 1024); | ||
77 | } | 101 | } |
78 | r = radeon_fence_wait(fence, false); | ||
79 | if (r) { | ||
80 | goto out_cleanup; | ||
81 | } | ||
82 | radeon_fence_unref(&fence); | ||
83 | } | ||
84 | end_jiffies = jiffies; | ||
85 | time = end_jiffies - start_jiffies; | ||
86 | time = jiffies_to_msecs(time); | ||
87 | if (time > 0) { | ||
88 | i = ((n * size) >> 10) / time; | ||
89 | printk(KERN_INFO "radeon: dma %u bo moves of %ukb from %d to %d" | ||
90 | " in %lums (%ukb/ms %ukb/s %uM/s)\n", n, size >> 10, | ||
91 | sdomain, ddomain, time, i, i * 1000, (i * 1000) / 1024); | ||
92 | } | 102 | } |
103 | |||
93 | start_jiffies = jiffies; | 104 | start_jiffies = jiffies; |
94 | for (i = 0; i < n; i++) { | 105 | for (i = 0; i < n; i++) { |
95 | r = radeon_fence_create(rdev, &fence); | 106 | r = radeon_fence_create(rdev, &fence); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 579c8920e081..e7b19440102e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -971,8 +971,7 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder | |||
971 | lvds->native_mode.vdisplay); | 971 | lvds->native_mode.vdisplay); |
972 | 972 | ||
973 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); | 973 | lvds->panel_vcc_delay = RBIOS16(lcd_info + 0x2c); |
974 | if (lvds->panel_vcc_delay > 2000 || lvds->panel_vcc_delay < 0) | 974 | lvds->panel_vcc_delay = min_t(u16, lvds->panel_vcc_delay, 2000); |
975 | lvds->panel_vcc_delay = 2000; | ||
976 | 975 | ||
977 | lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); | 976 | lvds->panel_pwr_delay = RBIOS8(lcd_info + 0x24); |
978 | lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; | 977 | lvds->panel_digon_delay = RBIOS16(lcd_info + 0x38) & 0xf; |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 55266416fa47..65f81942f399 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -580,16 +580,18 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
580 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 580 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
581 | struct drm_encoder *encoder; | 581 | struct drm_encoder *encoder; |
582 | struct drm_encoder_helper_funcs *encoder_funcs; | 582 | struct drm_encoder_helper_funcs *encoder_funcs; |
583 | bool dret; | 583 | bool dret = false; |
584 | enum drm_connector_status ret = connector_status_disconnected; | 584 | enum drm_connector_status ret = connector_status_disconnected; |
585 | 585 | ||
586 | encoder = radeon_best_single_encoder(connector); | 586 | encoder = radeon_best_single_encoder(connector); |
587 | if (!encoder) | 587 | if (!encoder) |
588 | ret = connector_status_disconnected; | 588 | ret = connector_status_disconnected; |
589 | 589 | ||
590 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | 590 | if (radeon_connector->ddc_bus) { |
591 | dret = radeon_ddc_probe(radeon_connector); | 591 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
592 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | 592 | dret = radeon_ddc_probe(radeon_connector); |
593 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
594 | } | ||
593 | if (dret) { | 595 | if (dret) { |
594 | if (radeon_connector->edid) { | 596 | if (radeon_connector->edid) { |
595 | kfree(radeon_connector->edid); | 597 | kfree(radeon_connector->edid); |
@@ -740,11 +742,13 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
740 | struct drm_mode_object *obj; | 742 | struct drm_mode_object *obj; |
741 | int i; | 743 | int i; |
742 | enum drm_connector_status ret = connector_status_disconnected; | 744 | enum drm_connector_status ret = connector_status_disconnected; |
743 | bool dret; | 745 | bool dret = false; |
744 | 746 | ||
745 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); | 747 | if (radeon_connector->ddc_bus) { |
746 | dret = radeon_ddc_probe(radeon_connector); | 748 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 1); |
747 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | 749 | dret = radeon_ddc_probe(radeon_connector); |
750 | radeon_i2c_do_lock(radeon_connector->ddc_bus, 0); | ||
751 | } | ||
748 | if (dret) { | 752 | if (dret) { |
749 | if (radeon_connector->edid) { | 753 | if (radeon_connector->edid) { |
750 | kfree(radeon_connector->edid); | 754 | kfree(radeon_connector->edid); |
@@ -776,7 +780,7 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
776 | * connected and the DVI port disconnected. If the edid doesn't | 780 | * connected and the DVI port disconnected. If the edid doesn't |
777 | * say HDMI, vice versa. | 781 | * say HDMI, vice versa. |
778 | */ | 782 | */ |
779 | if (radeon_connector->shared_ddc && connector_status_connected) { | 783 | if (radeon_connector->shared_ddc && (ret == connector_status_connected)) { |
780 | struct drm_device *dev = connector->dev; | 784 | struct drm_device *dev = connector->dev; |
781 | struct drm_connector *list_connector; | 785 | struct drm_connector *list_connector; |
782 | struct radeon_connector *list_radeon_connector; | 786 | struct radeon_connector *list_radeon_connector; |
@@ -1056,8 +1060,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1056 | return; | 1060 | return; |
1057 | } | 1061 | } |
1058 | if (radeon_connector->ddc_bus && i2c_bus->valid) { | 1062 | if (radeon_connector->ddc_bus && i2c_bus->valid) { |
1059 | if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, | 1063 | if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) { |
1060 | sizeof(struct radeon_i2c_bus_rec)) == 0) { | ||
1061 | radeon_connector->shared_ddc = true; | 1064 | radeon_connector->shared_ddc = true; |
1062 | shared_ddc = true; | 1065 | shared_ddc = true; |
1063 | } | 1066 | } |
@@ -1343,7 +1346,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1343 | radeon_connector->dac_load_detect = false; | 1346 | radeon_connector->dac_load_detect = false; |
1344 | drm_connector_attach_property(&radeon_connector->base, | 1347 | drm_connector_attach_property(&radeon_connector->base, |
1345 | rdev->mode_info.load_detect_property, | 1348 | rdev->mode_info.load_detect_property, |
1346 | 1); | 1349 | radeon_connector->dac_load_detect); |
1347 | drm_connector_attach_property(&radeon_connector->base, | 1350 | drm_connector_attach_property(&radeon_connector->base, |
1348 | rdev->mode_info.tv_std_property, | 1351 | rdev->mode_info.tv_std_property, |
1349 | radeon_combios_get_tv_info(rdev)); | 1352 | radeon_combios_get_tv_info(rdev)); |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 1190148cf5e6..e9d085021c1f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -86,7 +86,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) | |||
86 | &p->validated); | 86 | &p->validated); |
87 | } | 87 | } |
88 | } | 88 | } |
89 | return radeon_bo_list_validate(&p->validated, p->ib->fence); | 89 | return radeon_bo_list_validate(&p->validated); |
90 | } | 90 | } |
91 | 91 | ||
92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | 92 | int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) |
@@ -189,12 +189,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
189 | { | 189 | { |
190 | unsigned i; | 190 | unsigned i; |
191 | 191 | ||
192 | if (error && parser->ib) { | 192 | if (!error && parser->ib) { |
193 | radeon_bo_list_unvalidate(&parser->validated, | 193 | radeon_bo_list_fence(&parser->validated, parser->ib->fence); |
194 | parser->ib->fence); | ||
195 | } else { | ||
196 | radeon_bo_list_unreserve(&parser->validated); | ||
197 | } | 194 | } |
195 | radeon_bo_list_unreserve(&parser->validated); | ||
198 | for (i = 0; i < parser->nrelocs; i++) { | 196 | for (i = 0; i < parser->nrelocs; i++) { |
199 | if (parser->relocs[i].gobj) { | 197 | if (parser->relocs[i].gobj) { |
200 | mutex_lock(&parser->rdev->ddev->struct_mutex); | 198 | mutex_lock(&parser->rdev->ddev->struct_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 6a92f994cc26..7e17a362b54b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -278,7 +278,7 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
278 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); | 278 | DRM_INFO(" %s\n", connector_names[connector->connector_type]); |
279 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) | 279 | if (radeon_connector->hpd.hpd != RADEON_HPD_NONE) |
280 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); | 280 | DRM_INFO(" %s\n", hpd_names[radeon_connector->hpd.hpd]); |
281 | if (radeon_connector->ddc_bus) | 281 | if (radeon_connector->ddc_bus) { |
282 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 282 | DRM_INFO(" DDC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
283 | radeon_connector->ddc_bus->rec.mask_clk_reg, | 283 | radeon_connector->ddc_bus->rec.mask_clk_reg, |
284 | radeon_connector->ddc_bus->rec.mask_data_reg, | 284 | radeon_connector->ddc_bus->rec.mask_data_reg, |
@@ -288,6 +288,15 @@ static void radeon_print_display_setup(struct drm_device *dev) | |||
288 | radeon_connector->ddc_bus->rec.en_data_reg, | 288 | radeon_connector->ddc_bus->rec.en_data_reg, |
289 | radeon_connector->ddc_bus->rec.y_clk_reg, | 289 | radeon_connector->ddc_bus->rec.y_clk_reg, |
290 | radeon_connector->ddc_bus->rec.y_data_reg); | 290 | radeon_connector->ddc_bus->rec.y_data_reg); |
291 | } else { | ||
292 | if (connector->connector_type == DRM_MODE_CONNECTOR_VGA || | ||
293 | connector->connector_type == DRM_MODE_CONNECTOR_DVII || | ||
294 | connector->connector_type == DRM_MODE_CONNECTOR_DVID || | ||
295 | connector->connector_type == DRM_MODE_CONNECTOR_DVIA || | ||
296 | connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || | ||
297 | connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) | ||
298 | DRM_INFO(" DDC: no ddc bus - possible BIOS bug - please report to xorg-driver-ati@lists.x.org\n"); | ||
299 | } | ||
291 | DRM_INFO(" Encoders:\n"); | 300 | DRM_INFO(" Encoders:\n"); |
292 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 301 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
293 | radeon_encoder = to_radeon_encoder(encoder); | 302 | radeon_encoder = to_radeon_encoder(encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index e13785282a82..c57ad606504d 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -106,9 +106,10 @@ | |||
106 | * 1.29- R500 3D cmd buffer support | 106 | * 1.29- R500 3D cmd buffer support |
107 | * 1.30- Add support for occlusion queries | 107 | * 1.30- Add support for occlusion queries |
108 | * 1.31- Add support for num Z pipes from GET_PARAM | 108 | * 1.31- Add support for num Z pipes from GET_PARAM |
109 | * 1.32- fixes for rv740 setup | ||
109 | */ | 110 | */ |
110 | #define DRIVER_MAJOR 1 | 111 | #define DRIVER_MAJOR 1 |
111 | #define DRIVER_MINOR 31 | 112 | #define DRIVER_MINOR 32 |
112 | #define DRIVER_PATCHLEVEL 0 | 113 | #define DRIVER_PATCHLEVEL 0 |
113 | 114 | ||
114 | enum radeon_cp_microcode_version { | 115 | enum radeon_cp_microcode_version { |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 3ba213d1b06c..d71e346e9ab5 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -248,7 +248,7 @@ int radeonfb_create(struct drm_device *dev, | |||
248 | if (ret) | 248 | if (ret) |
249 | goto out_unref; | 249 | goto out_unref; |
250 | 250 | ||
251 | memset_io(fbptr, 0xff, aligned_size); | 251 | memset_io(fbptr, 0x0, aligned_size); |
252 | 252 | ||
253 | strcpy(info->fix.id, "radeondrmfb"); | 253 | strcpy(info->fix.id, "radeondrmfb"); |
254 | 254 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 0e1325e18534..db8e9a355a01 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -308,6 +308,9 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, | |||
308 | } | 308 | } |
309 | robj = gobj->driver_private; | 309 | robj = gobj->driver_private; |
310 | r = radeon_bo_wait(robj, NULL, false); | 310 | r = radeon_bo_wait(robj, NULL, false); |
311 | /* callback hw specific functions if any */ | ||
312 | if (robj->rdev->asic->ioctl_wait_idle) | ||
313 | robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); | ||
311 | mutex_lock(&dev->struct_mutex); | 314 | mutex_lock(&dev->struct_mutex); |
312 | drm_gem_object_unreference(gobj); | 315 | drm_gem_object_unreference(gobj); |
313 | mutex_unlock(&dev->struct_mutex); | 316 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d72a71bff218..f1da370928eb 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -306,11 +306,10 @@ void radeon_bo_list_unreserve(struct list_head *head) | |||
306 | } | 306 | } |
307 | } | 307 | } |
308 | 308 | ||
309 | int radeon_bo_list_validate(struct list_head *head, void *fence) | 309 | int radeon_bo_list_validate(struct list_head *head) |
310 | { | 310 | { |
311 | struct radeon_bo_list *lobj; | 311 | struct radeon_bo_list *lobj; |
312 | struct radeon_bo *bo; | 312 | struct radeon_bo *bo; |
313 | struct radeon_fence *old_fence = NULL; | ||
314 | int r; | 313 | int r; |
315 | 314 | ||
316 | r = radeon_bo_list_reserve(head); | 315 | r = radeon_bo_list_reserve(head); |
@@ -334,32 +333,27 @@ int radeon_bo_list_validate(struct list_head *head, void *fence) | |||
334 | } | 333 | } |
335 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); | 334 | lobj->gpu_offset = radeon_bo_gpu_offset(bo); |
336 | lobj->tiling_flags = bo->tiling_flags; | 335 | lobj->tiling_flags = bo->tiling_flags; |
337 | if (fence) { | ||
338 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; | ||
339 | bo->tbo.sync_obj = radeon_fence_ref(fence); | ||
340 | bo->tbo.sync_obj_arg = NULL; | ||
341 | } | ||
342 | if (old_fence) { | ||
343 | radeon_fence_unref(&old_fence); | ||
344 | } | ||
345 | } | 336 | } |
346 | return 0; | 337 | return 0; |
347 | } | 338 | } |
348 | 339 | ||
349 | void radeon_bo_list_unvalidate(struct list_head *head, void *fence) | 340 | void radeon_bo_list_fence(struct list_head *head, void *fence) |
350 | { | 341 | { |
351 | struct radeon_bo_list *lobj; | 342 | struct radeon_bo_list *lobj; |
352 | struct radeon_fence *old_fence; | 343 | struct radeon_bo *bo; |
353 | 344 | struct radeon_fence *old_fence = NULL; | |
354 | if (fence) | 345 | |
355 | list_for_each_entry(lobj, head, list) { | 346 | list_for_each_entry(lobj, head, list) { |
356 | old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj); | 347 | bo = lobj->bo; |
357 | if (old_fence == fence) { | 348 | spin_lock(&bo->tbo.lock); |
358 | lobj->bo->tbo.sync_obj = NULL; | 349 | old_fence = (struct radeon_fence *)bo->tbo.sync_obj; |
359 | radeon_fence_unref(&old_fence); | 350 | bo->tbo.sync_obj = radeon_fence_ref(fence); |
360 | } | 351 | bo->tbo.sync_obj_arg = NULL; |
352 | spin_unlock(&bo->tbo.lock); | ||
353 | if (old_fence) { | ||
354 | radeon_fence_unref(&old_fence); | ||
361 | } | 355 | } |
362 | radeon_bo_list_unreserve(head); | 356 | } |
363 | } | 357 | } |
364 | 358 | ||
365 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 359 | int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index a02f18011ad1..7ab43de1e244 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -156,8 +156,8 @@ extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, | |||
156 | struct list_head *head); | 156 | struct list_head *head); |
157 | extern int radeon_bo_list_reserve(struct list_head *head); | 157 | extern int radeon_bo_list_reserve(struct list_head *head); |
158 | extern void radeon_bo_list_unreserve(struct list_head *head); | 158 | extern void radeon_bo_list_unreserve(struct list_head *head); |
159 | extern int radeon_bo_list_validate(struct list_head *head, void *fence); | 159 | extern int radeon_bo_list_validate(struct list_head *head); |
160 | extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence); | 160 | extern void radeon_bo_list_fence(struct list_head *head, void *fence); |
161 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, | 161 | extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, |
162 | struct vm_area_struct *vma); | 162 | struct vm_area_struct *vma); |
163 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | 163 | extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 4d12b2d17b4d..6579eb4c1f28 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -41,68 +41,55 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) | |||
41 | { | 41 | { |
42 | struct radeon_fence *fence; | 42 | struct radeon_fence *fence; |
43 | struct radeon_ib *nib; | 43 | struct radeon_ib *nib; |
44 | unsigned long i; | 44 | int r = 0, i, c; |
45 | int r = 0; | ||
46 | 45 | ||
47 | *ib = NULL; | 46 | *ib = NULL; |
48 | r = radeon_fence_create(rdev, &fence); | 47 | r = radeon_fence_create(rdev, &fence); |
49 | if (r) { | 48 | if (r) { |
50 | DRM_ERROR("failed to create fence for new IB\n"); | 49 | dev_err(rdev->dev, "failed to create fence for new IB\n"); |
51 | return r; | 50 | return r; |
52 | } | 51 | } |
53 | mutex_lock(&rdev->ib_pool.mutex); | 52 | mutex_lock(&rdev->ib_pool.mutex); |
54 | i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 53 | for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) { |
55 | if (i < RADEON_IB_POOL_SIZE) { | 54 | i &= (RADEON_IB_POOL_SIZE - 1); |
56 | set_bit(i, rdev->ib_pool.alloc_bm); | 55 | if (rdev->ib_pool.ibs[i].free) { |
57 | rdev->ib_pool.ibs[i].length_dw = 0; | 56 | nib = &rdev->ib_pool.ibs[i]; |
58 | *ib = &rdev->ib_pool.ibs[i]; | 57 | break; |
59 | mutex_unlock(&rdev->ib_pool.mutex); | 58 | } |
60 | goto out; | ||
61 | } | 59 | } |
62 | if (list_empty(&rdev->ib_pool.scheduled_ibs)) { | 60 | if (nib == NULL) { |
63 | /* we go do nothings here */ | 61 | /* This should never happen, it means we allocated all |
62 | * IB and haven't scheduled one yet, return EBUSY to | ||
63 | * userspace hoping that on ioctl recall we get better | ||
64 | * luck | ||
65 | */ | ||
66 | dev_err(rdev->dev, "no free indirect buffer !\n"); | ||
64 | mutex_unlock(&rdev->ib_pool.mutex); | 67 | mutex_unlock(&rdev->ib_pool.mutex); |
65 | DRM_ERROR("all IB allocated none scheduled.\n"); | 68 | radeon_fence_unref(&fence); |
66 | r = -EINVAL; | 69 | return -EBUSY; |
67 | goto out; | ||
68 | } | 70 | } |
69 | /* get the first ib on the scheduled list */ | 71 | rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1); |
70 | nib = list_entry(rdev->ib_pool.scheduled_ibs.next, | 72 | nib->free = false; |
71 | struct radeon_ib, list); | 73 | if (nib->fence) { |
72 | if (nib->fence == NULL) { | ||
73 | /* we go do nothings here */ | ||
74 | mutex_unlock(&rdev->ib_pool.mutex); | 74 | mutex_unlock(&rdev->ib_pool.mutex); |
75 | DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx); | 75 | r = radeon_fence_wait(nib->fence, false); |
76 | r = -EINVAL; | 76 | if (r) { |
77 | goto out; | 77 | dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", |
78 | } | 78 | nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); |
79 | mutex_unlock(&rdev->ib_pool.mutex); | 79 | mutex_lock(&rdev->ib_pool.mutex); |
80 | 80 | nib->free = true; | |
81 | r = radeon_fence_wait(nib->fence, false); | 81 | mutex_unlock(&rdev->ib_pool.mutex); |
82 | if (r) { | 82 | radeon_fence_unref(&fence); |
83 | DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx, | 83 | return r; |
84 | (unsigned long)nib->gpu_addr, nib->length_dw); | 84 | } |
85 | DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n"); | 85 | mutex_lock(&rdev->ib_pool.mutex); |
86 | goto out; | ||
87 | } | 86 | } |
88 | radeon_fence_unref(&nib->fence); | 87 | radeon_fence_unref(&nib->fence); |
89 | 88 | nib->fence = fence; | |
90 | nib->length_dw = 0; | 89 | nib->length_dw = 0; |
91 | |||
92 | /* scheduled list is accessed here */ | ||
93 | mutex_lock(&rdev->ib_pool.mutex); | ||
94 | list_del(&nib->list); | ||
95 | INIT_LIST_HEAD(&nib->list); | ||
96 | mutex_unlock(&rdev->ib_pool.mutex); | 90 | mutex_unlock(&rdev->ib_pool.mutex); |
97 | |||
98 | *ib = nib; | 91 | *ib = nib; |
99 | out: | 92 | return 0; |
100 | if (r) { | ||
101 | radeon_fence_unref(&fence); | ||
102 | } else { | ||
103 | (*ib)->fence = fence; | ||
104 | } | ||
105 | return r; | ||
106 | } | 93 | } |
107 | 94 | ||
108 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | 95 | void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) |
@@ -113,19 +100,10 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
113 | if (tmp == NULL) { | 100 | if (tmp == NULL) { |
114 | return; | 101 | return; |
115 | } | 102 | } |
116 | mutex_lock(&rdev->ib_pool.mutex); | 103 | if (!tmp->fence->emited) |
117 | if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) { | ||
118 | /* IB is scheduled & not signaled don't do anythings */ | ||
119 | mutex_unlock(&rdev->ib_pool.mutex); | ||
120 | return; | ||
121 | } | ||
122 | list_del(&tmp->list); | ||
123 | INIT_LIST_HEAD(&tmp->list); | ||
124 | if (tmp->fence) | ||
125 | radeon_fence_unref(&tmp->fence); | 104 | radeon_fence_unref(&tmp->fence); |
126 | 105 | mutex_lock(&rdev->ib_pool.mutex); | |
127 | tmp->length_dw = 0; | 106 | tmp->free = true; |
128 | clear_bit(tmp->idx, rdev->ib_pool.alloc_bm); | ||
129 | mutex_unlock(&rdev->ib_pool.mutex); | 107 | mutex_unlock(&rdev->ib_pool.mutex); |
130 | } | 108 | } |
131 | 109 | ||
@@ -135,7 +113,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
135 | 113 | ||
136 | if (!ib->length_dw || !rdev->cp.ready) { | 114 | if (!ib->length_dw || !rdev->cp.ready) { |
137 | /* TODO: Nothings in the ib we should report. */ | 115 | /* TODO: Nothings in the ib we should report. */ |
138 | DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx); | 116 | DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); |
139 | return -EINVAL; | 117 | return -EINVAL; |
140 | } | 118 | } |
141 | 119 | ||
@@ -148,7 +126,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
148 | radeon_ring_ib_execute(rdev, ib); | 126 | radeon_ring_ib_execute(rdev, ib); |
149 | radeon_fence_emit(rdev, ib->fence); | 127 | radeon_fence_emit(rdev, ib->fence); |
150 | mutex_lock(&rdev->ib_pool.mutex); | 128 | mutex_lock(&rdev->ib_pool.mutex); |
151 | list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); | 129 | /* once scheduled IB is considered free and protected by the fence */ |
130 | ib->free = true; | ||
152 | mutex_unlock(&rdev->ib_pool.mutex); | 131 | mutex_unlock(&rdev->ib_pool.mutex); |
153 | radeon_ring_unlock_commit(rdev); | 132 | radeon_ring_unlock_commit(rdev); |
154 | return 0; | 133 | return 0; |
@@ -164,7 +143,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
164 | if (rdev->ib_pool.robj) | 143 | if (rdev->ib_pool.robj) |
165 | return 0; | 144 | return 0; |
166 | /* Allocate 1M object buffer */ | 145 | /* Allocate 1M object buffer */ |
167 | INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs); | ||
168 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, | 146 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, |
169 | true, RADEON_GEM_DOMAIN_GTT, | 147 | true, RADEON_GEM_DOMAIN_GTT, |
170 | &rdev->ib_pool.robj); | 148 | &rdev->ib_pool.robj); |
@@ -195,9 +173,9 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
195 | rdev->ib_pool.ibs[i].ptr = ptr + offset; | 173 | rdev->ib_pool.ibs[i].ptr = ptr + offset; |
196 | rdev->ib_pool.ibs[i].idx = i; | 174 | rdev->ib_pool.ibs[i].idx = i; |
197 | rdev->ib_pool.ibs[i].length_dw = 0; | 175 | rdev->ib_pool.ibs[i].length_dw = 0; |
198 | INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list); | 176 | rdev->ib_pool.ibs[i].free = true; |
199 | } | 177 | } |
200 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | 178 | rdev->ib_pool.head_id = 0; |
201 | rdev->ib_pool.ready = true; | 179 | rdev->ib_pool.ready = true; |
202 | DRM_INFO("radeon: ib pool ready.\n"); | 180 | DRM_INFO("radeon: ib pool ready.\n"); |
203 | if (radeon_debugfs_ib_init(rdev)) { | 181 | if (radeon_debugfs_ib_init(rdev)) { |
@@ -214,7 +192,6 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
214 | return; | 192 | return; |
215 | } | 193 | } |
216 | mutex_lock(&rdev->ib_pool.mutex); | 194 | mutex_lock(&rdev->ib_pool.mutex); |
217 | bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); | ||
218 | if (rdev->ib_pool.robj) { | 195 | if (rdev->ib_pool.robj) { |
219 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); | 196 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
220 | if (likely(r == 0)) { | 197 | if (likely(r == 0)) { |
@@ -363,7 +340,7 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data) | |||
363 | if (ib == NULL) { | 340 | if (ib == NULL) { |
364 | return 0; | 341 | return 0; |
365 | } | 342 | } |
366 | seq_printf(m, "IB %04lu\n", ib->idx); | 343 | seq_printf(m, "IB %04u\n", ib->idx); |
367 | seq_printf(m, "IB fence %p\n", ib->fence); | 344 | seq_printf(m, "IB fence %p\n", ib->fence); |
368 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); | 345 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); |
369 | for (i = 0; i < ib->length_dw; i++) { | 346 | for (i = 0; i < ib->length_dw; i++) { |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 9f5418983e2a..287fcebfb4e6 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -223,15 +223,31 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | int rs400_mc_wait_for_idle(struct radeon_device *rdev) | ||
227 | { | ||
228 | unsigned i; | ||
229 | uint32_t tmp; | ||
230 | |||
231 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
232 | /* read MC_STATUS */ | ||
233 | tmp = RREG32(0x0150); | ||
234 | if (tmp & (1 << 2)) { | ||
235 | return 0; | ||
236 | } | ||
237 | DRM_UDELAY(1); | ||
238 | } | ||
239 | return -1; | ||
240 | } | ||
241 | |||
226 | void rs400_gpu_init(struct radeon_device *rdev) | 242 | void rs400_gpu_init(struct radeon_device *rdev) |
227 | { | 243 | { |
228 | /* FIXME: HDP same place on rs400 ? */ | 244 | /* FIXME: HDP same place on rs400 ? */ |
229 | r100_hdp_reset(rdev); | 245 | r100_hdp_reset(rdev); |
230 | /* FIXME: is this correct ? */ | 246 | /* FIXME: is this correct ? */ |
231 | r420_pipes_init(rdev); | 247 | r420_pipes_init(rdev); |
232 | if (r300_mc_wait_for_idle(rdev)) { | 248 | if (rs400_mc_wait_for_idle(rdev)) { |
233 | printk(KERN_WARNING "Failed to wait MC idle while " | 249 | printk(KERN_WARNING "rs400: Failed to wait MC idle while " |
234 | "programming pipes. Bad things might happen.\n"); | 250 | "programming pipes. Bad things might happen. %08x\n", RREG32(0x150)); |
235 | } | 251 | } |
236 | } | 252 | } |
237 | 253 | ||
@@ -370,8 +386,8 @@ void rs400_mc_program(struct radeon_device *rdev) | |||
370 | r100_mc_stop(rdev, &save); | 386 | r100_mc_stop(rdev, &save); |
371 | 387 | ||
372 | /* Wait for mc idle */ | 388 | /* Wait for mc idle */ |
373 | if (r300_mc_wait_for_idle(rdev)) | 389 | if (rs400_mc_wait_for_idle(rdev)) |
374 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | 390 | dev_warn(rdev->dev, "rs400: Wait MC idle timeout before updating MC.\n"); |
375 | WREG32(R_000148_MC_FB_LOCATION, | 391 | WREG32(R_000148_MC_FB_LOCATION, |
376 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | | 392 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | |
377 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); | 393 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
@@ -448,7 +464,6 @@ int rs400_suspend(struct radeon_device *rdev) | |||
448 | 464 | ||
449 | void rs400_fini(struct radeon_device *rdev) | 465 | void rs400_fini(struct radeon_device *rdev) |
450 | { | 466 | { |
451 | rs400_suspend(rdev); | ||
452 | r100_cp_fini(rdev); | 467 | r100_cp_fini(rdev); |
453 | r100_wb_fini(rdev); | 468 | r100_wb_fini(rdev); |
454 | r100_ib_fini(rdev); | 469 | r100_ib_fini(rdev); |
@@ -527,7 +542,6 @@ int rs400_init(struct radeon_device *rdev) | |||
527 | if (r) { | 542 | if (r) { |
528 | /* Somethings want wront with the accel init stop accel */ | 543 | /* Somethings want wront with the accel init stop accel */ |
529 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 544 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
530 | rs400_suspend(rdev); | ||
531 | r100_cp_fini(rdev); | 545 | r100_cp_fini(rdev); |
532 | r100_wb_fini(rdev); | 546 | r100_wb_fini(rdev); |
533 | r100_ib_fini(rdev); | 547 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index d5255751e7b3..c3818562a13e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -610,7 +610,6 @@ int rs600_suspend(struct radeon_device *rdev) | |||
610 | 610 | ||
611 | void rs600_fini(struct radeon_device *rdev) | 611 | void rs600_fini(struct radeon_device *rdev) |
612 | { | 612 | { |
613 | rs600_suspend(rdev); | ||
614 | r100_cp_fini(rdev); | 613 | r100_cp_fini(rdev); |
615 | r100_wb_fini(rdev); | 614 | r100_wb_fini(rdev); |
616 | r100_ib_fini(rdev); | 615 | r100_ib_fini(rdev); |
@@ -689,7 +688,6 @@ int rs600_init(struct radeon_device *rdev) | |||
689 | if (r) { | 688 | if (r) { |
690 | /* Somethings want wront with the accel init stop accel */ | 689 | /* Somethings want wront with the accel init stop accel */ |
691 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 690 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
692 | rs600_suspend(rdev); | ||
693 | r100_cp_fini(rdev); | 691 | r100_cp_fini(rdev); |
694 | r100_wb_fini(rdev); | 692 | r100_wb_fini(rdev); |
695 | r100_ib_fini(rdev); | 693 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index cd31da913771..06e2771aee5a 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -676,7 +676,6 @@ int rs690_suspend(struct radeon_device *rdev) | |||
676 | 676 | ||
677 | void rs690_fini(struct radeon_device *rdev) | 677 | void rs690_fini(struct radeon_device *rdev) |
678 | { | 678 | { |
679 | rs690_suspend(rdev); | ||
680 | r100_cp_fini(rdev); | 679 | r100_cp_fini(rdev); |
681 | r100_wb_fini(rdev); | 680 | r100_wb_fini(rdev); |
682 | r100_ib_fini(rdev); | 681 | r100_ib_fini(rdev); |
@@ -756,7 +755,6 @@ int rs690_init(struct radeon_device *rdev) | |||
756 | if (r) { | 755 | if (r) { |
757 | /* Somethings want wront with the accel init stop accel */ | 756 | /* Somethings want wront with the accel init stop accel */ |
758 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 757 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
759 | rs690_suspend(rdev); | ||
760 | r100_cp_fini(rdev); | 758 | r100_cp_fini(rdev); |
761 | r100_wb_fini(rdev); | 759 | r100_wb_fini(rdev); |
762 | r100_ib_fini(rdev); | 760 | r100_ib_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 62756717b044..0e1e6b8632b8 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -537,7 +537,6 @@ void rv515_set_safe_registers(struct radeon_device *rdev) | |||
537 | 537 | ||
538 | void rv515_fini(struct radeon_device *rdev) | 538 | void rv515_fini(struct radeon_device *rdev) |
539 | { | 539 | { |
540 | rv515_suspend(rdev); | ||
541 | r100_cp_fini(rdev); | 540 | r100_cp_fini(rdev); |
542 | r100_wb_fini(rdev); | 541 | r100_wb_fini(rdev); |
543 | r100_ib_fini(rdev); | 542 | r100_ib_fini(rdev); |
@@ -615,13 +614,12 @@ int rv515_init(struct radeon_device *rdev) | |||
615 | if (r) { | 614 | if (r) { |
616 | /* Somethings want wront with the accel init stop accel */ | 615 | /* Somethings want wront with the accel init stop accel */ |
617 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | 616 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
618 | rv515_suspend(rdev); | ||
619 | r100_cp_fini(rdev); | 617 | r100_cp_fini(rdev); |
620 | r100_wb_fini(rdev); | 618 | r100_wb_fini(rdev); |
621 | r100_ib_fini(rdev); | 619 | r100_ib_fini(rdev); |
620 | radeon_irq_kms_fini(rdev); | ||
622 | rv370_pcie_gart_fini(rdev); | 621 | rv370_pcie_gart_fini(rdev); |
623 | radeon_agp_fini(rdev); | 622 | radeon_agp_fini(rdev); |
624 | radeon_irq_kms_fini(rdev); | ||
625 | rdev->accel_working = false; | 623 | rdev->accel_working = false; |
626 | } | 624 | } |
627 | return 0; | 625 | return 0; |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index afd9e8213c29..03021674d097 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -549,9 +549,12 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
549 | 549 | ||
550 | gb_tiling_config |= BANK_SWAPS(1); | 550 | gb_tiling_config |= BANK_SWAPS(1); |
551 | 551 | ||
552 | backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, | 552 | if (rdev->family == CHIP_RV740) |
553 | rdev->config.rv770.max_backends, | 553 | backend_map = 0x28; |
554 | (0xff << rdev->config.rv770.max_backends) & 0xff); | 554 | else |
555 | backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, | ||
556 | rdev->config.rv770.max_backends, | ||
557 | (0xff << rdev->config.rv770.max_backends) & 0xff); | ||
555 | gb_tiling_config |= BACKEND_MAP(backend_map); | 558 | gb_tiling_config |= BACKEND_MAP(backend_map); |
556 | 559 | ||
557 | cc_gc_shader_pipe_config = | 560 | cc_gc_shader_pipe_config = |
@@ -887,6 +890,12 @@ static int rv770_startup(struct radeon_device *rdev) | |||
887 | return r; | 890 | return r; |
888 | } | 891 | } |
889 | rv770_gpu_init(rdev); | 892 | rv770_gpu_init(rdev); |
893 | r = r600_blit_init(rdev); | ||
894 | if (r) { | ||
895 | r600_blit_fini(rdev); | ||
896 | rdev->asic->copy = NULL; | ||
897 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
898 | } | ||
890 | /* pin copy shader into vram */ | 899 | /* pin copy shader into vram */ |
891 | if (rdev->r600_blit.shader_obj) { | 900 | if (rdev->r600_blit.shader_obj) { |
892 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 901 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); |
@@ -1055,19 +1064,15 @@ int rv770_init(struct radeon_device *rdev) | |||
1055 | r = r600_pcie_gart_init(rdev); | 1064 | r = r600_pcie_gart_init(rdev); |
1056 | if (r) | 1065 | if (r) |
1057 | return r; | 1066 | return r; |
1058 | r = r600_blit_init(rdev); | ||
1059 | if (r) { | ||
1060 | r600_blit_fini(rdev); | ||
1061 | rdev->asic->copy = NULL; | ||
1062 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
1063 | } | ||
1064 | 1067 | ||
1065 | rdev->accel_working = true; | 1068 | rdev->accel_working = true; |
1066 | r = rv770_startup(rdev); | 1069 | r = rv770_startup(rdev); |
1067 | if (r) { | 1070 | if (r) { |
1068 | rv770_suspend(rdev); | 1071 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
1072 | r600_cp_fini(rdev); | ||
1069 | r600_wb_fini(rdev); | 1073 | r600_wb_fini(rdev); |
1070 | radeon_ring_fini(rdev); | 1074 | r600_irq_fini(rdev); |
1075 | radeon_irq_kms_fini(rdev); | ||
1071 | rv770_pcie_gart_fini(rdev); | 1076 | rv770_pcie_gart_fini(rdev); |
1072 | rdev->accel_working = false; | 1077 | rdev->accel_working = false; |
1073 | } | 1078 | } |
@@ -1089,13 +1094,11 @@ int rv770_init(struct radeon_device *rdev) | |||
1089 | 1094 | ||
1090 | void rv770_fini(struct radeon_device *rdev) | 1095 | void rv770_fini(struct radeon_device *rdev) |
1091 | { | 1096 | { |
1092 | rv770_suspend(rdev); | ||
1093 | |||
1094 | r600_blit_fini(rdev); | 1097 | r600_blit_fini(rdev); |
1098 | r600_cp_fini(rdev); | ||
1099 | r600_wb_fini(rdev); | ||
1095 | r600_irq_fini(rdev); | 1100 | r600_irq_fini(rdev); |
1096 | radeon_irq_kms_fini(rdev); | 1101 | radeon_irq_kms_fini(rdev); |
1097 | radeon_ring_fini(rdev); | ||
1098 | r600_wb_fini(rdev); | ||
1099 | rv770_pcie_gart_fini(rdev); | 1102 | rv770_pcie_gart_fini(rdev); |
1100 | radeon_gem_fini(rdev); | 1103 | radeon_gem_fini(rdev); |
1101 | radeon_fence_driver_fini(rdev); | 1104 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 1a3e909b7bba..c7320ce4567d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -1020,6 +1020,12 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement, | |||
1020 | struct ttm_mem_reg *mem) | 1020 | struct ttm_mem_reg *mem) |
1021 | { | 1021 | { |
1022 | int i; | 1022 | int i; |
1023 | struct drm_mm_node *node = mem->mm_node; | ||
1024 | |||
1025 | if (node && placement->lpfn != 0 && | ||
1026 | (node->start < placement->fpfn || | ||
1027 | node->start + node->size > placement->lpfn)) | ||
1028 | return -1; | ||
1023 | 1029 | ||
1024 | for (i = 0; i < placement->num_placement; i++) { | 1030 | for (i = 0; i < placement->num_placement; i++) { |
1025 | if ((placement->placement[i] & mem->placement & | 1031 | if ((placement->placement[i] & mem->placement & |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index e2123af7775a..3d47a2c12322 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -196,14 +196,15 @@ EXPORT_SYMBOL(ttm_tt_populate); | |||
196 | 196 | ||
197 | #ifdef CONFIG_X86 | 197 | #ifdef CONFIG_X86 |
198 | static inline int ttm_tt_set_page_caching(struct page *p, | 198 | static inline int ttm_tt_set_page_caching(struct page *p, |
199 | enum ttm_caching_state c_state) | 199 | enum ttm_caching_state c_old, |
200 | enum ttm_caching_state c_new) | ||
200 | { | 201 | { |
201 | int ret = 0; | 202 | int ret = 0; |
202 | 203 | ||
203 | if (PageHighMem(p)) | 204 | if (PageHighMem(p)) |
204 | return 0; | 205 | return 0; |
205 | 206 | ||
206 | if (get_page_memtype(p) != -1) { | 207 | if (c_old != tt_cached) { |
207 | /* p isn't in the default caching state, set it to | 208 | /* p isn't in the default caching state, set it to |
208 | * writeback first to free its current memtype. */ | 209 | * writeback first to free its current memtype. */ |
209 | 210 | ||
@@ -212,16 +213,17 @@ static inline int ttm_tt_set_page_caching(struct page *p, | |||
212 | return ret; | 213 | return ret; |
213 | } | 214 | } |
214 | 215 | ||
215 | if (c_state == tt_wc) | 216 | if (c_new == tt_wc) |
216 | ret = set_memory_wc((unsigned long) page_address(p), 1); | 217 | ret = set_memory_wc((unsigned long) page_address(p), 1); |
217 | else if (c_state == tt_uncached) | 218 | else if (c_new == tt_uncached) |
218 | ret = set_pages_uc(p, 1); | 219 | ret = set_pages_uc(p, 1); |
219 | 220 | ||
220 | return ret; | 221 | return ret; |
221 | } | 222 | } |
222 | #else /* CONFIG_X86 */ | 223 | #else /* CONFIG_X86 */ |
223 | static inline int ttm_tt_set_page_caching(struct page *p, | 224 | static inline int ttm_tt_set_page_caching(struct page *p, |
224 | enum ttm_caching_state c_state) | 225 | enum ttm_caching_state c_old, |
226 | enum ttm_caching_state c_new) | ||
225 | { | 227 | { |
226 | return 0; | 228 | return 0; |
227 | } | 229 | } |
@@ -254,7 +256,9 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm, | |||
254 | for (i = 0; i < ttm->num_pages; ++i) { | 256 | for (i = 0; i < ttm->num_pages; ++i) { |
255 | cur_page = ttm->pages[i]; | 257 | cur_page = ttm->pages[i]; |
256 | if (likely(cur_page != NULL)) { | 258 | if (likely(cur_page != NULL)) { |
257 | ret = ttm_tt_set_page_caching(cur_page, c_state); | 259 | ret = ttm_tt_set_page_caching(cur_page, |
260 | ttm->caching_state, | ||
261 | c_state); | ||
258 | if (unlikely(ret != 0)) | 262 | if (unlikely(ret != 0)) |
259 | goto out_err; | 263 | goto out_err; |
260 | } | 264 | } |
@@ -268,7 +272,7 @@ out_err: | |||
268 | for (j = 0; j < i; ++j) { | 272 | for (j = 0; j < i; ++j) { |
269 | cur_page = ttm->pages[j]; | 273 | cur_page = ttm->pages[j]; |
270 | if (likely(cur_page != NULL)) { | 274 | if (likely(cur_page != NULL)) { |
271 | (void)ttm_tt_set_page_caching(cur_page, | 275 | (void)ttm_tt_set_page_caching(cur_page, c_state, |
272 | ttm->caching_state); | 276 | ttm->caching_state); |
273 | } | 277 | } |
274 | } | 278 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index a6e8f687fa64..0c9c0811f42d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -348,22 +348,19 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
348 | */ | 348 | */ |
349 | 349 | ||
350 | DRM_INFO("It appears like vesafb is loaded. " | 350 | DRM_INFO("It appears like vesafb is loaded. " |
351 | "Ignore above error if any. Entering stealth mode.\n"); | 351 | "Ignore above error if any.\n"); |
352 | ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); | 352 | ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); |
353 | if (unlikely(ret != 0)) { | 353 | if (unlikely(ret != 0)) { |
354 | DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); | 354 | DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); |
355 | goto out_no_device; | 355 | goto out_no_device; |
356 | } | 356 | } |
357 | vmw_kms_init(dev_priv); | ||
358 | vmw_overlay_init(dev_priv); | ||
359 | } else { | ||
360 | ret = vmw_request_device(dev_priv); | ||
361 | if (unlikely(ret != 0)) | ||
362 | goto out_no_device; | ||
363 | vmw_kms_init(dev_priv); | ||
364 | vmw_overlay_init(dev_priv); | ||
365 | vmw_fb_init(dev_priv); | ||
366 | } | 357 | } |
358 | ret = vmw_request_device(dev_priv); | ||
359 | if (unlikely(ret != 0)) | ||
360 | goto out_no_device; | ||
361 | vmw_kms_init(dev_priv); | ||
362 | vmw_overlay_init(dev_priv); | ||
363 | vmw_fb_init(dev_priv); | ||
367 | 364 | ||
368 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; | 365 | dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; |
369 | register_pm_notifier(&dev_priv->pm_nb); | 366 | register_pm_notifier(&dev_priv->pm_nb); |
@@ -406,17 +403,15 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
406 | 403 | ||
407 | unregister_pm_notifier(&dev_priv->pm_nb); | 404 | unregister_pm_notifier(&dev_priv->pm_nb); |
408 | 405 | ||
409 | if (!dev_priv->stealth) { | 406 | vmw_fb_close(dev_priv); |
410 | vmw_fb_close(dev_priv); | 407 | vmw_kms_close(dev_priv); |
411 | vmw_kms_close(dev_priv); | 408 | vmw_overlay_close(dev_priv); |
412 | vmw_overlay_close(dev_priv); | 409 | vmw_release_device(dev_priv); |
413 | vmw_release_device(dev_priv); | 410 | if (dev_priv->stealth) |
414 | pci_release_regions(dev->pdev); | ||
415 | } else { | ||
416 | vmw_kms_close(dev_priv); | ||
417 | vmw_overlay_close(dev_priv); | ||
418 | pci_release_region(dev->pdev, 2); | 411 | pci_release_region(dev->pdev, 2); |
419 | } | 412 | else |
413 | pci_release_regions(dev->pdev); | ||
414 | |||
420 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) | 415 | if (dev_priv->capabilities & SVGA_CAP_IRQMASK) |
421 | drm_irq_uninstall(dev_priv->dev); | 416 | drm_irq_uninstall(dev_priv->dev); |
422 | if (dev->devname == vmw_devname) | 417 | if (dev->devname == vmw_devname) |
@@ -585,11 +580,6 @@ static int vmw_master_set(struct drm_device *dev, | |||
585 | int ret = 0; | 580 | int ret = 0; |
586 | 581 | ||
587 | DRM_INFO("Master set.\n"); | 582 | DRM_INFO("Master set.\n"); |
588 | if (dev_priv->stealth) { | ||
589 | ret = vmw_request_device(dev_priv); | ||
590 | if (unlikely(ret != 0)) | ||
591 | return ret; | ||
592 | } | ||
593 | 583 | ||
594 | if (active) { | 584 | if (active) { |
595 | BUG_ON(active != &dev_priv->fbdev_master); | 585 | BUG_ON(active != &dev_priv->fbdev_master); |
@@ -649,18 +639,11 @@ static void vmw_master_drop(struct drm_device *dev, | |||
649 | 639 | ||
650 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); | 640 | ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); |
651 | 641 | ||
652 | if (dev_priv->stealth) { | ||
653 | ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); | ||
654 | if (unlikely(ret != 0)) | ||
655 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | ||
656 | vmw_release_device(dev_priv); | ||
657 | } | ||
658 | dev_priv->active_master = &dev_priv->fbdev_master; | 642 | dev_priv->active_master = &dev_priv->fbdev_master; |
659 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); | 643 | ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); |
660 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); | 644 | ttm_vt_unlock(&dev_priv->fbdev_master.lock); |
661 | 645 | ||
662 | if (!dev_priv->stealth) | 646 | vmw_fb_on(dev_priv); |
663 | vmw_fb_on(dev_priv); | ||
664 | } | 647 | } |
665 | 648 | ||
666 | 649 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 135be9688c90..356dc935ec13 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -39,10 +39,10 @@ | |||
39 | #include "ttm/ttm_execbuf_util.h" | 39 | #include "ttm/ttm_execbuf_util.h" |
40 | #include "ttm/ttm_module.h" | 40 | #include "ttm/ttm_module.h" |
41 | 41 | ||
42 | #define VMWGFX_DRIVER_DATE "20090724" | 42 | #define VMWGFX_DRIVER_DATE "20100209" |
43 | #define VMWGFX_DRIVER_MAJOR 0 | 43 | #define VMWGFX_DRIVER_MAJOR 1 |
44 | #define VMWGFX_DRIVER_MINOR 1 | 44 | #define VMWGFX_DRIVER_MINOR 0 |
45 | #define VMWGFX_DRIVER_PATCHLEVEL 2 | 45 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
46 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 | 46 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 |
47 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 47 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
48 | #define VMWGFX_MAX_RELOCATIONS 2048 | 48 | #define VMWGFX_MAX_RELOCATIONS 2048 |
@@ -113,6 +113,7 @@ struct vmw_fifo_state { | |||
113 | unsigned long static_buffer_size; | 113 | unsigned long static_buffer_size; |
114 | bool using_bounce_buffer; | 114 | bool using_bounce_buffer; |
115 | uint32_t capabilities; | 115 | uint32_t capabilities; |
116 | struct mutex fifo_mutex; | ||
116 | struct rw_semaphore rwsem; | 117 | struct rw_semaphore rwsem; |
117 | }; | 118 | }; |
118 | 119 | ||
@@ -213,7 +214,7 @@ struct vmw_private { | |||
213 | * Fencing and IRQs. | 214 | * Fencing and IRQs. |
214 | */ | 215 | */ |
215 | 216 | ||
216 | uint32_t fence_seq; | 217 | atomic_t fence_seq; |
217 | wait_queue_head_t fence_queue; | 218 | wait_queue_head_t fence_queue; |
218 | wait_queue_head_t fifo_queue; | 219 | wait_queue_head_t fifo_queue; |
219 | atomic_t fence_queue_waiters; | 220 | atomic_t fence_queue_waiters; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index d69caf92ffe7..0897359b3e4e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -182,25 +182,19 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, | |||
182 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); | 182 | return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int vmw_cmd_dma(struct vmw_private *dev_priv, | 185 | static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, |
186 | struct vmw_sw_context *sw_context, | 186 | struct vmw_sw_context *sw_context, |
187 | SVGA3dCmdHeader *header) | 187 | SVGAGuestPtr *ptr, |
188 | struct vmw_dma_buffer **vmw_bo_p) | ||
188 | { | 189 | { |
189 | uint32_t handle; | ||
190 | struct vmw_dma_buffer *vmw_bo = NULL; | 190 | struct vmw_dma_buffer *vmw_bo = NULL; |
191 | struct ttm_buffer_object *bo; | 191 | struct ttm_buffer_object *bo; |
192 | struct vmw_surface *srf = NULL; | 192 | uint32_t handle = ptr->gmrId; |
193 | struct vmw_dma_cmd { | ||
194 | SVGA3dCmdHeader header; | ||
195 | SVGA3dCmdSurfaceDMA dma; | ||
196 | } *cmd; | ||
197 | struct vmw_relocation *reloc; | 193 | struct vmw_relocation *reloc; |
198 | int ret; | ||
199 | uint32_t cur_validate_node; | 194 | uint32_t cur_validate_node; |
200 | struct ttm_validate_buffer *val_buf; | 195 | struct ttm_validate_buffer *val_buf; |
196 | int ret; | ||
201 | 197 | ||
202 | cmd = container_of(header, struct vmw_dma_cmd, header); | ||
203 | handle = cmd->dma.guest.ptr.gmrId; | ||
204 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 198 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); |
205 | if (unlikely(ret != 0)) { | 199 | if (unlikely(ret != 0)) { |
206 | DRM_ERROR("Could not find or use GMR region.\n"); | 200 | DRM_ERROR("Could not find or use GMR region.\n"); |
@@ -209,14 +203,14 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
209 | bo = &vmw_bo->base; | 203 | bo = &vmw_bo->base; |
210 | 204 | ||
211 | if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { | 205 | if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { |
212 | DRM_ERROR("Max number of DMA commands per submission" | 206 | DRM_ERROR("Max number relocations per submission" |
213 | " exceeded\n"); | 207 | " exceeded\n"); |
214 | ret = -EINVAL; | 208 | ret = -EINVAL; |
215 | goto out_no_reloc; | 209 | goto out_no_reloc; |
216 | } | 210 | } |
217 | 211 | ||
218 | reloc = &sw_context->relocs[sw_context->cur_reloc++]; | 212 | reloc = &sw_context->relocs[sw_context->cur_reloc++]; |
219 | reloc->location = &cmd->dma.guest.ptr; | 213 | reloc->location = ptr; |
220 | 214 | ||
221 | cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf); | 215 | cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf); |
222 | if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) { | 216 | if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) { |
@@ -234,7 +228,89 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
234 | list_add_tail(&val_buf->head, &sw_context->validate_nodes); | 228 | list_add_tail(&val_buf->head, &sw_context->validate_nodes); |
235 | ++sw_context->cur_val_buf; | 229 | ++sw_context->cur_val_buf; |
236 | } | 230 | } |
231 | *vmw_bo_p = vmw_bo; | ||
232 | return 0; | ||
233 | |||
234 | out_no_reloc: | ||
235 | vmw_dmabuf_unreference(&vmw_bo); | ||
236 | vmw_bo_p = NULL; | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | static int vmw_cmd_end_query(struct vmw_private *dev_priv, | ||
241 | struct vmw_sw_context *sw_context, | ||
242 | SVGA3dCmdHeader *header) | ||
243 | { | ||
244 | struct vmw_dma_buffer *vmw_bo; | ||
245 | struct vmw_query_cmd { | ||
246 | SVGA3dCmdHeader header; | ||
247 | SVGA3dCmdEndQuery q; | ||
248 | } *cmd; | ||
249 | int ret; | ||
250 | |||
251 | cmd = container_of(header, struct vmw_query_cmd, header); | ||
252 | ret = vmw_cmd_cid_check(dev_priv, sw_context, header); | ||
253 | if (unlikely(ret != 0)) | ||
254 | return ret; | ||
255 | |||
256 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, | ||
257 | &cmd->q.guestResult, | ||
258 | &vmw_bo); | ||
259 | if (unlikely(ret != 0)) | ||
260 | return ret; | ||
261 | |||
262 | vmw_dmabuf_unreference(&vmw_bo); | ||
263 | return 0; | ||
264 | } | ||
237 | 265 | ||
266 | static int vmw_cmd_wait_query(struct vmw_private *dev_priv, | ||
267 | struct vmw_sw_context *sw_context, | ||
268 | SVGA3dCmdHeader *header) | ||
269 | { | ||
270 | struct vmw_dma_buffer *vmw_bo; | ||
271 | struct vmw_query_cmd { | ||
272 | SVGA3dCmdHeader header; | ||
273 | SVGA3dCmdWaitForQuery q; | ||
274 | } *cmd; | ||
275 | int ret; | ||
276 | |||
277 | cmd = container_of(header, struct vmw_query_cmd, header); | ||
278 | ret = vmw_cmd_cid_check(dev_priv, sw_context, header); | ||
279 | if (unlikely(ret != 0)) | ||
280 | return ret; | ||
281 | |||
282 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, | ||
283 | &cmd->q.guestResult, | ||
284 | &vmw_bo); | ||
285 | if (unlikely(ret != 0)) | ||
286 | return ret; | ||
287 | |||
288 | vmw_dmabuf_unreference(&vmw_bo); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | |||
293 | static int vmw_cmd_dma(struct vmw_private *dev_priv, | ||
294 | struct vmw_sw_context *sw_context, | ||
295 | SVGA3dCmdHeader *header) | ||
296 | { | ||
297 | struct vmw_dma_buffer *vmw_bo = NULL; | ||
298 | struct ttm_buffer_object *bo; | ||
299 | struct vmw_surface *srf = NULL; | ||
300 | struct vmw_dma_cmd { | ||
301 | SVGA3dCmdHeader header; | ||
302 | SVGA3dCmdSurfaceDMA dma; | ||
303 | } *cmd; | ||
304 | int ret; | ||
305 | |||
306 | cmd = container_of(header, struct vmw_dma_cmd, header); | ||
307 | ret = vmw_translate_guest_ptr(dev_priv, sw_context, | ||
308 | &cmd->dma.guest.ptr, | ||
309 | &vmw_bo); | ||
310 | if (unlikely(ret != 0)) | ||
311 | return ret; | ||
312 | |||
313 | bo = &vmw_bo->base; | ||
238 | ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, | 314 | ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, |
239 | cmd->dma.host.sid, &srf); | 315 | cmd->dma.host.sid, &srf); |
240 | if (ret) { | 316 | if (ret) { |
@@ -379,8 +455,8 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = { | |||
379 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), | 455 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), |
380 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), | 456 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), |
381 | VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), | 457 | VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), |
382 | VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), | 458 | VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query), |
383 | VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_cid_check), | 459 | VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query), |
384 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok), | 460 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok), |
385 | VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, | 461 | VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, |
386 | &vmw_cmd_blt_surf_screen_check) | 462 | &vmw_cmd_blt_surf_screen_check) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 4f4f6432be8b..a93367041cdc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -559,6 +559,9 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
559 | info->pixmap.scan_align = 1; | 559 | info->pixmap.scan_align = 1; |
560 | #endif | 560 | #endif |
561 | 561 | ||
562 | info->aperture_base = vmw_priv->vram_start; | ||
563 | info->aperture_size = vmw_priv->vram_size; | ||
564 | |||
562 | /* | 565 | /* |
563 | * Dirty & Deferred IO | 566 | * Dirty & Deferred IO |
564 | */ | 567 | */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 4157547cc6e4..39d43a01d846 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -74,6 +74,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
74 | fifo->reserved_size = 0; | 74 | fifo->reserved_size = 0; |
75 | fifo->using_bounce_buffer = false; | 75 | fifo->using_bounce_buffer = false; |
76 | 76 | ||
77 | mutex_init(&fifo->fifo_mutex); | ||
77 | init_rwsem(&fifo->rwsem); | 78 | init_rwsem(&fifo->rwsem); |
78 | 79 | ||
79 | /* | 80 | /* |
@@ -117,7 +118,7 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
117 | (unsigned int) min, | 118 | (unsigned int) min, |
118 | (unsigned int) fifo->capabilities); | 119 | (unsigned int) fifo->capabilities); |
119 | 120 | ||
120 | dev_priv->fence_seq = dev_priv->last_read_sequence; | 121 | atomic_set(&dev_priv->fence_seq, dev_priv->last_read_sequence); |
121 | iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); | 122 | iowrite32(dev_priv->last_read_sequence, fifo_mem + SVGA_FIFO_FENCE); |
122 | 123 | ||
123 | return vmw_fifo_send_fence(dev_priv, &dummy); | 124 | return vmw_fifo_send_fence(dev_priv, &dummy); |
@@ -283,7 +284,7 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) | |||
283 | uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; | 284 | uint32_t reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; |
284 | int ret; | 285 | int ret; |
285 | 286 | ||
286 | down_write(&fifo_state->rwsem); | 287 | mutex_lock(&fifo_state->fifo_mutex); |
287 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); | 288 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); |
288 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); | 289 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); |
289 | next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); | 290 | next_cmd = ioread32(fifo_mem + SVGA_FIFO_NEXT_CMD); |
@@ -351,7 +352,7 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes) | |||
351 | } | 352 | } |
352 | out_err: | 353 | out_err: |
353 | fifo_state->reserved_size = 0; | 354 | fifo_state->reserved_size = 0; |
354 | up_write(&fifo_state->rwsem); | 355 | mutex_unlock(&fifo_state->fifo_mutex); |
355 | return NULL; | 356 | return NULL; |
356 | } | 357 | } |
357 | 358 | ||
@@ -426,6 +427,7 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) | |||
426 | 427 | ||
427 | } | 428 | } |
428 | 429 | ||
430 | down_write(&fifo_state->rwsem); | ||
429 | if (fifo_state->using_bounce_buffer || reserveable) { | 431 | if (fifo_state->using_bounce_buffer || reserveable) { |
430 | next_cmd += bytes; | 432 | next_cmd += bytes; |
431 | if (next_cmd >= max) | 433 | if (next_cmd >= max) |
@@ -437,8 +439,9 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) | |||
437 | if (reserveable) | 439 | if (reserveable) |
438 | iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); | 440 | iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); |
439 | mb(); | 441 | mb(); |
440 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); | ||
441 | up_write(&fifo_state->rwsem); | 442 | up_write(&fifo_state->rwsem); |
443 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); | ||
444 | mutex_unlock(&fifo_state->fifo_mutex); | ||
442 | } | 445 | } |
443 | 446 | ||
444 | int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | 447 | int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) |
@@ -451,9 +454,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | |||
451 | 454 | ||
452 | fm = vmw_fifo_reserve(dev_priv, bytes); | 455 | fm = vmw_fifo_reserve(dev_priv, bytes); |
453 | if (unlikely(fm == NULL)) { | 456 | if (unlikely(fm == NULL)) { |
454 | down_write(&fifo_state->rwsem); | 457 | *sequence = atomic_read(&dev_priv->fence_seq); |
455 | *sequence = dev_priv->fence_seq; | ||
456 | up_write(&fifo_state->rwsem); | ||
457 | ret = -ENOMEM; | 458 | ret = -ENOMEM; |
458 | (void)vmw_fallback_wait(dev_priv, false, true, *sequence, | 459 | (void)vmw_fallback_wait(dev_priv, false, true, *sequence, |
459 | false, 3*HZ); | 460 | false, 3*HZ); |
@@ -461,7 +462,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *sequence) | |||
461 | } | 462 | } |
462 | 463 | ||
463 | do { | 464 | do { |
464 | *sequence = dev_priv->fence_seq++; | 465 | *sequence = atomic_add_return(1, &dev_priv->fence_seq); |
465 | } while (*sequence == 0); | 466 | } while (*sequence == 0); |
466 | 467 | ||
467 | if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) { | 468 | if (!(fifo_state->capabilities & SVGA_FIFO_CAP_FENCE)) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 778851f9f1d6..1c7a316454d8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -48,6 +48,12 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
48 | case DRM_VMW_PARAM_FIFO_OFFSET: | 48 | case DRM_VMW_PARAM_FIFO_OFFSET: |
49 | param->value = dev_priv->mmio_start; | 49 | param->value = dev_priv->mmio_start; |
50 | break; | 50 | break; |
51 | case DRM_VMW_PARAM_HW_CAPS: | ||
52 | param->value = dev_priv->capabilities; | ||
53 | break; | ||
54 | case DRM_VMW_PARAM_FIFO_CAPS: | ||
55 | param->value = dev_priv->fifo.capabilities; | ||
56 | break; | ||
51 | default: | 57 | default: |
52 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", | 58 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", |
53 | param->param); | 59 | param->param); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index d40086fc8647..4d7cb5393860 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | |||
@@ -85,19 +85,12 @@ bool vmw_fence_signaled(struct vmw_private *dev_priv, | |||
85 | return true; | 85 | return true; |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * Below is to signal stale fences that have wrapped. | ||
89 | * First, block fence submission. | ||
90 | */ | ||
91 | |||
92 | down_read(&fifo_state->rwsem); | ||
93 | |||
94 | /** | ||
95 | * Then check if the sequence is higher than what we've actually | 88 | * Then check if the sequence is higher than what we've actually |
96 | * emitted. Then the fence is stale and signaled. | 89 | * emitted. Then the fence is stale and signaled. |
97 | */ | 90 | */ |
98 | 91 | ||
99 | ret = ((dev_priv->fence_seq - sequence) > VMW_FENCE_WRAP); | 92 | ret = ((atomic_read(&dev_priv->fence_seq) - sequence) |
100 | up_read(&fifo_state->rwsem); | 93 | > VMW_FENCE_WRAP); |
101 | 94 | ||
102 | return ret; | 95 | return ret; |
103 | } | 96 | } |
@@ -127,7 +120,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, | |||
127 | 120 | ||
128 | if (fifo_idle) | 121 | if (fifo_idle) |
129 | down_read(&fifo_state->rwsem); | 122 | down_read(&fifo_state->rwsem); |
130 | signal_seq = dev_priv->fence_seq; | 123 | signal_seq = atomic_read(&dev_priv->fence_seq); |
131 | ret = 0; | 124 | ret = 0; |
132 | 125 | ||
133 | for (;;) { | 126 | for (;;) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index eeba6d1d06e4..31f9afed0a63 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -769,10 +769,10 @@ int vmw_kms_init(struct vmw_private *dev_priv) | |||
769 | 769 | ||
770 | drm_mode_config_init(dev); | 770 | drm_mode_config_init(dev); |
771 | dev->mode_config.funcs = &vmw_kms_funcs; | 771 | dev->mode_config.funcs = &vmw_kms_funcs; |
772 | dev->mode_config.min_width = 640; | 772 | dev->mode_config.min_width = 1; |
773 | dev->mode_config.min_height = 480; | 773 | dev->mode_config.min_height = 1; |
774 | dev->mode_config.max_width = 2048; | 774 | dev->mode_config.max_width = dev_priv->fb_max_width; |
775 | dev->mode_config.max_height = 2048; | 775 | dev->mode_config.max_height = dev_priv->fb_max_height; |
776 | 776 | ||
777 | ret = vmw_kms_init_legacy_display_system(dev_priv); | 777 | ret = vmw_kms_init_legacy_display_system(dev_priv); |
778 | 778 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index c7efbd47ab84..f8fbbc67a406 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -35,11 +35,6 @@ | |||
35 | #define VMW_RES_SURFACE ttm_driver_type1 | 35 | #define VMW_RES_SURFACE ttm_driver_type1 |
36 | #define VMW_RES_STREAM ttm_driver_type2 | 36 | #define VMW_RES_STREAM ttm_driver_type2 |
37 | 37 | ||
38 | /* XXX: This isn't a real hardware flag, but just a hack for kernel to | ||
39 | * know about primary surfaces. Find a better way to accomplish this. | ||
40 | */ | ||
41 | #define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9) | ||
42 | |||
43 | struct vmw_user_context { | 38 | struct vmw_user_context { |
44 | struct ttm_base_object base; | 39 | struct ttm_base_object base; |
45 | struct vmw_resource res; | 40 | struct vmw_resource res; |
@@ -579,6 +574,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
579 | 574 | ||
580 | srf->flags = req->flags; | 575 | srf->flags = req->flags; |
581 | srf->format = req->format; | 576 | srf->format = req->format; |
577 | srf->scanout = req->scanout; | ||
582 | memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); | 578 | memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); |
583 | srf->num_sizes = 0; | 579 | srf->num_sizes = 0; |
584 | for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) | 580 | for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) |
@@ -604,16 +600,6 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
604 | if (unlikely(ret != 0)) | 600 | if (unlikely(ret != 0)) |
605 | goto out_err1; | 601 | goto out_err1; |
606 | 602 | ||
607 | if (srf->flags & SVGA3D_SURFACE_HINT_SCANOUT) { | ||
608 | /* we should not send this flag down to hardware since | ||
609 | * its not a official one | ||
610 | */ | ||
611 | srf->flags &= ~SVGA3D_SURFACE_HINT_SCANOUT; | ||
612 | srf->scanout = true; | ||
613 | } else { | ||
614 | srf->scanout = false; | ||
615 | } | ||
616 | |||
617 | if (srf->scanout && | 603 | if (srf->scanout && |
618 | srf->num_sizes == 1 && | 604 | srf->num_sizes == 1 && |
619 | srf->sizes[0].width == 64 && | 605 | srf->sizes[0].width == 64 && |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 1ac0c93603c9..2f6cf69ecb39 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -961,7 +961,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, | |||
961 | remaining -= 7; | 961 | remaining -= 7; |
962 | pr_devel("client 0x%p called 'target'\n", priv); | 962 | pr_devel("client 0x%p called 'target'\n", priv); |
963 | /* if target is default */ | 963 | /* if target is default */ |
964 | if (!strncmp(buf, "default", 7)) | 964 | if (!strncmp(curr_pos, "default", 7)) |
965 | pdev = pci_dev_get(vga_default_device()); | 965 | pdev = pci_dev_get(vga_default_device()); |
966 | else { | 966 | else { |
967 | if (!vga_pci_str_to_vars(curr_pos, remaining, | 967 | if (!vga_pci_str_to_vars(curr_pos, remaining, |
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index a31e77c776ae..b8156b4893bb 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c | |||
@@ -179,7 +179,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; | |||
179 | * | 179 | * |
180 | * Some, but not all, of these voltages have low/high limits. | 180 | * Some, but not all, of these voltages have low/high limits. |
181 | */ | 181 | */ |
182 | #define ADT7462_VOLT_COUNT 12 | 182 | #define ADT7462_VOLT_COUNT 13 |
183 | 183 | ||
184 | #define ADT7462_VENDOR 0x41 | 184 | #define ADT7462_VENDOR 0x41 |
185 | #define ADT7462_DEVICE 0x62 | 185 | #define ADT7462_DEVICE 0x62 |
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c index cadcbd90ff3b..72ff2c4e757d 100644 --- a/drivers/hwmon/lm78.c +++ b/drivers/hwmon/lm78.c | |||
@@ -851,17 +851,16 @@ static struct lm78_data *lm78_update_device(struct device *dev) | |||
851 | static int __init lm78_isa_found(unsigned short address) | 851 | static int __init lm78_isa_found(unsigned short address) |
852 | { | 852 | { |
853 | int val, save, found = 0; | 853 | int val, save, found = 0; |
854 | 854 | int port; | |
855 | /* We have to request the region in two parts because some | 855 | |
856 | boards declare base+4 to base+7 as a PNP device */ | 856 | /* Some boards declare base+0 to base+7 as a PNP device, some base+4 |
857 | if (!request_region(address, 4, "lm78")) { | 857 | * to base+7 and some base+5 to base+6. So we better request each port |
858 | pr_debug("lm78: Failed to request low part of region\n"); | 858 | * individually for the probing phase. */ |
859 | return 0; | 859 | for (port = address; port < address + LM78_EXTENT; port++) { |
860 | } | 860 | if (!request_region(port, 1, "lm78")) { |
861 | if (!request_region(address + 4, 4, "lm78")) { | 861 | pr_debug("lm78: Failed to request port 0x%x\n", port); |
862 | pr_debug("lm78: Failed to request high part of region\n"); | 862 | goto release; |
863 | release_region(address, 4); | 863 | } |
864 | return 0; | ||
865 | } | 864 | } |
866 | 865 | ||
867 | #define REALLY_SLOW_IO | 866 | #define REALLY_SLOW_IO |
@@ -925,8 +924,8 @@ static int __init lm78_isa_found(unsigned short address) | |||
925 | val & 0x80 ? "LM79" : "LM78", (int)address); | 924 | val & 0x80 ? "LM79" : "LM78", (int)address); |
926 | 925 | ||
927 | release: | 926 | release: |
928 | release_region(address + 4, 4); | 927 | for (port--; port >= address; port--) |
929 | release_region(address, 4); | 928 | release_region(port, 1); |
930 | return found; | 929 | return found; |
931 | } | 930 | } |
932 | 931 | ||
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index 05f9225b6f94..32d4adee73db 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -1793,17 +1793,17 @@ static int __init | |||
1793 | w83781d_isa_found(unsigned short address) | 1793 | w83781d_isa_found(unsigned short address) |
1794 | { | 1794 | { |
1795 | int val, save, found = 0; | 1795 | int val, save, found = 0; |
1796 | 1796 | int port; | |
1797 | /* We have to request the region in two parts because some | 1797 | |
1798 | boards declare base+4 to base+7 as a PNP device */ | 1798 | /* Some boards declare base+0 to base+7 as a PNP device, some base+4 |
1799 | if (!request_region(address, 4, "w83781d")) { | 1799 | * to base+7 and some base+5 to base+6. So we better request each port |
1800 | pr_debug("w83781d: Failed to request low part of region\n"); | 1800 | * individually for the probing phase. */ |
1801 | return 0; | 1801 | for (port = address; port < address + W83781D_EXTENT; port++) { |
1802 | } | 1802 | if (!request_region(port, 1, "w83781d")) { |
1803 | if (!request_region(address + 4, 4, "w83781d")) { | 1803 | pr_debug("w83781d: Failed to request port 0x%x\n", |
1804 | pr_debug("w83781d: Failed to request high part of region\n"); | 1804 | port); |
1805 | release_region(address, 4); | 1805 | goto release; |
1806 | return 0; | 1806 | } |
1807 | } | 1807 | } |
1808 | 1808 | ||
1809 | #define REALLY_SLOW_IO | 1809 | #define REALLY_SLOW_IO |
@@ -1877,8 +1877,8 @@ w83781d_isa_found(unsigned short address) | |||
1877 | val == 0x30 ? "W83782D" : "W83781D", (int)address); | 1877 | val == 0x30 ? "W83782D" : "W83781D", (int)address); |
1878 | 1878 | ||
1879 | release: | 1879 | release: |
1880 | release_region(address + 4, 4); | 1880 | for (port--; port >= address; port--) |
1881 | release_region(address, 4); | 1881 | release_region(port, 1); |
1882 | return found; | 1882 | return found; |
1883 | } | 1883 | } |
1884 | 1884 | ||
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index b1c050ff311d..e29b6d5ba8ef 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/types.h> | ||
16 | 17 | ||
17 | /* include interfaces to usb layer */ | 18 | /* include interfaces to usb layer */ |
18 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
@@ -31,8 +32,8 @@ | |||
31 | #define CMD_I2C_IO_END (1<<1) | 32 | #define CMD_I2C_IO_END (1<<1) |
32 | 33 | ||
33 | /* i2c bit delay, default is 10us -> 100kHz */ | 34 | /* i2c bit delay, default is 10us -> 100kHz */ |
34 | static int delay = 10; | 35 | static unsigned short delay = 10; |
35 | module_param(delay, int, 0); | 36 | module_param(delay, ushort, 0); |
36 | MODULE_PARM_DESC(delay, "bit delay in microseconds, " | 37 | MODULE_PARM_DESC(delay, "bit delay in microseconds, " |
37 | "e.g. 10 for 100kHz (default is 100kHz)"); | 38 | "e.g. 10 for 100kHz (default is 100kHz)"); |
38 | 39 | ||
@@ -109,7 +110,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) | |||
109 | 110 | ||
110 | static u32 usb_func(struct i2c_adapter *adapter) | 111 | static u32 usb_func(struct i2c_adapter *adapter) |
111 | { | 112 | { |
112 | u32 func; | 113 | __le32 func; |
113 | 114 | ||
114 | /* get functionality from adapter */ | 115 | /* get functionality from adapter */ |
115 | if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) != | 116 | if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) != |
@@ -118,7 +119,7 @@ static u32 usb_func(struct i2c_adapter *adapter) | |||
118 | return 0; | 119 | return 0; |
119 | } | 120 | } |
120 | 121 | ||
121 | return func; | 122 | return le32_to_cpu(func); |
122 | } | 123 | } |
123 | 124 | ||
124 | /* This is the actual algorithm we define */ | 125 | /* This is the actual algorithm we define */ |
@@ -216,8 +217,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, | |||
216 | "i2c-tiny-usb at bus %03d device %03d", | 217 | "i2c-tiny-usb at bus %03d device %03d", |
217 | dev->usb_dev->bus->busnum, dev->usb_dev->devnum); | 218 | dev->usb_dev->bus->busnum, dev->usb_dev->devnum); |
218 | 219 | ||
219 | if (usb_write(&dev->adapter, CMD_SET_DELAY, | 220 | if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) { |
220 | cpu_to_le16(delay), 0, NULL, 0) != 0) { | ||
221 | dev_err(&dev->adapter.dev, | 221 | dev_err(&dev->adapter.dev, |
222 | "failure setting delay to %dus\n", delay); | 222 | "failure setting delay to %dus\n", delay); |
223 | retval = -EIO; | 223 | retval = -EIO; |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index cc9b5940fa97..875e34e0b235 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -2115,9 +2115,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
2115 | if (ret) | 2115 | if (ret) |
2116 | goto err1; | 2116 | goto err1; |
2117 | 2117 | ||
2118 | if (cma_loopback_addr(addr)) { | 2118 | if (!cma_any_addr(addr)) { |
2119 | ret = cma_bind_loopback(id_priv); | ||
2120 | } else if (!cma_zero_addr(addr)) { | ||
2121 | ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); | 2119 | ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); |
2122 | if (ret) | 2120 | if (ret) |
2123 | goto err1; | 2121 | goto err1; |
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c index aa6713b4a988..291d9393d359 100644 --- a/drivers/input/input-polldev.c +++ b/drivers/input/input-polldev.c | |||
@@ -100,6 +100,12 @@ static void input_close_polled_device(struct input_dev *input) | |||
100 | struct input_polled_dev *dev = input_get_drvdata(input); | 100 | struct input_polled_dev *dev = input_get_drvdata(input); |
101 | 101 | ||
102 | cancel_delayed_work_sync(&dev->work); | 102 | cancel_delayed_work_sync(&dev->work); |
103 | /* | ||
104 | * Clean up work struct to remove references to the workqueue. | ||
105 | * It may be destroyed by the next call. This causes problems | ||
106 | * at next device open-close in case of poll_interval == 0. | ||
107 | */ | ||
108 | INIT_DELAYED_WORK(&dev->work, dev->work.work.func); | ||
103 | input_polldev_stop_workqueue(); | 109 | input_polldev_stop_workqueue(); |
104 | 110 | ||
105 | if (dev->close) | 111 | if (dev->close) |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 9774bdfaa482..d8c0c8d6992c 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -1141,7 +1141,14 @@ static void psmouse_cleanup(struct serio *serio) | |||
1141 | psmouse_deactivate(parent); | 1141 | psmouse_deactivate(parent); |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | psmouse_deactivate(psmouse); | 1144 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
1145 | |||
1146 | /* | ||
1147 | * Disable stream mode so cleanup routine can proceed undisturbed. | ||
1148 | */ | ||
1149 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE)) | ||
1150 | printk(KERN_WARNING "psmouse.c: Failed to disable mouse on %s\n", | ||
1151 | psmouse->ps2dev.serio->phys); | ||
1145 | 1152 | ||
1146 | if (psmouse->cleanup) | 1153 | if (psmouse->cleanup) |
1147 | psmouse->cleanup(psmouse); | 1154 | psmouse->cleanup(psmouse); |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index d84a36e545f6..b54aee7cd9e3 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -1161,9 +1161,17 @@ static int i8042_pm_restore(struct device *dev) | |||
1161 | return 0; | 1161 | return 0; |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static int i8042_pm_thaw(struct device *dev) | ||
1165 | { | ||
1166 | i8042_interrupt(0, NULL); | ||
1167 | |||
1168 | return 0; | ||
1169 | } | ||
1170 | |||
1164 | static const struct dev_pm_ops i8042_pm_ops = { | 1171 | static const struct dev_pm_ops i8042_pm_ops = { |
1165 | .suspend = i8042_pm_reset, | 1172 | .suspend = i8042_pm_reset, |
1166 | .resume = i8042_pm_restore, | 1173 | .resume = i8042_pm_restore, |
1174 | .thaw = i8042_pm_thaw, | ||
1167 | .poweroff = i8042_pm_reset, | 1175 | .poweroff = i8042_pm_reset, |
1168 | .restore = i8042_pm_restore, | 1176 | .restore = i8042_pm_restore, |
1169 | }; | 1177 | }; |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 09a5e7341bd5..5256123a5228 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -618,8 +618,8 @@ static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
618 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 618 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
619 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 619 | static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
620 | { | 620 | { |
621 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; | 621 | dev->x = (pkt[2] << 8) | pkt[1]; |
622 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; | 622 | dev->y = (pkt[4] << 8) | pkt[3]; |
623 | dev->press = pkt[5] & 0xff; | 623 | dev->press = pkt[5] & 0xff; |
624 | dev->touch = pkt[0] & 0x01; | 624 | dev->touch = pkt[0] & 0x01; |
625 | 625 | ||
@@ -809,9 +809,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
809 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH | 809 | #ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH |
810 | [DEVTYPE_GENERAL_TOUCH] = { | 810 | [DEVTYPE_GENERAL_TOUCH] = { |
811 | .min_xc = 0x0, | 811 | .min_xc = 0x0, |
812 | .max_xc = 0x0500, | 812 | .max_xc = 0x7fff, |
813 | .min_yc = 0x0, | 813 | .min_yc = 0x0, |
814 | .max_yc = 0x0500, | 814 | .max_yc = 0x7fff, |
815 | .rept_size = 7, | 815 | .rept_size = 7, |
816 | .read_data = general_touch_read_data, | 816 | .read_data = general_touch_read_data, |
817 | }, | 817 | }, |
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c index 54abf9e303b7..f1c8cae70b4b 100644 --- a/drivers/md/dm-log-userspace-transfer.c +++ b/drivers/md/dm-log-userspace-transfer.c | |||
@@ -172,11 +172,15 @@ int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type, | |||
172 | { | 172 | { |
173 | int r = 0; | 173 | int r = 0; |
174 | size_t dummy = 0; | 174 | size_t dummy = 0; |
175 | int overhead_size = | 175 | int overhead_size = sizeof(struct dm_ulog_request) + sizeof(struct cn_msg); |
176 | sizeof(struct dm_ulog_request *) + sizeof(struct cn_msg); | ||
177 | struct dm_ulog_request *tfr = prealloced_ulog_tfr; | 176 | struct dm_ulog_request *tfr = prealloced_ulog_tfr; |
178 | struct receiving_pkg pkg; | 177 | struct receiving_pkg pkg; |
179 | 178 | ||
179 | /* | ||
180 | * Given the space needed to hold the 'struct cn_msg' and | ||
181 | * 'struct dm_ulog_request' - do we have enough payload | ||
182 | * space remaining? | ||
183 | */ | ||
180 | if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) { | 184 | if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) { |
181 | DMINFO("Size of tfr exceeds preallocated size"); | 185 | DMINFO("Size of tfr exceeds preallocated size"); |
182 | return -EINVAL; | 186 | return -EINVAL; |
@@ -191,7 +195,7 @@ resend: | |||
191 | */ | 195 | */ |
192 | mutex_lock(&dm_ulog_lock); | 196 | mutex_lock(&dm_ulog_lock); |
193 | 197 | ||
194 | memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); | 198 | memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - sizeof(struct cn_msg)); |
195 | memcpy(tfr->uuid, uuid, DM_UUID_LEN); | 199 | memcpy(tfr->uuid, uuid, DM_UUID_LEN); |
196 | tfr->luid = luid; | 200 | tfr->luid = luid; |
197 | tfr->seq = dm_ulog_seq++; | 201 | tfr->seq = dm_ulog_seq++; |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index ad779bd13aec..6c1046df81f6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -724,7 +724,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes) | |||
724 | /* | 724 | /* |
725 | * Dispatch io. | 725 | * Dispatch io. |
726 | */ | 726 | */ |
727 | if (unlikely(ms->log_failure)) { | 727 | if (unlikely(ms->log_failure) && errors_handled(ms)) { |
728 | spin_lock_irq(&ms->lock); | 728 | spin_lock_irq(&ms->lock); |
729 | bio_list_merge(&ms->failures, &sync); | 729 | bio_list_merge(&ms->failures, &sync); |
730 | spin_unlock_irq(&ms->lock); | 730 | spin_unlock_irq(&ms->lock); |
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index 5f19ceb6fe91..168bd38f5006 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c | |||
@@ -660,10 +660,9 @@ void dm_rh_recovery_end(struct dm_region *reg, int success) | |||
660 | spin_lock_irq(&rh->region_lock); | 660 | spin_lock_irq(&rh->region_lock); |
661 | if (success) | 661 | if (success) |
662 | list_add(®->list, ®->rh->recovered_regions); | 662 | list_add(®->list, ®->rh->recovered_regions); |
663 | else { | 663 | else |
664 | reg->state = DM_RH_NOSYNC; | ||
665 | list_add(®->list, ®->rh->failed_recovered_regions); | 664 | list_add(®->list, ®->rh->failed_recovered_regions); |
666 | } | 665 | |
667 | spin_unlock_irq(&rh->region_lock); | 666 | spin_unlock_irq(&rh->region_lock); |
668 | 667 | ||
669 | rh->wakeup_workers(rh->context); | 668 | rh->wakeup_workers(rh->context); |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 7d08879689ac..c097d8a4823d 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -254,7 +254,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, | |||
254 | * Issue the synchronous I/O from a different thread | 254 | * Issue the synchronous I/O from a different thread |
255 | * to avoid generic_make_request recursion. | 255 | * to avoid generic_make_request recursion. |
256 | */ | 256 | */ |
257 | INIT_WORK(&req.work, do_metadata); | 257 | INIT_WORK_ON_STACK(&req.work, do_metadata); |
258 | queue_work(ps->metadata_wq, &req.work); | 258 | queue_work(ps->metadata_wq, &req.work); |
259 | flush_workqueue(ps->metadata_wq); | 259 | flush_workqueue(ps->metadata_wq); |
260 | 260 | ||
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index e0efc1adcaff..bd58703ee8f6 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c | |||
@@ -110,7 +110,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | stripes = simple_strtoul(argv[0], &end, 10); | 112 | stripes = simple_strtoul(argv[0], &end, 10); |
113 | if (*end) { | 113 | if (!stripes || *end) { |
114 | ti->error = "Invalid stripe count"; | 114 | ti->error = "Invalid stripe count"; |
115 | return -EINVAL; | 115 | return -EINVAL; |
116 | } | 116 | } |
diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c index f53392df7b97..f91b40942e07 100644 --- a/drivers/md/dm-sysfs.c +++ b/drivers/md/dm-sysfs.c | |||
@@ -80,20 +80,12 @@ static struct sysfs_ops dm_sysfs_ops = { | |||
80 | }; | 80 | }; |
81 | 81 | ||
82 | /* | 82 | /* |
83 | * The sysfs structure is embedded in md struct, nothing to do here | ||
84 | */ | ||
85 | static void dm_sysfs_release(struct kobject *kobj) | ||
86 | { | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * dm kobject is embedded in mapped_device structure | 83 | * dm kobject is embedded in mapped_device structure |
91 | * no need to define release function here | 84 | * no need to define release function here |
92 | */ | 85 | */ |
93 | static struct kobj_type dm_ktype = { | 86 | static struct kobj_type dm_ktype = { |
94 | .sysfs_ops = &dm_sysfs_ops, | 87 | .sysfs_ops = &dm_sysfs_ops, |
95 | .default_attrs = dm_attrs, | 88 | .default_attrs = dm_attrs, |
96 | .release = dm_sysfs_release | ||
97 | }; | 89 | }; |
98 | 90 | ||
99 | /* | 91 | /* |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 3167480b532c..aa4e2aa86d49 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1595,10 +1595,15 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq) | |||
1595 | return BLKPREP_OK; | 1595 | return BLKPREP_OK; |
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | static void map_request(struct dm_target *ti, struct request *clone, | 1598 | /* |
1599 | struct mapped_device *md) | 1599 | * Returns: |
1600 | * 0 : the request has been processed (not requeued) | ||
1601 | * !0 : the request has been requeued | ||
1602 | */ | ||
1603 | static int map_request(struct dm_target *ti, struct request *clone, | ||
1604 | struct mapped_device *md) | ||
1600 | { | 1605 | { |
1601 | int r; | 1606 | int r, requeued = 0; |
1602 | struct dm_rq_target_io *tio = clone->end_io_data; | 1607 | struct dm_rq_target_io *tio = clone->end_io_data; |
1603 | 1608 | ||
1604 | /* | 1609 | /* |
@@ -1625,6 +1630,7 @@ static void map_request(struct dm_target *ti, struct request *clone, | |||
1625 | case DM_MAPIO_REQUEUE: | 1630 | case DM_MAPIO_REQUEUE: |
1626 | /* The target wants to requeue the I/O */ | 1631 | /* The target wants to requeue the I/O */ |
1627 | dm_requeue_unmapped_request(clone); | 1632 | dm_requeue_unmapped_request(clone); |
1633 | requeued = 1; | ||
1628 | break; | 1634 | break; |
1629 | default: | 1635 | default: |
1630 | if (r > 0) { | 1636 | if (r > 0) { |
@@ -1636,6 +1642,8 @@ static void map_request(struct dm_target *ti, struct request *clone, | |||
1636 | dm_kill_unmapped_request(clone, r); | 1642 | dm_kill_unmapped_request(clone, r); |
1637 | break; | 1643 | break; |
1638 | } | 1644 | } |
1645 | |||
1646 | return requeued; | ||
1639 | } | 1647 | } |
1640 | 1648 | ||
1641 | /* | 1649 | /* |
@@ -1677,12 +1685,17 @@ static void dm_request_fn(struct request_queue *q) | |||
1677 | atomic_inc(&md->pending[rq_data_dir(clone)]); | 1685 | atomic_inc(&md->pending[rq_data_dir(clone)]); |
1678 | 1686 | ||
1679 | spin_unlock(q->queue_lock); | 1687 | spin_unlock(q->queue_lock); |
1680 | map_request(ti, clone, md); | 1688 | if (map_request(ti, clone, md)) |
1689 | goto requeued; | ||
1690 | |||
1681 | spin_lock_irq(q->queue_lock); | 1691 | spin_lock_irq(q->queue_lock); |
1682 | } | 1692 | } |
1683 | 1693 | ||
1684 | goto out; | 1694 | goto out; |
1685 | 1695 | ||
1696 | requeued: | ||
1697 | spin_lock_irq(q->queue_lock); | ||
1698 | |||
1686 | plug_and_out: | 1699 | plug_and_out: |
1687 | if (!elv_queue_empty(q)) | 1700 | if (!elv_queue_empty(q)) |
1688 | /* Some requests still remain, retry later */ | 1701 | /* Some requests still remain, retry later */ |
diff --git a/drivers/md/md.c b/drivers/md/md.c index dd3dfe42d5a9..a20a71e5efd3 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -4075,8 +4075,10 @@ static void mddev_delayed_delete(struct work_struct *ws) | |||
4075 | { | 4075 | { |
4076 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | 4076 | mddev_t *mddev = container_of(ws, mddev_t, del_work); |
4077 | 4077 | ||
4078 | if (mddev->private == &md_redundancy_group) { | 4078 | if (mddev->private) { |
4079 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | 4079 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); |
4080 | if (mddev->private != (void*)1) | ||
4081 | sysfs_remove_group(&mddev->kobj, mddev->private); | ||
4080 | if (mddev->sysfs_action) | 4082 | if (mddev->sysfs_action) |
4081 | sysfs_put(mddev->sysfs_action); | 4083 | sysfs_put(mddev->sysfs_action); |
4082 | mddev->sysfs_action = NULL; | 4084 | mddev->sysfs_action = NULL; |
@@ -4287,10 +4289,7 @@ static int do_md_run(mddev_t * mddev) | |||
4287 | sysfs_notify_dirent(rdev->sysfs_state); | 4289 | sysfs_notify_dirent(rdev->sysfs_state); |
4288 | } | 4290 | } |
4289 | 4291 | ||
4290 | md_probe(mddev->unit, NULL, NULL); | ||
4291 | disk = mddev->gendisk; | 4292 | disk = mddev->gendisk; |
4292 | if (!disk) | ||
4293 | return -ENOMEM; | ||
4294 | 4293 | ||
4295 | spin_lock(&pers_lock); | 4294 | spin_lock(&pers_lock); |
4296 | pers = find_pers(mddev->level, mddev->clevel); | 4295 | pers = find_pers(mddev->level, mddev->clevel); |
@@ -4530,8 +4529,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
4530 | mddev->queue->unplug_fn = NULL; | 4529 | mddev->queue->unplug_fn = NULL; |
4531 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4530 | mddev->queue->backing_dev_info.congested_fn = NULL; |
4532 | module_put(mddev->pers->owner); | 4531 | module_put(mddev->pers->owner); |
4533 | if (mddev->pers->sync_request) | 4532 | if (mddev->pers->sync_request && mddev->private == NULL) |
4534 | mddev->private = &md_redundancy_group; | 4533 | mddev->private = (void*)1; |
4535 | mddev->pers = NULL; | 4534 | mddev->pers = NULL; |
4536 | /* tell userspace to handle 'inactive' */ | 4535 | /* tell userspace to handle 'inactive' */ |
4537 | sysfs_notify_dirent(mddev->sysfs_state); | 4536 | sysfs_notify_dirent(mddev->sysfs_state); |
@@ -4578,9 +4577,6 @@ out: | |||
4578 | } | 4577 | } |
4579 | mddev->bitmap_info.offset = 0; | 4578 | mddev->bitmap_info.offset = 0; |
4580 | 4579 | ||
4581 | /* make sure all md_delayed_delete calls have finished */ | ||
4582 | flush_scheduled_work(); | ||
4583 | |||
4584 | export_array(mddev); | 4580 | export_array(mddev); |
4585 | 4581 | ||
4586 | mddev->array_sectors = 0; | 4582 | mddev->array_sectors = 0; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e84204eb12df..ceb24afdc147 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -5136,9 +5136,8 @@ static int stop(mddev_t *mddev) | |||
5136 | mddev->thread = NULL; | 5136 | mddev->thread = NULL; |
5137 | mddev->queue->backing_dev_info.congested_fn = NULL; | 5137 | mddev->queue->backing_dev_info.congested_fn = NULL; |
5138 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 5138 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
5139 | sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); | ||
5140 | free_conf(conf); | 5139 | free_conf(conf); |
5141 | mddev->private = NULL; | 5140 | mddev->private = &raid5_attrs_group; |
5142 | return 0; | 5141 | return 0; |
5143 | } | 5142 | } |
5144 | 5143 | ||
@@ -5464,11 +5463,11 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
5464 | !test_bit(Faulty, &rdev->flags)) { | 5463 | !test_bit(Faulty, &rdev->flags)) { |
5465 | if (raid5_add_disk(mddev, rdev) == 0) { | 5464 | if (raid5_add_disk(mddev, rdev) == 0) { |
5466 | char nm[20]; | 5465 | char nm[20]; |
5467 | if (rdev->raid_disk >= conf->previous_raid_disks) | 5466 | if (rdev->raid_disk >= conf->previous_raid_disks) { |
5468 | set_bit(In_sync, &rdev->flags); | 5467 | set_bit(In_sync, &rdev->flags); |
5469 | else | 5468 | added_devices++; |
5469 | } else | ||
5470 | rdev->recovery_offset = 0; | 5470 | rdev->recovery_offset = 0; |
5471 | added_devices++; | ||
5472 | sprintf(nm, "rd%d", rdev->raid_disk); | 5471 | sprintf(nm, "rd%d", rdev->raid_disk); |
5473 | if (sysfs_create_link(&mddev->kobj, | 5472 | if (sysfs_create_link(&mddev->kobj, |
5474 | &rdev->kobj, nm)) | 5473 | &rdev->kobj, nm)) |
@@ -5480,9 +5479,12 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
5480 | break; | 5479 | break; |
5481 | } | 5480 | } |
5482 | 5481 | ||
5482 | /* When a reshape changes the number of devices, ->degraded | ||
5483 | * is measured against the large of the pre and post number of | ||
5484 | * devices.*/ | ||
5483 | if (mddev->delta_disks > 0) { | 5485 | if (mddev->delta_disks > 0) { |
5484 | spin_lock_irqsave(&conf->device_lock, flags); | 5486 | spin_lock_irqsave(&conf->device_lock, flags); |
5485 | mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) | 5487 | mddev->degraded += (conf->raid_disks - conf->previous_raid_disks) |
5486 | - added_devices; | 5488 | - added_devices; |
5487 | spin_unlock_irqrestore(&conf->device_lock, flags); | 5489 | spin_unlock_irqrestore(&conf->device_lock, flags); |
5488 | } | 5490 | } |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index becbaadb3b77..5ed75263340a 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -1333,9 +1333,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
1333 | 1333 | ||
1334 | DEB_CAP(("vbuf:%p\n",vb)); | 1334 | DEB_CAP(("vbuf:%p\n",vb)); |
1335 | 1335 | ||
1336 | release_all_pagetables(dev, buf); | ||
1337 | |||
1338 | saa7146_dma_free(dev,q,buf); | 1336 | saa7146_dma_free(dev,q,buf); |
1337 | |||
1338 | release_all_pagetables(dev, buf); | ||
1339 | } | 1339 | } |
1340 | 1340 | ||
1341 | static struct videobuf_queue_ops video_qops = { | 1341 | static struct videobuf_queue_ops video_qops = { |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index c37790ad92d0..9ddc57909d49 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -761,7 +761,6 @@ static int dvb_demux_open(struct inode *inode, struct file *file) | |||
761 | dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); | 761 | dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); |
762 | dmxdevfilter->type = DMXDEV_TYPE_NONE; | 762 | dmxdevfilter->type = DMXDEV_TYPE_NONE; |
763 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); | 763 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); |
764 | INIT_LIST_HEAD(&dmxdevfilter->feed.ts); | ||
765 | init_timer(&dmxdevfilter->timer); | 764 | init_timer(&dmxdevfilter->timer); |
766 | 765 | ||
767 | dvbdev->users++; | 766 | dvbdev->users++; |
@@ -887,6 +886,7 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, | |||
887 | dmxdevfilter->type = DMXDEV_TYPE_PES; | 886 | dmxdevfilter->type = DMXDEV_TYPE_PES; |
888 | memcpy(&dmxdevfilter->params, params, | 887 | memcpy(&dmxdevfilter->params, params, |
889 | sizeof(struct dmx_pes_filter_params)); | 888 | sizeof(struct dmx_pes_filter_params)); |
889 | INIT_LIST_HEAD(&dmxdevfilter->feed.ts); | ||
890 | 890 | ||
891 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); | 891 | dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); |
892 | 892 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index b78cfb7d1897..67f189b7aa1f 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -426,16 +426,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
426 | }; | 426 | }; |
427 | }; | 427 | }; |
428 | 428 | ||
429 | if (dvb_demux_tscheck) { | 429 | if (demux->cnt_storage) { |
430 | if (!demux->cnt_storage) | ||
431 | demux->cnt_storage = vmalloc(MAX_PID + 1); | ||
432 | |||
433 | if (!demux->cnt_storage) { | ||
434 | printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); | ||
435 | dvb_demux_tscheck = 0; | ||
436 | goto no_dvb_demux_tscheck; | ||
437 | } | ||
438 | |||
439 | /* check pkt counter */ | 430 | /* check pkt counter */ |
440 | if (pid < MAX_PID) { | 431 | if (pid < MAX_PID) { |
441 | if (buf[1] & 0x80) | 432 | if (buf[1] & 0x80) |
@@ -454,7 +445,6 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
454 | }; | 445 | }; |
455 | /* end check */ | 446 | /* end check */ |
456 | }; | 447 | }; |
457 | no_dvb_demux_tscheck: | ||
458 | 448 | ||
459 | list_for_each_entry(feed, &demux->feed_list, list_head) { | 449 | list_for_each_entry(feed, &demux->feed_list, list_head) { |
460 | if ((feed->pid != pid) && (feed->pid != 0x2000)) | 450 | if ((feed->pid != pid) && (feed->pid != 0x2000)) |
@@ -1246,6 +1236,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) | |||
1246 | dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed)); | 1236 | dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed)); |
1247 | if (!dvbdemux->feed) { | 1237 | if (!dvbdemux->feed) { |
1248 | vfree(dvbdemux->filter); | 1238 | vfree(dvbdemux->filter); |
1239 | dvbdemux->filter = NULL; | ||
1249 | return -ENOMEM; | 1240 | return -ENOMEM; |
1250 | } | 1241 | } |
1251 | for (i = 0; i < dvbdemux->filternum; i++) { | 1242 | for (i = 0; i < dvbdemux->filternum; i++) { |
@@ -1257,6 +1248,13 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) | |||
1257 | dvbdemux->feed[i].index = i; | 1248 | dvbdemux->feed[i].index = i; |
1258 | } | 1249 | } |
1259 | 1250 | ||
1251 | if (dvb_demux_tscheck) { | ||
1252 | dvbdemux->cnt_storage = vmalloc(MAX_PID + 1); | ||
1253 | |||
1254 | if (!dvbdemux->cnt_storage) | ||
1255 | printk(KERN_WARNING "Couldn't allocate memory for TS/TEI check. Disabling it\n"); | ||
1256 | } | ||
1257 | |||
1260 | INIT_LIST_HEAD(&dvbdemux->frontend_list); | 1258 | INIT_LIST_HEAD(&dvbdemux->frontend_list); |
1261 | 1259 | ||
1262 | for (i = 0; i < DMX_TS_PES_OTHER; i++) { | 1260 | for (i = 0; i < DMX_TS_PES_OTHER; i++) { |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 1b249897c9fb..465295b1d14b 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -112,11 +112,13 @@ config DVB_USB_CXUSB | |||
112 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 112 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
113 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 113 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
114 | select DVB_DIB7000P if !DVB_FE_CUSTOMISE | 114 | select DVB_DIB7000P if !DVB_FE_CUSTOMISE |
115 | select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE | ||
116 | select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE | 115 | select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE |
116 | select DVB_ATBM8830 if !DVB_FE_CUSTOMISE | ||
117 | select DVB_LGS8GXX if !DVB_FE_CUSTOMISE | ||
117 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE | 118 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE |
118 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE | 119 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
119 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 120 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
121 | select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE | ||
120 | help | 122 | help |
121 | Say Y here to support the Conexant USB2.0 hybrid reference design. | 123 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
122 | Currently, only DVB and ATSC modes are supported, analog mode | 124 | Currently, only DVB and ATSC modes are supported, analog mode |
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 3051b64aa17c..445fa1068064 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c | |||
@@ -192,8 +192,8 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa | |||
192 | spi_bias *= qam_tab[p->constellation]; | 192 | spi_bias *= qam_tab[p->constellation]; |
193 | spi_bias /= p->code_rate_HP + 1; | 193 | spi_bias /= p->code_rate_HP + 1; |
194 | spi_bias /= (guard_tab[p->guard_interval] + 32); | 194 | spi_bias /= (guard_tab[p->guard_interval] + 32); |
195 | spi_bias *= 1000ULL; | 195 | spi_bias *= 1000; |
196 | spi_bias /= 1000ULL + ppm/1000; | 196 | spi_bias /= 1000 + ppm/1000; |
197 | spi_bias *= p->code_rate_HP; | 197 | spi_bias *= p->code_rate_HP; |
198 | 198 | ||
199 | val0x04 = (p->transmission_mode << 2) | p->guard_interval; | 199 | val0x04 = (p->transmission_mode << 2) | p->guard_interval; |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 3182a406bdd1..ae08b077fd04 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -4461,6 +4461,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
4461 | request_modules(btv); | 4461 | request_modules(btv); |
4462 | } | 4462 | } |
4463 | 4463 | ||
4464 | init_bttv_i2c_ir(btv); | ||
4464 | bttv_input_init(btv); | 4465 | bttv_input_init(btv); |
4465 | 4466 | ||
4466 | /* everything is fine */ | 4467 | /* everything is fine */ |
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index 63aa31a041e8..407fa61e4cda 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c | |||
@@ -388,7 +388,12 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
388 | if (0 == btv->i2c_rc && i2c_scan) | 388 | if (0 == btv->i2c_rc && i2c_scan) |
389 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); | 389 | do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); |
390 | 390 | ||
391 | /* Instantiate the IR receiver device, if present */ | 391 | return btv->i2c_rc; |
392 | } | ||
393 | |||
394 | /* Instantiate the I2C IR receiver device, if present */ | ||
395 | void __devinit init_bttv_i2c_ir(struct bttv *btv) | ||
396 | { | ||
392 | if (0 == btv->i2c_rc) { | 397 | if (0 == btv->i2c_rc) { |
393 | struct i2c_board_info info; | 398 | struct i2c_board_info info; |
394 | /* The external IR receiver is at i2c address 0x34 (0x35 for | 399 | /* The external IR receiver is at i2c address 0x34 (0x35 for |
@@ -408,7 +413,6 @@ int __devinit init_bttv_i2c(struct bttv *btv) | |||
408 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | 413 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); |
409 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); | 414 | i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); |
410 | } | 415 | } |
411 | return btv->i2c_rc; | ||
412 | } | 416 | } |
413 | 417 | ||
414 | int __devexit fini_bttv_i2c(struct bttv *btv) | 418 | int __devexit fini_bttv_i2c(struct bttv *btv) |
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index a1d0e9c9f286..6cccc2a17eee 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h | |||
@@ -279,6 +279,7 @@ extern unsigned int bttv_debug; | |||
279 | extern unsigned int bttv_gpio; | 279 | extern unsigned int bttv_gpio; |
280 | extern void bttv_gpio_tracking(struct bttv *btv, char *comment); | 280 | extern void bttv_gpio_tracking(struct bttv *btv, char *comment); |
281 | extern int init_bttv_i2c(struct bttv *btv); | 281 | extern int init_bttv_i2c(struct bttv *btv); |
282 | extern void init_bttv_i2c_ir(struct bttv *btv); | ||
282 | extern int fini_bttv_i2c(struct bttv *btv); | 283 | extern int fini_bttv_i2c(struct bttv *btv); |
283 | 284 | ||
284 | #define bttv_printk if (bttv_verbose) printk | 285 | #define bttv_printk if (bttv_verbose) printk |
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index fc4dd6045720..7438f8d775ba 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c | |||
@@ -514,7 +514,7 @@ static int mt9t112_init_pll(const struct i2c_client *client) | |||
514 | /* poll to verify out of standby. Must Poll this bit */ | 514 | /* poll to verify out of standby. Must Poll this bit */ |
515 | for (i = 0; i < 100; i++) { | 515 | for (i = 0; i < 100; i++) { |
516 | mt9t112_reg_read(data, client, 0x0018); | 516 | mt9t112_reg_read(data, client, 0x0018); |
517 | if (0x4000 & data) | 517 | if (!(0x4000 & data)) |
518 | break; | 518 | break; |
519 | 519 | ||
520 | mdelay(10); | 520 | mdelay(10); |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 50b415e07eda..f7f7e04cf485 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -753,7 +753,7 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value) | |||
753 | buf[0] = 0xff; /* fixed */ | 753 | buf[0] = 0xff; /* fixed */ |
754 | 754 | ||
755 | ret = send_control_msg(pdev, | 755 | ret = send_control_msg(pdev, |
756 | SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf)); | 756 | SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1); |
757 | 757 | ||
758 | if (!mode && ret >= 0) { | 758 | if (!mode && ret >= 0) { |
759 | if (value < 0) | 759 | if (value < 0) |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 7dfecfc6017c..ee5bff02a92c 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -93,9 +93,9 @@ static int ts_open(struct file *file) | |||
93 | dprintk("open dev=%s\n", video_device_node_name(vdev)); | 93 | dprintk("open dev=%s\n", video_device_node_name(vdev)); |
94 | err = -EBUSY; | 94 | err = -EBUSY; |
95 | if (!mutex_trylock(&dev->empress_tsq.vb_lock)) | 95 | if (!mutex_trylock(&dev->empress_tsq.vb_lock)) |
96 | goto done; | 96 | return err; |
97 | if (atomic_read(&dev->empress_users)) | 97 | if (atomic_read(&dev->empress_users)) |
98 | goto done_up; | 98 | goto done; |
99 | 99 | ||
100 | /* Unmute audio */ | 100 | /* Unmute audio */ |
101 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, | 101 | saa_writeb(SAA7134_AUDIO_MUTE_CTRL, |
@@ -105,10 +105,8 @@ static int ts_open(struct file *file) | |||
105 | file->private_data = dev; | 105 | file->private_data = dev; |
106 | err = 0; | 106 | err = 0; |
107 | 107 | ||
108 | done_up: | ||
109 | mutex_unlock(&dev->empress_tsq.vb_lock); | ||
110 | done: | 108 | done: |
111 | unlock_kernel(); | 109 | mutex_unlock(&dev->empress_tsq.vb_lock); |
112 | return err; | 110 | return err; |
113 | } | 111 | } |
114 | 112 | ||
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 57752751712b..81279b3d694c 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -1796,7 +1796,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1796 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " | 1796 | dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: " |
1797 | "Command not in the active list! (sc=%p)\n", ioc->name, | 1797 | "Command not in the active list! (sc=%p)\n", ioc->name, |
1798 | SCpnt)); | 1798 | SCpnt)); |
1799 | retval = 0; | 1799 | retval = SUCCESS; |
1800 | goto out; | 1800 | goto out; |
1801 | } | 1801 | } |
1802 | 1802 | ||
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index b9f1e84897cc..e7f8027165e6 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -74,6 +74,9 @@ static void mmc_test_prepare_mrq(struct mmc_test_card *test, | |||
74 | } | 74 | } |
75 | 75 | ||
76 | mrq->cmd->arg = dev_addr; | 76 | mrq->cmd->arg = dev_addr; |
77 | if (!mmc_card_blockaddr(test->card)) | ||
78 | mrq->cmd->arg <<= 9; | ||
79 | |||
77 | mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 80 | mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
78 | 81 | ||
79 | if (blocks == 1) | 82 | if (blocks == 1) |
@@ -190,7 +193,7 @@ static int __mmc_test_prepare(struct mmc_test_card *test, int write) | |||
190 | } | 193 | } |
191 | 194 | ||
192 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 195 | for (i = 0;i < BUFFER_SIZE / 512;i++) { |
193 | ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); | 196 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
194 | if (ret) | 197 | if (ret) |
195 | return ret; | 198 | return ret; |
196 | } | 199 | } |
@@ -219,7 +222,7 @@ static int mmc_test_cleanup(struct mmc_test_card *test) | |||
219 | memset(test->buffer, 0, 512); | 222 | memset(test->buffer, 0, 512); |
220 | 223 | ||
221 | for (i = 0;i < BUFFER_SIZE / 512;i++) { | 224 | for (i = 0;i < BUFFER_SIZE / 512;i++) { |
222 | ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1); | 225 | ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); |
223 | if (ret) | 226 | if (ret) |
224 | return ret; | 227 | return ret; |
225 | } | 228 | } |
@@ -426,7 +429,7 @@ static int mmc_test_transfer(struct mmc_test_card *test, | |||
426 | for (i = 0;i < sectors;i++) { | 429 | for (i = 0;i < sectors;i++) { |
427 | ret = mmc_test_buffer_transfer(test, | 430 | ret = mmc_test_buffer_transfer(test, |
428 | test->buffer + i * 512, | 431 | test->buffer + i * 512, |
429 | dev_addr + i * 512, 512, 0); | 432 | dev_addr + i, 512, 0); |
430 | if (ret) | 433 | if (ret) |
431 | return ret; | 434 | return ret; |
432 | } | 435 | } |
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 62d9c9cc5671..1dd4403247ca 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c | |||
@@ -921,7 +921,7 @@ static int ax_probe(struct platform_device *pdev) | |||
921 | size = (res->end - res->start) + 1; | 921 | size = (res->end - res->start) + 1; |
922 | 922 | ||
923 | ax->mem2 = request_mem_region(res->start, size, pdev->name); | 923 | ax->mem2 = request_mem_region(res->start, size, pdev->name); |
924 | if (ax->mem == NULL) { | 924 | if (ax->mem2 == NULL) { |
925 | dev_err(&pdev->dev, "cannot reserve registers\n"); | 925 | dev_err(&pdev->dev, "cannot reserve registers\n"); |
926 | ret = -ENXIO; | 926 | ret = -ENXIO; |
927 | goto exit_mem1; | 927 | goto exit_mem1; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index fee6eee7ae5b..006cb2efcd22 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -296,6 +296,7 @@ static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, | |||
296 | req_hdr->opcode = opcode; | 296 | req_hdr->opcode = opcode; |
297 | req_hdr->subsystem = subsystem; | 297 | req_hdr->subsystem = subsystem; |
298 | req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); | 298 | req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); |
299 | req_hdr->version = 0; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, | 302 | static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, |
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index bdbd14727e4b..318a018ca7c5 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c | |||
@@ -2079,6 +2079,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2079 | struct sge_fl *fl, int len, int complete) | 2079 | struct sge_fl *fl, int len, int complete) |
2080 | { | 2080 | { |
2081 | struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; | 2081 | struct rx_sw_desc *sd = &fl->sdesc[fl->cidx]; |
2082 | struct port_info *pi = netdev_priv(qs->netdev); | ||
2082 | struct sk_buff *skb = NULL; | 2083 | struct sk_buff *skb = NULL; |
2083 | struct cpl_rx_pkt *cpl; | 2084 | struct cpl_rx_pkt *cpl; |
2084 | struct skb_frag_struct *rx_frag; | 2085 | struct skb_frag_struct *rx_frag; |
@@ -2116,11 +2117,18 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2116 | 2117 | ||
2117 | if (!nr_frags) { | 2118 | if (!nr_frags) { |
2118 | offset = 2 + sizeof(struct cpl_rx_pkt); | 2119 | offset = 2 + sizeof(struct cpl_rx_pkt); |
2119 | qs->lro_va = sd->pg_chunk.va + 2; | 2120 | cpl = qs->lro_va = sd->pg_chunk.va + 2; |
2120 | } | ||
2121 | len -= offset; | ||
2122 | 2121 | ||
2123 | prefetch(qs->lro_va); | 2122 | if ((pi->rx_offload & T3_RX_CSUM) && |
2123 | cpl->csum_valid && cpl->csum == htons(0xffff)) { | ||
2124 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2125 | qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; | ||
2126 | } else | ||
2127 | skb->ip_summed = CHECKSUM_NONE; | ||
2128 | } else | ||
2129 | cpl = qs->lro_va; | ||
2130 | |||
2131 | len -= offset; | ||
2124 | 2132 | ||
2125 | rx_frag += nr_frags; | 2133 | rx_frag += nr_frags; |
2126 | rx_frag->page = sd->pg_chunk.page; | 2134 | rx_frag->page = sd->pg_chunk.page; |
@@ -2136,12 +2144,8 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, | |||
2136 | return; | 2144 | return; |
2137 | 2145 | ||
2138 | skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); | 2146 | skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); |
2139 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2140 | cpl = qs->lro_va; | ||
2141 | 2147 | ||
2142 | if (unlikely(cpl->vlan_valid)) { | 2148 | if (unlikely(cpl->vlan_valid)) { |
2143 | struct net_device *dev = qs->netdev; | ||
2144 | struct port_info *pi = netdev_priv(dev); | ||
2145 | struct vlan_group *grp = pi->vlan_grp; | 2149 | struct vlan_group *grp = pi->vlan_grp; |
2146 | 2150 | ||
2147 | if (likely(grp != NULL)) { | 2151 | if (likely(grp != NULL)) { |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index d29bb532eccf..765543663a4f 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -4006,11 +4006,21 @@ check_page: | |||
4006 | } | 4006 | } |
4007 | } | 4007 | } |
4008 | 4008 | ||
4009 | if (!buffer_info->dma) | 4009 | if (!buffer_info->dma) { |
4010 | buffer_info->dma = pci_map_page(pdev, | 4010 | buffer_info->dma = pci_map_page(pdev, |
4011 | buffer_info->page, 0, | 4011 | buffer_info->page, 0, |
4012 | buffer_info->length, | 4012 | buffer_info->length, |
4013 | PCI_DMA_FROMDEVICE); | 4013 | PCI_DMA_FROMDEVICE); |
4014 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) { | ||
4015 | put_page(buffer_info->page); | ||
4016 | dev_kfree_skb(skb); | ||
4017 | buffer_info->page = NULL; | ||
4018 | buffer_info->skb = NULL; | ||
4019 | buffer_info->dma = 0; | ||
4020 | adapter->alloc_rx_buff_failed++; | ||
4021 | break; /* while !buffer_info->skb */ | ||
4022 | } | ||
4023 | } | ||
4014 | 4024 | ||
4015 | rx_desc = E1000_RX_DESC(*rx_ring, i); | 4025 | rx_desc = E1000_RX_DESC(*rx_ring, i); |
4016 | rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); | 4026 | rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); |
@@ -4101,6 +4111,13 @@ map_skb: | |||
4101 | skb->data, | 4111 | skb->data, |
4102 | buffer_info->length, | 4112 | buffer_info->length, |
4103 | PCI_DMA_FROMDEVICE); | 4113 | PCI_DMA_FROMDEVICE); |
4114 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) { | ||
4115 | dev_kfree_skb(skb); | ||
4116 | buffer_info->skb = NULL; | ||
4117 | buffer_info->dma = 0; | ||
4118 | adapter->alloc_rx_buff_failed++; | ||
4119 | break; /* while !buffer_info->skb */ | ||
4120 | } | ||
4104 | 4121 | ||
4105 | /* | 4122 | /* |
4106 | * XXX if it was allocated cleanly it will never map to a | 4123 | * XXX if it was allocated cleanly it will never map to a |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 997124d2992a..c881347cb26d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -421,6 +421,8 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector) | |||
421 | msixbm = E1000_EICR_RX_QUEUE0 << rx_queue; | 421 | msixbm = E1000_EICR_RX_QUEUE0 << rx_queue; |
422 | if (tx_queue > IGB_N0_QUEUE) | 422 | if (tx_queue > IGB_N0_QUEUE) |
423 | msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue; | 423 | msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue; |
424 | if (!adapter->msix_entries && msix_vector == 0) | ||
425 | msixbm |= E1000_EIMS_OTHER; | ||
424 | array_wr32(E1000_MSIXBM(0), msix_vector, msixbm); | 426 | array_wr32(E1000_MSIXBM(0), msix_vector, msixbm); |
425 | q_vector->eims_value = msixbm; | 427 | q_vector->eims_value = msixbm; |
426 | break; | 428 | break; |
@@ -877,7 +879,6 @@ static int igb_request_irq(struct igb_adapter *adapter) | |||
877 | { | 879 | { |
878 | struct net_device *netdev = adapter->netdev; | 880 | struct net_device *netdev = adapter->netdev; |
879 | struct pci_dev *pdev = adapter->pdev; | 881 | struct pci_dev *pdev = adapter->pdev; |
880 | struct e1000_hw *hw = &adapter->hw; | ||
881 | int err = 0; | 882 | int err = 0; |
882 | 883 | ||
883 | if (adapter->msix_entries) { | 884 | if (adapter->msix_entries) { |
@@ -909,20 +910,7 @@ static int igb_request_irq(struct igb_adapter *adapter) | |||
909 | igb_setup_all_tx_resources(adapter); | 910 | igb_setup_all_tx_resources(adapter); |
910 | igb_setup_all_rx_resources(adapter); | 911 | igb_setup_all_rx_resources(adapter); |
911 | } else { | 912 | } else { |
912 | switch (hw->mac.type) { | 913 | igb_assign_vector(adapter->q_vector[0], 0); |
913 | case e1000_82575: | ||
914 | wr32(E1000_MSIXBM(0), | ||
915 | (E1000_EICR_RX_QUEUE0 | | ||
916 | E1000_EICR_TX_QUEUE0 | | ||
917 | E1000_EIMS_OTHER)); | ||
918 | break; | ||
919 | case e1000_82580: | ||
920 | case e1000_82576: | ||
921 | wr32(E1000_IVAR0, E1000_IVAR_VALID); | ||
922 | break; | ||
923 | default: | ||
924 | break; | ||
925 | } | ||
926 | } | 914 | } |
927 | 915 | ||
928 | if (adapter->flags & IGB_FLAG_HAS_MSI) { | 916 | if (adapter->flags & IGB_FLAG_HAS_MSI) { |
@@ -1140,6 +1128,8 @@ int igb_up(struct igb_adapter *adapter) | |||
1140 | } | 1128 | } |
1141 | if (adapter->msix_entries) | 1129 | if (adapter->msix_entries) |
1142 | igb_configure_msix(adapter); | 1130 | igb_configure_msix(adapter); |
1131 | else | ||
1132 | igb_assign_vector(adapter->q_vector[0], 0); | ||
1143 | 1133 | ||
1144 | /* Clear any pending interrupts. */ | 1134 | /* Clear any pending interrupts. */ |
1145 | rd32(E1000_ICR); | 1135 | rd32(E1000_ICR); |
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 3103f4165311..35a06b47587b 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -357,12 +357,34 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) | |||
357 | u32 fctrl_reg; | 357 | u32 fctrl_reg; |
358 | u32 rmcs_reg; | 358 | u32 rmcs_reg; |
359 | u32 reg; | 359 | u32 reg; |
360 | u32 link_speed = 0; | ||
361 | bool link_up; | ||
360 | 362 | ||
361 | #ifdef CONFIG_DCB | 363 | #ifdef CONFIG_DCB |
362 | if (hw->fc.requested_mode == ixgbe_fc_pfc) | 364 | if (hw->fc.requested_mode == ixgbe_fc_pfc) |
363 | goto out; | 365 | goto out; |
364 | 366 | ||
365 | #endif /* CONFIG_DCB */ | 367 | #endif /* CONFIG_DCB */ |
368 | /* | ||
369 | * On 82598 having Rx FC on causes resets while doing 1G | ||
370 | * so if it's on turn it off once we know link_speed. For | ||
371 | * more details see 82598 Specification update. | ||
372 | */ | ||
373 | hw->mac.ops.check_link(hw, &link_speed, &link_up, false); | ||
374 | if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) { | ||
375 | switch (hw->fc.requested_mode) { | ||
376 | case ixgbe_fc_full: | ||
377 | hw->fc.requested_mode = ixgbe_fc_tx_pause; | ||
378 | break; | ||
379 | case ixgbe_fc_rx_pause: | ||
380 | hw->fc.requested_mode = ixgbe_fc_none; | ||
381 | break; | ||
382 | default: | ||
383 | /* no change */ | ||
384 | break; | ||
385 | } | ||
386 | } | ||
387 | |||
366 | /* Negotiate the fc mode to use */ | 388 | /* Negotiate the fc mode to use */ |
367 | ret_val = ixgbe_fc_autoneg(hw); | 389 | ret_val = ixgbe_fc_autoneg(hw); |
368 | if (ret_val) | 390 | if (ret_val) |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b5f64ad67975..951b73cf5ca2 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -5179,7 +5179,7 @@ dma_error: | |||
5179 | ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); | 5179 | ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); |
5180 | } | 5180 | } |
5181 | 5181 | ||
5182 | return count; | 5182 | return 0; |
5183 | } | 5183 | } |
5184 | 5184 | ||
5185 | static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, | 5185 | static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, |
@@ -5329,8 +5329,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
5329 | struct ixgbe_adapter *adapter = netdev_priv(dev); | 5329 | struct ixgbe_adapter *adapter = netdev_priv(dev); |
5330 | int txq = smp_processor_id(); | 5330 | int txq = smp_processor_id(); |
5331 | 5331 | ||
5332 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) | 5332 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { |
5333 | while (unlikely(txq >= dev->real_num_tx_queues)) | ||
5334 | txq -= dev->real_num_tx_queues; | ||
5333 | return txq; | 5335 | return txq; |
5336 | } | ||
5334 | 5337 | ||
5335 | #ifdef IXGBE_FCOE | 5338 | #ifdef IXGBE_FCOE |
5336 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && | 5339 | if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && |
@@ -5760,6 +5763,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
5760 | if (err) | 5763 | if (err) |
5761 | goto err_sw_init; | 5764 | goto err_sw_init; |
5762 | 5765 | ||
5766 | /* Make it possible the adapter to be woken up via WOL */ | ||
5767 | if (adapter->hw.mac.type == ixgbe_mac_82599EB) | ||
5768 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); | ||
5769 | |||
5763 | /* | 5770 | /* |
5764 | * If there is a fan on this device and it has failed log the | 5771 | * If there is a fan on this device and it has failed log the |
5765 | * failure. | 5772 | * failure. |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 9f9d6081959b..24279e6e55f5 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -1941,7 +1941,7 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1941 | netif_wake_queue(adapter->netdev); | 1941 | netif_wake_queue(adapter->netdev); |
1942 | 1942 | ||
1943 | clear_bit(__NX_RESETTING, &adapter->state); | 1943 | clear_bit(__NX_RESETTING, &adapter->state); |
1944 | 1944 | return; | |
1945 | } else { | 1945 | } else { |
1946 | clear_bit(__NX_RESETTING, &adapter->state); | 1946 | clear_bit(__NX_RESETTING, &adapter->state); |
1947 | if (!netxen_nic_reset_context(adapter)) { | 1947 | if (!netxen_nic_reset_context(adapter)) { |
@@ -2240,7 +2240,9 @@ netxen_detach_work(struct work_struct *work) | |||
2240 | 2240 | ||
2241 | netxen_nic_down(adapter, netdev); | 2241 | netxen_nic_down(adapter, netdev); |
2242 | 2242 | ||
2243 | rtnl_lock(); | ||
2243 | netxen_nic_detach(adapter); | 2244 | netxen_nic_detach(adapter); |
2245 | rtnl_unlock(); | ||
2244 | 2246 | ||
2245 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | 2247 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); |
2246 | 2248 | ||
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 103e8b0e2a0d..46997e177ee3 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -2284,6 +2284,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2284 | fail2: | 2284 | fail2: |
2285 | efx_fini_struct(efx); | 2285 | efx_fini_struct(efx); |
2286 | fail1: | 2286 | fail1: |
2287 | WARN_ON(rc > 0); | ||
2287 | EFX_LOG(efx, "initialisation failed. rc=%d\n", rc); | 2288 | EFX_LOG(efx, "initialisation failed. rc=%d\n", rc); |
2288 | free_netdev(net_dev); | 2289 | free_netdev(net_dev); |
2289 | return rc; | 2290 | return rc; |
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index bf0b96af5334..5712fddd72f2 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c | |||
@@ -29,6 +29,15 @@ | |||
29 | #define FALCON_BOARD_SFN4111T 0x51 | 29 | #define FALCON_BOARD_SFN4111T 0x51 |
30 | #define FALCON_BOARD_SFN4112F 0x52 | 30 | #define FALCON_BOARD_SFN4112F 0x52 |
31 | 31 | ||
32 | /* Board temperature is about 15°C above ambient when air flow is | ||
33 | * limited. */ | ||
34 | #define FALCON_BOARD_TEMP_BIAS 15 | ||
35 | |||
36 | /* SFC4000 datasheet says: 'The maximum permitted junction temperature | ||
37 | * is 125°C; the thermal design of the environment for the SFC4000 | ||
38 | * should aim to keep this well below 100°C.' */ | ||
39 | #define FALCON_JUNC_TEMP_MAX 90 | ||
40 | |||
32 | /***************************************************************************** | 41 | /***************************************************************************** |
33 | * Support for LM87 sensor chip used on several boards | 42 | * Support for LM87 sensor chip used on several boards |
34 | */ | 43 | */ |
@@ -548,16 +557,16 @@ fail_hwmon: | |||
548 | static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */ | 557 | static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */ |
549 | 558 | ||
550 | static const u8 sfe4002_lm87_regs[] = { | 559 | static const u8 sfe4002_lm87_regs[] = { |
551 | LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ | 560 | LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */ |
552 | LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ | 561 | LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */ |
553 | LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ | 562 | LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */ |
554 | LM87_IN_LIMITS(3, 0xb0, 0xc9), /* 5V: 4.6-5.2V */ | 563 | LM87_IN_LIMITS(3, 0xac, 0xd4), /* 5V: 5.0V +/- 10% */ |
555 | LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ | 564 | LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */ |
556 | LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ | 565 | LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */ |
557 | LM87_AIN_LIMITS(0, 0xa0, 0xb2), /* AIN1: 1.66V +/- 5% */ | 566 | LM87_AIN_LIMITS(0, 0x98, 0xbb), /* AIN1: 1.66V +/- 10% */ |
558 | LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ | 567 | LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */ |
559 | LM87_TEMP_INT_LIMITS(10, 60), /* board */ | 568 | LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS), |
560 | LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ | 569 | LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX), |
561 | 0 | 570 | 0 |
562 | }; | 571 | }; |
563 | 572 | ||
@@ -619,14 +628,14 @@ static int sfe4002_init(struct efx_nic *efx) | |||
619 | static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */ | 628 | static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */ |
620 | 629 | ||
621 | static const u8 sfn4112f_lm87_regs[] = { | 630 | static const u8 sfn4112f_lm87_regs[] = { |
622 | LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ | 631 | LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */ |
623 | LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ | 632 | LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */ |
624 | LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ | 633 | LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */ |
625 | LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ | 634 | LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */ |
626 | LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ | 635 | LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */ |
627 | LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ | 636 | LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */ |
628 | LM87_TEMP_INT_LIMITS(10, 60), /* board */ | 637 | LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS), |
629 | LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ | 638 | LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX), |
630 | 0 | 639 | 0 |
631 | }; | 640 | }; |
632 | 641 | ||
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 9f035b9f0350..f66b3da6ddff 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c | |||
@@ -127,7 +127,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) | |||
127 | efx_dword_t reg; | 127 | efx_dword_t reg; |
128 | 128 | ||
129 | /* Check for a reboot atomically with respect to efx_mcdi_copyout() */ | 129 | /* Check for a reboot atomically with respect to efx_mcdi_copyout() */ |
130 | rc = efx_mcdi_poll_reboot(efx); | 130 | rc = -efx_mcdi_poll_reboot(efx); |
131 | if (rc) | 131 | if (rc) |
132 | goto out; | 132 | goto out; |
133 | 133 | ||
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c index e0d13a451019..67eec7a6e487 100644 --- a/drivers/net/sfc/qt202x_phy.c +++ b/drivers/net/sfc/qt202x_phy.c | |||
@@ -320,7 +320,7 @@ static int qt202x_reset_phy(struct efx_nic *efx) | |||
320 | 320 | ||
321 | falcon_board(efx)->type->init_phy(efx); | 321 | falcon_board(efx)->type->init_phy(efx); |
322 | 322 | ||
323 | return rc; | 323 | return 0; |
324 | 324 | ||
325 | fail: | 325 | fail: |
326 | EFX_ERR(efx, "PHY reset timed out\n"); | 326 | EFX_ERR(efx, "PHY reset timed out\n"); |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d760650c5c04..67249c3c9f50 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1025,11 +1025,8 @@ static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr, | |||
1025 | static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) | 1025 | static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot) |
1026 | { | 1026 | { |
1027 | struct sky2_tx_le *le = sky2->tx_le + *slot; | 1027 | struct sky2_tx_le *le = sky2->tx_le + *slot; |
1028 | struct tx_ring_info *re = sky2->tx_ring + *slot; | ||
1029 | 1028 | ||
1030 | *slot = RING_NEXT(*slot, sky2->tx_ring_size); | 1029 | *slot = RING_NEXT(*slot, sky2->tx_ring_size); |
1031 | re->flags = 0; | ||
1032 | re->skb = NULL; | ||
1033 | le->ctrl = 0; | 1030 | le->ctrl = 0; |
1034 | return le; | 1031 | return le; |
1035 | } | 1032 | } |
@@ -1622,8 +1619,7 @@ static unsigned tx_le_req(const struct sk_buff *skb) | |||
1622 | return count; | 1619 | return count; |
1623 | } | 1620 | } |
1624 | 1621 | ||
1625 | static void sky2_tx_unmap(struct pci_dev *pdev, | 1622 | static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) |
1626 | const struct tx_ring_info *re) | ||
1627 | { | 1623 | { |
1628 | if (re->flags & TX_MAP_SINGLE) | 1624 | if (re->flags & TX_MAP_SINGLE) |
1629 | pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), | 1625 | pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), |
@@ -1633,6 +1629,7 @@ static void sky2_tx_unmap(struct pci_dev *pdev, | |||
1633 | pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), | 1629 | pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), |
1634 | pci_unmap_len(re, maplen), | 1630 | pci_unmap_len(re, maplen), |
1635 | PCI_DMA_TODEVICE); | 1631 | PCI_DMA_TODEVICE); |
1632 | re->flags = 0; | ||
1636 | } | 1633 | } |
1637 | 1634 | ||
1638 | /* | 1635 | /* |
@@ -1839,6 +1836,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1839 | dev->stats.tx_packets++; | 1836 | dev->stats.tx_packets++; |
1840 | dev->stats.tx_bytes += skb->len; | 1837 | dev->stats.tx_bytes += skb->len; |
1841 | 1838 | ||
1839 | re->skb = NULL; | ||
1842 | dev_kfree_skb_any(skb); | 1840 | dev_kfree_skb_any(skb); |
1843 | 1841 | ||
1844 | sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size); | 1842 | sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size); |
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 75a669d48e5e..d71c1976072e 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -1437,7 +1437,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status, int limit) | |||
1437 | /* Transmit complete. */ | 1437 | /* Transmit complete. */ |
1438 | lp->lstats.tx_ints++; | 1438 | lp->lstats.tx_ints++; |
1439 | tc35815_txdone(dev); | 1439 | tc35815_txdone(dev); |
1440 | netif_wake_queue(dev); | ||
1441 | if (ret < 0) | 1440 | if (ret < 0) |
1442 | ret = 0; | 1441 | ret = 0; |
1443 | } | 1442 | } |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4f27f022fbf7..5f3b9eaeb04f 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -584,6 +584,11 @@ static const struct usb_device_id products [] = { | |||
584 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 584 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
585 | .driver_info = (unsigned long) &mbm_info, | 585 | .driver_info = (unsigned long) &mbm_info, |
586 | }, { | 586 | }, { |
587 | /* Ericsson C3607w ver 2 */ | ||
588 | USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM, | ||
589 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
590 | .driver_info = (unsigned long) &mbm_info, | ||
591 | }, { | ||
587 | /* Toshiba F3507g */ | 592 | /* Toshiba F3507g */ |
588 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, | 593 | USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, |
589 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | 594 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index c93f58f5c6f2..317aa34b21cf 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -1877,13 +1877,12 @@ static void velocity_error(struct velocity_info *vptr, int status) | |||
1877 | /** | 1877 | /** |
1878 | * tx_srv - transmit interrupt service | 1878 | * tx_srv - transmit interrupt service |
1879 | * @vptr; Velocity | 1879 | * @vptr; Velocity |
1880 | * @status: | ||
1881 | * | 1880 | * |
1882 | * Scan the queues looking for transmitted packets that | 1881 | * Scan the queues looking for transmitted packets that |
1883 | * we can complete and clean up. Update any statistics as | 1882 | * we can complete and clean up. Update any statistics as |
1884 | * necessary/ | 1883 | * necessary/ |
1885 | */ | 1884 | */ |
1886 | static int velocity_tx_srv(struct velocity_info *vptr, u32 status) | 1885 | static int velocity_tx_srv(struct velocity_info *vptr) |
1887 | { | 1886 | { |
1888 | struct tx_desc *td; | 1887 | struct tx_desc *td; |
1889 | int qnum; | 1888 | int qnum; |
@@ -2090,14 +2089,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx) | |||
2090 | /** | 2089 | /** |
2091 | * velocity_rx_srv - service RX interrupt | 2090 | * velocity_rx_srv - service RX interrupt |
2092 | * @vptr: velocity | 2091 | * @vptr: velocity |
2093 | * @status: adapter status (unused) | ||
2094 | * | 2092 | * |
2095 | * Walk the receive ring of the velocity adapter and remove | 2093 | * Walk the receive ring of the velocity adapter and remove |
2096 | * any received packets from the receive queue. Hand the ring | 2094 | * any received packets from the receive queue. Hand the ring |
2097 | * slots back to the adapter for reuse. | 2095 | * slots back to the adapter for reuse. |
2098 | */ | 2096 | */ |
2099 | static int velocity_rx_srv(struct velocity_info *vptr, int status, | 2097 | static int velocity_rx_srv(struct velocity_info *vptr, int budget_left) |
2100 | int budget_left) | ||
2101 | { | 2098 | { |
2102 | struct net_device_stats *stats = &vptr->dev->stats; | 2099 | struct net_device_stats *stats = &vptr->dev->stats; |
2103 | int rd_curr = vptr->rx.curr; | 2100 | int rd_curr = vptr->rx.curr; |
@@ -2151,32 +2148,24 @@ static int velocity_poll(struct napi_struct *napi, int budget) | |||
2151 | struct velocity_info *vptr = container_of(napi, | 2148 | struct velocity_info *vptr = container_of(napi, |
2152 | struct velocity_info, napi); | 2149 | struct velocity_info, napi); |
2153 | unsigned int rx_done; | 2150 | unsigned int rx_done; |
2154 | u32 isr_status; | 2151 | unsigned long flags; |
2155 | |||
2156 | spin_lock(&vptr->lock); | ||
2157 | isr_status = mac_read_isr(vptr->mac_regs); | ||
2158 | |||
2159 | /* Ack the interrupt */ | ||
2160 | mac_write_isr(vptr->mac_regs, isr_status); | ||
2161 | if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) | ||
2162 | velocity_error(vptr, isr_status); | ||
2163 | 2152 | ||
2153 | spin_lock_irqsave(&vptr->lock, flags); | ||
2164 | /* | 2154 | /* |
2165 | * Do rx and tx twice for performance (taken from the VIA | 2155 | * Do rx and tx twice for performance (taken from the VIA |
2166 | * out-of-tree driver). | 2156 | * out-of-tree driver). |
2167 | */ | 2157 | */ |
2168 | rx_done = velocity_rx_srv(vptr, isr_status, budget / 2); | 2158 | rx_done = velocity_rx_srv(vptr, budget / 2); |
2169 | velocity_tx_srv(vptr, isr_status); | 2159 | velocity_tx_srv(vptr); |
2170 | rx_done += velocity_rx_srv(vptr, isr_status, budget - rx_done); | 2160 | rx_done += velocity_rx_srv(vptr, budget - rx_done); |
2171 | velocity_tx_srv(vptr, isr_status); | 2161 | velocity_tx_srv(vptr); |
2172 | |||
2173 | spin_unlock(&vptr->lock); | ||
2174 | 2162 | ||
2175 | /* If budget not fully consumed, exit the polling mode */ | 2163 | /* If budget not fully consumed, exit the polling mode */ |
2176 | if (rx_done < budget) { | 2164 | if (rx_done < budget) { |
2177 | napi_complete(napi); | 2165 | napi_complete(napi); |
2178 | mac_enable_int(vptr->mac_regs); | 2166 | mac_enable_int(vptr->mac_regs); |
2179 | } | 2167 | } |
2168 | spin_unlock_irqrestore(&vptr->lock, flags); | ||
2180 | 2169 | ||
2181 | return rx_done; | 2170 | return rx_done; |
2182 | } | 2171 | } |
@@ -2206,10 +2195,17 @@ static irqreturn_t velocity_intr(int irq, void *dev_instance) | |||
2206 | return IRQ_NONE; | 2195 | return IRQ_NONE; |
2207 | } | 2196 | } |
2208 | 2197 | ||
2198 | /* Ack the interrupt */ | ||
2199 | mac_write_isr(vptr->mac_regs, isr_status); | ||
2200 | |||
2209 | if (likely(napi_schedule_prep(&vptr->napi))) { | 2201 | if (likely(napi_schedule_prep(&vptr->napi))) { |
2210 | mac_disable_int(vptr->mac_regs); | 2202 | mac_disable_int(vptr->mac_regs); |
2211 | __napi_schedule(&vptr->napi); | 2203 | __napi_schedule(&vptr->napi); |
2212 | } | 2204 | } |
2205 | |||
2206 | if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) | ||
2207 | velocity_error(vptr, isr_status); | ||
2208 | |||
2213 | spin_unlock(&vptr->lock); | 2209 | spin_unlock(&vptr->lock); |
2214 | 2210 | ||
2215 | return IRQ_HANDLED; | 2211 | return IRQ_HANDLED; |
@@ -3100,7 +3096,7 @@ static int velocity_resume(struct pci_dev *pdev) | |||
3100 | velocity_init_registers(vptr, VELOCITY_INIT_WOL); | 3096 | velocity_init_registers(vptr, VELOCITY_INIT_WOL); |
3101 | mac_disable_int(vptr->mac_regs); | 3097 | mac_disable_int(vptr->mac_regs); |
3102 | 3098 | ||
3103 | velocity_tx_srv(vptr, 0); | 3099 | velocity_tx_srv(vptr); |
3104 | 3100 | ||
3105 | for (i = 0; i < vptr->tx.numq; i++) { | 3101 | for (i = 0; i < vptr->tx.numq; i++) { |
3106 | if (vptr->tx.used[i]) | 3102 | if (vptr->tx.used[i]) |
@@ -3344,6 +3340,7 @@ static int velocity_set_coalesce(struct net_device *dev, | |||
3344 | { | 3340 | { |
3345 | struct velocity_info *vptr = netdev_priv(dev); | 3341 | struct velocity_info *vptr = netdev_priv(dev); |
3346 | int max_us = 0x3f * 64; | 3342 | int max_us = 0x3f * 64; |
3343 | unsigned long flags; | ||
3347 | 3344 | ||
3348 | /* 6 bits of */ | 3345 | /* 6 bits of */ |
3349 | if (ecmd->tx_coalesce_usecs > max_us) | 3346 | if (ecmd->tx_coalesce_usecs > max_us) |
@@ -3365,6 +3362,7 @@ static int velocity_set_coalesce(struct net_device *dev, | |||
3365 | ecmd->tx_coalesce_usecs); | 3362 | ecmd->tx_coalesce_usecs); |
3366 | 3363 | ||
3367 | /* Setup the interrupt suppression and queue timers */ | 3364 | /* Setup the interrupt suppression and queue timers */ |
3365 | spin_lock_irqsave(&vptr->lock, flags); | ||
3368 | mac_disable_int(vptr->mac_regs); | 3366 | mac_disable_int(vptr->mac_regs); |
3369 | setup_adaptive_interrupts(vptr); | 3367 | setup_adaptive_interrupts(vptr); |
3370 | setup_queue_timers(vptr); | 3368 | setup_queue_timers(vptr); |
@@ -3372,6 +3370,7 @@ static int velocity_set_coalesce(struct net_device *dev, | |||
3372 | mac_write_int_mask(vptr->int_mask, vptr->mac_regs); | 3370 | mac_write_int_mask(vptr->int_mask, vptr->mac_regs); |
3373 | mac_clear_isr(vptr->mac_regs); | 3371 | mac_clear_isr(vptr->mac_regs); |
3374 | mac_enable_int(vptr->mac_regs); | 3372 | mac_enable_int(vptr->mac_regs); |
3373 | spin_unlock_irqrestore(&vptr->lock, flags); | ||
3375 | 3374 | ||
3376 | return 0; | 3375 | return 0; |
3377 | } | 3376 | } |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index fa12b9060b0b..29bf33692f71 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1615,7 +1615,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1615 | bf->bf_frmlen -= padsize; | 1615 | bf->bf_frmlen -= padsize; |
1616 | } | 1616 | } |
1617 | 1617 | ||
1618 | if (conf_is_ht(&hw->conf) && !is_pae(skb)) | 1618 | if (conf_is_ht(&hw->conf)) |
1619 | bf->bf_state.bf_type |= BUF_HT; | 1619 | bf->bf_state.bf_type |= BUF_HT; |
1620 | 1620 | ||
1621 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | 1621 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); |
@@ -1701,7 +1701,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1701 | goto tx_done; | 1701 | goto tx_done; |
1702 | } | 1702 | } |
1703 | 1703 | ||
1704 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 1704 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) { |
1705 | /* | 1705 | /* |
1706 | * Try aggregation if it's a unicast data frame | 1706 | * Try aggregation if it's a unicast data frame |
1707 | * and the destination is HT capable. | 1707 | * and the destination is HT capable. |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index fe3bf9491997..c484cc253892 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -115,6 +115,7 @@ | |||
115 | #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ | 115 | #define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ |
116 | #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ | 116 | #define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ |
117 | #define B43_MMIO_RNG 0x65A | 117 | #define B43_MMIO_RNG 0x65A |
118 | #define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */ | ||
118 | #define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ | 119 | #define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ |
119 | #define B43_MMIO_IFSCTL_USE_EDCF 0x0004 | 120 | #define B43_MMIO_IFSCTL_USE_EDCF 0x0004 |
120 | #define B43_MMIO_POWERUP_DELAY 0x6A8 | 121 | #define B43_MMIO_POWERUP_DELAY 0x6A8 |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4c41cfe44f26..490fb45d1d05 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -628,10 +628,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev) | |||
628 | static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) | 628 | static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) |
629 | { | 629 | { |
630 | /* slot_time is in usec. */ | 630 | /* slot_time is in usec. */ |
631 | if (dev->phy.type != B43_PHYTYPE_G) | 631 | /* This test used to exit for all but a G PHY. */ |
632 | if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) | ||
632 | return; | 633 | return; |
633 | b43_write16(dev, 0x684, 510 + slot_time); | 634 | b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time); |
634 | b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); | 635 | /* Shared memory location 0x0010 is the slot time and should be |
636 | * set to slot_time; however, this register is initially 0 and changing | ||
637 | * the value adversely affects the transmit rate for BCM4311 | ||
638 | * devices. Until this behavior is unterstood, delete this step | ||
639 | * | ||
640 | * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); | ||
641 | */ | ||
635 | } | 642 | } |
636 | 643 | ||
637 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) | 644 | static void b43_short_slot_timing_enable(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9b4b8b5c7574..31462813bac0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2008,7 +2008,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2008 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " | 2008 | IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " |
2009 | "%d index %d\n", scd_ssn , index); | 2009 | "%d index %d\n", scd_ssn , index); |
2010 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2010 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2011 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 2011 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
2012 | 2012 | ||
2013 | if (priv->mac80211_registered && | 2013 | if (priv->mac80211_registered && |
2014 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && | 2014 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index de45f308b744..cffaae772d51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -1125,7 +1125,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1125 | scd_ssn , index, txq_id, txq->swq_id); | 1125 | scd_ssn , index, txq_id, txq->swq_id); |
1126 | 1126 | ||
1127 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1127 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1128 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1128 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1129 | 1129 | ||
1130 | if (priv->mac80211_registered && | 1130 | if (priv->mac80211_registered && |
1131 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && | 1131 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
@@ -1153,16 +1153,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1153 | tx_resp->failure_frame); | 1153 | tx_resp->failure_frame); |
1154 | 1154 | ||
1155 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1155 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1156 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | 1156 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1157 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
1158 | 1157 | ||
1159 | if (priv->mac80211_registered && | 1158 | if (priv->mac80211_registered && |
1160 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | 1159 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) |
1161 | iwl_wake_queue(priv, txq_id); | 1160 | iwl_wake_queue(priv, txq_id); |
1162 | } | 1161 | } |
1163 | 1162 | ||
1164 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | 1163 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1165 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
1166 | 1164 | ||
1167 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 1165 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1168 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); | 1166 | IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5461f105bd2d..f36f804804fc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2745,6 +2745,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2745 | priv->staging_rxon.flags = 0; | 2745 | priv->staging_rxon.flags = 0; |
2746 | 2746 | ||
2747 | iwl_set_rxon_channel(priv, conf->channel); | 2747 | iwl_set_rxon_channel(priv, conf->channel); |
2748 | iwl_set_rxon_ht(priv, ht_conf); | ||
2748 | 2749 | ||
2749 | iwl_set_flags_for_band(priv, conf->channel->band); | 2750 | iwl_set_flags_for_band(priv, conf->channel->band); |
2750 | spin_unlock_irqrestore(&priv->lock, flags); | 2751 | spin_unlock_irqrestore(&priv->lock, flags); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 27ca859e7453..b69e972671b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -446,6 +446,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | |||
446 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, | 446 | int iwl_hw_tx_queue_init(struct iwl_priv *priv, |
447 | struct iwl_tx_queue *txq); | 447 | struct iwl_tx_queue *txq); |
448 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 448 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
449 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | ||
450 | int sta_id, int tid, int freed); | ||
449 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 451 | int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
450 | int slots_num, u32 txq_id); | 452 | int slots_num, u32 txq_id); |
451 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); | 453 | void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6f36b6e79f5e..2dbce85404aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -928,7 +928,10 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
928 | if (ieee80211_is_mgmt(fc) || | 928 | if (ieee80211_is_mgmt(fc) || |
929 | ieee80211_has_protected(fc) || | 929 | ieee80211_has_protected(fc) || |
930 | ieee80211_has_morefrags(fc) || | 930 | ieee80211_has_morefrags(fc) || |
931 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) | 931 | le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG || |
932 | (ieee80211_is_data_qos(fc) && | ||
933 | *ieee80211_get_qos_ctl(hdr) & | ||
934 | IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)) | ||
932 | ret = skb_linearize(skb); | 935 | ret = skb_linearize(skb); |
933 | else | 936 | else |
934 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? | 937 | ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 87ce2bd292c7..8f4071562857 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -120,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
120 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); | 120 | EXPORT_SYMBOL(iwl_txq_update_write_ptr); |
121 | 121 | ||
122 | 122 | ||
123 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | ||
124 | int sta_id, int tid, int freed) | ||
125 | { | ||
126 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) | ||
127 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
128 | else { | ||
129 | IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", | ||
130 | priv->stations[sta_id].tid[tid].tfds_in_queue, | ||
131 | freed); | ||
132 | priv->stations[sta_id].tid[tid].tfds_in_queue = 0; | ||
133 | } | ||
134 | } | ||
135 | EXPORT_SYMBOL(iwl_free_tfds_in_queue); | ||
136 | |||
123 | /** | 137 | /** |
124 | * iwl_tx_queue_free - Deallocate DMA queue. | 138 | * iwl_tx_queue_free - Deallocate DMA queue. |
125 | * @txq: Transmit queue to deallocate. | 139 | * @txq: Transmit queue to deallocate. |
@@ -1131,6 +1145,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1131 | struct iwl_queue *q = &txq->q; | 1145 | struct iwl_queue *q = &txq->q; |
1132 | struct iwl_tx_info *tx_info; | 1146 | struct iwl_tx_info *tx_info; |
1133 | int nfreed = 0; | 1147 | int nfreed = 0; |
1148 | struct ieee80211_hdr *hdr; | ||
1134 | 1149 | ||
1135 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { | 1150 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
1136 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " | 1151 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " |
@@ -1145,13 +1160,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
1145 | 1160 | ||
1146 | tx_info = &txq->txb[txq->q.read_ptr]; | 1161 | tx_info = &txq->txb[txq->q.read_ptr]; |
1147 | iwl_tx_status(priv, tx_info->skb[0]); | 1162 | iwl_tx_status(priv, tx_info->skb[0]); |
1163 | |||
1164 | hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data; | ||
1165 | if (hdr && ieee80211_is_data_qos(hdr->frame_control)) | ||
1166 | nfreed++; | ||
1148 | tx_info->skb[0] = NULL; | 1167 | tx_info->skb[0] = NULL; |
1149 | 1168 | ||
1150 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) | 1169 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
1151 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); | 1170 | priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); |
1152 | 1171 | ||
1153 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); | 1172 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
1154 | nfreed++; | ||
1155 | } | 1173 | } |
1156 | return nfreed; | 1174 | return nfreed; |
1157 | } | 1175 | } |
@@ -1559,7 +1577,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1559 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 1577 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
1560 | /* calculate mac80211 ampdu sw queue to wake */ | 1578 | /* calculate mac80211 ampdu sw queue to wake */ |
1561 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | 1579 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); |
1562 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1580 | iwl_free_tfds_in_queue(priv, sta_id, tid, freed); |
1563 | 1581 | ||
1564 | if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && | 1582 | if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && |
1565 | priv->mac80211_registered && | 1583 | priv->mac80211_registered && |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 6d6ed7485175..f727b4a83196 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -794,7 +794,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, | |||
794 | } | 794 | } |
795 | 795 | ||
796 | bss->bss = kzalloc(bss_len, GFP_KERNEL); | 796 | bss->bss = kzalloc(bss_len, GFP_KERNEL); |
797 | if (!bss) { | 797 | if (!bss->bss) { |
798 | kfree(bss); | 798 | kfree(bss); |
799 | IWM_ERR(iwm, "Couldn't allocate bss\n"); | 799 | IWM_ERR(iwm, "Couldn't allocate bss\n"); |
800 | return -ENOMEM; | 800 | return -ENOMEM; |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index bc5726dd5fe4..7ba3052b0708 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -65,6 +65,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
65 | /* Sitecom */ | 65 | /* Sitecom */ |
66 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, | 66 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, |
67 | {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, | 67 | {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, |
68 | {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B}, | ||
68 | /* Sphairon Access Systems GmbH */ | 69 | /* Sphairon Access Systems GmbH */ |
69 | {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, | 70 | {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, |
70 | /* Dick Smith Electronics */ | 71 | /* Dick Smith Electronics */ |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 8e952fdab764..cb2fd01eddae 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -720,12 +720,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func) | |||
720 | -ret_val); | 720 | -ret_val); |
721 | goto acpiphp_bus_add_out; | 721 | goto acpiphp_bus_add_out; |
722 | } | 722 | } |
723 | /* | ||
724 | * try to start anyway. We could have failed to add | ||
725 | * simply because this bus had previously been added | ||
726 | * on another add. Don't bother with the return value | ||
727 | * we just keep going. | ||
728 | */ | ||
729 | ret_val = acpi_bus_start(device); | 723 | ret_val = acpi_bus_start(device); |
730 | 724 | ||
731 | acpiphp_bus_add_out: | 725 | acpiphp_bus_add_out: |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c74694345b6e..d58b94030ef3 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -338,6 +338,23 @@ static void __devinit quirk_s3_64M(struct pci_dev *dev) | |||
338 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); | 338 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_868, quirk_s3_64M); |
339 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); | 339 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_968, quirk_s3_64M); |
340 | 340 | ||
341 | /* | ||
342 | * Some CS5536 BIOSes (for example, the Soekris NET5501 board w/ comBIOS | ||
343 | * ver. 1.33 20070103) don't set the correct ISA PCI region header info. | ||
344 | * BAR0 should be 8 bytes; instead, it may be set to something like 8k | ||
345 | * (which conflicts w/ BAR1's memory range). | ||
346 | */ | ||
347 | static void __devinit quirk_cs5536_vsa(struct pci_dev *dev) | ||
348 | { | ||
349 | if (pci_resource_len(dev, 0) != 8) { | ||
350 | struct resource *res = &dev->resource[0]; | ||
351 | res->end = res->start + 8 - 1; | ||
352 | dev_info(&dev->dev, "CS5536 ISA bridge bug detected " | ||
353 | "(incorrect header); workaround applied.\n"); | ||
354 | } | ||
355 | } | ||
356 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa); | ||
357 | |||
341 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | 358 | static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, |
342 | unsigned size, int nr, const char *name) | 359 | unsigned size, int nr, const char *name) |
343 | { | 360 | { |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 07d14dfdf0b4..226b3e93498c 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -934,7 +934,7 @@ static int __devinit acer_backlight_init(struct device *dev) | |||
934 | acer_backlight_device = bd; | 934 | acer_backlight_device = bd; |
935 | 935 | ||
936 | bd->props.power = FB_BLANK_UNBLANK; | 936 | bd->props.power = FB_BLANK_UNBLANK; |
937 | bd->props.brightness = max_brightness; | 937 | bd->props.brightness = read_brightness(bd); |
938 | bd->props.max_brightness = max_brightness; | 938 | bd->props.max_brightness = max_brightness; |
939 | backlight_update_status(bd); | 939 | backlight_update_status(bd); |
940 | return 0; | 940 | return 0; |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e67e4feb35cb..eb603f1d55ca 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -5771,7 +5771,7 @@ static void thermal_exit(void) | |||
5771 | case TPACPI_THERMAL_ACPI_TMP07: | 5771 | case TPACPI_THERMAL_ACPI_TMP07: |
5772 | case TPACPI_THERMAL_ACPI_UPDT: | 5772 | case TPACPI_THERMAL_ACPI_UPDT: |
5773 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, | 5773 | sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, |
5774 | &thermal_temp_input16_group); | 5774 | &thermal_temp_input8_group); |
5775 | break; | 5775 | break; |
5776 | case TPACPI_THERMAL_NONE: | 5776 | case TPACPI_THERMAL_NONE: |
5777 | default: | 5777 | default: |
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index fa39e759a275..6ea3cb5837c7 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
@@ -175,8 +175,14 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev) | |||
175 | dev_err(&dev->dev, "Do not pass platform_data through " | 175 | dev_err(&dev->dev, "Do not pass platform_data through " |
176 | "wm97xx_bat_set_pdata!\n"); | 176 | "wm97xx_bat_set_pdata!\n"); |
177 | return -EINVAL; | 177 | return -EINVAL; |
178 | } else | 178 | } |
179 | pdata = wmdata->batt_pdata; | 179 | |
180 | if (!wmdata) { | ||
181 | dev_err(&dev->dev, "No platform data supplied\n"); | ||
182 | return -EINVAL; | ||
183 | } | ||
184 | |||
185 | pdata = wmdata->batt_pdata; | ||
180 | 186 | ||
181 | if (dev->id != -1) | 187 | if (dev->id != -1) |
182 | return -EINVAL; | 188 | return -EINVAL; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 686ef270ecf7..b60a4c9f8f16 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -661,7 +661,7 @@ static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state) | |||
661 | static void print_constraints(struct regulator_dev *rdev) | 661 | static void print_constraints(struct regulator_dev *rdev) |
662 | { | 662 | { |
663 | struct regulation_constraints *constraints = rdev->constraints; | 663 | struct regulation_constraints *constraints = rdev->constraints; |
664 | char buf[80]; | 664 | char buf[80] = ""; |
665 | int count = 0; | 665 | int count = 0; |
666 | int ret; | 666 | int ret; |
667 | 667 | ||
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 76d08c282f9c..4f33a0f4a179 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
@@ -183,7 +183,7 @@ static int lp3971_ldo_set_voltage(struct regulator_dev *dev, | |||
183 | if (vol_map[val] >= min_vol) | 183 | if (vol_map[val] >= min_vol) |
184 | break; | 184 | break; |
185 | 185 | ||
186 | if (vol_map[val] > max_vol) | 186 | if (val > LDO_VOL_MAX_IDX || vol_map[val] > max_vol) |
187 | return -EINVAL; | 187 | return -EINVAL; |
188 | 188 | ||
189 | return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), | 189 | return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo), |
@@ -272,7 +272,7 @@ static int lp3971_dcdc_set_voltage(struct regulator_dev *dev, | |||
272 | if (vol_map[val] >= min_vol) | 272 | if (vol_map[val] >= min_vol) |
273 | break; | 273 | break; |
274 | 274 | ||
275 | if (vol_map[val] > max_vol) | 275 | if (val > BUCK_TARGET_VOL_MAX_IDX || vol_map[val] > max_vol) |
276 | return -EINVAL; | 276 | return -EINVAL; |
277 | 277 | ||
278 | ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck), | 278 | ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck), |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 999fe80c4051..62b654af9237 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -531,7 +531,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q) | |||
531 | qdio_siga_sync_q(q); | 531 | qdio_siga_sync_q(q); |
532 | get_buf_state(q, q->first_to_check, &state, 0); | 532 | get_buf_state(q, q->first_to_check, &state, 0); |
533 | 533 | ||
534 | if (state == SLSB_P_INPUT_PRIMED) | 534 | if (state == SLSB_P_INPUT_PRIMED || state == SLSB_P_INPUT_ERROR) |
535 | /* more work coming */ | 535 | /* more work coming */ |
536 | return 0; | 536 | return 0; |
537 | 537 | ||
@@ -960,6 +960,8 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
960 | qdio_handle_activate_check(cdev, intparm, cstat, | 960 | qdio_handle_activate_check(cdev, intparm, cstat, |
961 | dstat); | 961 | dstat); |
962 | break; | 962 | break; |
963 | case QDIO_IRQ_STATE_STOPPED: | ||
964 | break; | ||
963 | default: | 965 | default: |
964 | WARN_ON(1); | 966 | WARN_ON(1); |
965 | } | 967 | } |
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 0f7b493fb105..271399f62f1b 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c | |||
@@ -671,12 +671,11 @@ static void zfcp_fc_ct_els_job_handler(void *data) | |||
671 | { | 671 | { |
672 | struct fc_bsg_job *job = data; | 672 | struct fc_bsg_job *job = data; |
673 | struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data; | 673 | struct zfcp_fsf_ct_els *zfcp_ct_els = job->dd_data; |
674 | int status = zfcp_ct_els->status; | 674 | struct fc_bsg_reply *jr = job->reply; |
675 | int reply_status; | ||
676 | 675 | ||
677 | reply_status = status ? FC_CTELS_STATUS_REJECT : FC_CTELS_STATUS_OK; | 676 | jr->reply_payload_rcv_len = job->reply_payload.payload_len; |
678 | job->reply->reply_data.ctels_reply.status = reply_status; | 677 | jr->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; |
679 | job->reply->reply_payload_rcv_len = job->reply_payload.payload_len; | 678 | jr->result = zfcp_ct_els->status ? -EIO : 0; |
680 | job->job_done(job); | 679 | job->job_done(job); |
681 | } | 680 | } |
682 | 681 | ||
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 477542602284..9e71ac611146 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c | |||
@@ -2516,7 +2516,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt) | |||
2516 | if (info->scsi.phase == PHASE_IDLE) | 2516 | if (info->scsi.phase == PHASE_IDLE) |
2517 | fas216_kick(info); | 2517 | fas216_kick(info); |
2518 | 2518 | ||
2519 | mod_timer(&info->eh_timer, 30 * HZ); | 2519 | mod_timer(&info->eh_timer, jiffies + 30 * HZ); |
2520 | spin_unlock_irqrestore(&info->host_lock, flags); | 2520 | spin_unlock_irqrestore(&info->host_lock, flags); |
2521 | 2521 | ||
2522 | /* | 2522 | /* |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 10be9f36a4cc..2f47ae7cce91 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -2009,6 +2009,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) | |||
2009 | fcoe_interface_cleanup(fcoe); | 2009 | fcoe_interface_cleanup(fcoe); |
2010 | rtnl_unlock(); | 2010 | rtnl_unlock(); |
2011 | fcoe_if_destroy(fcoe->ctlr.lp); | 2011 | fcoe_if_destroy(fcoe->ctlr.lp); |
2012 | module_put(THIS_MODULE); | ||
2013 | |||
2012 | out_putdev: | 2014 | out_putdev: |
2013 | dev_put(netdev); | 2015 | dev_put(netdev); |
2014 | out_nodev: | 2016 | out_nodev: |
@@ -2059,6 +2061,11 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2059 | } | 2061 | } |
2060 | #endif | 2062 | #endif |
2061 | 2063 | ||
2064 | if (!try_module_get(THIS_MODULE)) { | ||
2065 | rc = -EINVAL; | ||
2066 | goto out_nomod; | ||
2067 | } | ||
2068 | |||
2062 | rtnl_lock(); | 2069 | rtnl_lock(); |
2063 | netdev = fcoe_if_to_netdev(buffer); | 2070 | netdev = fcoe_if_to_netdev(buffer); |
2064 | if (!netdev) { | 2071 | if (!netdev) { |
@@ -2099,17 +2106,24 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) | |||
2099 | if (!fcoe_link_ok(lport)) | 2106 | if (!fcoe_link_ok(lport)) |
2100 | fcoe_ctlr_link_up(&fcoe->ctlr); | 2107 | fcoe_ctlr_link_up(&fcoe->ctlr); |
2101 | 2108 | ||
2102 | rc = 0; | ||
2103 | out_free: | ||
2104 | /* | 2109 | /* |
2105 | * Release from init in fcoe_interface_create(), on success lport | 2110 | * Release from init in fcoe_interface_create(), on success lport |
2106 | * should be holding a reference taken in fcoe_if_create(). | 2111 | * should be holding a reference taken in fcoe_if_create(). |
2107 | */ | 2112 | */ |
2108 | fcoe_interface_put(fcoe); | 2113 | fcoe_interface_put(fcoe); |
2114 | dev_put(netdev); | ||
2115 | rtnl_unlock(); | ||
2116 | mutex_unlock(&fcoe_config_mutex); | ||
2117 | |||
2118 | return 0; | ||
2119 | out_free: | ||
2120 | fcoe_interface_put(fcoe); | ||
2109 | out_putdev: | 2121 | out_putdev: |
2110 | dev_put(netdev); | 2122 | dev_put(netdev); |
2111 | out_nodev: | 2123 | out_nodev: |
2112 | rtnl_unlock(); | 2124 | rtnl_unlock(); |
2125 | module_put(THIS_MODULE); | ||
2126 | out_nomod: | ||
2113 | mutex_unlock(&fcoe_config_mutex); | 2127 | mutex_unlock(&fcoe_config_mutex); |
2114 | return rc; | 2128 | return rc; |
2115 | } | 2129 | } |
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c index 9823291395ad..511cb6b371ee 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c | |||
@@ -1187,7 +1187,7 @@ static void fcoe_ctlr_timeout(unsigned long arg) | |||
1187 | next_timer = fip->ctlr_ka_time; | 1187 | next_timer = fip->ctlr_ka_time; |
1188 | 1188 | ||
1189 | if (time_after_eq(jiffies, fip->port_ka_time)) { | 1189 | if (time_after_eq(jiffies, fip->port_ka_time)) { |
1190 | fip->port_ka_time += jiffies + | 1190 | fip->port_ka_time = jiffies + |
1191 | msecs_to_jiffies(FIP_VN_KA_PERIOD); | 1191 | msecs_to_jiffies(FIP_VN_KA_PERIOD); |
1192 | fip->send_port_ka = 1; | 1192 | fip->send_port_ka = 1; |
1193 | } | 1193 | } |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 19d711cb938c..7f4364770e4a 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -1890,7 +1890,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1890 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); | 1890 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); |
1891 | sp->cnt++; | 1891 | sp->cnt++; |
1892 | 1892 | ||
1893 | if (ep->xid <= lport->lro_xid) | 1893 | if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) |
1894 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); | 1894 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); |
1895 | 1895 | ||
1896 | if (unlikely(lport->tt.frame_send(lport, fp))) | 1896 | if (unlikely(lport->tt.frame_send(lport, fp))) |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 881d5dfe8c74..6fde2fabfd9b 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -298,9 +298,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) | |||
298 | { | 298 | { |
299 | struct fc_lport *lport; | 299 | struct fc_lport *lport; |
300 | 300 | ||
301 | if (!fsp) | ||
302 | return; | ||
303 | |||
304 | lport = fsp->lp; | 301 | lport = fsp->lp; |
305 | if ((fsp->req_flags & FC_SRB_READ) && | 302 | if ((fsp->req_flags & FC_SRB_READ) && |
306 | (lport->lro_enabled) && (lport->tt.ddp_setup)) { | 303 | (lport->lro_enabled) && (lport->tt.ddp_setup)) { |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 0b165024a219..7ec8ce75007c 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -1800,7 +1800,8 @@ int fc_lport_bsg_request(struct fc_bsg_job *job) | |||
1800 | u32 did; | 1800 | u32 did; |
1801 | 1801 | ||
1802 | job->reply->reply_payload_rcv_len = 0; | 1802 | job->reply->reply_payload_rcv_len = 0; |
1803 | rsp->resid_len = job->reply_payload.payload_len; | 1803 | if (rsp) |
1804 | rsp->resid_len = job->reply_payload.payload_len; | ||
1804 | 1805 | ||
1805 | mutex_lock(&lport->lp_mutex); | 1806 | mutex_lock(&lport->lp_mutex); |
1806 | 1807 | ||
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 02300523b234..97923bb07765 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -623,7 +623,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, | |||
623 | 623 | ||
624 | tov = ntohl(plp->fl_csp.sp_e_d_tov); | 624 | tov = ntohl(plp->fl_csp.sp_e_d_tov); |
625 | if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) | 625 | if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) |
626 | tov /= 1000; | 626 | tov /= 1000000; |
627 | if (tov > rdata->e_d_tov) | 627 | if (tov > rdata->e_d_tov) |
628 | rdata->e_d_tov = tov; | 628 | rdata->e_d_tov = tov; |
629 | csp_seq = ntohs(plp->fl_csp.sp_tot_seq); | 629 | csp_seq = ntohs(plp->fl_csp.sp_tot_seq); |
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index db6856c138fc..4ad87fd74ddd 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c | |||
@@ -992,12 +992,10 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task) | |||
992 | if (r2t == NULL) { | 992 | if (r2t == NULL) { |
993 | if (kfifo_out(&tcp_task->r2tqueue, | 993 | if (kfifo_out(&tcp_task->r2tqueue, |
994 | (void *)&tcp_task->r2t, sizeof(void *)) != | 994 | (void *)&tcp_task->r2t, sizeof(void *)) != |
995 | sizeof(void *)) { | 995 | sizeof(void *)) |
996 | WARN_ONCE(1, "unexpected fifo state"); | ||
997 | r2t = NULL; | 996 | r2t = NULL; |
998 | } | 997 | else |
999 | 998 | r2t = tcp_task->r2t; | |
1000 | r2t = tcp_task->r2t; | ||
1001 | } | 999 | } |
1002 | spin_unlock_bh(&session->lock); | 1000 | spin_unlock_bh(&session->lock); |
1003 | } | 1001 | } |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 708ea3157b60..d9b8ca5116bc 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -3781,6 +3781,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) | |||
3781 | compat_alloc_user_space(sizeof(struct megasas_iocpacket)); | 3781 | compat_alloc_user_space(sizeof(struct megasas_iocpacket)); |
3782 | int i; | 3782 | int i; |
3783 | int error = 0; | 3783 | int error = 0; |
3784 | compat_uptr_t ptr; | ||
3784 | 3785 | ||
3785 | if (clear_user(ioc, sizeof(*ioc))) | 3786 | if (clear_user(ioc, sizeof(*ioc))) |
3786 | return -EFAULT; | 3787 | return -EFAULT; |
@@ -3793,9 +3794,22 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg) | |||
3793 | copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) | 3794 | copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) |
3794 | return -EFAULT; | 3795 | return -EFAULT; |
3795 | 3796 | ||
3796 | for (i = 0; i < MAX_IOCTL_SGE; i++) { | 3797 | /* |
3797 | compat_uptr_t ptr; | 3798 | * The sense_ptr is used in megasas_mgmt_fw_ioctl only when |
3799 | * sense_len is not null, so prepare the 64bit value under | ||
3800 | * the same condition. | ||
3801 | */ | ||
3802 | if (ioc->sense_len) { | ||
3803 | void __user **sense_ioc_ptr = | ||
3804 | (void __user **)(ioc->frame.raw + ioc->sense_off); | ||
3805 | compat_uptr_t *sense_cioc_ptr = | ||
3806 | (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off); | ||
3807 | if (get_user(ptr, sense_cioc_ptr) || | ||
3808 | put_user(compat_ptr(ptr), sense_ioc_ptr)) | ||
3809 | return -EFAULT; | ||
3810 | } | ||
3798 | 3811 | ||
3812 | for (i = 0; i < MAX_IOCTL_SGE; i++) { | ||
3799 | if (get_user(ptr, &cioc->sgl[i].iov_base) || | 3813 | if (get_user(ptr, &cioc->sgl[i].iov_base) || |
3800 | put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || | 3814 | put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || |
3801 | copy_in_user(&ioc->sgl[i].iov_len, | 3815 | copy_in_user(&ioc->sgl[i].iov_len, |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index f61fb8d01330..8bc6f53691e9 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -453,6 +453,5 @@ extern void qla24xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | |||
453 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); | 453 | extern void qla25xx_wrt_req_reg(struct qla_hw_data *, uint16_t, uint16_t); |
454 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 454 | extern void qla25xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
455 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); | 455 | extern void qla24xx_wrt_rsp_reg(struct qla_hw_data *, uint16_t, uint16_t); |
456 | extern struct scsi_qla_host * qla25xx_get_host(struct rsp_que *); | ||
457 | 456 | ||
458 | #endif /* _QLA_GBL_H */ | 457 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ffd0efdff40e..6fc63b98818c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1917,6 +1917,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1917 | struct rsp_que *rsp; | 1917 | struct rsp_que *rsp; |
1918 | struct device_reg_24xx __iomem *reg; | 1918 | struct device_reg_24xx __iomem *reg; |
1919 | struct scsi_qla_host *vha; | 1919 | struct scsi_qla_host *vha; |
1920 | unsigned long flags; | ||
1920 | 1921 | ||
1921 | rsp = (struct rsp_que *) dev_id; | 1922 | rsp = (struct rsp_que *) dev_id; |
1922 | if (!rsp) { | 1923 | if (!rsp) { |
@@ -1927,15 +1928,15 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1927 | ha = rsp->hw; | 1928 | ha = rsp->hw; |
1928 | reg = &ha->iobase->isp24; | 1929 | reg = &ha->iobase->isp24; |
1929 | 1930 | ||
1930 | spin_lock_irq(&ha->hardware_lock); | 1931 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1931 | 1932 | ||
1932 | vha = qla25xx_get_host(rsp); | 1933 | vha = pci_get_drvdata(ha->pdev); |
1933 | qla24xx_process_response_queue(vha, rsp); | 1934 | qla24xx_process_response_queue(vha, rsp); |
1934 | if (!ha->flags.disable_msix_handshake) { | 1935 | if (!ha->flags.disable_msix_handshake) { |
1935 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1936 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1936 | RD_REG_DWORD_RELAXED(®->hccr); | 1937 | RD_REG_DWORD_RELAXED(®->hccr); |
1937 | } | 1938 | } |
1938 | spin_unlock_irq(&ha->hardware_lock); | 1939 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1939 | 1940 | ||
1940 | return IRQ_HANDLED; | 1941 | return IRQ_HANDLED; |
1941 | } | 1942 | } |
@@ -1946,6 +1947,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1946 | struct qla_hw_data *ha; | 1947 | struct qla_hw_data *ha; |
1947 | struct rsp_que *rsp; | 1948 | struct rsp_que *rsp; |
1948 | struct device_reg_24xx __iomem *reg; | 1949 | struct device_reg_24xx __iomem *reg; |
1950 | unsigned long flags; | ||
1949 | 1951 | ||
1950 | rsp = (struct rsp_que *) dev_id; | 1952 | rsp = (struct rsp_que *) dev_id; |
1951 | if (!rsp) { | 1953 | if (!rsp) { |
@@ -1958,10 +1960,10 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1958 | /* Clear the interrupt, if enabled, for this response queue */ | 1960 | /* Clear the interrupt, if enabled, for this response queue */ |
1959 | if (rsp->options & ~BIT_6) { | 1961 | if (rsp->options & ~BIT_6) { |
1960 | reg = &ha->iobase->isp24; | 1962 | reg = &ha->iobase->isp24; |
1961 | spin_lock_irq(&ha->hardware_lock); | 1963 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1962 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1964 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1963 | RD_REG_DWORD_RELAXED(®->hccr); | 1965 | RD_REG_DWORD_RELAXED(®->hccr); |
1964 | spin_unlock_irq(&ha->hardware_lock); | 1966 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1965 | } | 1967 | } |
1966 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); | 1968 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); |
1967 | 1969 | ||
@@ -1979,6 +1981,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1979 | uint32_t stat; | 1981 | uint32_t stat; |
1980 | uint32_t hccr; | 1982 | uint32_t hccr; |
1981 | uint16_t mb[4]; | 1983 | uint16_t mb[4]; |
1984 | unsigned long flags; | ||
1982 | 1985 | ||
1983 | rsp = (struct rsp_que *) dev_id; | 1986 | rsp = (struct rsp_que *) dev_id; |
1984 | if (!rsp) { | 1987 | if (!rsp) { |
@@ -1990,7 +1993,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1990 | reg = &ha->iobase->isp24; | 1993 | reg = &ha->iobase->isp24; |
1991 | status = 0; | 1994 | status = 0; |
1992 | 1995 | ||
1993 | spin_lock_irq(&ha->hardware_lock); | 1996 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1994 | vha = pci_get_drvdata(ha->pdev); | 1997 | vha = pci_get_drvdata(ha->pdev); |
1995 | do { | 1998 | do { |
1996 | stat = RD_REG_DWORD(®->host_status); | 1999 | stat = RD_REG_DWORD(®->host_status); |
@@ -2039,7 +2042,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
2039 | } | 2042 | } |
2040 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 2043 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
2041 | } while (0); | 2044 | } while (0); |
2042 | spin_unlock_irq(&ha->hardware_lock); | 2045 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2043 | 2046 | ||
2044 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 2047 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
2045 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 2048 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -2277,30 +2280,3 @@ int qla25xx_request_irq(struct rsp_que *rsp) | |||
2277 | msix->rsp = rsp; | 2280 | msix->rsp = rsp; |
2278 | return ret; | 2281 | return ret; |
2279 | } | 2282 | } |
2280 | |||
2281 | struct scsi_qla_host * | ||
2282 | qla25xx_get_host(struct rsp_que *rsp) | ||
2283 | { | ||
2284 | srb_t *sp; | ||
2285 | struct qla_hw_data *ha = rsp->hw; | ||
2286 | struct scsi_qla_host *vha = NULL; | ||
2287 | struct sts_entry_24xx *pkt; | ||
2288 | struct req_que *req; | ||
2289 | uint16_t que; | ||
2290 | uint32_t handle; | ||
2291 | |||
2292 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2293 | que = MSW(pkt->handle); | ||
2294 | handle = (uint32_t) LSW(pkt->handle); | ||
2295 | req = ha->req_q_map[que]; | ||
2296 | if (handle < MAX_OUTSTANDING_COMMANDS) { | ||
2297 | sp = req->outstanding_cmds[handle]; | ||
2298 | if (sp) | ||
2299 | return sp->fcport->vha; | ||
2300 | else | ||
2301 | goto base_que; | ||
2302 | } | ||
2303 | base_que: | ||
2304 | vha = pci_get_drvdata(ha->pdev); | ||
2305 | return vha; | ||
2306 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index b901aa267e7d..ff17dee28613 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -636,13 +636,15 @@ failed: | |||
636 | 636 | ||
637 | static void qla_do_work(struct work_struct *work) | 637 | static void qla_do_work(struct work_struct *work) |
638 | { | 638 | { |
639 | unsigned long flags; | ||
639 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); | 640 | struct rsp_que *rsp = container_of(work, struct rsp_que, q_work); |
640 | struct scsi_qla_host *vha; | 641 | struct scsi_qla_host *vha; |
642 | struct qla_hw_data *ha = rsp->hw; | ||
641 | 643 | ||
642 | spin_lock_irq(&rsp->hw->hardware_lock); | 644 | spin_lock_irqsave(&rsp->hw->hardware_lock, flags); |
643 | vha = qla25xx_get_host(rsp); | 645 | vha = pci_get_drvdata(ha->pdev); |
644 | qla24xx_process_response_queue(vha, rsp); | 646 | qla24xx_process_response_queue(vha, rsp); |
645 | spin_unlock_irq(&rsp->hw->hardware_lock); | 647 | spin_unlock_irqrestore(&rsp->hw->hardware_lock, flags); |
646 | } | 648 | } |
647 | 649 | ||
648 | /* create response queue */ | 650 | /* create response queue */ |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index c3e37c8e7e26..e9b15c3746fa 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -83,6 +83,9 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ | |||
83 | 83 | ||
84 | #define PASS_LIMIT 256 | 84 | #define PASS_LIMIT 256 |
85 | 85 | ||
86 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
87 | |||
88 | |||
86 | /* | 89 | /* |
87 | * We default to IRQ0 for the "no irq" hack. Some | 90 | * We default to IRQ0 for the "no irq" hack. Some |
88 | * machine types want others as well - they're free | 91 | * machine types want others as well - they're free |
@@ -1792,7 +1795,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1792 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; | 1795 | up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; |
1793 | spin_unlock_irqrestore(&up->port.lock, flags); | 1796 | spin_unlock_irqrestore(&up->port.lock, flags); |
1794 | 1797 | ||
1795 | return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 1798 | return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0; |
1796 | } | 1799 | } |
1797 | 1800 | ||
1798 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1801 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
@@ -1850,8 +1853,6 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state) | |||
1850 | spin_unlock_irqrestore(&up->port.lock, flags); | 1853 | spin_unlock_irqrestore(&up->port.lock, flags); |
1851 | } | 1854 | } |
1852 | 1855 | ||
1853 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
1854 | |||
1855 | /* | 1856 | /* |
1856 | * Wait for transmitter & holding register to empty | 1857 | * Wait for transmitter & holding register to empty |
1857 | */ | 1858 | */ |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 5681ebed9c65..03dfd27c4bfb 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -494,8 +494,7 @@ static int ssb_devices_register(struct ssb_bus *bus) | |||
494 | #endif | 494 | #endif |
495 | break; | 495 | break; |
496 | case SSB_BUSTYPE_SDIO: | 496 | case SSB_BUSTYPE_SDIO: |
497 | #ifdef CONFIG_SSB_SDIO | 497 | #ifdef CONFIG_SSB_SDIOHOST |
498 | sdev->irq = bus->host_sdio->dev.irq; | ||
499 | dev->parent = &bus->host_sdio->dev; | 498 | dev->parent = &bus->host_sdio->dev; |
500 | #endif | 499 | #endif |
501 | break; | 500 | break; |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6e8bcdfd23b4..a678186f218f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1312,9 +1312,9 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1312 | void __user *addr = as->userurb; | 1312 | void __user *addr = as->userurb; |
1313 | unsigned int i; | 1313 | unsigned int i; |
1314 | 1314 | ||
1315 | if (as->userbuffer) | 1315 | if (as->userbuffer && urb->actual_length) |
1316 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1316 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1317 | urb->transfer_buffer_length)) | 1317 | urb->actual_length)) |
1318 | goto err_out; | 1318 | goto err_out; |
1319 | if (put_user(as->status, &userurb->status)) | 1319 | if (put_user(as->status, &userurb->status)) |
1320 | goto err_out; | 1320 | goto err_out; |
@@ -1334,14 +1334,11 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1334 | } | 1334 | } |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | free_async(as); | ||
1338 | |||
1339 | if (put_user(addr, (void __user * __user *)arg)) | 1337 | if (put_user(addr, (void __user * __user *)arg)) |
1340 | return -EFAULT; | 1338 | return -EFAULT; |
1341 | return 0; | 1339 | return 0; |
1342 | 1340 | ||
1343 | err_out: | 1341 | err_out: |
1344 | free_async(as); | ||
1345 | return -EFAULT; | 1342 | return -EFAULT; |
1346 | } | 1343 | } |
1347 | 1344 | ||
@@ -1371,8 +1368,11 @@ static struct async *reap_as(struct dev_state *ps) | |||
1371 | static int proc_reapurb(struct dev_state *ps, void __user *arg) | 1368 | static int proc_reapurb(struct dev_state *ps, void __user *arg) |
1372 | { | 1369 | { |
1373 | struct async *as = reap_as(ps); | 1370 | struct async *as = reap_as(ps); |
1374 | if (as) | 1371 | if (as) { |
1375 | return processcompl(as, (void __user * __user *)arg); | 1372 | int retval = processcompl(as, (void __user * __user *)arg); |
1373 | free_async(as); | ||
1374 | return retval; | ||
1375 | } | ||
1376 | if (signal_pending(current)) | 1376 | if (signal_pending(current)) |
1377 | return -EINTR; | 1377 | return -EINTR; |
1378 | return -EIO; | 1378 | return -EIO; |
@@ -1380,11 +1380,16 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg) | |||
1380 | 1380 | ||
1381 | static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) | 1381 | static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) |
1382 | { | 1382 | { |
1383 | int retval; | ||
1383 | struct async *as; | 1384 | struct async *as; |
1384 | 1385 | ||
1385 | if (!(as = async_getcompleted(ps))) | 1386 | as = async_getcompleted(ps); |
1386 | return -EAGAIN; | 1387 | retval = -EAGAIN; |
1387 | return processcompl(as, (void __user * __user *)arg); | 1388 | if (as) { |
1389 | retval = processcompl(as, (void __user * __user *)arg); | ||
1390 | free_async(as); | ||
1391 | } | ||
1392 | return retval; | ||
1388 | } | 1393 | } |
1389 | 1394 | ||
1390 | #ifdef CONFIG_COMPAT | 1395 | #ifdef CONFIG_COMPAT |
@@ -1475,9 +1480,9 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1475 | void __user *addr = as->userurb; | 1480 | void __user *addr = as->userurb; |
1476 | unsigned int i; | 1481 | unsigned int i; |
1477 | 1482 | ||
1478 | if (as->userbuffer) | 1483 | if (as->userbuffer && urb->actual_length) |
1479 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1484 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1480 | urb->transfer_buffer_length)) | 1485 | urb->actual_length)) |
1481 | return -EFAULT; | 1486 | return -EFAULT; |
1482 | if (put_user(as->status, &userurb->status)) | 1487 | if (put_user(as->status, &userurb->status)) |
1483 | return -EFAULT; | 1488 | return -EFAULT; |
@@ -1497,7 +1502,6 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1497 | } | 1502 | } |
1498 | } | 1503 | } |
1499 | 1504 | ||
1500 | free_async(as); | ||
1501 | if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) | 1505 | if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) |
1502 | return -EFAULT; | 1506 | return -EFAULT; |
1503 | return 0; | 1507 | return 0; |
@@ -1506,8 +1510,11 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1506 | static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) | 1510 | static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) |
1507 | { | 1511 | { |
1508 | struct async *as = reap_as(ps); | 1512 | struct async *as = reap_as(ps); |
1509 | if (as) | 1513 | if (as) { |
1510 | return processcompl_compat(as, (void __user * __user *)arg); | 1514 | int retval = processcompl_compat(as, (void __user * __user *)arg); |
1515 | free_async(as); | ||
1516 | return retval; | ||
1517 | } | ||
1511 | if (signal_pending(current)) | 1518 | if (signal_pending(current)) |
1512 | return -EINTR; | 1519 | return -EINTR; |
1513 | return -EIO; | 1520 | return -EIO; |
@@ -1515,11 +1522,16 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) | |||
1515 | 1522 | ||
1516 | static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) | 1523 | static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) |
1517 | { | 1524 | { |
1525 | int retval; | ||
1518 | struct async *as; | 1526 | struct async *as; |
1519 | 1527 | ||
1520 | if (!(as = async_getcompleted(ps))) | 1528 | retval = -EAGAIN; |
1521 | return -EAGAIN; | 1529 | as = async_getcompleted(ps); |
1522 | return processcompl_compat(as, (void __user * __user *)arg); | 1530 | if (as) { |
1531 | retval = processcompl_compat(as, (void __user * __user *)arg); | ||
1532 | free_async(as); | ||
1533 | } | ||
1534 | return retval; | ||
1523 | } | 1535 | } |
1524 | 1536 | ||
1525 | 1537 | ||
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index 0a577d5694fd..d4f0db58a8ad 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c | |||
@@ -358,7 +358,7 @@ done: | |||
358 | * b15: bmType (0 == data) | 358 | * b15: bmType (0 == data) |
359 | */ | 359 | */ |
360 | len = skb->len; | 360 | len = skb->len; |
361 | put_unaligned_le16((len & 0x3FFF) | BIT(14), skb_push(skb, 2)); | 361 | put_unaligned_le16(len & 0x3FFF, skb_push(skb, 2)); |
362 | 362 | ||
363 | /* add a zero-length EEM packet, if needed */ | 363 | /* add a zero-length EEM packet, if needed */ |
364 | if (padlen) | 364 | if (padlen) |
@@ -464,7 +464,6 @@ static int eem_unwrap(struct gether *port, | |||
464 | } | 464 | } |
465 | 465 | ||
466 | /* validate CRC */ | 466 | /* validate CRC */ |
467 | crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN); | ||
468 | if (header & BIT(14)) { | 467 | if (header & BIT(14)) { |
469 | crc = get_unaligned_le32(skb->data + len | 468 | crc = get_unaligned_le32(skb->data + len |
470 | - ETH_FCS_LEN); | 469 | - ETH_FCS_LEN); |
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 429560100b10..76496f5d272c 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #if defined USB_ETH_RNDIS | 29 | #if defined USB_ETH_RNDIS |
30 | # undef USB_ETH_RNDIS | 30 | # undef USB_ETH_RNDIS |
31 | #endif | 31 | #endif |
32 | #ifdef CONFIG_USB_ETH_RNDIS | 32 | #ifdef CONFIG_USB_G_MULTI_RNDIS |
33 | # define USB_ETH_RNDIS y | 33 | # define USB_ETH_RNDIS y |
34 | #endif | 34 | #endif |
35 | 35 | ||
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index e220fb8091a3..8b45145b9136 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/err.h> | ||
29 | 30 | ||
30 | #include <linux/usb/ch9.h> | 31 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb/gadget.h> | 32 | #include <linux/usb/gadget.h> |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 4b5dbd0127f5..5fc80a104150 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -2582,6 +2582,7 @@ err: | |||
2582 | hsotg->gadget.dev.driver = NULL; | 2582 | hsotg->gadget.dev.driver = NULL; |
2583 | return ret; | 2583 | return ret; |
2584 | } | 2584 | } |
2585 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
2585 | 2586 | ||
2586 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | 2587 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) |
2587 | { | 2588 | { |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index c75d9270c752..19372673bf09 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -196,7 +196,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
196 | if (hostpc_reg) { | 196 | if (hostpc_reg) { |
197 | u32 t3; | 197 | u32 t3; |
198 | 198 | ||
199 | spin_unlock_irq(&ehci->lock); | ||
199 | msleep(5);/* 5ms for HCD enter low pwr mode */ | 200 | msleep(5);/* 5ms for HCD enter low pwr mode */ |
201 | spin_lock_irq(&ehci->lock); | ||
200 | t3 = ehci_readl(ehci, hostpc_reg); | 202 | t3 = ehci_readl(ehci, hostpc_reg); |
201 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); | 203 | ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); |
202 | t3 = ehci_readl(ehci, hostpc_reg); | 204 | t3 = ehci_readl(ehci, hostpc_reg); |
@@ -904,17 +906,18 @@ static int ehci_hub_control ( | |||
904 | if ((temp & PORT_PE) == 0 | 906 | if ((temp & PORT_PE) == 0 |
905 | || (temp & PORT_RESET) != 0) | 907 | || (temp & PORT_RESET) != 0) |
906 | goto error; | 908 | goto error; |
907 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | 909 | |
908 | /* After above check the port must be connected. | 910 | /* After above check the port must be connected. |
909 | * Set appropriate bit thus could put phy into low power | 911 | * Set appropriate bit thus could put phy into low power |
910 | * mode if we have hostpc feature | 912 | * mode if we have hostpc feature |
911 | */ | 913 | */ |
914 | temp &= ~PORT_WKCONN_E; | ||
915 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
916 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
912 | if (hostpc_reg) { | 917 | if (hostpc_reg) { |
913 | temp &= ~PORT_WKCONN_E; | 918 | spin_unlock_irqrestore(&ehci->lock, flags); |
914 | temp |= (PORT_WKDISC_E | PORT_WKOC_E); | ||
915 | ehci_writel(ehci, temp | PORT_SUSPEND, | ||
916 | status_reg); | ||
917 | msleep(5);/* 5ms for HCD enter low pwr mode */ | 919 | msleep(5);/* 5ms for HCD enter low pwr mode */ |
920 | spin_lock_irqsave(&ehci->lock, flags); | ||
918 | temp1 = ehci_readl(ehci, hostpc_reg); | 921 | temp1 = ehci_readl(ehci, hostpc_reg); |
919 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, | 922 | ehci_writel(ehci, temp1 | HOSTPC_PHCD, |
920 | hostpc_reg); | 923 | hostpc_reg); |
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index d224ab467a40..e1232890c78b 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c | |||
@@ -105,7 +105,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
105 | if (ep->td_base) | 105 | if (ep->td_base) |
106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); | 106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); |
107 | 107 | ||
108 | if (ep->conf_frame_Q) { | 108 | if (kfifo_initialized(&ep->conf_frame_Q)) { |
109 | size = cq_howmany(&ep->conf_frame_Q); | 109 | size = cq_howmany(&ep->conf_frame_Q); |
110 | for (; size; size--) { | 110 | for (; size; size--) { |
111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); | 111 | struct packet *pkt = cq_get(&ep->conf_frame_Q); |
@@ -115,7 +115,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
115 | cq_delete(&ep->conf_frame_Q); | 115 | cq_delete(&ep->conf_frame_Q); |
116 | } | 116 | } |
117 | 117 | ||
118 | if (ep->empty_frame_Q) { | 118 | if (kfifo_initialized(&ep->empty_frame_Q)) { |
119 | size = cq_howmany(&ep->empty_frame_Q); | 119 | size = cq_howmany(&ep->empty_frame_Q); |
120 | for (; size; size--) { | 120 | for (; size; size--) { |
121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); | 121 | struct packet *pkt = cq_get(&ep->empty_frame_Q); |
@@ -125,7 +125,7 @@ void fhci_ep0_free(struct fhci_usb *usb) | |||
125 | cq_delete(&ep->empty_frame_Q); | 125 | cq_delete(&ep->empty_frame_Q); |
126 | } | 126 | } |
127 | 127 | ||
128 | if (ep->dummy_packets_Q) { | 128 | if (kfifo_initialized(&ep->dummy_packets_Q)) { |
129 | size = cq_howmany(&ep->dummy_packets_Q); | 129 | size = cq_howmany(&ep->dummy_packets_Q); |
130 | for (; size; size--) { | 130 | for (; size; size--) { |
131 | u8 *buff = cq_get(&ep->dummy_packets_Q); | 131 | u8 *buff = cq_get(&ep->dummy_packets_Q); |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 0ceec123ddfd..bee558aed427 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -35,7 +35,9 @@ | |||
35 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
38 | #include <linux/mm.h> | ||
38 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
40 | #include <asm/cacheflush.h> | ||
39 | 41 | ||
40 | #include "../core/hcd.h" | 42 | #include "../core/hcd.h" |
41 | #include "r8a66597.h" | 43 | #include "r8a66597.h" |
@@ -820,6 +822,26 @@ static void enable_r8a66597_pipe(struct r8a66597 *r8a66597, struct urb *urb, | |||
820 | enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb); | 822 | enable_r8a66597_pipe_dma(r8a66597, dev, pipe, urb); |
821 | } | 823 | } |
822 | 824 | ||
825 | static void r8a66597_urb_done(struct r8a66597 *r8a66597, struct urb *urb, | ||
826 | int status) | ||
827 | __releases(r8a66597->lock) | ||
828 | __acquires(r8a66597->lock) | ||
829 | { | ||
830 | if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) { | ||
831 | void *ptr; | ||
832 | |||
833 | for (ptr = urb->transfer_buffer; | ||
834 | ptr < urb->transfer_buffer + urb->transfer_buffer_length; | ||
835 | ptr += PAGE_SIZE) | ||
836 | flush_dcache_page(virt_to_page(ptr)); | ||
837 | } | ||
838 | |||
839 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); | ||
840 | spin_unlock(&r8a66597->lock); | ||
841 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, status); | ||
842 | spin_lock(&r8a66597->lock); | ||
843 | } | ||
844 | |||
823 | /* this function must be called with interrupt disabled */ | 845 | /* this function must be called with interrupt disabled */ |
824 | static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | 846 | static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) |
825 | { | 847 | { |
@@ -838,15 +860,9 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | |||
838 | list_del(&td->queue); | 860 | list_del(&td->queue); |
839 | kfree(td); | 861 | kfree(td); |
840 | 862 | ||
841 | if (urb) { | 863 | if (urb) |
842 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), | 864 | r8a66597_urb_done(r8a66597, urb, -ENODEV); |
843 | urb); | ||
844 | 865 | ||
845 | spin_unlock(&r8a66597->lock); | ||
846 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, | ||
847 | -ENODEV); | ||
848 | spin_lock(&r8a66597->lock); | ||
849 | } | ||
850 | break; | 866 | break; |
851 | } | 867 | } |
852 | } | 868 | } |
@@ -1006,6 +1022,8 @@ static void start_root_hub_sampling(struct r8a66597 *r8a66597, int port, | |||
1006 | /* this function must be called with interrupt disabled */ | 1022 | /* this function must be called with interrupt disabled */ |
1007 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | 1023 | static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, |
1008 | u16 syssts) | 1024 | u16 syssts) |
1025 | __releases(r8a66597->lock) | ||
1026 | __acquires(r8a66597->lock) | ||
1009 | { | 1027 | { |
1010 | if (syssts == SE0) { | 1028 | if (syssts == SE0) { |
1011 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); | 1029 | r8a66597_write(r8a66597, ~ATTCH, get_intsts_reg(port)); |
@@ -1023,7 +1041,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | |||
1023 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | 1041 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); |
1024 | } | 1042 | } |
1025 | 1043 | ||
1044 | spin_unlock(&r8a66597->lock); | ||
1026 | usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597)); | 1045 | usb_hcd_poll_rh_status(r8a66597_to_hcd(r8a66597)); |
1046 | spin_lock(&r8a66597->lock); | ||
1027 | } | 1047 | } |
1028 | 1048 | ||
1029 | /* this function must be called with interrupt disabled */ | 1049 | /* this function must be called with interrupt disabled */ |
@@ -1283,10 +1303,7 @@ __releases(r8a66597->lock) __acquires(r8a66597->lock) | |||
1283 | if (usb_pipeisoc(urb->pipe)) | 1303 | if (usb_pipeisoc(urb->pipe)) |
1284 | urb->start_frame = r8a66597_get_frame(hcd); | 1304 | urb->start_frame = r8a66597_get_frame(hcd); |
1285 | 1305 | ||
1286 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); | 1306 | r8a66597_urb_done(r8a66597, urb, status); |
1287 | spin_unlock(&r8a66597->lock); | ||
1288 | usb_hcd_giveback_urb(hcd, urb, status); | ||
1289 | spin_lock(&r8a66597->lock); | ||
1290 | } | 1307 | } |
1291 | 1308 | ||
1292 | if (restart) { | 1309 | if (restart) { |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 0025847743f3..8b37a4b9839e 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -3245,6 +3245,7 @@ static struct usb_device_id sisusb_table [] = { | |||
3245 | { USB_DEVICE(0x0711, 0x0902) }, | 3245 | { USB_DEVICE(0x0711, 0x0902) }, |
3246 | { USB_DEVICE(0x0711, 0x0903) }, | 3246 | { USB_DEVICE(0x0711, 0x0903) }, |
3247 | { USB_DEVICE(0x0711, 0x0918) }, | 3247 | { USB_DEVICE(0x0711, 0x0918) }, |
3248 | { USB_DEVICE(0x0711, 0x0920) }, | ||
3248 | { USB_DEVICE(0x182d, 0x021c) }, | 3249 | { USB_DEVICE(0x182d, 0x021c) }, |
3249 | { USB_DEVICE(0x182d, 0x0269) }, | 3250 | { USB_DEVICE(0x182d, 0x0269) }, |
3250 | { } | 3251 | { } |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index de56b3d743d7..3d2d3e549bd1 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
@@ -44,6 +44,7 @@ config ISP1301_OMAP | |||
44 | config USB_ULPI | 44 | config USB_ULPI |
45 | bool "Generic ULPI Transceiver Driver" | 45 | bool "Generic ULPI Transceiver Driver" |
46 | depends on ARM | 46 | depends on ARM |
47 | select USB_OTG_UTILS | ||
47 | help | 48 | help |
48 | Enable this to support ULPI connected USB OTG transceivers which | 49 | Enable this to support ULPI connected USB OTG transceivers which |
49 | are likely found on embedded boards. | 50 | are likely found on embedded boards. |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 216f187582ab..7638828e7317 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -50,7 +50,7 @@ | |||
50 | * Version Information | 50 | * Version Information |
51 | */ | 51 | */ |
52 | #define DRIVER_VERSION "v1.5.0" | 52 | #define DRIVER_VERSION "v1.5.0" |
53 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 53 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr" |
54 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 54 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
55 | 55 | ||
56 | static int debug; | 56 | static int debug; |
@@ -145,10 +145,15 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | |||
145 | 145 | ||
146 | 146 | ||
147 | 147 | ||
148 | /* | ||
149 | * Device ID not listed? Test via module params product/vendor or | ||
150 | * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! | ||
151 | */ | ||
148 | static struct usb_device_id id_table_combined [] = { | 152 | static struct usb_device_id id_table_combined [] = { |
149 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 153 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
150 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 154 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
151 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 155 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
156 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | ||
152 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 157 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
153 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, | 158 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, |
154 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, | 159 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, |
@@ -552,9 +557,16 @@ static struct usb_device_id id_table_combined [] = { | |||
552 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, | 557 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, |
553 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, | 558 | { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, |
554 | /* | 559 | /* |
555 | * Due to many user requests for multiple ELV devices we enable | 560 | * ELV devices: |
556 | * them by default. | ||
557 | */ | 561 | */ |
562 | { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, | ||
563 | { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, | ||
564 | { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, | ||
565 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) }, | ||
566 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) }, | ||
567 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) }, | ||
568 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) }, | ||
569 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) }, | ||
558 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, | 570 | { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, |
559 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, | 571 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, |
560 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, | 572 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, |
@@ -571,11 +583,17 @@ static struct usb_device_id id_table_combined [] = { | |||
571 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, | 583 | { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, |
572 | { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, | 584 | { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, |
573 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, | 585 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, |
586 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) }, | ||
574 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, |
588 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) }, | ||
575 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, | 589 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, |
576 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, | 590 | { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, |
577 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, | 591 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, |
578 | { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, | 592 | { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, |
593 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) }, | ||
594 | { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) }, | ||
595 | { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) }, | ||
596 | { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) }, | ||
579 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, | 597 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
580 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, | 598 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
581 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, | 599 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, |
@@ -697,6 +715,7 @@ static struct usb_device_id id_table_combined [] = { | |||
697 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 715 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
698 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 716 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
699 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 717 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
718 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) }, | ||
700 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, | 719 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, |
701 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 720 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
702 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 721 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index da92b4952ffb..c8951aeed983 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -38,6 +38,8 @@ | |||
38 | /* www.candapter.com Ewert Energy Systems CANdapter device */ | 38 | /* www.candapter.com Ewert Energy Systems CANdapter device */ |
39 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | 39 | #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ |
40 | 40 | ||
41 | #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ | ||
42 | |||
41 | /* OOCDlink by Joern Kaipf <joernk@web.de> | 43 | /* OOCDlink by Joern Kaipf <joernk@web.de> |
42 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ | 44 | * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ |
43 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ | 45 | #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ |
@@ -161,22 +163,37 @@ | |||
161 | /* | 163 | /* |
162 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). | 164 | * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). |
163 | * All of these devices use FTDI's vendor ID (0x0403). | 165 | * All of these devices use FTDI's vendor ID (0x0403). |
166 | * Further IDs taken from ELV Windows .inf file. | ||
164 | * | 167 | * |
165 | * The previously included PID for the UO 100 module was incorrect. | 168 | * The previously included PID for the UO 100 module was incorrect. |
166 | * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). | 169 | * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). |
167 | * | 170 | * |
168 | * Armin Laeuger originally sent the PID for the UM 100 module. | 171 | * Armin Laeuger originally sent the PID for the UM 100 module. |
169 | */ | 172 | */ |
173 | #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ | ||
174 | #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ | ||
175 | #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ | ||
176 | #define FTDI_ELV_WS550_PID 0xE004 /* WS 550 */ | ||
177 | #define FTDI_ELV_EC3000_PID 0xE006 /* ENERGY CONTROL 3000 USB */ | ||
178 | #define FTDI_ELV_WS888_PID 0xE008 /* WS 888 */ | ||
179 | #define FTDI_ELV_TWS550_PID 0xE009 /* Technoline WS 550 */ | ||
180 | #define FTDI_ELV_FEM_PID 0xE00A /* Funk Energie Monitor */ | ||
170 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ | 181 | #define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ |
171 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ | 182 | #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ |
172 | #define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ | 183 | #define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ |
184 | #define FTDI_ELV_UMS100_PID 0xE0EB /* ELV USB Master-Slave Schaltsteckdose UMS 100 */ | ||
185 | #define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */ | ||
186 | #define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */ | ||
187 | #define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */ | ||
173 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ | 188 | #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ |
174 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ | 189 | #define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ |
175 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ | 190 | #define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ |
176 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ | 191 | #define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ |
177 | #define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ | 192 | #define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ |
178 | #define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ | 193 | #define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ |
194 | #define FTDI_ELV_UTP8_PID 0xE0F5 /* ELV UTP 8 */ | ||
179 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ | 195 | #define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ |
196 | #define FTDI_ELV_WS444PC_PID 0xE0F7 /* Conrad WS 444 PC */ | ||
180 | #define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ | 197 | #define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ |
181 | #define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ | 198 | #define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ |
182 | #define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ | 199 | #define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ |
@@ -968,6 +985,7 @@ | |||
968 | #define PAPOUCH_VID 0x5050 /* Vendor ID */ | 985 | #define PAPOUCH_VID 0x5050 /* Vendor ID */ |
969 | #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ | 986 | #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ |
970 | #define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ | 987 | #define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ |
988 | #define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */ | ||
971 | 989 | ||
972 | /* | 990 | /* |
973 | * Marvell SheevaPlug | 991 | * Marvell SheevaPlug |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index ac1b6449fb6a..3eb6143bb646 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -298,6 +298,7 @@ static struct usb_device_id id_table [] = { | |||
298 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | 298 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ |
299 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 299 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
300 | }, | 300 | }, |
301 | { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ | ||
301 | 302 | ||
302 | { } | 303 | { } |
303 | }; | 304 | }; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c932f9053188..49575fba3756 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -941,7 +941,7 @@ UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, | |||
941 | UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133, | 941 | UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133, |
942 | "Microtech", | 942 | "Microtech", |
943 | "USB-SCSI-DB25", | 943 | "USB-SCSI-DB25", |
944 | US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, | 944 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
945 | US_FL_SCM_MULT_TARG ), | 945 | US_FL_SCM_MULT_TARG ), |
946 | 946 | ||
947 | UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, | 947 | UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, |
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c index eb12182b2059..d25df51bb0d2 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/efifb.c | |||
@@ -161,8 +161,17 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static void efifb_destroy(struct fb_info *info) | ||
165 | { | ||
166 | if (info->screen_base) | ||
167 | iounmap(info->screen_base); | ||
168 | release_mem_region(info->aperture_base, info->aperture_size); | ||
169 | framebuffer_release(info); | ||
170 | } | ||
171 | |||
164 | static struct fb_ops efifb_ops = { | 172 | static struct fb_ops efifb_ops = { |
165 | .owner = THIS_MODULE, | 173 | .owner = THIS_MODULE, |
174 | .fb_destroy = efifb_destroy, | ||
166 | .fb_setcolreg = efifb_setcolreg, | 175 | .fb_setcolreg = efifb_setcolreg, |
167 | .fb_fillrect = cfb_fillrect, | 176 | .fb_fillrect = cfb_fillrect, |
168 | .fb_copyarea = cfb_copyarea, | 177 | .fb_copyarea = cfb_copyarea, |
@@ -281,7 +290,7 @@ static int __init efifb_probe(struct platform_device *dev) | |||
281 | info->par = NULL; | 290 | info->par = NULL; |
282 | 291 | ||
283 | info->aperture_base = efifb_fix.smem_start; | 292 | info->aperture_base = efifb_fix.smem_start; |
284 | info->aperture_size = size_total; | 293 | info->aperture_size = size_remap; |
285 | 294 | ||
286 | info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); | 295 | info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); |
287 | if (!info->screen_base) { | 296 | if (!info->screen_base) { |
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c index c7b3f9df2317..2159e668751c 100644 --- a/drivers/watchdog/bfin_wdt.c +++ b/drivers/watchdog/bfin_wdt.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Watchdog Driver | 2 | * Blackfin On-Chip Watchdog Driver |
3 | * Supports BF53[123]/BF53[467]/BF54[2489]/BF561 | ||
4 | * | 3 | * |
5 | * Originally based on softdog.c | 4 | * Originally based on softdog.c |
6 | * Copyright 2006-2007 Analog Devices Inc. | 5 | * Copyright 2006-2010 Analog Devices Inc. |
7 | * Copyright 2006-2007 Michele d'Amico | 6 | * Copyright 2006-2007 Michele d'Amico |
8 | * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> | 7 | * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> |
9 | * | 8 | * |
@@ -137,13 +136,15 @@ static int bfin_wdt_running(void) | |||
137 | */ | 136 | */ |
138 | static int bfin_wdt_set_timeout(unsigned long t) | 137 | static int bfin_wdt_set_timeout(unsigned long t) |
139 | { | 138 | { |
140 | u32 cnt; | 139 | u32 cnt, max_t, sclk; |
141 | unsigned long flags; | 140 | unsigned long flags; |
142 | 141 | ||
143 | stampit(); | 142 | sclk = get_sclk(); |
143 | max_t = -1 / sclk; | ||
144 | cnt = t * sclk; | ||
145 | stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt); | ||
144 | 146 | ||
145 | cnt = t * get_sclk(); | 147 | if (t > max_t) { |
146 | if (cnt < get_sclk()) { | ||
147 | printk(KERN_WARNING PFX "timeout value is too large\n"); | 148 | printk(KERN_WARNING PFX "timeout value is too large\n"); |
148 | return -EINVAL; | 149 | return -EINVAL; |
149 | } | 150 | } |