diff options
Diffstat (limited to 'drivers')
717 files changed, 10405 insertions, 5017 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index e7515aa43d6b..6f190bc2b8b7 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -243,6 +243,8 @@ static int acpi_ac_resume(struct device *dev) | |||
243 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 243 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
244 | return 0; | 244 | return 0; |
245 | } | 245 | } |
246 | #else | ||
247 | #define acpi_ac_resume NULL | ||
246 | #endif | 248 | #endif |
247 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | 249 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); |
248 | 250 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 470e7542bf31..797a6938d051 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -549,7 +549,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
549 | { | 549 | { |
550 | unsigned long x; | 550 | unsigned long x; |
551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); | 551 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
552 | if (sscanf(buf, "%ld\n", &x) == 1) | 552 | if (sscanf(buf, "%lu\n", &x) == 1) |
553 | battery->alarm = x/1000; | 553 | battery->alarm = x/1000; |
554 | if (acpi_battery_present(battery)) | 554 | if (acpi_battery_present(battery)) |
555 | acpi_battery_set_alarm(battery); | 555 | acpi_battery_set_alarm(battery); |
@@ -841,6 +841,8 @@ static int acpi_battery_resume(struct device *dev) | |||
841 | acpi_battery_update(battery); | 841 | acpi_battery_update(battery); |
842 | return 0; | 842 | return 0; |
843 | } | 843 | } |
844 | #else | ||
845 | #define acpi_battery_resume NULL | ||
844 | #endif | 846 | #endif |
845 | 847 | ||
846 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); | 848 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 10e4964d051a..afec4526c48a 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -260,14 +260,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
260 | }, | 260 | }, |
261 | { | 261 | { |
262 | .callback = dmi_disable_osi_win8, | 262 | .callback = dmi_disable_osi_win8, |
263 | .ident = "Dell Inspiron 15R SE", | ||
264 | .matches = { | ||
265 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
266 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), | ||
267 | }, | ||
268 | }, | ||
269 | { | ||
270 | .callback = dmi_disable_osi_win8, | ||
271 | .ident = "ThinkPad Edge E530", | 263 | .ident = "ThinkPad Edge E530", |
272 | .matches = { | 264 | .matches = { |
273 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 265 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -322,56 +314,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
322 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), | 314 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), |
323 | }, | 315 | }, |
324 | }, | 316 | }, |
325 | { | ||
326 | .callback = dmi_disable_osi_win8, | ||
327 | .ident = "HP ProBook 2013 models", | ||
328 | .matches = { | ||
329 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
330 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), | ||
331 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
332 | }, | ||
333 | }, | ||
334 | { | ||
335 | .callback = dmi_disable_osi_win8, | ||
336 | .ident = "HP EliteBook 2013 models", | ||
337 | .matches = { | ||
338 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
339 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), | ||
340 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
341 | }, | ||
342 | }, | ||
343 | { | ||
344 | .callback = dmi_disable_osi_win8, | ||
345 | .ident = "HP ZBook 14", | ||
346 | .matches = { | ||
347 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
348 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), | ||
349 | }, | ||
350 | }, | ||
351 | { | ||
352 | .callback = dmi_disable_osi_win8, | ||
353 | .ident = "HP ZBook 15", | ||
354 | .matches = { | ||
355 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
356 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), | ||
357 | }, | ||
358 | }, | ||
359 | { | ||
360 | .callback = dmi_disable_osi_win8, | ||
361 | .ident = "HP ZBook 17", | ||
362 | .matches = { | ||
363 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
364 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), | ||
365 | }, | ||
366 | }, | ||
367 | { | ||
368 | .callback = dmi_disable_osi_win8, | ||
369 | .ident = "HP EliteBook 8780w", | ||
370 | .matches = { | ||
371 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
372 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | ||
373 | }, | ||
374 | }, | ||
375 | 317 | ||
376 | /* | 318 | /* |
377 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 319 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 11c11f6b8fa1..714e957a871a 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -80,6 +80,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event); | |||
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | 81 | #ifdef CONFIG_PM_SLEEP |
82 | static int acpi_button_resume(struct device *dev); | 82 | static int acpi_button_resume(struct device *dev); |
83 | #else | ||
84 | #define acpi_button_resume NULL | ||
83 | #endif | 85 | #endif |
84 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); | 86 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); |
85 | 87 | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 0b6ae6eb5c4a..368f9ddb8480 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -79,9 +79,10 @@ static int container_device_attach(struct acpi_device *adev, | |||
79 | ACPI_COMPANION_SET(dev, adev); | 79 | ACPI_COMPANION_SET(dev, adev); |
80 | dev->release = acpi_container_release; | 80 | dev->release = acpi_container_release; |
81 | ret = device_register(dev); | 81 | ret = device_register(dev); |
82 | if (ret) | 82 | if (ret) { |
83 | put_device(dev); | ||
83 | return ret; | 84 | return ret; |
84 | 85 | } | |
85 | adev->driver_data = dev; | 86 | adev->driver_data = dev; |
86 | return 1; | 87 | return 1; |
87 | } | 88 | } |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index c431c88faaff..5bfd769fc91f 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -609,7 +609,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
609 | static void dock_notify(struct dock_station *ds, u32 event) | 609 | static void dock_notify(struct dock_station *ds, u32 event) |
610 | { | 610 | { |
611 | acpi_handle handle = ds->handle; | 611 | acpi_handle handle = ds->handle; |
612 | struct acpi_device *ad; | 612 | struct acpi_device *adev = NULL; |
613 | int surprise_removal = 0; | 613 | int surprise_removal = 0; |
614 | 614 | ||
615 | /* | 615 | /* |
@@ -632,7 +632,8 @@ static void dock_notify(struct dock_station *ds, u32 event) | |||
632 | switch (event) { | 632 | switch (event) { |
633 | case ACPI_NOTIFY_BUS_CHECK: | 633 | case ACPI_NOTIFY_BUS_CHECK: |
634 | case ACPI_NOTIFY_DEVICE_CHECK: | 634 | case ACPI_NOTIFY_DEVICE_CHECK: |
635 | if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) { | 635 | acpi_bus_get_device(handle, &adev); |
636 | if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) { | ||
636 | begin_dock(ds); | 637 | begin_dock(ds); |
637 | dock(ds); | 638 | dock(ds); |
638 | if (!dock_present(ds)) { | 639 | if (!dock_present(ds)) { |
@@ -712,13 +713,11 @@ static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl, | |||
712 | static ssize_t show_docked(struct device *dev, | 713 | static ssize_t show_docked(struct device *dev, |
713 | struct device_attribute *attr, char *buf) | 714 | struct device_attribute *attr, char *buf) |
714 | { | 715 | { |
715 | struct acpi_device *tmp; | ||
716 | |||
717 | struct dock_station *dock_station = dev->platform_data; | 716 | struct dock_station *dock_station = dev->platform_data; |
717 | struct acpi_device *adev = NULL; | ||
718 | 718 | ||
719 | if (!acpi_bus_get_device(dock_station->handle, &tmp)) | 719 | acpi_bus_get_device(dock_station->handle, &adev); |
720 | return snprintf(buf, PAGE_SIZE, "1\n"); | 720 | return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); |
721 | return snprintf(buf, PAGE_SIZE, "0\n"); | ||
722 | } | 721 | } |
723 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); | 722 | static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); |
724 | 723 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 959d41acc108..d7d32c28829b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -67,6 +67,8 @@ enum ec_command { | |||
67 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 67 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
68 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 68 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
69 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | 69 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ |
70 | #define ACPI_EC_CLEAR_MAX 100 /* Maximum number of events to query | ||
71 | * when trying to clear the EC */ | ||
70 | 72 | ||
71 | enum { | 73 | enum { |
72 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 74 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
@@ -116,6 +118,7 @@ EXPORT_SYMBOL(first_ec); | |||
116 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 118 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
117 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 119 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ |
118 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | 120 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ |
121 | static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ | ||
119 | 122 | ||
120 | /* -------------------------------------------------------------------------- | 123 | /* -------------------------------------------------------------------------- |
121 | Transaction Management | 124 | Transaction Management |
@@ -440,6 +443,29 @@ acpi_handle ec_get_handle(void) | |||
440 | 443 | ||
441 | EXPORT_SYMBOL(ec_get_handle); | 444 | EXPORT_SYMBOL(ec_get_handle); |
442 | 445 | ||
446 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data); | ||
447 | |||
448 | /* | ||
449 | * Clears stale _Q events that might have accumulated in the EC. | ||
450 | * Run with locked ec mutex. | ||
451 | */ | ||
452 | static void acpi_ec_clear(struct acpi_ec *ec) | ||
453 | { | ||
454 | int i, status; | ||
455 | u8 value = 0; | ||
456 | |||
457 | for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { | ||
458 | status = acpi_ec_query_unlocked(ec, &value); | ||
459 | if (status || !value) | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | if (unlikely(i == ACPI_EC_CLEAR_MAX)) | ||
464 | pr_warn("Warning: Maximum of %d stale EC events cleared\n", i); | ||
465 | else | ||
466 | pr_info("%d stale EC events cleared\n", i); | ||
467 | } | ||
468 | |||
443 | void acpi_ec_block_transactions(void) | 469 | void acpi_ec_block_transactions(void) |
444 | { | 470 | { |
445 | struct acpi_ec *ec = first_ec; | 471 | struct acpi_ec *ec = first_ec; |
@@ -463,6 +489,10 @@ void acpi_ec_unblock_transactions(void) | |||
463 | mutex_lock(&ec->mutex); | 489 | mutex_lock(&ec->mutex); |
464 | /* Allow transactions to be carried out again */ | 490 | /* Allow transactions to be carried out again */ |
465 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | 491 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); |
492 | |||
493 | if (EC_FLAGS_CLEAR_ON_RESUME) | ||
494 | acpi_ec_clear(ec); | ||
495 | |||
466 | mutex_unlock(&ec->mutex); | 496 | mutex_unlock(&ec->mutex); |
467 | } | 497 | } |
468 | 498 | ||
@@ -821,6 +851,13 @@ static int acpi_ec_add(struct acpi_device *device) | |||
821 | 851 | ||
822 | /* EC is fully operational, allow queries */ | 852 | /* EC is fully operational, allow queries */ |
823 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 853 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
854 | |||
855 | /* Clear stale _Q events if hardware might require that */ | ||
856 | if (EC_FLAGS_CLEAR_ON_RESUME) { | ||
857 | mutex_lock(&ec->mutex); | ||
858 | acpi_ec_clear(ec); | ||
859 | mutex_unlock(&ec->mutex); | ||
860 | } | ||
824 | return ret; | 861 | return ret; |
825 | } | 862 | } |
826 | 863 | ||
@@ -922,6 +959,30 @@ static int ec_enlarge_storm_threshold(const struct dmi_system_id *id) | |||
922 | return 0; | 959 | return 0; |
923 | } | 960 | } |
924 | 961 | ||
962 | /* | ||
963 | * On some hardware it is necessary to clear events accumulated by the EC during | ||
964 | * sleep. These ECs stop reporting GPEs until they are manually polled, if too | ||
965 | * many events are accumulated. (e.g. Samsung Series 5/9 notebooks) | ||
966 | * | ||
967 | * https://bugzilla.kernel.org/show_bug.cgi?id=44161 | ||
968 | * | ||
969 | * Ideally, the EC should also be instructed NOT to accumulate events during | ||
970 | * sleep (which Windows seems to do somehow), but the interface to control this | ||
971 | * behaviour is not known at this time. | ||
972 | * | ||
973 | * Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx, | ||
974 | * however it is very likely that other Samsung models are affected. | ||
975 | * | ||
976 | * On systems which don't accumulate _Q events during sleep, this extra check | ||
977 | * should be harmless. | ||
978 | */ | ||
979 | static int ec_clear_on_resume(const struct dmi_system_id *id) | ||
980 | { | ||
981 | pr_debug("Detected system needing EC poll on resume.\n"); | ||
982 | EC_FLAGS_CLEAR_ON_RESUME = 1; | ||
983 | return 0; | ||
984 | } | ||
985 | |||
925 | static struct dmi_system_id ec_dmi_table[] __initdata = { | 986 | static struct dmi_system_id ec_dmi_table[] __initdata = { |
926 | { | 987 | { |
927 | ec_skip_dsdt_scan, "Compal JFL92", { | 988 | ec_skip_dsdt_scan, "Compal JFL92", { |
@@ -965,6 +1026,9 @@ static struct dmi_system_id ec_dmi_table[] __initdata = { | |||
965 | ec_validate_ecdt, "ASUS hardware", { | 1026 | ec_validate_ecdt, "ASUS hardware", { |
966 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), | 1027 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), |
967 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, | 1028 | DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, |
1029 | { | ||
1030 | ec_clear_on_resume, "Samsung hardware", { | ||
1031 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, | ||
968 | {}, | 1032 | {}, |
969 | }; | 1033 | }; |
970 | 1034 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 1fb62900f32a..09e423f3d8ad 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -55,6 +55,9 @@ MODULE_DEVICE_TABLE(acpi, fan_device_ids); | |||
55 | #ifdef CONFIG_PM_SLEEP | 55 | #ifdef CONFIG_PM_SLEEP |
56 | static int acpi_fan_suspend(struct device *dev); | 56 | static int acpi_fan_suspend(struct device *dev); |
57 | static int acpi_fan_resume(struct device *dev); | 57 | static int acpi_fan_resume(struct device *dev); |
58 | #else | ||
59 | #define acpi_fan_suspend NULL | ||
60 | #define acpi_fan_resume NULL | ||
58 | #endif | 61 | #endif |
59 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); | 62 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); |
60 | 63 | ||
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 52d45ea2bc4f..361b40c10c3f 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -430,6 +430,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
430 | pin_name(pin)); | 430 | pin_name(pin)); |
431 | } | 431 | } |
432 | 432 | ||
433 | kfree(entry); | ||
433 | return 0; | 434 | return 0; |
434 | } | 435 | } |
435 | 436 | ||
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 50fe34ffe932..75c28eae8860 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -60,7 +60,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
60 | seq_printf(seq, "%c%-8s %s:%s\n", | 60 | seq_printf(seq, "%c%-8s %s:%s\n", |
61 | dev->wakeup.flags.run_wake ? '*' : ' ', | 61 | dev->wakeup.flags.run_wake ? '*' : ' ', |
62 | (device_may_wakeup(&dev->dev) || | 62 | (device_may_wakeup(&dev->dev) || |
63 | (ldev && device_may_wakeup(ldev))) ? | 63 | device_may_wakeup(ldev)) ? |
64 | "enabled" : "disabled", | 64 | "enabled" : "disabled", |
65 | ldev->bus ? ldev->bus->name : | 65 | ldev->bus ? ldev->bus->name : |
66 | "no-bus", dev_name(ldev)); | 66 | "no-bus", dev_name(ldev)); |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 28baa05b8018..84243c32e29c 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -56,6 +56,12 @@ struct throttling_tstate { | |||
56 | int target_state; /* target T-state */ | 56 | int target_state; /* target T-state */ |
57 | }; | 57 | }; |
58 | 58 | ||
59 | struct acpi_processor_throttling_arg { | ||
60 | struct acpi_processor *pr; | ||
61 | int target_state; | ||
62 | bool force; | ||
63 | }; | ||
64 | |||
59 | #define THROTTLING_PRECHANGE (1) | 65 | #define THROTTLING_PRECHANGE (1) |
60 | #define THROTTLING_POSTCHANGE (2) | 66 | #define THROTTLING_POSTCHANGE (2) |
61 | 67 | ||
@@ -1060,16 +1066,24 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
1060 | return 0; | 1066 | return 0; |
1061 | } | 1067 | } |
1062 | 1068 | ||
1069 | static long acpi_processor_throttling_fn(void *data) | ||
1070 | { | ||
1071 | struct acpi_processor_throttling_arg *arg = data; | ||
1072 | struct acpi_processor *pr = arg->pr; | ||
1073 | |||
1074 | return pr->throttling.acpi_processor_set_throttling(pr, | ||
1075 | arg->target_state, arg->force); | ||
1076 | } | ||
1077 | |||
1063 | int acpi_processor_set_throttling(struct acpi_processor *pr, | 1078 | int acpi_processor_set_throttling(struct acpi_processor *pr, |
1064 | int state, bool force) | 1079 | int state, bool force) |
1065 | { | 1080 | { |
1066 | cpumask_var_t saved_mask; | ||
1067 | int ret = 0; | 1081 | int ret = 0; |
1068 | unsigned int i; | 1082 | unsigned int i; |
1069 | struct acpi_processor *match_pr; | 1083 | struct acpi_processor *match_pr; |
1070 | struct acpi_processor_throttling *p_throttling; | 1084 | struct acpi_processor_throttling *p_throttling; |
1085 | struct acpi_processor_throttling_arg arg; | ||
1071 | struct throttling_tstate t_state; | 1086 | struct throttling_tstate t_state; |
1072 | cpumask_var_t online_throttling_cpus; | ||
1073 | 1087 | ||
1074 | if (!pr) | 1088 | if (!pr) |
1075 | return -EINVAL; | 1089 | return -EINVAL; |
@@ -1080,14 +1094,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1080 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) | 1094 | if ((state < 0) || (state > (pr->throttling.state_count - 1))) |
1081 | return -EINVAL; | 1095 | return -EINVAL; |
1082 | 1096 | ||
1083 | if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) | ||
1084 | return -ENOMEM; | ||
1085 | |||
1086 | if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) { | ||
1087 | free_cpumask_var(saved_mask); | ||
1088 | return -ENOMEM; | ||
1089 | } | ||
1090 | |||
1091 | if (cpu_is_offline(pr->id)) { | 1097 | if (cpu_is_offline(pr->id)) { |
1092 | /* | 1098 | /* |
1093 | * the cpu pointed by pr->id is offline. Unnecessary to change | 1099 | * the cpu pointed by pr->id is offline. Unnecessary to change |
@@ -1096,17 +1102,15 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1096 | return -ENODEV; | 1102 | return -ENODEV; |
1097 | } | 1103 | } |
1098 | 1104 | ||
1099 | cpumask_copy(saved_mask, ¤t->cpus_allowed); | ||
1100 | t_state.target_state = state; | 1105 | t_state.target_state = state; |
1101 | p_throttling = &(pr->throttling); | 1106 | p_throttling = &(pr->throttling); |
1102 | cpumask_and(online_throttling_cpus, cpu_online_mask, | 1107 | |
1103 | p_throttling->shared_cpu_map); | ||
1104 | /* | 1108 | /* |
1105 | * The throttling notifier will be called for every | 1109 | * The throttling notifier will be called for every |
1106 | * affected cpu in order to get one proper T-state. | 1110 | * affected cpu in order to get one proper T-state. |
1107 | * The notifier event is THROTTLING_PRECHANGE. | 1111 | * The notifier event is THROTTLING_PRECHANGE. |
1108 | */ | 1112 | */ |
1109 | for_each_cpu(i, online_throttling_cpus) { | 1113 | for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { |
1110 | t_state.cpu = i; | 1114 | t_state.cpu = i; |
1111 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, | 1115 | acpi_processor_throttling_notifier(THROTTLING_PRECHANGE, |
1112 | &t_state); | 1116 | &t_state); |
@@ -1118,21 +1122,18 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1118 | * it can be called only for the cpu pointed by pr. | 1122 | * it can be called only for the cpu pointed by pr. |
1119 | */ | 1123 | */ |
1120 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { | 1124 | if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { |
1121 | /* FIXME: use work_on_cpu() */ | 1125 | arg.pr = pr; |
1122 | if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { | 1126 | arg.target_state = state; |
1123 | /* Can't migrate to the pr->id CPU. Exit */ | 1127 | arg.force = force; |
1124 | ret = -ENODEV; | 1128 | ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg); |
1125 | goto exit; | ||
1126 | } | ||
1127 | ret = p_throttling->acpi_processor_set_throttling(pr, | ||
1128 | t_state.target_state, force); | ||
1129 | } else { | 1129 | } else { |
1130 | /* | 1130 | /* |
1131 | * When the T-state coordination is SW_ALL or HW_ALL, | 1131 | * When the T-state coordination is SW_ALL or HW_ALL, |
1132 | * it is necessary to set T-state for every affected | 1132 | * it is necessary to set T-state for every affected |
1133 | * cpus. | 1133 | * cpus. |
1134 | */ | 1134 | */ |
1135 | for_each_cpu(i, online_throttling_cpus) { | 1135 | for_each_cpu_and(i, cpu_online_mask, |
1136 | p_throttling->shared_cpu_map) { | ||
1136 | match_pr = per_cpu(processors, i); | 1137 | match_pr = per_cpu(processors, i); |
1137 | /* | 1138 | /* |
1138 | * If the pointer is invalid, we will report the | 1139 | * If the pointer is invalid, we will report the |
@@ -1153,13 +1154,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1153 | "on CPU %d\n", i)); | 1154 | "on CPU %d\n", i)); |
1154 | continue; | 1155 | continue; |
1155 | } | 1156 | } |
1156 | t_state.cpu = i; | 1157 | |
1157 | /* FIXME: use work_on_cpu() */ | 1158 | arg.pr = match_pr; |
1158 | if (set_cpus_allowed_ptr(current, cpumask_of(i))) | 1159 | arg.target_state = state; |
1159 | continue; | 1160 | arg.force = force; |
1160 | ret = match_pr->throttling. | 1161 | ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, |
1161 | acpi_processor_set_throttling( | 1162 | &arg); |
1162 | match_pr, t_state.target_state, force); | ||
1163 | } | 1163 | } |
1164 | } | 1164 | } |
1165 | /* | 1165 | /* |
@@ -1168,17 +1168,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, | |||
1168 | * affected cpu to update the T-states. | 1168 | * affected cpu to update the T-states. |
1169 | * The notifier event is THROTTLING_POSTCHANGE | 1169 | * The notifier event is THROTTLING_POSTCHANGE |
1170 | */ | 1170 | */ |
1171 | for_each_cpu(i, online_throttling_cpus) { | 1171 | for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) { |
1172 | t_state.cpu = i; | 1172 | t_state.cpu = i; |
1173 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, | 1173 | acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE, |
1174 | &t_state); | 1174 | &t_state); |
1175 | } | 1175 | } |
1176 | /* restore the previous state */ | 1176 | |
1177 | /* FIXME: use work_on_cpu() */ | ||
1178 | set_cpus_allowed_ptr(current, saved_mask); | ||
1179 | exit: | ||
1180 | free_cpumask_var(online_throttling_cpus); | ||
1181 | free_cpumask_var(saved_mask); | ||
1182 | return ret; | 1177 | return ret; |
1183 | } | 1178 | } |
1184 | 1179 | ||
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index b7201fc6f1e1..0bdacc5e26a3 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c | |||
@@ -77,18 +77,24 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) | |||
77 | switch (ares->type) { | 77 | switch (ares->type) { |
78 | case ACPI_RESOURCE_TYPE_MEMORY24: | 78 | case ACPI_RESOURCE_TYPE_MEMORY24: |
79 | memory24 = &ares->data.memory24; | 79 | memory24 = &ares->data.memory24; |
80 | if (!memory24->address_length) | ||
81 | return false; | ||
80 | acpi_dev_get_memresource(res, memory24->minimum, | 82 | acpi_dev_get_memresource(res, memory24->minimum, |
81 | memory24->address_length, | 83 | memory24->address_length, |
82 | memory24->write_protect); | 84 | memory24->write_protect); |
83 | break; | 85 | break; |
84 | case ACPI_RESOURCE_TYPE_MEMORY32: | 86 | case ACPI_RESOURCE_TYPE_MEMORY32: |
85 | memory32 = &ares->data.memory32; | 87 | memory32 = &ares->data.memory32; |
88 | if (!memory32->address_length) | ||
89 | return false; | ||
86 | acpi_dev_get_memresource(res, memory32->minimum, | 90 | acpi_dev_get_memresource(res, memory32->minimum, |
87 | memory32->address_length, | 91 | memory32->address_length, |
88 | memory32->write_protect); | 92 | memory32->write_protect); |
89 | break; | 93 | break; |
90 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | 94 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: |
91 | fixed_memory32 = &ares->data.fixed_memory32; | 95 | fixed_memory32 = &ares->data.fixed_memory32; |
96 | if (!fixed_memory32->address_length) | ||
97 | return false; | ||
92 | acpi_dev_get_memresource(res, fixed_memory32->address, | 98 | acpi_dev_get_memresource(res, fixed_memory32->address, |
93 | fixed_memory32->address_length, | 99 | fixed_memory32->address_length, |
94 | fixed_memory32->write_protect); | 100 | fixed_memory32->write_protect); |
@@ -144,12 +150,16 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) | |||
144 | switch (ares->type) { | 150 | switch (ares->type) { |
145 | case ACPI_RESOURCE_TYPE_IO: | 151 | case ACPI_RESOURCE_TYPE_IO: |
146 | io = &ares->data.io; | 152 | io = &ares->data.io; |
153 | if (!io->address_length) | ||
154 | return false; | ||
147 | acpi_dev_get_ioresource(res, io->minimum, | 155 | acpi_dev_get_ioresource(res, io->minimum, |
148 | io->address_length, | 156 | io->address_length, |
149 | io->io_decode); | 157 | io->io_decode); |
150 | break; | 158 | break; |
151 | case ACPI_RESOURCE_TYPE_FIXED_IO: | 159 | case ACPI_RESOURCE_TYPE_FIXED_IO: |
152 | fixed_io = &ares->data.fixed_io; | 160 | fixed_io = &ares->data.fixed_io; |
161 | if (!fixed_io->address_length) | ||
162 | return false; | ||
153 | acpi_dev_get_ioresource(res, fixed_io->address, | 163 | acpi_dev_get_ioresource(res, fixed_io->address, |
154 | fixed_io->address_length, | 164 | fixed_io->address_length, |
155 | ACPI_DECODE_10); | 165 | ACPI_DECODE_10); |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index d465ae6cdd00..dbd48498b938 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -450,7 +450,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
450 | { | 450 | { |
451 | unsigned long x; | 451 | unsigned long x; |
452 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); | 452 | struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); |
453 | if (sscanf(buf, "%ld\n", &x) == 1) | 453 | if (sscanf(buf, "%lu\n", &x) == 1) |
454 | battery->alarm_capacity = x / | 454 | battery->alarm_capacity = x / |
455 | (1000 * acpi_battery_scale(battery)); | 455 | (1000 * acpi_battery_scale(battery)); |
456 | if (battery->present) | 456 | if (battery->present) |
@@ -668,6 +668,8 @@ static int acpi_sbs_resume(struct device *dev) | |||
668 | acpi_sbs_callback(sbs); | 668 | acpi_sbs_callback(sbs); |
669 | return 0; | 669 | return 0; |
670 | } | 670 | } |
671 | #else | ||
672 | #define acpi_sbs_resume NULL | ||
671 | #endif | 673 | #endif |
672 | 674 | ||
673 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); | 675 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7384158c7f87..57b053f424d1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -484,7 +484,6 @@ static void acpi_device_hotplug(void *data, u32 src) | |||
484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 484 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
485 | { | 485 | { |
486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 486 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
487 | struct acpi_scan_handler *handler = data; | ||
488 | struct acpi_device *adev; | 487 | struct acpi_device *adev; |
489 | acpi_status status; | 488 | acpi_status status; |
490 | 489 | ||
@@ -500,7 +499,10 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
500 | break; | 499 | break; |
501 | case ACPI_NOTIFY_EJECT_REQUEST: | 500 | case ACPI_NOTIFY_EJECT_REQUEST: |
502 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 501 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
503 | if (!handler->hotplug.enabled) { | 502 | if (!adev->handler) |
503 | goto err_out; | ||
504 | |||
505 | if (!adev->handler->hotplug.enabled) { | ||
504 | acpi_handle_err(handle, "Eject disabled\n"); | 506 | acpi_handle_err(handle, "Eject disabled\n"); |
505 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 507 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; |
506 | goto err_out; | 508 | goto err_out; |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index b718806657cd..c40fb2e81bbc 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -71,6 +71,17 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
74 | static bool acpi_sleep_state_supported(u8 sleep_state) | ||
75 | { | ||
76 | acpi_status status; | ||
77 | u8 type_a, type_b; | ||
78 | |||
79 | status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); | ||
80 | return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware | ||
81 | || (acpi_gbl_FADT.sleep_control.address | ||
82 | && acpi_gbl_FADT.sleep_status.address)); | ||
83 | } | ||
84 | |||
74 | #ifdef CONFIG_ACPI_SLEEP | 85 | #ifdef CONFIG_ACPI_SLEEP |
75 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 86 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
76 | 87 | ||
@@ -604,15 +615,9 @@ static void acpi_sleep_suspend_setup(void) | |||
604 | { | 615 | { |
605 | int i; | 616 | int i; |
606 | 617 | ||
607 | for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { | 618 | for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) |
608 | acpi_status status; | 619 | if (acpi_sleep_state_supported(i)) |
609 | u8 type_a, type_b; | ||
610 | |||
611 | status = acpi_get_sleep_type_data(i, &type_a, &type_b); | ||
612 | if (ACPI_SUCCESS(status)) { | ||
613 | sleep_states[i] = 1; | 620 | sleep_states[i] = 1; |
614 | } | ||
615 | } | ||
616 | 621 | ||
617 | suspend_set_ops(old_suspend_ordering ? | 622 | suspend_set_ops(old_suspend_ordering ? |
618 | &acpi_suspend_ops_old : &acpi_suspend_ops); | 623 | &acpi_suspend_ops_old : &acpi_suspend_ops); |
@@ -740,11 +745,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = { | |||
740 | 745 | ||
741 | static void acpi_sleep_hibernate_setup(void) | 746 | static void acpi_sleep_hibernate_setup(void) |
742 | { | 747 | { |
743 | acpi_status status; | 748 | if (!acpi_sleep_state_supported(ACPI_STATE_S4)) |
744 | u8 type_a, type_b; | ||
745 | |||
746 | status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); | ||
747 | if (ACPI_FAILURE(status)) | ||
748 | return; | 749 | return; |
749 | 750 | ||
750 | hibernation_set_ops(old_suspend_ordering ? | 751 | hibernation_set_ops(old_suspend_ordering ? |
@@ -793,8 +794,6 @@ static void acpi_power_off(void) | |||
793 | 794 | ||
794 | int __init acpi_sleep_init(void) | 795 | int __init acpi_sleep_init(void) |
795 | { | 796 | { |
796 | acpi_status status; | ||
797 | u8 type_a, type_b; | ||
798 | char supported[ACPI_S_STATE_COUNT * 3 + 1]; | 797 | char supported[ACPI_S_STATE_COUNT * 3 + 1]; |
799 | char *pos = supported; | 798 | char *pos = supported; |
800 | int i; | 799 | int i; |
@@ -806,8 +805,7 @@ int __init acpi_sleep_init(void) | |||
806 | acpi_sleep_suspend_setup(); | 805 | acpi_sleep_suspend_setup(); |
807 | acpi_sleep_hibernate_setup(); | 806 | acpi_sleep_hibernate_setup(); |
808 | 807 | ||
809 | status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); | 808 | if (acpi_sleep_state_supported(ACPI_STATE_S5)) { |
810 | if (ACPI_SUCCESS(status)) { | ||
811 | sleep_states[ACPI_STATE_S5] = 1; | 809 | sleep_states[ACPI_STATE_S5] = 1; |
812 | pm_power_off_prepare = acpi_power_off_prepare; | 810 | pm_power_off_prepare = acpi_power_off_prepare; |
813 | pm_power_off = acpi_power_off; | 811 | pm_power_off = acpi_power_off; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 8349a555b92b..08626c851be7 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -102,6 +102,8 @@ MODULE_DEVICE_TABLE(acpi, thermal_device_ids); | |||
102 | 102 | ||
103 | #ifdef CONFIG_PM_SLEEP | 103 | #ifdef CONFIG_PM_SLEEP |
104 | static int acpi_thermal_resume(struct device *dev); | 104 | static int acpi_thermal_resume(struct device *dev); |
105 | #else | ||
106 | #define acpi_thermal_resume NULL | ||
105 | #endif | 107 | #endif |
106 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); | 108 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); |
107 | 109 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 0347a37eb438..85e3b612bdc0 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -99,10 +99,6 @@ acpi_extract_package(union acpi_object *package, | |||
99 | 99 | ||
100 | union acpi_object *element = &(package->package.elements[i]); | 100 | union acpi_object *element = &(package->package.elements[i]); |
101 | 101 | ||
102 | if (!element) { | ||
103 | return AE_BAD_DATA; | ||
104 | } | ||
105 | |||
106 | switch (element->type) { | 102 | switch (element->type) { |
107 | 103 | ||
108 | case ACPI_TYPE_INTEGER: | 104 | case ACPI_TYPE_INTEGER: |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index b727d105046d..b6ba88ed31ae 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -81,11 +81,12 @@ static bool allow_duplicates; | |||
81 | module_param(allow_duplicates, bool, 0644); | 81 | module_param(allow_duplicates, bool, 0644); |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * For Windows 8 systems: if set ture and the GPU driver has | 84 | * For Windows 8 systems: used to decide if video module |
85 | * registered a backlight interface, skip registering ACPI video's. | 85 | * should skip registering backlight interface of its own. |
86 | */ | 86 | */ |
87 | static bool use_native_backlight = false; | 87 | static int use_native_backlight_param = -1; |
88 | module_param(use_native_backlight, bool, 0644); | 88 | module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); |
89 | static bool use_native_backlight_dmi = false; | ||
89 | 90 | ||
90 | static int register_count; | 91 | static int register_count; |
91 | static struct mutex video_list_lock; | 92 | static struct mutex video_list_lock; |
@@ -231,9 +232,17 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
231 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 232 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
232 | int event); | 233 | int event); |
233 | 234 | ||
235 | static bool acpi_video_use_native_backlight(void) | ||
236 | { | ||
237 | if (use_native_backlight_param != -1) | ||
238 | return use_native_backlight_param; | ||
239 | else | ||
240 | return use_native_backlight_dmi; | ||
241 | } | ||
242 | |||
234 | static bool acpi_video_verify_backlight_support(void) | 243 | static bool acpi_video_verify_backlight_support(void) |
235 | { | 244 | { |
236 | if (acpi_osi_is_win8() && use_native_backlight && | 245 | if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && |
237 | backlight_device_registered(BACKLIGHT_RAW)) | 246 | backlight_device_registered(BACKLIGHT_RAW)) |
238 | return false; | 247 | return false; |
239 | return acpi_video_backlight_support(); | 248 | return acpi_video_backlight_support(); |
@@ -398,6 +407,12 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d) | |||
398 | return 0; | 407 | return 0; |
399 | } | 408 | } |
400 | 409 | ||
410 | static int __init video_set_use_native_backlight(const struct dmi_system_id *d) | ||
411 | { | ||
412 | use_native_backlight_dmi = true; | ||
413 | return 0; | ||
414 | } | ||
415 | |||
401 | static struct dmi_system_id video_dmi_table[] __initdata = { | 416 | static struct dmi_system_id video_dmi_table[] __initdata = { |
402 | /* | 417 | /* |
403 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 | 418 | * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 |
@@ -442,6 +457,120 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
442 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), | 457 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), |
443 | }, | 458 | }, |
444 | }, | 459 | }, |
460 | { | ||
461 | .callback = video_set_use_native_backlight, | ||
462 | .ident = "ThinkPad T430s", | ||
463 | .matches = { | ||
464 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
465 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), | ||
466 | }, | ||
467 | }, | ||
468 | { | ||
469 | .callback = video_set_use_native_backlight, | ||
470 | .ident = "ThinkPad X230", | ||
471 | .matches = { | ||
472 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
473 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), | ||
474 | }, | ||
475 | }, | ||
476 | { | ||
477 | .callback = video_set_use_native_backlight, | ||
478 | .ident = "ThinkPad X1 Carbon", | ||
479 | .matches = { | ||
480 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
481 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), | ||
482 | }, | ||
483 | }, | ||
484 | { | ||
485 | .callback = video_set_use_native_backlight, | ||
486 | .ident = "Lenovo Yoga 13", | ||
487 | .matches = { | ||
488 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
489 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), | ||
490 | }, | ||
491 | }, | ||
492 | { | ||
493 | .callback = video_set_use_native_backlight, | ||
494 | .ident = "Dell Inspiron 7520", | ||
495 | .matches = { | ||
496 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
497 | DMI_MATCH(DMI_PRODUCT_VERSION, "Inspiron 7520"), | ||
498 | }, | ||
499 | }, | ||
500 | { | ||
501 | .callback = video_set_use_native_backlight, | ||
502 | .ident = "Acer Aspire 5733Z", | ||
503 | .matches = { | ||
504 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
505 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5733Z"), | ||
506 | }, | ||
507 | }, | ||
508 | { | ||
509 | .callback = video_set_use_native_backlight, | ||
510 | .ident = "Acer Aspire V5-431", | ||
511 | .matches = { | ||
512 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
513 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire V5-431"), | ||
514 | }, | ||
515 | }, | ||
516 | { | ||
517 | .callback = video_set_use_native_backlight, | ||
518 | .ident = "HP ProBook 4340s", | ||
519 | .matches = { | ||
520 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
521 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP ProBook 4340s"), | ||
522 | }, | ||
523 | }, | ||
524 | { | ||
525 | .callback = video_set_use_native_backlight, | ||
526 | .ident = "HP ProBook 2013 models", | ||
527 | .matches = { | ||
528 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
529 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook "), | ||
530 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
531 | }, | ||
532 | }, | ||
533 | { | ||
534 | .callback = video_set_use_native_backlight, | ||
535 | .ident = "HP EliteBook 2013 models", | ||
536 | .matches = { | ||
537 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
538 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "), | ||
539 | DMI_MATCH(DMI_PRODUCT_NAME, " G1"), | ||
540 | }, | ||
541 | }, | ||
542 | { | ||
543 | .callback = video_set_use_native_backlight, | ||
544 | .ident = "HP ZBook 14", | ||
545 | .matches = { | ||
546 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
547 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 14"), | ||
548 | }, | ||
549 | }, | ||
550 | { | ||
551 | .callback = video_set_use_native_backlight, | ||
552 | .ident = "HP ZBook 15", | ||
553 | .matches = { | ||
554 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
555 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 15"), | ||
556 | }, | ||
557 | }, | ||
558 | { | ||
559 | .callback = video_set_use_native_backlight, | ||
560 | .ident = "HP ZBook 17", | ||
561 | .matches = { | ||
562 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
563 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ZBook 17"), | ||
564 | }, | ||
565 | }, | ||
566 | { | ||
567 | .callback = video_set_use_native_backlight, | ||
568 | .ident = "HP EliteBook 8780w", | ||
569 | .matches = { | ||
570 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
571 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 8780w"), | ||
572 | }, | ||
573 | }, | ||
445 | {} | 574 | {} |
446 | }; | 575 | }; |
447 | 576 | ||
@@ -685,6 +814,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
685 | union acpi_object *o; | 814 | union acpi_object *o; |
686 | struct acpi_video_device_brightness *br = NULL; | 815 | struct acpi_video_device_brightness *br = NULL; |
687 | int result = -EINVAL; | 816 | int result = -EINVAL; |
817 | u32 value; | ||
688 | 818 | ||
689 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { | 819 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
690 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " | 820 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " |
@@ -715,7 +845,12 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
715 | printk(KERN_ERR PREFIX "Invalid data\n"); | 845 | printk(KERN_ERR PREFIX "Invalid data\n"); |
716 | continue; | 846 | continue; |
717 | } | 847 | } |
718 | br->levels[count] = (u32) o->integer.value; | 848 | value = (u32) o->integer.value; |
849 | /* Skip duplicate entries */ | ||
850 | if (count > 2 && br->levels[count - 1] == value) | ||
851 | continue; | ||
852 | |||
853 | br->levels[count] = value; | ||
719 | 854 | ||
720 | if (br->levels[count] > max_level) | 855 | if (br->levels[count] > max_level) |
721 | max_level = br->levels[count]; | 856 | max_level = br->levels[count]; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index f0447d3daf2c..19080c8e2f2a 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -168,14 +168,6 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), | 168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), |
169 | }, | 169 | }, |
170 | }, | 170 | }, |
171 | { | ||
172 | .callback = video_detect_force_vendor, | ||
173 | .ident = "Lenovo Yoga 13", | ||
174 | .matches = { | ||
175 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
176 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), | ||
177 | }, | ||
178 | }, | ||
179 | { }, | 171 | { }, |
180 | }; | 172 | }; |
181 | 173 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 4e737728aee2..868429a47be4 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -247,6 +247,7 @@ config SATA_HIGHBANK | |||
247 | 247 | ||
248 | config SATA_MV | 248 | config SATA_MV |
249 | tristate "Marvell SATA support" | 249 | tristate "Marvell SATA support" |
250 | select GENERIC_PHY | ||
250 | help | 251 | help |
251 | This option enables support for the Marvell Serial ATA family. | 252 | This option enables support for the Marvell Serial ATA family. |
252 | Currently supports 88SX[56]0[48][01] PCI(-X) chips, | 253 | Currently supports 88SX[56]0[48][01] PCI(-X) chips, |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index dc2756fb6f33..c81d809c111b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -61,6 +61,7 @@ enum board_ids { | |||
61 | /* board IDs by feature in alphabetical order */ | 61 | /* board IDs by feature in alphabetical order */ |
62 | board_ahci, | 62 | board_ahci, |
63 | board_ahci_ign_iferr, | 63 | board_ahci_ign_iferr, |
64 | board_ahci_noncq, | ||
64 | board_ahci_nosntf, | 65 | board_ahci_nosntf, |
65 | board_ahci_yes_fbs, | 66 | board_ahci_yes_fbs, |
66 | 67 | ||
@@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = { | |||
121 | .udma_mask = ATA_UDMA6, | 122 | .udma_mask = ATA_UDMA6, |
122 | .port_ops = &ahci_ops, | 123 | .port_ops = &ahci_ops, |
123 | }, | 124 | }, |
125 | [board_ahci_noncq] = { | ||
126 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), | ||
127 | .flags = AHCI_FLAG_COMMON, | ||
128 | .pio_mask = ATA_PIO4, | ||
129 | .udma_mask = ATA_UDMA6, | ||
130 | .port_ops = &ahci_ops, | ||
131 | }, | ||
124 | [board_ahci_nosntf] = { | 132 | [board_ahci_nosntf] = { |
125 | AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF), | 133 | AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF), |
126 | .flags = AHCI_FLAG_COMMON, | 134 | .flags = AHCI_FLAG_COMMON, |
@@ -452,6 +460,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
452 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | 460 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ |
453 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | 461 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ |
454 | 462 | ||
463 | /* | ||
464 | * Samsung SSDs found on some macbooks. NCQ times out. | ||
465 | * https://bugzilla.kernel.org/show_bug.cgi?id=60731 | ||
466 | */ | ||
467 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, | ||
468 | |||
455 | /* Enmotus */ | 469 | /* Enmotus */ |
456 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, | 470 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, |
457 | 471 | ||
@@ -1170,8 +1184,10 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, | |||
1170 | 1184 | ||
1171 | nvec = rc; | 1185 | nvec = rc; |
1172 | rc = pci_enable_msi_block(pdev, nvec); | 1186 | rc = pci_enable_msi_block(pdev, nvec); |
1173 | if (rc) | 1187 | if (rc < 0) |
1174 | goto intx; | 1188 | goto intx; |
1189 | else if (rc > 0) | ||
1190 | goto single_msi; | ||
1175 | 1191 | ||
1176 | return nvec; | 1192 | return nvec; |
1177 | 1193 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 1a3dbd1b196e..8cb2522d592a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4175,6 +4175,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4175 | 4175 | ||
4176 | /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */ | 4176 | /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */ |
4177 | { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA }, | 4177 | { "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA }, |
4178 | { "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA }, | ||
4178 | 4179 | ||
4179 | /* Blacklist entries taken from Silicon Image 3124/3132 | 4180 | /* Blacklist entries taken from Silicon Image 3124/3132 |
4180 | Windows driver .inf file - also several Linux problem reports */ | 4181 | Windows driver .inf file - also several Linux problem reports */ |
@@ -4224,7 +4225,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4224 | 4225 | ||
4225 | /* devices that don't properly handle queued TRIM commands */ | 4226 | /* devices that don't properly handle queued TRIM commands */ |
4226 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4227 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4227 | { "Crucial_CT???M500SSD1", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4228 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4228 | 4229 | ||
4229 | /* | 4230 | /* |
4230 | * Some WD SATA-I drives spin up and down erratically when the link | 4231 | * Some WD SATA-I drives spin up and down erratically when the link |
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 20fd337a5731..7ccc084bf1df 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c | |||
@@ -447,8 +447,11 @@ static void sata_pmp_quirks(struct ata_port *ap) | |||
447 | * otherwise. Don't try hard to recover it. | 447 | * otherwise. Don't try hard to recover it. |
448 | */ | 448 | */ |
449 | ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; | 449 | ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY; |
450 | } else if (vendor == 0x197b && devid == 0x2352) { | 450 | } else if (vendor == 0x197b && (devid == 0x2352 || devid == 0x0325)) { |
451 | /* chip found in Thermaltake BlackX Duet, jmicron JMB350? */ | 451 | /* |
452 | * 0x2352: found in Thermaltake BlackX Duet, jmicron JMB350? | ||
453 | * 0x0325: jmicron JMB394. | ||
454 | */ | ||
452 | ata_for_each_link(link, ap, EDGE) { | 455 | ata_for_each_link(link, ap, EDGE) { |
453 | /* SRST breaks detection and disks get misclassified | 456 | /* SRST breaks detection and disks get misclassified |
454 | * LPM disabled to avoid potential problems | 457 | * LPM disabled to avoid potential problems |
diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index 26386f0b89a8..b0b18ec5465f 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c | |||
@@ -119,7 +119,9 @@ static int pata_imx_probe(struct platform_device *pdev) | |||
119 | return PTR_ERR(priv->clk); | 119 | return PTR_ERR(priv->clk); |
120 | } | 120 | } |
121 | 121 | ||
122 | clk_prepare_enable(priv->clk); | 122 | ret = clk_prepare_enable(priv->clk); |
123 | if (ret) | ||
124 | return ret; | ||
123 | 125 | ||
124 | host = ata_host_alloc(&pdev->dev, 1); | 126 | host = ata_host_alloc(&pdev->dev, 1); |
125 | if (!host) { | 127 | if (!host) { |
@@ -212,7 +214,9 @@ static int pata_imx_resume(struct device *dev) | |||
212 | struct ata_host *host = dev_get_drvdata(dev); | 214 | struct ata_host *host = dev_get_drvdata(dev); |
213 | struct pata_imx_priv *priv = host->private_data; | 215 | struct pata_imx_priv *priv = host->private_data; |
214 | 216 | ||
215 | clk_prepare_enable(priv->clk); | 217 | int ret = clk_prepare_enable(priv->clk); |
218 | if (ret) | ||
219 | return ret; | ||
216 | 220 | ||
217 | __raw_writel(priv->ata_ctl, priv->host_regs + PATA_IMX_ATA_CONTROL); | 221 | __raw_writel(priv->ata_ctl, priv->host_regs + PATA_IMX_ATA_CONTROL); |
218 | 222 | ||
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 20a7517bd339..05c8a44adf8e 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -4104,7 +4104,6 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4104 | if (!hpriv->port_phys) | 4104 | if (!hpriv->port_phys) |
4105 | return -ENOMEM; | 4105 | return -ENOMEM; |
4106 | host->private_data = hpriv; | 4106 | host->private_data = hpriv; |
4107 | hpriv->n_ports = n_ports; | ||
4108 | hpriv->board_idx = chip_soc; | 4107 | hpriv->board_idx = chip_soc; |
4109 | 4108 | ||
4110 | host->iomap = NULL; | 4109 | host->iomap = NULL; |
@@ -4126,17 +4125,24 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4126 | clk_prepare_enable(hpriv->port_clks[port]); | 4125 | clk_prepare_enable(hpriv->port_clks[port]); |
4127 | 4126 | ||
4128 | sprintf(port_number, "port%d", port); | 4127 | sprintf(port_number, "port%d", port); |
4129 | hpriv->port_phys[port] = devm_phy_get(&pdev->dev, port_number); | 4128 | hpriv->port_phys[port] = devm_phy_optional_get(&pdev->dev, |
4129 | port_number); | ||
4130 | if (IS_ERR(hpriv->port_phys[port])) { | 4130 | if (IS_ERR(hpriv->port_phys[port])) { |
4131 | rc = PTR_ERR(hpriv->port_phys[port]); | 4131 | rc = PTR_ERR(hpriv->port_phys[port]); |
4132 | hpriv->port_phys[port] = NULL; | 4132 | hpriv->port_phys[port] = NULL; |
4133 | if ((rc != -EPROBE_DEFER) && (rc != -ENODEV)) | 4133 | if (rc != -EPROBE_DEFER) |
4134 | dev_warn(&pdev->dev, "error getting phy"); | 4134 | dev_warn(&pdev->dev, "error getting phy %d", rc); |
4135 | |||
4136 | /* Cleanup only the initialized ports */ | ||
4137 | hpriv->n_ports = port; | ||
4135 | goto err; | 4138 | goto err; |
4136 | } else | 4139 | } else |
4137 | phy_power_on(hpriv->port_phys[port]); | 4140 | phy_power_on(hpriv->port_phys[port]); |
4138 | } | 4141 | } |
4139 | 4142 | ||
4143 | /* All the ports have been initialized */ | ||
4144 | hpriv->n_ports = n_ports; | ||
4145 | |||
4140 | /* | 4146 | /* |
4141 | * (Re-)program MBUS remapping windows if we are asked to. | 4147 | * (Re-)program MBUS remapping windows if we are asked to. |
4142 | */ | 4148 | */ |
@@ -4174,7 +4180,7 @@ err: | |||
4174 | clk_disable_unprepare(hpriv->clk); | 4180 | clk_disable_unprepare(hpriv->clk); |
4175 | clk_put(hpriv->clk); | 4181 | clk_put(hpriv->clk); |
4176 | } | 4182 | } |
4177 | for (port = 0; port < n_ports; port++) { | 4183 | for (port = 0; port < hpriv->n_ports; port++) { |
4178 | if (!IS_ERR(hpriv->port_clks[port])) { | 4184 | if (!IS_ERR(hpriv->port_clks[port])) { |
4179 | clk_disable_unprepare(hpriv->port_clks[port]); | 4185 | clk_disable_unprepare(hpriv->port_clks[port]); |
4180 | clk_put(hpriv->port_clks[port]); | 4186 | clk_put(hpriv->port_clks[port]); |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index d67fc351343c..b7695e804635 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -157,6 +157,7 @@ static const struct sil_drivelist { | |||
157 | { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, | 157 | { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, |
158 | { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, | 158 | { "ST3120022ASL", SIL_QUIRK_MOD15WRITE }, |
159 | { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, | 159 | { "ST3160021ASL", SIL_QUIRK_MOD15WRITE }, |
160 | { "TOSHIBA MK2561GSYN", SIL_QUIRK_MOD15WRITE }, | ||
160 | { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, | 161 | { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX }, |
161 | { } | 162 | { } |
162 | }; | 163 | }; |
diff --git a/drivers/base/component.c b/drivers/base/component.c index c53efe6c6d8e..c4778995cd72 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c | |||
@@ -133,9 +133,16 @@ static int try_to_bring_up_master(struct master *master, | |||
133 | goto out; | 133 | goto out; |
134 | } | 134 | } |
135 | 135 | ||
136 | if (!devres_open_group(master->dev, NULL, GFP_KERNEL)) { | ||
137 | ret = -ENOMEM; | ||
138 | goto out; | ||
139 | } | ||
140 | |||
136 | /* Found all components */ | 141 | /* Found all components */ |
137 | ret = master->ops->bind(master->dev); | 142 | ret = master->ops->bind(master->dev); |
138 | if (ret < 0) { | 143 | if (ret < 0) { |
144 | devres_release_group(master->dev, NULL); | ||
145 | dev_info(master->dev, "master bind failed: %d\n", ret); | ||
139 | master_remove_components(master); | 146 | master_remove_components(master); |
140 | goto out; | 147 | goto out; |
141 | } | 148 | } |
@@ -166,6 +173,7 @@ static void take_down_master(struct master *master) | |||
166 | { | 173 | { |
167 | if (master->bound) { | 174 | if (master->bound) { |
168 | master->ops->unbind(master->dev); | 175 | master->ops->unbind(master->dev); |
176 | devres_release_group(master->dev, NULL); | ||
169 | master->bound = false; | 177 | master->bound = false; |
170 | } | 178 | } |
171 | 179 | ||
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 1e16cbd61da2..61d6d62cc0d3 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -616,36 +616,35 @@ static int dma_buf_describe(struct seq_file *s) | |||
616 | if (ret) | 616 | if (ret) |
617 | return ret; | 617 | return ret; |
618 | 618 | ||
619 | seq_printf(s, "\nDma-buf Objects:\n"); | 619 | seq_puts(s, "\nDma-buf Objects:\n"); |
620 | seq_printf(s, "\texp_name\tsize\tflags\tmode\tcount\n"); | 620 | seq_puts(s, "size\tflags\tmode\tcount\texp_name\n"); |
621 | 621 | ||
622 | list_for_each_entry(buf_obj, &db_list.head, list_node) { | 622 | list_for_each_entry(buf_obj, &db_list.head, list_node) { |
623 | ret = mutex_lock_interruptible(&buf_obj->lock); | 623 | ret = mutex_lock_interruptible(&buf_obj->lock); |
624 | 624 | ||
625 | if (ret) { | 625 | if (ret) { |
626 | seq_printf(s, | 626 | seq_puts(s, |
627 | "\tERROR locking buffer object: skipping\n"); | 627 | "\tERROR locking buffer object: skipping\n"); |
628 | continue; | 628 | continue; |
629 | } | 629 | } |
630 | 630 | ||
631 | seq_printf(s, "\t"); | 631 | seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\n", |
632 | 632 | buf_obj->size, | |
633 | seq_printf(s, "\t%s\t%08zu\t%08x\t%08x\t%08ld\n", | ||
634 | buf_obj->exp_name, buf_obj->size, | ||
635 | buf_obj->file->f_flags, buf_obj->file->f_mode, | 633 | buf_obj->file->f_flags, buf_obj->file->f_mode, |
636 | (long)(buf_obj->file->f_count.counter)); | 634 | (long)(buf_obj->file->f_count.counter), |
635 | buf_obj->exp_name); | ||
637 | 636 | ||
638 | seq_printf(s, "\t\tAttached Devices:\n"); | 637 | seq_puts(s, "\tAttached Devices:\n"); |
639 | attach_count = 0; | 638 | attach_count = 0; |
640 | 639 | ||
641 | list_for_each_entry(attach_obj, &buf_obj->attachments, node) { | 640 | list_for_each_entry(attach_obj, &buf_obj->attachments, node) { |
642 | seq_printf(s, "\t\t"); | 641 | seq_puts(s, "\t"); |
643 | 642 | ||
644 | seq_printf(s, "%s\n", attach_obj->dev->init_name); | 643 | seq_printf(s, "%s\n", dev_name(attach_obj->dev)); |
645 | attach_count++; | 644 | attach_count++; |
646 | } | 645 | } |
647 | 646 | ||
648 | seq_printf(s, "\n\t\tTotal %d devices attached\n", | 647 | seq_printf(s, "Total %d devices attached\n\n", |
649 | attach_count); | 648 | attach_count); |
650 | 649 | ||
651 | count++; | 650 | count++; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8a97ddfa6122..c30df50e4440 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -1580,6 +1580,7 @@ static int fw_pm_notify(struct notifier_block *notify_block, | |||
1580 | switch (mode) { | 1580 | switch (mode) { |
1581 | case PM_HIBERNATION_PREPARE: | 1581 | case PM_HIBERNATION_PREPARE: |
1582 | case PM_SUSPEND_PREPARE: | 1582 | case PM_SUSPEND_PREPARE: |
1583 | case PM_RESTORE_PREPARE: | ||
1583 | kill_requests_without_uevent(); | 1584 | kill_requests_without_uevent(); |
1584 | device_cache_fw_images(); | 1585 | device_cache_fw_images(); |
1585 | break; | 1586 | break; |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 8184451b57c0..422b7d84f686 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -874,7 +874,7 @@ bio_pageinc(struct bio *bio) | |||
874 | /* Non-zero page count for non-head members of | 874 | /* Non-zero page count for non-head members of |
875 | * compound pages is no longer allowed by the kernel. | 875 | * compound pages is no longer allowed by the kernel. |
876 | */ | 876 | */ |
877 | page = compound_trans_head(bv.bv_page); | 877 | page = compound_head(bv.bv_page); |
878 | atomic_inc(&page->_count); | 878 | atomic_inc(&page->_count); |
879 | } | 879 | } |
880 | } | 880 | } |
@@ -887,7 +887,7 @@ bio_pagedec(struct bio *bio) | |||
887 | struct bvec_iter iter; | 887 | struct bvec_iter iter; |
888 | 888 | ||
889 | bio_for_each_segment(bv, bio, iter) { | 889 | bio_for_each_segment(bv, bio, iter) { |
890 | page = compound_trans_head(bv.bv_page); | 890 | page = compound_head(bv.bv_page); |
891 | atomic_dec(&page->_count); | 891 | atomic_dec(&page->_count); |
892 | } | 892 | } |
893 | } | 893 | } |
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 516026954be6..d777bb7cea93 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -4498,7 +4498,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
4498 | } | 4498 | } |
4499 | dev_info(&pdev->dev, "NUMA node %d (closest: %d,%d, probe on %d:%d)\n", | 4499 | dev_info(&pdev->dev, "NUMA node %d (closest: %d,%d, probe on %d:%d)\n", |
4500 | my_node, pcibus_to_node(pdev->bus), dev_to_node(&pdev->dev), | 4500 | my_node, pcibus_to_node(pdev->bus), dev_to_node(&pdev->dev), |
4501 | cpu_to_node(smp_processor_id()), smp_processor_id()); | 4501 | cpu_to_node(raw_smp_processor_id()), raw_smp_processor_id()); |
4502 | 4502 | ||
4503 | dd = kzalloc_node(sizeof(struct driver_data), GFP_KERNEL, my_node); | 4503 | dd = kzalloc_node(sizeof(struct driver_data), GFP_KERNEL, my_node); |
4504 | if (dd == NULL) { | 4504 | if (dd == NULL) { |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index b52e9a6d6aad..54174cb32feb 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 | 53 | #define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 |
54 | 54 | ||
55 | /* unaligned IO handling */ | 55 | /* unaligned IO handling */ |
56 | #define MTIP_MAX_UNALIGNED_SLOTS 8 | 56 | #define MTIP_MAX_UNALIGNED_SLOTS 2 |
57 | 57 | ||
58 | /* Macro to extract the tag bit number from a tag value. */ | 58 | /* Macro to extract the tag bit number from a tag value. */ |
59 | #define MTIP_TAG_BIT(tag) (tag & 0x1F) | 59 | #define MTIP_TAG_BIT(tag) (tag & 0x1F) |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 3107282a9741..091b9ea14feb 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
@@ -60,7 +60,9 @@ enum { | |||
60 | NULL_IRQ_NONE = 0, | 60 | NULL_IRQ_NONE = 0, |
61 | NULL_IRQ_SOFTIRQ = 1, | 61 | NULL_IRQ_SOFTIRQ = 1, |
62 | NULL_IRQ_TIMER = 2, | 62 | NULL_IRQ_TIMER = 2, |
63 | }; | ||
63 | 64 | ||
65 | enum { | ||
64 | NULL_Q_BIO = 0, | 66 | NULL_Q_BIO = 0, |
65 | NULL_Q_RQ = 1, | 67 | NULL_Q_RQ = 1, |
66 | NULL_Q_MQ = 2, | 68 | NULL_Q_MQ = 2, |
@@ -172,18 +174,20 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) | |||
172 | 174 | ||
173 | static void end_cmd(struct nullb_cmd *cmd) | 175 | static void end_cmd(struct nullb_cmd *cmd) |
174 | { | 176 | { |
175 | if (cmd->rq) { | 177 | switch (queue_mode) { |
176 | if (queue_mode == NULL_Q_MQ) | 178 | case NULL_Q_MQ: |
177 | blk_mq_end_io(cmd->rq, 0); | 179 | blk_mq_end_io(cmd->rq, 0); |
178 | else { | 180 | return; |
179 | INIT_LIST_HEAD(&cmd->rq->queuelist); | 181 | case NULL_Q_RQ: |
180 | blk_end_request_all(cmd->rq, 0); | 182 | INIT_LIST_HEAD(&cmd->rq->queuelist); |
181 | } | 183 | blk_end_request_all(cmd->rq, 0); |
182 | } else if (cmd->bio) | 184 | break; |
185 | case NULL_Q_BIO: | ||
183 | bio_endio(cmd->bio, 0); | 186 | bio_endio(cmd->bio, 0); |
187 | break; | ||
188 | } | ||
184 | 189 | ||
185 | if (queue_mode != NULL_Q_MQ) | 190 | free_cmd(cmd); |
186 | free_cmd(cmd); | ||
187 | } | 191 | } |
188 | 192 | ||
189 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) | 193 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) |
@@ -195,6 +199,7 @@ static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) | |||
195 | cq = &per_cpu(completion_queues, smp_processor_id()); | 199 | cq = &per_cpu(completion_queues, smp_processor_id()); |
196 | 200 | ||
197 | while ((entry = llist_del_all(&cq->list)) != NULL) { | 201 | while ((entry = llist_del_all(&cq->list)) != NULL) { |
202 | entry = llist_reverse_order(entry); | ||
198 | do { | 203 | do { |
199 | cmd = container_of(entry, struct nullb_cmd, ll_list); | 204 | cmd = container_of(entry, struct nullb_cmd, ll_list); |
200 | end_cmd(cmd); | 205 | end_cmd(cmd); |
@@ -221,61 +226,31 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd) | |||
221 | 226 | ||
222 | static void null_softirq_done_fn(struct request *rq) | 227 | static void null_softirq_done_fn(struct request *rq) |
223 | { | 228 | { |
224 | blk_end_request_all(rq, 0); | 229 | end_cmd(rq->special); |
225 | } | ||
226 | |||
227 | #ifdef CONFIG_SMP | ||
228 | |||
229 | static void null_ipi_cmd_end_io(void *data) | ||
230 | { | ||
231 | struct completion_queue *cq; | ||
232 | struct llist_node *entry, *next; | ||
233 | struct nullb_cmd *cmd; | ||
234 | |||
235 | cq = &per_cpu(completion_queues, smp_processor_id()); | ||
236 | |||
237 | entry = llist_del_all(&cq->list); | ||
238 | |||
239 | while (entry) { | ||
240 | next = entry->next; | ||
241 | cmd = llist_entry(entry, struct nullb_cmd, ll_list); | ||
242 | end_cmd(cmd); | ||
243 | entry = next; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | static void null_cmd_end_ipi(struct nullb_cmd *cmd) | ||
248 | { | ||
249 | struct call_single_data *data = &cmd->csd; | ||
250 | int cpu = get_cpu(); | ||
251 | struct completion_queue *cq = &per_cpu(completion_queues, cpu); | ||
252 | |||
253 | cmd->ll_list.next = NULL; | ||
254 | |||
255 | if (llist_add(&cmd->ll_list, &cq->list)) { | ||
256 | data->func = null_ipi_cmd_end_io; | ||
257 | data->flags = 0; | ||
258 | __smp_call_function_single(cpu, data, 0); | ||
259 | } | ||
260 | |||
261 | put_cpu(); | ||
262 | } | 230 | } |
263 | 231 | ||
264 | #endif /* CONFIG_SMP */ | ||
265 | |||
266 | static inline void null_handle_cmd(struct nullb_cmd *cmd) | 232 | static inline void null_handle_cmd(struct nullb_cmd *cmd) |
267 | { | 233 | { |
268 | /* Complete IO by inline, softirq or timer */ | 234 | /* Complete IO by inline, softirq or timer */ |
269 | switch (irqmode) { | 235 | switch (irqmode) { |
270 | case NULL_IRQ_NONE: | ||
271 | end_cmd(cmd); | ||
272 | break; | ||
273 | case NULL_IRQ_SOFTIRQ: | 236 | case NULL_IRQ_SOFTIRQ: |
274 | #ifdef CONFIG_SMP | 237 | switch (queue_mode) { |
275 | null_cmd_end_ipi(cmd); | 238 | case NULL_Q_MQ: |
276 | #else | 239 | blk_mq_complete_request(cmd->rq); |
240 | break; | ||
241 | case NULL_Q_RQ: | ||
242 | blk_complete_request(cmd->rq); | ||
243 | break; | ||
244 | case NULL_Q_BIO: | ||
245 | /* | ||
246 | * XXX: no proper submitting cpu information available. | ||
247 | */ | ||
248 | end_cmd(cmd); | ||
249 | break; | ||
250 | } | ||
251 | break; | ||
252 | case NULL_IRQ_NONE: | ||
277 | end_cmd(cmd); | 253 | end_cmd(cmd); |
278 | #endif | ||
279 | break; | 254 | break; |
280 | case NULL_IRQ_TIMER: | 255 | case NULL_IRQ_TIMER: |
281 | null_cmd_end_timer(cmd); | 256 | null_cmd_end_timer(cmd); |
@@ -411,6 +386,7 @@ static struct blk_mq_ops null_mq_ops = { | |||
411 | .queue_rq = null_queue_rq, | 386 | .queue_rq = null_queue_rq, |
412 | .map_queue = blk_mq_map_queue, | 387 | .map_queue = blk_mq_map_queue, |
413 | .init_hctx = null_init_hctx, | 388 | .init_hctx = null_init_hctx, |
389 | .complete = null_softirq_done_fn, | ||
414 | }; | 390 | }; |
415 | 391 | ||
416 | static struct blk_mq_reg null_mq_reg = { | 392 | static struct blk_mq_reg null_mq_reg = { |
@@ -609,13 +585,6 @@ static int __init null_init(void) | |||
609 | { | 585 | { |
610 | unsigned int i; | 586 | unsigned int i; |
611 | 587 | ||
612 | #if !defined(CONFIG_SMP) | ||
613 | if (irqmode == NULL_IRQ_SOFTIRQ) { | ||
614 | pr_warn("null_blk: softirq completions not available.\n"); | ||
615 | pr_warn("null_blk: using direct completions.\n"); | ||
616 | irqmode = NULL_IRQ_NONE; | ||
617 | } | ||
618 | #endif | ||
619 | if (bs > PAGE_SIZE) { | 588 | if (bs > PAGE_SIZE) { |
620 | pr_warn("null_blk: invalid block size\n"); | 589 | pr_warn("null_blk: invalid block size\n"); |
621 | pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE); | 590 | pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE); |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index 1f14ac403945..51824d1f23ea 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #define NVME_Q_DEPTH 1024 | 46 | #define NVME_Q_DEPTH 1024 |
47 | #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) | 47 | #define SQ_SIZE(depth) (depth * sizeof(struct nvme_command)) |
48 | #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) | 48 | #define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion)) |
49 | #define NVME_MINORS 64 | ||
50 | #define ADMIN_TIMEOUT (60 * HZ) | 49 | #define ADMIN_TIMEOUT (60 * HZ) |
51 | 50 | ||
52 | static int nvme_major; | 51 | static int nvme_major; |
@@ -58,6 +57,17 @@ module_param(use_threaded_interrupts, int, 0); | |||
58 | static DEFINE_SPINLOCK(dev_list_lock); | 57 | static DEFINE_SPINLOCK(dev_list_lock); |
59 | static LIST_HEAD(dev_list); | 58 | static LIST_HEAD(dev_list); |
60 | static struct task_struct *nvme_thread; | 59 | static struct task_struct *nvme_thread; |
60 | static struct workqueue_struct *nvme_workq; | ||
61 | |||
62 | static void nvme_reset_failed_dev(struct work_struct *ws); | ||
63 | |||
64 | struct async_cmd_info { | ||
65 | struct kthread_work work; | ||
66 | struct kthread_worker *worker; | ||
67 | u32 result; | ||
68 | int status; | ||
69 | void *ctx; | ||
70 | }; | ||
61 | 71 | ||
62 | /* | 72 | /* |
63 | * An NVM Express queue. Each device has at least two (one for admin | 73 | * An NVM Express queue. Each device has at least two (one for admin |
@@ -66,6 +76,7 @@ static struct task_struct *nvme_thread; | |||
66 | struct nvme_queue { | 76 | struct nvme_queue { |
67 | struct device *q_dmadev; | 77 | struct device *q_dmadev; |
68 | struct nvme_dev *dev; | 78 | struct nvme_dev *dev; |
79 | char irqname[24]; /* nvme4294967295-65535\0 */ | ||
69 | spinlock_t q_lock; | 80 | spinlock_t q_lock; |
70 | struct nvme_command *sq_cmds; | 81 | struct nvme_command *sq_cmds; |
71 | volatile struct nvme_completion *cqes; | 82 | volatile struct nvme_completion *cqes; |
@@ -80,9 +91,11 @@ struct nvme_queue { | |||
80 | u16 sq_head; | 91 | u16 sq_head; |
81 | u16 sq_tail; | 92 | u16 sq_tail; |
82 | u16 cq_head; | 93 | u16 cq_head; |
94 | u16 qid; | ||
83 | u8 cq_phase; | 95 | u8 cq_phase; |
84 | u8 cqe_seen; | 96 | u8 cqe_seen; |
85 | u8 q_suspended; | 97 | u8 q_suspended; |
98 | struct async_cmd_info cmdinfo; | ||
86 | unsigned long cmdid_data[]; | 99 | unsigned long cmdid_data[]; |
87 | }; | 100 | }; |
88 | 101 | ||
@@ -97,6 +110,7 @@ static inline void _nvme_check_size(void) | |||
97 | BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64); | 110 | BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64); |
98 | BUILD_BUG_ON(sizeof(struct nvme_features) != 64); | 111 | BUILD_BUG_ON(sizeof(struct nvme_features) != 64); |
99 | BUILD_BUG_ON(sizeof(struct nvme_format_cmd) != 64); | 112 | BUILD_BUG_ON(sizeof(struct nvme_format_cmd) != 64); |
113 | BUILD_BUG_ON(sizeof(struct nvme_abort_cmd) != 64); | ||
100 | BUILD_BUG_ON(sizeof(struct nvme_command) != 64); | 114 | BUILD_BUG_ON(sizeof(struct nvme_command) != 64); |
101 | BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); | 115 | BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); |
102 | BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); | 116 | BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); |
@@ -111,6 +125,7 @@ struct nvme_cmd_info { | |||
111 | nvme_completion_fn fn; | 125 | nvme_completion_fn fn; |
112 | void *ctx; | 126 | void *ctx; |
113 | unsigned long timeout; | 127 | unsigned long timeout; |
128 | int aborted; | ||
114 | }; | 129 | }; |
115 | 130 | ||
116 | static struct nvme_cmd_info *nvme_cmd_info(struct nvme_queue *nvmeq) | 131 | static struct nvme_cmd_info *nvme_cmd_info(struct nvme_queue *nvmeq) |
@@ -154,6 +169,7 @@ static int alloc_cmdid(struct nvme_queue *nvmeq, void *ctx, | |||
154 | info[cmdid].fn = handler; | 169 | info[cmdid].fn = handler; |
155 | info[cmdid].ctx = ctx; | 170 | info[cmdid].ctx = ctx; |
156 | info[cmdid].timeout = jiffies + timeout; | 171 | info[cmdid].timeout = jiffies + timeout; |
172 | info[cmdid].aborted = 0; | ||
157 | return cmdid; | 173 | return cmdid; |
158 | } | 174 | } |
159 | 175 | ||
@@ -172,6 +188,7 @@ static int alloc_cmdid_killable(struct nvme_queue *nvmeq, void *ctx, | |||
172 | #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) | 188 | #define CMD_CTX_COMPLETED (0x310 + CMD_CTX_BASE) |
173 | #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) | 189 | #define CMD_CTX_INVALID (0x314 + CMD_CTX_BASE) |
174 | #define CMD_CTX_FLUSH (0x318 + CMD_CTX_BASE) | 190 | #define CMD_CTX_FLUSH (0x318 + CMD_CTX_BASE) |
191 | #define CMD_CTX_ABORT (0x31C + CMD_CTX_BASE) | ||
175 | 192 | ||
176 | static void special_completion(struct nvme_dev *dev, void *ctx, | 193 | static void special_completion(struct nvme_dev *dev, void *ctx, |
177 | struct nvme_completion *cqe) | 194 | struct nvme_completion *cqe) |
@@ -180,6 +197,10 @@ static void special_completion(struct nvme_dev *dev, void *ctx, | |||
180 | return; | 197 | return; |
181 | if (ctx == CMD_CTX_FLUSH) | 198 | if (ctx == CMD_CTX_FLUSH) |
182 | return; | 199 | return; |
200 | if (ctx == CMD_CTX_ABORT) { | ||
201 | ++dev->abort_limit; | ||
202 | return; | ||
203 | } | ||
183 | if (ctx == CMD_CTX_COMPLETED) { | 204 | if (ctx == CMD_CTX_COMPLETED) { |
184 | dev_warn(&dev->pci_dev->dev, | 205 | dev_warn(&dev->pci_dev->dev, |
185 | "completed id %d twice on queue %d\n", | 206 | "completed id %d twice on queue %d\n", |
@@ -196,6 +217,15 @@ static void special_completion(struct nvme_dev *dev, void *ctx, | |||
196 | dev_warn(&dev->pci_dev->dev, "Unknown special completion %p\n", ctx); | 217 | dev_warn(&dev->pci_dev->dev, "Unknown special completion %p\n", ctx); |
197 | } | 218 | } |
198 | 219 | ||
220 | static void async_completion(struct nvme_dev *dev, void *ctx, | ||
221 | struct nvme_completion *cqe) | ||
222 | { | ||
223 | struct async_cmd_info *cmdinfo = ctx; | ||
224 | cmdinfo->result = le32_to_cpup(&cqe->result); | ||
225 | cmdinfo->status = le16_to_cpup(&cqe->status) >> 1; | ||
226 | queue_kthread_work(cmdinfo->worker, &cmdinfo->work); | ||
227 | } | ||
228 | |||
199 | /* | 229 | /* |
200 | * Called with local interrupts disabled and the q_lock held. May not sleep. | 230 | * Called with local interrupts disabled and the q_lock held. May not sleep. |
201 | */ | 231 | */ |
@@ -693,7 +723,7 @@ static int nvme_process_cq(struct nvme_queue *nvmeq) | |||
693 | if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) | 723 | if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) |
694 | return 0; | 724 | return 0; |
695 | 725 | ||
696 | writel(head, nvmeq->q_db + (1 << nvmeq->dev->db_stride)); | 726 | writel(head, nvmeq->q_db + nvmeq->dev->db_stride); |
697 | nvmeq->cq_head = head; | 727 | nvmeq->cq_head = head; |
698 | nvmeq->cq_phase = phase; | 728 | nvmeq->cq_phase = phase; |
699 | 729 | ||
@@ -804,12 +834,34 @@ int nvme_submit_sync_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd, | |||
804 | return cmdinfo.status; | 834 | return cmdinfo.status; |
805 | } | 835 | } |
806 | 836 | ||
837 | static int nvme_submit_async_cmd(struct nvme_queue *nvmeq, | ||
838 | struct nvme_command *cmd, | ||
839 | struct async_cmd_info *cmdinfo, unsigned timeout) | ||
840 | { | ||
841 | int cmdid; | ||
842 | |||
843 | cmdid = alloc_cmdid_killable(nvmeq, cmdinfo, async_completion, timeout); | ||
844 | if (cmdid < 0) | ||
845 | return cmdid; | ||
846 | cmdinfo->status = -EINTR; | ||
847 | cmd->common.command_id = cmdid; | ||
848 | nvme_submit_cmd(nvmeq, cmd); | ||
849 | return 0; | ||
850 | } | ||
851 | |||
807 | int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, | 852 | int nvme_submit_admin_cmd(struct nvme_dev *dev, struct nvme_command *cmd, |
808 | u32 *result) | 853 | u32 *result) |
809 | { | 854 | { |
810 | return nvme_submit_sync_cmd(dev->queues[0], cmd, result, ADMIN_TIMEOUT); | 855 | return nvme_submit_sync_cmd(dev->queues[0], cmd, result, ADMIN_TIMEOUT); |
811 | } | 856 | } |
812 | 857 | ||
858 | static int nvme_submit_admin_cmd_async(struct nvme_dev *dev, | ||
859 | struct nvme_command *cmd, struct async_cmd_info *cmdinfo) | ||
860 | { | ||
861 | return nvme_submit_async_cmd(dev->queues[0], cmd, cmdinfo, | ||
862 | ADMIN_TIMEOUT); | ||
863 | } | ||
864 | |||
813 | static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) | 865 | static int adapter_delete_queue(struct nvme_dev *dev, u8 opcode, u16 id) |
814 | { | 866 | { |
815 | int status; | 867 | int status; |
@@ -920,6 +972,56 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, | |||
920 | } | 972 | } |
921 | 973 | ||
922 | /** | 974 | /** |
975 | * nvme_abort_cmd - Attempt aborting a command | ||
976 | * @cmdid: Command id of a timed out IO | ||
977 | * @queue: The queue with timed out IO | ||
978 | * | ||
979 | * Schedule controller reset if the command was already aborted once before and | ||
980 | * still hasn't been returned to the driver, or if this is the admin queue. | ||
981 | */ | ||
982 | static void nvme_abort_cmd(int cmdid, struct nvme_queue *nvmeq) | ||
983 | { | ||
984 | int a_cmdid; | ||
985 | struct nvme_command cmd; | ||
986 | struct nvme_dev *dev = nvmeq->dev; | ||
987 | struct nvme_cmd_info *info = nvme_cmd_info(nvmeq); | ||
988 | |||
989 | if (!nvmeq->qid || info[cmdid].aborted) { | ||
990 | if (work_busy(&dev->reset_work)) | ||
991 | return; | ||
992 | list_del_init(&dev->node); | ||
993 | dev_warn(&dev->pci_dev->dev, | ||
994 | "I/O %d QID %d timeout, reset controller\n", cmdid, | ||
995 | nvmeq->qid); | ||
996 | PREPARE_WORK(&dev->reset_work, nvme_reset_failed_dev); | ||
997 | queue_work(nvme_workq, &dev->reset_work); | ||
998 | return; | ||
999 | } | ||
1000 | |||
1001 | if (!dev->abort_limit) | ||
1002 | return; | ||
1003 | |||
1004 | a_cmdid = alloc_cmdid(dev->queues[0], CMD_CTX_ABORT, special_completion, | ||
1005 | ADMIN_TIMEOUT); | ||
1006 | if (a_cmdid < 0) | ||
1007 | return; | ||
1008 | |||
1009 | memset(&cmd, 0, sizeof(cmd)); | ||
1010 | cmd.abort.opcode = nvme_admin_abort_cmd; | ||
1011 | cmd.abort.cid = cmdid; | ||
1012 | cmd.abort.sqid = cpu_to_le16(nvmeq->qid); | ||
1013 | cmd.abort.command_id = a_cmdid; | ||
1014 | |||
1015 | --dev->abort_limit; | ||
1016 | info[cmdid].aborted = 1; | ||
1017 | info[cmdid].timeout = jiffies + ADMIN_TIMEOUT; | ||
1018 | |||
1019 | dev_warn(nvmeq->q_dmadev, "Aborting I/O %d QID %d\n", cmdid, | ||
1020 | nvmeq->qid); | ||
1021 | nvme_submit_cmd(dev->queues[0], &cmd); | ||
1022 | } | ||
1023 | |||
1024 | /** | ||
923 | * nvme_cancel_ios - Cancel outstanding I/Os | 1025 | * nvme_cancel_ios - Cancel outstanding I/Os |
924 | * @queue: The queue to cancel I/Os on | 1026 | * @queue: The queue to cancel I/Os on |
925 | * @timeout: True to only cancel I/Os which have timed out | 1027 | * @timeout: True to only cancel I/Os which have timed out |
@@ -942,7 +1044,12 @@ static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout) | |||
942 | continue; | 1044 | continue; |
943 | if (info[cmdid].ctx == CMD_CTX_CANCELLED) | 1045 | if (info[cmdid].ctx == CMD_CTX_CANCELLED) |
944 | continue; | 1046 | continue; |
945 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid); | 1047 | if (timeout && nvmeq->dev->initialized) { |
1048 | nvme_abort_cmd(cmdid, nvmeq); | ||
1049 | continue; | ||
1050 | } | ||
1051 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", cmdid, | ||
1052 | nvmeq->qid); | ||
946 | ctx = cancel_cmdid(nvmeq, cmdid, &fn); | 1053 | ctx = cancel_cmdid(nvmeq, cmdid, &fn); |
947 | fn(nvmeq->dev, ctx, &cqe); | 1054 | fn(nvmeq->dev, ctx, &cqe); |
948 | } | 1055 | } |
@@ -964,26 +1071,31 @@ static void nvme_free_queue(struct nvme_queue *nvmeq) | |||
964 | kfree(nvmeq); | 1071 | kfree(nvmeq); |
965 | } | 1072 | } |
966 | 1073 | ||
967 | static void nvme_free_queues(struct nvme_dev *dev) | 1074 | static void nvme_free_queues(struct nvme_dev *dev, int lowest) |
968 | { | 1075 | { |
969 | int i; | 1076 | int i; |
970 | 1077 | ||
971 | for (i = dev->queue_count - 1; i >= 0; i--) { | 1078 | for (i = dev->queue_count - 1; i >= lowest; i--) { |
972 | nvme_free_queue(dev->queues[i]); | 1079 | nvme_free_queue(dev->queues[i]); |
973 | dev->queue_count--; | 1080 | dev->queue_count--; |
974 | dev->queues[i] = NULL; | 1081 | dev->queues[i] = NULL; |
975 | } | 1082 | } |
976 | } | 1083 | } |
977 | 1084 | ||
978 | static void nvme_disable_queue(struct nvme_dev *dev, int qid) | 1085 | /** |
1086 | * nvme_suspend_queue - put queue into suspended state | ||
1087 | * @nvmeq - queue to suspend | ||
1088 | * | ||
1089 | * Returns 1 if already suspended, 0 otherwise. | ||
1090 | */ | ||
1091 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) | ||
979 | { | 1092 | { |
980 | struct nvme_queue *nvmeq = dev->queues[qid]; | 1093 | int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; |
981 | int vector = dev->entry[nvmeq->cq_vector].vector; | ||
982 | 1094 | ||
983 | spin_lock_irq(&nvmeq->q_lock); | 1095 | spin_lock_irq(&nvmeq->q_lock); |
984 | if (nvmeq->q_suspended) { | 1096 | if (nvmeq->q_suspended) { |
985 | spin_unlock_irq(&nvmeq->q_lock); | 1097 | spin_unlock_irq(&nvmeq->q_lock); |
986 | return; | 1098 | return 1; |
987 | } | 1099 | } |
988 | nvmeq->q_suspended = 1; | 1100 | nvmeq->q_suspended = 1; |
989 | spin_unlock_irq(&nvmeq->q_lock); | 1101 | spin_unlock_irq(&nvmeq->q_lock); |
@@ -991,18 +1103,35 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) | |||
991 | irq_set_affinity_hint(vector, NULL); | 1103 | irq_set_affinity_hint(vector, NULL); |
992 | free_irq(vector, nvmeq); | 1104 | free_irq(vector, nvmeq); |
993 | 1105 | ||
994 | /* Don't tell the adapter to delete the admin queue */ | 1106 | return 0; |
995 | if (qid) { | 1107 | } |
996 | adapter_delete_sq(dev, qid); | ||
997 | adapter_delete_cq(dev, qid); | ||
998 | } | ||
999 | 1108 | ||
1109 | static void nvme_clear_queue(struct nvme_queue *nvmeq) | ||
1110 | { | ||
1000 | spin_lock_irq(&nvmeq->q_lock); | 1111 | spin_lock_irq(&nvmeq->q_lock); |
1001 | nvme_process_cq(nvmeq); | 1112 | nvme_process_cq(nvmeq); |
1002 | nvme_cancel_ios(nvmeq, false); | 1113 | nvme_cancel_ios(nvmeq, false); |
1003 | spin_unlock_irq(&nvmeq->q_lock); | 1114 | spin_unlock_irq(&nvmeq->q_lock); |
1004 | } | 1115 | } |
1005 | 1116 | ||
1117 | static void nvme_disable_queue(struct nvme_dev *dev, int qid) | ||
1118 | { | ||
1119 | struct nvme_queue *nvmeq = dev->queues[qid]; | ||
1120 | |||
1121 | if (!nvmeq) | ||
1122 | return; | ||
1123 | if (nvme_suspend_queue(nvmeq)) | ||
1124 | return; | ||
1125 | |||
1126 | /* Don't tell the adapter to delete the admin queue. | ||
1127 | * Don't tell a removed adapter to delete IO queues. */ | ||
1128 | if (qid && readl(&dev->bar->csts) != -1) { | ||
1129 | adapter_delete_sq(dev, qid); | ||
1130 | adapter_delete_cq(dev, qid); | ||
1131 | } | ||
1132 | nvme_clear_queue(nvmeq); | ||
1133 | } | ||
1134 | |||
1006 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 1135 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
1007 | int depth, int vector) | 1136 | int depth, int vector) |
1008 | { | 1137 | { |
@@ -1025,15 +1154,18 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | |||
1025 | 1154 | ||
1026 | nvmeq->q_dmadev = dmadev; | 1155 | nvmeq->q_dmadev = dmadev; |
1027 | nvmeq->dev = dev; | 1156 | nvmeq->dev = dev; |
1157 | snprintf(nvmeq->irqname, sizeof(nvmeq->irqname), "nvme%dq%d", | ||
1158 | dev->instance, qid); | ||
1028 | spin_lock_init(&nvmeq->q_lock); | 1159 | spin_lock_init(&nvmeq->q_lock); |
1029 | nvmeq->cq_head = 0; | 1160 | nvmeq->cq_head = 0; |
1030 | nvmeq->cq_phase = 1; | 1161 | nvmeq->cq_phase = 1; |
1031 | init_waitqueue_head(&nvmeq->sq_full); | 1162 | init_waitqueue_head(&nvmeq->sq_full); |
1032 | init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); | 1163 | init_waitqueue_entry(&nvmeq->sq_cong_wait, nvme_thread); |
1033 | bio_list_init(&nvmeq->sq_cong); | 1164 | bio_list_init(&nvmeq->sq_cong); |
1034 | nvmeq->q_db = &dev->dbs[qid << (dev->db_stride + 1)]; | 1165 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
1035 | nvmeq->q_depth = depth; | 1166 | nvmeq->q_depth = depth; |
1036 | nvmeq->cq_vector = vector; | 1167 | nvmeq->cq_vector = vector; |
1168 | nvmeq->qid = qid; | ||
1037 | nvmeq->q_suspended = 1; | 1169 | nvmeq->q_suspended = 1; |
1038 | dev->queue_count++; | 1170 | dev->queue_count++; |
1039 | 1171 | ||
@@ -1052,11 +1184,10 @@ static int queue_request_irq(struct nvme_dev *dev, struct nvme_queue *nvmeq, | |||
1052 | { | 1184 | { |
1053 | if (use_threaded_interrupts) | 1185 | if (use_threaded_interrupts) |
1054 | return request_threaded_irq(dev->entry[nvmeq->cq_vector].vector, | 1186 | return request_threaded_irq(dev->entry[nvmeq->cq_vector].vector, |
1055 | nvme_irq_check, nvme_irq, | 1187 | nvme_irq_check, nvme_irq, IRQF_SHARED, |
1056 | IRQF_DISABLED | IRQF_SHARED, | ||
1057 | name, nvmeq); | 1188 | name, nvmeq); |
1058 | return request_irq(dev->entry[nvmeq->cq_vector].vector, nvme_irq, | 1189 | return request_irq(dev->entry[nvmeq->cq_vector].vector, nvme_irq, |
1059 | IRQF_DISABLED | IRQF_SHARED, name, nvmeq); | 1190 | IRQF_SHARED, name, nvmeq); |
1060 | } | 1191 | } |
1061 | 1192 | ||
1062 | static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) | 1193 | static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) |
@@ -1067,7 +1198,7 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid) | |||
1067 | nvmeq->sq_tail = 0; | 1198 | nvmeq->sq_tail = 0; |
1068 | nvmeq->cq_head = 0; | 1199 | nvmeq->cq_head = 0; |
1069 | nvmeq->cq_phase = 1; | 1200 | nvmeq->cq_phase = 1; |
1070 | nvmeq->q_db = &dev->dbs[qid << (dev->db_stride + 1)]; | 1201 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
1071 | memset(nvmeq->cmdid_data, 0, extra); | 1202 | memset(nvmeq->cmdid_data, 0, extra); |
1072 | memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); | 1203 | memset((void *)nvmeq->cqes, 0, CQ_SIZE(nvmeq->q_depth)); |
1073 | nvme_cancel_ios(nvmeq, false); | 1204 | nvme_cancel_ios(nvmeq, false); |
@@ -1087,13 +1218,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
1087 | if (result < 0) | 1218 | if (result < 0) |
1088 | goto release_cq; | 1219 | goto release_cq; |
1089 | 1220 | ||
1090 | result = queue_request_irq(dev, nvmeq, "nvme"); | 1221 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
1091 | if (result < 0) | 1222 | if (result < 0) |
1092 | goto release_sq; | 1223 | goto release_sq; |
1093 | 1224 | ||
1094 | spin_lock(&nvmeq->q_lock); | 1225 | spin_lock_irq(&nvmeq->q_lock); |
1095 | nvme_init_queue(nvmeq, qid); | 1226 | nvme_init_queue(nvmeq, qid); |
1096 | spin_unlock(&nvmeq->q_lock); | 1227 | spin_unlock_irq(&nvmeq->q_lock); |
1097 | 1228 | ||
1098 | return result; | 1229 | return result; |
1099 | 1230 | ||
@@ -1205,13 +1336,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
1205 | if (result) | 1336 | if (result) |
1206 | return result; | 1337 | return result; |
1207 | 1338 | ||
1208 | result = queue_request_irq(dev, nvmeq, "nvme admin"); | 1339 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
1209 | if (result) | 1340 | if (result) |
1210 | return result; | 1341 | return result; |
1211 | 1342 | ||
1212 | spin_lock(&nvmeq->q_lock); | 1343 | spin_lock_irq(&nvmeq->q_lock); |
1213 | nvme_init_queue(nvmeq, 0); | 1344 | nvme_init_queue(nvmeq, 0); |
1214 | spin_unlock(&nvmeq->q_lock); | 1345 | spin_unlock_irq(&nvmeq->q_lock); |
1215 | return result; | 1346 | return result; |
1216 | } | 1347 | } |
1217 | 1348 | ||
@@ -1487,10 +1618,47 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
1487 | } | 1618 | } |
1488 | } | 1619 | } |
1489 | 1620 | ||
1621 | #ifdef CONFIG_COMPAT | ||
1622 | static int nvme_compat_ioctl(struct block_device *bdev, fmode_t mode, | ||
1623 | unsigned int cmd, unsigned long arg) | ||
1624 | { | ||
1625 | struct nvme_ns *ns = bdev->bd_disk->private_data; | ||
1626 | |||
1627 | switch (cmd) { | ||
1628 | case SG_IO: | ||
1629 | return nvme_sg_io32(ns, arg); | ||
1630 | } | ||
1631 | return nvme_ioctl(bdev, mode, cmd, arg); | ||
1632 | } | ||
1633 | #else | ||
1634 | #define nvme_compat_ioctl NULL | ||
1635 | #endif | ||
1636 | |||
1637 | static int nvme_open(struct block_device *bdev, fmode_t mode) | ||
1638 | { | ||
1639 | struct nvme_ns *ns = bdev->bd_disk->private_data; | ||
1640 | struct nvme_dev *dev = ns->dev; | ||
1641 | |||
1642 | kref_get(&dev->kref); | ||
1643 | return 0; | ||
1644 | } | ||
1645 | |||
1646 | static void nvme_free_dev(struct kref *kref); | ||
1647 | |||
1648 | static void nvme_release(struct gendisk *disk, fmode_t mode) | ||
1649 | { | ||
1650 | struct nvme_ns *ns = disk->private_data; | ||
1651 | struct nvme_dev *dev = ns->dev; | ||
1652 | |||
1653 | kref_put(&dev->kref, nvme_free_dev); | ||
1654 | } | ||
1655 | |||
1490 | static const struct block_device_operations nvme_fops = { | 1656 | static const struct block_device_operations nvme_fops = { |
1491 | .owner = THIS_MODULE, | 1657 | .owner = THIS_MODULE, |
1492 | .ioctl = nvme_ioctl, | 1658 | .ioctl = nvme_ioctl, |
1493 | .compat_ioctl = nvme_ioctl, | 1659 | .compat_ioctl = nvme_compat_ioctl, |
1660 | .open = nvme_open, | ||
1661 | .release = nvme_release, | ||
1494 | }; | 1662 | }; |
1495 | 1663 | ||
1496 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) | 1664 | static void nvme_resubmit_bios(struct nvme_queue *nvmeq) |
@@ -1514,13 +1682,25 @@ static void nvme_resubmit_bios(struct nvme_queue *nvmeq) | |||
1514 | 1682 | ||
1515 | static int nvme_kthread(void *data) | 1683 | static int nvme_kthread(void *data) |
1516 | { | 1684 | { |
1517 | struct nvme_dev *dev; | 1685 | struct nvme_dev *dev, *next; |
1518 | 1686 | ||
1519 | while (!kthread_should_stop()) { | 1687 | while (!kthread_should_stop()) { |
1520 | set_current_state(TASK_INTERRUPTIBLE); | 1688 | set_current_state(TASK_INTERRUPTIBLE); |
1521 | spin_lock(&dev_list_lock); | 1689 | spin_lock(&dev_list_lock); |
1522 | list_for_each_entry(dev, &dev_list, node) { | 1690 | list_for_each_entry_safe(dev, next, &dev_list, node) { |
1523 | int i; | 1691 | int i; |
1692 | if (readl(&dev->bar->csts) & NVME_CSTS_CFS && | ||
1693 | dev->initialized) { | ||
1694 | if (work_busy(&dev->reset_work)) | ||
1695 | continue; | ||
1696 | list_del_init(&dev->node); | ||
1697 | dev_warn(&dev->pci_dev->dev, | ||
1698 | "Failed status, reset controller\n"); | ||
1699 | PREPARE_WORK(&dev->reset_work, | ||
1700 | nvme_reset_failed_dev); | ||
1701 | queue_work(nvme_workq, &dev->reset_work); | ||
1702 | continue; | ||
1703 | } | ||
1524 | for (i = 0; i < dev->queue_count; i++) { | 1704 | for (i = 0; i < dev->queue_count; i++) { |
1525 | struct nvme_queue *nvmeq = dev->queues[i]; | 1705 | struct nvme_queue *nvmeq = dev->queues[i]; |
1526 | if (!nvmeq) | 1706 | if (!nvmeq) |
@@ -1541,33 +1721,6 @@ static int nvme_kthread(void *data) | |||
1541 | return 0; | 1721 | return 0; |
1542 | } | 1722 | } |
1543 | 1723 | ||
1544 | static DEFINE_IDA(nvme_index_ida); | ||
1545 | |||
1546 | static int nvme_get_ns_idx(void) | ||
1547 | { | ||
1548 | int index, error; | ||
1549 | |||
1550 | do { | ||
1551 | if (!ida_pre_get(&nvme_index_ida, GFP_KERNEL)) | ||
1552 | return -1; | ||
1553 | |||
1554 | spin_lock(&dev_list_lock); | ||
1555 | error = ida_get_new(&nvme_index_ida, &index); | ||
1556 | spin_unlock(&dev_list_lock); | ||
1557 | } while (error == -EAGAIN); | ||
1558 | |||
1559 | if (error) | ||
1560 | index = -1; | ||
1561 | return index; | ||
1562 | } | ||
1563 | |||
1564 | static void nvme_put_ns_idx(int index) | ||
1565 | { | ||
1566 | spin_lock(&dev_list_lock); | ||
1567 | ida_remove(&nvme_index_ida, index); | ||
1568 | spin_unlock(&dev_list_lock); | ||
1569 | } | ||
1570 | |||
1571 | static void nvme_config_discard(struct nvme_ns *ns) | 1724 | static void nvme_config_discard(struct nvme_ns *ns) |
1572 | { | 1725 | { |
1573 | u32 logical_block_size = queue_logical_block_size(ns->queue); | 1726 | u32 logical_block_size = queue_logical_block_size(ns->queue); |
@@ -1601,7 +1754,7 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1601 | ns->dev = dev; | 1754 | ns->dev = dev; |
1602 | ns->queue->queuedata = ns; | 1755 | ns->queue->queuedata = ns; |
1603 | 1756 | ||
1604 | disk = alloc_disk(NVME_MINORS); | 1757 | disk = alloc_disk(0); |
1605 | if (!disk) | 1758 | if (!disk) |
1606 | goto out_free_queue; | 1759 | goto out_free_queue; |
1607 | ns->ns_id = nsid; | 1760 | ns->ns_id = nsid; |
@@ -1614,12 +1767,12 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1614 | blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); | 1767 | blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors); |
1615 | 1768 | ||
1616 | disk->major = nvme_major; | 1769 | disk->major = nvme_major; |
1617 | disk->minors = NVME_MINORS; | 1770 | disk->first_minor = 0; |
1618 | disk->first_minor = NVME_MINORS * nvme_get_ns_idx(); | ||
1619 | disk->fops = &nvme_fops; | 1771 | disk->fops = &nvme_fops; |
1620 | disk->private_data = ns; | 1772 | disk->private_data = ns; |
1621 | disk->queue = ns->queue; | 1773 | disk->queue = ns->queue; |
1622 | disk->driverfs_dev = &dev->pci_dev->dev; | 1774 | disk->driverfs_dev = &dev->pci_dev->dev; |
1775 | disk->flags = GENHD_FL_EXT_DEVT; | ||
1623 | sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid); | 1776 | sprintf(disk->disk_name, "nvme%dn%d", dev->instance, nsid); |
1624 | set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); | 1777 | set_capacity(disk, le64_to_cpup(&id->nsze) << (ns->lba_shift - 9)); |
1625 | 1778 | ||
@@ -1635,15 +1788,6 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, unsigned nsid, | |||
1635 | return NULL; | 1788 | return NULL; |
1636 | } | 1789 | } |
1637 | 1790 | ||
1638 | static void nvme_ns_free(struct nvme_ns *ns) | ||
1639 | { | ||
1640 | int index = ns->disk->first_minor / NVME_MINORS; | ||
1641 | put_disk(ns->disk); | ||
1642 | nvme_put_ns_idx(index); | ||
1643 | blk_cleanup_queue(ns->queue); | ||
1644 | kfree(ns); | ||
1645 | } | ||
1646 | |||
1647 | static int set_queue_count(struct nvme_dev *dev, int count) | 1791 | static int set_queue_count(struct nvme_dev *dev, int count) |
1648 | { | 1792 | { |
1649 | int status; | 1793 | int status; |
@@ -1659,11 +1803,12 @@ static int set_queue_count(struct nvme_dev *dev, int count) | |||
1659 | 1803 | ||
1660 | static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues) | 1804 | static size_t db_bar_size(struct nvme_dev *dev, unsigned nr_io_queues) |
1661 | { | 1805 | { |
1662 | return 4096 + ((nr_io_queues + 1) << (dev->db_stride + 3)); | 1806 | return 4096 + ((nr_io_queues + 1) * 8 * dev->db_stride); |
1663 | } | 1807 | } |
1664 | 1808 | ||
1665 | static int nvme_setup_io_queues(struct nvme_dev *dev) | 1809 | static int nvme_setup_io_queues(struct nvme_dev *dev) |
1666 | { | 1810 | { |
1811 | struct nvme_queue *adminq = dev->queues[0]; | ||
1667 | struct pci_dev *pdev = dev->pci_dev; | 1812 | struct pci_dev *pdev = dev->pci_dev; |
1668 | int result, cpu, i, vecs, nr_io_queues, size, q_depth; | 1813 | int result, cpu, i, vecs, nr_io_queues, size, q_depth; |
1669 | 1814 | ||
@@ -1690,7 +1835,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1690 | } | 1835 | } |
1691 | 1836 | ||
1692 | /* Deregister the admin queue's interrupt */ | 1837 | /* Deregister the admin queue's interrupt */ |
1693 | free_irq(dev->entry[0].vector, dev->queues[0]); | 1838 | free_irq(dev->entry[0].vector, adminq); |
1694 | 1839 | ||
1695 | vecs = nr_io_queues; | 1840 | vecs = nr_io_queues; |
1696 | for (i = 0; i < vecs; i++) | 1841 | for (i = 0; i < vecs; i++) |
@@ -1728,9 +1873,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1728 | */ | 1873 | */ |
1729 | nr_io_queues = vecs; | 1874 | nr_io_queues = vecs; |
1730 | 1875 | ||
1731 | result = queue_request_irq(dev, dev->queues[0], "nvme admin"); | 1876 | result = queue_request_irq(dev, adminq, adminq->irqname); |
1732 | if (result) { | 1877 | if (result) { |
1733 | dev->queues[0]->q_suspended = 1; | 1878 | adminq->q_suspended = 1; |
1734 | goto free_queues; | 1879 | goto free_queues; |
1735 | } | 1880 | } |
1736 | 1881 | ||
@@ -1739,9 +1884,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1739 | for (i = dev->queue_count - 1; i > nr_io_queues; i--) { | 1884 | for (i = dev->queue_count - 1; i > nr_io_queues; i--) { |
1740 | struct nvme_queue *nvmeq = dev->queues[i]; | 1885 | struct nvme_queue *nvmeq = dev->queues[i]; |
1741 | 1886 | ||
1742 | spin_lock(&nvmeq->q_lock); | 1887 | spin_lock_irq(&nvmeq->q_lock); |
1743 | nvme_cancel_ios(nvmeq, false); | 1888 | nvme_cancel_ios(nvmeq, false); |
1744 | spin_unlock(&nvmeq->q_lock); | 1889 | spin_unlock_irq(&nvmeq->q_lock); |
1745 | 1890 | ||
1746 | nvme_free_queue(nvmeq); | 1891 | nvme_free_queue(nvmeq); |
1747 | dev->queue_count--; | 1892 | dev->queue_count--; |
@@ -1782,7 +1927,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1782 | return 0; | 1927 | return 0; |
1783 | 1928 | ||
1784 | free_queues: | 1929 | free_queues: |
1785 | nvme_free_queues(dev); | 1930 | nvme_free_queues(dev, 1); |
1786 | return result; | 1931 | return result; |
1787 | } | 1932 | } |
1788 | 1933 | ||
@@ -1794,6 +1939,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) | |||
1794 | */ | 1939 | */ |
1795 | static int nvme_dev_add(struct nvme_dev *dev) | 1940 | static int nvme_dev_add(struct nvme_dev *dev) |
1796 | { | 1941 | { |
1942 | struct pci_dev *pdev = dev->pci_dev; | ||
1797 | int res; | 1943 | int res; |
1798 | unsigned nn, i; | 1944 | unsigned nn, i; |
1799 | struct nvme_ns *ns; | 1945 | struct nvme_ns *ns; |
@@ -1803,8 +1949,7 @@ static int nvme_dev_add(struct nvme_dev *dev) | |||
1803 | dma_addr_t dma_addr; | 1949 | dma_addr_t dma_addr; |
1804 | int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; | 1950 | int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; |
1805 | 1951 | ||
1806 | mem = dma_alloc_coherent(&dev->pci_dev->dev, 8192, &dma_addr, | 1952 | mem = dma_alloc_coherent(&pdev->dev, 8192, &dma_addr, GFP_KERNEL); |
1807 | GFP_KERNEL); | ||
1808 | if (!mem) | 1953 | if (!mem) |
1809 | return -ENOMEM; | 1954 | return -ENOMEM; |
1810 | 1955 | ||
@@ -1817,13 +1962,14 @@ static int nvme_dev_add(struct nvme_dev *dev) | |||
1817 | ctrl = mem; | 1962 | ctrl = mem; |
1818 | nn = le32_to_cpup(&ctrl->nn); | 1963 | nn = le32_to_cpup(&ctrl->nn); |
1819 | dev->oncs = le16_to_cpup(&ctrl->oncs); | 1964 | dev->oncs = le16_to_cpup(&ctrl->oncs); |
1965 | dev->abort_limit = ctrl->acl + 1; | ||
1820 | memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); | 1966 | memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn)); |
1821 | memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); | 1967 | memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn)); |
1822 | memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); | 1968 | memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr)); |
1823 | if (ctrl->mdts) | 1969 | if (ctrl->mdts) |
1824 | dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); | 1970 | dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9); |
1825 | if ((dev->pci_dev->vendor == PCI_VENDOR_ID_INTEL) && | 1971 | if ((pdev->vendor == PCI_VENDOR_ID_INTEL) && |
1826 | (dev->pci_dev->device == 0x0953) && ctrl->vs[3]) | 1972 | (pdev->device == 0x0953) && ctrl->vs[3]) |
1827 | dev->stripe_size = 1 << (ctrl->vs[3] + shift); | 1973 | dev->stripe_size = 1 << (ctrl->vs[3] + shift); |
1828 | 1974 | ||
1829 | id_ns = mem; | 1975 | id_ns = mem; |
@@ -1871,16 +2017,21 @@ static int nvme_dev_map(struct nvme_dev *dev) | |||
1871 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) | 2017 | dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) |
1872 | goto disable; | 2018 | goto disable; |
1873 | 2019 | ||
1874 | pci_set_drvdata(pdev, dev); | ||
1875 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); | 2020 | dev->bar = ioremap(pci_resource_start(pdev, 0), 8192); |
1876 | if (!dev->bar) | 2021 | if (!dev->bar) |
1877 | goto disable; | 2022 | goto disable; |
1878 | 2023 | if (readl(&dev->bar->csts) == -1) { | |
1879 | dev->db_stride = NVME_CAP_STRIDE(readq(&dev->bar->cap)); | 2024 | result = -ENODEV; |
2025 | goto unmap; | ||
2026 | } | ||
2027 | dev->db_stride = 1 << NVME_CAP_STRIDE(readq(&dev->bar->cap)); | ||
1880 | dev->dbs = ((void __iomem *)dev->bar) + 4096; | 2028 | dev->dbs = ((void __iomem *)dev->bar) + 4096; |
1881 | 2029 | ||
1882 | return 0; | 2030 | return 0; |
1883 | 2031 | ||
2032 | unmap: | ||
2033 | iounmap(dev->bar); | ||
2034 | dev->bar = NULL; | ||
1884 | disable: | 2035 | disable: |
1885 | pci_release_regions(pdev); | 2036 | pci_release_regions(pdev); |
1886 | disable_pci: | 2037 | disable_pci: |
@@ -1898,37 +2049,183 @@ static void nvme_dev_unmap(struct nvme_dev *dev) | |||
1898 | if (dev->bar) { | 2049 | if (dev->bar) { |
1899 | iounmap(dev->bar); | 2050 | iounmap(dev->bar); |
1900 | dev->bar = NULL; | 2051 | dev->bar = NULL; |
2052 | pci_release_regions(dev->pci_dev); | ||
1901 | } | 2053 | } |
1902 | 2054 | ||
1903 | pci_release_regions(dev->pci_dev); | ||
1904 | if (pci_is_enabled(dev->pci_dev)) | 2055 | if (pci_is_enabled(dev->pci_dev)) |
1905 | pci_disable_device(dev->pci_dev); | 2056 | pci_disable_device(dev->pci_dev); |
1906 | } | 2057 | } |
1907 | 2058 | ||
2059 | struct nvme_delq_ctx { | ||
2060 | struct task_struct *waiter; | ||
2061 | struct kthread_worker *worker; | ||
2062 | atomic_t refcount; | ||
2063 | }; | ||
2064 | |||
2065 | static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) | ||
2066 | { | ||
2067 | dq->waiter = current; | ||
2068 | mb(); | ||
2069 | |||
2070 | for (;;) { | ||
2071 | set_current_state(TASK_KILLABLE); | ||
2072 | if (!atomic_read(&dq->refcount)) | ||
2073 | break; | ||
2074 | if (!schedule_timeout(ADMIN_TIMEOUT) || | ||
2075 | fatal_signal_pending(current)) { | ||
2076 | set_current_state(TASK_RUNNING); | ||
2077 | |||
2078 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); | ||
2079 | nvme_disable_queue(dev, 0); | ||
2080 | |||
2081 | send_sig(SIGKILL, dq->worker->task, 1); | ||
2082 | flush_kthread_worker(dq->worker); | ||
2083 | return; | ||
2084 | } | ||
2085 | } | ||
2086 | set_current_state(TASK_RUNNING); | ||
2087 | } | ||
2088 | |||
2089 | static void nvme_put_dq(struct nvme_delq_ctx *dq) | ||
2090 | { | ||
2091 | atomic_dec(&dq->refcount); | ||
2092 | if (dq->waiter) | ||
2093 | wake_up_process(dq->waiter); | ||
2094 | } | ||
2095 | |||
2096 | static struct nvme_delq_ctx *nvme_get_dq(struct nvme_delq_ctx *dq) | ||
2097 | { | ||
2098 | atomic_inc(&dq->refcount); | ||
2099 | return dq; | ||
2100 | } | ||
2101 | |||
2102 | static void nvme_del_queue_end(struct nvme_queue *nvmeq) | ||
2103 | { | ||
2104 | struct nvme_delq_ctx *dq = nvmeq->cmdinfo.ctx; | ||
2105 | |||
2106 | nvme_clear_queue(nvmeq); | ||
2107 | nvme_put_dq(dq); | ||
2108 | } | ||
2109 | |||
2110 | static int adapter_async_del_queue(struct nvme_queue *nvmeq, u8 opcode, | ||
2111 | kthread_work_func_t fn) | ||
2112 | { | ||
2113 | struct nvme_command c; | ||
2114 | |||
2115 | memset(&c, 0, sizeof(c)); | ||
2116 | c.delete_queue.opcode = opcode; | ||
2117 | c.delete_queue.qid = cpu_to_le16(nvmeq->qid); | ||
2118 | |||
2119 | init_kthread_work(&nvmeq->cmdinfo.work, fn); | ||
2120 | return nvme_submit_admin_cmd_async(nvmeq->dev, &c, &nvmeq->cmdinfo); | ||
2121 | } | ||
2122 | |||
2123 | static void nvme_del_cq_work_handler(struct kthread_work *work) | ||
2124 | { | ||
2125 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2126 | cmdinfo.work); | ||
2127 | nvme_del_queue_end(nvmeq); | ||
2128 | } | ||
2129 | |||
2130 | static int nvme_delete_cq(struct nvme_queue *nvmeq) | ||
2131 | { | ||
2132 | return adapter_async_del_queue(nvmeq, nvme_admin_delete_cq, | ||
2133 | nvme_del_cq_work_handler); | ||
2134 | } | ||
2135 | |||
2136 | static void nvme_del_sq_work_handler(struct kthread_work *work) | ||
2137 | { | ||
2138 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2139 | cmdinfo.work); | ||
2140 | int status = nvmeq->cmdinfo.status; | ||
2141 | |||
2142 | if (!status) | ||
2143 | status = nvme_delete_cq(nvmeq); | ||
2144 | if (status) | ||
2145 | nvme_del_queue_end(nvmeq); | ||
2146 | } | ||
2147 | |||
2148 | static int nvme_delete_sq(struct nvme_queue *nvmeq) | ||
2149 | { | ||
2150 | return adapter_async_del_queue(nvmeq, nvme_admin_delete_sq, | ||
2151 | nvme_del_sq_work_handler); | ||
2152 | } | ||
2153 | |||
2154 | static void nvme_del_queue_start(struct kthread_work *work) | ||
2155 | { | ||
2156 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | ||
2157 | cmdinfo.work); | ||
2158 | allow_signal(SIGKILL); | ||
2159 | if (nvme_delete_sq(nvmeq)) | ||
2160 | nvme_del_queue_end(nvmeq); | ||
2161 | } | ||
2162 | |||
2163 | static void nvme_disable_io_queues(struct nvme_dev *dev) | ||
2164 | { | ||
2165 | int i; | ||
2166 | DEFINE_KTHREAD_WORKER_ONSTACK(worker); | ||
2167 | struct nvme_delq_ctx dq; | ||
2168 | struct task_struct *kworker_task = kthread_run(kthread_worker_fn, | ||
2169 | &worker, "nvme%d", dev->instance); | ||
2170 | |||
2171 | if (IS_ERR(kworker_task)) { | ||
2172 | dev_err(&dev->pci_dev->dev, | ||
2173 | "Failed to create queue del task\n"); | ||
2174 | for (i = dev->queue_count - 1; i > 0; i--) | ||
2175 | nvme_disable_queue(dev, i); | ||
2176 | return; | ||
2177 | } | ||
2178 | |||
2179 | dq.waiter = NULL; | ||
2180 | atomic_set(&dq.refcount, 0); | ||
2181 | dq.worker = &worker; | ||
2182 | for (i = dev->queue_count - 1; i > 0; i--) { | ||
2183 | struct nvme_queue *nvmeq = dev->queues[i]; | ||
2184 | |||
2185 | if (nvme_suspend_queue(nvmeq)) | ||
2186 | continue; | ||
2187 | nvmeq->cmdinfo.ctx = nvme_get_dq(&dq); | ||
2188 | nvmeq->cmdinfo.worker = dq.worker; | ||
2189 | init_kthread_work(&nvmeq->cmdinfo.work, nvme_del_queue_start); | ||
2190 | queue_kthread_work(dq.worker, &nvmeq->cmdinfo.work); | ||
2191 | } | ||
2192 | nvme_wait_dq(&dq, dev); | ||
2193 | kthread_stop(kworker_task); | ||
2194 | } | ||
2195 | |||
1908 | static void nvme_dev_shutdown(struct nvme_dev *dev) | 2196 | static void nvme_dev_shutdown(struct nvme_dev *dev) |
1909 | { | 2197 | { |
1910 | int i; | 2198 | int i; |
1911 | 2199 | ||
1912 | for (i = dev->queue_count - 1; i >= 0; i--) | 2200 | dev->initialized = 0; |
1913 | nvme_disable_queue(dev, i); | ||
1914 | 2201 | ||
1915 | spin_lock(&dev_list_lock); | 2202 | spin_lock(&dev_list_lock); |
1916 | list_del_init(&dev->node); | 2203 | list_del_init(&dev->node); |
1917 | spin_unlock(&dev_list_lock); | 2204 | spin_unlock(&dev_list_lock); |
1918 | 2205 | ||
1919 | if (dev->bar) | 2206 | if (!dev->bar || (dev->bar && readl(&dev->bar->csts) == -1)) { |
2207 | for (i = dev->queue_count - 1; i >= 0; i--) { | ||
2208 | struct nvme_queue *nvmeq = dev->queues[i]; | ||
2209 | nvme_suspend_queue(nvmeq); | ||
2210 | nvme_clear_queue(nvmeq); | ||
2211 | } | ||
2212 | } else { | ||
2213 | nvme_disable_io_queues(dev); | ||
1920 | nvme_shutdown_ctrl(dev); | 2214 | nvme_shutdown_ctrl(dev); |
2215 | nvme_disable_queue(dev, 0); | ||
2216 | } | ||
1921 | nvme_dev_unmap(dev); | 2217 | nvme_dev_unmap(dev); |
1922 | } | 2218 | } |
1923 | 2219 | ||
1924 | static void nvme_dev_remove(struct nvme_dev *dev) | 2220 | static void nvme_dev_remove(struct nvme_dev *dev) |
1925 | { | 2221 | { |
1926 | struct nvme_ns *ns, *next; | 2222 | struct nvme_ns *ns; |
1927 | 2223 | ||
1928 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | 2224 | list_for_each_entry(ns, &dev->namespaces, list) { |
1929 | list_del(&ns->list); | 2225 | if (ns->disk->flags & GENHD_FL_UP) |
1930 | del_gendisk(ns->disk); | 2226 | del_gendisk(ns->disk); |
1931 | nvme_ns_free(ns); | 2227 | if (!blk_queue_dying(ns->queue)) |
2228 | blk_cleanup_queue(ns->queue); | ||
1932 | } | 2229 | } |
1933 | } | 2230 | } |
1934 | 2231 | ||
@@ -1985,14 +2282,22 @@ static void nvme_release_instance(struct nvme_dev *dev) | |||
1985 | spin_unlock(&dev_list_lock); | 2282 | spin_unlock(&dev_list_lock); |
1986 | } | 2283 | } |
1987 | 2284 | ||
2285 | static void nvme_free_namespaces(struct nvme_dev *dev) | ||
2286 | { | ||
2287 | struct nvme_ns *ns, *next; | ||
2288 | |||
2289 | list_for_each_entry_safe(ns, next, &dev->namespaces, list) { | ||
2290 | list_del(&ns->list); | ||
2291 | put_disk(ns->disk); | ||
2292 | kfree(ns); | ||
2293 | } | ||
2294 | } | ||
2295 | |||
1988 | static void nvme_free_dev(struct kref *kref) | 2296 | static void nvme_free_dev(struct kref *kref) |
1989 | { | 2297 | { |
1990 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); | 2298 | struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref); |
1991 | nvme_dev_remove(dev); | 2299 | |
1992 | nvme_dev_shutdown(dev); | 2300 | nvme_free_namespaces(dev); |
1993 | nvme_free_queues(dev); | ||
1994 | nvme_release_instance(dev); | ||
1995 | nvme_release_prp_pools(dev); | ||
1996 | kfree(dev->queues); | 2301 | kfree(dev->queues); |
1997 | kfree(dev->entry); | 2302 | kfree(dev->entry); |
1998 | kfree(dev); | 2303 | kfree(dev); |
@@ -2056,6 +2361,7 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
2056 | return result; | 2361 | return result; |
2057 | 2362 | ||
2058 | disable: | 2363 | disable: |
2364 | nvme_disable_queue(dev, 0); | ||
2059 | spin_lock(&dev_list_lock); | 2365 | spin_lock(&dev_list_lock); |
2060 | list_del_init(&dev->node); | 2366 | list_del_init(&dev->node); |
2061 | spin_unlock(&dev_list_lock); | 2367 | spin_unlock(&dev_list_lock); |
@@ -2064,6 +2370,71 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
2064 | return result; | 2370 | return result; |
2065 | } | 2371 | } |
2066 | 2372 | ||
2373 | static int nvme_remove_dead_ctrl(void *arg) | ||
2374 | { | ||
2375 | struct nvme_dev *dev = (struct nvme_dev *)arg; | ||
2376 | struct pci_dev *pdev = dev->pci_dev; | ||
2377 | |||
2378 | if (pci_get_drvdata(pdev)) | ||
2379 | pci_stop_and_remove_bus_device(pdev); | ||
2380 | kref_put(&dev->kref, nvme_free_dev); | ||
2381 | return 0; | ||
2382 | } | ||
2383 | |||
2384 | static void nvme_remove_disks(struct work_struct *ws) | ||
2385 | { | ||
2386 | int i; | ||
2387 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
2388 | |||
2389 | nvme_dev_remove(dev); | ||
2390 | spin_lock(&dev_list_lock); | ||
2391 | for (i = dev->queue_count - 1; i > 0; i--) { | ||
2392 | BUG_ON(!dev->queues[i] || !dev->queues[i]->q_suspended); | ||
2393 | nvme_free_queue(dev->queues[i]); | ||
2394 | dev->queue_count--; | ||
2395 | dev->queues[i] = NULL; | ||
2396 | } | ||
2397 | spin_unlock(&dev_list_lock); | ||
2398 | } | ||
2399 | |||
2400 | static int nvme_dev_resume(struct nvme_dev *dev) | ||
2401 | { | ||
2402 | int ret; | ||
2403 | |||
2404 | ret = nvme_dev_start(dev); | ||
2405 | if (ret && ret != -EBUSY) | ||
2406 | return ret; | ||
2407 | if (ret == -EBUSY) { | ||
2408 | spin_lock(&dev_list_lock); | ||
2409 | PREPARE_WORK(&dev->reset_work, nvme_remove_disks); | ||
2410 | queue_work(nvme_workq, &dev->reset_work); | ||
2411 | spin_unlock(&dev_list_lock); | ||
2412 | } | ||
2413 | dev->initialized = 1; | ||
2414 | return 0; | ||
2415 | } | ||
2416 | |||
2417 | static void nvme_dev_reset(struct nvme_dev *dev) | ||
2418 | { | ||
2419 | nvme_dev_shutdown(dev); | ||
2420 | if (nvme_dev_resume(dev)) { | ||
2421 | dev_err(&dev->pci_dev->dev, "Device failed to resume\n"); | ||
2422 | kref_get(&dev->kref); | ||
2423 | if (IS_ERR(kthread_run(nvme_remove_dead_ctrl, dev, "nvme%d", | ||
2424 | dev->instance))) { | ||
2425 | dev_err(&dev->pci_dev->dev, | ||
2426 | "Failed to start controller remove task\n"); | ||
2427 | kref_put(&dev->kref, nvme_free_dev); | ||
2428 | } | ||
2429 | } | ||
2430 | } | ||
2431 | |||
2432 | static void nvme_reset_failed_dev(struct work_struct *ws) | ||
2433 | { | ||
2434 | struct nvme_dev *dev = container_of(ws, struct nvme_dev, reset_work); | ||
2435 | nvme_dev_reset(dev); | ||
2436 | } | ||
2437 | |||
2067 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 2438 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
2068 | { | 2439 | { |
2069 | int result = -ENOMEM; | 2440 | int result = -ENOMEM; |
@@ -2082,8 +2453,9 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2082 | goto free; | 2453 | goto free; |
2083 | 2454 | ||
2084 | INIT_LIST_HEAD(&dev->namespaces); | 2455 | INIT_LIST_HEAD(&dev->namespaces); |
2456 | INIT_WORK(&dev->reset_work, nvme_reset_failed_dev); | ||
2085 | dev->pci_dev = pdev; | 2457 | dev->pci_dev = pdev; |
2086 | 2458 | pci_set_drvdata(pdev, dev); | |
2087 | result = nvme_set_instance(dev); | 2459 | result = nvme_set_instance(dev); |
2088 | if (result) | 2460 | if (result) |
2089 | goto free; | 2461 | goto free; |
@@ -2099,6 +2471,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2099 | goto release_pools; | 2471 | goto release_pools; |
2100 | } | 2472 | } |
2101 | 2473 | ||
2474 | kref_init(&dev->kref); | ||
2102 | result = nvme_dev_add(dev); | 2475 | result = nvme_dev_add(dev); |
2103 | if (result) | 2476 | if (result) |
2104 | goto shutdown; | 2477 | goto shutdown; |
@@ -2113,15 +2486,16 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2113 | if (result) | 2486 | if (result) |
2114 | goto remove; | 2487 | goto remove; |
2115 | 2488 | ||
2116 | kref_init(&dev->kref); | 2489 | dev->initialized = 1; |
2117 | return 0; | 2490 | return 0; |
2118 | 2491 | ||
2119 | remove: | 2492 | remove: |
2120 | nvme_dev_remove(dev); | 2493 | nvme_dev_remove(dev); |
2494 | nvme_free_namespaces(dev); | ||
2121 | shutdown: | 2495 | shutdown: |
2122 | nvme_dev_shutdown(dev); | 2496 | nvme_dev_shutdown(dev); |
2123 | release_pools: | 2497 | release_pools: |
2124 | nvme_free_queues(dev); | 2498 | nvme_free_queues(dev, 0); |
2125 | nvme_release_prp_pools(dev); | 2499 | nvme_release_prp_pools(dev); |
2126 | release: | 2500 | release: |
2127 | nvme_release_instance(dev); | 2501 | nvme_release_instance(dev); |
@@ -2132,10 +2506,28 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2132 | return result; | 2506 | return result; |
2133 | } | 2507 | } |
2134 | 2508 | ||
2509 | static void nvme_shutdown(struct pci_dev *pdev) | ||
2510 | { | ||
2511 | struct nvme_dev *dev = pci_get_drvdata(pdev); | ||
2512 | nvme_dev_shutdown(dev); | ||
2513 | } | ||
2514 | |||
2135 | static void nvme_remove(struct pci_dev *pdev) | 2515 | static void nvme_remove(struct pci_dev *pdev) |
2136 | { | 2516 | { |
2137 | struct nvme_dev *dev = pci_get_drvdata(pdev); | 2517 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
2518 | |||
2519 | spin_lock(&dev_list_lock); | ||
2520 | list_del_init(&dev->node); | ||
2521 | spin_unlock(&dev_list_lock); | ||
2522 | |||
2523 | pci_set_drvdata(pdev, NULL); | ||
2524 | flush_work(&dev->reset_work); | ||
2138 | misc_deregister(&dev->miscdev); | 2525 | misc_deregister(&dev->miscdev); |
2526 | nvme_dev_remove(dev); | ||
2527 | nvme_dev_shutdown(dev); | ||
2528 | nvme_free_queues(dev, 0); | ||
2529 | nvme_release_instance(dev); | ||
2530 | nvme_release_prp_pools(dev); | ||
2139 | kref_put(&dev->kref, nvme_free_dev); | 2531 | kref_put(&dev->kref, nvme_free_dev); |
2140 | } | 2532 | } |
2141 | 2533 | ||
@@ -2159,13 +2551,12 @@ static int nvme_resume(struct device *dev) | |||
2159 | { | 2551 | { |
2160 | struct pci_dev *pdev = to_pci_dev(dev); | 2552 | struct pci_dev *pdev = to_pci_dev(dev); |
2161 | struct nvme_dev *ndev = pci_get_drvdata(pdev); | 2553 | struct nvme_dev *ndev = pci_get_drvdata(pdev); |
2162 | int ret; | ||
2163 | 2554 | ||
2164 | ret = nvme_dev_start(ndev); | 2555 | if (nvme_dev_resume(ndev) && !work_busy(&ndev->reset_work)) { |
2165 | /* XXX: should remove gendisks if resume fails */ | 2556 | PREPARE_WORK(&ndev->reset_work, nvme_reset_failed_dev); |
2166 | if (ret) | 2557 | queue_work(nvme_workq, &ndev->reset_work); |
2167 | nvme_free_queues(ndev); | 2558 | } |
2168 | return ret; | 2559 | return 0; |
2169 | } | 2560 | } |
2170 | 2561 | ||
2171 | static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume); | 2562 | static SIMPLE_DEV_PM_OPS(nvme_dev_pm_ops, nvme_suspend, nvme_resume); |
@@ -2192,6 +2583,7 @@ static struct pci_driver nvme_driver = { | |||
2192 | .id_table = nvme_id_table, | 2583 | .id_table = nvme_id_table, |
2193 | .probe = nvme_probe, | 2584 | .probe = nvme_probe, |
2194 | .remove = nvme_remove, | 2585 | .remove = nvme_remove, |
2586 | .shutdown = nvme_shutdown, | ||
2195 | .driver = { | 2587 | .driver = { |
2196 | .pm = &nvme_dev_pm_ops, | 2588 | .pm = &nvme_dev_pm_ops, |
2197 | }, | 2589 | }, |
@@ -2206,9 +2598,14 @@ static int __init nvme_init(void) | |||
2206 | if (IS_ERR(nvme_thread)) | 2598 | if (IS_ERR(nvme_thread)) |
2207 | return PTR_ERR(nvme_thread); | 2599 | return PTR_ERR(nvme_thread); |
2208 | 2600 | ||
2601 | result = -ENOMEM; | ||
2602 | nvme_workq = create_singlethread_workqueue("nvme"); | ||
2603 | if (!nvme_workq) | ||
2604 | goto kill_kthread; | ||
2605 | |||
2209 | result = register_blkdev(nvme_major, "nvme"); | 2606 | result = register_blkdev(nvme_major, "nvme"); |
2210 | if (result < 0) | 2607 | if (result < 0) |
2211 | goto kill_kthread; | 2608 | goto kill_workq; |
2212 | else if (result > 0) | 2609 | else if (result > 0) |
2213 | nvme_major = result; | 2610 | nvme_major = result; |
2214 | 2611 | ||
@@ -2219,6 +2616,8 @@ static int __init nvme_init(void) | |||
2219 | 2616 | ||
2220 | unregister_blkdev: | 2617 | unregister_blkdev: |
2221 | unregister_blkdev(nvme_major, "nvme"); | 2618 | unregister_blkdev(nvme_major, "nvme"); |
2619 | kill_workq: | ||
2620 | destroy_workqueue(nvme_workq); | ||
2222 | kill_kthread: | 2621 | kill_kthread: |
2223 | kthread_stop(nvme_thread); | 2622 | kthread_stop(nvme_thread); |
2224 | return result; | 2623 | return result; |
@@ -2228,6 +2627,7 @@ static void __exit nvme_exit(void) | |||
2228 | { | 2627 | { |
2229 | pci_unregister_driver(&nvme_driver); | 2628 | pci_unregister_driver(&nvme_driver); |
2230 | unregister_blkdev(nvme_major, "nvme"); | 2629 | unregister_blkdev(nvme_major, "nvme"); |
2630 | destroy_workqueue(nvme_workq); | ||
2231 | kthread_stop(nvme_thread); | 2631 | kthread_stop(nvme_thread); |
2232 | } | 2632 | } |
2233 | 2633 | ||
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index 4a4ff4eb8e23..4a0ceb64e269 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/bio.h> | 25 | #include <linux/bio.h> |
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/blkdev.h> | 27 | #include <linux/blkdev.h> |
28 | #include <linux/compat.h> | ||
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/fs.h> | 31 | #include <linux/fs.h> |
@@ -3038,6 +3039,152 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr) | |||
3038 | return retcode; | 3039 | return retcode; |
3039 | } | 3040 | } |
3040 | 3041 | ||
3042 | #ifdef CONFIG_COMPAT | ||
3043 | typedef struct sg_io_hdr32 { | ||
3044 | compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */ | ||
3045 | compat_int_t dxfer_direction; /* [i] data transfer direction */ | ||
3046 | unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */ | ||
3047 | unsigned char mx_sb_len; /* [i] max length to write to sbp */ | ||
3048 | unsigned short iovec_count; /* [i] 0 implies no scatter gather */ | ||
3049 | compat_uint_t dxfer_len; /* [i] byte count of data transfer */ | ||
3050 | compat_uint_t dxferp; /* [i], [*io] points to data transfer memory | ||
3051 | or scatter gather list */ | ||
3052 | compat_uptr_t cmdp; /* [i], [*i] points to command to perform */ | ||
3053 | compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */ | ||
3054 | compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */ | ||
3055 | compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */ | ||
3056 | compat_int_t pack_id; /* [i->o] unused internally (normally) */ | ||
3057 | compat_uptr_t usr_ptr; /* [i->o] unused internally */ | ||
3058 | unsigned char status; /* [o] scsi status */ | ||
3059 | unsigned char masked_status; /* [o] shifted, masked scsi status */ | ||
3060 | unsigned char msg_status; /* [o] messaging level data (optional) */ | ||
3061 | unsigned char sb_len_wr; /* [o] byte count actually written to sbp */ | ||
3062 | unsigned short host_status; /* [o] errors from host adapter */ | ||
3063 | unsigned short driver_status; /* [o] errors from software driver */ | ||
3064 | compat_int_t resid; /* [o] dxfer_len - actual_transferred */ | ||
3065 | compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */ | ||
3066 | compat_uint_t info; /* [o] auxiliary information */ | ||
3067 | } sg_io_hdr32_t; /* 64 bytes long (on sparc32) */ | ||
3068 | |||
3069 | typedef struct sg_iovec32 { | ||
3070 | compat_uint_t iov_base; | ||
3071 | compat_uint_t iov_len; | ||
3072 | } sg_iovec32_t; | ||
3073 | |||
3074 | static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count) | ||
3075 | { | ||
3076 | sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1); | ||
3077 | sg_iovec32_t __user *iov32 = dxferp; | ||
3078 | int i; | ||
3079 | |||
3080 | for (i = 0; i < iovec_count; i++) { | ||
3081 | u32 base, len; | ||
3082 | |||
3083 | if (get_user(base, &iov32[i].iov_base) || | ||
3084 | get_user(len, &iov32[i].iov_len) || | ||
3085 | put_user(compat_ptr(base), &iov[i].iov_base) || | ||
3086 | put_user(len, &iov[i].iov_len)) | ||
3087 | return -EFAULT; | ||
3088 | } | ||
3089 | |||
3090 | if (put_user(iov, &sgio->dxferp)) | ||
3091 | return -EFAULT; | ||
3092 | return 0; | ||
3093 | } | ||
3094 | |||
3095 | int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg) | ||
3096 | { | ||
3097 | sg_io_hdr32_t __user *sgio32 = (sg_io_hdr32_t __user *)arg; | ||
3098 | sg_io_hdr_t __user *sgio; | ||
3099 | u16 iovec_count; | ||
3100 | u32 data; | ||
3101 | void __user *dxferp; | ||
3102 | int err; | ||
3103 | int interface_id; | ||
3104 | |||
3105 | if (get_user(interface_id, &sgio32->interface_id)) | ||
3106 | return -EFAULT; | ||
3107 | if (interface_id != 'S') | ||
3108 | return -EINVAL; | ||
3109 | |||
3110 | if (get_user(iovec_count, &sgio32->iovec_count)) | ||
3111 | return -EFAULT; | ||
3112 | |||
3113 | { | ||
3114 | void __user *top = compat_alloc_user_space(0); | ||
3115 | void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) + | ||
3116 | (iovec_count * sizeof(sg_iovec_t))); | ||
3117 | if (new > top) | ||
3118 | return -EINVAL; | ||
3119 | |||
3120 | sgio = new; | ||
3121 | } | ||
3122 | |||
3123 | /* Ok, now construct. */ | ||
3124 | if (copy_in_user(&sgio->interface_id, &sgio32->interface_id, | ||
3125 | (2 * sizeof(int)) + | ||
3126 | (2 * sizeof(unsigned char)) + | ||
3127 | (1 * sizeof(unsigned short)) + | ||
3128 | (1 * sizeof(unsigned int)))) | ||
3129 | return -EFAULT; | ||
3130 | |||
3131 | if (get_user(data, &sgio32->dxferp)) | ||
3132 | return -EFAULT; | ||
3133 | dxferp = compat_ptr(data); | ||
3134 | if (iovec_count) { | ||
3135 | if (sg_build_iovec(sgio, dxferp, iovec_count)) | ||
3136 | return -EFAULT; | ||
3137 | } else { | ||
3138 | if (put_user(dxferp, &sgio->dxferp)) | ||
3139 | return -EFAULT; | ||
3140 | } | ||
3141 | |||
3142 | { | ||
3143 | unsigned char __user *cmdp; | ||
3144 | unsigned char __user *sbp; | ||
3145 | |||
3146 | if (get_user(data, &sgio32->cmdp)) | ||
3147 | return -EFAULT; | ||
3148 | cmdp = compat_ptr(data); | ||
3149 | |||
3150 | if (get_user(data, &sgio32->sbp)) | ||
3151 | return -EFAULT; | ||
3152 | sbp = compat_ptr(data); | ||
3153 | |||
3154 | if (put_user(cmdp, &sgio->cmdp) || | ||
3155 | put_user(sbp, &sgio->sbp)) | ||
3156 | return -EFAULT; | ||
3157 | } | ||
3158 | |||
3159 | if (copy_in_user(&sgio->timeout, &sgio32->timeout, | ||
3160 | 3 * sizeof(int))) | ||
3161 | return -EFAULT; | ||
3162 | |||
3163 | if (get_user(data, &sgio32->usr_ptr)) | ||
3164 | return -EFAULT; | ||
3165 | if (put_user(compat_ptr(data), &sgio->usr_ptr)) | ||
3166 | return -EFAULT; | ||
3167 | |||
3168 | err = nvme_sg_io(ns, sgio); | ||
3169 | if (err >= 0) { | ||
3170 | void __user *datap; | ||
3171 | |||
3172 | if (copy_in_user(&sgio32->pack_id, &sgio->pack_id, | ||
3173 | sizeof(int)) || | ||
3174 | get_user(datap, &sgio->usr_ptr) || | ||
3175 | put_user((u32)(unsigned long)datap, | ||
3176 | &sgio32->usr_ptr) || | ||
3177 | copy_in_user(&sgio32->status, &sgio->status, | ||
3178 | (4 * sizeof(unsigned char)) + | ||
3179 | (2 * sizeof(unsigned short)) + | ||
3180 | (3 * sizeof(int)))) | ||
3181 | err = -EFAULT; | ||
3182 | } | ||
3183 | |||
3184 | return err; | ||
3185 | } | ||
3186 | #endif | ||
3187 | |||
3041 | int nvme_sg_get_version_num(int __user *ip) | 3188 | int nvme_sg_get_version_num(int __user *ip) |
3042 | { | 3189 | { |
3043 | return put_user(sg_version_num, ip); | 3190 | return put_user(sg_version_num, ip); |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6a680d4de7f1..b1cb3f4c4db4 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -110,9 +110,9 @@ static int __virtblk_add_req(struct virtqueue *vq, | |||
110 | return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); | 110 | return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC); |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline void virtblk_request_done(struct virtblk_req *vbr) | 113 | static inline void virtblk_request_done(struct request *req) |
114 | { | 114 | { |
115 | struct request *req = vbr->req; | 115 | struct virtblk_req *vbr = req->special; |
116 | int error = virtblk_result(vbr); | 116 | int error = virtblk_result(vbr); |
117 | 117 | ||
118 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { | 118 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { |
@@ -138,7 +138,7 @@ static void virtblk_done(struct virtqueue *vq) | |||
138 | do { | 138 | do { |
139 | virtqueue_disable_cb(vq); | 139 | virtqueue_disable_cb(vq); |
140 | while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { | 140 | while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) { |
141 | virtblk_request_done(vbr); | 141 | blk_mq_complete_request(vbr->req); |
142 | req_done = true; | 142 | req_done = true; |
143 | } | 143 | } |
144 | if (unlikely(virtqueue_is_broken(vq))) | 144 | if (unlikely(virtqueue_is_broken(vq))) |
@@ -479,6 +479,7 @@ static struct blk_mq_ops virtio_mq_ops = { | |||
479 | .map_queue = blk_mq_map_queue, | 479 | .map_queue = blk_mq_map_queue, |
480 | .alloc_hctx = blk_mq_alloc_single_hw_queue, | 480 | .alloc_hctx = blk_mq_alloc_single_hw_queue, |
481 | .free_hctx = blk_mq_free_single_hw_queue, | 481 | .free_hctx = blk_mq_free_single_hw_queue, |
482 | .complete = virtblk_request_done, | ||
482 | }; | 483 | }; |
483 | 484 | ||
484 | static struct blk_mq_reg virtio_mq_reg = { | 485 | static struct blk_mq_reg virtio_mq_reg = { |
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index da18046d0e07..64c60edcdfbc 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -285,7 +285,8 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | |||
285 | 285 | ||
286 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || | 286 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST || |
287 | !rb_next(&persistent_gnt->node)) { | 287 | !rb_next(&persistent_gnt->node)) { |
288 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 288 | ret = gnttab_unmap_refs(unmap, NULL, pages, |
289 | segs_to_unmap); | ||
289 | BUG_ON(ret); | 290 | BUG_ON(ret); |
290 | put_free_pages(blkif, pages, segs_to_unmap); | 291 | put_free_pages(blkif, pages, segs_to_unmap); |
291 | segs_to_unmap = 0; | 292 | segs_to_unmap = 0; |
@@ -298,7 +299,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root, | |||
298 | BUG_ON(num != 0); | 299 | BUG_ON(num != 0); |
299 | } | 300 | } |
300 | 301 | ||
301 | static void unmap_purged_grants(struct work_struct *work) | 302 | void xen_blkbk_unmap_purged_grants(struct work_struct *work) |
302 | { | 303 | { |
303 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 304 | struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
304 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; | 305 | struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST]; |
@@ -320,7 +321,8 @@ static void unmap_purged_grants(struct work_struct *work) | |||
320 | pages[segs_to_unmap] = persistent_gnt->page; | 321 | pages[segs_to_unmap] = persistent_gnt->page; |
321 | 322 | ||
322 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 323 | if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
323 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 324 | ret = gnttab_unmap_refs(unmap, NULL, pages, |
325 | segs_to_unmap); | ||
324 | BUG_ON(ret); | 326 | BUG_ON(ret); |
325 | put_free_pages(blkif, pages, segs_to_unmap); | 327 | put_free_pages(blkif, pages, segs_to_unmap); |
326 | segs_to_unmap = 0; | 328 | segs_to_unmap = 0; |
@@ -328,7 +330,7 @@ static void unmap_purged_grants(struct work_struct *work) | |||
328 | kfree(persistent_gnt); | 330 | kfree(persistent_gnt); |
329 | } | 331 | } |
330 | if (segs_to_unmap > 0) { | 332 | if (segs_to_unmap > 0) { |
331 | ret = gnttab_unmap_refs(unmap, pages, segs_to_unmap); | 333 | ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap); |
332 | BUG_ON(ret); | 334 | BUG_ON(ret); |
333 | put_free_pages(blkif, pages, segs_to_unmap); | 335 | put_free_pages(blkif, pages, segs_to_unmap); |
334 | } | 336 | } |
@@ -373,7 +375,7 @@ static void purge_persistent_gnt(struct xen_blkif *blkif) | |||
373 | 375 | ||
374 | pr_debug(DRV_PFX "Going to purge %u persistent grants\n", num_clean); | 376 | pr_debug(DRV_PFX "Going to purge %u persistent grants\n", num_clean); |
375 | 377 | ||
376 | INIT_LIST_HEAD(&blkif->persistent_purge_list); | 378 | BUG_ON(!list_empty(&blkif->persistent_purge_list)); |
377 | root = &blkif->persistent_gnts; | 379 | root = &blkif->persistent_gnts; |
378 | purge_list: | 380 | purge_list: |
379 | foreach_grant_safe(persistent_gnt, n, root, node) { | 381 | foreach_grant_safe(persistent_gnt, n, root, node) { |
@@ -418,7 +420,6 @@ finished: | |||
418 | blkif->vbd.overflow_max_grants = 0; | 420 | blkif->vbd.overflow_max_grants = 0; |
419 | 421 | ||
420 | /* We can defer this work */ | 422 | /* We can defer this work */ |
421 | INIT_WORK(&blkif->persistent_purge_work, unmap_purged_grants); | ||
422 | schedule_work(&blkif->persistent_purge_work); | 423 | schedule_work(&blkif->persistent_purge_work); |
423 | pr_debug(DRV_PFX "Purged %u/%u\n", (total - num_clean), total); | 424 | pr_debug(DRV_PFX "Purged %u/%u\n", (total - num_clean), total); |
424 | return; | 425 | return; |
@@ -623,9 +624,23 @@ purge_gnt_list: | |||
623 | print_stats(blkif); | 624 | print_stats(blkif); |
624 | } | 625 | } |
625 | 626 | ||
626 | /* Since we are shutting down remove all pages from the buffer */ | 627 | /* Drain pending purge work */ |
627 | shrink_free_pagepool(blkif, 0 /* All */); | 628 | flush_work(&blkif->persistent_purge_work); |
628 | 629 | ||
630 | if (log_stats) | ||
631 | print_stats(blkif); | ||
632 | |||
633 | blkif->xenblkd = NULL; | ||
634 | xen_blkif_put(blkif); | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | /* | ||
640 | * Remove persistent grants and empty the pool of free pages | ||
641 | */ | ||
642 | void xen_blkbk_free_caches(struct xen_blkif *blkif) | ||
643 | { | ||
629 | /* Free all persistent grant pages */ | 644 | /* Free all persistent grant pages */ |
630 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) | 645 | if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) |
631 | free_persistent_gnts(blkif, &blkif->persistent_gnts, | 646 | free_persistent_gnts(blkif, &blkif->persistent_gnts, |
@@ -634,13 +649,8 @@ purge_gnt_list: | |||
634 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); | 649 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); |
635 | blkif->persistent_gnt_c = 0; | 650 | blkif->persistent_gnt_c = 0; |
636 | 651 | ||
637 | if (log_stats) | 652 | /* Since we are shutting down remove all pages from the buffer */ |
638 | print_stats(blkif); | 653 | shrink_free_pagepool(blkif, 0 /* All */); |
639 | |||
640 | blkif->xenblkd = NULL; | ||
641 | xen_blkif_put(blkif); | ||
642 | |||
643 | return 0; | ||
644 | } | 654 | } |
645 | 655 | ||
646 | /* | 656 | /* |
@@ -668,14 +678,15 @@ static void xen_blkbk_unmap(struct xen_blkif *blkif, | |||
668 | GNTMAP_host_map, pages[i]->handle); | 678 | GNTMAP_host_map, pages[i]->handle); |
669 | pages[i]->handle = BLKBACK_INVALID_HANDLE; | 679 | pages[i]->handle = BLKBACK_INVALID_HANDLE; |
670 | if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { | 680 | if (++invcount == BLKIF_MAX_SEGMENTS_PER_REQUEST) { |
671 | ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); | 681 | ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, |
682 | invcount); | ||
672 | BUG_ON(ret); | 683 | BUG_ON(ret); |
673 | put_free_pages(blkif, unmap_pages, invcount); | 684 | put_free_pages(blkif, unmap_pages, invcount); |
674 | invcount = 0; | 685 | invcount = 0; |
675 | } | 686 | } |
676 | } | 687 | } |
677 | if (invcount) { | 688 | if (invcount) { |
678 | ret = gnttab_unmap_refs(unmap, unmap_pages, invcount); | 689 | ret = gnttab_unmap_refs(unmap, NULL, unmap_pages, invcount); |
679 | BUG_ON(ret); | 690 | BUG_ON(ret); |
680 | put_free_pages(blkif, unmap_pages, invcount); | 691 | put_free_pages(blkif, unmap_pages, invcount); |
681 | } | 692 | } |
@@ -737,7 +748,7 @@ again: | |||
737 | } | 748 | } |
738 | 749 | ||
739 | if (segs_to_map) { | 750 | if (segs_to_map) { |
740 | ret = gnttab_map_refs(map, pages_to_gnt, segs_to_map); | 751 | ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); |
741 | BUG_ON(ret); | 752 | BUG_ON(ret); |
742 | } | 753 | } |
743 | 754 | ||
@@ -835,7 +846,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req, | |||
835 | struct grant_page **pages = pending_req->indirect_pages; | 846 | struct grant_page **pages = pending_req->indirect_pages; |
836 | struct xen_blkif *blkif = pending_req->blkif; | 847 | struct xen_blkif *blkif = pending_req->blkif; |
837 | int indirect_grefs, rc, n, nseg, i; | 848 | int indirect_grefs, rc, n, nseg, i; |
838 | struct blkif_request_segment_aligned *segments = NULL; | 849 | struct blkif_request_segment *segments = NULL; |
839 | 850 | ||
840 | nseg = pending_req->nr_pages; | 851 | nseg = pending_req->nr_pages; |
841 | indirect_grefs = INDIRECT_PAGES(nseg); | 852 | indirect_grefs = INDIRECT_PAGES(nseg); |
@@ -931,9 +942,7 @@ static void xen_blk_drain_io(struct xen_blkif *blkif) | |||
931 | { | 942 | { |
932 | atomic_set(&blkif->drain, 1); | 943 | atomic_set(&blkif->drain, 1); |
933 | do { | 944 | do { |
934 | /* The initial value is one, and one refcnt taken at the | 945 | if (atomic_read(&blkif->inflight) == 0) |
935 | * start of the xen_blkif_schedule thread. */ | ||
936 | if (atomic_read(&blkif->refcnt) <= 2) | ||
937 | break; | 946 | break; |
938 | wait_for_completion_interruptible_timeout( | 947 | wait_for_completion_interruptible_timeout( |
939 | &blkif->drain_complete, HZ); | 948 | &blkif->drain_complete, HZ); |
@@ -973,17 +982,30 @@ static void __end_block_io_op(struct pending_req *pending_req, int error) | |||
973 | * the proper response on the ring. | 982 | * the proper response on the ring. |
974 | */ | 983 | */ |
975 | if (atomic_dec_and_test(&pending_req->pendcnt)) { | 984 | if (atomic_dec_and_test(&pending_req->pendcnt)) { |
976 | xen_blkbk_unmap(pending_req->blkif, | 985 | struct xen_blkif *blkif = pending_req->blkif; |
986 | |||
987 | xen_blkbk_unmap(blkif, | ||
977 | pending_req->segments, | 988 | pending_req->segments, |
978 | pending_req->nr_pages); | 989 | pending_req->nr_pages); |
979 | make_response(pending_req->blkif, pending_req->id, | 990 | make_response(blkif, pending_req->id, |
980 | pending_req->operation, pending_req->status); | 991 | pending_req->operation, pending_req->status); |
981 | xen_blkif_put(pending_req->blkif); | 992 | free_req(blkif, pending_req); |
982 | if (atomic_read(&pending_req->blkif->refcnt) <= 2) { | 993 | /* |
983 | if (atomic_read(&pending_req->blkif->drain)) | 994 | * Make sure the request is freed before releasing blkif, |
984 | complete(&pending_req->blkif->drain_complete); | 995 | * or there could be a race between free_req and the |
996 | * cleanup done in xen_blkif_free during shutdown. | ||
997 | * | ||
998 | * NB: The fact that we might try to wake up pending_free_wq | ||
999 | * before drain_complete (in case there's a drain going on) | ||
1000 | * it's not a problem with our current implementation | ||
1001 | * because we can assure there's no thread waiting on | ||
1002 | * pending_free_wq if there's a drain going on, but it has | ||
1003 | * to be taken into account if the current model is changed. | ||
1004 | */ | ||
1005 | if (atomic_dec_and_test(&blkif->inflight) && atomic_read(&blkif->drain)) { | ||
1006 | complete(&blkif->drain_complete); | ||
985 | } | 1007 | } |
986 | free_req(pending_req->blkif, pending_req); | 1008 | xen_blkif_put(blkif); |
987 | } | 1009 | } |
988 | } | 1010 | } |
989 | 1011 | ||
@@ -1237,6 +1259,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, | |||
1237 | * below (in "!bio") if we are handling a BLKIF_OP_DISCARD. | 1259 | * below (in "!bio") if we are handling a BLKIF_OP_DISCARD. |
1238 | */ | 1260 | */ |
1239 | xen_blkif_get(blkif); | 1261 | xen_blkif_get(blkif); |
1262 | atomic_inc(&blkif->inflight); | ||
1240 | 1263 | ||
1241 | for (i = 0; i < nseg; i++) { | 1264 | for (i = 0; i < nseg; i++) { |
1242 | while ((bio == NULL) || | 1265 | while ((bio == NULL) || |
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 8d8807563d99..be052773ad03 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #define MAX_INDIRECT_SEGMENTS 256 | 57 | #define MAX_INDIRECT_SEGMENTS 256 |
58 | 58 | ||
59 | #define SEGS_PER_INDIRECT_FRAME \ | 59 | #define SEGS_PER_INDIRECT_FRAME \ |
60 | (PAGE_SIZE/sizeof(struct blkif_request_segment_aligned)) | 60 | (PAGE_SIZE/sizeof(struct blkif_request_segment)) |
61 | #define MAX_INDIRECT_PAGES \ | 61 | #define MAX_INDIRECT_PAGES \ |
62 | ((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) | 62 | ((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) |
63 | #define INDIRECT_PAGES(_segs) \ | 63 | #define INDIRECT_PAGES(_segs) \ |
@@ -278,6 +278,7 @@ struct xen_blkif { | |||
278 | /* for barrier (drain) requests */ | 278 | /* for barrier (drain) requests */ |
279 | struct completion drain_complete; | 279 | struct completion drain_complete; |
280 | atomic_t drain; | 280 | atomic_t drain; |
281 | atomic_t inflight; | ||
281 | /* One thread per one blkif. */ | 282 | /* One thread per one blkif. */ |
282 | struct task_struct *xenblkd; | 283 | struct task_struct *xenblkd; |
283 | unsigned int waiting_reqs; | 284 | unsigned int waiting_reqs; |
@@ -376,6 +377,7 @@ int xen_blkif_xenbus_init(void); | |||
376 | irqreturn_t xen_blkif_be_int(int irq, void *dev_id); | 377 | irqreturn_t xen_blkif_be_int(int irq, void *dev_id); |
377 | int xen_blkif_schedule(void *arg); | 378 | int xen_blkif_schedule(void *arg); |
378 | int xen_blkif_purge_persistent(void *arg); | 379 | int xen_blkif_purge_persistent(void *arg); |
380 | void xen_blkbk_free_caches(struct xen_blkif *blkif); | ||
379 | 381 | ||
380 | int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, | 382 | int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, |
381 | struct backend_info *be, int state); | 383 | struct backend_info *be, int state); |
@@ -383,6 +385,7 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, | |||
383 | int xen_blkbk_barrier(struct xenbus_transaction xbt, | 385 | int xen_blkbk_barrier(struct xenbus_transaction xbt, |
384 | struct backend_info *be, int state); | 386 | struct backend_info *be, int state); |
385 | struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); | 387 | struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be); |
388 | void xen_blkbk_unmap_purged_grants(struct work_struct *work); | ||
386 | 389 | ||
387 | static inline void blkif_get_x86_32_req(struct blkif_request *dst, | 390 | static inline void blkif_get_x86_32_req(struct blkif_request *dst, |
388 | struct blkif_x86_32_request *src) | 391 | struct blkif_x86_32_request *src) |
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index c2014a0aa206..9a547e6b6ebf 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c | |||
@@ -125,8 +125,11 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) | |||
125 | blkif->persistent_gnts.rb_node = NULL; | 125 | blkif->persistent_gnts.rb_node = NULL; |
126 | spin_lock_init(&blkif->free_pages_lock); | 126 | spin_lock_init(&blkif->free_pages_lock); |
127 | INIT_LIST_HEAD(&blkif->free_pages); | 127 | INIT_LIST_HEAD(&blkif->free_pages); |
128 | INIT_LIST_HEAD(&blkif->persistent_purge_list); | ||
128 | blkif->free_pages_num = 0; | 129 | blkif->free_pages_num = 0; |
129 | atomic_set(&blkif->persistent_gnt_in_use, 0); | 130 | atomic_set(&blkif->persistent_gnt_in_use, 0); |
131 | atomic_set(&blkif->inflight, 0); | ||
132 | INIT_WORK(&blkif->persistent_purge_work, xen_blkbk_unmap_purged_grants); | ||
130 | 133 | ||
131 | INIT_LIST_HEAD(&blkif->pending_free); | 134 | INIT_LIST_HEAD(&blkif->pending_free); |
132 | 135 | ||
@@ -259,6 +262,17 @@ static void xen_blkif_free(struct xen_blkif *blkif) | |||
259 | if (!atomic_dec_and_test(&blkif->refcnt)) | 262 | if (!atomic_dec_and_test(&blkif->refcnt)) |
260 | BUG(); | 263 | BUG(); |
261 | 264 | ||
265 | /* Remove all persistent grants and the cache of ballooned pages. */ | ||
266 | xen_blkbk_free_caches(blkif); | ||
267 | |||
268 | /* Make sure everything is drained before shutting down */ | ||
269 | BUG_ON(blkif->persistent_gnt_c != 0); | ||
270 | BUG_ON(atomic_read(&blkif->persistent_gnt_in_use) != 0); | ||
271 | BUG_ON(blkif->free_pages_num != 0); | ||
272 | BUG_ON(!list_empty(&blkif->persistent_purge_list)); | ||
273 | BUG_ON(!list_empty(&blkif->free_pages)); | ||
274 | BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); | ||
275 | |||
262 | /* Check that there is no request in use */ | 276 | /* Check that there is no request in use */ |
263 | list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) { | 277 | list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) { |
264 | list_del(&req->free_list); | 278 | list_del(&req->free_list); |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 8dcfb54f1603..efe1b4761735 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -162,7 +162,7 @@ static DEFINE_SPINLOCK(minor_lock); | |||
162 | #define DEV_NAME "xvd" /* name in /dev */ | 162 | #define DEV_NAME "xvd" /* name in /dev */ |
163 | 163 | ||
164 | #define SEGS_PER_INDIRECT_FRAME \ | 164 | #define SEGS_PER_INDIRECT_FRAME \ |
165 | (PAGE_SIZE/sizeof(struct blkif_request_segment_aligned)) | 165 | (PAGE_SIZE/sizeof(struct blkif_request_segment)) |
166 | #define INDIRECT_GREFS(_segs) \ | 166 | #define INDIRECT_GREFS(_segs) \ |
167 | ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) | 167 | ((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME) |
168 | 168 | ||
@@ -393,7 +393,7 @@ static int blkif_queue_request(struct request *req) | |||
393 | unsigned long id; | 393 | unsigned long id; |
394 | unsigned int fsect, lsect; | 394 | unsigned int fsect, lsect; |
395 | int i, ref, n; | 395 | int i, ref, n; |
396 | struct blkif_request_segment_aligned *segments = NULL; | 396 | struct blkif_request_segment *segments = NULL; |
397 | 397 | ||
398 | /* | 398 | /* |
399 | * Used to store if we are able to queue the request by just using | 399 | * Used to store if we are able to queue the request by just using |
@@ -550,7 +550,7 @@ static int blkif_queue_request(struct request *req) | |||
550 | } else { | 550 | } else { |
551 | n = i % SEGS_PER_INDIRECT_FRAME; | 551 | n = i % SEGS_PER_INDIRECT_FRAME; |
552 | segments[n] = | 552 | segments[n] = |
553 | (struct blkif_request_segment_aligned) { | 553 | (struct blkif_request_segment) { |
554 | .gref = ref, | 554 | .gref = ref, |
555 | .first_sect = fsect, | 555 | .first_sect = fsect, |
556 | .last_sect = lsect }; | 556 | .last_sect = lsect }; |
@@ -1904,13 +1904,16 @@ static void blkback_changed(struct xenbus_device *dev, | |||
1904 | case XenbusStateReconfiguring: | 1904 | case XenbusStateReconfiguring: |
1905 | case XenbusStateReconfigured: | 1905 | case XenbusStateReconfigured: |
1906 | case XenbusStateUnknown: | 1906 | case XenbusStateUnknown: |
1907 | case XenbusStateClosed: | ||
1908 | break; | 1907 | break; |
1909 | 1908 | ||
1910 | case XenbusStateConnected: | 1909 | case XenbusStateConnected: |
1911 | blkfront_connect(info); | 1910 | blkfront_connect(info); |
1912 | break; | 1911 | break; |
1913 | 1912 | ||
1913 | case XenbusStateClosed: | ||
1914 | if (dev->state == XenbusStateClosed) | ||
1915 | break; | ||
1916 | /* Missed the backend's Closing state -- fallthrough */ | ||
1914 | case XenbusStateClosing: | 1917 | case XenbusStateClosing: |
1915 | blkfront_closing(info); | 1918 | blkfront_closing(info); |
1916 | break; | 1919 | break; |
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 011e55d820b1..51c557cfd92b 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -612,6 +612,8 @@ static ssize_t disksize_store(struct device *dev, | |||
612 | 612 | ||
613 | disksize = PAGE_ALIGN(disksize); | 613 | disksize = PAGE_ALIGN(disksize); |
614 | meta = zram_meta_alloc(disksize); | 614 | meta = zram_meta_alloc(disksize); |
615 | if (!meta) | ||
616 | return -ENOMEM; | ||
615 | down_write(&zram->init_lock); | 617 | down_write(&zram->init_lock); |
616 | if (zram->init_done) { | 618 | if (zram->init_done) { |
617 | up_write(&zram->init_lock); | 619 | up_write(&zram->init_lock); |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index fa3243d71c76..1386749b48ff 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -499,6 +499,7 @@ config RAW_DRIVER | |||
499 | config MAX_RAW_DEVS | 499 | config MAX_RAW_DEVS |
500 | int "Maximum number of RAW devices to support (1-65536)" | 500 | int "Maximum number of RAW devices to support (1-65536)" |
501 | depends on RAW_DRIVER | 501 | depends on RAW_DRIVER |
502 | range 1 65536 | ||
502 | default "256" | 503 | default "256" |
503 | help | 504 | help |
504 | The maximum number of RAW devices that are supported. | 505 | The maximum number of RAW devices that are supported. |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index f3223aac4df1..6e8d65e9b1d3 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -190,7 +190,7 @@ static int bind_get(int number, dev_t *dev) | |||
190 | struct raw_device_data *rawdev; | 190 | struct raw_device_data *rawdev; |
191 | struct block_device *bdev; | 191 | struct block_device *bdev; |
192 | 192 | ||
193 | if (number <= 0 || number >= MAX_RAW_MINORS) | 193 | if (number <= 0 || number >= max_raw_minors) |
194 | return -EINVAL; | 194 | return -EINVAL; |
195 | 195 | ||
196 | rawdev = &raw_devices[number]; | 196 | rawdev = &raw_devices[number]; |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index feea87cc6b8f..6928d094451d 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -890,12 +890,10 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
890 | } else { | 890 | } else { |
891 | /* Failback to copying a page */ | 891 | /* Failback to copying a page */ |
892 | struct page *page = alloc_page(GFP_KERNEL); | 892 | struct page *page = alloc_page(GFP_KERNEL); |
893 | char *src = buf->ops->map(pipe, buf, 1); | 893 | char *src; |
894 | char *dst; | ||
895 | 894 | ||
896 | if (!page) | 895 | if (!page) |
897 | return -ENOMEM; | 896 | return -ENOMEM; |
898 | dst = kmap(page); | ||
899 | 897 | ||
900 | offset = sd->pos & ~PAGE_MASK; | 898 | offset = sd->pos & ~PAGE_MASK; |
901 | 899 | ||
@@ -903,9 +901,8 @@ static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
903 | if (len + offset > PAGE_SIZE) | 901 | if (len + offset > PAGE_SIZE) |
904 | len = PAGE_SIZE - offset; | 902 | len = PAGE_SIZE - offset; |
905 | 903 | ||
906 | memcpy(dst + offset, src + buf->offset, len); | 904 | src = buf->ops->map(pipe, buf, 1); |
907 | 905 | memcpy(page_address(page) + offset, src + buf->offset, len); | |
908 | kunmap(page); | ||
909 | buf->ops->unmap(pipe, buf, src); | 906 | buf->ops->unmap(pipe, buf, src); |
910 | 907 | ||
911 | sg_set_page(&(sgl->sg[sgl->n]), page, len, offset); | 908 | sg_set_page(&(sgl->sg[sgl->n]), page, len, offset); |
diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index bd313f7816a8..c1af80bcdf20 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c | |||
@@ -242,7 +242,7 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, | |||
242 | 242 | ||
243 | irq = irq_of_parse_and_map(np, 0); | 243 | irq = irq_of_parse_and_map(np, 0); |
244 | if (!irq) | 244 | if (!irq) |
245 | return; | 245 | goto out_free_characteristics; |
246 | 246 | ||
247 | clk = at91_clk_register_master(pmc, irq, name, num_parents, | 247 | clk = at91_clk_register_master(pmc, irq, name, num_parents, |
248 | parent_names, layout, | 248 | parent_names, layout, |
diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index 6a934a5296bd..05e04ce0f148 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c | |||
@@ -494,6 +494,9 @@ static const struct file_operations nomadik_src_clk_debugfs_ops = { | |||
494 | 494 | ||
495 | static int __init nomadik_src_clk_init_debugfs(void) | 495 | static int __init nomadik_src_clk_init_debugfs(void) |
496 | { | 496 | { |
497 | /* Vital for multiplatform */ | ||
498 | if (!src_base) | ||
499 | return -ENODEV; | ||
497 | src_pcksr0_boot = readl(src_base + SRC_PCKSR0); | 500 | src_pcksr0_boot = readl(src_base + SRC_PCKSR0); |
498 | src_pcksr1_boot = readl(src_base + SRC_PCKSR1); | 501 | src_pcksr1_boot = readl(src_base + SRC_PCKSR1); |
499 | debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO, | 502 | debugfs_create_file("nomadik-src-clk", S_IFREG | S_IRUGO, |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 5517944495d8..c42e608af6bb 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -2226,24 +2226,25 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister); | |||
2226 | */ | 2226 | */ |
2227 | int __clk_get(struct clk *clk) | 2227 | int __clk_get(struct clk *clk) |
2228 | { | 2228 | { |
2229 | if (clk && !try_module_get(clk->owner)) | 2229 | if (clk) { |
2230 | return 0; | 2230 | if (!try_module_get(clk->owner)) |
2231 | return 0; | ||
2231 | 2232 | ||
2232 | kref_get(&clk->ref); | 2233 | kref_get(&clk->ref); |
2234 | } | ||
2233 | return 1; | 2235 | return 1; |
2234 | } | 2236 | } |
2235 | 2237 | ||
2236 | void __clk_put(struct clk *clk) | 2238 | void __clk_put(struct clk *clk) |
2237 | { | 2239 | { |
2238 | if (WARN_ON_ONCE(IS_ERR(clk))) | 2240 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) |
2239 | return; | 2241 | return; |
2240 | 2242 | ||
2241 | clk_prepare_lock(); | 2243 | clk_prepare_lock(); |
2242 | kref_put(&clk->ref, __clk_release); | 2244 | kref_put(&clk->ref, __clk_release); |
2243 | clk_prepare_unlock(); | 2245 | clk_prepare_unlock(); |
2244 | 2246 | ||
2245 | if (clk) | 2247 | module_put(clk->owner); |
2246 | module_put(clk->owner); | ||
2247 | } | 2248 | } |
2248 | 2249 | ||
2249 | /*** clk rate change notifiers ***/ | 2250 | /*** clk rate change notifiers ***/ |
diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index 17a598398a53..86f1e362eafb 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c | |||
@@ -179,6 +179,7 @@ static struct clk *clk_register_psc(struct device *dev, | |||
179 | 179 | ||
180 | init.name = name; | 180 | init.name = name; |
181 | init.ops = &clk_psc_ops; | 181 | init.ops = &clk_psc_ops; |
182 | init.flags = 0; | ||
182 | init.parent_names = (parent_name ? &parent_name : NULL); | 183 | init.parent_names = (parent_name ? &parent_name : NULL); |
183 | init.num_parents = (parent_name ? 1 : 0); | 184 | init.num_parents = (parent_name ? 1 : 0); |
184 | 185 | ||
diff --git a/drivers/clk/mvebu/armada-370.c b/drivers/clk/mvebu/armada-370.c index 81a202d12a7a..bef198a83863 100644 --- a/drivers/clk/mvebu/armada-370.c +++ b/drivers/clk/mvebu/armada-370.c | |||
@@ -141,13 +141,6 @@ static const struct coreclk_soc_desc a370_coreclks = { | |||
141 | .num_ratios = ARRAY_SIZE(a370_coreclk_ratios), | 141 | .num_ratios = ARRAY_SIZE(a370_coreclk_ratios), |
142 | }; | 142 | }; |
143 | 143 | ||
144 | static void __init a370_coreclk_init(struct device_node *np) | ||
145 | { | ||
146 | mvebu_coreclk_setup(np, &a370_coreclks); | ||
147 | } | ||
148 | CLK_OF_DECLARE(a370_core_clk, "marvell,armada-370-core-clock", | ||
149 | a370_coreclk_init); | ||
150 | |||
151 | /* | 144 | /* |
152 | * Clock Gating Control | 145 | * Clock Gating Control |
153 | */ | 146 | */ |
@@ -168,9 +161,15 @@ static const struct clk_gating_soc_desc a370_gating_desc[] __initconst = { | |||
168 | { } | 161 | { } |
169 | }; | 162 | }; |
170 | 163 | ||
171 | static void __init a370_clk_gating_init(struct device_node *np) | 164 | static void __init a370_clk_init(struct device_node *np) |
172 | { | 165 | { |
173 | mvebu_clk_gating_setup(np, a370_gating_desc); | 166 | struct device_node *cgnp = |
167 | of_find_compatible_node(NULL, NULL, "marvell,armada-370-gating-clock"); | ||
168 | |||
169 | mvebu_coreclk_setup(np, &a370_coreclks); | ||
170 | |||
171 | if (cgnp) | ||
172 | mvebu_clk_gating_setup(cgnp, a370_gating_desc); | ||
174 | } | 173 | } |
175 | CLK_OF_DECLARE(a370_clk_gating, "marvell,armada-370-gating-clock", | 174 | CLK_OF_DECLARE(a370_clk, "marvell,armada-370-core-clock", a370_clk_init); |
176 | a370_clk_gating_init); | 175 | |
diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c index 9922c4475aa8..b3094315a3c0 100644 --- a/drivers/clk/mvebu/armada-xp.c +++ b/drivers/clk/mvebu/armada-xp.c | |||
@@ -158,13 +158,6 @@ static const struct coreclk_soc_desc axp_coreclks = { | |||
158 | .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), | 158 | .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static void __init axp_coreclk_init(struct device_node *np) | ||
162 | { | ||
163 | mvebu_coreclk_setup(np, &axp_coreclks); | ||
164 | } | ||
165 | CLK_OF_DECLARE(axp_core_clk, "marvell,armada-xp-core-clock", | ||
166 | axp_coreclk_init); | ||
167 | |||
168 | /* | 161 | /* |
169 | * Clock Gating Control | 162 | * Clock Gating Control |
170 | */ | 163 | */ |
@@ -202,9 +195,14 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { | |||
202 | { } | 195 | { } |
203 | }; | 196 | }; |
204 | 197 | ||
205 | static void __init axp_clk_gating_init(struct device_node *np) | 198 | static void __init axp_clk_init(struct device_node *np) |
206 | { | 199 | { |
207 | mvebu_clk_gating_setup(np, axp_gating_desc); | 200 | struct device_node *cgnp = |
201 | of_find_compatible_node(NULL, NULL, "marvell,armada-xp-gating-clock"); | ||
202 | |||
203 | mvebu_coreclk_setup(np, &axp_coreclks); | ||
204 | |||
205 | if (cgnp) | ||
206 | mvebu_clk_gating_setup(cgnp, axp_gating_desc); | ||
208 | } | 207 | } |
209 | CLK_OF_DECLARE(axp_clk_gating, "marvell,armada-xp-gating-clock", | 208 | CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init); |
210 | axp_clk_gating_init); | ||
diff --git a/drivers/clk/mvebu/dove.c b/drivers/clk/mvebu/dove.c index 38aee1e3f242..b8c2424ac926 100644 --- a/drivers/clk/mvebu/dove.c +++ b/drivers/clk/mvebu/dove.c | |||
@@ -154,12 +154,6 @@ static const struct coreclk_soc_desc dove_coreclks = { | |||
154 | .num_ratios = ARRAY_SIZE(dove_coreclk_ratios), | 154 | .num_ratios = ARRAY_SIZE(dove_coreclk_ratios), |
155 | }; | 155 | }; |
156 | 156 | ||
157 | static void __init dove_coreclk_init(struct device_node *np) | ||
158 | { | ||
159 | mvebu_coreclk_setup(np, &dove_coreclks); | ||
160 | } | ||
161 | CLK_OF_DECLARE(dove_core_clk, "marvell,dove-core-clock", dove_coreclk_init); | ||
162 | |||
163 | /* | 157 | /* |
164 | * Clock Gating Control | 158 | * Clock Gating Control |
165 | */ | 159 | */ |
@@ -186,9 +180,14 @@ static const struct clk_gating_soc_desc dove_gating_desc[] __initconst = { | |||
186 | { } | 180 | { } |
187 | }; | 181 | }; |
188 | 182 | ||
189 | static void __init dove_clk_gating_init(struct device_node *np) | 183 | static void __init dove_clk_init(struct device_node *np) |
190 | { | 184 | { |
191 | mvebu_clk_gating_setup(np, dove_gating_desc); | 185 | struct device_node *cgnp = |
186 | of_find_compatible_node(NULL, NULL, "marvell,dove-gating-clock"); | ||
187 | |||
188 | mvebu_coreclk_setup(np, &dove_coreclks); | ||
189 | |||
190 | if (cgnp) | ||
191 | mvebu_clk_gating_setup(cgnp, dove_gating_desc); | ||
192 | } | 192 | } |
193 | CLK_OF_DECLARE(dove_clk_gating, "marvell,dove-gating-clock", | 193 | CLK_OF_DECLARE(dove_clk, "marvell,dove-core-clock", dove_clk_init); |
194 | dove_clk_gating_init); | ||
diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 2636a55f29f9..ddb666a86500 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c | |||
@@ -193,13 +193,6 @@ static const struct coreclk_soc_desc kirkwood_coreclks = { | |||
193 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), | 193 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), |
194 | }; | 194 | }; |
195 | 195 | ||
196 | static void __init kirkwood_coreclk_init(struct device_node *np) | ||
197 | { | ||
198 | mvebu_coreclk_setup(np, &kirkwood_coreclks); | ||
199 | } | ||
200 | CLK_OF_DECLARE(kirkwood_core_clk, "marvell,kirkwood-core-clock", | ||
201 | kirkwood_coreclk_init); | ||
202 | |||
203 | static const struct coreclk_soc_desc mv88f6180_coreclks = { | 196 | static const struct coreclk_soc_desc mv88f6180_coreclks = { |
204 | .get_tclk_freq = kirkwood_get_tclk_freq, | 197 | .get_tclk_freq = kirkwood_get_tclk_freq, |
205 | .get_cpu_freq = mv88f6180_get_cpu_freq, | 198 | .get_cpu_freq = mv88f6180_get_cpu_freq, |
@@ -208,13 +201,6 @@ static const struct coreclk_soc_desc mv88f6180_coreclks = { | |||
208 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), | 201 | .num_ratios = ARRAY_SIZE(kirkwood_coreclk_ratios), |
209 | }; | 202 | }; |
210 | 203 | ||
211 | static void __init mv88f6180_coreclk_init(struct device_node *np) | ||
212 | { | ||
213 | mvebu_coreclk_setup(np, &mv88f6180_coreclks); | ||
214 | } | ||
215 | CLK_OF_DECLARE(mv88f6180_core_clk, "marvell,mv88f6180-core-clock", | ||
216 | mv88f6180_coreclk_init); | ||
217 | |||
218 | /* | 204 | /* |
219 | * Clock Gating Control | 205 | * Clock Gating Control |
220 | */ | 206 | */ |
@@ -239,9 +225,21 @@ static const struct clk_gating_soc_desc kirkwood_gating_desc[] __initconst = { | |||
239 | { } | 225 | { } |
240 | }; | 226 | }; |
241 | 227 | ||
242 | static void __init kirkwood_clk_gating_init(struct device_node *np) | 228 | static void __init kirkwood_clk_init(struct device_node *np) |
243 | { | 229 | { |
244 | mvebu_clk_gating_setup(np, kirkwood_gating_desc); | 230 | struct device_node *cgnp = |
231 | of_find_compatible_node(NULL, NULL, "marvell,kirkwood-gating-clock"); | ||
232 | |||
233 | |||
234 | if (of_device_is_compatible(np, "marvell,mv88f6180-core-clock")) | ||
235 | mvebu_coreclk_setup(np, &mv88f6180_coreclks); | ||
236 | else | ||
237 | mvebu_coreclk_setup(np, &kirkwood_coreclks); | ||
238 | |||
239 | if (cgnp) | ||
240 | mvebu_clk_gating_setup(cgnp, kirkwood_gating_desc); | ||
245 | } | 241 | } |
246 | CLK_OF_DECLARE(kirkwood_clk_gating, "marvell,kirkwood-gating-clock", | 242 | CLK_OF_DECLARE(kirkwood_clk, "marvell,kirkwood-core-clock", |
247 | kirkwood_clk_gating_init); | 243 | kirkwood_clk_init); |
244 | CLK_OF_DECLARE(mv88f6180_clk, "marvell,mv88f6180-core-clock", | ||
245 | kirkwood_clk_init); | ||
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c index a59ec217a124..99c27b1c625b 100644 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ b/drivers/clk/shmobile/clk-rcar-gen2.c | |||
@@ -26,6 +26,8 @@ struct rcar_gen2_cpg { | |||
26 | void __iomem *reg; | 26 | void __iomem *reg; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | #define CPG_FRQCRB 0x00000004 | ||
30 | #define CPG_FRQCRB_KICK BIT(31) | ||
29 | #define CPG_SDCKCR 0x00000074 | 31 | #define CPG_SDCKCR 0x00000074 |
30 | #define CPG_PLL0CR 0x000000d8 | 32 | #define CPG_PLL0CR 0x000000d8 |
31 | #define CPG_FRQCRC 0x000000e0 | 33 | #define CPG_FRQCRC 0x000000e0 |
@@ -45,6 +47,7 @@ struct rcar_gen2_cpg { | |||
45 | struct cpg_z_clk { | 47 | struct cpg_z_clk { |
46 | struct clk_hw hw; | 48 | struct clk_hw hw; |
47 | void __iomem *reg; | 49 | void __iomem *reg; |
50 | void __iomem *kick_reg; | ||
48 | }; | 51 | }; |
49 | 52 | ||
50 | #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) | 53 | #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) |
@@ -83,17 +86,45 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, | |||
83 | { | 86 | { |
84 | struct cpg_z_clk *zclk = to_z_clk(hw); | 87 | struct cpg_z_clk *zclk = to_z_clk(hw); |
85 | unsigned int mult; | 88 | unsigned int mult; |
86 | u32 val; | 89 | u32 val, kick; |
90 | unsigned int i; | ||
87 | 91 | ||
88 | mult = div_u64((u64)rate * 32, parent_rate); | 92 | mult = div_u64((u64)rate * 32, parent_rate); |
89 | mult = clamp(mult, 1U, 32U); | 93 | mult = clamp(mult, 1U, 32U); |
90 | 94 | ||
95 | if (clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK) | ||
96 | return -EBUSY; | ||
97 | |||
91 | val = clk_readl(zclk->reg); | 98 | val = clk_readl(zclk->reg); |
92 | val &= ~CPG_FRQCRC_ZFC_MASK; | 99 | val &= ~CPG_FRQCRC_ZFC_MASK; |
93 | val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; | 100 | val |= (32 - mult) << CPG_FRQCRC_ZFC_SHIFT; |
94 | clk_writel(val, zclk->reg); | 101 | clk_writel(val, zclk->reg); |
95 | 102 | ||
96 | return 0; | 103 | /* |
104 | * Set KICK bit in FRQCRB to update hardware setting and wait for | ||
105 | * clock change completion. | ||
106 | */ | ||
107 | kick = clk_readl(zclk->kick_reg); | ||
108 | kick |= CPG_FRQCRB_KICK; | ||
109 | clk_writel(kick, zclk->kick_reg); | ||
110 | |||
111 | /* | ||
112 | * Note: There is no HW information about the worst case latency. | ||
113 | * | ||
114 | * Using experimental measurements, it seems that no more than | ||
115 | * ~10 iterations are needed, independently of the CPU rate. | ||
116 | * Since this value might be dependant of external xtal rate, pll1 | ||
117 | * rate or even the other emulation clocks rate, use 1000 as a | ||
118 | * "super" safe value. | ||
119 | */ | ||
120 | for (i = 1000; i; i--) { | ||
121 | if (!(clk_readl(zclk->kick_reg) & CPG_FRQCRB_KICK)) | ||
122 | return 0; | ||
123 | |||
124 | cpu_relax(); | ||
125 | } | ||
126 | |||
127 | return -ETIMEDOUT; | ||
97 | } | 128 | } |
98 | 129 | ||
99 | static const struct clk_ops cpg_z_clk_ops = { | 130 | static const struct clk_ops cpg_z_clk_ops = { |
@@ -120,6 +151,7 @@ static struct clk * __init cpg_z_clk_register(struct rcar_gen2_cpg *cpg) | |||
120 | init.num_parents = 1; | 151 | init.num_parents = 1; |
121 | 152 | ||
122 | zclk->reg = cpg->reg + CPG_FRQCRC; | 153 | zclk->reg = cpg->reg + CPG_FRQCRC; |
154 | zclk->kick_reg = cpg->reg + CPG_FRQCRB; | ||
123 | zclk->hw.init = &init; | 155 | zclk->hw.init = &init; |
124 | 156 | ||
125 | clk = clk_register(NULL, &zclk->hw); | 157 | clk = clk_register(NULL, &zclk->hw); |
@@ -186,7 +218,7 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, | |||
186 | const char *name) | 218 | const char *name) |
187 | { | 219 | { |
188 | const struct clk_div_table *table = NULL; | 220 | const struct clk_div_table *table = NULL; |
189 | const char *parent_name = "main"; | 221 | const char *parent_name; |
190 | unsigned int shift; | 222 | unsigned int shift; |
191 | unsigned int mult = 1; | 223 | unsigned int mult = 1; |
192 | unsigned int div = 1; | 224 | unsigned int div = 1; |
@@ -201,23 +233,31 @@ rcar_gen2_cpg_register_clock(struct device_node *np, struct rcar_gen2_cpg *cpg, | |||
201 | * the multiplier value. | 233 | * the multiplier value. |
202 | */ | 234 | */ |
203 | u32 value = clk_readl(cpg->reg + CPG_PLL0CR); | 235 | u32 value = clk_readl(cpg->reg + CPG_PLL0CR); |
236 | parent_name = "main"; | ||
204 | mult = ((value >> 24) & ((1 << 7) - 1)) + 1; | 237 | mult = ((value >> 24) & ((1 << 7) - 1)) + 1; |
205 | } else if (!strcmp(name, "pll1")) { | 238 | } else if (!strcmp(name, "pll1")) { |
239 | parent_name = "main"; | ||
206 | mult = config->pll1_mult / 2; | 240 | mult = config->pll1_mult / 2; |
207 | } else if (!strcmp(name, "pll3")) { | 241 | } else if (!strcmp(name, "pll3")) { |
242 | parent_name = "main"; | ||
208 | mult = config->pll3_mult; | 243 | mult = config->pll3_mult; |
209 | } else if (!strcmp(name, "lb")) { | 244 | } else if (!strcmp(name, "lb")) { |
245 | parent_name = "pll1_div2"; | ||
210 | div = cpg_mode & BIT(18) ? 36 : 24; | 246 | div = cpg_mode & BIT(18) ? 36 : 24; |
211 | } else if (!strcmp(name, "qspi")) { | 247 | } else if (!strcmp(name, "qspi")) { |
248 | parent_name = "pll1_div2"; | ||
212 | div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) | 249 | div = (cpg_mode & (BIT(3) | BIT(2) | BIT(1))) == BIT(2) |
213 | ? 16 : 20; | 250 | ? 8 : 10; |
214 | } else if (!strcmp(name, "sdh")) { | 251 | } else if (!strcmp(name, "sdh")) { |
252 | parent_name = "pll1_div2"; | ||
215 | table = cpg_sdh_div_table; | 253 | table = cpg_sdh_div_table; |
216 | shift = 8; | 254 | shift = 8; |
217 | } else if (!strcmp(name, "sd0")) { | 255 | } else if (!strcmp(name, "sd0")) { |
256 | parent_name = "pll1_div2"; | ||
218 | table = cpg_sd01_div_table; | 257 | table = cpg_sd01_div_table; |
219 | shift = 4; | 258 | shift = 4; |
220 | } else if (!strcmp(name, "sd1")) { | 259 | } else if (!strcmp(name, "sd1")) { |
260 | parent_name = "pll1_div2"; | ||
221 | table = cpg_sd01_div_table; | 261 | table = cpg_sd01_div_table; |
222 | shift = 0; | 262 | shift = 0; |
223 | } else if (!strcmp(name, "z")) { | 263 | } else if (!strcmp(name, "z")) { |
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 4d75b1f37e3a..290f9c1a3749 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c | |||
@@ -59,7 +59,7 @@ static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, | |||
59 | return 0; | 59 | return 0; |
60 | 60 | ||
61 | if (divider_ux1 > get_max_div(divider)) | 61 | if (divider_ux1 > get_max_div(divider)) |
62 | return -EINVAL; | 62 | return get_max_div(divider); |
63 | 63 | ||
64 | return divider_ux1; | 64 | return divider_ux1; |
65 | } | 65 | } |
diff --git a/drivers/clk/tegra/clk-id.h b/drivers/clk/tegra/clk-id.h index cf0c323f2c36..c39613c519af 100644 --- a/drivers/clk/tegra/clk-id.h +++ b/drivers/clk/tegra/clk-id.h | |||
@@ -180,9 +180,13 @@ enum clk_id { | |||
180 | tegra_clk_sbc6_8, | 180 | tegra_clk_sbc6_8, |
181 | tegra_clk_sclk, | 181 | tegra_clk_sclk, |
182 | tegra_clk_sdmmc1, | 182 | tegra_clk_sdmmc1, |
183 | tegra_clk_sdmmc1_8, | ||
183 | tegra_clk_sdmmc2, | 184 | tegra_clk_sdmmc2, |
185 | tegra_clk_sdmmc2_8, | ||
184 | tegra_clk_sdmmc3, | 186 | tegra_clk_sdmmc3, |
187 | tegra_clk_sdmmc3_8, | ||
185 | tegra_clk_sdmmc4, | 188 | tegra_clk_sdmmc4, |
189 | tegra_clk_sdmmc4_8, | ||
186 | tegra_clk_se, | 190 | tegra_clk_se, |
187 | tegra_clk_soc_therm, | 191 | tegra_clk_soc_therm, |
188 | tegra_clk_sor0, | 192 | tegra_clk_sor0, |
diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 5c35885f4a7c..1fa5c3f33b20 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c | |||
@@ -371,9 +371,7 @@ static const char *mux_pllp3_pllc_clkm[] = { | |||
371 | static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { | 371 | static const char *mux_pllm_pllc_pllp_plla_pllc2_c3_clkm[] = { |
372 | "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" | 372 | "pll_m", "pll_c", "pll_p", "pll_a", "pll_c2", "pll_c3", "clk_m" |
373 | }; | 373 | }; |
374 | static u32 mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx[] = { | 374 | #define mux_pllm_pllc_pllp_plla_pllc2_c3_clkm_idx NULL |
375 | [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6, | ||
376 | }; | ||
377 | 375 | ||
378 | static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { | 376 | static const char *mux_pllm_pllc2_c_c3_pllp_plla_pllc4[] = { |
379 | "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", | 377 | "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0", "pll_c4", |
@@ -465,6 +463,10 @@ static struct tegra_periph_init_data periph_clks[] = { | |||
465 | MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), | 463 | MUX("adx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX1, 180, TEGRA_PERIPH_ON_APB, tegra_clk_adx1), |
466 | MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), | 464 | MUX("amx1", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX1, 185, TEGRA_PERIPH_ON_APB, tegra_clk_amx1), |
467 | MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), | 465 | MUX("vi_sensor2", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR2, 20, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor2), |
466 | MUX8("sdmmc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC1, 14, 0, tegra_clk_sdmmc1_8), | ||
467 | MUX8("sdmmc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC2, 9, 0, tegra_clk_sdmmc2_8), | ||
468 | MUX8("sdmmc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC3, 69, 0, tegra_clk_sdmmc3_8), | ||
469 | MUX8("sdmmc4", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SDMMC4, 15, 0, tegra_clk_sdmmc4_8), | ||
468 | MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), | 470 | MUX8("sbc1", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC1, 41, TEGRA_PERIPH_ON_APB, tegra_clk_sbc1_8), |
469 | MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), | 471 | MUX8("sbc2", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC2, 44, TEGRA_PERIPH_ON_APB, tegra_clk_sbc2_8), |
470 | MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), | 472 | MUX8("sbc3", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SBC3, 46, TEGRA_PERIPH_ON_APB, tegra_clk_sbc3_8), |
@@ -492,7 +494,7 @@ static struct tegra_periph_init_data periph_clks[] = { | |||
492 | UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), | 494 | UART("uartb", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, tegra_clk_uartb), |
493 | UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), | 495 | UART("uartc", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, tegra_clk_uartc), |
494 | UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), | 496 | UART("uartd", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, tegra_clk_uartd), |
495 | UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 65, tegra_clk_uarte), | 497 | UART("uarte", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTE, 66, tegra_clk_uarte), |
496 | XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), | 498 | XUSB("xusb_host_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_host_src), |
497 | XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), | 499 | XUSB("xusb_falcon_src", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_falcon_src), |
498 | XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), | 500 | XUSB("xusb_fs_src", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, TEGRA_PERIPH_NO_RESET, tegra_clk_xusb_fs_src), |
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c index 05dce4aa2c11..feb3201c85ce 100644 --- a/drivers/clk/tegra/clk-tegra-super-gen4.c +++ b/drivers/clk/tegra/clk-tegra-super-gen4.c | |||
@@ -120,7 +120,7 @@ void __init tegra_super_clk_gen4_init(void __iomem *clk_base, | |||
120 | ARRAY_SIZE(cclk_lp_parents), | 120 | ARRAY_SIZE(cclk_lp_parents), |
121 | CLK_SET_RATE_PARENT, | 121 | CLK_SET_RATE_PARENT, |
122 | clk_base + CCLKLP_BURST_POLICY, | 122 | clk_base + CCLKLP_BURST_POLICY, |
123 | 0, 4, 8, 9, NULL); | 123 | TEGRA_DIVIDER_2, 4, 8, 9, NULL); |
124 | *dt_clk = clk; | 124 | *dt_clk = clk; |
125 | } | 125 | } |
126 | 126 | ||
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 90d9d25f2228..80431f0fb268 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c | |||
@@ -682,12 +682,12 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { | |||
682 | [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, | 682 | [tegra_clk_timer] = { .dt_id = TEGRA114_CLK_TIMER, .present = true }, |
683 | [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, | 683 | [tegra_clk_uarta] = { .dt_id = TEGRA114_CLK_UARTA, .present = true }, |
684 | [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, | 684 | [tegra_clk_uartd] = { .dt_id = TEGRA114_CLK_UARTD, .present = true }, |
685 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, | 685 | [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA114_CLK_SDMMC2, .present = true }, |
686 | [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, | 686 | [tegra_clk_i2s1] = { .dt_id = TEGRA114_CLK_I2S1, .present = true }, |
687 | [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, | 687 | [tegra_clk_i2c1] = { .dt_id = TEGRA114_CLK_I2C1, .present = true }, |
688 | [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, | 688 | [tegra_clk_ndflash] = { .dt_id = TEGRA114_CLK_NDFLASH, .present = true }, |
689 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, | 689 | [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA114_CLK_SDMMC1, .present = true }, |
690 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, | 690 | [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA114_CLK_SDMMC4, .present = true }, |
691 | [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, | 691 | [tegra_clk_pwm] = { .dt_id = TEGRA114_CLK_PWM, .present = true }, |
692 | [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, | 692 | [tegra_clk_i2s0] = { .dt_id = TEGRA114_CLK_I2S0, .present = true }, |
693 | [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, | 693 | [tegra_clk_i2s2] = { .dt_id = TEGRA114_CLK_I2S2, .present = true }, |
@@ -723,7 +723,7 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { | |||
723 | [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, | 723 | [tegra_clk_bsev] = { .dt_id = TEGRA114_CLK_BSEV, .present = true }, |
724 | [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, | 724 | [tegra_clk_i2c3] = { .dt_id = TEGRA114_CLK_I2C3, .present = true }, |
725 | [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, | 725 | [tegra_clk_sbc4_8] = { .dt_id = TEGRA114_CLK_SBC4, .present = true }, |
726 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, | 726 | [tegra_clk_sdmmc3_8] = { .dt_id = TEGRA114_CLK_SDMMC3, .present = true }, |
727 | [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, | 727 | [tegra_clk_owr] = { .dt_id = TEGRA114_CLK_OWR, .present = true }, |
728 | [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, | 728 | [tegra_clk_csite] = { .dt_id = TEGRA114_CLK_CSITE, .present = true }, |
729 | [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, | 729 | [tegra_clk_la] = { .dt_id = TEGRA114_CLK_LA, .present = true }, |
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index aff86b5bc745..166e02f16c8a 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c | |||
@@ -516,11 +516,11 @@ static struct div_nmp pllp_nmp = { | |||
516 | }; | 516 | }; |
517 | 517 | ||
518 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { | 518 | static struct tegra_clk_pll_freq_table pll_p_freq_table[] = { |
519 | {12000000, 216000000, 432, 12, 1, 8}, | 519 | {12000000, 408000000, 408, 12, 0, 8}, |
520 | {13000000, 216000000, 432, 13, 1, 8}, | 520 | {13000000, 408000000, 408, 13, 0, 8}, |
521 | {16800000, 216000000, 360, 14, 1, 8}, | 521 | {16800000, 408000000, 340, 14, 0, 8}, |
522 | {19200000, 216000000, 360, 16, 1, 8}, | 522 | {19200000, 408000000, 340, 16, 0, 8}, |
523 | {26000000, 216000000, 432, 26, 1, 8}, | 523 | {26000000, 408000000, 408, 26, 0, 8}, |
524 | {0, 0, 0, 0, 0, 0}, | 524 | {0, 0, 0, 0, 0, 0}, |
525 | }; | 525 | }; |
526 | 526 | ||
@@ -570,6 +570,15 @@ static struct tegra_clk_pll_params pll_a_params = { | |||
570 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, | 570 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_USE_LOCK, |
571 | }; | 571 | }; |
572 | 572 | ||
573 | static struct div_nmp plld_nmp = { | ||
574 | .divm_shift = 0, | ||
575 | .divm_width = 5, | ||
576 | .divn_shift = 8, | ||
577 | .divn_width = 11, | ||
578 | .divp_shift = 20, | ||
579 | .divp_width = 3, | ||
580 | }; | ||
581 | |||
573 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { | 582 | static struct tegra_clk_pll_freq_table pll_d_freq_table[] = { |
574 | {12000000, 216000000, 864, 12, 4, 12}, | 583 | {12000000, 216000000, 864, 12, 4, 12}, |
575 | {13000000, 216000000, 864, 13, 4, 12}, | 584 | {13000000, 216000000, 864, 13, 4, 12}, |
@@ -603,19 +612,18 @@ static struct tegra_clk_pll_params pll_d_params = { | |||
603 | .lock_mask = PLL_BASE_LOCK, | 612 | .lock_mask = PLL_BASE_LOCK, |
604 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, | 613 | .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE, |
605 | .lock_delay = 1000, | 614 | .lock_delay = 1000, |
606 | .div_nmp = &pllp_nmp, | 615 | .div_nmp = &plld_nmp, |
607 | .freq_table = pll_d_freq_table, | 616 | .freq_table = pll_d_freq_table, |
608 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | | 617 | .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON | |
609 | TEGRA_PLL_USE_LOCK, | 618 | TEGRA_PLL_USE_LOCK, |
610 | }; | 619 | }; |
611 | 620 | ||
612 | static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { | 621 | static struct tegra_clk_pll_freq_table tegra124_pll_d2_freq_table[] = { |
613 | { 12000000, 148500000, 99, 1, 8}, | 622 | { 12000000, 594000000, 99, 1, 2}, |
614 | { 12000000, 594000000, 99, 1, 1}, | 623 | { 13000000, 594000000, 91, 1, 2}, /* actual: 591.5 MHz */ |
615 | { 13000000, 594000000, 91, 1, 1}, /* actual: 591.5 MHz */ | 624 | { 16800000, 594000000, 71, 1, 2}, /* actual: 596.4 MHz */ |
616 | { 16800000, 594000000, 71, 1, 1}, /* actual: 596.4 MHz */ | 625 | { 19200000, 594000000, 62, 1, 2}, /* actual: 595.2 MHz */ |
617 | { 19200000, 594000000, 62, 1, 1}, /* actual: 595.2 MHz */ | 626 | { 26000000, 594000000, 91, 2, 2}, /* actual: 591.5 MHz */ |
618 | { 26000000, 594000000, 91, 2, 1}, /* actual: 591.5 MHz */ | ||
619 | { 0, 0, 0, 0, 0, 0 }, | 627 | { 0, 0, 0, 0, 0, 0 }, |
620 | }; | 628 | }; |
621 | 629 | ||
@@ -753,21 +761,19 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { | |||
753 | [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, | 761 | [tegra_clk_rtc] = { .dt_id = TEGRA124_CLK_RTC, .present = true }, |
754 | [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, | 762 | [tegra_clk_timer] = { .dt_id = TEGRA124_CLK_TIMER, .present = true }, |
755 | [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, | 763 | [tegra_clk_uarta] = { .dt_id = TEGRA124_CLK_UARTA, .present = true }, |
756 | [tegra_clk_sdmmc2] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, | 764 | [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, |
757 | [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, | 765 | [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, |
758 | [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, | 766 | [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, |
759 | [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, | 767 | [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, |
760 | [tegra_clk_sdmmc1] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, | 768 | [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, |
761 | [tegra_clk_sdmmc4] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, | 769 | [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, |
762 | [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, | 770 | [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, |
763 | [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, | 771 | [tegra_clk_i2s2] = { .dt_id = TEGRA124_CLK_I2S2, .present = true }, |
764 | [tegra_clk_gr2d] = { .dt_id = TEGRA124_CLK_GR_2D, .present = true }, | ||
765 | [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, | 772 | [tegra_clk_usbd] = { .dt_id = TEGRA124_CLK_USBD, .present = true }, |
766 | [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, | 773 | [tegra_clk_isp_8] = { .dt_id = TEGRA124_CLK_ISP, .present = true }, |
767 | [tegra_clk_gr3d] = { .dt_id = TEGRA124_CLK_GR_3D, .present = true }, | ||
768 | [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, | 774 | [tegra_clk_disp2] = { .dt_id = TEGRA124_CLK_DISP2, .present = true }, |
769 | [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, | 775 | [tegra_clk_disp1] = { .dt_id = TEGRA124_CLK_DISP1, .present = true }, |
770 | [tegra_clk_host1x] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, | 776 | [tegra_clk_host1x_8] = { .dt_id = TEGRA124_CLK_HOST1X, .present = true }, |
771 | [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, | 777 | [tegra_clk_vcp] = { .dt_id = TEGRA124_CLK_VCP, .present = true }, |
772 | [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, | 778 | [tegra_clk_i2s0] = { .dt_id = TEGRA124_CLK_I2S0, .present = true }, |
773 | [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, | 779 | [tegra_clk_apbdma] = { .dt_id = TEGRA124_CLK_APBDMA, .present = true }, |
@@ -794,7 +800,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { | |||
794 | [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, | 800 | [tegra_clk_uartd] = { .dt_id = TEGRA124_CLK_UARTD, .present = true }, |
795 | [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, | 801 | [tegra_clk_i2c3] = { .dt_id = TEGRA124_CLK_I2C3, .present = true }, |
796 | [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, | 802 | [tegra_clk_sbc4] = { .dt_id = TEGRA124_CLK_SBC4, .present = true }, |
797 | [tegra_clk_sdmmc3] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, | 803 | [tegra_clk_sdmmc3_8] = { .dt_id = TEGRA124_CLK_SDMMC3, .present = true }, |
798 | [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, | 804 | [tegra_clk_pcie] = { .dt_id = TEGRA124_CLK_PCIE, .present = true }, |
799 | [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, | 805 | [tegra_clk_owr] = { .dt_id = TEGRA124_CLK_OWR, .present = true }, |
800 | [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, | 806 | [tegra_clk_afi] = { .dt_id = TEGRA124_CLK_AFI, .present = true }, |
@@ -1286,9 +1292,9 @@ static void __init tegra124_pll_init(void __iomem *clk_base, | |||
1286 | clk_register_clkdev(clk, "pll_d2", NULL); | 1292 | clk_register_clkdev(clk, "pll_d2", NULL); |
1287 | clks[TEGRA124_CLK_PLL_D2] = clk; | 1293 | clks[TEGRA124_CLK_PLL_D2] = clk; |
1288 | 1294 | ||
1289 | /* PLLD2_OUT0 ?? */ | 1295 | /* PLLD2_OUT0 */ |
1290 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", | 1296 | clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2", |
1291 | CLK_SET_RATE_PARENT, 1, 2); | 1297 | CLK_SET_RATE_PARENT, 1, 1); |
1292 | clk_register_clkdev(clk, "pll_d2_out0", NULL); | 1298 | clk_register_clkdev(clk, "pll_d2_out0", NULL); |
1293 | clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; | 1299 | clks[TEGRA124_CLK_PLL_D2_OUT0] = clk; |
1294 | 1300 | ||
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index dbace152b2fa..dace2b1b5ae6 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c | |||
@@ -574,6 +574,8 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { | |||
574 | [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, | 574 | [tegra_clk_tvdac] = { .dt_id = TEGRA20_CLK_TVDAC, .present = true }, |
575 | [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, | 575 | [tegra_clk_vi_sensor] = { .dt_id = TEGRA20_CLK_VI_SENSOR, .present = true }, |
576 | [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, | 576 | [tegra_clk_afi] = { .dt_id = TEGRA20_CLK_AFI, .present = true }, |
577 | [tegra_clk_fuse] = { .dt_id = TEGRA20_CLK_FUSE, .present = true }, | ||
578 | [tegra_clk_kfuse] = { .dt_id = TEGRA20_CLK_KFUSE, .present = true }, | ||
577 | }; | 579 | }; |
578 | 580 | ||
579 | static unsigned long tegra20_clk_measure_input_freq(void) | 581 | static unsigned long tegra20_clk_measure_input_freq(void) |
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index 974b2db2fe10..0595dc6c453e 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c | |||
@@ -99,31 +99,6 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) | |||
99 | return; | 99 | return; |
100 | } | 100 | } |
101 | 101 | ||
102 | static void __init kona_timers_init(struct device_node *node) | ||
103 | { | ||
104 | u32 freq; | ||
105 | struct clk *external_clk; | ||
106 | |||
107 | external_clk = of_clk_get_by_name(node, NULL); | ||
108 | |||
109 | if (!IS_ERR(external_clk)) { | ||
110 | arch_timer_rate = clk_get_rate(external_clk); | ||
111 | clk_prepare_enable(external_clk); | ||
112 | } else if (!of_property_read_u32(node, "clock-frequency", &freq)) { | ||
113 | arch_timer_rate = freq; | ||
114 | } else { | ||
115 | panic("unable to determine clock-frequency"); | ||
116 | } | ||
117 | |||
118 | /* Setup IRQ numbers */ | ||
119 | timers.tmr_irq = irq_of_parse_and_map(node, 0); | ||
120 | |||
121 | /* Setup IO addresses */ | ||
122 | timers.tmr_regs = of_iomap(node, 0); | ||
123 | |||
124 | kona_timer_disable_and_clear(timers.tmr_regs); | ||
125 | } | ||
126 | |||
127 | static int kona_timer_set_next_event(unsigned long clc, | 102 | static int kona_timer_set_next_event(unsigned long clc, |
128 | struct clock_event_device *unused) | 103 | struct clock_event_device *unused) |
129 | { | 104 | { |
@@ -198,7 +173,34 @@ static struct irqaction kona_timer_irq = { | |||
198 | 173 | ||
199 | static void __init kona_timer_init(struct device_node *node) | 174 | static void __init kona_timer_init(struct device_node *node) |
200 | { | 175 | { |
201 | kona_timers_init(node); | 176 | u32 freq; |
177 | struct clk *external_clk; | ||
178 | |||
179 | if (!of_device_is_available(node)) { | ||
180 | pr_info("Kona Timer v1 marked as disabled in device tree\n"); | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | external_clk = of_clk_get_by_name(node, NULL); | ||
185 | |||
186 | if (!IS_ERR(external_clk)) { | ||
187 | arch_timer_rate = clk_get_rate(external_clk); | ||
188 | clk_prepare_enable(external_clk); | ||
189 | } else if (!of_property_read_u32(node, "clock-frequency", &freq)) { | ||
190 | arch_timer_rate = freq; | ||
191 | } else { | ||
192 | pr_err("Kona Timer v1 unable to determine clock-frequency"); | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | /* Setup IRQ numbers */ | ||
197 | timers.tmr_irq = irq_of_parse_and_map(node, 0); | ||
198 | |||
199 | /* Setup IO addresses */ | ||
200 | timers.tmr_regs = of_iomap(node, 0); | ||
201 | |||
202 | kona_timer_disable_and_clear(timers.tmr_regs); | ||
203 | |||
202 | kona_timer_clockevents_init(); | 204 | kona_timer_clockevents_init(); |
203 | setup_irq(timers.tmr_irq, &kona_timer_irq); | 205 | setup_irq(timers.tmr_irq, &kona_timer_irq); |
204 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); | 206 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); |
diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c index 02821b06a39e..a918bc481c52 100644 --- a/drivers/clocksource/vf_pit_timer.c +++ b/drivers/clocksource/vf_pit_timer.c | |||
@@ -54,7 +54,7 @@ static inline void pit_irq_acknowledge(void) | |||
54 | 54 | ||
55 | static u64 pit_read_sched_clock(void) | 55 | static u64 pit_read_sched_clock(void) |
56 | { | 56 | { |
57 | return __raw_readl(clksrc_base + PITCVAL); | 57 | return ~__raw_readl(clksrc_base + PITCVAL); |
58 | } | 58 | } |
59 | 59 | ||
60 | static int __init pit_clocksource_init(unsigned long rate) | 60 | static int __init pit_clocksource_init(unsigned long rate) |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 08ca8c9f41cd..199b52b7c3e1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1109,12 +1109,27 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1109 | goto err_set_policy_cpu; | 1109 | goto err_set_policy_cpu; |
1110 | } | 1110 | } |
1111 | 1111 | ||
1112 | /* related cpus should atleast have policy->cpus */ | ||
1113 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | ||
1114 | |||
1115 | /* | ||
1116 | * affected cpus must always be the one, which are online. We aren't | ||
1117 | * managing offline cpus here. | ||
1118 | */ | ||
1119 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); | ||
1120 | |||
1121 | if (!frozen) { | ||
1122 | policy->user_policy.min = policy->min; | ||
1123 | policy->user_policy.max = policy->max; | ||
1124 | } | ||
1125 | |||
1126 | down_write(&policy->rwsem); | ||
1112 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1127 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
1113 | for_each_cpu(j, policy->cpus) | 1128 | for_each_cpu(j, policy->cpus) |
1114 | per_cpu(cpufreq_cpu_data, j) = policy; | 1129 | per_cpu(cpufreq_cpu_data, j) = policy; |
1115 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1130 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
1116 | 1131 | ||
1117 | if (cpufreq_driver->get) { | 1132 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { |
1118 | policy->cur = cpufreq_driver->get(policy->cpu); | 1133 | policy->cur = cpufreq_driver->get(policy->cpu); |
1119 | if (!policy->cur) { | 1134 | if (!policy->cur) { |
1120 | pr_err("%s: ->get() failed\n", __func__); | 1135 | pr_err("%s: ->get() failed\n", __func__); |
@@ -1162,20 +1177,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1162 | } | 1177 | } |
1163 | } | 1178 | } |
1164 | 1179 | ||
1165 | /* related cpus should atleast have policy->cpus */ | ||
1166 | cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus); | ||
1167 | |||
1168 | /* | ||
1169 | * affected cpus must always be the one, which are online. We aren't | ||
1170 | * managing offline cpus here. | ||
1171 | */ | ||
1172 | cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); | ||
1173 | |||
1174 | if (!frozen) { | ||
1175 | policy->user_policy.min = policy->min; | ||
1176 | policy->user_policy.max = policy->max; | ||
1177 | } | ||
1178 | |||
1179 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, | 1180 | blocking_notifier_call_chain(&cpufreq_policy_notifier_list, |
1180 | CPUFREQ_START, policy); | 1181 | CPUFREQ_START, policy); |
1181 | 1182 | ||
@@ -1206,6 +1207,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
1206 | policy->user_policy.policy = policy->policy; | 1207 | policy->user_policy.policy = policy->policy; |
1207 | policy->user_policy.governor = policy->governor; | 1208 | policy->user_policy.governor = policy->governor; |
1208 | } | 1209 | } |
1210 | up_write(&policy->rwsem); | ||
1209 | 1211 | ||
1210 | kobject_uevent(&policy->kobj, KOBJ_ADD); | 1212 | kobject_uevent(&policy->kobj, KOBJ_ADD); |
1211 | up_read(&cpufreq_rwsem); | 1213 | up_read(&cpufreq_rwsem); |
@@ -1323,8 +1325,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, | |||
1323 | up_read(&policy->rwsem); | 1325 | up_read(&policy->rwsem); |
1324 | 1326 | ||
1325 | if (cpu != policy->cpu) { | 1327 | if (cpu != policy->cpu) { |
1326 | if (!frozen) | 1328 | sysfs_remove_link(&dev->kobj, "cpufreq"); |
1327 | sysfs_remove_link(&dev->kobj, "cpufreq"); | ||
1328 | } else if (cpus > 1) { | 1329 | } else if (cpus > 1) { |
1329 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); | 1330 | new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); |
1330 | if (new_cpu >= 0) { | 1331 | if (new_cpu >= 0) { |
@@ -1547,23 +1548,16 @@ static unsigned int __cpufreq_get(unsigned int cpu) | |||
1547 | */ | 1548 | */ |
1548 | unsigned int cpufreq_get(unsigned int cpu) | 1549 | unsigned int cpufreq_get(unsigned int cpu) |
1549 | { | 1550 | { |
1550 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | 1551 | struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); |
1551 | unsigned int ret_freq = 0; | 1552 | unsigned int ret_freq = 0; |
1552 | 1553 | ||
1553 | if (cpufreq_disabled() || !cpufreq_driver) | 1554 | if (policy) { |
1554 | return -ENOENT; | 1555 | down_read(&policy->rwsem); |
1555 | 1556 | ret_freq = __cpufreq_get(cpu); | |
1556 | BUG_ON(!policy); | 1557 | up_read(&policy->rwsem); |
1557 | |||
1558 | if (!down_read_trylock(&cpufreq_rwsem)) | ||
1559 | return 0; | ||
1560 | |||
1561 | down_read(&policy->rwsem); | ||
1562 | |||
1563 | ret_freq = __cpufreq_get(cpu); | ||
1564 | 1558 | ||
1565 | up_read(&policy->rwsem); | 1559 | cpufreq_cpu_put(policy); |
1566 | up_read(&cpufreq_rwsem); | 1560 | } |
1567 | 1561 | ||
1568 | return ret_freq; | 1562 | return ret_freq; |
1569 | } | 1563 | } |
@@ -2149,7 +2143,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
2149 | * BIOS might change freq behind our back | 2143 | * BIOS might change freq behind our back |
2150 | * -> ask driver for current freq and notify governors about a change | 2144 | * -> ask driver for current freq and notify governors about a change |
2151 | */ | 2145 | */ |
2152 | if (cpufreq_driver->get) { | 2146 | if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { |
2153 | new_policy.cur = cpufreq_driver->get(cpu); | 2147 | new_policy.cur = cpufreq_driver->get(cpu); |
2154 | if (!policy->cur) { | 2148 | if (!policy->cur) { |
2155 | pr_debug("Driver did not initialize current freq"); | 2149 | pr_debug("Driver did not initialize current freq"); |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7e257b233602..2cd36b9297f3 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -34,12 +34,15 @@ | |||
34 | 34 | ||
35 | #define SAMPLE_COUNT 3 | 35 | #define SAMPLE_COUNT 3 |
36 | 36 | ||
37 | #define BYT_RATIOS 0x66a | 37 | #define BYT_RATIOS 0x66a |
38 | #define BYT_VIDS 0x66b | 38 | #define BYT_VIDS 0x66b |
39 | #define BYT_TURBO_RATIOS 0x66c | ||
39 | 40 | ||
40 | #define FRAC_BITS 8 | 41 | |
42 | #define FRAC_BITS 6 | ||
41 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) | 43 | #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) |
42 | #define fp_toint(X) ((X) >> FRAC_BITS) | 44 | #define fp_toint(X) ((X) >> FRAC_BITS) |
45 | #define FP_ROUNDUP(X) ((X) += 1 << FRAC_BITS) | ||
43 | 46 | ||
44 | static inline int32_t mul_fp(int32_t x, int32_t y) | 47 | static inline int32_t mul_fp(int32_t x, int32_t y) |
45 | { | 48 | { |
@@ -51,12 +54,11 @@ static inline int32_t div_fp(int32_t x, int32_t y) | |||
51 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); | 54 | return div_s64((int64_t)x << FRAC_BITS, (int64_t)y); |
52 | } | 55 | } |
53 | 56 | ||
54 | static u64 energy_divisor; | ||
55 | |||
56 | struct sample { | 57 | struct sample { |
57 | int32_t core_pct_busy; | 58 | int32_t core_pct_busy; |
58 | u64 aperf; | 59 | u64 aperf; |
59 | u64 mperf; | 60 | u64 mperf; |
61 | unsigned long long tsc; | ||
60 | int freq; | 62 | int freq; |
61 | }; | 63 | }; |
62 | 64 | ||
@@ -96,6 +98,7 @@ struct cpudata { | |||
96 | 98 | ||
97 | u64 prev_aperf; | 99 | u64 prev_aperf; |
98 | u64 prev_mperf; | 100 | u64 prev_mperf; |
101 | unsigned long long prev_tsc; | ||
99 | int sample_ptr; | 102 | int sample_ptr; |
100 | struct sample samples[SAMPLE_COUNT]; | 103 | struct sample samples[SAMPLE_COUNT]; |
101 | }; | 104 | }; |
@@ -357,7 +360,7 @@ static int byt_get_min_pstate(void) | |||
357 | { | 360 | { |
358 | u64 value; | 361 | u64 value; |
359 | rdmsrl(BYT_RATIOS, value); | 362 | rdmsrl(BYT_RATIOS, value); |
360 | return value & 0xFF; | 363 | return (value >> 8) & 0xFF; |
361 | } | 364 | } |
362 | 365 | ||
363 | static int byt_get_max_pstate(void) | 366 | static int byt_get_max_pstate(void) |
@@ -367,6 +370,13 @@ static int byt_get_max_pstate(void) | |||
367 | return (value >> 16) & 0xFF; | 370 | return (value >> 16) & 0xFF; |
368 | } | 371 | } |
369 | 372 | ||
373 | static int byt_get_turbo_pstate(void) | ||
374 | { | ||
375 | u64 value; | ||
376 | rdmsrl(BYT_TURBO_RATIOS, value); | ||
377 | return value & 0x3F; | ||
378 | } | ||
379 | |||
370 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) | 380 | static void byt_set_pstate(struct cpudata *cpudata, int pstate) |
371 | { | 381 | { |
372 | u64 val; | 382 | u64 val; |
@@ -469,7 +479,7 @@ static struct cpu_defaults byt_params = { | |||
469 | .funcs = { | 479 | .funcs = { |
470 | .get_max = byt_get_max_pstate, | 480 | .get_max = byt_get_max_pstate, |
471 | .get_min = byt_get_min_pstate, | 481 | .get_min = byt_get_min_pstate, |
472 | .get_turbo = byt_get_max_pstate, | 482 | .get_turbo = byt_get_turbo_pstate, |
473 | .set = byt_set_pstate, | 483 | .set = byt_set_pstate, |
474 | .get_vid = byt_get_vid, | 484 | .get_vid = byt_get_vid, |
475 | }, | 485 | }, |
@@ -547,31 +557,48 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) | |||
547 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, | 557 | static inline void intel_pstate_calc_busy(struct cpudata *cpu, |
548 | struct sample *sample) | 558 | struct sample *sample) |
549 | { | 559 | { |
550 | u64 core_pct; | 560 | int32_t core_pct; |
551 | core_pct = div64_u64(int_tofp(sample->aperf * 100), | 561 | int32_t c0_pct; |
552 | sample->mperf); | 562 | |
553 | sample->freq = fp_toint(cpu->pstate.max_pstate * core_pct * 1000); | 563 | core_pct = div_fp(int_tofp((sample->aperf)), |
564 | int_tofp((sample->mperf))); | ||
565 | core_pct = mul_fp(core_pct, int_tofp(100)); | ||
566 | FP_ROUNDUP(core_pct); | ||
567 | |||
568 | c0_pct = div_fp(int_tofp(sample->mperf), int_tofp(sample->tsc)); | ||
554 | 569 | ||
555 | sample->core_pct_busy = core_pct; | 570 | sample->freq = fp_toint( |
571 | mul_fp(int_tofp(cpu->pstate.max_pstate * 1000), core_pct)); | ||
572 | |||
573 | sample->core_pct_busy = mul_fp(core_pct, c0_pct); | ||
556 | } | 574 | } |
557 | 575 | ||
558 | static inline void intel_pstate_sample(struct cpudata *cpu) | 576 | static inline void intel_pstate_sample(struct cpudata *cpu) |
559 | { | 577 | { |
560 | u64 aperf, mperf; | 578 | u64 aperf, mperf; |
579 | unsigned long long tsc; | ||
561 | 580 | ||
562 | rdmsrl(MSR_IA32_APERF, aperf); | 581 | rdmsrl(MSR_IA32_APERF, aperf); |
563 | rdmsrl(MSR_IA32_MPERF, mperf); | 582 | rdmsrl(MSR_IA32_MPERF, mperf); |
583 | tsc = native_read_tsc(); | ||
584 | |||
585 | aperf = aperf >> FRAC_BITS; | ||
586 | mperf = mperf >> FRAC_BITS; | ||
587 | tsc = tsc >> FRAC_BITS; | ||
564 | 588 | ||
565 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; | 589 | cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; |
566 | cpu->samples[cpu->sample_ptr].aperf = aperf; | 590 | cpu->samples[cpu->sample_ptr].aperf = aperf; |
567 | cpu->samples[cpu->sample_ptr].mperf = mperf; | 591 | cpu->samples[cpu->sample_ptr].mperf = mperf; |
592 | cpu->samples[cpu->sample_ptr].tsc = tsc; | ||
568 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; | 593 | cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; |
569 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; | 594 | cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; |
595 | cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; | ||
570 | 596 | ||
571 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); | 597 | intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); |
572 | 598 | ||
573 | cpu->prev_aperf = aperf; | 599 | cpu->prev_aperf = aperf; |
574 | cpu->prev_mperf = mperf; | 600 | cpu->prev_mperf = mperf; |
601 | cpu->prev_tsc = tsc; | ||
575 | } | 602 | } |
576 | 603 | ||
577 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) | 604 | static inline void intel_pstate_set_sample_time(struct cpudata *cpu) |
@@ -590,7 +617,8 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) | |||
590 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; | 617 | core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; |
591 | max_pstate = int_tofp(cpu->pstate.max_pstate); | 618 | max_pstate = int_tofp(cpu->pstate.max_pstate); |
592 | current_pstate = int_tofp(cpu->pstate.current_pstate); | 619 | current_pstate = int_tofp(cpu->pstate.current_pstate); |
593 | return mul_fp(core_busy, div_fp(max_pstate, current_pstate)); | 620 | core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); |
621 | return FP_ROUNDUP(core_busy); | ||
594 | } | 622 | } |
595 | 623 | ||
596 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) | 624 | static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) |
@@ -617,12 +645,10 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
617 | { | 645 | { |
618 | struct cpudata *cpu = (struct cpudata *) __data; | 646 | struct cpudata *cpu = (struct cpudata *) __data; |
619 | struct sample *sample; | 647 | struct sample *sample; |
620 | u64 energy; | ||
621 | 648 | ||
622 | intel_pstate_sample(cpu); | 649 | intel_pstate_sample(cpu); |
623 | 650 | ||
624 | sample = &cpu->samples[cpu->sample_ptr]; | 651 | sample = &cpu->samples[cpu->sample_ptr]; |
625 | rdmsrl(MSR_PKG_ENERGY_STATUS, energy); | ||
626 | 652 | ||
627 | intel_pstate_adjust_busy_pstate(cpu); | 653 | intel_pstate_adjust_busy_pstate(cpu); |
628 | 654 | ||
@@ -631,7 +657,6 @@ static void intel_pstate_timer_func(unsigned long __data) | |||
631 | cpu->pstate.current_pstate, | 657 | cpu->pstate.current_pstate, |
632 | sample->mperf, | 658 | sample->mperf, |
633 | sample->aperf, | 659 | sample->aperf, |
634 | div64_u64(energy, energy_divisor), | ||
635 | sample->freq); | 660 | sample->freq); |
636 | 661 | ||
637 | intel_pstate_set_sample_time(cpu); | 662 | intel_pstate_set_sample_time(cpu); |
@@ -913,7 +938,6 @@ static int __init intel_pstate_init(void) | |||
913 | int cpu, rc = 0; | 938 | int cpu, rc = 0; |
914 | const struct x86_cpu_id *id; | 939 | const struct x86_cpu_id *id; |
915 | struct cpu_defaults *cpu_info; | 940 | struct cpu_defaults *cpu_info; |
916 | u64 units; | ||
917 | 941 | ||
918 | if (no_load) | 942 | if (no_load) |
919 | return -ENODEV; | 943 | return -ENODEV; |
@@ -947,9 +971,6 @@ static int __init intel_pstate_init(void) | |||
947 | if (rc) | 971 | if (rc) |
948 | goto out; | 972 | goto out; |
949 | 973 | ||
950 | rdmsrl(MSR_RAPL_POWER_UNIT, units); | ||
951 | energy_divisor = 1 << ((units >> 8) & 0x1f); /* bits{12:8} */ | ||
952 | |||
953 | intel_pstate_debug_expose_params(); | 974 | intel_pstate_debug_expose_params(); |
954 | intel_pstate_sysfs_expose_params(); | 975 | intel_pstate_sysfs_expose_params(); |
955 | 976 | ||
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index e10b646634d7..6684e0342792 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -1076,7 +1076,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1076 | { | 1076 | { |
1077 | struct powernow_k8_data *data; | 1077 | struct powernow_k8_data *data; |
1078 | struct init_on_cpu init_on_cpu; | 1078 | struct init_on_cpu init_on_cpu; |
1079 | int rc; | 1079 | int rc, cpu; |
1080 | 1080 | ||
1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); | 1081 | smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1); |
1082 | if (rc) | 1082 | if (rc) |
@@ -1140,7 +1140,9 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1140 | pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1141 | data->currfid, data->currvid); | 1141 | data->currfid, data->currvid); |
1142 | 1142 | ||
1143 | per_cpu(powernow_data, pol->cpu) = data; | 1143 | /* Point all the CPUs in this policy to the same data */ |
1144 | for_each_cpu(cpu, pol->cpus) | ||
1145 | per_cpu(powernow_data, cpu) = data; | ||
1144 | 1146 | ||
1145 | return 0; | 1147 | return 0; |
1146 | 1148 | ||
@@ -1155,6 +1157,7 @@ err_out: | |||
1155 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | 1157 | static int powernowk8_cpu_exit(struct cpufreq_policy *pol) |
1156 | { | 1158 | { |
1157 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1159 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1160 | int cpu; | ||
1158 | 1161 | ||
1159 | if (!data) | 1162 | if (!data) |
1160 | return -EINVAL; | 1163 | return -EINVAL; |
@@ -1165,7 +1168,8 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol) | |||
1165 | 1168 | ||
1166 | kfree(data->powernow_table); | 1169 | kfree(data->powernow_table); |
1167 | kfree(data); | 1170 | kfree(data); |
1168 | per_cpu(powernow_data, pol->cpu) = NULL; | 1171 | for_each_cpu(cpu, pol->cpus) |
1172 | per_cpu(powernow_data, cpu) = NULL; | ||
1169 | 1173 | ||
1170 | return 0; | 1174 | return 0; |
1171 | } | 1175 | } |
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index 6c4c000671c5..1e5481d88a26 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c | |||
@@ -158,6 +158,15 @@ static inline unsigned long nx842_get_scatterlist_size( | |||
158 | return sl->entry_nr * sizeof(struct nx842_slentry); | 158 | return sl->entry_nr * sizeof(struct nx842_slentry); |
159 | } | 159 | } |
160 | 160 | ||
161 | static inline unsigned long nx842_get_pa(void *addr) | ||
162 | { | ||
163 | if (is_vmalloc_addr(addr)) | ||
164 | return page_to_phys(vmalloc_to_page(addr)) | ||
165 | + offset_in_page(addr); | ||
166 | else | ||
167 | return __pa(addr); | ||
168 | } | ||
169 | |||
161 | static int nx842_build_scatterlist(unsigned long buf, int len, | 170 | static int nx842_build_scatterlist(unsigned long buf, int len, |
162 | struct nx842_scatterlist *sl) | 171 | struct nx842_scatterlist *sl) |
163 | { | 172 | { |
@@ -168,7 +177,7 @@ static int nx842_build_scatterlist(unsigned long buf, int len, | |||
168 | 177 | ||
169 | entry = sl->entries; | 178 | entry = sl->entries; |
170 | while (len) { | 179 | while (len) { |
171 | entry->ptr = __pa(buf); | 180 | entry->ptr = nx842_get_pa((void *)buf); |
172 | nextpage = ALIGN(buf + 1, NX842_HW_PAGE_SIZE); | 181 | nextpage = ALIGN(buf + 1, NX842_HW_PAGE_SIZE); |
173 | if (nextpage < buf + len) { | 182 | if (nextpage < buf + len) { |
174 | /* we aren't at the end yet */ | 183 | /* we aren't at the end yet */ |
@@ -370,8 +379,8 @@ int nx842_compress(const unsigned char *in, unsigned int inlen, | |||
370 | op.flags = NX842_OP_COMPRESS; | 379 | op.flags = NX842_OP_COMPRESS; |
371 | csbcpb = &workmem->csbcpb; | 380 | csbcpb = &workmem->csbcpb; |
372 | memset(csbcpb, 0, sizeof(*csbcpb)); | 381 | memset(csbcpb, 0, sizeof(*csbcpb)); |
373 | op.csbcpb = __pa(csbcpb); | 382 | op.csbcpb = nx842_get_pa(csbcpb); |
374 | op.out = __pa(slout.entries); | 383 | op.out = nx842_get_pa(slout.entries); |
375 | 384 | ||
376 | for (i = 0; i < hdr->blocks_nr; i++) { | 385 | for (i = 0; i < hdr->blocks_nr; i++) { |
377 | /* | 386 | /* |
@@ -401,13 +410,13 @@ int nx842_compress(const unsigned char *in, unsigned int inlen, | |||
401 | */ | 410 | */ |
402 | if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { | 411 | if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { |
403 | /* Create direct DDE */ | 412 | /* Create direct DDE */ |
404 | op.in = __pa(inbuf); | 413 | op.in = nx842_get_pa((void *)inbuf); |
405 | op.inlen = max_sync_size; | 414 | op.inlen = max_sync_size; |
406 | 415 | ||
407 | } else { | 416 | } else { |
408 | /* Create indirect DDE (scatterlist) */ | 417 | /* Create indirect DDE (scatterlist) */ |
409 | nx842_build_scatterlist(inbuf, max_sync_size, &slin); | 418 | nx842_build_scatterlist(inbuf, max_sync_size, &slin); |
410 | op.in = __pa(slin.entries); | 419 | op.in = nx842_get_pa(slin.entries); |
411 | op.inlen = -nx842_get_scatterlist_size(&slin); | 420 | op.inlen = -nx842_get_scatterlist_size(&slin); |
412 | } | 421 | } |
413 | 422 | ||
@@ -565,7 +574,7 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, | |||
565 | op.flags = NX842_OP_DECOMPRESS; | 574 | op.flags = NX842_OP_DECOMPRESS; |
566 | csbcpb = &workmem->csbcpb; | 575 | csbcpb = &workmem->csbcpb; |
567 | memset(csbcpb, 0, sizeof(*csbcpb)); | 576 | memset(csbcpb, 0, sizeof(*csbcpb)); |
568 | op.csbcpb = __pa(csbcpb); | 577 | op.csbcpb = nx842_get_pa(csbcpb); |
569 | 578 | ||
570 | /* | 579 | /* |
571 | * max_sync_size may have changed since compression, | 580 | * max_sync_size may have changed since compression, |
@@ -597,12 +606,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, | |||
597 | if (likely((inbuf & NX842_HW_PAGE_MASK) == | 606 | if (likely((inbuf & NX842_HW_PAGE_MASK) == |
598 | ((inbuf + hdr->sizes[i] - 1) & NX842_HW_PAGE_MASK))) { | 607 | ((inbuf + hdr->sizes[i] - 1) & NX842_HW_PAGE_MASK))) { |
599 | /* Create direct DDE */ | 608 | /* Create direct DDE */ |
600 | op.in = __pa(inbuf); | 609 | op.in = nx842_get_pa((void *)inbuf); |
601 | op.inlen = hdr->sizes[i]; | 610 | op.inlen = hdr->sizes[i]; |
602 | } else { | 611 | } else { |
603 | /* Create indirect DDE (scatterlist) */ | 612 | /* Create indirect DDE (scatterlist) */ |
604 | nx842_build_scatterlist(inbuf, hdr->sizes[i] , &slin); | 613 | nx842_build_scatterlist(inbuf, hdr->sizes[i] , &slin); |
605 | op.in = __pa(slin.entries); | 614 | op.in = nx842_get_pa(slin.entries); |
606 | op.inlen = -nx842_get_scatterlist_size(&slin); | 615 | op.inlen = -nx842_get_scatterlist_size(&slin); |
607 | } | 616 | } |
608 | 617 | ||
@@ -613,12 +622,12 @@ int nx842_decompress(const unsigned char *in, unsigned int inlen, | |||
613 | */ | 622 | */ |
614 | if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { | 623 | if (likely(max_sync_size == NX842_HW_PAGE_SIZE)) { |
615 | /* Create direct DDE */ | 624 | /* Create direct DDE */ |
616 | op.out = __pa(outbuf); | 625 | op.out = nx842_get_pa((void *)outbuf); |
617 | op.outlen = max_sync_size; | 626 | op.outlen = max_sync_size; |
618 | } else { | 627 | } else { |
619 | /* Create indirect DDE (scatterlist) */ | 628 | /* Create indirect DDE (scatterlist) */ |
620 | nx842_build_scatterlist(outbuf, max_sync_size, &slout); | 629 | nx842_build_scatterlist(outbuf, max_sync_size, &slout); |
621 | op.out = __pa(slout.entries); | 630 | op.out = nx842_get_pa(slout.entries); |
622 | op.outlen = -nx842_get_scatterlist_size(&slout); | 631 | op.outlen = -nx842_get_scatterlist_size(&slout); |
623 | } | 632 | } |
624 | 633 | ||
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 9bed1a2a67a1..605b016bcea4 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -346,6 +346,7 @@ config MOXART_DMA | |||
346 | tristate "MOXART DMA support" | 346 | tristate "MOXART DMA support" |
347 | depends on ARCH_MOXART | 347 | depends on ARCH_MOXART |
348 | select DMA_ENGINE | 348 | select DMA_ENGINE |
349 | select DMA_OF | ||
349 | select DMA_VIRTUAL_CHANNELS | 350 | select DMA_VIRTUAL_CHANNELS |
350 | help | 351 | help |
351 | Enable support for the MOXA ART SoC DMA controller. | 352 | Enable support for the MOXA ART SoC DMA controller. |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 4e7918339b12..19041cefabb1 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -449,6 +449,7 @@ static const struct of_device_id sdma_dt_ids[] = { | |||
449 | { .compatible = "fsl,imx51-sdma", .data = &sdma_imx51, }, | 449 | { .compatible = "fsl,imx51-sdma", .data = &sdma_imx51, }, |
450 | { .compatible = "fsl,imx35-sdma", .data = &sdma_imx35, }, | 450 | { .compatible = "fsl,imx35-sdma", .data = &sdma_imx35, }, |
451 | { .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, }, | 451 | { .compatible = "fsl,imx31-sdma", .data = &sdma_imx31, }, |
452 | { .compatible = "fsl,imx25-sdma", .data = &sdma_imx25, }, | ||
452 | { /* sentinel */ } | 453 | { /* sentinel */ } |
453 | }; | 454 | }; |
454 | MODULE_DEVICE_TABLE(of, sdma_dt_ids); | 455 | MODULE_DEVICE_TABLE(of, sdma_dt_ids); |
diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 87529181efcc..4e3549a16132 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c | |||
@@ -77,7 +77,8 @@ static irqreturn_t ioat_dma_do_interrupt(int irq, void *data) | |||
77 | attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET); | 77 | attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET); |
78 | for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) { | 78 | for_each_set_bit(bit, &attnstatus, BITS_PER_LONG) { |
79 | chan = ioat_chan_by_index(instance, bit); | 79 | chan = ioat_chan_by_index(instance, bit); |
80 | tasklet_schedule(&chan->cleanup_task); | 80 | if (test_bit(IOAT_RUN, &chan->state)) |
81 | tasklet_schedule(&chan->cleanup_task); | ||
81 | } | 82 | } |
82 | 83 | ||
83 | writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET); | 84 | writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET); |
@@ -93,7 +94,8 @@ static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data) | |||
93 | { | 94 | { |
94 | struct ioat_chan_common *chan = data; | 95 | struct ioat_chan_common *chan = data; |
95 | 96 | ||
96 | tasklet_schedule(&chan->cleanup_task); | 97 | if (test_bit(IOAT_RUN, &chan->state)) |
98 | tasklet_schedule(&chan->cleanup_task); | ||
97 | 99 | ||
98 | return IRQ_HANDLED; | 100 | return IRQ_HANDLED; |
99 | } | 101 | } |
@@ -116,7 +118,6 @@ void ioat_init_channel(struct ioatdma_device *device, struct ioat_chan_common *c | |||
116 | chan->timer.function = device->timer_fn; | 118 | chan->timer.function = device->timer_fn; |
117 | chan->timer.data = data; | 119 | chan->timer.data = data; |
118 | tasklet_init(&chan->cleanup_task, device->cleanup_fn, data); | 120 | tasklet_init(&chan->cleanup_task, device->cleanup_fn, data); |
119 | tasklet_disable(&chan->cleanup_task); | ||
120 | } | 121 | } |
121 | 122 | ||
122 | /** | 123 | /** |
@@ -354,13 +355,49 @@ static int ioat1_dma_alloc_chan_resources(struct dma_chan *c) | |||
354 | writel(((u64) chan->completion_dma) >> 32, | 355 | writel(((u64) chan->completion_dma) >> 32, |
355 | chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); | 356 | chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); |
356 | 357 | ||
357 | tasklet_enable(&chan->cleanup_task); | 358 | set_bit(IOAT_RUN, &chan->state); |
358 | ioat1_dma_start_null_desc(ioat); /* give chain to dma device */ | 359 | ioat1_dma_start_null_desc(ioat); /* give chain to dma device */ |
359 | dev_dbg(to_dev(chan), "%s: allocated %d descriptors\n", | 360 | dev_dbg(to_dev(chan), "%s: allocated %d descriptors\n", |
360 | __func__, ioat->desccount); | 361 | __func__, ioat->desccount); |
361 | return ioat->desccount; | 362 | return ioat->desccount; |
362 | } | 363 | } |
363 | 364 | ||
365 | void ioat_stop(struct ioat_chan_common *chan) | ||
366 | { | ||
367 | struct ioatdma_device *device = chan->device; | ||
368 | struct pci_dev *pdev = device->pdev; | ||
369 | int chan_id = chan_num(chan); | ||
370 | struct msix_entry *msix; | ||
371 | |||
372 | /* 1/ stop irq from firing tasklets | ||
373 | * 2/ stop the tasklet from re-arming irqs | ||
374 | */ | ||
375 | clear_bit(IOAT_RUN, &chan->state); | ||
376 | |||
377 | /* flush inflight interrupts */ | ||
378 | switch (device->irq_mode) { | ||
379 | case IOAT_MSIX: | ||
380 | msix = &device->msix_entries[chan_id]; | ||
381 | synchronize_irq(msix->vector); | ||
382 | break; | ||
383 | case IOAT_MSI: | ||
384 | case IOAT_INTX: | ||
385 | synchronize_irq(pdev->irq); | ||
386 | break; | ||
387 | default: | ||
388 | break; | ||
389 | } | ||
390 | |||
391 | /* flush inflight timers */ | ||
392 | del_timer_sync(&chan->timer); | ||
393 | |||
394 | /* flush inflight tasklet runs */ | ||
395 | tasklet_kill(&chan->cleanup_task); | ||
396 | |||
397 | /* final cleanup now that everything is quiesced and can't re-arm */ | ||
398 | device->cleanup_fn((unsigned long) &chan->common); | ||
399 | } | ||
400 | |||
364 | /** | 401 | /** |
365 | * ioat1_dma_free_chan_resources - release all the descriptors | 402 | * ioat1_dma_free_chan_resources - release all the descriptors |
366 | * @chan: the channel to be cleaned | 403 | * @chan: the channel to be cleaned |
@@ -379,9 +416,7 @@ static void ioat1_dma_free_chan_resources(struct dma_chan *c) | |||
379 | if (ioat->desccount == 0) | 416 | if (ioat->desccount == 0) |
380 | return; | 417 | return; |
381 | 418 | ||
382 | tasklet_disable(&chan->cleanup_task); | 419 | ioat_stop(chan); |
383 | del_timer_sync(&chan->timer); | ||
384 | ioat1_cleanup(ioat); | ||
385 | 420 | ||
386 | /* Delay 100ms after reset to allow internal DMA logic to quiesce | 421 | /* Delay 100ms after reset to allow internal DMA logic to quiesce |
387 | * before removing DMA descriptor resources. | 422 | * before removing DMA descriptor resources. |
@@ -526,8 +561,11 @@ ioat1_dma_prep_memcpy(struct dma_chan *c, dma_addr_t dma_dest, | |||
526 | static void ioat1_cleanup_event(unsigned long data) | 561 | static void ioat1_cleanup_event(unsigned long data) |
527 | { | 562 | { |
528 | struct ioat_dma_chan *ioat = to_ioat_chan((void *) data); | 563 | struct ioat_dma_chan *ioat = to_ioat_chan((void *) data); |
564 | struct ioat_chan_common *chan = &ioat->base; | ||
529 | 565 | ||
530 | ioat1_cleanup(ioat); | 566 | ioat1_cleanup(ioat); |
567 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
568 | return; | ||
531 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 569 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
532 | } | 570 | } |
533 | 571 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index 11fb877ddca9..e982f00a9843 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -356,6 +356,7 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan, | |||
356 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); | 356 | void ioat_kobject_add(struct ioatdma_device *device, struct kobj_type *type); |
357 | void ioat_kobject_del(struct ioatdma_device *device); | 357 | void ioat_kobject_del(struct ioatdma_device *device); |
358 | int ioat_dma_setup_interrupts(struct ioatdma_device *device); | 358 | int ioat_dma_setup_interrupts(struct ioatdma_device *device); |
359 | void ioat_stop(struct ioat_chan_common *chan); | ||
359 | extern const struct sysfs_ops ioat_sysfs_ops; | 360 | extern const struct sysfs_ops ioat_sysfs_ops; |
360 | extern struct ioat_sysfs_entry ioat_version_attr; | 361 | extern struct ioat_sysfs_entry ioat_version_attr; |
361 | extern struct ioat_sysfs_entry ioat_cap_attr; | 362 | extern struct ioat_sysfs_entry ioat_cap_attr; |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 5d3affe7e976..8d1058085eeb 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -190,8 +190,11 @@ static void ioat2_cleanup(struct ioat2_dma_chan *ioat) | |||
190 | void ioat2_cleanup_event(unsigned long data) | 190 | void ioat2_cleanup_event(unsigned long data) |
191 | { | 191 | { |
192 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); | 192 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); |
193 | struct ioat_chan_common *chan = &ioat->base; | ||
193 | 194 | ||
194 | ioat2_cleanup(ioat); | 195 | ioat2_cleanup(ioat); |
196 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
197 | return; | ||
195 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 198 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
196 | } | 199 | } |
197 | 200 | ||
@@ -553,10 +556,10 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
553 | ioat->issued = 0; | 556 | ioat->issued = 0; |
554 | ioat->tail = 0; | 557 | ioat->tail = 0; |
555 | ioat->alloc_order = order; | 558 | ioat->alloc_order = order; |
559 | set_bit(IOAT_RUN, &chan->state); | ||
556 | spin_unlock_bh(&ioat->prep_lock); | 560 | spin_unlock_bh(&ioat->prep_lock); |
557 | spin_unlock_bh(&chan->cleanup_lock); | 561 | spin_unlock_bh(&chan->cleanup_lock); |
558 | 562 | ||
559 | tasklet_enable(&chan->cleanup_task); | ||
560 | ioat2_start_null_desc(ioat); | 563 | ioat2_start_null_desc(ioat); |
561 | 564 | ||
562 | /* check that we got off the ground */ | 565 | /* check that we got off the ground */ |
@@ -566,7 +569,6 @@ int ioat2_alloc_chan_resources(struct dma_chan *c) | |||
566 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); | 569 | } while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status)); |
567 | 570 | ||
568 | if (is_ioat_active(status) || is_ioat_idle(status)) { | 571 | if (is_ioat_active(status) || is_ioat_idle(status)) { |
569 | set_bit(IOAT_RUN, &chan->state); | ||
570 | return 1 << ioat->alloc_order; | 572 | return 1 << ioat->alloc_order; |
571 | } else { | 573 | } else { |
572 | u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 574 | u32 chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
@@ -809,11 +811,8 @@ void ioat2_free_chan_resources(struct dma_chan *c) | |||
809 | if (!ioat->ring) | 811 | if (!ioat->ring) |
810 | return; | 812 | return; |
811 | 813 | ||
812 | tasklet_disable(&chan->cleanup_task); | 814 | ioat_stop(chan); |
813 | del_timer_sync(&chan->timer); | ||
814 | device->cleanup_fn((unsigned long) c); | ||
815 | device->reset_hw(chan); | 815 | device->reset_hw(chan); |
816 | clear_bit(IOAT_RUN, &chan->state); | ||
817 | 816 | ||
818 | spin_lock_bh(&chan->cleanup_lock); | 817 | spin_lock_bh(&chan->cleanup_lock); |
819 | spin_lock_bh(&ioat->prep_lock); | 818 | spin_lock_bh(&ioat->prep_lock); |
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 820817e97e62..b9b38a1cf92f 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -464,8 +464,11 @@ static void ioat3_cleanup(struct ioat2_dma_chan *ioat) | |||
464 | static void ioat3_cleanup_event(unsigned long data) | 464 | static void ioat3_cleanup_event(unsigned long data) |
465 | { | 465 | { |
466 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); | 466 | struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data); |
467 | struct ioat_chan_common *chan = &ioat->base; | ||
467 | 468 | ||
468 | ioat3_cleanup(ioat); | 469 | ioat3_cleanup(ioat); |
470 | if (!test_bit(IOAT_RUN, &chan->state)) | ||
471 | return; | ||
469 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); | 472 | writew(IOAT_CHANCTRL_RUN, ioat->base.reg_base + IOAT_CHANCTRL_OFFSET); |
470 | } | 473 | } |
471 | 474 | ||
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 53fb0c8365b0..766b68ed505c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -497,8 +497,8 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) | |||
497 | if (!mv_can_chain(grp_start)) | 497 | if (!mv_can_chain(grp_start)) |
498 | goto submit_done; | 498 | goto submit_done; |
499 | 499 | ||
500 | dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %x\n", | 500 | dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %pa\n", |
501 | old_chain_tail->async_tx.phys); | 501 | &old_chain_tail->async_tx.phys); |
502 | 502 | ||
503 | /* fix up the hardware chain */ | 503 | /* fix up the hardware chain */ |
504 | mv_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys); | 504 | mv_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys); |
@@ -527,7 +527,8 @@ submit_done: | |||
527 | /* returns the number of allocated descriptors */ | 527 | /* returns the number of allocated descriptors */ |
528 | static int mv_xor_alloc_chan_resources(struct dma_chan *chan) | 528 | static int mv_xor_alloc_chan_resources(struct dma_chan *chan) |
529 | { | 529 | { |
530 | char *hw_desc; | 530 | void *virt_desc; |
531 | dma_addr_t dma_desc; | ||
531 | int idx; | 532 | int idx; |
532 | struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); | 533 | struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); |
533 | struct mv_xor_desc_slot *slot = NULL; | 534 | struct mv_xor_desc_slot *slot = NULL; |
@@ -542,17 +543,16 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) | |||
542 | " %d descriptor slots", idx); | 543 | " %d descriptor slots", idx); |
543 | break; | 544 | break; |
544 | } | 545 | } |
545 | hw_desc = (char *) mv_chan->dma_desc_pool_virt; | 546 | virt_desc = mv_chan->dma_desc_pool_virt; |
546 | slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE]; | 547 | slot->hw_desc = virt_desc + idx * MV_XOR_SLOT_SIZE; |
547 | 548 | ||
548 | dma_async_tx_descriptor_init(&slot->async_tx, chan); | 549 | dma_async_tx_descriptor_init(&slot->async_tx, chan); |
549 | slot->async_tx.tx_submit = mv_xor_tx_submit; | 550 | slot->async_tx.tx_submit = mv_xor_tx_submit; |
550 | INIT_LIST_HEAD(&slot->chain_node); | 551 | INIT_LIST_HEAD(&slot->chain_node); |
551 | INIT_LIST_HEAD(&slot->slot_node); | 552 | INIT_LIST_HEAD(&slot->slot_node); |
552 | INIT_LIST_HEAD(&slot->tx_list); | 553 | INIT_LIST_HEAD(&slot->tx_list); |
553 | hw_desc = (char *) mv_chan->dma_desc_pool; | 554 | dma_desc = mv_chan->dma_desc_pool; |
554 | slot->async_tx.phys = | 555 | slot->async_tx.phys = dma_desc + idx * MV_XOR_SLOT_SIZE; |
555 | (dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE]; | ||
556 | slot->idx = idx++; | 556 | slot->idx = idx++; |
557 | 557 | ||
558 | spin_lock_bh(&mv_chan->lock); | 558 | spin_lock_bh(&mv_chan->lock); |
@@ -582,8 +582,8 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | |||
582 | int slot_cnt; | 582 | int slot_cnt; |
583 | 583 | ||
584 | dev_dbg(mv_chan_to_devp(mv_chan), | 584 | dev_dbg(mv_chan_to_devp(mv_chan), |
585 | "%s dest: %x src %x len: %u flags: %ld\n", | 585 | "%s dest: %pad src %pad len: %u flags: %ld\n", |
586 | __func__, dest, src, len, flags); | 586 | __func__, &dest, &src, len, flags); |
587 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) | 587 | if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) |
588 | return NULL; | 588 | return NULL; |
589 | 589 | ||
@@ -626,8 +626,8 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, | |||
626 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); | 626 | BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); |
627 | 627 | ||
628 | dev_dbg(mv_chan_to_devp(mv_chan), | 628 | dev_dbg(mv_chan_to_devp(mv_chan), |
629 | "%s src_cnt: %d len: dest %x %u flags: %ld\n", | 629 | "%s src_cnt: %d len: %u dest %pad flags: %ld\n", |
630 | __func__, src_cnt, len, dest, flags); | 630 | __func__, src_cnt, len, &dest, flags); |
631 | 631 | ||
632 | spin_lock_bh(&mv_chan->lock); | 632 | spin_lock_bh(&mv_chan->lock); |
633 | slot_cnt = mv_chan_xor_slot_count(len, src_cnt); | 633 | slot_cnt = mv_chan_xor_slot_count(len, src_cnt); |
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 00a2de957b23..bf18c786ed40 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c | |||
@@ -1641,6 +1641,7 @@ static void dma_tasklet(unsigned long data) | |||
1641 | struct d40_chan *d40c = (struct d40_chan *) data; | 1641 | struct d40_chan *d40c = (struct d40_chan *) data; |
1642 | struct d40_desc *d40d; | 1642 | struct d40_desc *d40d; |
1643 | unsigned long flags; | 1643 | unsigned long flags; |
1644 | bool callback_active; | ||
1644 | dma_async_tx_callback callback; | 1645 | dma_async_tx_callback callback; |
1645 | void *callback_param; | 1646 | void *callback_param; |
1646 | 1647 | ||
@@ -1668,6 +1669,7 @@ static void dma_tasklet(unsigned long data) | |||
1668 | } | 1669 | } |
1669 | 1670 | ||
1670 | /* Callback to client */ | 1671 | /* Callback to client */ |
1672 | callback_active = !!(d40d->txd.flags & DMA_PREP_INTERRUPT); | ||
1671 | callback = d40d->txd.callback; | 1673 | callback = d40d->txd.callback; |
1672 | callback_param = d40d->txd.callback_param; | 1674 | callback_param = d40d->txd.callback_param; |
1673 | 1675 | ||
@@ -1690,7 +1692,7 @@ static void dma_tasklet(unsigned long data) | |||
1690 | 1692 | ||
1691 | spin_unlock_irqrestore(&d40c->lock, flags); | 1693 | spin_unlock_irqrestore(&d40c->lock, flags); |
1692 | 1694 | ||
1693 | if (callback && (d40d->txd.flags & DMA_PREP_INTERRUPT)) | 1695 | if (callback_active && callback) |
1694 | callback(callback_param); | 1696 | callback(callback_param); |
1695 | 1697 | ||
1696 | return; | 1698 | return; |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index e8c9ef03495b..33edd6766344 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -559,7 +559,8 @@ static void edac_mc_workq_function(struct work_struct *work_req) | |||
559 | * | 559 | * |
560 | * called with the mem_ctls_mutex held | 560 | * called with the mem_ctls_mutex held |
561 | */ | 561 | */ |
562 | static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec) | 562 | static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec, |
563 | bool init) | ||
563 | { | 564 | { |
564 | edac_dbg(0, "\n"); | 565 | edac_dbg(0, "\n"); |
565 | 566 | ||
@@ -567,7 +568,9 @@ static void edac_mc_workq_setup(struct mem_ctl_info *mci, unsigned msec) | |||
567 | if (mci->op_state != OP_RUNNING_POLL) | 568 | if (mci->op_state != OP_RUNNING_POLL) |
568 | return; | 569 | return; |
569 | 570 | ||
570 | INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); | 571 | if (init) |
572 | INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function); | ||
573 | |||
571 | mod_delayed_work(edac_workqueue, &mci->work, msecs_to_jiffies(msec)); | 574 | mod_delayed_work(edac_workqueue, &mci->work, msecs_to_jiffies(msec)); |
572 | } | 575 | } |
573 | 576 | ||
@@ -601,7 +604,7 @@ static void edac_mc_workq_teardown(struct mem_ctl_info *mci) | |||
601 | * user space has updated our poll period value, need to | 604 | * user space has updated our poll period value, need to |
602 | * reset our workq delays | 605 | * reset our workq delays |
603 | */ | 606 | */ |
604 | void edac_mc_reset_delay_period(int value) | 607 | void edac_mc_reset_delay_period(unsigned long value) |
605 | { | 608 | { |
606 | struct mem_ctl_info *mci; | 609 | struct mem_ctl_info *mci; |
607 | struct list_head *item; | 610 | struct list_head *item; |
@@ -611,7 +614,7 @@ void edac_mc_reset_delay_period(int value) | |||
611 | list_for_each(item, &mc_devices) { | 614 | list_for_each(item, &mc_devices) { |
612 | mci = list_entry(item, struct mem_ctl_info, link); | 615 | mci = list_entry(item, struct mem_ctl_info, link); |
613 | 616 | ||
614 | edac_mc_workq_setup(mci, (unsigned long) value); | 617 | edac_mc_workq_setup(mci, value, false); |
615 | } | 618 | } |
616 | 619 | ||
617 | mutex_unlock(&mem_ctls_mutex); | 620 | mutex_unlock(&mem_ctls_mutex); |
@@ -782,7 +785,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci) | |||
782 | /* This instance is NOW RUNNING */ | 785 | /* This instance is NOW RUNNING */ |
783 | mci->op_state = OP_RUNNING_POLL; | 786 | mci->op_state = OP_RUNNING_POLL; |
784 | 787 | ||
785 | edac_mc_workq_setup(mci, edac_mc_get_poll_msec()); | 788 | edac_mc_workq_setup(mci, edac_mc_get_poll_msec(), true); |
786 | } else { | 789 | } else { |
787 | mci->op_state = OP_RUNNING_INTERRUPT; | 790 | mci->op_state = OP_RUNNING_INTERRUPT; |
788 | } | 791 | } |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 51c0362acf5c..b335c6ab5efe 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -52,18 +52,20 @@ int edac_mc_get_poll_msec(void) | |||
52 | 52 | ||
53 | static int edac_set_poll_msec(const char *val, struct kernel_param *kp) | 53 | static int edac_set_poll_msec(const char *val, struct kernel_param *kp) |
54 | { | 54 | { |
55 | long l; | 55 | unsigned long l; |
56 | int ret; | 56 | int ret; |
57 | 57 | ||
58 | if (!val) | 58 | if (!val) |
59 | return -EINVAL; | 59 | return -EINVAL; |
60 | 60 | ||
61 | ret = kstrtol(val, 0, &l); | 61 | ret = kstrtoul(val, 0, &l); |
62 | if (ret) | 62 | if (ret) |
63 | return ret; | 63 | return ret; |
64 | if ((int)l != l) | 64 | |
65 | if (l < 1000) | ||
65 | return -EINVAL; | 66 | return -EINVAL; |
66 | *((int *)kp->arg) = l; | 67 | |
68 | *((unsigned long *)kp->arg) = l; | ||
67 | 69 | ||
68 | /* notify edac_mc engine to reset the poll period */ | 70 | /* notify edac_mc engine to reset the poll period */ |
69 | edac_mc_reset_delay_period(l); | 71 | edac_mc_reset_delay_period(l); |
diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h index 3d139c6e7fe3..f2118bfcf8df 100644 --- a/drivers/edac/edac_module.h +++ b/drivers/edac/edac_module.h | |||
@@ -52,7 +52,7 @@ extern void edac_device_workq_setup(struct edac_device_ctl_info *edac_dev, | |||
52 | extern void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev); | 52 | extern void edac_device_workq_teardown(struct edac_device_ctl_info *edac_dev); |
53 | extern void edac_device_reset_delay_period(struct edac_device_ctl_info | 53 | extern void edac_device_reset_delay_period(struct edac_device_ctl_info |
54 | *edac_dev, unsigned long value); | 54 | *edac_dev, unsigned long value); |
55 | extern void edac_mc_reset_delay_period(int value); | 55 | extern void edac_mc_reset_delay_period(unsigned long value); |
56 | 56 | ||
57 | extern void *edac_align_ptr(void **p, unsigned size, int n_elems); | 57 | extern void *edac_align_ptr(void **p, unsigned size, int n_elems); |
58 | 58 | ||
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index d63f4798f7d0..57e96a3350f0 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
@@ -943,33 +943,35 @@ static int i7300_get_devices(struct mem_ctl_info *mci) | |||
943 | 943 | ||
944 | /* Attempt to 'get' the MCH register we want */ | 944 | /* Attempt to 'get' the MCH register we want */ |
945 | pdev = NULL; | 945 | pdev = NULL; |
946 | while (!pvt->pci_dev_16_1_fsb_addr_map || | 946 | while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
947 | !pvt->pci_dev_16_2_fsb_err_regs) { | 947 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, |
948 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 948 | pdev))) { |
949 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev); | ||
950 | if (!pdev) { | ||
951 | /* End of list, leave */ | ||
952 | i7300_printk(KERN_ERR, | ||
953 | "'system address,Process Bus' " | ||
954 | "device not found:" | ||
955 | "vendor 0x%x device 0x%x ERR funcs " | ||
956 | "(broken BIOS?)\n", | ||
957 | PCI_VENDOR_ID_INTEL, | ||
958 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); | ||
959 | goto error; | ||
960 | } | ||
961 | |||
962 | /* Store device 16 funcs 1 and 2 */ | 949 | /* Store device 16 funcs 1 and 2 */ |
963 | switch (PCI_FUNC(pdev->devfn)) { | 950 | switch (PCI_FUNC(pdev->devfn)) { |
964 | case 1: | 951 | case 1: |
965 | pvt->pci_dev_16_1_fsb_addr_map = pdev; | 952 | if (!pvt->pci_dev_16_1_fsb_addr_map) |
953 | pvt->pci_dev_16_1_fsb_addr_map = | ||
954 | pci_dev_get(pdev); | ||
966 | break; | 955 | break; |
967 | case 2: | 956 | case 2: |
968 | pvt->pci_dev_16_2_fsb_err_regs = pdev; | 957 | if (!pvt->pci_dev_16_2_fsb_err_regs) |
958 | pvt->pci_dev_16_2_fsb_err_regs = | ||
959 | pci_dev_get(pdev); | ||
969 | break; | 960 | break; |
970 | } | 961 | } |
971 | } | 962 | } |
972 | 963 | ||
964 | if (!pvt->pci_dev_16_1_fsb_addr_map || | ||
965 | !pvt->pci_dev_16_2_fsb_err_regs) { | ||
966 | /* At least one device was not found */ | ||
967 | i7300_printk(KERN_ERR, | ||
968 | "'system address,Process Bus' device not found:" | ||
969 | "vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n", | ||
970 | PCI_VENDOR_ID_INTEL, | ||
971 | PCI_DEVICE_ID_INTEL_I7300_MCH_ERR); | ||
972 | goto error; | ||
973 | } | ||
974 | |||
973 | edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", | 975 | edac_dbg(1, "System Address, processor bus- PCI Bus ID: %s %x:%x\n", |
974 | pci_name(pvt->pci_dev_16_0_fsb_ctlr), | 976 | pci_name(pvt->pci_dev_16_0_fsb_ctlr), |
975 | pvt->pci_dev_16_0_fsb_ctlr->vendor, | 977 | pvt->pci_dev_16_0_fsb_ctlr->vendor, |
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 87533ca7752e..d871275196f6 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1334,14 +1334,19 @@ static int i7core_get_onedevice(struct pci_dev **prev, | |||
1334 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need | 1334 | * is at addr 8086:2c40, instead of 8086:2c41. So, we need |
1335 | * to probe for the alternate address in case of failure | 1335 | * to probe for the alternate address in case of failure |
1336 | */ | 1336 | */ |
1337 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) | 1337 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_I7_NONCORE && !pdev) { |
1338 | pci_dev_get(*prev); /* pci_get_device will put it */ | ||
1338 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1339 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1339 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); | 1340 | PCI_DEVICE_ID_INTEL_I7_NONCORE_ALT, *prev); |
1341 | } | ||
1340 | 1342 | ||
1341 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && !pdev) | 1343 | if (dev_descr->dev_id == PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE && |
1344 | !pdev) { | ||
1345 | pci_dev_get(*prev); /* pci_get_device will put it */ | ||
1342 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1346 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1343 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, | 1347 | PCI_DEVICE_ID_INTEL_LYNNFIELD_NONCORE_ALT, |
1344 | *prev); | 1348 | *prev); |
1349 | } | ||
1345 | 1350 | ||
1346 | if (!pdev) { | 1351 | if (!pdev) { |
1347 | if (*prev) { | 1352 | if (*prev) { |
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index c20602f601ee..98a14f6143a7 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -222,27 +222,19 @@ static void arizona_extcon_pulse_micbias(struct arizona_extcon_info *info) | |||
222 | struct snd_soc_dapm_context *dapm = arizona->dapm; | 222 | struct snd_soc_dapm_context *dapm = arizona->dapm; |
223 | int ret; | 223 | int ret; |
224 | 224 | ||
225 | mutex_lock(&dapm->card->dapm_mutex); | ||
226 | |||
227 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); | 225 | ret = snd_soc_dapm_force_enable_pin(dapm, widget); |
228 | if (ret != 0) | 226 | if (ret != 0) |
229 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", | 227 | dev_warn(arizona->dev, "Failed to enable %s: %d\n", |
230 | widget, ret); | 228 | widget, ret); |
231 | 229 | ||
232 | mutex_unlock(&dapm->card->dapm_mutex); | ||
233 | |||
234 | snd_soc_dapm_sync(dapm); | 230 | snd_soc_dapm_sync(dapm); |
235 | 231 | ||
236 | if (!arizona->pdata.micd_force_micbias) { | 232 | if (!arizona->pdata.micd_force_micbias) { |
237 | mutex_lock(&dapm->card->dapm_mutex); | ||
238 | |||
239 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); | 233 | ret = snd_soc_dapm_disable_pin(arizona->dapm, widget); |
240 | if (ret != 0) | 234 | if (ret != 0) |
241 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", | 235 | dev_warn(arizona->dev, "Failed to disable %s: %d\n", |
242 | widget, ret); | 236 | widget, ret); |
243 | 237 | ||
244 | mutex_unlock(&dapm->card->dapm_mutex); | ||
245 | |||
246 | snd_soc_dapm_sync(dapm); | 238 | snd_soc_dapm_sync(dapm); |
247 | } | 239 | } |
248 | } | 240 | } |
@@ -304,16 +296,12 @@ static void arizona_stop_mic(struct arizona_extcon_info *info) | |||
304 | ARIZONA_MICD_ENA, 0, | 296 | ARIZONA_MICD_ENA, 0, |
305 | &change); | 297 | &change); |
306 | 298 | ||
307 | mutex_lock(&dapm->card->dapm_mutex); | ||
308 | |||
309 | ret = snd_soc_dapm_disable_pin(dapm, widget); | 299 | ret = snd_soc_dapm_disable_pin(dapm, widget); |
310 | if (ret != 0) | 300 | if (ret != 0) |
311 | dev_warn(arizona->dev, | 301 | dev_warn(arizona->dev, |
312 | "Failed to disable %s: %d\n", | 302 | "Failed to disable %s: %d\n", |
313 | widget, ret); | 303 | widget, ret); |
314 | 304 | ||
315 | mutex_unlock(&dapm->card->dapm_mutex); | ||
316 | |||
317 | snd_soc_dapm_sync(dapm); | 305 | snd_soc_dapm_sync(dapm); |
318 | 306 | ||
319 | if (info->micd_reva) { | 307 | if (info->micd_reva) { |
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index de4aa409abe2..2c6d5e118ac1 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -916,7 +916,7 @@ static int lookup_existing_device(struct device *dev, void *data) | |||
916 | old->config_rom_retries = 0; | 916 | old->config_rom_retries = 0; |
917 | fw_notice(card, "rediscovered device %s\n", dev_name(dev)); | 917 | fw_notice(card, "rediscovered device %s\n", dev_name(dev)); |
918 | 918 | ||
919 | PREPARE_DELAYED_WORK(&old->work, fw_device_update); | 919 | old->workfn = fw_device_update; |
920 | fw_schedule_device_work(old, 0); | 920 | fw_schedule_device_work(old, 0); |
921 | 921 | ||
922 | if (current_node == card->root_node) | 922 | if (current_node == card->root_node) |
@@ -1075,7 +1075,7 @@ static void fw_device_init(struct work_struct *work) | |||
1075 | if (atomic_cmpxchg(&device->state, | 1075 | if (atomic_cmpxchg(&device->state, |
1076 | FW_DEVICE_INITIALIZING, | 1076 | FW_DEVICE_INITIALIZING, |
1077 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { | 1077 | FW_DEVICE_RUNNING) == FW_DEVICE_GONE) { |
1078 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1078 | device->workfn = fw_device_shutdown; |
1079 | fw_schedule_device_work(device, SHUTDOWN_DELAY); | 1079 | fw_schedule_device_work(device, SHUTDOWN_DELAY); |
1080 | } else { | 1080 | } else { |
1081 | fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", | 1081 | fw_notice(card, "created device %s: GUID %08x%08x, S%d00\n", |
@@ -1196,13 +1196,20 @@ static void fw_device_refresh(struct work_struct *work) | |||
1196 | dev_name(&device->device), fw_rcode_string(ret)); | 1196 | dev_name(&device->device), fw_rcode_string(ret)); |
1197 | gone: | 1197 | gone: |
1198 | atomic_set(&device->state, FW_DEVICE_GONE); | 1198 | atomic_set(&device->state, FW_DEVICE_GONE); |
1199 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1199 | device->workfn = fw_device_shutdown; |
1200 | fw_schedule_device_work(device, SHUTDOWN_DELAY); | 1200 | fw_schedule_device_work(device, SHUTDOWN_DELAY); |
1201 | out: | 1201 | out: |
1202 | if (node_id == card->root_node->node_id) | 1202 | if (node_id == card->root_node->node_id) |
1203 | fw_schedule_bm_work(card, 0); | 1203 | fw_schedule_bm_work(card, 0); |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | static void fw_device_workfn(struct work_struct *work) | ||
1207 | { | ||
1208 | struct fw_device *device = container_of(to_delayed_work(work), | ||
1209 | struct fw_device, work); | ||
1210 | device->workfn(work); | ||
1211 | } | ||
1212 | |||
1206 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | 1213 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event) |
1207 | { | 1214 | { |
1208 | struct fw_device *device; | 1215 | struct fw_device *device; |
@@ -1252,7 +1259,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1252 | * power-up after getting plugged in. We schedule the | 1259 | * power-up after getting plugged in. We schedule the |
1253 | * first config rom scan half a second after bus reset. | 1260 | * first config rom scan half a second after bus reset. |
1254 | */ | 1261 | */ |
1255 | INIT_DELAYED_WORK(&device->work, fw_device_init); | 1262 | device->workfn = fw_device_init; |
1263 | INIT_DELAYED_WORK(&device->work, fw_device_workfn); | ||
1256 | fw_schedule_device_work(device, INITIAL_DELAY); | 1264 | fw_schedule_device_work(device, INITIAL_DELAY); |
1257 | break; | 1265 | break; |
1258 | 1266 | ||
@@ -1268,7 +1276,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1268 | if (atomic_cmpxchg(&device->state, | 1276 | if (atomic_cmpxchg(&device->state, |
1269 | FW_DEVICE_RUNNING, | 1277 | FW_DEVICE_RUNNING, |
1270 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { | 1278 | FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) { |
1271 | PREPARE_DELAYED_WORK(&device->work, fw_device_refresh); | 1279 | device->workfn = fw_device_refresh; |
1272 | fw_schedule_device_work(device, | 1280 | fw_schedule_device_work(device, |
1273 | device->is_local ? 0 : INITIAL_DELAY); | 1281 | device->is_local ? 0 : INITIAL_DELAY); |
1274 | } | 1282 | } |
@@ -1283,7 +1291,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1283 | smp_wmb(); /* update node_id before generation */ | 1291 | smp_wmb(); /* update node_id before generation */ |
1284 | device->generation = card->generation; | 1292 | device->generation = card->generation; |
1285 | if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { | 1293 | if (atomic_read(&device->state) == FW_DEVICE_RUNNING) { |
1286 | PREPARE_DELAYED_WORK(&device->work, fw_device_update); | 1294 | device->workfn = fw_device_update; |
1287 | fw_schedule_device_work(device, 0); | 1295 | fw_schedule_device_work(device, 0); |
1288 | } | 1296 | } |
1289 | break; | 1297 | break; |
@@ -1308,7 +1316,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
1308 | device = node->data; | 1316 | device = node->data; |
1309 | if (atomic_xchg(&device->state, | 1317 | if (atomic_xchg(&device->state, |
1310 | FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { | 1318 | FW_DEVICE_GONE) == FW_DEVICE_RUNNING) { |
1311 | PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); | 1319 | device->workfn = fw_device_shutdown; |
1312 | fw_schedule_device_work(device, | 1320 | fw_schedule_device_work(device, |
1313 | list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); | 1321 | list_empty(&card->link) ? 0 : SHUTDOWN_DELAY); |
1314 | } | 1322 | } |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 6b895986dc22..4af0a7bad7f2 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -929,8 +929,6 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, | |||
929 | if (rcode == RCODE_COMPLETE) { | 929 | if (rcode == RCODE_COMPLETE) { |
930 | fwnet_transmit_packet_done(ptask); | 930 | fwnet_transmit_packet_done(ptask); |
931 | } else { | 931 | } else { |
932 | fwnet_transmit_packet_failed(ptask); | ||
933 | |||
934 | if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { | 932 | if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { |
935 | dev_err(&ptask->dev->netdev->dev, | 933 | dev_err(&ptask->dev->netdev->dev, |
936 | "fwnet_write_complete failed: %x (skipped %d)\n", | 934 | "fwnet_write_complete failed: %x (skipped %d)\n", |
@@ -938,8 +936,10 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, | |||
938 | 936 | ||
939 | errors_skipped = 0; | 937 | errors_skipped = 0; |
940 | last_rcode = rcode; | 938 | last_rcode = rcode; |
941 | } else | 939 | } else { |
942 | errors_skipped++; | 940 | errors_skipped++; |
941 | } | ||
942 | fwnet_transmit_packet_failed(ptask); | ||
943 | } | 943 | } |
944 | } | 944 | } |
945 | 945 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6f74d8d3f700..8db663219560 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -290,7 +290,6 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
290 | #define QUIRK_NO_MSI 0x10 | 290 | #define QUIRK_NO_MSI 0x10 |
291 | #define QUIRK_TI_SLLZ059 0x20 | 291 | #define QUIRK_TI_SLLZ059 0x20 |
292 | #define QUIRK_IR_WAKE 0x40 | 292 | #define QUIRK_IR_WAKE 0x40 |
293 | #define QUIRK_PHY_LCTRL_TIMEOUT 0x80 | ||
294 | 293 | ||
295 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | 294 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ |
296 | static const struct { | 295 | static const struct { |
@@ -303,10 +302,7 @@ static const struct { | |||
303 | QUIRK_BE_HEADERS}, | 302 | QUIRK_BE_HEADERS}, |
304 | 303 | ||
305 | {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, | 304 | {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, |
306 | QUIRK_PHY_LCTRL_TIMEOUT | QUIRK_NO_MSI}, | 305 | QUIRK_NO_MSI}, |
307 | |||
308 | {PCI_VENDOR_ID_ATT, PCI_ANY_ID, PCI_ANY_ID, | ||
309 | QUIRK_PHY_LCTRL_TIMEOUT}, | ||
310 | 306 | ||
311 | {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, | 307 | {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, |
312 | QUIRK_RESET_PACKET}, | 308 | QUIRK_RESET_PACKET}, |
@@ -353,7 +349,6 @@ MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" | |||
353 | ", disable MSI = " __stringify(QUIRK_NO_MSI) | 349 | ", disable MSI = " __stringify(QUIRK_NO_MSI) |
354 | ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059) | 350 | ", TI SLLZ059 erratum = " __stringify(QUIRK_TI_SLLZ059) |
355 | ", IR wake unreliable = " __stringify(QUIRK_IR_WAKE) | 351 | ", IR wake unreliable = " __stringify(QUIRK_IR_WAKE) |
356 | ", phy LCtrl timeout = " __stringify(QUIRK_PHY_LCTRL_TIMEOUT) | ||
357 | ")"); | 352 | ")"); |
358 | 353 | ||
359 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 354 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
@@ -2299,9 +2294,6 @@ static int ohci_enable(struct fw_card *card, | |||
2299 | * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but | 2294 | * TI TSB82AA2 + TSB81BA3(A) cards signal LPS enabled early but |
2300 | * cannot actually use the phy at that time. These need tens of | 2295 | * cannot actually use the phy at that time. These need tens of |
2301 | * millisecods pause between LPS write and first phy access too. | 2296 | * millisecods pause between LPS write and first phy access too. |
2302 | * | ||
2303 | * But do not wait for 50msec on Agere/LSI cards. Their phy | ||
2304 | * arbitration state machine may time out during such a long wait. | ||
2305 | */ | 2297 | */ |
2306 | 2298 | ||
2307 | reg_write(ohci, OHCI1394_HCControlSet, | 2299 | reg_write(ohci, OHCI1394_HCControlSet, |
@@ -2309,11 +2301,8 @@ static int ohci_enable(struct fw_card *card, | |||
2309 | OHCI1394_HCControl_postedWriteEnable); | 2301 | OHCI1394_HCControl_postedWriteEnable); |
2310 | flush_writes(ohci); | 2302 | flush_writes(ohci); |
2311 | 2303 | ||
2312 | if (!(ohci->quirks & QUIRK_PHY_LCTRL_TIMEOUT)) | 2304 | for (lps = 0, i = 0; !lps && i < 3; i++) { |
2313 | msleep(50); | 2305 | msleep(50); |
2314 | |||
2315 | for (lps = 0, i = 0; !lps && i < 150; i++) { | ||
2316 | msleep(1); | ||
2317 | lps = reg_read(ohci, OHCI1394_HCControlSet) & | 2306 | lps = reg_read(ohci, OHCI1394_HCControlSet) & |
2318 | OHCI1394_HCControl_LPS; | 2307 | OHCI1394_HCControl_LPS; |
2319 | } | 2308 | } |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 281029daf98c..7aef911fdc71 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -146,6 +146,7 @@ struct sbp2_logical_unit { | |||
146 | */ | 146 | */ |
147 | int generation; | 147 | int generation; |
148 | int retries; | 148 | int retries; |
149 | work_func_t workfn; | ||
149 | struct delayed_work work; | 150 | struct delayed_work work; |
150 | bool has_sdev; | 151 | bool has_sdev; |
151 | bool blocked; | 152 | bool blocked; |
@@ -864,7 +865,7 @@ static void sbp2_login(struct work_struct *work) | |||
864 | /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ | 865 | /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ |
865 | sbp2_set_busy_timeout(lu); | 866 | sbp2_set_busy_timeout(lu); |
866 | 867 | ||
867 | PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect); | 868 | lu->workfn = sbp2_reconnect; |
868 | sbp2_agent_reset(lu); | 869 | sbp2_agent_reset(lu); |
869 | 870 | ||
870 | /* This was a re-login. */ | 871 | /* This was a re-login. */ |
@@ -918,7 +919,7 @@ static void sbp2_login(struct work_struct *work) | |||
918 | * If a bus reset happened, sbp2_update will have requeued | 919 | * If a bus reset happened, sbp2_update will have requeued |
919 | * lu->work already. Reset the work from reconnect to login. | 920 | * lu->work already. Reset the work from reconnect to login. |
920 | */ | 921 | */ |
921 | PREPARE_DELAYED_WORK(&lu->work, sbp2_login); | 922 | lu->workfn = sbp2_login; |
922 | } | 923 | } |
923 | 924 | ||
924 | static void sbp2_reconnect(struct work_struct *work) | 925 | static void sbp2_reconnect(struct work_struct *work) |
@@ -952,7 +953,7 @@ static void sbp2_reconnect(struct work_struct *work) | |||
952 | lu->retries++ >= 5) { | 953 | lu->retries++ >= 5) { |
953 | dev_err(tgt_dev(tgt), "failed to reconnect\n"); | 954 | dev_err(tgt_dev(tgt), "failed to reconnect\n"); |
954 | lu->retries = 0; | 955 | lu->retries = 0; |
955 | PREPARE_DELAYED_WORK(&lu->work, sbp2_login); | 956 | lu->workfn = sbp2_login; |
956 | } | 957 | } |
957 | sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); | 958 | sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); |
958 | 959 | ||
@@ -972,6 +973,13 @@ static void sbp2_reconnect(struct work_struct *work) | |||
972 | sbp2_conditionally_unblock(lu); | 973 | sbp2_conditionally_unblock(lu); |
973 | } | 974 | } |
974 | 975 | ||
976 | static void sbp2_lu_workfn(struct work_struct *work) | ||
977 | { | ||
978 | struct sbp2_logical_unit *lu = container_of(to_delayed_work(work), | ||
979 | struct sbp2_logical_unit, work); | ||
980 | lu->workfn(work); | ||
981 | } | ||
982 | |||
975 | static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | 983 | static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) |
976 | { | 984 | { |
977 | struct sbp2_logical_unit *lu; | 985 | struct sbp2_logical_unit *lu; |
@@ -998,7 +1006,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | |||
998 | lu->blocked = false; | 1006 | lu->blocked = false; |
999 | ++tgt->dont_block; | 1007 | ++tgt->dont_block; |
1000 | INIT_LIST_HEAD(&lu->orb_list); | 1008 | INIT_LIST_HEAD(&lu->orb_list); |
1001 | INIT_DELAYED_WORK(&lu->work, sbp2_login); | 1009 | lu->workfn = sbp2_login; |
1010 | INIT_DELAYED_WORK(&lu->work, sbp2_lu_workfn); | ||
1002 | 1011 | ||
1003 | list_add_tail(&lu->link, &tgt->lu_list); | 1012 | list_add_tail(&lu->link, &tgt->lu_list); |
1004 | return 0; | 1013 | return 0; |
diff --git a/drivers/fmc/fmc-write-eeprom.c b/drivers/fmc/fmc-write-eeprom.c index ee5b47904130..9bb2cbd5c9f2 100644 --- a/drivers/fmc/fmc-write-eeprom.c +++ b/drivers/fmc/fmc-write-eeprom.c | |||
@@ -27,7 +27,7 @@ FMC_PARAM_BUSID(fwe_drv); | |||
27 | /* The "file=" is like the generic "gateware=" used elsewhere */ | 27 | /* The "file=" is like the generic "gateware=" used elsewhere */ |
28 | static char *fwe_file[FMC_MAX_CARDS]; | 28 | static char *fwe_file[FMC_MAX_CARDS]; |
29 | static int fwe_file_n; | 29 | static int fwe_file_n; |
30 | module_param_array_named(file, fwe_file, charp, &fwe_file_n, 444); | 30 | module_param_array_named(file, fwe_file, charp, &fwe_file_n, 0444); |
31 | 31 | ||
32 | static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw, | 32 | static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw, |
33 | int write) | 33 | int write) |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 697338772b64..903f24d28ba0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -403,6 +403,7 @@ config GPIO_GRGPIO | |||
403 | 403 | ||
404 | config GPIO_TB10X | 404 | config GPIO_TB10X |
405 | bool | 405 | bool |
406 | select GENERIC_IRQ_CHIP | ||
406 | select OF_GPIO | 407 | select OF_GPIO |
407 | 408 | ||
408 | comment "I2C GPIO expanders:" | 409 | comment "I2C GPIO expanders:" |
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index 233d088ac59f..f32357e2d78d 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012-2013 Broadcom Corporation | 2 | * Copyright (C) 2012-2014 Broadcom Corporation |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License as | 5 | * modify it under the terms of the GNU General Public License as |
@@ -657,6 +657,6 @@ static struct platform_driver bcm_kona_gpio_driver = { | |||
657 | 657 | ||
658 | module_platform_driver(bcm_kona_gpio_driver); | 658 | module_platform_driver(bcm_kona_gpio_driver); |
659 | 659 | ||
660 | MODULE_AUTHOR("Broadcom"); | 660 | MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>"); |
661 | MODULE_DESCRIPTION("Broadcom Kona GPIO Driver"); | 661 | MODULE_DESCRIPTION("Broadcom Kona GPIO Driver"); |
662 | MODULE_LICENSE("GPL v2"); | 662 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index d3550274b8f7..3c2ba2ad0ada 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c | |||
@@ -97,3 +97,4 @@ module_platform_driver(clps711x_gpio_driver); | |||
97 | MODULE_LICENSE("GPL"); | 97 | MODULE_LICENSE("GPL"); |
98 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | 98 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); |
99 | MODULE_DESCRIPTION("CLPS711X GPIO driver"); | 99 | MODULE_DESCRIPTION("CLPS711X GPIO driver"); |
100 | MODULE_ALIAS("platform:clps711x-gpio"); | ||
diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c index d1b50ef5fab8..e585163f1ad5 100644 --- a/drivers/gpio/gpio-intel-mid.c +++ b/drivers/gpio/gpio-intel-mid.c | |||
@@ -394,8 +394,8 @@ static const struct irq_domain_ops intel_gpio_irq_ops = { | |||
394 | 394 | ||
395 | static int intel_gpio_runtime_idle(struct device *dev) | 395 | static int intel_gpio_runtime_idle(struct device *dev) |
396 | { | 396 | { |
397 | pm_schedule_suspend(dev, 500); | 397 | int err = pm_schedule_suspend(dev, 500); |
398 | return -EBUSY; | 398 | return err ?: -EBUSY; |
399 | } | 399 | } |
400 | 400 | ||
401 | static const struct dev_pm_ops intel_gpio_pm_ops = { | 401 | static const struct dev_pm_ops intel_gpio_pm_ops = { |
diff --git a/drivers/gpio/gpio-xtensa.c b/drivers/gpio/gpio-xtensa.c index 1d136eceda62..7081304d6797 100644 --- a/drivers/gpio/gpio-xtensa.c +++ b/drivers/gpio/gpio-xtensa.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #error GPIO32 option is not enabled for your xtensa core variant | 40 | #error GPIO32 option is not enabled for your xtensa core variant |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #if XCHAL_HAVE_CP | ||
44 | |||
43 | static inline unsigned long enable_cp(unsigned long *cpenable) | 45 | static inline unsigned long enable_cp(unsigned long *cpenable) |
44 | { | 46 | { |
45 | unsigned long flags; | 47 | unsigned long flags; |
@@ -57,6 +59,20 @@ static inline void disable_cp(unsigned long flags, unsigned long cpenable) | |||
57 | local_irq_restore(flags); | 59 | local_irq_restore(flags); |
58 | } | 60 | } |
59 | 61 | ||
62 | #else | ||
63 | |||
64 | static inline unsigned long enable_cp(unsigned long *cpenable) | ||
65 | { | ||
66 | *cpenable = 0; /* avoid uninitialized value warning */ | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static inline void disable_cp(unsigned long flags, unsigned long cpenable) | ||
71 | { | ||
72 | } | ||
73 | |||
74 | #endif /* XCHAL_HAVE_CP */ | ||
75 | |||
60 | static int xtensa_impwire_get_direction(struct gpio_chip *gc, unsigned offset) | 76 | static int xtensa_impwire_get_direction(struct gpio_chip *gc, unsigned offset) |
61 | { | 77 | { |
62 | return 1; /* input only */ | 78 | return 1; /* input only */ |
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index acf3a36c9ebc..32982da82694 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
@@ -68,15 +68,7 @@ void __armada_drm_queue_unref_work(struct drm_device *dev, | |||
68 | { | 68 | { |
69 | struct armada_private *priv = dev->dev_private; | 69 | struct armada_private *priv = dev->dev_private; |
70 | 70 | ||
71 | /* | 71 | WARN_ON(!kfifo_put(&priv->fb_unref, fb)); |
72 | * Yes, we really must jump through these hoops just to store a | ||
73 | * _pointer_ to something into the kfifo. This is utterly insane | ||
74 | * and idiotic, because it kfifo requires the _data_ pointed to by | ||
75 | * the pointer const, not the pointer itself. Not only that, but | ||
76 | * you have to pass a pointer _to_ the pointer you want stored. | ||
77 | */ | ||
78 | const struct drm_framebuffer *silly_api_alert = fb; | ||
79 | WARN_ON(!kfifo_put(&priv->fb_unref, &silly_api_alert)); | ||
80 | schedule_work(&priv->fb_unref_work); | 72 | schedule_work(&priv->fb_unref_work); |
81 | } | 73 | } |
82 | 74 | ||
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c index 3f65dd6676b2..a28640f47c27 100644 --- a/drivers/gpu/drm/ast/ast_fb.c +++ b/drivers/gpu/drm/ast/ast_fb.c | |||
@@ -65,7 +65,7 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, | |||
65 | * then the BO is being moved and we should | 65 | * then the BO is being moved and we should |
66 | * store up the damage until later. | 66 | * store up the damage until later. |
67 | */ | 67 | */ |
68 | if (!drm_can_sleep()) | 68 | if (drm_can_sleep()) |
69 | ret = ast_bo_reserve(bo, true); | 69 | ret = ast_bo_reserve(bo, true); |
70 | if (ret) { | 70 | if (ret) { |
71 | if (ret != -EBUSY) | 71 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/bochs/Kconfig b/drivers/gpu/drm/bochs/Kconfig index c8fcf12019f0..5f8b0c2b9a44 100644 --- a/drivers/gpu/drm/bochs/Kconfig +++ b/drivers/gpu/drm/bochs/Kconfig | |||
@@ -2,6 +2,7 @@ config DRM_BOCHS | |||
2 | tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" | 2 | tristate "DRM Support for bochs dispi vga interface (qemu stdvga)" |
3 | depends on DRM && PCI | 3 | depends on DRM && PCI |
4 | select DRM_KMS_HELPER | 4 | select DRM_KMS_HELPER |
5 | select DRM_KMS_FB_HELPER | ||
5 | select FB_SYS_FILLRECT | 6 | select FB_SYS_FILLRECT |
6 | select FB_SYS_COPYAREA | 7 | select FB_SYS_COPYAREA |
7 | select FB_SYS_IMAGEBLIT | 8 | select FB_SYS_IMAGEBLIT |
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c index 2fd4a92162cb..32bbba0a787b 100644 --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c | |||
@@ -39,7 +39,7 @@ static void cirrus_dirty_update(struct cirrus_fbdev *afbdev, | |||
39 | * then the BO is being moved and we should | 39 | * then the BO is being moved and we should |
40 | * store up the damage until later. | 40 | * store up the damage until later. |
41 | */ | 41 | */ |
42 | if (!drm_can_sleep()) | 42 | if (drm_can_sleep()) |
43 | ret = cirrus_bo_reserve(bo, true); | 43 | ret = cirrus_bo_reserve(bo, true); |
44 | if (ret) { | 44 | if (ret) { |
45 | if (ret != -EBUSY) | 45 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index dffc836144cc..f4dc9b7a3831 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -296,6 +296,18 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
296 | case DRM_CAP_ASYNC_PAGE_FLIP: | 296 | case DRM_CAP_ASYNC_PAGE_FLIP: |
297 | req->value = dev->mode_config.async_page_flip; | 297 | req->value = dev->mode_config.async_page_flip; |
298 | break; | 298 | break; |
299 | case DRM_CAP_CURSOR_WIDTH: | ||
300 | if (dev->mode_config.cursor_width) | ||
301 | req->value = dev->mode_config.cursor_width; | ||
302 | else | ||
303 | req->value = 64; | ||
304 | break; | ||
305 | case DRM_CAP_CURSOR_HEIGHT: | ||
306 | if (dev->mode_config.cursor_height) | ||
307 | req->value = dev->mode_config.cursor_height; | ||
308 | else | ||
309 | req->value = 64; | ||
310 | break; | ||
299 | default: | 311 | default: |
300 | return -EINVAL; | 312 | return -EINVAL; |
301 | } | 313 | } |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 5736aaa7e86c..f7af69bcf3f4 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -468,8 +468,8 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) | |||
468 | } else { | 468 | } else { |
469 | list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, | 469 | list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, |
470 | legacy_dev_list) { | 470 | legacy_dev_list) { |
471 | drm_put_dev(dev); | ||
472 | list_del(&dev->legacy_dev_list); | 471 | list_del(&dev->legacy_dev_list); |
472 | drm_put_dev(dev); | ||
473 | } | 473 | } |
474 | } | 474 | } |
475 | DRM_INFO("Module unloaded\n"); | 475 | DRM_INFO("Module unloaded\n"); |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f227f544aa36..6e1a1a20cf6b 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -51,7 +51,7 @@ config DRM_EXYNOS_G2D | |||
51 | 51 | ||
52 | config DRM_EXYNOS_IPP | 52 | config DRM_EXYNOS_IPP |
53 | bool "Exynos DRM IPP" | 53 | bool "Exynos DRM IPP" |
54 | depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM | 54 | depends on DRM_EXYNOS |
55 | help | 55 | help |
56 | Choose this option if you want to use IPP feature for DRM. | 56 | Choose this option if you want to use IPP feature for DRM. |
57 | 57 | ||
@@ -69,6 +69,6 @@ config DRM_EXYNOS_ROTATOR | |||
69 | 69 | ||
70 | config DRM_EXYNOS_GSC | 70 | config DRM_EXYNOS_GSC |
71 | bool "Exynos DRM GSC" | 71 | bool "Exynos DRM GSC" |
72 | depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 | 72 | depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM |
73 | help | 73 | help |
74 | Choose this option if you want to use Exynos GSC for DRM. | 74 | Choose this option if you want to use Exynos GSC for DRM. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 9d096a0c5f8d..c204b4e3356e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -171,22 +171,28 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
171 | file->driver_priv = file_priv; | 171 | file->driver_priv = file_priv; |
172 | 172 | ||
173 | ret = exynos_drm_subdrv_open(dev, file); | 173 | ret = exynos_drm_subdrv_open(dev, file); |
174 | if (ret) { | 174 | if (ret) |
175 | kfree(file_priv); | 175 | goto err_file_priv_free; |
176 | file->driver_priv = NULL; | ||
177 | } | ||
178 | 176 | ||
179 | anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, | 177 | anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, |
180 | NULL, 0); | 178 | NULL, 0); |
181 | if (IS_ERR(anon_filp)) { | 179 | if (IS_ERR(anon_filp)) { |
182 | kfree(file_priv); | 180 | ret = PTR_ERR(anon_filp); |
183 | return PTR_ERR(anon_filp); | 181 | goto err_subdrv_close; |
184 | } | 182 | } |
185 | 183 | ||
186 | anon_filp->f_mode = FMODE_READ | FMODE_WRITE; | 184 | anon_filp->f_mode = FMODE_READ | FMODE_WRITE; |
187 | file_priv->anon_filp = anon_filp; | 185 | file_priv->anon_filp = anon_filp; |
188 | 186 | ||
189 | return ret; | 187 | return ret; |
188 | |||
189 | err_subdrv_close: | ||
190 | exynos_drm_subdrv_close(dev, file); | ||
191 | |||
192 | err_file_priv_free: | ||
193 | kfree(file_priv); | ||
194 | file->driver_priv = NULL; | ||
195 | return ret; | ||
190 | } | 196 | } |
191 | 197 | ||
192 | static void exynos_drm_preclose(struct drm_device *dev, | 198 | static void exynos_drm_preclose(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 380aec28840b..6c1885eedfdf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -607,7 +607,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) | |||
607 | reg_type = REG_TYPE_NONE; | 607 | reg_type = REG_TYPE_NONE; |
608 | DRM_ERROR("Unknown register offset![%d]\n", reg_offset); | 608 | DRM_ERROR("Unknown register offset![%d]\n", reg_offset); |
609 | break; | 609 | break; |
610 | }; | 610 | } |
611 | 611 | ||
612 | return reg_type; | 612 | return reg_type; |
613 | } | 613 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index d519a4e5fe40..09312b877470 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
19 | #include <plat/map-base.h> | ||
20 | 19 | ||
21 | #include <drm/drmP.h> | 20 | #include <drm/drmP.h> |
22 | #include <drm/exynos_drm.h> | 21 | #include <drm/exynos_drm.h> |
@@ -826,7 +825,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node, | |||
826 | DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); | 825 | DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); |
827 | 826 | ||
828 | /* | 827 | /* |
829 | * quf == NULL condition means all event deletion. | 828 | * qbuf == NULL condition means all event deletion. |
830 | * stop operations want to delete all event list. | 829 | * stop operations want to delete all event list. |
831 | * another case delete only same buf id. | 830 | * another case delete only same buf id. |
832 | */ | 831 | */ |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a0e10aeb0e67..c021ddc1ffb4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
35 | #include <linux/of.h> | 35 | #include <linux/of.h> |
36 | #include <linux/of_gpio.h> | 36 | #include <linux/of_gpio.h> |
37 | #include <linux/hdmi.h> | ||
37 | 38 | ||
38 | #include <drm/exynos_drm.h> | 39 | #include <drm/exynos_drm.h> |
39 | 40 | ||
@@ -59,19 +60,6 @@ | |||
59 | #define HDMI_AUI_VERSION 0x01 | 60 | #define HDMI_AUI_VERSION 0x01 |
60 | #define HDMI_AUI_LENGTH 0x0A | 61 | #define HDMI_AUI_LENGTH 0x0A |
61 | 62 | ||
62 | /* HDMI infoframe to configure HDMI out packet header, AUI and AVI */ | ||
63 | enum HDMI_PACKET_TYPE { | ||
64 | /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */ | ||
65 | /* InfoFrame packet type */ | ||
66 | HDMI_PACKET_TYPE_INFOFRAME = 0x80, | ||
67 | /* Vendor-Specific InfoFrame */ | ||
68 | HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1, | ||
69 | /* Auxiliary Video information InfoFrame */ | ||
70 | HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2, | ||
71 | /* Audio information InfoFrame */ | ||
72 | HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4 | ||
73 | }; | ||
74 | |||
75 | enum hdmi_type { | 63 | enum hdmi_type { |
76 | HDMI_TYPE13, | 64 | HDMI_TYPE13, |
77 | HDMI_TYPE14, | 65 | HDMI_TYPE14, |
@@ -379,12 +367,6 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = { | |||
379 | }, | 367 | }, |
380 | }; | 368 | }; |
381 | 369 | ||
382 | struct hdmi_infoframe { | ||
383 | enum HDMI_PACKET_TYPE type; | ||
384 | u8 ver; | ||
385 | u8 len; | ||
386 | }; | ||
387 | |||
388 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) | 370 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) |
389 | { | 371 | { |
390 | return readl(hdata->regs + reg_id); | 372 | return readl(hdata->regs + reg_id); |
@@ -682,7 +664,7 @@ static u8 hdmi_chksum(struct hdmi_context *hdata, | |||
682 | } | 664 | } |
683 | 665 | ||
684 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, | 666 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, |
685 | struct hdmi_infoframe *infoframe) | 667 | union hdmi_infoframe *infoframe) |
686 | { | 668 | { |
687 | u32 hdr_sum; | 669 | u32 hdr_sum; |
688 | u8 chksum; | 670 | u8 chksum; |
@@ -700,13 +682,15 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
700 | return; | 682 | return; |
701 | } | 683 | } |
702 | 684 | ||
703 | switch (infoframe->type) { | 685 | switch (infoframe->any.type) { |
704 | case HDMI_PACKET_TYPE_AVI: | 686 | case HDMI_INFOFRAME_TYPE_AVI: |
705 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); | 687 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); |
706 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type); | 688 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type); |
707 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver); | 689 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, |
708 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len); | 690 | infoframe->any.version); |
709 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 691 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length); |
692 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
693 | infoframe->any.length; | ||
710 | 694 | ||
711 | /* Output format zero hardcoded ,RGB YBCR selection */ | 695 | /* Output format zero hardcoded ,RGB YBCR selection */ |
712 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | | 696 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | |
@@ -722,18 +706,20 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
722 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); | 706 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); |
723 | 707 | ||
724 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), | 708 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), |
725 | infoframe->len, hdr_sum); | 709 | infoframe->any.length, hdr_sum); |
726 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); | 710 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); |
727 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); | 711 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); |
728 | break; | 712 | break; |
729 | case HDMI_PACKET_TYPE_AUI: | 713 | case HDMI_INFOFRAME_TYPE_AUDIO: |
730 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); | 714 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); |
731 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type); | 715 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type); |
732 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver); | 716 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, |
733 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len); | 717 | infoframe->any.version); |
734 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 718 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length); |
719 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
720 | infoframe->any.length; | ||
735 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), | 721 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), |
736 | infoframe->len, hdr_sum); | 722 | infoframe->any.length, hdr_sum); |
737 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); | 723 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); |
738 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); | 724 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); |
739 | break; | 725 | break; |
@@ -985,7 +971,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata) | |||
985 | 971 | ||
986 | static void hdmi_conf_init(struct hdmi_context *hdata) | 972 | static void hdmi_conf_init(struct hdmi_context *hdata) |
987 | { | 973 | { |
988 | struct hdmi_infoframe infoframe; | 974 | union hdmi_infoframe infoframe; |
989 | 975 | ||
990 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ | 976 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ |
991 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | | 977 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | |
@@ -1021,14 +1007,14 @@ static void hdmi_conf_init(struct hdmi_context *hdata) | |||
1021 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); | 1007 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); |
1022 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); | 1008 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); |
1023 | } else { | 1009 | } else { |
1024 | infoframe.type = HDMI_PACKET_TYPE_AVI; | 1010 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI; |
1025 | infoframe.ver = HDMI_AVI_VERSION; | 1011 | infoframe.any.version = HDMI_AVI_VERSION; |
1026 | infoframe.len = HDMI_AVI_LENGTH; | 1012 | infoframe.any.length = HDMI_AVI_LENGTH; |
1027 | hdmi_reg_infoframe(hdata, &infoframe); | 1013 | hdmi_reg_infoframe(hdata, &infoframe); |
1028 | 1014 | ||
1029 | infoframe.type = HDMI_PACKET_TYPE_AUI; | 1015 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO; |
1030 | infoframe.ver = HDMI_AUI_VERSION; | 1016 | infoframe.any.version = HDMI_AUI_VERSION; |
1031 | infoframe.len = HDMI_AUI_LENGTH; | 1017 | infoframe.any.length = HDMI_AUI_LENGTH; |
1032 | hdmi_reg_infoframe(hdata, &infoframe); | 1018 | hdmi_reg_infoframe(hdata, &infoframe); |
1033 | 1019 | ||
1034 | /* enable AVI packet every vsync, fixes purple line problem */ | 1020 | /* enable AVI packet every vsync, fixes purple line problem */ |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 400b0c4a10fb..faa77f543a07 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -208,7 +208,7 @@ struct tda998x_priv { | |||
208 | # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) | 208 | # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) |
209 | # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) | 209 | # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) |
210 | #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ | 210 | #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ |
211 | # define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) | 211 | # define PLL_SERIAL_2_SRL_NOSC(x) ((x) << 0) |
212 | # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) | 212 | # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) |
213 | #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ | 213 | #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ |
214 | # define PLL_SERIAL_3_SRL_CCIR (1 << 0) | 214 | # define PLL_SERIAL_3_SRL_CCIR (1 << 0) |
@@ -528,10 +528,10 @@ tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) | |||
528 | { | 528 | { |
529 | uint8_t buf[PB(5) + 1]; | 529 | uint8_t buf[PB(5) + 1]; |
530 | 530 | ||
531 | memset(buf, 0, sizeof(buf)); | ||
531 | buf[HB(0)] = 0x84; | 532 | buf[HB(0)] = 0x84; |
532 | buf[HB(1)] = 0x01; | 533 | buf[HB(1)] = 0x01; |
533 | buf[HB(2)] = 10; | 534 | buf[HB(2)] = 10; |
534 | buf[PB(0)] = 0; | ||
535 | buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ | 535 | buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ |
536 | buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ | 536 | buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ |
537 | buf[PB(4)] = p->audio_frame[4]; | 537 | buf[PB(4)] = p->audio_frame[4]; |
@@ -824,6 +824,11 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
824 | } | 824 | } |
825 | 825 | ||
826 | div = 148500 / mode->clock; | 826 | div = 148500 / mode->clock; |
827 | if (div != 0) { | ||
828 | div--; | ||
829 | if (div > 3) | ||
830 | div = 3; | ||
831 | } | ||
827 | 832 | ||
828 | /* mute the audio FIFO: */ | 833 | /* mute the audio FIFO: */ |
829 | reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); | 834 | reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); |
@@ -913,7 +918,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
913 | 918 | ||
914 | if (priv->rev == TDA19988) { | 919 | if (priv->rev == TDA19988) { |
915 | /* let incoming pixels fill the active space (if any) */ | 920 | /* let incoming pixels fill the active space (if any) */ |
916 | reg_write(encoder, REG_ENABLE_SPACE, 0x01); | 921 | reg_write(encoder, REG_ENABLE_SPACE, 0x00); |
917 | } | 922 | } |
918 | 923 | ||
919 | /* must be last register set: */ | 924 | /* must be last register set: */ |
@@ -1094,6 +1099,8 @@ tda998x_encoder_destroy(struct drm_encoder *encoder) | |||
1094 | { | 1099 | { |
1095 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | 1100 | struct tda998x_priv *priv = to_tda998x_priv(encoder); |
1096 | drm_i2c_encoder_destroy(encoder); | 1101 | drm_i2c_encoder_destroy(encoder); |
1102 | if (priv->cec) | ||
1103 | i2c_unregister_device(priv->cec); | ||
1097 | kfree(priv); | 1104 | kfree(priv); |
1098 | } | 1105 | } |
1099 | 1106 | ||
@@ -1142,8 +1149,12 @@ tda998x_encoder_init(struct i2c_client *client, | |||
1142 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); | 1149 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
1143 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); | 1150 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); |
1144 | 1151 | ||
1145 | priv->current_page = 0; | 1152 | priv->current_page = 0xff; |
1146 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1153 | priv->cec = i2c_new_dummy(client->adapter, 0x34); |
1154 | if (!priv->cec) { | ||
1155 | kfree(priv); | ||
1156 | return -ENODEV; | ||
1157 | } | ||
1147 | priv->dpms = DRM_MODE_DPMS_OFF; | 1158 | priv->dpms = DRM_MODE_DPMS_OFF; |
1148 | 1159 | ||
1149 | encoder_slave->slave_priv = priv; | 1160 | encoder_slave->slave_priv = priv; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 04f1f02c4019..ec7bb0fc71bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -403,7 +403,7 @@ MODULE_DEVICE_TABLE(pci, pciidlist); | |||
403 | void intel_detect_pch(struct drm_device *dev) | 403 | void intel_detect_pch(struct drm_device *dev) |
404 | { | 404 | { |
405 | struct drm_i915_private *dev_priv = dev->dev_private; | 405 | struct drm_i915_private *dev_priv = dev->dev_private; |
406 | struct pci_dev *pch; | 406 | struct pci_dev *pch = NULL; |
407 | 407 | ||
408 | /* In all current cases, num_pipes is equivalent to the PCH_NOP setting | 408 | /* In all current cases, num_pipes is equivalent to the PCH_NOP setting |
409 | * (which really amounts to a PCH but no South Display). | 409 | * (which really amounts to a PCH but no South Display). |
@@ -424,12 +424,9 @@ void intel_detect_pch(struct drm_device *dev) | |||
424 | * all the ISA bridge devices and check for the first match, instead | 424 | * all the ISA bridge devices and check for the first match, instead |
425 | * of only checking the first one. | 425 | * of only checking the first one. |
426 | */ | 426 | */ |
427 | pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL); | 427 | while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { |
428 | while (pch) { | ||
429 | struct pci_dev *curr = pch; | ||
430 | if (pch->vendor == PCI_VENDOR_ID_INTEL) { | 428 | if (pch->vendor == PCI_VENDOR_ID_INTEL) { |
431 | unsigned short id; | 429 | unsigned short id = pch->device & INTEL_PCH_DEVICE_ID_MASK; |
432 | id = pch->device & INTEL_PCH_DEVICE_ID_MASK; | ||
433 | dev_priv->pch_id = id; | 430 | dev_priv->pch_id = id; |
434 | 431 | ||
435 | if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { | 432 | if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) { |
@@ -461,18 +458,16 @@ void intel_detect_pch(struct drm_device *dev) | |||
461 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); | 458 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); |
462 | WARN_ON(!IS_HASWELL(dev)); | 459 | WARN_ON(!IS_HASWELL(dev)); |
463 | WARN_ON(!IS_ULT(dev)); | 460 | WARN_ON(!IS_ULT(dev)); |
464 | } else { | 461 | } else |
465 | goto check_next; | 462 | continue; |
466 | } | 463 | |
467 | pci_dev_put(pch); | ||
468 | break; | 464 | break; |
469 | } | 465 | } |
470 | check_next: | ||
471 | pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, curr); | ||
472 | pci_dev_put(curr); | ||
473 | } | 466 | } |
474 | if (!pch) | 467 | if (!pch) |
475 | DRM_DEBUG_KMS("No PCH found?\n"); | 468 | DRM_DEBUG_KMS("No PCH found.\n"); |
469 | |||
470 | pci_dev_put(pch); | ||
476 | } | 471 | } |
477 | 472 | ||
478 | bool i915_semaphore_is_enabled(struct drm_device *dev) | 473 | bool i915_semaphore_is_enabled(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4a2bf8e3f739..df77e20e3c3d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1831,6 +1831,14 @@ struct drm_i915_file_private { | |||
1831 | 1831 | ||
1832 | /* Early gen2 have a totally busted CS tlb and require pinned batches. */ | 1832 | /* Early gen2 have a totally busted CS tlb and require pinned batches. */ |
1833 | #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) | 1833 | #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) |
1834 | /* | ||
1835 | * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts | ||
1836 | * even when in MSI mode. This results in spurious interrupt warnings if the | ||
1837 | * legacy irq no. is shared with another device. The kernel then disables that | ||
1838 | * interrupt source and so prevents the other device from working properly. | ||
1839 | */ | ||
1840 | #define HAS_AUX_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
1841 | #define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
1834 | 1842 | ||
1835 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1843 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
1836 | * rows, which changed the alignment requirements and fence programming. | 1844 | * rows, which changed the alignment requirements and fence programming. |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 1a24e84f2315..28d24caa49f3 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -82,9 +82,22 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) | |||
82 | r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size, | 82 | r = devm_request_mem_region(dev->dev, base, dev_priv->gtt.stolen_size, |
83 | "Graphics Stolen Memory"); | 83 | "Graphics Stolen Memory"); |
84 | if (r == NULL) { | 84 | if (r == NULL) { |
85 | DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", | 85 | /* |
86 | base, base + (uint32_t)dev_priv->gtt.stolen_size); | 86 | * One more attempt but this time requesting region from |
87 | base = 0; | 87 | * base + 1, as we have seen that this resolves the region |
88 | * conflict with the PCI Bus. | ||
89 | * This is a BIOS w/a: Some BIOS wrap stolen in the root | ||
90 | * PCI bus, but have an off-by-one error. Hence retry the | ||
91 | * reservation starting from 1 instead of 0. | ||
92 | */ | ||
93 | r = devm_request_mem_region(dev->dev, base + 1, | ||
94 | dev_priv->gtt.stolen_size - 1, | ||
95 | "Graphics Stolen Memory"); | ||
96 | if (r == NULL) { | ||
97 | DRM_ERROR("conflict detected with stolen region: [0x%08x - 0x%08x]\n", | ||
98 | base, base + (uint32_t)dev_priv->gtt.stolen_size); | ||
99 | base = 0; | ||
100 | } | ||
88 | } | 101 | } |
89 | 102 | ||
90 | return base; | 103 | return base; |
@@ -201,6 +214,13 @@ int i915_gem_init_stolen(struct drm_device *dev) | |||
201 | struct drm_i915_private *dev_priv = dev->dev_private; | 214 | struct drm_i915_private *dev_priv = dev->dev_private; |
202 | int bios_reserved = 0; | 215 | int bios_reserved = 0; |
203 | 216 | ||
217 | #ifdef CONFIG_INTEL_IOMMU | ||
218 | if (intel_iommu_gfx_mapped) { | ||
219 | DRM_INFO("DMAR active, disabling use of stolen memory\n"); | ||
220 | return 0; | ||
221 | } | ||
222 | #endif | ||
223 | |||
204 | if (dev_priv->gtt.stolen_size == 0) | 224 | if (dev_priv->gtt.stolen_size == 0) |
205 | return 0; | 225 | return 0; |
206 | 226 | ||
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index d7fd2fd2f0a5..990cf8f43efd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -146,7 +146,10 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e, | |||
146 | va_list tmp; | 146 | va_list tmp; |
147 | 147 | ||
148 | va_copy(tmp, args); | 148 | va_copy(tmp, args); |
149 | if (!__i915_error_seek(e, vsnprintf(NULL, 0, f, tmp))) | 149 | len = vsnprintf(NULL, 0, f, tmp); |
150 | va_end(tmp); | ||
151 | |||
152 | if (!__i915_error_seek(e, len)) | ||
150 | return; | 153 | return; |
151 | } | 154 | } |
152 | 155 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 17d8fcb1b6f7..d554169ac592 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -567,8 +567,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
567 | 567 | ||
568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; | 568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; |
569 | } else { | 569 | } else { |
570 | enum transcoder cpu_transcoder = | 570 | enum transcoder cpu_transcoder = (enum transcoder) pipe; |
571 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); | ||
572 | u32 htotal; | 571 | u32 htotal; |
573 | 572 | ||
574 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; | 573 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; |
@@ -619,33 +618,25 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
619 | 618 | ||
620 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ | 619 | /* raw reads, only for fast reads of display block, no need for forcewake etc. */ |
621 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) | 620 | #define __raw_i915_read32(dev_priv__, reg__) readl((dev_priv__)->regs + (reg__)) |
622 | #define __raw_i915_read16(dev_priv__, reg__) readw((dev_priv__)->regs + (reg__)) | ||
623 | 621 | ||
624 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) | 622 | static bool ilk_pipe_in_vblank_locked(struct drm_device *dev, enum pipe pipe) |
625 | { | 623 | { |
626 | struct drm_i915_private *dev_priv = dev->dev_private; | 624 | struct drm_i915_private *dev_priv = dev->dev_private; |
627 | uint32_t status; | 625 | uint32_t status; |
628 | 626 | int reg; | |
629 | if (INTEL_INFO(dev)->gen < 7) { | 627 | |
630 | status = pipe == PIPE_A ? | 628 | if (INTEL_INFO(dev)->gen >= 8) { |
631 | DE_PIPEA_VBLANK : | 629 | status = GEN8_PIPE_VBLANK; |
632 | DE_PIPEB_VBLANK; | 630 | reg = GEN8_DE_PIPE_ISR(pipe); |
631 | } else if (INTEL_INFO(dev)->gen >= 7) { | ||
632 | status = DE_PIPE_VBLANK_IVB(pipe); | ||
633 | reg = DEISR; | ||
633 | } else { | 634 | } else { |
634 | switch (pipe) { | 635 | status = DE_PIPE_VBLANK(pipe); |
635 | default: | 636 | reg = DEISR; |
636 | case PIPE_A: | ||
637 | status = DE_PIPEA_VBLANK_IVB; | ||
638 | break; | ||
639 | case PIPE_B: | ||
640 | status = DE_PIPEB_VBLANK_IVB; | ||
641 | break; | ||
642 | case PIPE_C: | ||
643 | status = DE_PIPEC_VBLANK_IVB; | ||
644 | break; | ||
645 | } | ||
646 | } | 637 | } |
647 | 638 | ||
648 | return __raw_i915_read32(dev_priv, DEISR) & status; | 639 | return __raw_i915_read32(dev_priv, reg) & status; |
649 | } | 640 | } |
650 | 641 | ||
651 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | 642 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
@@ -703,7 +694,28 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
703 | else | 694 | else |
704 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; | 695 | position = __raw_i915_read32(dev_priv, PIPEDSL(pipe)) & DSL_LINEMASK_GEN3; |
705 | 696 | ||
706 | if (HAS_PCH_SPLIT(dev)) { | 697 | if (HAS_DDI(dev)) { |
698 | /* | ||
699 | * On HSW HDMI outputs there seems to be a 2 line | ||
700 | * difference, whereas eDP has the normal 1 line | ||
701 | * difference that earlier platforms have. External | ||
702 | * DP is unknown. For now just check for the 2 line | ||
703 | * difference case on all output types on HSW+. | ||
704 | * | ||
705 | * This might misinterpret the scanline counter being | ||
706 | * one line too far along on eDP, but that's less | ||
707 | * dangerous than the alternative since that would lead | ||
708 | * the vblank timestamp code astray when it sees a | ||
709 | * scanline count before vblank_start during a vblank | ||
710 | * interrupt. | ||
711 | */ | ||
712 | in_vbl = ilk_pipe_in_vblank_locked(dev, pipe); | ||
713 | if ((in_vbl && (position == vbl_start - 2 || | ||
714 | position == vbl_start - 1)) || | ||
715 | (!in_vbl && (position == vbl_end - 2 || | ||
716 | position == vbl_end - 1))) | ||
717 | position = (position + 2) % vtotal; | ||
718 | } else if (HAS_PCH_SPLIT(dev)) { | ||
707 | /* | 719 | /* |
708 | * The scanline counter increments at the leading edge | 720 | * The scanline counter increments at the leading edge |
709 | * of hsync, ie. it completely misses the active portion | 721 | * of hsync, ie. it completely misses the active portion |
@@ -2770,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev) | |||
2770 | return; | 2782 | return; |
2771 | 2783 | ||
2772 | if (HAS_PCH_IBX(dev)) { | 2784 | if (HAS_PCH_IBX(dev)) { |
2773 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | | 2785 | mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; |
2774 | SDE_TRANSA_FIFO_UNDER | SDE_POISON; | ||
2775 | } else { | 2786 | } else { |
2776 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; | 2787 | mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; |
2777 | 2788 | ||
2778 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); | 2789 | I915_WRITE(SERR_INT, I915_READ(SERR_INT)); |
2779 | } | 2790 | } |
@@ -2833,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
2833 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | | 2844 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | |
2834 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | | 2845 | DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | |
2835 | DE_PLANEB_FLIP_DONE_IVB | | 2846 | DE_PLANEB_FLIP_DONE_IVB | |
2836 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | | 2847 | DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB); |
2837 | DE_ERR_INT_IVB); | ||
2838 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | | 2848 | extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | |
2839 | DE_PIPEA_VBLANK_IVB); | 2849 | DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB); |
2840 | 2850 | ||
2841 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); | 2851 | I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); |
2842 | } else { | 2852 | } else { |
2843 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | | 2853 | display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | |
2844 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | | 2854 | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | |
2845 | DE_AUX_CHANNEL_A | | 2855 | DE_AUX_CHANNEL_A | |
2846 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN | | ||
2847 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | | 2856 | DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | |
2848 | DE_POISON); | 2857 | DE_POISON); |
2849 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; | 2858 | extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT | |
2859 | DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN; | ||
2850 | } | 2860 | } |
2851 | 2861 | ||
2852 | dev_priv->irq_mask = ~display_mask; | 2862 | dev_priv->irq_mask = ~display_mask; |
@@ -2962,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) | |||
2962 | struct drm_device *dev = dev_priv->dev; | 2972 | struct drm_device *dev = dev_priv->dev; |
2963 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | | 2973 | uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | |
2964 | GEN8_PIPE_CDCLK_CRC_DONE | | 2974 | GEN8_PIPE_CDCLK_CRC_DONE | |
2965 | GEN8_PIPE_FIFO_UNDERRUN | | ||
2966 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | 2975 | GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
2967 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; | 2976 | uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | |
2977 | GEN8_PIPE_FIFO_UNDERRUN; | ||
2968 | int pipe; | 2978 | int pipe; |
2969 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; | 2979 | dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; |
2970 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; | 2980 | dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index e06b9e017d6b..234ac5f7bc5a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -1244,6 +1244,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) | |||
1244 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { | 1244 | if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { |
1245 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1245 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1246 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | 1246 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1247 | ironlake_edp_panel_vdd_on(intel_dp); | ||
1247 | ironlake_edp_panel_off(intel_dp); | 1248 | ironlake_edp_panel_off(intel_dp); |
1248 | } | 1249 | } |
1249 | 1250 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9fa24347963a..9b8a7c7ea7fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1092,12 +1092,12 @@ static void assert_cursor(struct drm_i915_private *dev_priv, | |||
1092 | struct drm_device *dev = dev_priv->dev; | 1092 | struct drm_device *dev = dev_priv->dev; |
1093 | bool cur_state; | 1093 | bool cur_state; |
1094 | 1094 | ||
1095 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 1095 | if (IS_845G(dev) || IS_I865G(dev)) |
1096 | cur_state = I915_READ(CURCNTR_IVB(pipe)) & CURSOR_MODE; | ||
1097 | else if (IS_845G(dev) || IS_I865G(dev)) | ||
1098 | cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE; | 1096 | cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE; |
1099 | else | 1097 | else if (INTEL_INFO(dev)->gen <= 6 || IS_VALLEYVIEW(dev)) |
1100 | cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; | 1098 | cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE; |
1099 | else | ||
1100 | cur_state = I915_READ(CURCNTR_IVB(pipe)) & CURSOR_MODE; | ||
1101 | 1101 | ||
1102 | WARN(cur_state != state, | 1102 | WARN(cur_state != state, |
1103 | "cursor on pipe %c assertion failure (expected %s, current %s)\n", | 1103 | "cursor on pipe %c assertion failure (expected %s, current %s)\n", |
@@ -8586,6 +8586,20 @@ static int intel_gen7_queue_flip(struct drm_device *dev, | |||
8586 | if (ring->id == RCS) | 8586 | if (ring->id == RCS) |
8587 | len += 6; | 8587 | len += 6; |
8588 | 8588 | ||
8589 | /* | ||
8590 | * BSpec MI_DISPLAY_FLIP for IVB: | ||
8591 | * "The full packet must be contained within the same cache line." | ||
8592 | * | ||
8593 | * Currently the LRI+SRM+MI_DISPLAY_FLIP all fit within the same | ||
8594 | * cacheline, if we ever start emitting more commands before | ||
8595 | * the MI_DISPLAY_FLIP we may need to first emit everything else, | ||
8596 | * then do the cacheline alignment, and finally emit the | ||
8597 | * MI_DISPLAY_FLIP. | ||
8598 | */ | ||
8599 | ret = intel_ring_cacheline_align(ring); | ||
8600 | if (ret) | ||
8601 | goto err_unpin; | ||
8602 | |||
8589 | ret = intel_ring_begin(ring, len); | 8603 | ret = intel_ring_begin(ring, len); |
8590 | if (ret) | 8604 | if (ret) |
8591 | goto err_unpin; | 8605 | goto err_unpin; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ede4e8e290d..2688f6d64bb9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
404 | int i, ret, recv_bytes; | 404 | int i, ret, recv_bytes; |
405 | uint32_t status; | 405 | uint32_t status; |
406 | int try, precharge, clock = 0; | 406 | int try, precharge, clock = 0; |
407 | bool has_aux_irq = true; | 407 | bool has_aux_irq = HAS_AUX_IRQ(dev); |
408 | uint32_t timeout; | 408 | uint32_t timeout; |
409 | 409 | ||
410 | /* dp aux is extremely sensitive to irq latency, hence request the | 410 | /* dp aux is extremely sensitive to irq latency, hence request the |
@@ -537,6 +537,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
537 | uint8_t msg[20]; | 537 | uint8_t msg[20]; |
538 | int msg_bytes; | 538 | int msg_bytes; |
539 | uint8_t ack; | 539 | uint8_t ack; |
540 | int retry; | ||
540 | 541 | ||
541 | if (WARN_ON(send_bytes > 16)) | 542 | if (WARN_ON(send_bytes > 16)) |
542 | return -E2BIG; | 543 | return -E2BIG; |
@@ -548,19 +549,21 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
548 | msg[3] = send_bytes - 1; | 549 | msg[3] = send_bytes - 1; |
549 | memcpy(&msg[4], send, send_bytes); | 550 | memcpy(&msg[4], send, send_bytes); |
550 | msg_bytes = send_bytes + 4; | 551 | msg_bytes = send_bytes + 4; |
551 | for (;;) { | 552 | for (retry = 0; retry < 7; retry++) { |
552 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); | 553 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
553 | if (ret < 0) | 554 | if (ret < 0) |
554 | return ret; | 555 | return ret; |
555 | ack >>= 4; | 556 | ack >>= 4; |
556 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) | 557 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) |
557 | break; | 558 | return send_bytes; |
558 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 559 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
559 | udelay(100); | 560 | usleep_range(400, 500); |
560 | else | 561 | else |
561 | return -EIO; | 562 | return -EIO; |
562 | } | 563 | } |
563 | return send_bytes; | 564 | |
565 | DRM_ERROR("too many retries, giving up\n"); | ||
566 | return -EIO; | ||
564 | } | 567 | } |
565 | 568 | ||
566 | /* Write a single byte to the aux channel in native mode */ | 569 | /* Write a single byte to the aux channel in native mode */ |
@@ -582,6 +585,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
582 | int reply_bytes; | 585 | int reply_bytes; |
583 | uint8_t ack; | 586 | uint8_t ack; |
584 | int ret; | 587 | int ret; |
588 | int retry; | ||
585 | 589 | ||
586 | if (WARN_ON(recv_bytes > 19)) | 590 | if (WARN_ON(recv_bytes > 19)) |
587 | return -E2BIG; | 591 | return -E2BIG; |
@@ -595,7 +599,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
595 | msg_bytes = 4; | 599 | msg_bytes = 4; |
596 | reply_bytes = recv_bytes + 1; | 600 | reply_bytes = recv_bytes + 1; |
597 | 601 | ||
598 | for (;;) { | 602 | for (retry = 0; retry < 7; retry++) { |
599 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, | 603 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
600 | reply, reply_bytes); | 604 | reply, reply_bytes); |
601 | if (ret == 0) | 605 | if (ret == 0) |
@@ -608,10 +612,13 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
608 | return ret - 1; | 612 | return ret - 1; |
609 | } | 613 | } |
610 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 614 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
611 | udelay(100); | 615 | usleep_range(400, 500); |
612 | else | 616 | else |
613 | return -EIO; | 617 | return -EIO; |
614 | } | 618 | } |
619 | |||
620 | DRM_ERROR("too many retries, giving up\n"); | ||
621 | return -EIO; | ||
615 | } | 622 | } |
616 | 623 | ||
617 | static int | 624 | static int |
@@ -1242,17 +1249,24 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1242 | 1249 | ||
1243 | DRM_DEBUG_KMS("Turn eDP power off\n"); | 1250 | DRM_DEBUG_KMS("Turn eDP power off\n"); |
1244 | 1251 | ||
1252 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | ||
1253 | |||
1245 | pp = ironlake_get_pp_control(intel_dp); | 1254 | pp = ironlake_get_pp_control(intel_dp); |
1246 | /* We need to switch off panel power _and_ force vdd, for otherwise some | 1255 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1247 | * panels get very unhappy and cease to work. */ | 1256 | * panels get very unhappy and cease to work. */ |
1248 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1257 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
1249 | 1258 | ||
1250 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); | 1259 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); |
1251 | 1260 | ||
1252 | I915_WRITE(pp_ctrl_reg, pp); | 1261 | I915_WRITE(pp_ctrl_reg, pp); |
1253 | POSTING_READ(pp_ctrl_reg); | 1262 | POSTING_READ(pp_ctrl_reg); |
1254 | 1263 | ||
1264 | intel_dp->want_panel_vdd = false; | ||
1265 | |||
1255 | ironlake_wait_panel_off(intel_dp); | 1266 | ironlake_wait_panel_off(intel_dp); |
1267 | |||
1268 | /* We got a reference when we enabled the VDD. */ | ||
1269 | intel_runtime_pm_put(dev_priv); | ||
1256 | } | 1270 | } |
1257 | 1271 | ||
1258 | void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | 1272 | void ironlake_edp_backlight_on(struct intel_dp *intel_dp) |
@@ -1632,7 +1646,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) | |||
1632 | val |= EDP_PSR_LINK_DISABLE; | 1646 | val |= EDP_PSR_LINK_DISABLE; |
1633 | 1647 | ||
1634 | I915_WRITE(EDP_PSR_CTL(dev), val | | 1648 | I915_WRITE(EDP_PSR_CTL(dev), val | |
1635 | IS_BROADWELL(dev) ? 0 : link_entry_time | | 1649 | (IS_BROADWELL(dev) ? 0 : link_entry_time) | |
1636 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | | 1650 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
1637 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | | 1651 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
1638 | EDP_PSR_ENABLE); | 1652 | EDP_PSR_ENABLE); |
@@ -1777,6 +1791,7 @@ static void intel_disable_dp(struct intel_encoder *encoder) | |||
1777 | 1791 | ||
1778 | /* Make sure the panel is off before trying to change the mode. But also | 1792 | /* Make sure the panel is off before trying to change the mode. But also |
1779 | * ensure that we have vdd while we switch off the panel. */ | 1793 | * ensure that we have vdd while we switch off the panel. */ |
1794 | ironlake_edp_panel_vdd_on(intel_dp); | ||
1780 | ironlake_edp_backlight_off(intel_dp); | 1795 | ironlake_edp_backlight_off(intel_dp); |
1781 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | 1796 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1782 | ironlake_edp_panel_off(intel_dp); | 1797 | ironlake_edp_panel_off(intel_dp); |
@@ -1869,10 +1884,12 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) | |||
1869 | 1884 | ||
1870 | mutex_unlock(&dev_priv->dpio_lock); | 1885 | mutex_unlock(&dev_priv->dpio_lock); |
1871 | 1886 | ||
1872 | /* init power sequencer on this pipe and port */ | 1887 | if (is_edp(intel_dp)) { |
1873 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); | 1888 | /* init power sequencer on this pipe and port */ |
1874 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, | 1889 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); |
1875 | &power_seq); | 1890 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, |
1891 | &power_seq); | ||
1892 | } | ||
1876 | 1893 | ||
1877 | intel_enable_dp(encoder); | 1894 | intel_enable_dp(encoder); |
1878 | 1895 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 6db0d9d17f47..ee3181ebcc92 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -845,7 +845,7 @@ static int hdmi_portclock_limit(struct intel_hdmi *hdmi) | |||
845 | { | 845 | { |
846 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); | 846 | struct drm_device *dev = intel_hdmi_to_dev(hdmi); |
847 | 847 | ||
848 | if (IS_G4X(dev)) | 848 | if (!hdmi->has_hdmi_sink || IS_G4X(dev)) |
849 | return 165000; | 849 | return 165000; |
850 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) | 850 | else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) |
851 | return 300000; | 851 | return 300000; |
@@ -899,8 +899,8 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, | |||
899 | * outputs. We also need to check that the higher clock still fits | 899 | * outputs. We also need to check that the higher clock still fits |
900 | * within limits. | 900 | * within limits. |
901 | */ | 901 | */ |
902 | if (pipe_config->pipe_bpp > 8*3 && clock_12bpc <= portclock_limit | 902 | if (pipe_config->pipe_bpp > 8*3 && intel_hdmi->has_hdmi_sink && |
903 | && HAS_PCH_SPLIT(dev)) { | 903 | clock_12bpc <= portclock_limit && HAS_PCH_SPLIT(dev)) { |
904 | DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); | 904 | DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n"); |
905 | desired_bpp = 12*3; | 905 | desired_bpp = 12*3; |
906 | 906 | ||
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index b1dc33f47899..d33b61d0dd33 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -258,13 +258,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) | |||
258 | algo->data = bus; | 258 | algo->data = bus; |
259 | } | 259 | } |
260 | 260 | ||
261 | /* | ||
262 | * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI | ||
263 | * mode. This results in spurious interrupt warnings if the legacy irq no. is | ||
264 | * shared with another device. The kernel then disables that interrupt source | ||
265 | * and so prevents the other device from working properly. | ||
266 | */ | ||
267 | #define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
268 | static int | 261 | static int |
269 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, | 262 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, |
270 | u32 gmbus2_status, | 263 | u32 gmbus2_status, |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 4e960ec7419f..acde2945eb8a 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -226,6 +226,8 @@ struct opregion_asle { | |||
226 | #define ACPI_DIGITAL_OUTPUT (3<<8) | 226 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
227 | #define ACPI_LVDS_OUTPUT (4<<8) | 227 | #define ACPI_LVDS_OUTPUT (4<<8) |
228 | 228 | ||
229 | #define MAX_DSLP 1500 | ||
230 | |||
229 | #ifdef CONFIG_ACPI | 231 | #ifdef CONFIG_ACPI |
230 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) | 232 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) |
231 | { | 233 | { |
@@ -260,10 +262,11 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) | |||
260 | /* The spec says 2ms should be the default, but it's too small | 262 | /* The spec says 2ms should be the default, but it's too small |
261 | * for some machines. */ | 263 | * for some machines. */ |
262 | dslp = 50; | 264 | dslp = 50; |
263 | } else if (dslp > 500) { | 265 | } else if (dslp > MAX_DSLP) { |
264 | /* Hey bios, trust must be earned. */ | 266 | /* Hey bios, trust must be earned. */ |
265 | WARN_ONCE(1, "excessive driver sleep timeout (DSPL) %u\n", dslp); | 267 | DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, " |
266 | dslp = 500; | 268 | "using %u ms instead\n", dslp, MAX_DSLP); |
269 | dslp = MAX_DSLP; | ||
267 | } | 270 | } |
268 | 271 | ||
269 | /* The spec tells us to do this, but we are the only user... */ | 272 | /* The spec tells us to do this, but we are the only user... */ |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 350de359123a..079ea38f14d9 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -698,7 +698,7 @@ static void i9xx_enable_backlight(struct intel_connector *connector) | |||
698 | freq /= 0xff; | 698 | freq /= 0xff; |
699 | 699 | ||
700 | ctl = freq << 17; | 700 | ctl = freq << 17; |
701 | if (IS_GEN2(dev) && panel->backlight.combination_mode) | 701 | if (panel->backlight.combination_mode) |
702 | ctl |= BLM_LEGACY_MODE; | 702 | ctl |= BLM_LEGACY_MODE; |
703 | if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm) | 703 | if (IS_PINEVIEW(dev) && panel->backlight.active_low_pwm) |
704 | ctl |= BLM_POLARITY_PNV; | 704 | ctl |= BLM_POLARITY_PNV; |
@@ -979,7 +979,7 @@ static int i9xx_setup_backlight(struct intel_connector *connector) | |||
979 | 979 | ||
980 | ctl = I915_READ(BLC_PWM_CTL); | 980 | ctl = I915_READ(BLC_PWM_CTL); |
981 | 981 | ||
982 | if (IS_GEN2(dev)) | 982 | if (IS_GEN2(dev) || IS_I915GM(dev) || IS_I945GM(dev)) |
983 | panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; | 983 | panel->backlight.combination_mode = ctl & BLM_LEGACY_MODE; |
984 | 984 | ||
985 | if (IS_PINEVIEW(dev)) | 985 | if (IS_PINEVIEW(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d77cc81900f9..e1fc35a72656 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3493,6 +3493,8 @@ static void valleyview_setup_pctx(struct drm_device *dev) | |||
3493 | u32 pcbr; | 3493 | u32 pcbr; |
3494 | int pctx_size = 24*1024; | 3494 | int pctx_size = 24*1024; |
3495 | 3495 | ||
3496 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); | ||
3497 | |||
3496 | pcbr = I915_READ(VLV_PCBR); | 3498 | pcbr = I915_READ(VLV_PCBR); |
3497 | if (pcbr) { | 3499 | if (pcbr) { |
3498 | /* BIOS set it up already, grab the pre-alloc'd space */ | 3500 | /* BIOS set it up already, grab the pre-alloc'd space */ |
@@ -3542,8 +3544,6 @@ static void valleyview_enable_rps(struct drm_device *dev) | |||
3542 | I915_WRITE(GTFIFODBG, gtfifodbg); | 3544 | I915_WRITE(GTFIFODBG, gtfifodbg); |
3543 | } | 3545 | } |
3544 | 3546 | ||
3545 | valleyview_setup_pctx(dev); | ||
3546 | |||
3547 | /* If VLV, Forcewake all wells, else re-direct to regular path */ | 3547 | /* If VLV, Forcewake all wells, else re-direct to regular path */ |
3548 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); | 3548 | gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); |
3549 | 3549 | ||
@@ -4395,6 +4395,8 @@ void intel_enable_gt_powersave(struct drm_device *dev) | |||
4395 | ironlake_enable_rc6(dev); | 4395 | ironlake_enable_rc6(dev); |
4396 | intel_init_emon(dev); | 4396 | intel_init_emon(dev); |
4397 | } else if (IS_GEN6(dev) || IS_GEN7(dev)) { | 4397 | } else if (IS_GEN6(dev) || IS_GEN7(dev)) { |
4398 | if (IS_VALLEYVIEW(dev)) | ||
4399 | valleyview_setup_pctx(dev); | ||
4398 | /* | 4400 | /* |
4399 | * PCU communication is slow and this doesn't need to be | 4401 | * PCU communication is slow and this doesn't need to be |
4400 | * done at any specific time, so do this out of our fast path | 4402 | * done at any specific time, so do this out of our fast path |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b7f1742caf87..31b36c5ac894 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -1653,6 +1653,27 @@ int intel_ring_begin(struct intel_ring_buffer *ring, | |||
1653 | return 0; | 1653 | return 0; |
1654 | } | 1654 | } |
1655 | 1655 | ||
1656 | /* Align the ring tail to a cacheline boundary */ | ||
1657 | int intel_ring_cacheline_align(struct intel_ring_buffer *ring) | ||
1658 | { | ||
1659 | int num_dwords = (64 - (ring->tail & 63)) / sizeof(uint32_t); | ||
1660 | int ret; | ||
1661 | |||
1662 | if (num_dwords == 0) | ||
1663 | return 0; | ||
1664 | |||
1665 | ret = intel_ring_begin(ring, num_dwords); | ||
1666 | if (ret) | ||
1667 | return ret; | ||
1668 | |||
1669 | while (num_dwords--) | ||
1670 | intel_ring_emit(ring, MI_NOOP); | ||
1671 | |||
1672 | intel_ring_advance(ring); | ||
1673 | |||
1674 | return 0; | ||
1675 | } | ||
1676 | |||
1656 | void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) | 1677 | void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) |
1657 | { | 1678 | { |
1658 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 1679 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 71a73f4fe252..0b243ce33714 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -233,6 +233,7 @@ intel_write_status_page(struct intel_ring_buffer *ring, | |||
233 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); | 233 | void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); |
234 | 234 | ||
235 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); | 235 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); |
236 | int __must_check intel_ring_cacheline_align(struct intel_ring_buffer *ring); | ||
236 | static inline void intel_ring_emit(struct intel_ring_buffer *ring, | 237 | static inline void intel_ring_emit(struct intel_ring_buffer *ring, |
237 | u32 data) | 238 | u32 data) |
238 | { | 239 | { |
diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c index f9adc27ef32a..13b7dd83faa9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ b/drivers/gpu/drm/mgag200/mgag200_fb.c | |||
@@ -41,7 +41,7 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev, | |||
41 | * then the BO is being moved and we should | 41 | * then the BO is being moved and we should |
42 | * store up the damage until later. | 42 | * store up the damage until later. |
43 | */ | 43 | */ |
44 | if (!drm_can_sleep()) | 44 | if (drm_can_sleep()) |
45 | ret = mgag200_bo_reserve(bo, true); | 45 | ret = mgag200_bo_reserve(bo, true); |
46 | if (ret) { | 46 | if (ret) { |
47 | if (ret != -EBUSY) | 47 | if (ret != -EBUSY) |
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index b8583f275e80..968374776db9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -1519,11 +1519,11 @@ static int mga_vga_mode_valid(struct drm_connector *connector, | |||
1519 | (mga_vga_calculate_mode_bandwidth(mode, bpp) | 1519 | (mga_vga_calculate_mode_bandwidth(mode, bpp) |
1520 | > (32700 * 1024))) { | 1520 | > (32700 * 1024))) { |
1521 | return MODE_BANDWIDTH; | 1521 | return MODE_BANDWIDTH; |
1522 | } else if (mode->type == G200_EH && | 1522 | } else if (mdev->type == G200_EH && |
1523 | (mga_vga_calculate_mode_bandwidth(mode, bpp) | 1523 | (mga_vga_calculate_mode_bandwidth(mode, bpp) |
1524 | > (37500 * 1024))) { | 1524 | > (37500 * 1024))) { |
1525 | return MODE_BANDWIDTH; | 1525 | return MODE_BANDWIDTH; |
1526 | } else if (mode->type == G200_ER && | 1526 | } else if (mdev->type == G200_ER && |
1527 | (mga_vga_calculate_mode_bandwidth(mode, | 1527 | (mga_vga_calculate_mode_bandwidth(mode, |
1528 | bpp) > (55000 * 1024))) { | 1528 | bpp) > (55000 * 1024))) { |
1529 | return MODE_BANDWIDTH; | 1529 | return MODE_BANDWIDTH; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 1964f4f0d452..84c5b13b33c9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
@@ -39,6 +39,7 @@ struct mdp4_crtc { | |||
39 | spinlock_t lock; | 39 | spinlock_t lock; |
40 | bool stale; | 40 | bool stale; |
41 | uint32_t width, height; | 41 | uint32_t width, height; |
42 | uint32_t x, y; | ||
42 | 43 | ||
43 | /* next cursor to scan-out: */ | 44 | /* next cursor to scan-out: */ |
44 | uint32_t next_iova; | 45 | uint32_t next_iova; |
@@ -57,9 +58,16 @@ struct mdp4_crtc { | |||
57 | #define PENDING_FLIP 0x2 | 58 | #define PENDING_FLIP 0x2 |
58 | atomic_t pending; | 59 | atomic_t pending; |
59 | 60 | ||
60 | /* the fb that we currently hold a scanout ref to: */ | 61 | /* the fb that we logically (from PoV of KMS API) hold a ref |
62 | * to. Which we may not yet be scanning out (we may still | ||
63 | * be scanning out previous in case of page_flip while waiting | ||
64 | * for gpu rendering to complete: | ||
65 | */ | ||
61 | struct drm_framebuffer *fb; | 66 | struct drm_framebuffer *fb; |
62 | 67 | ||
68 | /* the fb that we currently hold a scanout ref to: */ | ||
69 | struct drm_framebuffer *scanout_fb; | ||
70 | |||
63 | /* for unref'ing framebuffers after scanout completes: */ | 71 | /* for unref'ing framebuffers after scanout completes: */ |
64 | struct drm_flip_work unref_fb_work; | 72 | struct drm_flip_work unref_fb_work; |
65 | 73 | ||
@@ -77,24 +85,73 @@ static struct mdp4_kms *get_kms(struct drm_crtc *crtc) | |||
77 | return to_mdp4_kms(to_mdp_kms(priv->kms)); | 85 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
78 | } | 86 | } |
79 | 87 | ||
80 | static void update_fb(struct drm_crtc *crtc, bool async, | 88 | static void request_pending(struct drm_crtc *crtc, uint32_t pending) |
81 | struct drm_framebuffer *new_fb) | ||
82 | { | 89 | { |
83 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 90 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
84 | struct drm_framebuffer *old_fb = mdp4_crtc->fb; | ||
85 | 91 | ||
86 | if (old_fb) | 92 | atomic_or(pending, &mdp4_crtc->pending); |
87 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb); | 93 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); |
94 | } | ||
95 | |||
96 | static void crtc_flush(struct drm_crtc *crtc) | ||
97 | { | ||
98 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
99 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
100 | uint32_t i, flush = 0; | ||
101 | |||
102 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { | ||
103 | struct drm_plane *plane = mdp4_crtc->planes[i]; | ||
104 | if (plane) { | ||
105 | enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); | ||
106 | flush |= pipe2flush(pipe_id); | ||
107 | } | ||
108 | } | ||
109 | flush |= ovlp2flush(mdp4_crtc->ovlp); | ||
110 | |||
111 | DBG("%s: flush=%08x", mdp4_crtc->name, flush); | ||
112 | |||
113 | mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush); | ||
114 | } | ||
115 | |||
116 | static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) | ||
117 | { | ||
118 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
119 | struct drm_framebuffer *old_fb = mdp4_crtc->fb; | ||
88 | 120 | ||
89 | /* grab reference to incoming scanout fb: */ | 121 | /* grab reference to incoming scanout fb: */ |
90 | drm_framebuffer_reference(new_fb); | 122 | drm_framebuffer_reference(new_fb); |
91 | mdp4_crtc->base.fb = new_fb; | 123 | mdp4_crtc->base.fb = new_fb; |
92 | mdp4_crtc->fb = new_fb; | 124 | mdp4_crtc->fb = new_fb; |
93 | 125 | ||
94 | if (!async) { | 126 | if (old_fb) |
95 | /* enable vblank to pick up the old_fb */ | 127 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb); |
96 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); | 128 | } |
97 | } | 129 | |
130 | /* unlike update_fb(), take a ref to the new scanout fb *before* updating | ||
131 | * plane, then call this. Needed to ensure we don't unref the buffer that | ||
132 | * is actually still being scanned out. | ||
133 | * | ||
134 | * Note that this whole thing goes away with atomic.. since we can defer | ||
135 | * calling into driver until rendering is done. | ||
136 | */ | ||
137 | static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) | ||
138 | { | ||
139 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
140 | |||
141 | /* flush updates, to make sure hw is updated to new scanout fb, | ||
142 | * so that we can safely queue unref to current fb (ie. next | ||
143 | * vblank we know hw is done w/ previous scanout_fb). | ||
144 | */ | ||
145 | crtc_flush(crtc); | ||
146 | |||
147 | if (mdp4_crtc->scanout_fb) | ||
148 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, | ||
149 | mdp4_crtc->scanout_fb); | ||
150 | |||
151 | mdp4_crtc->scanout_fb = fb; | ||
152 | |||
153 | /* enable vblank to complete flip: */ | ||
154 | request_pending(crtc, PENDING_FLIP); | ||
98 | } | 155 | } |
99 | 156 | ||
100 | /* if file!=NULL, this is preclose potential cancel-flip path */ | 157 | /* if file!=NULL, this is preclose potential cancel-flip path */ |
@@ -120,34 +177,6 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
120 | spin_unlock_irqrestore(&dev->event_lock, flags); | 177 | spin_unlock_irqrestore(&dev->event_lock, flags); |
121 | } | 178 | } |
122 | 179 | ||
123 | static void crtc_flush(struct drm_crtc *crtc) | ||
124 | { | ||
125 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
126 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
127 | uint32_t i, flush = 0; | ||
128 | |||
129 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { | ||
130 | struct drm_plane *plane = mdp4_crtc->planes[i]; | ||
131 | if (plane) { | ||
132 | enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); | ||
133 | flush |= pipe2flush(pipe_id); | ||
134 | } | ||
135 | } | ||
136 | flush |= ovlp2flush(mdp4_crtc->ovlp); | ||
137 | |||
138 | DBG("%s: flush=%08x", mdp4_crtc->name, flush); | ||
139 | |||
140 | mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush); | ||
141 | } | ||
142 | |||
143 | static void request_pending(struct drm_crtc *crtc, uint32_t pending) | ||
144 | { | ||
145 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
146 | |||
147 | atomic_or(pending, &mdp4_crtc->pending); | ||
148 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); | ||
149 | } | ||
150 | |||
151 | static void pageflip_cb(struct msm_fence_cb *cb) | 180 | static void pageflip_cb(struct msm_fence_cb *cb) |
152 | { | 181 | { |
153 | struct mdp4_crtc *mdp4_crtc = | 182 | struct mdp4_crtc *mdp4_crtc = |
@@ -158,11 +187,9 @@ static void pageflip_cb(struct msm_fence_cb *cb) | |||
158 | if (!fb) | 187 | if (!fb) |
159 | return; | 188 | return; |
160 | 189 | ||
190 | drm_framebuffer_reference(fb); | ||
161 | mdp4_plane_set_scanout(mdp4_crtc->plane, fb); | 191 | mdp4_plane_set_scanout(mdp4_crtc->plane, fb); |
162 | crtc_flush(crtc); | 192 | update_scanout(crtc, fb); |
163 | |||
164 | /* enable vblank to complete flip: */ | ||
165 | request_pending(crtc, PENDING_FLIP); | ||
166 | } | 193 | } |
167 | 194 | ||
168 | static void unref_fb_worker(struct drm_flip_work *work, void *val) | 195 | static void unref_fb_worker(struct drm_flip_work *work, void *val) |
@@ -320,6 +347,20 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, | |||
320 | mode->vsync_end, mode->vtotal, | 347 | mode->vsync_end, mode->vtotal, |
321 | mode->type, mode->flags); | 348 | mode->type, mode->flags); |
322 | 349 | ||
350 | /* grab extra ref for update_scanout() */ | ||
351 | drm_framebuffer_reference(crtc->fb); | ||
352 | |||
353 | ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, | ||
354 | 0, 0, mode->hdisplay, mode->vdisplay, | ||
355 | x << 16, y << 16, | ||
356 | mode->hdisplay << 16, mode->vdisplay << 16); | ||
357 | if (ret) { | ||
358 | drm_framebuffer_unreference(crtc->fb); | ||
359 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | ||
360 | mdp4_crtc->name, ret); | ||
361 | return ret; | ||
362 | } | ||
363 | |||
323 | mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), | 364 | mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), |
324 | MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | | 365 | MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | |
325 | MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); | 366 | MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); |
@@ -341,24 +382,15 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, | |||
341 | 382 | ||
342 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); | 383 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); |
343 | 384 | ||
344 | update_fb(crtc, false, crtc->fb); | ||
345 | |||
346 | ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, | ||
347 | 0, 0, mode->hdisplay, mode->vdisplay, | ||
348 | x << 16, y << 16, | ||
349 | mode->hdisplay << 16, mode->vdisplay << 16); | ||
350 | if (ret) { | ||
351 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | ||
352 | mdp4_crtc->name, ret); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | if (dma == DMA_E) { | 385 | if (dma == DMA_E) { |
357 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000); | 386 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000); |
358 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); | 387 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); |
359 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); | 388 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); |
360 | } | 389 | } |
361 | 390 | ||
391 | update_fb(crtc, crtc->fb); | ||
392 | update_scanout(crtc, crtc->fb); | ||
393 | |||
362 | return 0; | 394 | return 0; |
363 | } | 395 | } |
364 | 396 | ||
@@ -385,13 +417,24 @@ static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
385 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 417 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
386 | struct drm_plane *plane = mdp4_crtc->plane; | 418 | struct drm_plane *plane = mdp4_crtc->plane; |
387 | struct drm_display_mode *mode = &crtc->mode; | 419 | struct drm_display_mode *mode = &crtc->mode; |
420 | int ret; | ||
388 | 421 | ||
389 | update_fb(crtc, false, crtc->fb); | 422 | /* grab extra ref for update_scanout() */ |
423 | drm_framebuffer_reference(crtc->fb); | ||
390 | 424 | ||
391 | return mdp4_plane_mode_set(plane, crtc, crtc->fb, | 425 | ret = mdp4_plane_mode_set(plane, crtc, crtc->fb, |
392 | 0, 0, mode->hdisplay, mode->vdisplay, | 426 | 0, 0, mode->hdisplay, mode->vdisplay, |
393 | x << 16, y << 16, | 427 | x << 16, y << 16, |
394 | mode->hdisplay << 16, mode->vdisplay << 16); | 428 | mode->hdisplay << 16, mode->vdisplay << 16); |
429 | if (ret) { | ||
430 | drm_framebuffer_unreference(crtc->fb); | ||
431 | return ret; | ||
432 | } | ||
433 | |||
434 | update_fb(crtc, crtc->fb); | ||
435 | update_scanout(crtc, crtc->fb); | ||
436 | |||
437 | return 0; | ||
395 | } | 438 | } |
396 | 439 | ||
397 | static void mdp4_crtc_load_lut(struct drm_crtc *crtc) | 440 | static void mdp4_crtc_load_lut(struct drm_crtc *crtc) |
@@ -419,7 +462,7 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc, | |||
419 | mdp4_crtc->event = event; | 462 | mdp4_crtc->event = event; |
420 | spin_unlock_irqrestore(&dev->event_lock, flags); | 463 | spin_unlock_irqrestore(&dev->event_lock, flags); |
421 | 464 | ||
422 | update_fb(crtc, true, new_fb); | 465 | update_fb(crtc, new_fb); |
423 | 466 | ||
424 | return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); | 467 | return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); |
425 | } | 468 | } |
@@ -442,12 +485,12 @@ static int mdp4_crtc_set_property(struct drm_crtc *crtc, | |||
442 | static void update_cursor(struct drm_crtc *crtc) | 485 | static void update_cursor(struct drm_crtc *crtc) |
443 | { | 486 | { |
444 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 487 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
488 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
445 | enum mdp4_dma dma = mdp4_crtc->dma; | 489 | enum mdp4_dma dma = mdp4_crtc->dma; |
446 | unsigned long flags; | 490 | unsigned long flags; |
447 | 491 | ||
448 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); | 492 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); |
449 | if (mdp4_crtc->cursor.stale) { | 493 | if (mdp4_crtc->cursor.stale) { |
450 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
451 | struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; | 494 | struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; |
452 | struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; | 495 | struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; |
453 | uint32_t iova = mdp4_crtc->cursor.next_iova; | 496 | uint32_t iova = mdp4_crtc->cursor.next_iova; |
@@ -479,6 +522,11 @@ static void update_cursor(struct drm_crtc *crtc) | |||
479 | mdp4_crtc->cursor.scanout_bo = next_bo; | 522 | mdp4_crtc->cursor.scanout_bo = next_bo; |
480 | mdp4_crtc->cursor.stale = false; | 523 | mdp4_crtc->cursor.stale = false; |
481 | } | 524 | } |
525 | |||
526 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), | ||
527 | MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) | | ||
528 | MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y)); | ||
529 | |||
482 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); | 530 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); |
483 | } | 531 | } |
484 | 532 | ||
@@ -530,6 +578,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, | |||
530 | drm_gem_object_unreference_unlocked(old_bo); | 578 | drm_gem_object_unreference_unlocked(old_bo); |
531 | } | 579 | } |
532 | 580 | ||
581 | crtc_flush(crtc); | ||
533 | request_pending(crtc, PENDING_CURSOR); | 582 | request_pending(crtc, PENDING_CURSOR); |
534 | 583 | ||
535 | return 0; | 584 | return 0; |
@@ -542,12 +591,15 @@ fail: | |||
542 | static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 591 | static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) |
543 | { | 592 | { |
544 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 593 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
545 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | 594 | unsigned long flags; |
546 | enum mdp4_dma dma = mdp4_crtc->dma; | ||
547 | 595 | ||
548 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), | 596 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); |
549 | MDP4_DMA_CURSOR_POS_X(x) | | 597 | mdp4_crtc->cursor.x = x; |
550 | MDP4_DMA_CURSOR_POS_Y(y)); | 598 | mdp4_crtc->cursor.y = y; |
599 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); | ||
600 | |||
601 | crtc_flush(crtc); | ||
602 | request_pending(crtc, PENDING_CURSOR); | ||
551 | 603 | ||
552 | return 0; | 604 | return 0; |
553 | } | 605 | } |
@@ -713,6 +765,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, | |||
713 | crtc = &mdp4_crtc->base; | 765 | crtc = &mdp4_crtc->base; |
714 | 766 | ||
715 | mdp4_crtc->plane = plane; | 767 | mdp4_crtc->plane = plane; |
768 | mdp4_crtc->id = id; | ||
716 | 769 | ||
717 | mdp4_crtc->ovlp = ovlp_id; | 770 | mdp4_crtc->ovlp = ovlp_id; |
718 | mdp4_crtc->dma = dma_id; | 771 | mdp4_crtc->dma = dma_id; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 2406027200ec..1e893dd13859 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | |||
@@ -170,8 +170,8 @@ int mdp4_plane_mode_set(struct drm_plane *plane, | |||
170 | MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h)); | 170 | MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h)); |
171 | 171 | ||
172 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe), | 172 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe), |
173 | MDP4_PIPE_SRC_XY_X(crtc_x) | | 173 | MDP4_PIPE_DST_XY_X(crtc_x) | |
174 | MDP4_PIPE_SRC_XY_Y(crtc_y)); | 174 | MDP4_PIPE_DST_XY_Y(crtc_y)); |
175 | 175 | ||
176 | mdp4_plane_set_scanout(plane, fb); | 176 | mdp4_plane_set_scanout(plane, fb); |
177 | 177 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 71a3b2345eb3..f2794021f086 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
@@ -296,6 +296,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, | |||
296 | x << 16, y << 16, | 296 | x << 16, y << 16, |
297 | mode->hdisplay << 16, mode->vdisplay << 16); | 297 | mode->hdisplay << 16, mode->vdisplay << 16); |
298 | if (ret) { | 298 | if (ret) { |
299 | drm_framebuffer_unreference(crtc->fb); | ||
299 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | 300 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", |
300 | mdp5_crtc->name, ret); | 301 | mdp5_crtc->name, ret); |
301 | return ret; | 302 | return ret; |
@@ -343,11 +344,15 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
343 | 0, 0, mode->hdisplay, mode->vdisplay, | 344 | 0, 0, mode->hdisplay, mode->vdisplay, |
344 | x << 16, y << 16, | 345 | x << 16, y << 16, |
345 | mode->hdisplay << 16, mode->vdisplay << 16); | 346 | mode->hdisplay << 16, mode->vdisplay << 16); |
347 | if (ret) { | ||
348 | drm_framebuffer_unreference(crtc->fb); | ||
349 | return ret; | ||
350 | } | ||
346 | 351 | ||
347 | update_fb(crtc, crtc->fb); | 352 | update_fb(crtc, crtc->fb); |
348 | update_scanout(crtc, crtc->fb); | 353 | update_scanout(crtc, crtc->fb); |
349 | 354 | ||
350 | return ret; | 355 | return 0; |
351 | } | 356 | } |
352 | 357 | ||
353 | static void mdp5_crtc_load_lut(struct drm_crtc *crtc) | 358 | static void mdp5_crtc_load_lut(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index d8d60c969ac7..3da8264d3039 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -644,7 +644,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, | |||
644 | 644 | ||
645 | fail: | 645 | fail: |
646 | if (obj) | 646 | if (obj) |
647 | drm_gem_object_unreference_unlocked(obj); | 647 | drm_gem_object_unreference(obj); |
648 | 648 | ||
649 | return ERR_PTR(ret); | 649 | return ERR_PTR(ret); |
650 | } | 650 | } |
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 5281d4bc37f7..5423e914e491 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
@@ -163,7 +163,7 @@ retry: | |||
163 | 163 | ||
164 | 164 | ||
165 | /* if locking succeeded, pin bo: */ | 165 | /* if locking succeeded, pin bo: */ |
166 | ret = msm_gem_get_iova(&msm_obj->base, | 166 | ret = msm_gem_get_iova_locked(&msm_obj->base, |
167 | submit->gpu->id, &iova); | 167 | submit->gpu->id, &iova); |
168 | 168 | ||
169 | /* this would break the logic in the fail path.. there is no | 169 | /* this would break the logic in the fail path.. there is no |
@@ -247,7 +247,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob | |||
247 | /* For now, just map the entire thing. Eventually we probably | 247 | /* For now, just map the entire thing. Eventually we probably |
248 | * to do it page-by-page, w/ kmap() if not vmap()d.. | 248 | * to do it page-by-page, w/ kmap() if not vmap()d.. |
249 | */ | 249 | */ |
250 | ptr = msm_gem_vaddr(&obj->base); | 250 | ptr = msm_gem_vaddr_locked(&obj->base); |
251 | 251 | ||
252 | if (IS_ERR(ptr)) { | 252 | if (IS_ERR(ptr)) { |
253 | ret = PTR_ERR(ptr); | 253 | ret = PTR_ERR(ptr); |
@@ -307,14 +307,12 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool fail) | |||
307 | { | 307 | { |
308 | unsigned i; | 308 | unsigned i; |
309 | 309 | ||
310 | mutex_lock(&submit->dev->struct_mutex); | ||
311 | for (i = 0; i < submit->nr_bos; i++) { | 310 | for (i = 0; i < submit->nr_bos; i++) { |
312 | struct msm_gem_object *msm_obj = submit->bos[i].obj; | 311 | struct msm_gem_object *msm_obj = submit->bos[i].obj; |
313 | submit_unlock_unpin_bo(submit, i); | 312 | submit_unlock_unpin_bo(submit, i); |
314 | list_del_init(&msm_obj->submit_entry); | 313 | list_del_init(&msm_obj->submit_entry); |
315 | drm_gem_object_unreference(&msm_obj->base); | 314 | drm_gem_object_unreference(&msm_obj->base); |
316 | } | 315 | } |
317 | mutex_unlock(&submit->dev->struct_mutex); | ||
318 | 316 | ||
319 | ww_acquire_fini(&submit->ticket); | 317 | ww_acquire_fini(&submit->ticket); |
320 | kfree(submit); | 318 | kfree(submit); |
@@ -342,6 +340,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
342 | if (args->nr_cmds > MAX_CMDS) | 340 | if (args->nr_cmds > MAX_CMDS) |
343 | return -EINVAL; | 341 | return -EINVAL; |
344 | 342 | ||
343 | mutex_lock(&dev->struct_mutex); | ||
344 | |||
345 | submit = submit_create(dev, gpu, args->nr_bos); | 345 | submit = submit_create(dev, gpu, args->nr_bos); |
346 | if (!submit) { | 346 | if (!submit) { |
347 | ret = -ENOMEM; | 347 | ret = -ENOMEM; |
@@ -410,5 +410,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
410 | out: | 410 | out: |
411 | if (submit) | 411 | if (submit) |
412 | submit_cleanup(submit, !!ret); | 412 | submit_cleanup(submit, !!ret); |
413 | mutex_unlock(&dev->struct_mutex); | ||
413 | return ret; | 414 | return ret; |
414 | } | 415 | } |
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 4ebce8be489d..0cfe3f426ee4 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c | |||
@@ -298,8 +298,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | |||
298 | struct msm_drm_private *priv = dev->dev_private; | 298 | struct msm_drm_private *priv = dev->dev_private; |
299 | int i, ret; | 299 | int i, ret; |
300 | 300 | ||
301 | mutex_lock(&dev->struct_mutex); | ||
302 | |||
303 | submit->fence = ++priv->next_fence; | 301 | submit->fence = ++priv->next_fence; |
304 | 302 | ||
305 | gpu->submitted_fence = submit->fence; | 303 | gpu->submitted_fence = submit->fence; |
@@ -331,7 +329,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | |||
331 | msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); | 329 | msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); |
332 | } | 330 | } |
333 | hangcheck_timer_reset(gpu); | 331 | hangcheck_timer_reset(gpu); |
334 | mutex_unlock(&dev->struct_mutex); | ||
335 | 332 | ||
336 | return ret; | 333 | return ret; |
337 | } | 334 | } |
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e88145ba1bf5..d310c195bdfe 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -141,6 +141,7 @@ nouveau-y += core/subdev/mc/base.o | |||
141 | nouveau-y += core/subdev/mc/nv04.o | 141 | nouveau-y += core/subdev/mc/nv04.o |
142 | nouveau-y += core/subdev/mc/nv40.o | 142 | nouveau-y += core/subdev/mc/nv40.o |
143 | nouveau-y += core/subdev/mc/nv44.o | 143 | nouveau-y += core/subdev/mc/nv44.o |
144 | nouveau-y += core/subdev/mc/nv4c.o | ||
144 | nouveau-y += core/subdev/mc/nv50.o | 145 | nouveau-y += core/subdev/mc/nv50.o |
145 | nouveau-y += core/subdev/mc/nv94.o | 146 | nouveau-y += core/subdev/mc/nv94.o |
146 | nouveau-y += core/subdev/mc/nv98.o | 147 | nouveau-y += core/subdev/mc/nv98.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 1b653dd74a70..08b88591ed60 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c | |||
@@ -311,7 +311,7 @@ nv40_identify(struct nouveau_device *device) | |||
311 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 311 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
312 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 312 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
313 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 313 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
314 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 314 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
315 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 315 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
316 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 316 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
317 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 317 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -334,7 +334,7 @@ nv40_identify(struct nouveau_device *device) | |||
334 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 334 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
335 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 335 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
336 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 336 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
337 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 337 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
338 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 338 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
339 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 339 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
340 | device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; | 340 | device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; |
@@ -357,7 +357,7 @@ nv40_identify(struct nouveau_device *device) | |||
357 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 357 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
358 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 358 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
359 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 359 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
360 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 360 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
361 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 361 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
362 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 362 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
363 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 363 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -380,7 +380,7 @@ nv40_identify(struct nouveau_device *device) | |||
380 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 380 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
381 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 381 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
382 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 382 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
383 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 383 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
384 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 384 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
385 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 385 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
386 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 386 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
@@ -403,7 +403,7 @@ nv40_identify(struct nouveau_device *device) | |||
403 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; | 403 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; |
404 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; | 404 | device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; |
405 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; | 405 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; |
406 | device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; | 406 | device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; |
407 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; | 407 | device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; |
408 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | 408 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; |
409 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; | 409 | device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 940eaa5d8b9a..9ad722e4e087 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -1142,7 +1142,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) | |||
1142 | if (conf != ~0) { | 1142 | if (conf != ~0) { |
1143 | if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { | 1143 | if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { |
1144 | u32 soff = (ffs(outp.or) - 1) * 0x08; | 1144 | u32 soff = (ffs(outp.or) - 1) * 0x08; |
1145 | u32 ctrl = nv_rd32(priv, 0x610798 + soff); | 1145 | u32 ctrl = nv_rd32(priv, 0x610794 + soff); |
1146 | u32 datarate; | 1146 | u32 datarate; |
1147 | 1147 | ||
1148 | switch ((ctrl & 0x000f0000) >> 16) { | 1148 | switch ((ctrl & 0x000f0000) >> 16) { |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 9a850fe19515..54c1b5b471cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
@@ -112,7 +112,7 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
112 | 112 | ||
113 | nv_wr32(priv, 0x002270, cur->addr >> 12); | 113 | nv_wr32(priv, 0x002270, cur->addr >> 12); |
114 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); | 114 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); |
115 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) | 115 | if (!nv_wait(priv, 0x002284 + (engine * 8), 0x00100000, 0x00000000)) |
116 | nv_error(priv, "runlist %d update timeout\n", engine); | 116 | nv_error(priv, "runlist %d update timeout\n", engine); |
117 | mutex_unlock(&nv_subdev(priv)->mutex); | 117 | mutex_unlock(&nv_subdev(priv)->mutex); |
118 | } | 118 | } |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index 30ed19c52e05..7a367c402978 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c | |||
@@ -539,7 +539,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, | |||
539 | ustatus &= ~0x04030000; | 539 | ustatus &= ~0x04030000; |
540 | } | 540 | } |
541 | if (ustatus && display) { | 541 | if (ustatus && display) { |
542 | nv_error("%s - TP%d:", name, i); | 542 | nv_error(priv, "%s - TP%d:", name, i); |
543 | nouveau_bitfield_print(nv50_mpc_traps, ustatus); | 543 | nouveau_bitfield_print(nv50_mpc_traps, ustatus); |
544 | pr_cont("\n"); | 544 | pr_cont("\n"); |
545 | ustatus = 0; | 545 | ustatus = 0; |
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index adc88b73d911..3c6738edd127 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h | |||
@@ -47,6 +47,7 @@ struct nouveau_mc_oclass { | |||
47 | extern struct nouveau_oclass *nv04_mc_oclass; | 47 | extern struct nouveau_oclass *nv04_mc_oclass; |
48 | extern struct nouveau_oclass *nv40_mc_oclass; | 48 | extern struct nouveau_oclass *nv40_mc_oclass; |
49 | extern struct nouveau_oclass *nv44_mc_oclass; | 49 | extern struct nouveau_oclass *nv44_mc_oclass; |
50 | extern struct nouveau_oclass *nv4c_mc_oclass; | ||
50 | extern struct nouveau_oclass *nv50_mc_oclass; | 51 | extern struct nouveau_oclass *nv50_mc_oclass; |
51 | extern struct nouveau_oclass *nv94_mc_oclass; | 52 | extern struct nouveau_oclass *nv94_mc_oclass; |
52 | extern struct nouveau_oclass *nv98_mc_oclass; | 53 | extern struct nouveau_oclass *nv98_mc_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index aa0fbbec7f08..ef0c9c4a8cc3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
@@ -130,6 +130,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
130 | u16 pcir; | 130 | u16 pcir; |
131 | int i; | 131 | int i; |
132 | 132 | ||
133 | /* there is no prom on nv4x IGP's */ | ||
134 | if (device->card_type == NV_40 && device->chipset >= 0x4c) | ||
135 | return; | ||
136 | |||
133 | /* enable access to rom */ | 137 | /* enable access to rom */ |
134 | if (device->card_type >= NV_50) | 138 | if (device->card_type >= NV_50) |
135 | pcireg = 0x088050; | 139 | pcireg = 0x088050; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c index 9159a5ccee93..265d1253624a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c | |||
@@ -36,7 +36,7 @@ nv1a_fb_oclass = &(struct nv04_fb_impl) { | |||
36 | .fini = _nouveau_fb_fini, | 36 | .fini = _nouveau_fb_fini, |
37 | }, | 37 | }, |
38 | .base.memtype = nv04_fb_memtype_valid, | 38 | .base.memtype = nv04_fb_memtype_valid, |
39 | .base.ram = &nv10_ram_oclass, | 39 | .base.ram = &nv1a_ram_oclass, |
40 | .tile.regions = 8, | 40 | .tile.regions = 8, |
41 | .tile.init = nv10_fb_tile_init, | 41 | .tile.init = nv10_fb_tile_init, |
42 | .tile.fini = nv10_fb_tile_fini, | 42 | .tile.fini = nv10_fb_tile_fini, |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h index b0d5c31606c1..81a408e7d034 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h | |||
@@ -14,6 +14,7 @@ int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *, | |||
14 | extern const struct nouveau_mc_intr nv04_mc_intr[]; | 14 | extern const struct nouveau_mc_intr nv04_mc_intr[]; |
15 | int nv04_mc_init(struct nouveau_object *); | 15 | int nv04_mc_init(struct nouveau_object *); |
16 | void nv40_mc_msi_rearm(struct nouveau_mc *); | 16 | void nv40_mc_msi_rearm(struct nouveau_mc *); |
17 | int nv44_mc_init(struct nouveau_object *object); | ||
17 | int nv50_mc_init(struct nouveau_object *); | 18 | int nv50_mc_init(struct nouveau_object *); |
18 | extern const struct nouveau_mc_intr nv50_mc_intr[]; | 19 | extern const struct nouveau_mc_intr nv50_mc_intr[]; |
19 | extern const struct nouveau_mc_intr nvc0_mc_intr[]; | 20 | extern const struct nouveau_mc_intr nvc0_mc_intr[]; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 3bfee5c6c4f2..cc4d0d2d886e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include "nv04.h" | 25 | #include "nv04.h" |
26 | 26 | ||
27 | static int | 27 | int |
28 | nv44_mc_init(struct nouveau_object *object) | 28 | nv44_mc_init(struct nouveau_object *object) |
29 | { | 29 | { |
30 | struct nv04_mc_priv *priv = (void *)object; | 30 | struct nv04_mc_priv *priv = (void *)object; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c new file mode 100644 index 000000000000..a75c35ccf25c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Ilia Mirkin | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ilia Mirkin | ||
23 | */ | ||
24 | |||
25 | #include "nv04.h" | ||
26 | |||
27 | static void | ||
28 | nv4c_mc_msi_rearm(struct nouveau_mc *pmc) | ||
29 | { | ||
30 | struct nv04_mc_priv *priv = (void *)pmc; | ||
31 | nv_wr08(priv, 0x088050, 0xff); | ||
32 | } | ||
33 | |||
34 | struct nouveau_oclass * | ||
35 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | ||
36 | .base.handle = NV_SUBDEV(MC, 0x4c), | ||
37 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
38 | .ctor = nv04_mc_ctor, | ||
39 | .dtor = _nouveau_mc_dtor, | ||
40 | .init = nv44_mc_init, | ||
41 | .fini = _nouveau_mc_fini, | ||
42 | }, | ||
43 | .intr = nv04_mc_intr, | ||
44 | .msi_rearm = nv4c_mc_msi_rearm, | ||
45 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 4ef83df2b246..83face3f608f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -106,6 +106,29 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * | |||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | 108 | ||
109 | /* | ||
110 | * On some platforms, _DSM(nouveau_op_dsm_muid, func0) has special | ||
111 | * requirements on the fourth parameter, so a private implementation | ||
112 | * instead of using acpi_check_dsm(). | ||
113 | */ | ||
114 | static int nouveau_check_optimus_dsm(acpi_handle handle) | ||
115 | { | ||
116 | int result; | ||
117 | |||
118 | /* | ||
119 | * Function 0 returns a Buffer containing available functions. | ||
120 | * The args parameter is ignored for function 0, so just put 0 in it | ||
121 | */ | ||
122 | if (nouveau_optimus_dsm(handle, 0, 0, &result)) | ||
123 | return 0; | ||
124 | |||
125 | /* | ||
126 | * ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. | ||
127 | * If the n-th bit is enabled, function n is supported | ||
128 | */ | ||
129 | return result & 1 && result & (1 << NOUVEAU_DSM_OPTIMUS_CAPS); | ||
130 | } | ||
131 | |||
109 | static int nouveau_dsm(acpi_handle handle, int func, int arg) | 132 | static int nouveau_dsm(acpi_handle handle, int func, int arg) |
110 | { | 133 | { |
111 | int ret = 0; | 134 | int ret = 0; |
@@ -207,8 +230,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
207 | 1 << NOUVEAU_DSM_POWER)) | 230 | 1 << NOUVEAU_DSM_POWER)) |
208 | retval |= NOUVEAU_DSM_HAS_MUX; | 231 | retval |= NOUVEAU_DSM_HAS_MUX; |
209 | 232 | ||
210 | if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100, | 233 | if (nouveau_check_optimus_dsm(dhandle)) |
211 | 1 << NOUVEAU_DSM_OPTIMUS_CAPS)) | ||
212 | retval |= NOUVEAU_DSM_HAS_OPT; | 234 | retval |= NOUVEAU_DSM_HAS_OPT; |
213 | 235 | ||
214 | if (retval & NOUVEAU_DSM_HAS_OPT) { | 236 | if (retval & NOUVEAU_DSM_HAS_OPT) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 488686d490c0..4aed1714b9ab 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1249,7 +1249,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) | |||
1249 | mem->bus.is_iomem = !dev->agp->cant_use_aperture; | 1249 | mem->bus.is_iomem = !dev->agp->cant_use_aperture; |
1250 | } | 1250 | } |
1251 | #endif | 1251 | #endif |
1252 | if (!node->memtype) | 1252 | if (nv_device(drm->device)->card_type < NV_50 || !node->memtype) |
1253 | /* untiled */ | 1253 | /* untiled */ |
1254 | break; | 1254 | break; |
1255 | /* fallthrough, tiled memory */ | 1255 | /* fallthrough, tiled memory */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 78c8e7146d56..89c484d8ac26 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -376,6 +376,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) | |||
376 | if (ret) | 376 | if (ret) |
377 | goto fail_device; | 377 | goto fail_device; |
378 | 378 | ||
379 | dev->irq_enabled = true; | ||
380 | |||
379 | /* workaround an odd issue on nvc1 by disabling the device's | 381 | /* workaround an odd issue on nvc1 by disabling the device's |
380 | * nosnoop capability. hopefully won't cause issues until a | 382 | * nosnoop capability. hopefully won't cause issues until a |
381 | * better fix is found - assuming there is one... | 383 | * better fix is found - assuming there is one... |
@@ -475,6 +477,7 @@ nouveau_drm_remove(struct pci_dev *pdev) | |||
475 | struct nouveau_drm *drm = nouveau_drm(dev); | 477 | struct nouveau_drm *drm = nouveau_drm(dev); |
476 | struct nouveau_object *device; | 478 | struct nouveau_object *device; |
477 | 479 | ||
480 | dev->irq_enabled = false; | ||
478 | device = drm->client.base.device; | 481 | device = drm->client.base.device; |
479 | drm_put_dev(dev); | 482 | drm_put_dev(dev); |
480 | 483 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 81638d7f2eff..471347edc27e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c | |||
@@ -14,7 +14,9 @@ nouveau_vga_set_decode(void *priv, bool state) | |||
14 | { | 14 | { |
15 | struct nouveau_device *device = nouveau_dev(priv); | 15 | struct nouveau_device *device = nouveau_dev(priv); |
16 | 16 | ||
17 | if (device->chipset >= 0x40) | 17 | if (device->card_type == NV_40 && device->chipset >= 0x4c) |
18 | nv_wr32(device, 0x088060, state); | ||
19 | else if (device->chipset >= 0x40) | ||
18 | nv_wr32(device, 0x088054, state); | 20 | nv_wr32(device, 0x088054, state); |
19 | else | 21 | else |
20 | nv_wr32(device, 0x001854, state); | 22 | nv_wr32(device, 0x001854, state); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index a9338c85630f..daa4dd375ab1 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -559,7 +559,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
559 | u32 adjusted_clock = mode->clock; | 559 | u32 adjusted_clock = mode->clock; |
560 | int encoder_mode = atombios_get_encoder_mode(encoder); | 560 | int encoder_mode = atombios_get_encoder_mode(encoder); |
561 | u32 dp_clock = mode->clock; | 561 | u32 dp_clock = mode->clock; |
562 | int bpc = radeon_get_monitor_bpc(connector); | 562 | int bpc = radeon_crtc->bpc; |
563 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | 563 | bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); |
564 | 564 | ||
565 | /* reset the pll flags */ | 565 | /* reset the pll flags */ |
@@ -1176,7 +1176,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1176 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); | 1176 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); |
1177 | 1177 | ||
1178 | /* Set NUM_BANKS. */ | 1178 | /* Set NUM_BANKS. */ |
1179 | if (rdev->family >= CHIP_BONAIRE) { | 1179 | if (rdev->family >= CHIP_TAHITI) { |
1180 | unsigned tileb, index, num_banks, tile_split_bytes; | 1180 | unsigned tileb, index, num_banks, tile_split_bytes; |
1181 | 1181 | ||
1182 | /* Calculate the macrotile mode index. */ | 1182 | /* Calculate the macrotile mode index. */ |
@@ -1194,13 +1194,14 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1194 | return -EINVAL; | 1194 | return -EINVAL; |
1195 | } | 1195 | } |
1196 | 1196 | ||
1197 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | 1197 | if (rdev->family >= CHIP_BONAIRE) |
1198 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | ||
1199 | else | ||
1200 | num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3; | ||
1198 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); | 1201 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); |
1199 | } else { | 1202 | } else { |
1200 | /* SI and older. */ | 1203 | /* NI and older. */ |
1201 | if (rdev->family >= CHIP_TAHITI) | 1204 | if (rdev->family >= CHIP_CAYMAN) |
1202 | tmp = rdev->config.si.tile_config; | ||
1203 | else if (rdev->family >= CHIP_CAYMAN) | ||
1204 | tmp = rdev->config.cayman.tile_config; | 1205 | tmp = rdev->config.cayman.tile_config; |
1205 | else | 1206 | else |
1206 | tmp = rdev->config.evergreen.tile_config; | 1207 | tmp = rdev->config.evergreen.tile_config; |
@@ -1773,6 +1774,20 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1773 | return ATOM_PPLL1; | 1774 | return ATOM_PPLL1; |
1774 | DRM_ERROR("unable to allocate a PPLL\n"); | 1775 | DRM_ERROR("unable to allocate a PPLL\n"); |
1775 | return ATOM_PPLL_INVALID; | 1776 | return ATOM_PPLL_INVALID; |
1777 | } else if (ASIC_IS_DCE41(rdev)) { | ||
1778 | /* Don't share PLLs on DCE4.1 chips */ | ||
1779 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | ||
1780 | if (rdev->clock.dp_extclk) | ||
1781 | /* skip PPLL programming if using ext clock */ | ||
1782 | return ATOM_PPLL_INVALID; | ||
1783 | } | ||
1784 | pll_in_use = radeon_get_pll_use_mask(crtc); | ||
1785 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | ||
1786 | return ATOM_PPLL1; | ||
1787 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | ||
1788 | return ATOM_PPLL2; | ||
1789 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1790 | return ATOM_PPLL_INVALID; | ||
1776 | } else if (ASIC_IS_DCE4(rdev)) { | 1791 | } else if (ASIC_IS_DCE4(rdev)) { |
1777 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, | 1792 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1778 | * depending on the asic: | 1793 | * depending on the asic: |
@@ -1800,7 +1815,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1800 | if (pll != ATOM_PPLL_INVALID) | 1815 | if (pll != ATOM_PPLL_INVALID) |
1801 | return pll; | 1816 | return pll; |
1802 | } | 1817 | } |
1803 | } else if (!ASIC_IS_DCE41(rdev)) { /* Don't share PLLs on DCE4.1 chips */ | 1818 | } else { |
1804 | /* use the same PPLL for all monitors with the same clock */ | 1819 | /* use the same PPLL for all monitors with the same clock */ |
1805 | pll = radeon_get_shared_nondp_ppll(crtc); | 1820 | pll = radeon_get_shared_nondp_ppll(crtc); |
1806 | if (pll != ATOM_PPLL_INVALID) | 1821 | if (pll != ATOM_PPLL_INVALID) |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index a42d61571f49..607dc14d195e 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -464,11 +464,12 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) | |||
464 | 464 | ||
465 | static u8 radeon_atom_get_bpc(struct drm_encoder *encoder) | 465 | static u8 radeon_atom_get_bpc(struct drm_encoder *encoder) |
466 | { | 466 | { |
467 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
468 | int bpc = 8; | 467 | int bpc = 8; |
469 | 468 | ||
470 | if (connector) | 469 | if (encoder->crtc) { |
471 | bpc = radeon_get_monitor_bpc(connector); | 470 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
471 | bpc = radeon_crtc->bpc; | ||
472 | } | ||
472 | 473 | ||
473 | switch (bpc) { | 474 | switch (bpc) { |
474 | case 0: | 475 | case 0: |
@@ -1313,7 +1314,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
1313 | } | 1314 | } |
1314 | if (is_dp) | 1315 | if (is_dp) |
1315 | args.v5.ucLaneNum = dp_lane_count; | 1316 | args.v5.ucLaneNum = dp_lane_count; |
1316 | else if (radeon_encoder->pixel_clock > 165000) | 1317 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
1317 | args.v5.ucLaneNum = 8; | 1318 | args.v5.ucLaneNum = 8; |
1318 | else | 1319 | else |
1319 | args.v5.ucLaneNum = 4; | 1320 | args.v5.ucLaneNum = 4; |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0fbd36f3d4e9..ea103ccdf4bd 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "cypress_dpm.h" | 29 | #include "cypress_dpm.h" |
30 | #include "btc_dpm.h" | 30 | #include "btc_dpm.h" |
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | #include <linux/seq_file.h> | ||
32 | 33 | ||
33 | #define MC_CG_ARB_FREQ_F0 0x0a | 34 | #define MC_CG_ARB_FREQ_F0 0x0a |
34 | #define MC_CG_ARB_FREQ_F1 0x0b | 35 | #define MC_CG_ARB_FREQ_F1 0x0b |
@@ -2756,6 +2757,37 @@ void btc_dpm_fini(struct radeon_device *rdev) | |||
2756 | r600_free_extended_power_table(rdev); | 2757 | r600_free_extended_power_table(rdev); |
2757 | } | 2758 | } |
2758 | 2759 | ||
2760 | void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | ||
2761 | struct seq_file *m) | ||
2762 | { | ||
2763 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2764 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
2765 | struct rv7xx_ps *ps = rv770_get_ps(rps); | ||
2766 | struct rv7xx_pl *pl; | ||
2767 | u32 current_index = | ||
2768 | (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >> | ||
2769 | CURRENT_PROFILE_INDEX_SHIFT; | ||
2770 | |||
2771 | if (current_index > 2) { | ||
2772 | seq_printf(m, "invalid dpm profile %d\n", current_index); | ||
2773 | } else { | ||
2774 | if (current_index == 0) | ||
2775 | pl = &ps->low; | ||
2776 | else if (current_index == 1) | ||
2777 | pl = &ps->medium; | ||
2778 | else /* current_index == 2 */ | ||
2779 | pl = &ps->high; | ||
2780 | seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk); | ||
2781 | if (rdev->family >= CHIP_CEDAR) { | ||
2782 | seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n", | ||
2783 | current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci); | ||
2784 | } else { | ||
2785 | seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u\n", | ||
2786 | current_index, pl->sclk, pl->mclk, pl->vddc); | ||
2787 | } | ||
2788 | } | ||
2789 | } | ||
2790 | |||
2759 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) | 2791 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) |
2760 | { | 2792 | { |
2761 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2793 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
diff --git a/drivers/gpu/drm/radeon/btcd.h b/drivers/gpu/drm/radeon/btcd.h index 29e32de7e025..9c65be2d55a9 100644 --- a/drivers/gpu/drm/radeon/btcd.h +++ b/drivers/gpu/drm/radeon/btcd.h | |||
@@ -44,6 +44,10 @@ | |||
44 | # define DYN_SPREAD_SPECTRUM_EN (1 << 23) | 44 | # define DYN_SPREAD_SPECTRUM_EN (1 << 23) |
45 | # define AC_DC_SW (1 << 24) | 45 | # define AC_DC_SW (1 << 24) |
46 | 46 | ||
47 | #define TARGET_AND_CURRENT_PROFILE_INDEX 0x66c | ||
48 | # define CURRENT_PROFILE_INDEX_MASK (0xf << 4) | ||
49 | # define CURRENT_PROFILE_INDEX_SHIFT 4 | ||
50 | |||
47 | #define CG_BIF_REQ_AND_RSP 0x7f4 | 51 | #define CG_BIF_REQ_AND_RSP 0x7f4 |
48 | #define CG_CLIENT_REQ(x) ((x) << 0) | 52 | #define CG_CLIENT_REQ(x) ((x) << 0) |
49 | #define CG_CLIENT_REQ_MASK (0xff << 0) | 53 | #define CG_CLIENT_REQ_MASK (0xff << 0) |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index e6419ca7cd37..bbb17841a9e5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -3046,7 +3046,7 @@ static u32 cik_create_bitmask(u32 bit_width) | |||
3046 | } | 3046 | } |
3047 | 3047 | ||
3048 | /** | 3048 | /** |
3049 | * cik_select_se_sh - select which SE, SH to address | 3049 | * cik_get_rb_disabled - computes the mask of disabled RBs |
3050 | * | 3050 | * |
3051 | * @rdev: radeon_device pointer | 3051 | * @rdev: radeon_device pointer |
3052 | * @max_rb_num: max RBs (render backends) for the asic | 3052 | * @max_rb_num: max RBs (render backends) for the asic |
@@ -4134,8 +4134,11 @@ static void cik_cp_compute_enable(struct radeon_device *rdev, bool enable) | |||
4134 | { | 4134 | { |
4135 | if (enable) | 4135 | if (enable) |
4136 | WREG32(CP_MEC_CNTL, 0); | 4136 | WREG32(CP_MEC_CNTL, 0); |
4137 | else | 4137 | else { |
4138 | WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT)); | 4138 | WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT)); |
4139 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | ||
4140 | rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; | ||
4141 | } | ||
4139 | udelay(50); | 4142 | udelay(50); |
4140 | } | 4143 | } |
4141 | 4144 | ||
@@ -7902,7 +7905,8 @@ int cik_resume(struct radeon_device *rdev) | |||
7902 | /* init golden registers */ | 7905 | /* init golden registers */ |
7903 | cik_init_golden_registers(rdev); | 7906 | cik_init_golden_registers(rdev); |
7904 | 7907 | ||
7905 | radeon_pm_resume(rdev); | 7908 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
7909 | radeon_pm_resume(rdev); | ||
7906 | 7910 | ||
7907 | rdev->accel_working = true; | 7911 | rdev->accel_working = true; |
7908 | r = cik_startup(rdev); | 7912 | r = cik_startup(rdev); |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 1ecb3f1070e3..94626ea90fa5 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -264,6 +264,8 @@ static void cik_sdma_gfx_stop(struct radeon_device *rdev) | |||
264 | WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); | 264 | WREG32(SDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); |
265 | WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0); | 265 | WREG32(SDMA0_GFX_IB_CNTL + reg_offset, 0); |
266 | } | 266 | } |
267 | rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; | ||
268 | rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false; | ||
267 | } | 269 | } |
268 | 270 | ||
269 | /** | 271 | /** |
@@ -291,6 +293,11 @@ void cik_sdma_enable(struct radeon_device *rdev, bool enable) | |||
291 | u32 me_cntl, reg_offset; | 293 | u32 me_cntl, reg_offset; |
292 | int i; | 294 | int i; |
293 | 295 | ||
296 | if (enable == false) { | ||
297 | cik_sdma_gfx_stop(rdev); | ||
298 | cik_sdma_rlc_stop(rdev); | ||
299 | } | ||
300 | |||
294 | for (i = 0; i < 2; i++) { | 301 | for (i = 0; i < 2; i++) { |
295 | if (i == 0) | 302 | if (i == 0) |
296 | reg_offset = SDMA0_REGISTER_OFFSET; | 303 | reg_offset = SDMA0_REGISTER_OFFSET; |
@@ -420,10 +427,6 @@ static int cik_sdma_load_microcode(struct radeon_device *rdev) | |||
420 | if (!rdev->sdma_fw) | 427 | if (!rdev->sdma_fw) |
421 | return -EINVAL; | 428 | return -EINVAL; |
422 | 429 | ||
423 | /* stop the gfx rings and rlc compute queues */ | ||
424 | cik_sdma_gfx_stop(rdev); | ||
425 | cik_sdma_rlc_stop(rdev); | ||
426 | |||
427 | /* halt the MEs */ | 430 | /* halt the MEs */ |
428 | cik_sdma_enable(rdev, false); | 431 | cik_sdma_enable(rdev, false); |
429 | 432 | ||
@@ -492,9 +495,6 @@ int cik_sdma_resume(struct radeon_device *rdev) | |||
492 | */ | 495 | */ |
493 | void cik_sdma_fini(struct radeon_device *rdev) | 496 | void cik_sdma_fini(struct radeon_device *rdev) |
494 | { | 497 | { |
495 | /* stop the gfx rings and rlc compute queues */ | ||
496 | cik_sdma_gfx_stop(rdev); | ||
497 | cik_sdma_rlc_stop(rdev); | ||
498 | /* halt the MEs */ | 498 | /* halt the MEs */ |
499 | cik_sdma_enable(rdev, false); | 499 | cik_sdma_enable(rdev, false); |
500 | radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]); | 500 | radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]); |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 713a5d359901..94e858751994 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -278,13 +278,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev) | |||
278 | return !ASIC_IS_NODCE(rdev); | 278 | return !ASIC_IS_NODCE(rdev); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void dce6_audio_enable(struct radeon_device *rdev, | 281 | void dce6_audio_enable(struct radeon_device *rdev, |
282 | struct r600_audio_pin *pin, | 282 | struct r600_audio_pin *pin, |
283 | bool enable) | 283 | bool enable) |
284 | { | 284 | { |
285 | if (!pin) | ||
286 | return; | ||
287 | |||
285 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, | 288 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, |
286 | AUDIO_ENABLED); | 289 | enable ? AUDIO_ENABLED : 0); |
287 | DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id); | ||
288 | } | 290 | } |
289 | 291 | ||
290 | static const u32 pin_offsets[7] = | 292 | static const u32 pin_offsets[7] = |
@@ -323,7 +325,8 @@ int dce6_audio_init(struct radeon_device *rdev) | |||
323 | rdev->audio.pin[i].connected = false; | 325 | rdev->audio.pin[i].connected = false; |
324 | rdev->audio.pin[i].offset = pin_offsets[i]; | 326 | rdev->audio.pin[i].offset = pin_offsets[i]; |
325 | rdev->audio.pin[i].id = i; | 327 | rdev->audio.pin[i].id = i; |
326 | dce6_audio_enable(rdev, &rdev->audio.pin[i], true); | 328 | /* disable audio. it will be set up later */ |
329 | dce6_audio_enable(rdev, &rdev->audio.pin[i], false); | ||
327 | } | 330 | } |
328 | 331 | ||
329 | return 0; | 332 | return 0; |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f2b9e21ce4da..27b0ff16082e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1680,7 +1680,7 @@ bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) | |||
1680 | case RADEON_HPD_6: | 1680 | case RADEON_HPD_6: |
1681 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | 1681 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) |
1682 | connected = true; | 1682 | connected = true; |
1683 | break; | 1683 | break; |
1684 | default: | 1684 | default: |
1685 | break; | 1685 | break; |
1686 | } | 1686 | } |
@@ -5299,7 +5299,8 @@ int evergreen_resume(struct radeon_device *rdev) | |||
5299 | /* init golden registers */ | 5299 | /* init golden registers */ |
5300 | evergreen_init_golden_registers(rdev); | 5300 | evergreen_init_golden_registers(rdev); |
5301 | 5301 | ||
5302 | radeon_pm_resume(rdev); | 5302 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
5303 | radeon_pm_resume(rdev); | ||
5303 | 5304 | ||
5304 | rdev->accel_working = true; | 5305 | rdev->accel_working = true; |
5305 | r = evergreen_startup(rdev); | 5306 | r = evergreen_startup(rdev); |
@@ -5475,9 +5476,9 @@ void evergreen_fini(struct radeon_device *rdev) | |||
5475 | radeon_wb_fini(rdev); | 5476 | radeon_wb_fini(rdev); |
5476 | radeon_ib_pool_fini(rdev); | 5477 | radeon_ib_pool_fini(rdev); |
5477 | radeon_irq_kms_fini(rdev); | 5478 | radeon_irq_kms_fini(rdev); |
5478 | evergreen_pcie_gart_fini(rdev); | ||
5479 | uvd_v1_0_fini(rdev); | 5479 | uvd_v1_0_fini(rdev); |
5480 | radeon_uvd_fini(rdev); | 5480 | radeon_uvd_fini(rdev); |
5481 | evergreen_pcie_gart_fini(rdev); | ||
5481 | r600_vram_scratch_fini(rdev); | 5482 | r600_vram_scratch_fini(rdev); |
5482 | radeon_gem_fini(rdev); | 5483 | radeon_gem_fini(rdev); |
5483 | radeon_fence_driver_fini(rdev); | 5484 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 0c6d5cef4cf1..05b0c95813fd 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -306,6 +306,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
306 | return; | 306 | return; |
307 | offset = dig->afmt->offset; | 307 | offset = dig->afmt->offset; |
308 | 308 | ||
309 | /* disable audio prior to setting up hw */ | ||
310 | if (ASIC_IS_DCE6(rdev)) { | ||
311 | dig->afmt->pin = dce6_audio_get_pin(rdev); | ||
312 | dce6_audio_enable(rdev, dig->afmt->pin, false); | ||
313 | } else { | ||
314 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
315 | r600_audio_enable(rdev, dig->afmt->pin, false); | ||
316 | } | ||
317 | |||
309 | evergreen_audio_set_dto(encoder, mode->clock); | 318 | evergreen_audio_set_dto(encoder, mode->clock); |
310 | 319 | ||
311 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, | 320 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, |
@@ -409,12 +418,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
409 | WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); | 418 | WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); |
410 | WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); | 419 | WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); |
411 | WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); | 420 | WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); |
421 | |||
422 | /* enable audio after to setting up hw */ | ||
423 | if (ASIC_IS_DCE6(rdev)) | ||
424 | dce6_audio_enable(rdev, dig->afmt->pin, true); | ||
425 | else | ||
426 | r600_audio_enable(rdev, dig->afmt->pin, true); | ||
412 | } | 427 | } |
413 | 428 | ||
414 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | 429 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) |
415 | { | 430 | { |
416 | struct drm_device *dev = encoder->dev; | ||
417 | struct radeon_device *rdev = dev->dev_private; | ||
418 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 431 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
419 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 432 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
420 | 433 | ||
@@ -427,15 +440,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
427 | if (!enable && !dig->afmt->enabled) | 440 | if (!enable && !dig->afmt->enabled) |
428 | return; | 441 | return; |
429 | 442 | ||
430 | if (enable) { | ||
431 | if (ASIC_IS_DCE6(rdev)) | ||
432 | dig->afmt->pin = dce6_audio_get_pin(rdev); | ||
433 | else | ||
434 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
435 | } else { | ||
436 | dig->afmt->pin = NULL; | ||
437 | } | ||
438 | |||
439 | dig->afmt->enabled = enable; | 443 | dig->afmt->enabled = enable; |
440 | 444 | ||
441 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 445 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
diff --git a/drivers/gpu/drm/radeon/evergreen_smc.h b/drivers/gpu/drm/radeon/evergreen_smc.h index 76ada8cfe902..3a03ba37d043 100644 --- a/drivers/gpu/drm/radeon/evergreen_smc.h +++ b/drivers/gpu/drm/radeon/evergreen_smc.h | |||
@@ -57,7 +57,7 @@ typedef struct SMC_Evergreen_MCRegisters SMC_Evergreen_MCRegisters; | |||
57 | 57 | ||
58 | #define EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION 0x100 | 58 | #define EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION 0x100 |
59 | 59 | ||
60 | #define EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters 0x0 | 60 | #define EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters 0x8 |
61 | #define EVERGREEN_SMC_FIRMWARE_HEADER_stateTable 0xC | 61 | #define EVERGREEN_SMC_FIRMWARE_HEADER_stateTable 0xC |
62 | #define EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable 0x20 | 62 | #define EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable 0x20 |
63 | 63 | ||
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index b6e01d5d2cce..351db361239d 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -1223,7 +1223,7 @@ int kv_dpm_enable(struct radeon_device *rdev) | |||
1223 | 1223 | ||
1224 | int kv_dpm_late_enable(struct radeon_device *rdev) | 1224 | int kv_dpm_late_enable(struct radeon_device *rdev) |
1225 | { | 1225 | { |
1226 | int ret; | 1226 | int ret = 0; |
1227 | 1227 | ||
1228 | if (rdev->irq.installed && | 1228 | if (rdev->irq.installed && |
1229 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | 1229 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ea932ac66fc6..bf6300cfd62d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -2105,7 +2105,8 @@ int cayman_resume(struct radeon_device *rdev) | |||
2105 | /* init golden registers */ | 2105 | /* init golden registers */ |
2106 | ni_init_golden_registers(rdev); | 2106 | ni_init_golden_registers(rdev); |
2107 | 2107 | ||
2108 | radeon_pm_resume(rdev); | 2108 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
2109 | radeon_pm_resume(rdev); | ||
2109 | 2110 | ||
2110 | rdev->accel_working = true; | 2111 | rdev->accel_working = true; |
2111 | r = cayman_startup(rdev); | 2112 | r = cayman_startup(rdev); |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index c351226ecb31..ca814276b075 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
@@ -2588,7 +2588,7 @@ static int ni_populate_sq_ramping_values(struct radeon_device *rdev, | |||
2588 | if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) | 2588 | if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) |
2589 | enable_sq_ramping = false; | 2589 | enable_sq_ramping = false; |
2590 | 2590 | ||
2591 | if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) | 2591 | if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) |
2592 | enable_sq_ramping = false; | 2592 | enable_sq_ramping = false; |
2593 | 2593 | ||
2594 | for (i = 0; i < state->performance_level_count; i++) { | 2594 | for (i = 0; i < state->performance_level_count; i++) { |
@@ -3945,7 +3945,6 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev, | |||
3945 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 3945 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
3946 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 3946 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
3947 | struct ni_ps *ps = ni_get_ps(rps); | 3947 | struct ni_ps *ps = ni_get_ps(rps); |
3948 | u16 vddc; | ||
3949 | struct rv7xx_pl *pl = &ps->performance_levels[index]; | 3948 | struct rv7xx_pl *pl = &ps->performance_levels[index]; |
3950 | 3949 | ||
3951 | ps->performance_level_count = index + 1; | 3950 | ps->performance_level_count = index + 1; |
@@ -3961,8 +3960,8 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev, | |||
3961 | 3960 | ||
3962 | /* patch up vddc if necessary */ | 3961 | /* patch up vddc if necessary */ |
3963 | if (pl->vddc == 0xff01) { | 3962 | if (pl->vddc == 0xff01) { |
3964 | if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) | 3963 | if (pi->max_vddc) |
3965 | pl->vddc = vddc; | 3964 | pl->vddc = pi->max_vddc; |
3966 | } | 3965 | } |
3967 | 3966 | ||
3968 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { | 3967 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { |
@@ -4322,7 +4321,8 @@ void ni_dpm_print_power_state(struct radeon_device *rdev, | |||
4322 | void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 4321 | void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
4323 | struct seq_file *m) | 4322 | struct seq_file *m) |
4324 | { | 4323 | { |
4325 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 4324 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
4325 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
4326 | struct ni_ps *ps = ni_get_ps(rps); | 4326 | struct ni_ps *ps = ni_get_ps(rps); |
4327 | struct rv7xx_pl *pl; | 4327 | struct rv7xx_pl *pl; |
4328 | u32 current_index = | 4328 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index ef024ce3f7cc..3cc78bb66042 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -3942,8 +3942,6 @@ int r100_resume(struct radeon_device *rdev) | |||
3942 | /* Initialize surface registers */ | 3942 | /* Initialize surface registers */ |
3943 | radeon_surface_init(rdev); | 3943 | radeon_surface_init(rdev); |
3944 | 3944 | ||
3945 | radeon_pm_resume(rdev); | ||
3946 | |||
3947 | rdev->accel_working = true; | 3945 | rdev->accel_working = true; |
3948 | r = r100_startup(rdev); | 3946 | r = r100_startup(rdev); |
3949 | if (r) { | 3947 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 7c63ef840e86..0b658b34b33a 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -1430,8 +1430,6 @@ int r300_resume(struct radeon_device *rdev) | |||
1430 | /* Initialize surface registers */ | 1430 | /* Initialize surface registers */ |
1431 | radeon_surface_init(rdev); | 1431 | radeon_surface_init(rdev); |
1432 | 1432 | ||
1433 | radeon_pm_resume(rdev); | ||
1434 | |||
1435 | rdev->accel_working = true; | 1433 | rdev->accel_working = true; |
1436 | r = r300_startup(rdev); | 1434 | r = r300_startup(rdev); |
1437 | if (r) { | 1435 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 3768aab2710b..802b19220a21 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c | |||
@@ -325,8 +325,6 @@ int r420_resume(struct radeon_device *rdev) | |||
325 | /* Initialize surface registers */ | 325 | /* Initialize surface registers */ |
326 | radeon_surface_init(rdev); | 326 | radeon_surface_init(rdev); |
327 | 327 | ||
328 | radeon_pm_resume(rdev); | ||
329 | |||
330 | rdev->accel_working = true; | 328 | rdev->accel_working = true; |
331 | r = r420_startup(rdev); | 329 | r = r420_startup(rdev); |
332 | if (r) { | 330 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index e209eb75024f..98d6053c36c6 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
@@ -240,8 +240,6 @@ int r520_resume(struct radeon_device *rdev) | |||
240 | /* Initialize surface registers */ | 240 | /* Initialize surface registers */ |
241 | radeon_surface_init(rdev); | 241 | radeon_surface_init(rdev); |
242 | 242 | ||
243 | radeon_pm_resume(rdev); | ||
244 | |||
245 | rdev->accel_working = true; | 243 | rdev->accel_working = true; |
246 | r = r520_startup(rdev); | 244 | r = r520_startup(rdev); |
247 | if (r) { | 245 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 56140b4e5bb2..647ef4079217 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2968,7 +2968,8 @@ int r600_resume(struct radeon_device *rdev) | |||
2968 | /* post card */ | 2968 | /* post card */ |
2969 | atom_asic_init(rdev->mode_info.atom_context); | 2969 | atom_asic_init(rdev->mode_info.atom_context); |
2970 | 2970 | ||
2971 | radeon_pm_resume(rdev); | 2971 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
2972 | radeon_pm_resume(rdev); | ||
2972 | 2973 | ||
2973 | rdev->accel_working = true; | 2974 | rdev->accel_working = true; |
2974 | r = r600_startup(rdev); | 2975 | r = r600_startup(rdev); |
@@ -3991,6 +3992,10 @@ restart_ih: | |||
3991 | break; | 3992 | break; |
3992 | } | 3993 | } |
3993 | break; | 3994 | break; |
3995 | case 124: /* UVD */ | ||
3996 | DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); | ||
3997 | radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); | ||
3998 | break; | ||
3994 | case 176: /* CP_INT in ring buffer */ | 3999 | case 176: /* CP_INT in ring buffer */ |
3995 | case 177: /* CP_INT in IB1 */ | 4000 | case 177: /* CP_INT in IB1 */ |
3996 | case 178: /* CP_INT in IB2 */ | 4001 | case 178: /* CP_INT in IB2 */ |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 47fc2b886979..bffac10c4296 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | /* enable the audio stream */ | 144 | /* enable the audio stream */ |
145 | static void r600_audio_enable(struct radeon_device *rdev, | 145 | void r600_audio_enable(struct radeon_device *rdev, |
146 | struct r600_audio_pin *pin, | 146 | struct r600_audio_pin *pin, |
147 | bool enable) | 147 | bool enable) |
148 | { | 148 | { |
149 | u32 value = 0; | 149 | u32 value = 0; |
150 | 150 | ||
151 | if (!pin) | ||
152 | return; | ||
153 | |||
151 | if (ASIC_IS_DCE4(rdev)) { | 154 | if (ASIC_IS_DCE4(rdev)) { |
152 | if (enable) { | 155 | if (enable) { |
153 | value |= 0x81000000; /* Required to enable audio */ | 156 | value |= 0x81000000; /* Required to enable audio */ |
@@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev, | |||
158 | WREG32_P(R600_AUDIO_ENABLE, | 161 | WREG32_P(R600_AUDIO_ENABLE, |
159 | enable ? 0x81000000 : 0x0, ~0x81000000); | 162 | enable ? 0x81000000 : 0x0, ~0x81000000); |
160 | } | 163 | } |
161 | DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id); | ||
162 | } | 164 | } |
163 | 165 | ||
164 | /* | 166 | /* |
@@ -178,8 +180,8 @@ int r600_audio_init(struct radeon_device *rdev) | |||
178 | rdev->audio.pin[0].status_bits = 0; | 180 | rdev->audio.pin[0].status_bits = 0; |
179 | rdev->audio.pin[0].category_code = 0; | 181 | rdev->audio.pin[0].category_code = 0; |
180 | rdev->audio.pin[0].id = 0; | 182 | rdev->audio.pin[0].id = 0; |
181 | 183 | /* disable audio. it will be set up later */ | |
182 | r600_audio_enable(rdev, &rdev->audio.pin[0], true); | 184 | r600_audio_enable(rdev, &rdev->audio.pin[0], false); |
183 | 185 | ||
184 | return 0; | 186 | return 0; |
185 | } | 187 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 7b399dc5fd54..2812c7d1ae6f 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1007,8 +1007,22 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1007 | case R_008C64_SQ_VSTMP_RING_SIZE: | 1007 | case R_008C64_SQ_VSTMP_RING_SIZE: |
1008 | case R_0288C8_SQ_GS_VERT_ITEMSIZE: | 1008 | case R_0288C8_SQ_GS_VERT_ITEMSIZE: |
1009 | /* get value to populate the IB don't remove */ | 1009 | /* get value to populate the IB don't remove */ |
1010 | tmp =radeon_get_ib_value(p, idx); | 1010 | /*tmp =radeon_get_ib_value(p, idx); |
1011 | ib[idx] = 0; | 1011 | ib[idx] = 0;*/ |
1012 | break; | ||
1013 | case SQ_ESGS_RING_BASE: | ||
1014 | case SQ_GSVS_RING_BASE: | ||
1015 | case SQ_ESTMP_RING_BASE: | ||
1016 | case SQ_GSTMP_RING_BASE: | ||
1017 | case SQ_PSTMP_RING_BASE: | ||
1018 | case SQ_VSTMP_RING_BASE: | ||
1019 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); | ||
1020 | if (r) { | ||
1021 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1022 | "0x%04X\n", reg); | ||
1023 | return -EINVAL; | ||
1024 | } | ||
1025 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1012 | break; | 1026 | break; |
1013 | case SQ_CONFIG: | 1027 | case SQ_CONFIG: |
1014 | track->sq_config = radeon_get_ib_value(p, idx); | 1028 | track->sq_config = radeon_get_ib_value(p, idx); |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 3016fc14f502..85a2bb28aed2 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -329,9 +329,6 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
329 | u8 *sadb; | 329 | u8 *sadb; |
330 | int sad_count; | 330 | int sad_count; |
331 | 331 | ||
332 | /* XXX: setting this register causes hangs on some asics */ | ||
333 | return; | ||
334 | |||
335 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 332 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
336 | if (connector->encoder == encoder) { | 333 | if (connector->encoder == encoder) { |
337 | radeon_connector = to_radeon_connector(connector); | 334 | radeon_connector = to_radeon_connector(connector); |
@@ -460,6 +457,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
460 | return; | 457 | return; |
461 | offset = dig->afmt->offset; | 458 | offset = dig->afmt->offset; |
462 | 459 | ||
460 | /* disable audio prior to setting up hw */ | ||
461 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
462 | r600_audio_enable(rdev, dig->afmt->pin, false); | ||
463 | |||
463 | r600_audio_set_dto(encoder, mode->clock); | 464 | r600_audio_set_dto(encoder, mode->clock); |
464 | 465 | ||
465 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 466 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
@@ -531,6 +532,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
531 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); | 532 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
532 | 533 | ||
533 | r600_hdmi_audio_workaround(encoder); | 534 | r600_hdmi_audio_workaround(encoder); |
535 | |||
536 | /* enable audio after to setting up hw */ | ||
537 | r600_audio_enable(rdev, dig->afmt->pin, true); | ||
534 | } | 538 | } |
535 | 539 | ||
536 | /* | 540 | /* |
@@ -651,11 +655,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
651 | if (!enable && !dig->afmt->enabled) | 655 | if (!enable && !dig->afmt->enabled) |
652 | return; | 656 | return; |
653 | 657 | ||
654 | if (enable) | ||
655 | dig->afmt->pin = r600_audio_get_pin(rdev); | ||
656 | else | ||
657 | dig->afmt->pin = NULL; | ||
658 | |||
659 | /* Older chipsets require setting HDMI and routing manually */ | 658 | /* Older chipsets require setting HDMI and routing manually */ |
660 | if (!ASIC_IS_DCE3(rdev)) { | 659 | if (!ASIC_IS_DCE3(rdev)) { |
661 | if (enable) | 660 | if (enable) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 4a8ac1cd6b4c..e887d027b6d0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -135,6 +135,9 @@ extern int radeon_hard_reset; | |||
135 | /* R600+ */ | 135 | /* R600+ */ |
136 | #define R600_RING_TYPE_UVD_INDEX 5 | 136 | #define R600_RING_TYPE_UVD_INDEX 5 |
137 | 137 | ||
138 | /* number of hw syncs before falling back on blocking */ | ||
139 | #define RADEON_NUM_SYNCS 4 | ||
140 | |||
138 | /* hardcode those limit for now */ | 141 | /* hardcode those limit for now */ |
139 | #define RADEON_VA_IB_OFFSET (1 << 20) | 142 | #define RADEON_VA_IB_OFFSET (1 << 20) |
140 | #define RADEON_VA_RESERVED_SIZE (8 << 20) | 143 | #define RADEON_VA_RESERVED_SIZE (8 << 20) |
@@ -554,7 +557,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, | |||
554 | /* | 557 | /* |
555 | * Semaphores. | 558 | * Semaphores. |
556 | */ | 559 | */ |
557 | /* everything here is constant */ | ||
558 | struct radeon_semaphore { | 560 | struct radeon_semaphore { |
559 | struct radeon_sa_bo *sa_bo; | 561 | struct radeon_sa_bo *sa_bo; |
560 | signed waiters; | 562 | signed waiters; |
@@ -2745,6 +2747,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
2745 | void r600_audio_update_hdmi(struct work_struct *work); | 2747 | void r600_audio_update_hdmi(struct work_struct *work); |
2746 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); | 2748 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); |
2747 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); | 2749 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); |
2750 | void r600_audio_enable(struct radeon_device *rdev, | ||
2751 | struct r600_audio_pin *pin, | ||
2752 | bool enable); | ||
2753 | void dce6_audio_enable(struct radeon_device *rdev, | ||
2754 | struct r600_audio_pin *pin, | ||
2755 | bool enable); | ||
2748 | 2756 | ||
2749 | /* | 2757 | /* |
2750 | * R600 vram scratch functions | 2758 | * R600 vram scratch functions |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index f74db43346fd..dda02bfc10a4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1555,7 +1555,7 @@ static struct radeon_asic btc_asic = { | |||
1555 | .get_sclk = &btc_dpm_get_sclk, | 1555 | .get_sclk = &btc_dpm_get_sclk, |
1556 | .get_mclk = &btc_dpm_get_mclk, | 1556 | .get_mclk = &btc_dpm_get_mclk, |
1557 | .print_power_state = &rv770_dpm_print_power_state, | 1557 | .print_power_state = &rv770_dpm_print_power_state, |
1558 | .debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level, | 1558 | .debugfs_print_current_performance_level = &btc_dpm_debugfs_print_current_performance_level, |
1559 | .force_performance_level = &rv770_dpm_force_performance_level, | 1559 | .force_performance_level = &rv770_dpm_force_performance_level, |
1560 | .vblank_too_short = &btc_dpm_vblank_too_short, | 1560 | .vblank_too_short = &btc_dpm_vblank_too_short, |
1561 | }, | 1561 | }, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index b3bc433eed4c..ae637cfda783 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -551,6 +551,8 @@ void btc_dpm_fini(struct radeon_device *rdev); | |||
551 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low); | 551 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low); |
552 | u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); | 552 | u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); |
553 | bool btc_dpm_vblank_too_short(struct radeon_device *rdev); | 553 | bool btc_dpm_vblank_too_short(struct radeon_device *rdev); |
554 | void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | ||
555 | struct seq_file *m); | ||
554 | int sumo_dpm_init(struct radeon_device *rdev); | 556 | int sumo_dpm_init(struct radeon_device *rdev); |
555 | int sumo_dpm_enable(struct radeon_device *rdev); | 557 | int sumo_dpm_enable(struct radeon_device *rdev); |
556 | int sumo_dpm_late_enable(struct radeon_device *rdev); | 558 | int sumo_dpm_late_enable(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 485848f889f5..fa9a9c02751e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -219,7 +219,8 @@ static int radeon_atpx_verify_interface(struct radeon_atpx *atpx) | |||
219 | memcpy(&output, info->buffer.pointer, size); | 219 | memcpy(&output, info->buffer.pointer, size); |
220 | 220 | ||
221 | /* TODO: check version? */ | 221 | /* TODO: check version? */ |
222 | printk("ATPX version %u\n", output.version); | 222 | printk("ATPX version %u, functions 0x%08x\n", |
223 | output.version, output.function_bits); | ||
223 | 224 | ||
224 | radeon_atpx_parse_functions(&atpx->functions, output.function_bits); | 225 | radeon_atpx_parse_functions(&atpx->functions, output.function_bits); |
225 | 226 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index b012cbbc3ed5..044bc98fb459 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1521,13 +1521,16 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) | |||
1521 | if (r) | 1521 | if (r) |
1522 | DRM_ERROR("ib ring test failed (%d).\n", r); | 1522 | DRM_ERROR("ib ring test failed (%d).\n", r); |
1523 | 1523 | ||
1524 | if (rdev->pm.dpm_enabled) { | 1524 | if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { |
1525 | /* do dpm late init */ | 1525 | /* do dpm late init */ |
1526 | r = radeon_pm_late_init(rdev); | 1526 | r = radeon_pm_late_init(rdev); |
1527 | if (r) { | 1527 | if (r) { |
1528 | rdev->pm.dpm_enabled = false; | 1528 | rdev->pm.dpm_enabled = false; |
1529 | DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); | 1529 | DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); |
1530 | } | 1530 | } |
1531 | } else { | ||
1532 | /* resume old pm late */ | ||
1533 | radeon_pm_resume(rdev); | ||
1531 | } | 1534 | } |
1532 | 1535 | ||
1533 | radeon_restore_bios_scratch_regs(rdev); | 1536 | radeon_restore_bios_scratch_regs(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d680608f6f5b..fbd8b930f2be 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -571,6 +571,8 @@ static void radeon_crtc_init(struct drm_device *dev, int index) | |||
571 | radeon_crtc->max_cursor_width = CURSOR_WIDTH; | 571 | radeon_crtc->max_cursor_width = CURSOR_WIDTH; |
572 | radeon_crtc->max_cursor_height = CURSOR_HEIGHT; | 572 | radeon_crtc->max_cursor_height = CURSOR_HEIGHT; |
573 | } | 573 | } |
574 | dev->mode_config.cursor_width = radeon_crtc->max_cursor_width; | ||
575 | dev->mode_config.cursor_height = radeon_crtc->max_cursor_height; | ||
574 | 576 | ||
575 | #if 0 | 577 | #if 0 |
576 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; | 578 | radeon_crtc->mode_set.crtc = &radeon_crtc->base; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index ec8c388eec17..84a1bbb75f91 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -78,9 +78,10 @@ | |||
78 | * 2.34.0 - Add CIK tiling mode array query | 78 | * 2.34.0 - Add CIK tiling mode array query |
79 | * 2.35.0 - Add CIK macrotile mode array query | 79 | * 2.35.0 - Add CIK macrotile mode array query |
80 | * 2.36.0 - Fix CIK DCE tiling setup | 80 | * 2.36.0 - Fix CIK DCE tiling setup |
81 | * 2.37.0 - allow GS ring setup on r6xx/r7xx | ||
81 | */ | 82 | */ |
82 | #define KMS_DRIVER_MAJOR 2 | 83 | #define KMS_DRIVER_MAJOR 2 |
83 | #define KMS_DRIVER_MINOR 36 | 84 | #define KMS_DRIVER_MINOR 37 |
84 | #define KMS_DRIVER_PATCHLEVEL 0 | 85 | #define KMS_DRIVER_PATCHLEVEL 0 |
85 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 86 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
86 | int radeon_driver_unload_kms(struct drm_device *dev); | 87 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 114d1672d616..66ed3ea71440 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -33,6 +33,13 @@ | |||
33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/pm_runtime.h> | 35 | #include <linux/pm_runtime.h> |
36 | |||
37 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
38 | bool radeon_is_px(void); | ||
39 | #else | ||
40 | static inline bool radeon_is_px(void) { return false; } | ||
41 | #endif | ||
42 | |||
36 | /** | 43 | /** |
37 | * radeon_driver_unload_kms - Main unload function for KMS. | 44 | * radeon_driver_unload_kms - Main unload function for KMS. |
38 | * | 45 | * |
@@ -130,7 +137,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
130 | "Error during ACPI methods call\n"); | 137 | "Error during ACPI methods call\n"); |
131 | } | 138 | } |
132 | 139 | ||
133 | if (radeon_runtime_pm != 0) { | 140 | if ((radeon_runtime_pm == 1) || |
141 | ((radeon_runtime_pm == -1) && radeon_is_px())) { | ||
134 | pm_runtime_use_autosuspend(dev->dev); | 142 | pm_runtime_use_autosuspend(dev->dev); |
135 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); | 143 | pm_runtime_set_autosuspend_delay(dev->dev, 5000); |
136 | pm_runtime_set_active(dev->dev); | 144 | pm_runtime_set_active(dev->dev); |
@@ -537,6 +545,10 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
537 | 545 | ||
538 | radeon_vm_init(rdev, &fpriv->vm); | 546 | radeon_vm_init(rdev, &fpriv->vm); |
539 | 547 | ||
548 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | ||
549 | if (r) | ||
550 | return r; | ||
551 | |||
540 | /* map the ib pool buffer read only into | 552 | /* map the ib pool buffer read only into |
541 | * virtual address space */ | 553 | * virtual address space */ |
542 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, | 554 | bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, |
@@ -544,6 +556,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) | |||
544 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, | 556 | r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, |
545 | RADEON_VM_PAGE_READABLE | | 557 | RADEON_VM_PAGE_READABLE | |
546 | RADEON_VM_PAGE_SNOOPED); | 558 | RADEON_VM_PAGE_SNOOPED); |
559 | |||
560 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | ||
547 | if (r) { | 561 | if (r) { |
548 | radeon_vm_fini(rdev, &fpriv->vm); | 562 | radeon_vm_fini(rdev, &fpriv->vm); |
549 | kfree(fpriv); | 563 | kfree(fpriv); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 1b783f0e6d3a..15e44a7281ab 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -139,7 +139,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /* 64 dwords should be enough for fence too */ | 141 | /* 64 dwords should be enough for fence too */ |
142 | r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_RINGS * 8); | 142 | r = radeon_ring_lock(rdev, ring, 64 + RADEON_NUM_SYNCS * 8); |
143 | if (r) { | 143 | if (r) { |
144 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); | 144 | dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); |
145 | return r; | 145 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 2b42aa1914f2..9006b32d5eed 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -34,14 +34,15 @@ | |||
34 | int radeon_semaphore_create(struct radeon_device *rdev, | 34 | int radeon_semaphore_create(struct radeon_device *rdev, |
35 | struct radeon_semaphore **semaphore) | 35 | struct radeon_semaphore **semaphore) |
36 | { | 36 | { |
37 | uint32_t *cpu_addr; | ||
37 | int i, r; | 38 | int i, r; |
38 | 39 | ||
39 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); | 40 | *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); |
40 | if (*semaphore == NULL) { | 41 | if (*semaphore == NULL) { |
41 | return -ENOMEM; | 42 | return -ENOMEM; |
42 | } | 43 | } |
43 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, | 44 | r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &(*semaphore)->sa_bo, |
44 | &(*semaphore)->sa_bo, 8, 8, true); | 45 | 8 * RADEON_NUM_SYNCS, 8, true); |
45 | if (r) { | 46 | if (r) { |
46 | kfree(*semaphore); | 47 | kfree(*semaphore); |
47 | *semaphore = NULL; | 48 | *semaphore = NULL; |
@@ -49,7 +50,10 @@ int radeon_semaphore_create(struct radeon_device *rdev, | |||
49 | } | 50 | } |
50 | (*semaphore)->waiters = 0; | 51 | (*semaphore)->waiters = 0; |
51 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); | 52 | (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); |
52 | *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; | 53 | |
54 | cpu_addr = radeon_sa_bo_cpu_addr((*semaphore)->sa_bo); | ||
55 | for (i = 0; i < RADEON_NUM_SYNCS; ++i) | ||
56 | cpu_addr[i] = 0; | ||
53 | 57 | ||
54 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 58 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
55 | (*semaphore)->sync_to[i] = NULL; | 59 | (*semaphore)->sync_to[i] = NULL; |
@@ -125,6 +129,7 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
125 | struct radeon_semaphore *semaphore, | 129 | struct radeon_semaphore *semaphore, |
126 | int ring) | 130 | int ring) |
127 | { | 131 | { |
132 | unsigned count = 0; | ||
128 | int i, r; | 133 | int i, r; |
129 | 134 | ||
130 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 135 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
@@ -140,6 +145,12 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
140 | return -EINVAL; | 145 | return -EINVAL; |
141 | } | 146 | } |
142 | 147 | ||
148 | if (++count > RADEON_NUM_SYNCS) { | ||
149 | /* not enough room, wait manually */ | ||
150 | radeon_fence_wait_locked(fence); | ||
151 | continue; | ||
152 | } | ||
153 | |||
143 | /* allocate enough space for sync command */ | 154 | /* allocate enough space for sync command */ |
144 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); | 155 | r = radeon_ring_alloc(rdev, &rdev->ring[i], 16); |
145 | if (r) { | 156 | if (r) { |
@@ -164,6 +175,8 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
164 | 175 | ||
165 | radeon_ring_commit(rdev, &rdev->ring[i]); | 176 | radeon_ring_commit(rdev, &rdev->ring[i]); |
166 | radeon_fence_note_sync(fence, ring); | 177 | radeon_fence_note_sync(fence, ring); |
178 | |||
179 | semaphore->gpu_addr += 8; | ||
167 | } | 180 | } |
168 | 181 | ||
169 | return 0; | 182 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 77f5b0c3edb8..040a2a10ea17 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -714,6 +714,9 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
714 | DRM_ERROR("Failed initializing VRAM heap.\n"); | 714 | DRM_ERROR("Failed initializing VRAM heap.\n"); |
715 | return r; | 715 | return r; |
716 | } | 716 | } |
717 | /* Change the size here instead of the init above so only lpfn is affected */ | ||
718 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | ||
719 | |||
717 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, | 720 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, |
718 | RADEON_GEM_DOMAIN_VRAM, | 721 | RADEON_GEM_DOMAIN_VRAM, |
719 | NULL, &rdev->stollen_vga_memory); | 722 | NULL, &rdev->stollen_vga_memory); |
@@ -935,7 +938,7 @@ static ssize_t radeon_ttm_gtt_read(struct file *f, char __user *buf, | |||
935 | while (size) { | 938 | while (size) { |
936 | loff_t p = *pos / PAGE_SIZE; | 939 | loff_t p = *pos / PAGE_SIZE; |
937 | unsigned off = *pos & ~PAGE_MASK; | 940 | unsigned off = *pos & ~PAGE_MASK; |
938 | ssize_t cur_size = min(size, PAGE_SIZE - off); | 941 | size_t cur_size = min_t(size_t, size, PAGE_SIZE - off); |
939 | struct page *page; | 942 | struct page *page; |
940 | void *ptr; | 943 | void *ptr; |
941 | 944 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 6781fee1eaad..3e6804b2b2ef 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -171,6 +171,8 @@ void radeon_uvd_fini(struct radeon_device *rdev) | |||
171 | 171 | ||
172 | radeon_bo_unref(&rdev->uvd.vcpu_bo); | 172 | radeon_bo_unref(&rdev->uvd.vcpu_bo); |
173 | 173 | ||
174 | radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX]); | ||
175 | |||
174 | release_firmware(rdev->uvd_fw); | 176 | release_firmware(rdev->uvd_fw); |
175 | } | 177 | } |
176 | 178 | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 20bfbda7b3f1..ec0c6829c1dc 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -18,6 +18,7 @@ r600 0x9400 | |||
18 | 0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL | 18 | 0x00028A3C VGT_GROUP_VECT_1_FMT_CNTL |
19 | 0x00028A40 VGT_GS_MODE | 19 | 0x00028A40 VGT_GS_MODE |
20 | 0x00028A6C VGT_GS_OUT_PRIM_TYPE | 20 | 0x00028A6C VGT_GS_OUT_PRIM_TYPE |
21 | 0x00028B38 VGT_GS_MAX_VERT_OUT | ||
21 | 0x000088C8 VGT_GS_PER_ES | 22 | 0x000088C8 VGT_GS_PER_ES |
22 | 0x000088E8 VGT_GS_PER_VS | 23 | 0x000088E8 VGT_GS_PER_VS |
23 | 0x000088D4 VGT_GS_VERTEX_REUSE | 24 | 0x000088D4 VGT_GS_VERTEX_REUSE |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index b5c2369cda2f..130d5cc50d43 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -474,8 +474,6 @@ int rs400_resume(struct radeon_device *rdev) | |||
474 | /* Initialize surface registers */ | 474 | /* Initialize surface registers */ |
475 | radeon_surface_init(rdev); | 475 | radeon_surface_init(rdev); |
476 | 476 | ||
477 | radeon_pm_resume(rdev); | ||
478 | |||
479 | rdev->accel_working = true; | 477 | rdev->accel_working = true; |
480 | r = rs400_startup(rdev); | 478 | r = rs400_startup(rdev); |
481 | if (r) { | 479 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index fdcde7693032..72d3616de08e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -1048,8 +1048,6 @@ int rs600_resume(struct radeon_device *rdev) | |||
1048 | /* Initialize surface registers */ | 1048 | /* Initialize surface registers */ |
1049 | radeon_surface_init(rdev); | 1049 | radeon_surface_init(rdev); |
1050 | 1050 | ||
1051 | radeon_pm_resume(rdev); | ||
1052 | |||
1053 | rdev->accel_working = true; | 1051 | rdev->accel_working = true; |
1054 | r = rs600_startup(rdev); | 1052 | r = rs600_startup(rdev); |
1055 | if (r) { | 1053 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 35950738bd5e..3462b64369bf 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
@@ -756,8 +756,6 @@ int rs690_resume(struct radeon_device *rdev) | |||
756 | /* Initialize surface registers */ | 756 | /* Initialize surface registers */ |
757 | radeon_surface_init(rdev); | 757 | radeon_surface_init(rdev); |
758 | 758 | ||
759 | radeon_pm_resume(rdev); | ||
760 | |||
761 | rdev->accel_working = true; | 759 | rdev->accel_working = true; |
762 | r = rs690_startup(rdev); | 760 | r = rs690_startup(rdev); |
763 | if (r) { | 761 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 98e8138ff779..237dd29d9f1c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -586,8 +586,6 @@ int rv515_resume(struct radeon_device *rdev) | |||
586 | /* Initialize surface registers */ | 586 | /* Initialize surface registers */ |
587 | radeon_surface_init(rdev); | 587 | radeon_surface_init(rdev); |
588 | 588 | ||
589 | radeon_pm_resume(rdev); | ||
590 | |||
591 | rdev->accel_working = true; | 589 | rdev->accel_working = true; |
592 | r = rv515_startup(rdev); | 590 | r = rv515_startup(rdev); |
593 | if (r) { | 591 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 6c772e58c784..fef310773aad 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1811,7 +1811,8 @@ int rv770_resume(struct radeon_device *rdev) | |||
1811 | /* init golden registers */ | 1811 | /* init golden registers */ |
1812 | rv770_init_golden_registers(rdev); | 1812 | rv770_init_golden_registers(rdev); |
1813 | 1813 | ||
1814 | radeon_pm_resume(rdev); | 1814 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
1815 | radeon_pm_resume(rdev); | ||
1815 | 1816 | ||
1816 | rdev->accel_working = true; | 1817 | rdev->accel_working = true; |
1817 | r = rv770_startup(rdev); | 1818 | r = rv770_startup(rdev); |
@@ -1955,9 +1956,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
1955 | radeon_wb_fini(rdev); | 1956 | radeon_wb_fini(rdev); |
1956 | radeon_ib_pool_fini(rdev); | 1957 | radeon_ib_pool_fini(rdev); |
1957 | radeon_irq_kms_fini(rdev); | 1958 | radeon_irq_kms_fini(rdev); |
1958 | rv770_pcie_gart_fini(rdev); | ||
1959 | uvd_v1_0_fini(rdev); | 1959 | uvd_v1_0_fini(rdev); |
1960 | radeon_uvd_fini(rdev); | 1960 | radeon_uvd_fini(rdev); |
1961 | rv770_pcie_gart_fini(rdev); | ||
1961 | r600_vram_scratch_fini(rdev); | 1962 | r600_vram_scratch_fini(rdev); |
1962 | radeon_gem_fini(rdev); | 1963 | radeon_gem_fini(rdev); |
1963 | radeon_fence_driver_fini(rdev); | 1964 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 80c595aba359..b5f63f5e22a3 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2174,7 +2174,6 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2174 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2174 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
2175 | struct rv7xx_ps *ps = rv770_get_ps(rps); | 2175 | struct rv7xx_ps *ps = rv770_get_ps(rps); |
2176 | u32 sclk, mclk; | 2176 | u32 sclk, mclk; |
2177 | u16 vddc; | ||
2178 | struct rv7xx_pl *pl; | 2177 | struct rv7xx_pl *pl; |
2179 | 2178 | ||
2180 | switch (index) { | 2179 | switch (index) { |
@@ -2214,8 +2213,8 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2214 | 2213 | ||
2215 | /* patch up vddc if necessary */ | 2214 | /* patch up vddc if necessary */ |
2216 | if (pl->vddc == 0xff01) { | 2215 | if (pl->vddc == 0xff01) { |
2217 | if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) | 2216 | if (pi->max_vddc) |
2218 | pl->vddc = vddc; | 2217 | pl->vddc = pi->max_vddc; |
2219 | } | 2218 | } |
2220 | 2219 | ||
2221 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { | 2220 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { |
@@ -2527,14 +2526,7 @@ u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low) | |||
2527 | bool rv770_dpm_vblank_too_short(struct radeon_device *rdev) | 2526 | bool rv770_dpm_vblank_too_short(struct radeon_device *rdev) |
2528 | { | 2527 | { |
2529 | u32 vblank_time = r600_dpm_get_vblank_time(rdev); | 2528 | u32 vblank_time = r600_dpm_get_vblank_time(rdev); |
2530 | u32 switch_limit = 300; | 2529 | u32 switch_limit = 200; /* 300 */ |
2531 | |||
2532 | /* quirks */ | ||
2533 | /* ASUS K70AF */ | ||
2534 | if ((rdev->pdev->device == 0x9553) && | ||
2535 | (rdev->pdev->subsystem_vendor == 0x1043) && | ||
2536 | (rdev->pdev->subsystem_device == 0x1c42)) | ||
2537 | switch_limit = 200; | ||
2538 | 2530 | ||
2539 | /* RV770 */ | 2531 | /* RV770 */ |
2540 | /* mclk switching doesn't seem to work reliably on desktop RV770s */ | 2532 | /* mclk switching doesn't seem to work reliably on desktop RV770s */ |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 09ec4f6c53bb..9a124d0608b3 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -6338,6 +6338,10 @@ restart_ih: | |||
6338 | break; | 6338 | break; |
6339 | } | 6339 | } |
6340 | break; | 6340 | break; |
6341 | case 124: /* UVD */ | ||
6342 | DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); | ||
6343 | radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); | ||
6344 | break; | ||
6341 | case 146: | 6345 | case 146: |
6342 | case 147: | 6346 | case 147: |
6343 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | 6347 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); |
@@ -6614,7 +6618,8 @@ int si_resume(struct radeon_device *rdev) | |||
6614 | /* init golden registers */ | 6618 | /* init golden registers */ |
6615 | si_init_golden_registers(rdev); | 6619 | si_init_golden_registers(rdev); |
6616 | 6620 | ||
6617 | radeon_pm_resume(rdev); | 6621 | if (rdev->pm.pm_method == PM_METHOD_DPM) |
6622 | radeon_pm_resume(rdev); | ||
6618 | 6623 | ||
6619 | rdev->accel_working = true; | 6624 | rdev->accel_working = true; |
6620 | r = si_startup(rdev); | 6625 | r = si_startup(rdev); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 0471501338fb..0a2f5b4bca43 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2395,7 +2395,7 @@ static int si_populate_sq_ramping_values(struct radeon_device *rdev, | |||
2395 | if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) | 2395 | if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT)) |
2396 | enable_sq_ramping = false; | 2396 | enable_sq_ramping = false; |
2397 | 2397 | ||
2398 | if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) | 2398 | if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT)) |
2399 | enable_sq_ramping = false; | 2399 | enable_sq_ramping = false; |
2400 | 2400 | ||
2401 | for (i = 0; i < state->performance_level_count; i++) { | 2401 | for (i = 0; i < state->performance_level_count; i++) { |
@@ -6472,7 +6472,8 @@ void si_dpm_fini(struct radeon_device *rdev) | |||
6472 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 6472 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
6473 | struct seq_file *m) | 6473 | struct seq_file *m) |
6474 | { | 6474 | { |
6475 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 6475 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
6476 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
6476 | struct ni_ps *ps = ni_get_ps(rps); | 6477 | struct ni_ps *ps = ni_get_ps(rps); |
6477 | struct rv7xx_pl *pl; | 6478 | struct rv7xx_pl *pl; |
6478 | u32 current_index = | 6479 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index f121efe12dc5..8b47b3cd0357 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c | |||
@@ -1807,7 +1807,7 @@ void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev | |||
1807 | struct seq_file *m) | 1807 | struct seq_file *m) |
1808 | { | 1808 | { |
1809 | struct sumo_power_info *pi = sumo_get_pi(rdev); | 1809 | struct sumo_power_info *pi = sumo_get_pi(rdev); |
1810 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 1810 | struct radeon_ps *rps = &pi->current_rps; |
1811 | struct sumo_ps *ps = sumo_get_ps(rps); | 1811 | struct sumo_ps *ps = sumo_get_ps(rps); |
1812 | struct sumo_pl *pl; | 1812 | struct sumo_pl *pl; |
1813 | u32 current_index = | 1813 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 2d447192d6f7..2da0e17eb960 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
@@ -1926,7 +1926,8 @@ void trinity_dpm_print_power_state(struct radeon_device *rdev, | |||
1926 | void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 1926 | void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
1927 | struct seq_file *m) | 1927 | struct seq_file *m) |
1928 | { | 1928 | { |
1929 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 1929 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
1930 | struct radeon_ps *rps = &pi->current_rps; | ||
1930 | struct trinity_ps *ps = trinity_get_ps(rps); | 1931 | struct trinity_ps *ps = trinity_get_ps(rps); |
1931 | struct trinity_pl *pl; | 1932 | struct trinity_pl *pl; |
1932 | u32 current_index = | 1933 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 824550db3fed..d1771004cb52 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c | |||
@@ -57,7 +57,6 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, | |||
57 | radeon_ring_write(ring, 0); | 57 | radeon_ring_write(ring, 0); |
58 | radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); | 58 | radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); |
59 | radeon_ring_write(ring, 2); | 59 | radeon_ring_write(ring, 2); |
60 | return; | ||
61 | } | 60 | } |
62 | 61 | ||
63 | /** | 62 | /** |
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index 88a529008ce0..c71594754f46 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
@@ -104,7 +104,7 @@ static void tegra_drm_context_free(struct tegra_drm_context *context) | |||
104 | 104 | ||
105 | static void tegra_drm_lastclose(struct drm_device *drm) | 105 | static void tegra_drm_lastclose(struct drm_device *drm) |
106 | { | 106 | { |
107 | #ifdef CONFIG_TEGRA_DRM_FBDEV | 107 | #ifdef CONFIG_DRM_TEGRA_FBDEV |
108 | struct tegra_drm *tegra = drm->dev_private; | 108 | struct tegra_drm *tegra = drm->dev_private; |
109 | 109 | ||
110 | tegra_fbdev_restore_mode(tegra->fbdev); | 110 | tegra_fbdev_restore_mode(tegra->fbdev); |
diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c index 338f7f6561d7..0266fb40479e 100644 --- a/drivers/gpu/drm/tegra/rgb.c +++ b/drivers/gpu/drm/tegra/rgb.c | |||
@@ -15,6 +15,7 @@ | |||
15 | struct tegra_rgb { | 15 | struct tegra_rgb { |
16 | struct tegra_output output; | 16 | struct tegra_output output; |
17 | struct tegra_dc *dc; | 17 | struct tegra_dc *dc; |
18 | bool enabled; | ||
18 | 19 | ||
19 | struct clk *clk_parent; | 20 | struct clk *clk_parent; |
20 | struct clk *clk; | 21 | struct clk *clk; |
@@ -89,6 +90,9 @@ static int tegra_output_rgb_enable(struct tegra_output *output) | |||
89 | struct tegra_rgb *rgb = to_rgb(output); | 90 | struct tegra_rgb *rgb = to_rgb(output); |
90 | unsigned long value; | 91 | unsigned long value; |
91 | 92 | ||
93 | if (rgb->enabled) | ||
94 | return 0; | ||
95 | |||
92 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); | 96 | tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable)); |
93 | 97 | ||
94 | value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; | 98 | value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL; |
@@ -122,6 +126,8 @@ static int tegra_output_rgb_enable(struct tegra_output *output) | |||
122 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); | 126 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL); |
123 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); | 127 | tegra_dc_writel(rgb->dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL); |
124 | 128 | ||
129 | rgb->enabled = true; | ||
130 | |||
125 | return 0; | 131 | return 0; |
126 | } | 132 | } |
127 | 133 | ||
@@ -130,6 +136,9 @@ static int tegra_output_rgb_disable(struct tegra_output *output) | |||
130 | struct tegra_rgb *rgb = to_rgb(output); | 136 | struct tegra_rgb *rgb = to_rgb(output); |
131 | unsigned long value; | 137 | unsigned long value; |
132 | 138 | ||
139 | if (!rgb->enabled) | ||
140 | return 0; | ||
141 | |||
133 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); | 142 | value = tegra_dc_readl(rgb->dc, DC_CMD_DISPLAY_POWER_CONTROL); |
134 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | | 143 | value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE | |
135 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); | 144 | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE); |
@@ -144,6 +153,8 @@ static int tegra_output_rgb_disable(struct tegra_output *output) | |||
144 | 153 | ||
145 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); | 154 | tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable)); |
146 | 155 | ||
156 | rgb->enabled = false; | ||
157 | |||
147 | return 0; | 158 | return 0; |
148 | } | 159 | } |
149 | 160 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index 3302f99e7497..764be36397fd 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c | |||
@@ -126,6 +126,7 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev, | |||
126 | agp_be->ttm.func = &ttm_agp_func; | 126 | agp_be->ttm.func = &ttm_agp_func; |
127 | 127 | ||
128 | if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) { | 128 | if (ttm_tt_init(&agp_be->ttm, bdev, size, page_flags, dummy_read_page)) { |
129 | kfree(agp_be); | ||
129 | return NULL; | 130 | return NULL; |
130 | } | 131 | } |
131 | 132 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a06651309388..214b7992a3aa 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -351,9 +351,11 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
351 | 351 | ||
352 | moved: | 352 | moved: |
353 | if (bo->evicted) { | 353 | if (bo->evicted) { |
354 | ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); | 354 | if (bdev->driver->invalidate_caches) { |
355 | if (ret) | 355 | ret = bdev->driver->invalidate_caches(bdev, bo->mem.placement); |
356 | pr_err("Can not flush read caches\n"); | 356 | if (ret) |
357 | pr_err("Can not flush read caches\n"); | ||
358 | } | ||
357 | bo->evicted = false; | 359 | bo->evicted = false; |
358 | } | 360 | } |
359 | 361 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 801231c9ae48..0ce48e5a9cb4 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -339,11 +339,13 @@ int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, | |||
339 | vma->vm_private_data = bo; | 339 | vma->vm_private_data = bo; |
340 | 340 | ||
341 | /* | 341 | /* |
342 | * PFNMAP is faster than MIXEDMAP due to reduced page | 342 | * We'd like to use VM_PFNMAP on shared mappings, where |
343 | * administration. So use MIXEDMAP only if private VMA, where | 343 | * (vma->vm_flags & VM_SHARED) != 0, for performance reasons, |
344 | * we need to support COW. | 344 | * but for some reason VM_PFNMAP + x86 PAT + write-combine is very |
345 | * bad for performance. Until that has been sorted out, use | ||
346 | * VM_MIXEDMAP on all mappings. See freedesktop.org bug #75719 | ||
345 | */ | 347 | */ |
346 | vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP; | 348 | vma->vm_flags |= VM_MIXEDMAP; |
347 | vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; | 349 | vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; |
348 | return 0; | 350 | return 0; |
349 | out_unref: | 351 | out_unref: |
@@ -359,7 +361,7 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo) | |||
359 | 361 | ||
360 | vma->vm_ops = &ttm_bo_vm_ops; | 362 | vma->vm_ops = &ttm_bo_vm_ops; |
361 | vma->vm_private_data = ttm_bo_reference(bo); | 363 | vma->vm_private_data = ttm_bo_reference(bo); |
362 | vma->vm_flags |= (vma->vm_flags & VM_SHARED) ? VM_PFNMAP : VM_MIXEDMAP; | 364 | vma->vm_flags |= VM_MIXEDMAP; |
363 | vma->vm_flags |= VM_IO | VM_DONTEXPAND; | 365 | vma->vm_flags |= VM_IO | VM_DONTEXPAND; |
364 | return 0; | 366 | return 0; |
365 | } | 367 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_object.c b/drivers/gpu/drm/ttm/ttm_object.c index 37079859afc8..53b51c4e671a 100644 --- a/drivers/gpu/drm/ttm/ttm_object.c +++ b/drivers/gpu/drm/ttm/ttm_object.c | |||
@@ -292,7 +292,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, | |||
292 | 292 | ||
293 | if (ret == 0) { | 293 | if (ret == 0) { |
294 | ref = drm_hash_entry(hash, struct ttm_ref_object, hash); | 294 | ref = drm_hash_entry(hash, struct ttm_ref_object, hash); |
295 | if (!kref_get_unless_zero(&ref->kref)) { | 295 | if (kref_get_unless_zero(&ref->kref)) { |
296 | rcu_read_unlock(); | 296 | rcu_read_unlock(); |
297 | break; | 297 | break; |
298 | } | 298 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 9af99084b344..75f319090043 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -380,6 +380,9 @@ static void ttm_tt_clear_mapping(struct ttm_tt *ttm) | |||
380 | pgoff_t i; | 380 | pgoff_t i; |
381 | struct page **page = ttm->pages; | 381 | struct page **page = ttm->pages; |
382 | 382 | ||
383 | if (ttm->page_flags & TTM_PAGE_FLAG_SG) | ||
384 | return; | ||
385 | |||
383 | for (i = 0; i < ttm->num_pages; ++i) { | 386 | for (i = 0; i < ttm->num_pages; ++i) { |
384 | (*page)->mapping = NULL; | 387 | (*page)->mapping = NULL; |
385 | (*page++)->index = 0; | 388 | (*page++)->index = 0; |
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_reg.h b/drivers/gpu/drm/vmwgfx/svga3d_reg.h index d95335cb90bd..f58dc7dd15c5 100644 --- a/drivers/gpu/drm/vmwgfx/svga3d_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga3d_reg.h | |||
@@ -261,12 +261,7 @@ typedef enum SVGA3dSurfaceFormat { | |||
261 | /* Planar video formats. */ | 261 | /* Planar video formats. */ |
262 | SVGA3D_YV12 = 121, | 262 | SVGA3D_YV12 = 121, |
263 | 263 | ||
264 | /* Shader constant formats. */ | 264 | SVGA3D_FORMAT_MAX = 122, |
265 | SVGA3D_SURFACE_SHADERCONST_FLOAT = 122, | ||
266 | SVGA3D_SURFACE_SHADERCONST_INT = 123, | ||
267 | SVGA3D_SURFACE_SHADERCONST_BOOL = 124, | ||
268 | |||
269 | SVGA3D_FORMAT_MAX = 125, | ||
270 | } SVGA3dSurfaceFormat; | 265 | } SVGA3dSurfaceFormat; |
271 | 266 | ||
272 | typedef uint32 SVGA3dColor; /* a, r, g, b */ | 267 | typedef uint32 SVGA3dColor; /* a, r, g, b */ |
@@ -1223,9 +1218,19 @@ typedef enum { | |||
1223 | #define SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL 1129 | 1218 | #define SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL 1129 |
1224 | 1219 | ||
1225 | #define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 | 1220 | #define SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE 1130 |
1226 | 1221 | #define SVGA_3D_CMD_GB_SCREEN_DMA 1131 | |
1222 | #define SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH 1132 | ||
1223 | #define SVGA_3D_CMD_GB_MOB_FENCE 1133 | ||
1224 | #define SVGA_3D_CMD_DEFINE_GB_SURFACE_V2 1134 | ||
1227 | #define SVGA_3D_CMD_DEFINE_GB_MOB64 1135 | 1225 | #define SVGA_3D_CMD_DEFINE_GB_MOB64 1135 |
1228 | #define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136 | 1226 | #define SVGA_3D_CMD_REDEFINE_GB_MOB64 1136 |
1227 | #define SVGA_3D_CMD_NOP_ERROR 1137 | ||
1228 | |||
1229 | #define SVGA_3D_CMD_RESERVED1 1138 | ||
1230 | #define SVGA_3D_CMD_RESERVED2 1139 | ||
1231 | #define SVGA_3D_CMD_RESERVED3 1140 | ||
1232 | #define SVGA_3D_CMD_RESERVED4 1141 | ||
1233 | #define SVGA_3D_CMD_RESERVED5 1142 | ||
1229 | 1234 | ||
1230 | #define SVGA_3D_CMD_MAX 1142 | 1235 | #define SVGA_3D_CMD_MAX 1142 |
1231 | #define SVGA_3D_CMD_FUTURE_MAX 3000 | 1236 | #define SVGA_3D_CMD_FUTURE_MAX 3000 |
@@ -1973,8 +1978,7 @@ struct { | |||
1973 | uint32 sizeInBytes; | 1978 | uint32 sizeInBytes; |
1974 | uint32 validSizeInBytes; | 1979 | uint32 validSizeInBytes; |
1975 | SVGAMobFormat ptDepth; | 1980 | SVGAMobFormat ptDepth; |
1976 | } | 1981 | } __packed |
1977 | __attribute__((__packed__)) | ||
1978 | SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */ | 1982 | SVGA3dCmdSetOTableBase; /* SVGA_3D_CMD_SET_OTABLE_BASE */ |
1979 | 1983 | ||
1980 | typedef | 1984 | typedef |
@@ -1984,15 +1988,13 @@ struct { | |||
1984 | uint32 sizeInBytes; | 1988 | uint32 sizeInBytes; |
1985 | uint32 validSizeInBytes; | 1989 | uint32 validSizeInBytes; |
1986 | SVGAMobFormat ptDepth; | 1990 | SVGAMobFormat ptDepth; |
1987 | } | 1991 | } __packed |
1988 | __attribute__((__packed__)) | ||
1989 | SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */ | 1992 | SVGA3dCmdSetOTableBase64; /* SVGA_3D_CMD_SET_OTABLE_BASE64 */ |
1990 | 1993 | ||
1991 | typedef | 1994 | typedef |
1992 | struct { | 1995 | struct { |
1993 | SVGAOTableType type; | 1996 | SVGAOTableType type; |
1994 | } | 1997 | } __packed |
1995 | __attribute__((__packed__)) | ||
1996 | SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */ | 1998 | SVGA3dCmdReadbackOTable; /* SVGA_3D_CMD_READBACK_OTABLE */ |
1997 | 1999 | ||
1998 | /* | 2000 | /* |
@@ -2005,8 +2007,7 @@ struct SVGA3dCmdDefineGBMob { | |||
2005 | SVGAMobFormat ptDepth; | 2007 | SVGAMobFormat ptDepth; |
2006 | PPN base; | 2008 | PPN base; |
2007 | uint32 sizeInBytes; | 2009 | uint32 sizeInBytes; |
2008 | } | 2010 | } __packed |
2009 | __attribute__((__packed__)) | ||
2010 | SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ | 2011 | SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ |
2011 | 2012 | ||
2012 | 2013 | ||
@@ -2017,8 +2018,7 @@ SVGA3dCmdDefineGBMob; /* SVGA_3D_CMD_DEFINE_GB_MOB */ | |||
2017 | typedef | 2018 | typedef |
2018 | struct SVGA3dCmdDestroyGBMob { | 2019 | struct SVGA3dCmdDestroyGBMob { |
2019 | SVGAMobId mobid; | 2020 | SVGAMobId mobid; |
2020 | } | 2021 | } __packed |
2021 | __attribute__((__packed__)) | ||
2022 | SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ | 2022 | SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ |
2023 | 2023 | ||
2024 | /* | 2024 | /* |
@@ -2031,8 +2031,7 @@ struct SVGA3dCmdRedefineGBMob { | |||
2031 | SVGAMobFormat ptDepth; | 2031 | SVGAMobFormat ptDepth; |
2032 | PPN base; | 2032 | PPN base; |
2033 | uint32 sizeInBytes; | 2033 | uint32 sizeInBytes; |
2034 | } | 2034 | } __packed |
2035 | __attribute__((__packed__)) | ||
2036 | SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ | 2035 | SVGA3dCmdRedefineGBMob; /* SVGA_3D_CMD_REDEFINE_GB_MOB */ |
2037 | 2036 | ||
2038 | /* | 2037 | /* |
@@ -2045,8 +2044,7 @@ struct SVGA3dCmdDefineGBMob64 { | |||
2045 | SVGAMobFormat ptDepth; | 2044 | SVGAMobFormat ptDepth; |
2046 | PPN64 base; | 2045 | PPN64 base; |
2047 | uint32 sizeInBytes; | 2046 | uint32 sizeInBytes; |
2048 | } | 2047 | } __packed |
2049 | __attribute__((__packed__)) | ||
2050 | SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */ | 2048 | SVGA3dCmdDefineGBMob64; /* SVGA_3D_CMD_DEFINE_GB_MOB64 */ |
2051 | 2049 | ||
2052 | /* | 2050 | /* |
@@ -2059,8 +2057,7 @@ struct SVGA3dCmdRedefineGBMob64 { | |||
2059 | SVGAMobFormat ptDepth; | 2057 | SVGAMobFormat ptDepth; |
2060 | PPN64 base; | 2058 | PPN64 base; |
2061 | uint32 sizeInBytes; | 2059 | uint32 sizeInBytes; |
2062 | } | 2060 | } __packed |
2063 | __attribute__((__packed__)) | ||
2064 | SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ | 2061 | SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ |
2065 | 2062 | ||
2066 | /* | 2063 | /* |
@@ -2070,8 +2067,7 @@ SVGA3dCmdRedefineGBMob64; /* SVGA_3D_CMD_REDEFINE_GB_MOB64 */ | |||
2070 | typedef | 2067 | typedef |
2071 | struct SVGA3dCmdUpdateGBMobMapping { | 2068 | struct SVGA3dCmdUpdateGBMobMapping { |
2072 | SVGAMobId mobid; | 2069 | SVGAMobId mobid; |
2073 | } | 2070 | } __packed |
2074 | __attribute__((__packed__)) | ||
2075 | SVGA3dCmdUpdateGBMobMapping; /* SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING */ | 2071 | SVGA3dCmdUpdateGBMobMapping; /* SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING */ |
2076 | 2072 | ||
2077 | /* | 2073 | /* |
@@ -2087,7 +2083,8 @@ struct SVGA3dCmdDefineGBSurface { | |||
2087 | uint32 multisampleCount; | 2083 | uint32 multisampleCount; |
2088 | SVGA3dTextureFilter autogenFilter; | 2084 | SVGA3dTextureFilter autogenFilter; |
2089 | SVGA3dSize size; | 2085 | SVGA3dSize size; |
2090 | } SVGA3dCmdDefineGBSurface; /* SVGA_3D_CMD_DEFINE_GB_SURFACE */ | 2086 | } __packed |
2087 | SVGA3dCmdDefineGBSurface; /* SVGA_3D_CMD_DEFINE_GB_SURFACE */ | ||
2091 | 2088 | ||
2092 | /* | 2089 | /* |
2093 | * Destroy a guest-backed surface. | 2090 | * Destroy a guest-backed surface. |
@@ -2096,7 +2093,8 @@ struct SVGA3dCmdDefineGBSurface { | |||
2096 | typedef | 2093 | typedef |
2097 | struct SVGA3dCmdDestroyGBSurface { | 2094 | struct SVGA3dCmdDestroyGBSurface { |
2098 | uint32 sid; | 2095 | uint32 sid; |
2099 | } SVGA3dCmdDestroyGBSurface; /* SVGA_3D_CMD_DESTROY_GB_SURFACE */ | 2096 | } __packed |
2097 | SVGA3dCmdDestroyGBSurface; /* SVGA_3D_CMD_DESTROY_GB_SURFACE */ | ||
2100 | 2098 | ||
2101 | /* | 2099 | /* |
2102 | * Bind a guest-backed surface to an object. | 2100 | * Bind a guest-backed surface to an object. |
@@ -2106,7 +2104,8 @@ typedef | |||
2106 | struct SVGA3dCmdBindGBSurface { | 2104 | struct SVGA3dCmdBindGBSurface { |
2107 | uint32 sid; | 2105 | uint32 sid; |
2108 | SVGAMobId mobid; | 2106 | SVGAMobId mobid; |
2109 | } SVGA3dCmdBindGBSurface; /* SVGA_3D_CMD_BIND_GB_SURFACE */ | 2107 | } __packed |
2108 | SVGA3dCmdBindGBSurface; /* SVGA_3D_CMD_BIND_GB_SURFACE */ | ||
2110 | 2109 | ||
2111 | /* | 2110 | /* |
2112 | * Conditionally bind a mob to a guest backed surface if testMobid | 2111 | * Conditionally bind a mob to a guest backed surface if testMobid |
@@ -2123,7 +2122,7 @@ struct{ | |||
2123 | SVGAMobId testMobid; | 2122 | SVGAMobId testMobid; |
2124 | SVGAMobId mobid; | 2123 | SVGAMobId mobid; |
2125 | uint32 flags; | 2124 | uint32 flags; |
2126 | } | 2125 | } __packed |
2127 | SVGA3dCmdCondBindGBSurface; /* SVGA_3D_CMD_COND_BIND_GB_SURFACE */ | 2126 | SVGA3dCmdCondBindGBSurface; /* SVGA_3D_CMD_COND_BIND_GB_SURFACE */ |
2128 | 2127 | ||
2129 | /* | 2128 | /* |
@@ -2135,7 +2134,8 @@ typedef | |||
2135 | struct SVGA3dCmdUpdateGBImage { | 2134 | struct SVGA3dCmdUpdateGBImage { |
2136 | SVGA3dSurfaceImageId image; | 2135 | SVGA3dSurfaceImageId image; |
2137 | SVGA3dBox box; | 2136 | SVGA3dBox box; |
2138 | } SVGA3dCmdUpdateGBImage; /* SVGA_3D_CMD_UPDATE_GB_IMAGE */ | 2137 | } __packed |
2138 | SVGA3dCmdUpdateGBImage; /* SVGA_3D_CMD_UPDATE_GB_IMAGE */ | ||
2139 | 2139 | ||
2140 | /* | 2140 | /* |
2141 | * Update an entire guest-backed surface. | 2141 | * Update an entire guest-backed surface. |
@@ -2145,7 +2145,8 @@ struct SVGA3dCmdUpdateGBImage { | |||
2145 | typedef | 2145 | typedef |
2146 | struct SVGA3dCmdUpdateGBSurface { | 2146 | struct SVGA3dCmdUpdateGBSurface { |
2147 | uint32 sid; | 2147 | uint32 sid; |
2148 | } SVGA3dCmdUpdateGBSurface; /* SVGA_3D_CMD_UPDATE_GB_SURFACE */ | 2148 | } __packed |
2149 | SVGA3dCmdUpdateGBSurface; /* SVGA_3D_CMD_UPDATE_GB_SURFACE */ | ||
2149 | 2150 | ||
2150 | /* | 2151 | /* |
2151 | * Readback an image in a guest-backed surface. | 2152 | * Readback an image in a guest-backed surface. |
@@ -2155,7 +2156,8 @@ struct SVGA3dCmdUpdateGBSurface { | |||
2155 | typedef | 2156 | typedef |
2156 | struct SVGA3dCmdReadbackGBImage { | 2157 | struct SVGA3dCmdReadbackGBImage { |
2157 | SVGA3dSurfaceImageId image; | 2158 | SVGA3dSurfaceImageId image; |
2158 | } SVGA3dCmdReadbackGBImage; /* SVGA_3D_CMD_READBACK_GB_IMAGE*/ | 2159 | } __packed |
2160 | SVGA3dCmdReadbackGBImage; /* SVGA_3D_CMD_READBACK_GB_IMAGE*/ | ||
2159 | 2161 | ||
2160 | /* | 2162 | /* |
2161 | * Readback an entire guest-backed surface. | 2163 | * Readback an entire guest-backed surface. |
@@ -2165,7 +2167,8 @@ struct SVGA3dCmdReadbackGBImage { | |||
2165 | typedef | 2167 | typedef |
2166 | struct SVGA3dCmdReadbackGBSurface { | 2168 | struct SVGA3dCmdReadbackGBSurface { |
2167 | uint32 sid; | 2169 | uint32 sid; |
2168 | } SVGA3dCmdReadbackGBSurface; /* SVGA_3D_CMD_READBACK_GB_SURFACE */ | 2170 | } __packed |
2171 | SVGA3dCmdReadbackGBSurface; /* SVGA_3D_CMD_READBACK_GB_SURFACE */ | ||
2169 | 2172 | ||
2170 | /* | 2173 | /* |
2171 | * Readback a sub rect of an image in a guest-backed surface. After | 2174 | * Readback a sub rect of an image in a guest-backed surface. After |
@@ -2179,7 +2182,7 @@ struct SVGA3dCmdReadbackGBImagePartial { | |||
2179 | SVGA3dSurfaceImageId image; | 2182 | SVGA3dSurfaceImageId image; |
2180 | SVGA3dBox box; | 2183 | SVGA3dBox box; |
2181 | uint32 invertBox; | 2184 | uint32 invertBox; |
2182 | } | 2185 | } __packed |
2183 | SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ | 2186 | SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ |
2184 | 2187 | ||
2185 | /* | 2188 | /* |
@@ -2190,7 +2193,8 @@ SVGA3dCmdReadbackGBImagePartial; /* SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL */ | |||
2190 | typedef | 2193 | typedef |
2191 | struct SVGA3dCmdInvalidateGBImage { | 2194 | struct SVGA3dCmdInvalidateGBImage { |
2192 | SVGA3dSurfaceImageId image; | 2195 | SVGA3dSurfaceImageId image; |
2193 | } SVGA3dCmdInvalidateGBImage; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE */ | 2196 | } __packed |
2197 | SVGA3dCmdInvalidateGBImage; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE */ | ||
2194 | 2198 | ||
2195 | /* | 2199 | /* |
2196 | * Invalidate an entire guest-backed surface. | 2200 | * Invalidate an entire guest-backed surface. |
@@ -2200,7 +2204,8 @@ struct SVGA3dCmdInvalidateGBImage { | |||
2200 | typedef | 2204 | typedef |
2201 | struct SVGA3dCmdInvalidateGBSurface { | 2205 | struct SVGA3dCmdInvalidateGBSurface { |
2202 | uint32 sid; | 2206 | uint32 sid; |
2203 | } SVGA3dCmdInvalidateGBSurface; /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE */ | 2207 | } __packed |
2208 | SVGA3dCmdInvalidateGBSurface; /* SVGA_3D_CMD_INVALIDATE_GB_SURFACE */ | ||
2204 | 2209 | ||
2205 | /* | 2210 | /* |
2206 | * Invalidate a sub rect of an image in a guest-backed surface. After | 2211 | * Invalidate a sub rect of an image in a guest-backed surface. After |
@@ -2214,7 +2219,7 @@ struct SVGA3dCmdInvalidateGBImagePartial { | |||
2214 | SVGA3dSurfaceImageId image; | 2219 | SVGA3dSurfaceImageId image; |
2215 | SVGA3dBox box; | 2220 | SVGA3dBox box; |
2216 | uint32 invertBox; | 2221 | uint32 invertBox; |
2217 | } | 2222 | } __packed |
2218 | SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ | 2223 | SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ |
2219 | 2224 | ||
2220 | /* | 2225 | /* |
@@ -2224,7 +2229,8 @@ SVGA3dCmdInvalidateGBImagePartial; /* SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL */ | |||
2224 | typedef | 2229 | typedef |
2225 | struct SVGA3dCmdDefineGBContext { | 2230 | struct SVGA3dCmdDefineGBContext { |
2226 | uint32 cid; | 2231 | uint32 cid; |
2227 | } SVGA3dCmdDefineGBContext; /* SVGA_3D_CMD_DEFINE_GB_CONTEXT */ | 2232 | } __packed |
2233 | SVGA3dCmdDefineGBContext; /* SVGA_3D_CMD_DEFINE_GB_CONTEXT */ | ||
2228 | 2234 | ||
2229 | /* | 2235 | /* |
2230 | * Destroy a guest-backed context. | 2236 | * Destroy a guest-backed context. |
@@ -2233,7 +2239,8 @@ struct SVGA3dCmdDefineGBContext { | |||
2233 | typedef | 2239 | typedef |
2234 | struct SVGA3dCmdDestroyGBContext { | 2240 | struct SVGA3dCmdDestroyGBContext { |
2235 | uint32 cid; | 2241 | uint32 cid; |
2236 | } SVGA3dCmdDestroyGBContext; /* SVGA_3D_CMD_DESTROY_GB_CONTEXT */ | 2242 | } __packed |
2243 | SVGA3dCmdDestroyGBContext; /* SVGA_3D_CMD_DESTROY_GB_CONTEXT */ | ||
2237 | 2244 | ||
2238 | /* | 2245 | /* |
2239 | * Bind a guest-backed context. | 2246 | * Bind a guest-backed context. |
@@ -2252,7 +2259,8 @@ struct SVGA3dCmdBindGBContext { | |||
2252 | uint32 cid; | 2259 | uint32 cid; |
2253 | SVGAMobId mobid; | 2260 | SVGAMobId mobid; |
2254 | uint32 validContents; | 2261 | uint32 validContents; |
2255 | } SVGA3dCmdBindGBContext; /* SVGA_3D_CMD_BIND_GB_CONTEXT */ | 2262 | } __packed |
2263 | SVGA3dCmdBindGBContext; /* SVGA_3D_CMD_BIND_GB_CONTEXT */ | ||
2256 | 2264 | ||
2257 | /* | 2265 | /* |
2258 | * Readback a guest-backed context. | 2266 | * Readback a guest-backed context. |
@@ -2262,7 +2270,8 @@ struct SVGA3dCmdBindGBContext { | |||
2262 | typedef | 2270 | typedef |
2263 | struct SVGA3dCmdReadbackGBContext { | 2271 | struct SVGA3dCmdReadbackGBContext { |
2264 | uint32 cid; | 2272 | uint32 cid; |
2265 | } SVGA3dCmdReadbackGBContext; /* SVGA_3D_CMD_READBACK_GB_CONTEXT */ | 2273 | } __packed |
2274 | SVGA3dCmdReadbackGBContext; /* SVGA_3D_CMD_READBACK_GB_CONTEXT */ | ||
2266 | 2275 | ||
2267 | /* | 2276 | /* |
2268 | * Invalidate a guest-backed context. | 2277 | * Invalidate a guest-backed context. |
@@ -2270,7 +2279,8 @@ struct SVGA3dCmdReadbackGBContext { | |||
2270 | typedef | 2279 | typedef |
2271 | struct SVGA3dCmdInvalidateGBContext { | 2280 | struct SVGA3dCmdInvalidateGBContext { |
2272 | uint32 cid; | 2281 | uint32 cid; |
2273 | } SVGA3dCmdInvalidateGBContext; /* SVGA_3D_CMD_INVALIDATE_GB_CONTEXT */ | 2282 | } __packed |
2283 | SVGA3dCmdInvalidateGBContext; /* SVGA_3D_CMD_INVALIDATE_GB_CONTEXT */ | ||
2274 | 2284 | ||
2275 | /* | 2285 | /* |
2276 | * Define a guest-backed shader. | 2286 | * Define a guest-backed shader. |
@@ -2281,7 +2291,8 @@ struct SVGA3dCmdDefineGBShader { | |||
2281 | uint32 shid; | 2291 | uint32 shid; |
2282 | SVGA3dShaderType type; | 2292 | SVGA3dShaderType type; |
2283 | uint32 sizeInBytes; | 2293 | uint32 sizeInBytes; |
2284 | } SVGA3dCmdDefineGBShader; /* SVGA_3D_CMD_DEFINE_GB_SHADER */ | 2294 | } __packed |
2295 | SVGA3dCmdDefineGBShader; /* SVGA_3D_CMD_DEFINE_GB_SHADER */ | ||
2285 | 2296 | ||
2286 | /* | 2297 | /* |
2287 | * Bind a guest-backed shader. | 2298 | * Bind a guest-backed shader. |
@@ -2291,7 +2302,8 @@ typedef struct SVGA3dCmdBindGBShader { | |||
2291 | uint32 shid; | 2302 | uint32 shid; |
2292 | SVGAMobId mobid; | 2303 | SVGAMobId mobid; |
2293 | uint32 offsetInBytes; | 2304 | uint32 offsetInBytes; |
2294 | } SVGA3dCmdBindGBShader; /* SVGA_3D_CMD_BIND_GB_SHADER */ | 2305 | } __packed |
2306 | SVGA3dCmdBindGBShader; /* SVGA_3D_CMD_BIND_GB_SHADER */ | ||
2295 | 2307 | ||
2296 | /* | 2308 | /* |
2297 | * Destroy a guest-backed shader. | 2309 | * Destroy a guest-backed shader. |
@@ -2299,7 +2311,8 @@ typedef struct SVGA3dCmdBindGBShader { | |||
2299 | 2311 | ||
2300 | typedef struct SVGA3dCmdDestroyGBShader { | 2312 | typedef struct SVGA3dCmdDestroyGBShader { |
2301 | uint32 shid; | 2313 | uint32 shid; |
2302 | } SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ | 2314 | } __packed |
2315 | SVGA3dCmdDestroyGBShader; /* SVGA_3D_CMD_DESTROY_GB_SHADER */ | ||
2303 | 2316 | ||
2304 | typedef | 2317 | typedef |
2305 | struct { | 2318 | struct { |
@@ -2314,14 +2327,16 @@ struct { | |||
2314 | * Note that FLOAT and INT constants are 4-dwords in length, while | 2327 | * Note that FLOAT and INT constants are 4-dwords in length, while |
2315 | * BOOL constants are 1-dword in length. | 2328 | * BOOL constants are 1-dword in length. |
2316 | */ | 2329 | */ |
2317 | } SVGA3dCmdSetGBShaderConstInline; | 2330 | } __packed |
2331 | SVGA3dCmdSetGBShaderConstInline; | ||
2318 | /* SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE */ | 2332 | /* SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE */ |
2319 | 2333 | ||
2320 | typedef | 2334 | typedef |
2321 | struct { | 2335 | struct { |
2322 | uint32 cid; | 2336 | uint32 cid; |
2323 | SVGA3dQueryType type; | 2337 | SVGA3dQueryType type; |
2324 | } SVGA3dCmdBeginGBQuery; /* SVGA_3D_CMD_BEGIN_GB_QUERY */ | 2338 | } __packed |
2339 | SVGA3dCmdBeginGBQuery; /* SVGA_3D_CMD_BEGIN_GB_QUERY */ | ||
2325 | 2340 | ||
2326 | typedef | 2341 | typedef |
2327 | struct { | 2342 | struct { |
@@ -2329,7 +2344,8 @@ struct { | |||
2329 | SVGA3dQueryType type; | 2344 | SVGA3dQueryType type; |
2330 | SVGAMobId mobid; | 2345 | SVGAMobId mobid; |
2331 | uint32 offset; | 2346 | uint32 offset; |
2332 | } SVGA3dCmdEndGBQuery; /* SVGA_3D_CMD_END_GB_QUERY */ | 2347 | } __packed |
2348 | SVGA3dCmdEndGBQuery; /* SVGA_3D_CMD_END_GB_QUERY */ | ||
2333 | 2349 | ||
2334 | 2350 | ||
2335 | /* | 2351 | /* |
@@ -2346,21 +2362,22 @@ struct { | |||
2346 | SVGA3dQueryType type; | 2362 | SVGA3dQueryType type; |
2347 | SVGAMobId mobid; | 2363 | SVGAMobId mobid; |
2348 | uint32 offset; | 2364 | uint32 offset; |
2349 | } SVGA3dCmdWaitForGBQuery; /* SVGA_3D_CMD_WAIT_FOR_GB_QUERY */ | 2365 | } __packed |
2366 | SVGA3dCmdWaitForGBQuery; /* SVGA_3D_CMD_WAIT_FOR_GB_QUERY */ | ||
2350 | 2367 | ||
2351 | typedef | 2368 | typedef |
2352 | struct { | 2369 | struct { |
2353 | SVGAMobId mobid; | 2370 | SVGAMobId mobid; |
2354 | uint32 fbOffset; | 2371 | uint32 fbOffset; |
2355 | uint32 initalized; | 2372 | uint32 initalized; |
2356 | } | 2373 | } __packed |
2357 | SVGA3dCmdEnableGart; /* SVGA_3D_CMD_ENABLE_GART */ | 2374 | SVGA3dCmdEnableGart; /* SVGA_3D_CMD_ENABLE_GART */ |
2358 | 2375 | ||
2359 | typedef | 2376 | typedef |
2360 | struct { | 2377 | struct { |
2361 | SVGAMobId mobid; | 2378 | SVGAMobId mobid; |
2362 | uint32 gartOffset; | 2379 | uint32 gartOffset; |
2363 | } | 2380 | } __packed |
2364 | SVGA3dCmdMapMobIntoGart; /* SVGA_3D_CMD_MAP_MOB_INTO_GART */ | 2381 | SVGA3dCmdMapMobIntoGart; /* SVGA_3D_CMD_MAP_MOB_INTO_GART */ |
2365 | 2382 | ||
2366 | 2383 | ||
@@ -2368,7 +2385,7 @@ typedef | |||
2368 | struct { | 2385 | struct { |
2369 | uint32 gartOffset; | 2386 | uint32 gartOffset; |
2370 | uint32 numPages; | 2387 | uint32 numPages; |
2371 | } | 2388 | } __packed |
2372 | SVGA3dCmdUnmapGartRange; /* SVGA_3D_CMD_UNMAP_GART_RANGE */ | 2389 | SVGA3dCmdUnmapGartRange; /* SVGA_3D_CMD_UNMAP_GART_RANGE */ |
2373 | 2390 | ||
2374 | 2391 | ||
@@ -2385,27 +2402,27 @@ struct { | |||
2385 | int32 xRoot; | 2402 | int32 xRoot; |
2386 | int32 yRoot; | 2403 | int32 yRoot; |
2387 | uint32 flags; | 2404 | uint32 flags; |
2388 | } | 2405 | } __packed |
2389 | SVGA3dCmdDefineGBScreenTarget; /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET */ | 2406 | SVGA3dCmdDefineGBScreenTarget; /* SVGA_3D_CMD_DEFINE_GB_SCREENTARGET */ |
2390 | 2407 | ||
2391 | typedef | 2408 | typedef |
2392 | struct { | 2409 | struct { |
2393 | uint32 stid; | 2410 | uint32 stid; |
2394 | } | 2411 | } __packed |
2395 | SVGA3dCmdDestroyGBScreenTarget; /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET */ | 2412 | SVGA3dCmdDestroyGBScreenTarget; /* SVGA_3D_CMD_DESTROY_GB_SCREENTARGET */ |
2396 | 2413 | ||
2397 | typedef | 2414 | typedef |
2398 | struct { | 2415 | struct { |
2399 | uint32 stid; | 2416 | uint32 stid; |
2400 | SVGA3dSurfaceImageId image; | 2417 | SVGA3dSurfaceImageId image; |
2401 | } | 2418 | } __packed |
2402 | SVGA3dCmdBindGBScreenTarget; /* SVGA_3D_CMD_BIND_GB_SCREENTARGET */ | 2419 | SVGA3dCmdBindGBScreenTarget; /* SVGA_3D_CMD_BIND_GB_SCREENTARGET */ |
2403 | 2420 | ||
2404 | typedef | 2421 | typedef |
2405 | struct { | 2422 | struct { |
2406 | uint32 stid; | 2423 | uint32 stid; |
2407 | SVGA3dBox box; | 2424 | SVGA3dBox box; |
2408 | } | 2425 | } __packed |
2409 | SVGA3dCmdUpdateGBScreenTarget; /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET */ | 2426 | SVGA3dCmdUpdateGBScreenTarget; /* SVGA_3D_CMD_UPDATE_GB_SCREENTARGET */ |
2410 | 2427 | ||
2411 | /* | 2428 | /* |
@@ -2583,4 +2600,28 @@ typedef union { | |||
2583 | float f; | 2600 | float f; |
2584 | } SVGA3dDevCapResult; | 2601 | } SVGA3dDevCapResult; |
2585 | 2602 | ||
2603 | typedef enum { | ||
2604 | SVGA3DCAPS_RECORD_UNKNOWN = 0, | ||
2605 | SVGA3DCAPS_RECORD_DEVCAPS_MIN = 0x100, | ||
2606 | SVGA3DCAPS_RECORD_DEVCAPS = 0x100, | ||
2607 | SVGA3DCAPS_RECORD_DEVCAPS_MAX = 0x1ff, | ||
2608 | } SVGA3dCapsRecordType; | ||
2609 | |||
2610 | typedef | ||
2611 | struct SVGA3dCapsRecordHeader { | ||
2612 | uint32 length; | ||
2613 | SVGA3dCapsRecordType type; | ||
2614 | } | ||
2615 | SVGA3dCapsRecordHeader; | ||
2616 | |||
2617 | typedef | ||
2618 | struct SVGA3dCapsRecord { | ||
2619 | SVGA3dCapsRecordHeader header; | ||
2620 | uint32 data[1]; | ||
2621 | } | ||
2622 | SVGA3dCapsRecord; | ||
2623 | |||
2624 | |||
2625 | typedef uint32 SVGA3dCapPair[2]; | ||
2626 | |||
2586 | #endif /* _SVGA3D_REG_H_ */ | 2627 | #endif /* _SVGA3D_REG_H_ */ |
diff --git a/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h index 8369c3ba10fe..ef3385096145 100644 --- a/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h | |||
@@ -38,8 +38,11 @@ | |||
38 | 38 | ||
39 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) | 39 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y)) |
40 | #define max_t(type, x, y) ((x) > (y) ? (x) : (y)) | 40 | #define max_t(type, x, y) ((x) > (y) ? (x) : (y)) |
41 | #define min_t(type, x, y) ((x) < (y) ? (x) : (y)) | ||
41 | #define surf_size_struct SVGA3dSize | 42 | #define surf_size_struct SVGA3dSize |
42 | #define u32 uint32 | 43 | #define u32 uint32 |
44 | #define u64 uint64_t | ||
45 | #define U32_MAX ((u32)~0U) | ||
43 | 46 | ||
44 | #endif /* __KERNEL__ */ | 47 | #endif /* __KERNEL__ */ |
45 | 48 | ||
@@ -704,8 +707,8 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { | |||
704 | 707 | ||
705 | static inline u32 clamped_umul32(u32 a, u32 b) | 708 | static inline u32 clamped_umul32(u32 a, u32 b) |
706 | { | 709 | { |
707 | uint64_t tmp = (uint64_t) a*b; | 710 | u64 tmp = (u64) a*b; |
708 | return (tmp > (uint64_t) ((u32) -1)) ? (u32) -1 : tmp; | 711 | return (tmp > (u64) U32_MAX) ? U32_MAX : tmp; |
709 | } | 712 | } |
710 | 713 | ||
711 | static inline const struct svga3d_surface_desc * | 714 | static inline const struct svga3d_surface_desc * |
@@ -834,7 +837,7 @@ svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format, | |||
834 | bool cubemap) | 837 | bool cubemap) |
835 | { | 838 | { |
836 | const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format); | 839 | const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format); |
837 | u32 total_size = 0; | 840 | u64 total_size = 0; |
838 | u32 mip; | 841 | u32 mip; |
839 | 842 | ||
840 | for (mip = 0; mip < num_mip_levels; mip++) { | 843 | for (mip = 0; mip < num_mip_levels; mip++) { |
@@ -847,7 +850,7 @@ svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format, | |||
847 | if (cubemap) | 850 | if (cubemap) |
848 | total_size *= SVGA3D_MAX_SURFACE_FACES; | 851 | total_size *= SVGA3D_MAX_SURFACE_FACES; |
849 | 852 | ||
850 | return total_size; | 853 | return (u32) min_t(u64, total_size, (u64) U32_MAX); |
851 | } | 854 | } |
852 | 855 | ||
853 | 856 | ||
diff --git a/drivers/gpu/drm/vmwgfx/svga_reg.h b/drivers/gpu/drm/vmwgfx/svga_reg.h index 71defa4d2d75..11323dd5196f 100644 --- a/drivers/gpu/drm/vmwgfx/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga_reg.h | |||
@@ -169,10 +169,17 @@ enum { | |||
169 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ | 169 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ |
170 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ | 170 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ |
171 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ | 171 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ |
172 | SVGA_REG_COMMAND_LOW = 48, /* Lower 32 bits and submits commands */ | ||
173 | SVGA_REG_COMMAND_HIGH = 49, /* Upper 32 bits of command buffer PA */ | ||
172 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, /* Max primary memory */ | 174 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, /* Max primary memory */ |
173 | SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Suggested limit on mob mem */ | 175 | SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Suggested limit on mob mem */ |
174 | SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ | 176 | SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ |
175 | SVGA_REG_TOP = 53, /* Must be 1 more than the last register */ | 177 | SVGA_REG_CMD_PREPEND_LOW = 53, |
178 | SVGA_REG_CMD_PREPEND_HIGH = 54, | ||
179 | SVGA_REG_SCREENTARGET_MAX_WIDTH = 55, | ||
180 | SVGA_REG_SCREENTARGET_MAX_HEIGHT = 56, | ||
181 | SVGA_REG_MOB_MAX_SIZE = 57, | ||
182 | SVGA_REG_TOP = 58, /* Must be 1 more than the last register */ | ||
176 | 183 | ||
177 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ | 184 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ |
178 | /* Next 768 (== 256*3) registers exist for colormap */ | 185 | /* Next 768 (== 256*3) registers exist for colormap */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 82c41daebc0e..1e80152674b5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c | |||
@@ -37,7 +37,7 @@ struct vmw_user_context { | |||
37 | 37 | ||
38 | 38 | ||
39 | 39 | ||
40 | typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *); | 40 | typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool); |
41 | 41 | ||
42 | static void vmw_user_context_free(struct vmw_resource *res); | 42 | static void vmw_user_context_free(struct vmw_resource *res); |
43 | static struct vmw_resource * | 43 | static struct vmw_resource * |
@@ -50,9 +50,11 @@ static int vmw_gb_context_unbind(struct vmw_resource *res, | |||
50 | bool readback, | 50 | bool readback, |
51 | struct ttm_validate_buffer *val_buf); | 51 | struct ttm_validate_buffer *val_buf); |
52 | static int vmw_gb_context_destroy(struct vmw_resource *res); | 52 | static int vmw_gb_context_destroy(struct vmw_resource *res); |
53 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi); | 53 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind); |
54 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi); | 54 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi, |
55 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi); | 55 | bool rebind); |
56 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind); | ||
57 | static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs); | ||
56 | static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs); | 58 | static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs); |
57 | static uint64_t vmw_user_context_size; | 59 | static uint64_t vmw_user_context_size; |
58 | 60 | ||
@@ -111,10 +113,14 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) | |||
111 | 113 | ||
112 | if (res->func->destroy == vmw_gb_context_destroy) { | 114 | if (res->func->destroy == vmw_gb_context_destroy) { |
113 | mutex_lock(&dev_priv->cmdbuf_mutex); | 115 | mutex_lock(&dev_priv->cmdbuf_mutex); |
116 | mutex_lock(&dev_priv->binding_mutex); | ||
117 | (void) vmw_context_binding_state_kill | ||
118 | (&container_of(res, struct vmw_user_context, res)->cbs); | ||
114 | (void) vmw_gb_context_destroy(res); | 119 | (void) vmw_gb_context_destroy(res); |
115 | if (dev_priv->pinned_bo != NULL && | 120 | if (dev_priv->pinned_bo != NULL && |
116 | !dev_priv->query_cid_valid) | 121 | !dev_priv->query_cid_valid) |
117 | __vmw_execbuf_release_pinned_bo(dev_priv, NULL); | 122 | __vmw_execbuf_release_pinned_bo(dev_priv, NULL); |
123 | mutex_unlock(&dev_priv->binding_mutex); | ||
118 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 124 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
119 | return; | 125 | return; |
120 | } | 126 | } |
@@ -328,7 +334,7 @@ static int vmw_gb_context_unbind(struct vmw_resource *res, | |||
328 | BUG_ON(bo->mem.mem_type != VMW_PL_MOB); | 334 | BUG_ON(bo->mem.mem_type != VMW_PL_MOB); |
329 | 335 | ||
330 | mutex_lock(&dev_priv->binding_mutex); | 336 | mutex_lock(&dev_priv->binding_mutex); |
331 | vmw_context_binding_state_kill(&uctx->cbs); | 337 | vmw_context_binding_state_scrub(&uctx->cbs); |
332 | 338 | ||
333 | submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); | 339 | submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0); |
334 | 340 | ||
@@ -378,10 +384,6 @@ static int vmw_gb_context_destroy(struct vmw_resource *res) | |||
378 | SVGA3dCmdHeader header; | 384 | SVGA3dCmdHeader header; |
379 | SVGA3dCmdDestroyGBContext body; | 385 | SVGA3dCmdDestroyGBContext body; |
380 | } *cmd; | 386 | } *cmd; |
381 | struct vmw_user_context *uctx = | ||
382 | container_of(res, struct vmw_user_context, res); | ||
383 | |||
384 | BUG_ON(!list_empty(&uctx->cbs.list)); | ||
385 | 387 | ||
386 | if (likely(res->id == -1)) | 388 | if (likely(res->id == -1)) |
387 | return 0; | 389 | return 0; |
@@ -528,8 +530,9 @@ out_unlock: | |||
528 | * vmw_context_scrub_shader - scrub a shader binding from a context. | 530 | * vmw_context_scrub_shader - scrub a shader binding from a context. |
529 | * | 531 | * |
530 | * @bi: single binding information. | 532 | * @bi: single binding information. |
533 | * @rebind: Whether to issue a bind instead of scrub command. | ||
531 | */ | 534 | */ |
532 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | 535 | static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind) |
533 | { | 536 | { |
534 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 537 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
535 | struct { | 538 | struct { |
@@ -548,7 +551,7 @@ static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | |||
548 | cmd->header.size = sizeof(cmd->body); | 551 | cmd->header.size = sizeof(cmd->body); |
549 | cmd->body.cid = bi->ctx->id; | 552 | cmd->body.cid = bi->ctx->id; |
550 | cmd->body.type = bi->i1.shader_type; | 553 | cmd->body.type = bi->i1.shader_type; |
551 | cmd->body.shid = SVGA3D_INVALID_ID; | 554 | cmd->body.shid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
552 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 555 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
553 | 556 | ||
554 | return 0; | 557 | return 0; |
@@ -559,8 +562,10 @@ static int vmw_context_scrub_shader(struct vmw_ctx_bindinfo *bi) | |||
559 | * from a context. | 562 | * from a context. |
560 | * | 563 | * |
561 | * @bi: single binding information. | 564 | * @bi: single binding information. |
565 | * @rebind: Whether to issue a bind instead of scrub command. | ||
562 | */ | 566 | */ |
563 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | 567 | static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi, |
568 | bool rebind) | ||
564 | { | 569 | { |
565 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 570 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
566 | struct { | 571 | struct { |
@@ -579,7 +584,7 @@ static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | |||
579 | cmd->header.size = sizeof(cmd->body); | 584 | cmd->header.size = sizeof(cmd->body); |
580 | cmd->body.cid = bi->ctx->id; | 585 | cmd->body.cid = bi->ctx->id; |
581 | cmd->body.type = bi->i1.rt_type; | 586 | cmd->body.type = bi->i1.rt_type; |
582 | cmd->body.target.sid = SVGA3D_INVALID_ID; | 587 | cmd->body.target.sid = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
583 | cmd->body.target.face = 0; | 588 | cmd->body.target.face = 0; |
584 | cmd->body.target.mipmap = 0; | 589 | cmd->body.target.mipmap = 0; |
585 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 590 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
@@ -591,11 +596,13 @@ static int vmw_context_scrub_render_target(struct vmw_ctx_bindinfo *bi) | |||
591 | * vmw_context_scrub_texture - scrub a texture binding from a context. | 596 | * vmw_context_scrub_texture - scrub a texture binding from a context. |
592 | * | 597 | * |
593 | * @bi: single binding information. | 598 | * @bi: single binding information. |
599 | * @rebind: Whether to issue a bind instead of scrub command. | ||
594 | * | 600 | * |
595 | * TODO: Possibly complement this function with a function that takes | 601 | * TODO: Possibly complement this function with a function that takes |
596 | * a list of texture bindings and combines them to a single command. | 602 | * a list of texture bindings and combines them to a single command. |
597 | */ | 603 | */ |
598 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi) | 604 | static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi, |
605 | bool rebind) | ||
599 | { | 606 | { |
600 | struct vmw_private *dev_priv = bi->ctx->dev_priv; | 607 | struct vmw_private *dev_priv = bi->ctx->dev_priv; |
601 | struct { | 608 | struct { |
@@ -619,7 +626,7 @@ static int vmw_context_scrub_texture(struct vmw_ctx_bindinfo *bi) | |||
619 | cmd->body.c.cid = bi->ctx->id; | 626 | cmd->body.c.cid = bi->ctx->id; |
620 | cmd->body.s1.stage = bi->i1.texture_stage; | 627 | cmd->body.s1.stage = bi->i1.texture_stage; |
621 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; | 628 | cmd->body.s1.name = SVGA3D_TS_BIND_TEXTURE; |
622 | cmd->body.s1.value = (uint32) SVGA3D_INVALID_ID; | 629 | cmd->body.s1.value = ((rebind) ? bi->res->id : SVGA3D_INVALID_ID); |
623 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 630 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); |
624 | 631 | ||
625 | return 0; | 632 | return 0; |
@@ -692,6 +699,7 @@ int vmw_context_binding_add(struct vmw_ctx_binding_state *cbs, | |||
692 | vmw_context_binding_drop(loc); | 699 | vmw_context_binding_drop(loc); |
693 | 700 | ||
694 | loc->bi = *bi; | 701 | loc->bi = *bi; |
702 | loc->bi.scrubbed = false; | ||
695 | list_add_tail(&loc->ctx_list, &cbs->list); | 703 | list_add_tail(&loc->ctx_list, &cbs->list); |
696 | INIT_LIST_HEAD(&loc->res_list); | 704 | INIT_LIST_HEAD(&loc->res_list); |
697 | 705 | ||
@@ -727,12 +735,11 @@ static void vmw_context_binding_transfer(struct vmw_ctx_binding_state *cbs, | |||
727 | if (loc->bi.ctx != NULL) | 735 | if (loc->bi.ctx != NULL) |
728 | vmw_context_binding_drop(loc); | 736 | vmw_context_binding_drop(loc); |
729 | 737 | ||
730 | loc->bi = *bi; | 738 | if (bi->res != NULL) { |
731 | list_add_tail(&loc->ctx_list, &cbs->list); | 739 | loc->bi = *bi; |
732 | if (bi->res != NULL) | 740 | list_add_tail(&loc->ctx_list, &cbs->list); |
733 | list_add_tail(&loc->res_list, &bi->res->binding_head); | 741 | list_add_tail(&loc->res_list, &bi->res->binding_head); |
734 | else | 742 | } |
735 | INIT_LIST_HEAD(&loc->res_list); | ||
736 | } | 743 | } |
737 | 744 | ||
738 | /** | 745 | /** |
@@ -746,7 +753,10 @@ static void vmw_context_binding_transfer(struct vmw_ctx_binding_state *cbs, | |||
746 | */ | 753 | */ |
747 | static void vmw_context_binding_kill(struct vmw_ctx_binding *cb) | 754 | static void vmw_context_binding_kill(struct vmw_ctx_binding *cb) |
748 | { | 755 | { |
749 | (void) vmw_scrub_funcs[cb->bi.bt](&cb->bi); | 756 | if (!cb->bi.scrubbed) { |
757 | (void) vmw_scrub_funcs[cb->bi.bt](&cb->bi, false); | ||
758 | cb->bi.scrubbed = true; | ||
759 | } | ||
750 | vmw_context_binding_drop(cb); | 760 | vmw_context_binding_drop(cb); |
751 | } | 761 | } |
752 | 762 | ||
@@ -768,6 +778,27 @@ static void vmw_context_binding_state_kill(struct vmw_ctx_binding_state *cbs) | |||
768 | } | 778 | } |
769 | 779 | ||
770 | /** | 780 | /** |
781 | * vmw_context_binding_state_scrub - Scrub all bindings associated with a | ||
782 | * struct vmw_ctx_binding state structure. | ||
783 | * | ||
784 | * @cbs: Pointer to the context binding state tracker. | ||
785 | * | ||
786 | * Emits commands to scrub all bindings associated with the | ||
787 | * context binding state tracker. | ||
788 | */ | ||
789 | static void vmw_context_binding_state_scrub(struct vmw_ctx_binding_state *cbs) | ||
790 | { | ||
791 | struct vmw_ctx_binding *entry; | ||
792 | |||
793 | list_for_each_entry(entry, &cbs->list, ctx_list) { | ||
794 | if (!entry->bi.scrubbed) { | ||
795 | (void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false); | ||
796 | entry->bi.scrubbed = true; | ||
797 | } | ||
798 | } | ||
799 | } | ||
800 | |||
801 | /** | ||
771 | * vmw_context_binding_res_list_kill - Kill all bindings on a | 802 | * vmw_context_binding_res_list_kill - Kill all bindings on a |
772 | * resource binding list | 803 | * resource binding list |
773 | * | 804 | * |
@@ -785,6 +816,27 @@ void vmw_context_binding_res_list_kill(struct list_head *head) | |||
785 | } | 816 | } |
786 | 817 | ||
787 | /** | 818 | /** |
819 | * vmw_context_binding_res_list_scrub - Scrub all bindings on a | ||
820 | * resource binding list | ||
821 | * | ||
822 | * @head: list head of resource binding list | ||
823 | * | ||
824 | * Scrub all bindings associated with a specific resource. Typically | ||
825 | * called before the resource is evicted. | ||
826 | */ | ||
827 | void vmw_context_binding_res_list_scrub(struct list_head *head) | ||
828 | { | ||
829 | struct vmw_ctx_binding *entry; | ||
830 | |||
831 | list_for_each_entry(entry, head, res_list) { | ||
832 | if (!entry->bi.scrubbed) { | ||
833 | (void) vmw_scrub_funcs[entry->bi.bt](&entry->bi, false); | ||
834 | entry->bi.scrubbed = true; | ||
835 | } | ||
836 | } | ||
837 | } | ||
838 | |||
839 | /** | ||
788 | * vmw_context_binding_state_transfer - Commit staged binding info | 840 | * vmw_context_binding_state_transfer - Commit staged binding info |
789 | * | 841 | * |
790 | * @ctx: Pointer to context to commit the staged binding info to. | 842 | * @ctx: Pointer to context to commit the staged binding info to. |
@@ -803,3 +855,50 @@ void vmw_context_binding_state_transfer(struct vmw_resource *ctx, | |||
803 | list_for_each_entry_safe(entry, next, &from->list, ctx_list) | 855 | list_for_each_entry_safe(entry, next, &from->list, ctx_list) |
804 | vmw_context_binding_transfer(&uctx->cbs, &entry->bi); | 856 | vmw_context_binding_transfer(&uctx->cbs, &entry->bi); |
805 | } | 857 | } |
858 | |||
859 | /** | ||
860 | * vmw_context_rebind_all - Rebind all scrubbed bindings of a context | ||
861 | * | ||
862 | * @ctx: The context resource | ||
863 | * | ||
864 | * Walks through the context binding list and rebinds all scrubbed | ||
865 | * resources. | ||
866 | */ | ||
867 | int vmw_context_rebind_all(struct vmw_resource *ctx) | ||
868 | { | ||
869 | struct vmw_ctx_binding *entry; | ||
870 | struct vmw_user_context *uctx = | ||
871 | container_of(ctx, struct vmw_user_context, res); | ||
872 | struct vmw_ctx_binding_state *cbs = &uctx->cbs; | ||
873 | int ret; | ||
874 | |||
875 | list_for_each_entry(entry, &cbs->list, ctx_list) { | ||
876 | if (likely(!entry->bi.scrubbed)) | ||
877 | continue; | ||
878 | |||
879 | if (WARN_ON(entry->bi.res == NULL || entry->bi.res->id == | ||
880 | SVGA3D_INVALID_ID)) | ||
881 | continue; | ||
882 | |||
883 | ret = vmw_scrub_funcs[entry->bi.bt](&entry->bi, true); | ||
884 | if (unlikely(ret != 0)) | ||
885 | return ret; | ||
886 | |||
887 | entry->bi.scrubbed = false; | ||
888 | } | ||
889 | |||
890 | return 0; | ||
891 | } | ||
892 | |||
893 | /** | ||
894 | * vmw_context_binding_list - Return a list of context bindings | ||
895 | * | ||
896 | * @ctx: The context resource | ||
897 | * | ||
898 | * Returns the current list of bindings of the given context. Note that | ||
899 | * this list becomes stale as soon as the dev_priv::binding_mutex is unlocked. | ||
900 | */ | ||
901 | struct list_head *vmw_context_binding_list(struct vmw_resource *ctx) | ||
902 | { | ||
903 | return &(container_of(ctx, struct vmw_user_context, res)->cbs.list); | ||
904 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9893328f8fdc..0083cbf99edf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -667,6 +667,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
667 | dev_priv->memory_size = 512*1024*1024; | 667 | dev_priv->memory_size = 512*1024*1024; |
668 | } | 668 | } |
669 | dev_priv->max_mob_pages = 0; | 669 | dev_priv->max_mob_pages = 0; |
670 | dev_priv->max_mob_size = 0; | ||
670 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { | 671 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { |
671 | uint64_t mem_size = | 672 | uint64_t mem_size = |
672 | vmw_read(dev_priv, | 673 | vmw_read(dev_priv, |
@@ -676,6 +677,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
676 | dev_priv->prim_bb_mem = | 677 | dev_priv->prim_bb_mem = |
677 | vmw_read(dev_priv, | 678 | vmw_read(dev_priv, |
678 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); | 679 | SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM); |
680 | dev_priv->max_mob_size = | ||
681 | vmw_read(dev_priv, SVGA_REG_MOB_MAX_SIZE); | ||
679 | } else | 682 | } else |
680 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 683 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
681 | 684 | ||
@@ -941,6 +944,7 @@ static void vmw_postclose(struct drm_device *dev, | |||
941 | drm_master_put(&vmw_fp->locked_master); | 944 | drm_master_put(&vmw_fp->locked_master); |
942 | } | 945 | } |
943 | 946 | ||
947 | vmw_compat_shader_man_destroy(vmw_fp->shman); | ||
944 | ttm_object_file_release(&vmw_fp->tfile); | 948 | ttm_object_file_release(&vmw_fp->tfile); |
945 | kfree(vmw_fp); | 949 | kfree(vmw_fp); |
946 | } | 950 | } |
@@ -960,11 +964,17 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
960 | if (unlikely(vmw_fp->tfile == NULL)) | 964 | if (unlikely(vmw_fp->tfile == NULL)) |
961 | goto out_no_tfile; | 965 | goto out_no_tfile; |
962 | 966 | ||
967 | vmw_fp->shman = vmw_compat_shader_man_create(dev_priv); | ||
968 | if (IS_ERR(vmw_fp->shman)) | ||
969 | goto out_no_shman; | ||
970 | |||
963 | file_priv->driver_priv = vmw_fp; | 971 | file_priv->driver_priv = vmw_fp; |
964 | dev_priv->bdev.dev_mapping = dev->dev_mapping; | 972 | dev_priv->bdev.dev_mapping = dev->dev_mapping; |
965 | 973 | ||
966 | return 0; | 974 | return 0; |
967 | 975 | ||
976 | out_no_shman: | ||
977 | ttm_object_file_release(&vmw_fp->tfile); | ||
968 | out_no_tfile: | 978 | out_no_tfile: |
969 | kfree(vmw_fp); | 979 | kfree(vmw_fp); |
970 | return ret; | 980 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 554e7fa33082..07831554dad7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <drm/ttm/ttm_module.h> | 40 | #include <drm/ttm/ttm_module.h> |
41 | #include "vmwgfx_fence.h" | 41 | #include "vmwgfx_fence.h" |
42 | 42 | ||
43 | #define VMWGFX_DRIVER_DATE "20121114" | 43 | #define VMWGFX_DRIVER_DATE "20140228" |
44 | #define VMWGFX_DRIVER_MAJOR 2 | 44 | #define VMWGFX_DRIVER_MAJOR 2 |
45 | #define VMWGFX_DRIVER_MINOR 5 | 45 | #define VMWGFX_DRIVER_MINOR 5 |
46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
@@ -75,10 +75,14 @@ | |||
75 | #define VMW_RES_FENCE ttm_driver_type3 | 75 | #define VMW_RES_FENCE ttm_driver_type3 |
76 | #define VMW_RES_SHADER ttm_driver_type4 | 76 | #define VMW_RES_SHADER ttm_driver_type4 |
77 | 77 | ||
78 | struct vmw_compat_shader_manager; | ||
79 | |||
78 | struct vmw_fpriv { | 80 | struct vmw_fpriv { |
79 | struct drm_master *locked_master; | 81 | struct drm_master *locked_master; |
80 | struct ttm_object_file *tfile; | 82 | struct ttm_object_file *tfile; |
81 | struct list_head fence_events; | 83 | struct list_head fence_events; |
84 | bool gb_aware; | ||
85 | struct vmw_compat_shader_manager *shman; | ||
82 | }; | 86 | }; |
83 | 87 | ||
84 | struct vmw_dma_buffer { | 88 | struct vmw_dma_buffer { |
@@ -272,6 +276,7 @@ struct vmw_ctx_bindinfo { | |||
272 | struct vmw_resource *ctx; | 276 | struct vmw_resource *ctx; |
273 | struct vmw_resource *res; | 277 | struct vmw_resource *res; |
274 | enum vmw_ctx_binding_type bt; | 278 | enum vmw_ctx_binding_type bt; |
279 | bool scrubbed; | ||
275 | union { | 280 | union { |
276 | SVGA3dShaderType shader_type; | 281 | SVGA3dShaderType shader_type; |
277 | SVGA3dRenderTargetType rt_type; | 282 | SVGA3dRenderTargetType rt_type; |
@@ -318,7 +323,7 @@ struct vmw_sw_context{ | |||
318 | struct drm_open_hash res_ht; | 323 | struct drm_open_hash res_ht; |
319 | bool res_ht_initialized; | 324 | bool res_ht_initialized; |
320 | bool kernel; /**< is the called made from the kernel */ | 325 | bool kernel; /**< is the called made from the kernel */ |
321 | struct ttm_object_file *tfile; | 326 | struct vmw_fpriv *fp; |
322 | struct list_head validate_nodes; | 327 | struct list_head validate_nodes; |
323 | struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; | 328 | struct vmw_relocation relocs[VMWGFX_MAX_RELOCATIONS]; |
324 | uint32_t cur_reloc; | 329 | uint32_t cur_reloc; |
@@ -336,6 +341,7 @@ struct vmw_sw_context{ | |||
336 | bool needs_post_query_barrier; | 341 | bool needs_post_query_barrier; |
337 | struct vmw_resource *error_resource; | 342 | struct vmw_resource *error_resource; |
338 | struct vmw_ctx_binding_state staged_bindings; | 343 | struct vmw_ctx_binding_state staged_bindings; |
344 | struct list_head staged_shaders; | ||
339 | }; | 345 | }; |
340 | 346 | ||
341 | struct vmw_legacy_display; | 347 | struct vmw_legacy_display; |
@@ -380,6 +386,7 @@ struct vmw_private { | |||
380 | uint32_t max_gmr_ids; | 386 | uint32_t max_gmr_ids; |
381 | uint32_t max_gmr_pages; | 387 | uint32_t max_gmr_pages; |
382 | uint32_t max_mob_pages; | 388 | uint32_t max_mob_pages; |
389 | uint32_t max_mob_size; | ||
383 | uint32_t memory_size; | 390 | uint32_t memory_size; |
384 | bool has_gmr; | 391 | bool has_gmr; |
385 | bool has_mob; | 392 | bool has_mob; |
@@ -569,6 +576,8 @@ struct vmw_user_resource_conv; | |||
569 | 576 | ||
570 | extern void vmw_resource_unreference(struct vmw_resource **p_res); | 577 | extern void vmw_resource_unreference(struct vmw_resource **p_res); |
571 | extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res); | 578 | extern struct vmw_resource *vmw_resource_reference(struct vmw_resource *res); |
579 | extern struct vmw_resource * | ||
580 | vmw_resource_reference_unless_doomed(struct vmw_resource *res); | ||
572 | extern int vmw_resource_validate(struct vmw_resource *res); | 581 | extern int vmw_resource_validate(struct vmw_resource *res); |
573 | extern int vmw_resource_reserve(struct vmw_resource *res, bool no_backup); | 582 | extern int vmw_resource_reserve(struct vmw_resource *res, bool no_backup); |
574 | extern bool vmw_resource_needs_backup(const struct vmw_resource *res); | 583 | extern bool vmw_resource_needs_backup(const struct vmw_resource *res); |
@@ -957,6 +966,9 @@ extern void | |||
957 | vmw_context_binding_state_transfer(struct vmw_resource *res, | 966 | vmw_context_binding_state_transfer(struct vmw_resource *res, |
958 | struct vmw_ctx_binding_state *cbs); | 967 | struct vmw_ctx_binding_state *cbs); |
959 | extern void vmw_context_binding_res_list_kill(struct list_head *head); | 968 | extern void vmw_context_binding_res_list_kill(struct list_head *head); |
969 | extern void vmw_context_binding_res_list_scrub(struct list_head *head); | ||
970 | extern int vmw_context_rebind_all(struct vmw_resource *ctx); | ||
971 | extern struct list_head *vmw_context_binding_list(struct vmw_resource *ctx); | ||
960 | 972 | ||
961 | /* | 973 | /* |
962 | * Surface management - vmwgfx_surface.c | 974 | * Surface management - vmwgfx_surface.c |
@@ -991,6 +1003,28 @@ extern int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | |||
991 | struct drm_file *file_priv); | 1003 | struct drm_file *file_priv); |
992 | extern int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, | 1004 | extern int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, |
993 | struct drm_file *file_priv); | 1005 | struct drm_file *file_priv); |
1006 | extern int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man, | ||
1007 | SVGA3dShaderType shader_type, | ||
1008 | u32 *user_key); | ||
1009 | extern void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man, | ||
1010 | struct list_head *list); | ||
1011 | extern void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man, | ||
1012 | struct list_head *list); | ||
1013 | extern int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man, | ||
1014 | u32 user_key, | ||
1015 | SVGA3dShaderType shader_type, | ||
1016 | struct list_head *list); | ||
1017 | extern int vmw_compat_shader_add(struct vmw_compat_shader_manager *man, | ||
1018 | u32 user_key, const void *bytecode, | ||
1019 | SVGA3dShaderType shader_type, | ||
1020 | size_t size, | ||
1021 | struct ttm_object_file *tfile, | ||
1022 | struct list_head *list); | ||
1023 | extern struct vmw_compat_shader_manager * | ||
1024 | vmw_compat_shader_man_create(struct vmw_private *dev_priv); | ||
1025 | extern void | ||
1026 | vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man); | ||
1027 | |||
994 | 1028 | ||
995 | /** | 1029 | /** |
996 | * Inline helper functions | 1030 | * Inline helper functions |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 7a5f1eb55c5a..efb575a7996c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -114,8 +114,10 @@ static void vmw_resource_list_unreserve(struct list_head *list, | |||
114 | * persistent context binding tracker. | 114 | * persistent context binding tracker. |
115 | */ | 115 | */ |
116 | if (unlikely(val->staged_bindings)) { | 116 | if (unlikely(val->staged_bindings)) { |
117 | vmw_context_binding_state_transfer | 117 | if (!backoff) { |
118 | (val->res, val->staged_bindings); | 118 | vmw_context_binding_state_transfer |
119 | (val->res, val->staged_bindings); | ||
120 | } | ||
119 | kfree(val->staged_bindings); | 121 | kfree(val->staged_bindings); |
120 | val->staged_bindings = NULL; | 122 | val->staged_bindings = NULL; |
121 | } | 123 | } |
@@ -178,6 +180,44 @@ static int vmw_resource_val_add(struct vmw_sw_context *sw_context, | |||
178 | } | 180 | } |
179 | 181 | ||
180 | /** | 182 | /** |
183 | * vmw_resource_context_res_add - Put resources previously bound to a context on | ||
184 | * the validation list | ||
185 | * | ||
186 | * @dev_priv: Pointer to a device private structure | ||
187 | * @sw_context: Pointer to a software context used for this command submission | ||
188 | * @ctx: Pointer to the context resource | ||
189 | * | ||
190 | * This function puts all resources that were previously bound to @ctx on | ||
191 | * the resource validation list. This is part of the context state reemission | ||
192 | */ | ||
193 | static int vmw_resource_context_res_add(struct vmw_private *dev_priv, | ||
194 | struct vmw_sw_context *sw_context, | ||
195 | struct vmw_resource *ctx) | ||
196 | { | ||
197 | struct list_head *binding_list; | ||
198 | struct vmw_ctx_binding *entry; | ||
199 | int ret = 0; | ||
200 | struct vmw_resource *res; | ||
201 | |||
202 | mutex_lock(&dev_priv->binding_mutex); | ||
203 | binding_list = vmw_context_binding_list(ctx); | ||
204 | |||
205 | list_for_each_entry(entry, binding_list, ctx_list) { | ||
206 | res = vmw_resource_reference_unless_doomed(entry->bi.res); | ||
207 | if (unlikely(res == NULL)) | ||
208 | continue; | ||
209 | |||
210 | ret = vmw_resource_val_add(sw_context, entry->bi.res, NULL); | ||
211 | vmw_resource_unreference(&res); | ||
212 | if (unlikely(ret != 0)) | ||
213 | break; | ||
214 | } | ||
215 | |||
216 | mutex_unlock(&dev_priv->binding_mutex); | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | /** | ||
181 | * vmw_resource_relocation_add - Add a relocation to the relocation list | 221 | * vmw_resource_relocation_add - Add a relocation to the relocation list |
182 | * | 222 | * |
183 | * @list: Pointer to head of relocation list. | 223 | * @list: Pointer to head of relocation list. |
@@ -233,8 +273,12 @@ static void vmw_resource_relocations_apply(uint32_t *cb, | |||
233 | { | 273 | { |
234 | struct vmw_resource_relocation *rel; | 274 | struct vmw_resource_relocation *rel; |
235 | 275 | ||
236 | list_for_each_entry(rel, list, head) | 276 | list_for_each_entry(rel, list, head) { |
237 | cb[rel->offset] = rel->res->id; | 277 | if (likely(rel->res != NULL)) |
278 | cb[rel->offset] = rel->res->id; | ||
279 | else | ||
280 | cb[rel->offset] = SVGA_3D_CMD_NOP; | ||
281 | } | ||
238 | } | 282 | } |
239 | 283 | ||
240 | static int vmw_cmd_invalid(struct vmw_private *dev_priv, | 284 | static int vmw_cmd_invalid(struct vmw_private *dev_priv, |
@@ -379,22 +423,27 @@ static int vmw_resources_validate(struct vmw_sw_context *sw_context) | |||
379 | } | 423 | } |
380 | 424 | ||
381 | /** | 425 | /** |
382 | * vmw_cmd_res_check - Check that a resource is present and if so, put it | 426 | * vmw_cmd_compat_res_check - Check that a resource is present and if so, put it |
383 | * on the resource validate list unless it's already there. | 427 | * on the resource validate list unless it's already there. |
384 | * | 428 | * |
385 | * @dev_priv: Pointer to a device private structure. | 429 | * @dev_priv: Pointer to a device private structure. |
386 | * @sw_context: Pointer to the software context. | 430 | * @sw_context: Pointer to the software context. |
387 | * @res_type: Resource type. | 431 | * @res_type: Resource type. |
388 | * @converter: User-space visisble type specific information. | 432 | * @converter: User-space visisble type specific information. |
389 | * @id: Pointer to the location in the command buffer currently being | 433 | * @id: user-space resource id handle. |
434 | * @id_loc: Pointer to the location in the command buffer currently being | ||
390 | * parsed from where the user-space resource id handle is located. | 435 | * parsed from where the user-space resource id handle is located. |
436 | * @p_val: Pointer to pointer to resource validalidation node. Populated | ||
437 | * on exit. | ||
391 | */ | 438 | */ |
392 | static int vmw_cmd_res_check(struct vmw_private *dev_priv, | 439 | static int |
393 | struct vmw_sw_context *sw_context, | 440 | vmw_cmd_compat_res_check(struct vmw_private *dev_priv, |
394 | enum vmw_res_type res_type, | 441 | struct vmw_sw_context *sw_context, |
395 | const struct vmw_user_resource_conv *converter, | 442 | enum vmw_res_type res_type, |
396 | uint32_t *id, | 443 | const struct vmw_user_resource_conv *converter, |
397 | struct vmw_resource_val_node **p_val) | 444 | uint32_t id, |
445 | uint32_t *id_loc, | ||
446 | struct vmw_resource_val_node **p_val) | ||
398 | { | 447 | { |
399 | struct vmw_res_cache_entry *rcache = | 448 | struct vmw_res_cache_entry *rcache = |
400 | &sw_context->res_cache[res_type]; | 449 | &sw_context->res_cache[res_type]; |
@@ -402,7 +451,7 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
402 | struct vmw_resource_val_node *node; | 451 | struct vmw_resource_val_node *node; |
403 | int ret; | 452 | int ret; |
404 | 453 | ||
405 | if (*id == SVGA3D_INVALID_ID) { | 454 | if (id == SVGA3D_INVALID_ID) { |
406 | if (p_val) | 455 | if (p_val) |
407 | *p_val = NULL; | 456 | *p_val = NULL; |
408 | if (res_type == vmw_res_context) { | 457 | if (res_type == vmw_res_context) { |
@@ -417,7 +466,7 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
417 | * resource | 466 | * resource |
418 | */ | 467 | */ |
419 | 468 | ||
420 | if (likely(rcache->valid && *id == rcache->handle)) { | 469 | if (likely(rcache->valid && id == rcache->handle)) { |
421 | const struct vmw_resource *res = rcache->res; | 470 | const struct vmw_resource *res = rcache->res; |
422 | 471 | ||
423 | rcache->node->first_usage = false; | 472 | rcache->node->first_usage = false; |
@@ -426,28 +475,28 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
426 | 475 | ||
427 | return vmw_resource_relocation_add | 476 | return vmw_resource_relocation_add |
428 | (&sw_context->res_relocations, res, | 477 | (&sw_context->res_relocations, res, |
429 | id - sw_context->buf_start); | 478 | id_loc - sw_context->buf_start); |
430 | } | 479 | } |
431 | 480 | ||
432 | ret = vmw_user_resource_lookup_handle(dev_priv, | 481 | ret = vmw_user_resource_lookup_handle(dev_priv, |
433 | sw_context->tfile, | 482 | sw_context->fp->tfile, |
434 | *id, | 483 | id, |
435 | converter, | 484 | converter, |
436 | &res); | 485 | &res); |
437 | if (unlikely(ret != 0)) { | 486 | if (unlikely(ret != 0)) { |
438 | DRM_ERROR("Could not find or use resource 0x%08x.\n", | 487 | DRM_ERROR("Could not find or use resource 0x%08x.\n", |
439 | (unsigned) *id); | 488 | (unsigned) id); |
440 | dump_stack(); | 489 | dump_stack(); |
441 | return ret; | 490 | return ret; |
442 | } | 491 | } |
443 | 492 | ||
444 | rcache->valid = true; | 493 | rcache->valid = true; |
445 | rcache->res = res; | 494 | rcache->res = res; |
446 | rcache->handle = *id; | 495 | rcache->handle = id; |
447 | 496 | ||
448 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, | 497 | ret = vmw_resource_relocation_add(&sw_context->res_relocations, |
449 | res, | 498 | res, |
450 | id - sw_context->buf_start); | 499 | id_loc - sw_context->buf_start); |
451 | if (unlikely(ret != 0)) | 500 | if (unlikely(ret != 0)) |
452 | goto out_no_reloc; | 501 | goto out_no_reloc; |
453 | 502 | ||
@@ -459,7 +508,11 @@ static int vmw_cmd_res_check(struct vmw_private *dev_priv, | |||
459 | if (p_val) | 508 | if (p_val) |
460 | *p_val = node; | 509 | *p_val = node; |
461 | 510 | ||
462 | if (node->first_usage && res_type == vmw_res_context) { | 511 | if (dev_priv->has_mob && node->first_usage && |
512 | res_type == vmw_res_context) { | ||
513 | ret = vmw_resource_context_res_add(dev_priv, sw_context, res); | ||
514 | if (unlikely(ret != 0)) | ||
515 | goto out_no_reloc; | ||
463 | node->staged_bindings = | 516 | node->staged_bindings = |
464 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); | 517 | kzalloc(sizeof(*node->staged_bindings), GFP_KERNEL); |
465 | if (node->staged_bindings == NULL) { | 518 | if (node->staged_bindings == NULL) { |
@@ -481,6 +534,59 @@ out_no_reloc: | |||
481 | } | 534 | } |
482 | 535 | ||
483 | /** | 536 | /** |
537 | * vmw_cmd_res_check - Check that a resource is present and if so, put it | ||
538 | * on the resource validate list unless it's already there. | ||
539 | * | ||
540 | * @dev_priv: Pointer to a device private structure. | ||
541 | * @sw_context: Pointer to the software context. | ||
542 | * @res_type: Resource type. | ||
543 | * @converter: User-space visisble type specific information. | ||
544 | * @id_loc: Pointer to the location in the command buffer currently being | ||
545 | * parsed from where the user-space resource id handle is located. | ||
546 | * @p_val: Pointer to pointer to resource validalidation node. Populated | ||
547 | * on exit. | ||
548 | */ | ||
549 | static int | ||
550 | vmw_cmd_res_check(struct vmw_private *dev_priv, | ||
551 | struct vmw_sw_context *sw_context, | ||
552 | enum vmw_res_type res_type, | ||
553 | const struct vmw_user_resource_conv *converter, | ||
554 | uint32_t *id_loc, | ||
555 | struct vmw_resource_val_node **p_val) | ||
556 | { | ||
557 | return vmw_cmd_compat_res_check(dev_priv, sw_context, res_type, | ||
558 | converter, *id_loc, id_loc, p_val); | ||
559 | } | ||
560 | |||
561 | /** | ||
562 | * vmw_rebind_contexts - Rebind all resources previously bound to | ||
563 | * referenced contexts. | ||
564 | * | ||
565 | * @sw_context: Pointer to the software context. | ||
566 | * | ||
567 | * Rebind context binding points that have been scrubbed because of eviction. | ||
568 | */ | ||
569 | static int vmw_rebind_contexts(struct vmw_sw_context *sw_context) | ||
570 | { | ||
571 | struct vmw_resource_val_node *val; | ||
572 | int ret; | ||
573 | |||
574 | list_for_each_entry(val, &sw_context->resource_list, head) { | ||
575 | if (likely(!val->staged_bindings)) | ||
576 | continue; | ||
577 | |||
578 | ret = vmw_context_rebind_all(val->res); | ||
579 | if (unlikely(ret != 0)) { | ||
580 | if (ret != -ERESTARTSYS) | ||
581 | DRM_ERROR("Failed to rebind context.\n"); | ||
582 | return ret; | ||
583 | } | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | /** | ||
484 | * vmw_cmd_cid_check - Check a command header for valid context information. | 590 | * vmw_cmd_cid_check - Check a command header for valid context information. |
485 | * | 591 | * |
486 | * @dev_priv: Pointer to a device private structure. | 592 | * @dev_priv: Pointer to a device private structure. |
@@ -496,7 +602,7 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, | |||
496 | { | 602 | { |
497 | struct vmw_cid_cmd { | 603 | struct vmw_cid_cmd { |
498 | SVGA3dCmdHeader header; | 604 | SVGA3dCmdHeader header; |
499 | __le32 cid; | 605 | uint32_t cid; |
500 | } *cmd; | 606 | } *cmd; |
501 | 607 | ||
502 | cmd = container_of(header, struct vmw_cid_cmd, header); | 608 | cmd = container_of(header, struct vmw_cid_cmd, header); |
@@ -767,7 +873,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, | |||
767 | struct vmw_relocation *reloc; | 873 | struct vmw_relocation *reloc; |
768 | int ret; | 874 | int ret; |
769 | 875 | ||
770 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 876 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
771 | if (unlikely(ret != 0)) { | 877 | if (unlikely(ret != 0)) { |
772 | DRM_ERROR("Could not find or use MOB buffer.\n"); | 878 | DRM_ERROR("Could not find or use MOB buffer.\n"); |
773 | return -EINVAL; | 879 | return -EINVAL; |
@@ -828,7 +934,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, | |||
828 | struct vmw_relocation *reloc; | 934 | struct vmw_relocation *reloc; |
829 | int ret; | 935 | int ret; |
830 | 936 | ||
831 | ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); | 937 | ret = vmw_user_dmabuf_lookup(sw_context->fp->tfile, handle, &vmw_bo); |
832 | if (unlikely(ret != 0)) { | 938 | if (unlikely(ret != 0)) { |
833 | DRM_ERROR("Could not find or use GMR region.\n"); | 939 | DRM_ERROR("Could not find or use GMR region.\n"); |
834 | return -EINVAL; | 940 | return -EINVAL; |
@@ -1127,7 +1233,8 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, | |||
1127 | 1233 | ||
1128 | srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); | 1234 | srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res); |
1129 | 1235 | ||
1130 | vmw_kms_cursor_snoop(srf, sw_context->tfile, &vmw_bo->base, header); | 1236 | vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, |
1237 | header); | ||
1131 | 1238 | ||
1132 | out_no_surface: | 1239 | out_no_surface: |
1133 | vmw_dmabuf_unreference(&vmw_bo); | 1240 | vmw_dmabuf_unreference(&vmw_bo); |
@@ -1478,6 +1585,98 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, | |||
1478 | &cmd->body.sid, NULL); | 1585 | &cmd->body.sid, NULL); |
1479 | } | 1586 | } |
1480 | 1587 | ||
1588 | |||
1589 | /** | ||
1590 | * vmw_cmd_shader_define - Validate an SVGA_3D_CMD_SHADER_DEFINE | ||
1591 | * command | ||
1592 | * | ||
1593 | * @dev_priv: Pointer to a device private struct. | ||
1594 | * @sw_context: The software context being used for this batch. | ||
1595 | * @header: Pointer to the command header in the command stream. | ||
1596 | */ | ||
1597 | static int vmw_cmd_shader_define(struct vmw_private *dev_priv, | ||
1598 | struct vmw_sw_context *sw_context, | ||
1599 | SVGA3dCmdHeader *header) | ||
1600 | { | ||
1601 | struct vmw_shader_define_cmd { | ||
1602 | SVGA3dCmdHeader header; | ||
1603 | SVGA3dCmdDefineShader body; | ||
1604 | } *cmd; | ||
1605 | int ret; | ||
1606 | size_t size; | ||
1607 | |||
1608 | cmd = container_of(header, struct vmw_shader_define_cmd, | ||
1609 | header); | ||
1610 | |||
1611 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1612 | user_context_converter, &cmd->body.cid, | ||
1613 | NULL); | ||
1614 | if (unlikely(ret != 0)) | ||
1615 | return ret; | ||
1616 | |||
1617 | if (unlikely(!dev_priv->has_mob)) | ||
1618 | return 0; | ||
1619 | |||
1620 | size = cmd->header.size - sizeof(cmd->body); | ||
1621 | ret = vmw_compat_shader_add(sw_context->fp->shman, | ||
1622 | cmd->body.shid, cmd + 1, | ||
1623 | cmd->body.type, size, | ||
1624 | sw_context->fp->tfile, | ||
1625 | &sw_context->staged_shaders); | ||
1626 | if (unlikely(ret != 0)) | ||
1627 | return ret; | ||
1628 | |||
1629 | return vmw_resource_relocation_add(&sw_context->res_relocations, | ||
1630 | NULL, &cmd->header.id - | ||
1631 | sw_context->buf_start); | ||
1632 | |||
1633 | return 0; | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
1637 | * vmw_cmd_shader_destroy - Validate an SVGA_3D_CMD_SHADER_DESTROY | ||
1638 | * command | ||
1639 | * | ||
1640 | * @dev_priv: Pointer to a device private struct. | ||
1641 | * @sw_context: The software context being used for this batch. | ||
1642 | * @header: Pointer to the command header in the command stream. | ||
1643 | */ | ||
1644 | static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, | ||
1645 | struct vmw_sw_context *sw_context, | ||
1646 | SVGA3dCmdHeader *header) | ||
1647 | { | ||
1648 | struct vmw_shader_destroy_cmd { | ||
1649 | SVGA3dCmdHeader header; | ||
1650 | SVGA3dCmdDestroyShader body; | ||
1651 | } *cmd; | ||
1652 | int ret; | ||
1653 | |||
1654 | cmd = container_of(header, struct vmw_shader_destroy_cmd, | ||
1655 | header); | ||
1656 | |||
1657 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1658 | user_context_converter, &cmd->body.cid, | ||
1659 | NULL); | ||
1660 | if (unlikely(ret != 0)) | ||
1661 | return ret; | ||
1662 | |||
1663 | if (unlikely(!dev_priv->has_mob)) | ||
1664 | return 0; | ||
1665 | |||
1666 | ret = vmw_compat_shader_remove(sw_context->fp->shman, | ||
1667 | cmd->body.shid, | ||
1668 | cmd->body.type, | ||
1669 | &sw_context->staged_shaders); | ||
1670 | if (unlikely(ret != 0)) | ||
1671 | return ret; | ||
1672 | |||
1673 | return vmw_resource_relocation_add(&sw_context->res_relocations, | ||
1674 | NULL, &cmd->header.id - | ||
1675 | sw_context->buf_start); | ||
1676 | |||
1677 | return 0; | ||
1678 | } | ||
1679 | |||
1481 | /** | 1680 | /** |
1482 | * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER | 1681 | * vmw_cmd_set_shader - Validate an SVGA_3D_CMD_SET_SHADER |
1483 | * command | 1682 | * command |
@@ -1509,10 +1708,18 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
1509 | if (dev_priv->has_mob) { | 1708 | if (dev_priv->has_mob) { |
1510 | struct vmw_ctx_bindinfo bi; | 1709 | struct vmw_ctx_bindinfo bi; |
1511 | struct vmw_resource_val_node *res_node; | 1710 | struct vmw_resource_val_node *res_node; |
1512 | 1711 | u32 shid = cmd->body.shid; | |
1513 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_shader, | 1712 | |
1514 | user_shader_converter, | 1713 | if (shid != SVGA3D_INVALID_ID) |
1515 | &cmd->body.shid, &res_node); | 1714 | (void) vmw_compat_shader_lookup(sw_context->fp->shman, |
1715 | cmd->body.type, | ||
1716 | &shid); | ||
1717 | |||
1718 | ret = vmw_cmd_compat_res_check(dev_priv, sw_context, | ||
1719 | vmw_res_shader, | ||
1720 | user_shader_converter, | ||
1721 | shid, | ||
1722 | &cmd->body.shid, &res_node); | ||
1516 | if (unlikely(ret != 0)) | 1723 | if (unlikely(ret != 0)) |
1517 | return ret; | 1724 | return ret; |
1518 | 1725 | ||
@@ -1527,6 +1734,39 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, | |||
1527 | } | 1734 | } |
1528 | 1735 | ||
1529 | /** | 1736 | /** |
1737 | * vmw_cmd_set_shader_const - Validate an SVGA_3D_CMD_SET_SHADER_CONST | ||
1738 | * command | ||
1739 | * | ||
1740 | * @dev_priv: Pointer to a device private struct. | ||
1741 | * @sw_context: The software context being used for this batch. | ||
1742 | * @header: Pointer to the command header in the command stream. | ||
1743 | */ | ||
1744 | static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, | ||
1745 | struct vmw_sw_context *sw_context, | ||
1746 | SVGA3dCmdHeader *header) | ||
1747 | { | ||
1748 | struct vmw_set_shader_const_cmd { | ||
1749 | SVGA3dCmdHeader header; | ||
1750 | SVGA3dCmdSetShaderConst body; | ||
1751 | } *cmd; | ||
1752 | int ret; | ||
1753 | |||
1754 | cmd = container_of(header, struct vmw_set_shader_const_cmd, | ||
1755 | header); | ||
1756 | |||
1757 | ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, | ||
1758 | user_context_converter, &cmd->body.cid, | ||
1759 | NULL); | ||
1760 | if (unlikely(ret != 0)) | ||
1761 | return ret; | ||
1762 | |||
1763 | if (dev_priv->has_mob) | ||
1764 | header->id = SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE; | ||
1765 | |||
1766 | return 0; | ||
1767 | } | ||
1768 | |||
1769 | /** | ||
1530 | * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER | 1770 | * vmw_cmd_bind_gb_shader - Validate an SVGA_3D_CMD_BIND_GB_SHADER |
1531 | * command | 1771 | * command |
1532 | * | 1772 | * |
@@ -1595,7 +1835,7 @@ static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, | |||
1595 | return 0; | 1835 | return 0; |
1596 | } | 1836 | } |
1597 | 1837 | ||
1598 | static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = { | 1838 | static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { |
1599 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid, | 1839 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid, |
1600 | false, false, false), | 1840 | false, false, false), |
1601 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid, | 1841 | VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid, |
@@ -1634,14 +1874,14 @@ static const struct vmw_cmd_entry const vmw_cmd_entries[SVGA_3D_CMD_MAX] = { | |||
1634 | true, false, false), | 1874 | true, false, false), |
1635 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check, | 1875 | VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check, |
1636 | false, false, false), | 1876 | false, false, false), |
1637 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check, | 1877 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_shader_define, |
1638 | true, true, false), | 1878 | true, false, false), |
1639 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check, | 1879 | VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_shader_destroy, |
1640 | true, true, false), | 1880 | true, false, false), |
1641 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader, | 1881 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader, |
1642 | true, false, false), | 1882 | true, false, false), |
1643 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check, | 1883 | VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_set_shader_const, |
1644 | true, true, false), | 1884 | true, false, false), |
1645 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw, | 1885 | VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw, |
1646 | true, false, false), | 1886 | true, false, false), |
1647 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check, | 1887 | VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check, |
@@ -1792,6 +2032,9 @@ static int vmw_cmd_check(struct vmw_private *dev_priv, | |||
1792 | goto out_invalid; | 2032 | goto out_invalid; |
1793 | 2033 | ||
1794 | entry = &vmw_cmd_entries[cmd_id]; | 2034 | entry = &vmw_cmd_entries[cmd_id]; |
2035 | if (unlikely(!entry->func)) | ||
2036 | goto out_invalid; | ||
2037 | |||
1795 | if (unlikely(!entry->user_allow && !sw_context->kernel)) | 2038 | if (unlikely(!entry->user_allow && !sw_context->kernel)) |
1796 | goto out_privileged; | 2039 | goto out_privileged; |
1797 | 2040 | ||
@@ -2171,7 +2414,7 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2171 | } else | 2414 | } else |
2172 | sw_context->kernel = true; | 2415 | sw_context->kernel = true; |
2173 | 2416 | ||
2174 | sw_context->tfile = vmw_fpriv(file_priv)->tfile; | 2417 | sw_context->fp = vmw_fpriv(file_priv); |
2175 | sw_context->cur_reloc = 0; | 2418 | sw_context->cur_reloc = 0; |
2176 | sw_context->cur_val_buf = 0; | 2419 | sw_context->cur_val_buf = 0; |
2177 | sw_context->fence_flags = 0; | 2420 | sw_context->fence_flags = 0; |
@@ -2188,16 +2431,17 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2188 | goto out_unlock; | 2431 | goto out_unlock; |
2189 | sw_context->res_ht_initialized = true; | 2432 | sw_context->res_ht_initialized = true; |
2190 | } | 2433 | } |
2434 | INIT_LIST_HEAD(&sw_context->staged_shaders); | ||
2191 | 2435 | ||
2192 | INIT_LIST_HEAD(&resource_list); | 2436 | INIT_LIST_HEAD(&resource_list); |
2193 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, | 2437 | ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands, |
2194 | command_size); | 2438 | command_size); |
2195 | if (unlikely(ret != 0)) | 2439 | if (unlikely(ret != 0)) |
2196 | goto out_err; | 2440 | goto out_err_nores; |
2197 | 2441 | ||
2198 | ret = vmw_resources_reserve(sw_context); | 2442 | ret = vmw_resources_reserve(sw_context); |
2199 | if (unlikely(ret != 0)) | 2443 | if (unlikely(ret != 0)) |
2200 | goto out_err; | 2444 | goto out_err_nores; |
2201 | 2445 | ||
2202 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes); | 2446 | ret = ttm_eu_reserve_buffers(&ticket, &sw_context->validate_nodes); |
2203 | if (unlikely(ret != 0)) | 2447 | if (unlikely(ret != 0)) |
@@ -2225,6 +2469,12 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2225 | goto out_err; | 2469 | goto out_err; |
2226 | } | 2470 | } |
2227 | 2471 | ||
2472 | if (dev_priv->has_mob) { | ||
2473 | ret = vmw_rebind_contexts(sw_context); | ||
2474 | if (unlikely(ret != 0)) | ||
2475 | goto out_unlock_binding; | ||
2476 | } | ||
2477 | |||
2228 | cmd = vmw_fifo_reserve(dev_priv, command_size); | 2478 | cmd = vmw_fifo_reserve(dev_priv, command_size); |
2229 | if (unlikely(cmd == NULL)) { | 2479 | if (unlikely(cmd == NULL)) { |
2230 | DRM_ERROR("Failed reserving fifo space for commands.\n"); | 2480 | DRM_ERROR("Failed reserving fifo space for commands.\n"); |
@@ -2276,6 +2526,8 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2276 | } | 2526 | } |
2277 | 2527 | ||
2278 | list_splice_init(&sw_context->resource_list, &resource_list); | 2528 | list_splice_init(&sw_context->resource_list, &resource_list); |
2529 | vmw_compat_shaders_commit(sw_context->fp->shman, | ||
2530 | &sw_context->staged_shaders); | ||
2279 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2531 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
2280 | 2532 | ||
2281 | /* | 2533 | /* |
@@ -2289,10 +2541,11 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
2289 | out_unlock_binding: | 2541 | out_unlock_binding: |
2290 | mutex_unlock(&dev_priv->binding_mutex); | 2542 | mutex_unlock(&dev_priv->binding_mutex); |
2291 | out_err: | 2543 | out_err: |
2292 | vmw_resource_relocations_free(&sw_context->res_relocations); | ||
2293 | vmw_free_relocations(sw_context); | ||
2294 | ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes); | 2544 | ttm_eu_backoff_reservation(&ticket, &sw_context->validate_nodes); |
2545 | out_err_nores: | ||
2295 | vmw_resource_list_unreserve(&sw_context->resource_list, true); | 2546 | vmw_resource_list_unreserve(&sw_context->resource_list, true); |
2547 | vmw_resource_relocations_free(&sw_context->res_relocations); | ||
2548 | vmw_free_relocations(sw_context); | ||
2296 | vmw_clear_validations(sw_context); | 2549 | vmw_clear_validations(sw_context); |
2297 | if (unlikely(dev_priv->pinned_bo != NULL && | 2550 | if (unlikely(dev_priv->pinned_bo != NULL && |
2298 | !dev_priv->query_cid_valid)) | 2551 | !dev_priv->query_cid_valid)) |
@@ -2301,6 +2554,8 @@ out_unlock: | |||
2301 | list_splice_init(&sw_context->resource_list, &resource_list); | 2554 | list_splice_init(&sw_context->resource_list, &resource_list); |
2302 | error_resource = sw_context->error_resource; | 2555 | error_resource = sw_context->error_resource; |
2303 | sw_context->error_resource = NULL; | 2556 | sw_context->error_resource = NULL; |
2557 | vmw_compat_shaders_revert(sw_context->fp->shman, | ||
2558 | &sw_context->staged_shaders); | ||
2304 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 2559 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
2305 | 2560 | ||
2306 | /* | 2561 | /* |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 116c49736763..47b70949bf3a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -29,12 +29,18 @@ | |||
29 | #include <drm/vmwgfx_drm.h> | 29 | #include <drm/vmwgfx_drm.h> |
30 | #include "vmwgfx_kms.h" | 30 | #include "vmwgfx_kms.h" |
31 | 31 | ||
32 | struct svga_3d_compat_cap { | ||
33 | SVGA3dCapsRecordHeader header; | ||
34 | SVGA3dCapPair pairs[SVGA3D_DEVCAP_MAX]; | ||
35 | }; | ||
36 | |||
32 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, | 37 | int vmw_getparam_ioctl(struct drm_device *dev, void *data, |
33 | struct drm_file *file_priv) | 38 | struct drm_file *file_priv) |
34 | { | 39 | { |
35 | struct vmw_private *dev_priv = vmw_priv(dev); | 40 | struct vmw_private *dev_priv = vmw_priv(dev); |
36 | struct drm_vmw_getparam_arg *param = | 41 | struct drm_vmw_getparam_arg *param = |
37 | (struct drm_vmw_getparam_arg *)data; | 42 | (struct drm_vmw_getparam_arg *)data; |
43 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | ||
38 | 44 | ||
39 | switch (param->param) { | 45 | switch (param->param) { |
40 | case DRM_VMW_PARAM_NUM_STREAMS: | 46 | case DRM_VMW_PARAM_NUM_STREAMS: |
@@ -60,6 +66,11 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
60 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 66 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
61 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; | 67 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; |
62 | 68 | ||
69 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) { | ||
70 | param->value = SVGA3D_HWVERSION_WS8_B1; | ||
71 | break; | ||
72 | } | ||
73 | |||
63 | param->value = | 74 | param->value = |
64 | ioread32(fifo_mem + | 75 | ioread32(fifo_mem + |
65 | ((fifo->capabilities & | 76 | ((fifo->capabilities & |
@@ -69,19 +80,31 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
69 | break; | 80 | break; |
70 | } | 81 | } |
71 | case DRM_VMW_PARAM_MAX_SURF_MEMORY: | 82 | case DRM_VMW_PARAM_MAX_SURF_MEMORY: |
72 | param->value = dev_priv->memory_size; | 83 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && |
84 | !vmw_fp->gb_aware) | ||
85 | param->value = dev_priv->max_mob_pages * PAGE_SIZE / 2; | ||
86 | else | ||
87 | param->value = dev_priv->memory_size; | ||
73 | break; | 88 | break; |
74 | case DRM_VMW_PARAM_3D_CAPS_SIZE: | 89 | case DRM_VMW_PARAM_3D_CAPS_SIZE: |
75 | if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) | 90 | if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && |
76 | param->value = SVGA3D_DEVCAP_MAX; | 91 | vmw_fp->gb_aware) |
92 | param->value = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); | ||
93 | else if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) | ||
94 | param->value = sizeof(struct svga_3d_compat_cap) + | ||
95 | sizeof(uint32_t); | ||
77 | else | 96 | else |
78 | param->value = (SVGA_FIFO_3D_CAPS_LAST - | 97 | param->value = (SVGA_FIFO_3D_CAPS_LAST - |
79 | SVGA_FIFO_3D_CAPS + 1); | 98 | SVGA_FIFO_3D_CAPS + 1) * |
80 | param->value *= sizeof(uint32_t); | 99 | sizeof(uint32_t); |
81 | break; | 100 | break; |
82 | case DRM_VMW_PARAM_MAX_MOB_MEMORY: | 101 | case DRM_VMW_PARAM_MAX_MOB_MEMORY: |
102 | vmw_fp->gb_aware = true; | ||
83 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; | 103 | param->value = dev_priv->max_mob_pages * PAGE_SIZE; |
84 | break; | 104 | break; |
105 | case DRM_VMW_PARAM_MAX_MOB_SIZE: | ||
106 | param->value = dev_priv->max_mob_size; | ||
107 | break; | ||
85 | default: | 108 | default: |
86 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", | 109 | DRM_ERROR("Illegal vmwgfx get param request: %d\n", |
87 | param->param); | 110 | param->param); |
@@ -91,6 +114,38 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
91 | return 0; | 114 | return 0; |
92 | } | 115 | } |
93 | 116 | ||
117 | static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, | ||
118 | size_t size) | ||
119 | { | ||
120 | struct svga_3d_compat_cap *compat_cap = | ||
121 | (struct svga_3d_compat_cap *) bounce; | ||
122 | unsigned int i; | ||
123 | size_t pair_offset = offsetof(struct svga_3d_compat_cap, pairs); | ||
124 | unsigned int max_size; | ||
125 | |||
126 | if (size < pair_offset) | ||
127 | return -EINVAL; | ||
128 | |||
129 | max_size = (size - pair_offset) / sizeof(SVGA3dCapPair); | ||
130 | |||
131 | if (max_size > SVGA3D_DEVCAP_MAX) | ||
132 | max_size = SVGA3D_DEVCAP_MAX; | ||
133 | |||
134 | compat_cap->header.length = | ||
135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); | ||
136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; | ||
137 | |||
138 | mutex_lock(&dev_priv->hw_mutex); | ||
139 | for (i = 0; i < max_size; ++i) { | ||
140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | ||
141 | compat_cap->pairs[i][0] = i; | ||
142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | ||
143 | } | ||
144 | mutex_unlock(&dev_priv->hw_mutex); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
94 | 149 | ||
95 | int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | 150 | int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, |
96 | struct drm_file *file_priv) | 151 | struct drm_file *file_priv) |
@@ -104,41 +159,49 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
104 | void *bounce; | 159 | void *bounce; |
105 | int ret; | 160 | int ret; |
106 | bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); | 161 | bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); |
162 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | ||
107 | 163 | ||
108 | if (unlikely(arg->pad64 != 0)) { | 164 | if (unlikely(arg->pad64 != 0)) { |
109 | DRM_ERROR("Illegal GET_3D_CAP argument.\n"); | 165 | DRM_ERROR("Illegal GET_3D_CAP argument.\n"); |
110 | return -EINVAL; | 166 | return -EINVAL; |
111 | } | 167 | } |
112 | 168 | ||
113 | if (gb_objects) | 169 | if (gb_objects && vmw_fp->gb_aware) |
114 | size = SVGA3D_DEVCAP_MAX; | 170 | size = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); |
171 | else if (gb_objects) | ||
172 | size = sizeof(struct svga_3d_compat_cap) + sizeof(uint32_t); | ||
115 | else | 173 | else |
116 | size = (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1); | 174 | size = (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1) * |
117 | 175 | sizeof(uint32_t); | |
118 | size *= sizeof(uint32_t); | ||
119 | 176 | ||
120 | if (arg->max_size < size) | 177 | if (arg->max_size < size) |
121 | size = arg->max_size; | 178 | size = arg->max_size; |
122 | 179 | ||
123 | bounce = vmalloc(size); | 180 | bounce = vzalloc(size); |
124 | if (unlikely(bounce == NULL)) { | 181 | if (unlikely(bounce == NULL)) { |
125 | DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n"); | 182 | DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n"); |
126 | return -ENOMEM; | 183 | return -ENOMEM; |
127 | } | 184 | } |
128 | 185 | ||
129 | if (gb_objects) { | 186 | if (gb_objects && vmw_fp->gb_aware) { |
130 | int i; | 187 | int i, num; |
131 | uint32_t *bounce32 = (uint32_t *) bounce; | 188 | uint32_t *bounce32 = (uint32_t *) bounce; |
132 | 189 | ||
190 | num = size / sizeof(uint32_t); | ||
191 | if (num > SVGA3D_DEVCAP_MAX) | ||
192 | num = SVGA3D_DEVCAP_MAX; | ||
193 | |||
133 | mutex_lock(&dev_priv->hw_mutex); | 194 | mutex_lock(&dev_priv->hw_mutex); |
134 | for (i = 0; i < SVGA3D_DEVCAP_MAX; ++i) { | 195 | for (i = 0; i < num; ++i) { |
135 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
136 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
137 | } | 198 | } |
138 | mutex_unlock(&dev_priv->hw_mutex); | 199 | mutex_unlock(&dev_priv->hw_mutex); |
139 | 200 | } else if (gb_objects) { | |
201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); | ||
202 | if (unlikely(ret != 0)) | ||
203 | goto out_err; | ||
140 | } else { | 204 | } else { |
141 | |||
142 | fifo_mem = dev_priv->mmio_virt; | 205 | fifo_mem = dev_priv->mmio_virt; |
143 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); | 206 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
144 | } | 207 | } |
@@ -146,6 +209,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
146 | ret = copy_to_user(buffer, bounce, size); | 209 | ret = copy_to_user(buffer, bounce, size); |
147 | if (ret) | 210 | if (ret) |
148 | ret = -EFAULT; | 211 | ret = -EFAULT; |
212 | out_err: | ||
149 | vfree(bounce); | 213 | vfree(bounce); |
150 | 214 | ||
151 | if (unlikely(ret != 0)) | 215 | if (unlikely(ret != 0)) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 4910e7b81811..04a64b8cd3cd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | |||
@@ -134,6 +134,7 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv, | |||
134 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 134 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
135 | if (unlikely(cmd == NULL)) { | 135 | if (unlikely(cmd == NULL)) { |
136 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); | 136 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); |
137 | ret = -ENOMEM; | ||
137 | goto out_no_fifo; | 138 | goto out_no_fifo; |
138 | } | 139 | } |
139 | 140 | ||
@@ -187,18 +188,20 @@ static void vmw_takedown_otable_base(struct vmw_private *dev_priv, | |||
187 | 188 | ||
188 | bo = otable->page_table->pt_bo; | 189 | bo = otable->page_table->pt_bo; |
189 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 190 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
190 | if (unlikely(cmd == NULL)) | 191 | if (unlikely(cmd == NULL)) { |
191 | DRM_ERROR("Failed reserving FIFO space for OTable setup.\n"); | 192 | DRM_ERROR("Failed reserving FIFO space for OTable " |
192 | 193 | "takedown.\n"); | |
193 | memset(cmd, 0, sizeof(*cmd)); | 194 | } else { |
194 | cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; | 195 | memset(cmd, 0, sizeof(*cmd)); |
195 | cmd->header.size = sizeof(cmd->body); | 196 | cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE; |
196 | cmd->body.type = type; | 197 | cmd->header.size = sizeof(cmd->body); |
197 | cmd->body.baseAddress = 0; | 198 | cmd->body.type = type; |
198 | cmd->body.sizeInBytes = 0; | 199 | cmd->body.baseAddress = 0; |
199 | cmd->body.validSizeInBytes = 0; | 200 | cmd->body.sizeInBytes = 0; |
200 | cmd->body.ptDepth = SVGA3D_MOBFMT_INVALID; | 201 | cmd->body.validSizeInBytes = 0; |
201 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | 202 | cmd->body.ptDepth = SVGA3D_MOBFMT_INVALID; |
203 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
204 | } | ||
202 | 205 | ||
203 | if (bo) { | 206 | if (bo) { |
204 | int ret; | 207 | int ret; |
@@ -561,11 +564,12 @@ void vmw_mob_unbind(struct vmw_private *dev_priv, | |||
561 | if (unlikely(cmd == NULL)) { | 564 | if (unlikely(cmd == NULL)) { |
562 | DRM_ERROR("Failed reserving FIFO space for Memory " | 565 | DRM_ERROR("Failed reserving FIFO space for Memory " |
563 | "Object unbinding.\n"); | 566 | "Object unbinding.\n"); |
567 | } else { | ||
568 | cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB; | ||
569 | cmd->header.size = sizeof(cmd->body); | ||
570 | cmd->body.mobid = mob->id; | ||
571 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
564 | } | 572 | } |
565 | cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB; | ||
566 | cmd->header.size = sizeof(cmd->body); | ||
567 | cmd->body.mobid = mob->id; | ||
568 | vmw_fifo_commit(dev_priv, sizeof(*cmd)); | ||
569 | if (bo) { | 573 | if (bo) { |
570 | vmw_fence_single_bo(bo, NULL); | 574 | vmw_fence_single_bo(bo, NULL); |
571 | ttm_bo_unreserve(bo); | 575 | ttm_bo_unreserve(bo); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 6fdd82d42f65..9757b57f8388 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -88,6 +88,11 @@ struct vmw_resource *vmw_resource_reference(struct vmw_resource *res) | |||
88 | return res; | 88 | return res; |
89 | } | 89 | } |
90 | 90 | ||
91 | struct vmw_resource * | ||
92 | vmw_resource_reference_unless_doomed(struct vmw_resource *res) | ||
93 | { | ||
94 | return kref_get_unless_zero(&res->kref) ? res : NULL; | ||
95 | } | ||
91 | 96 | ||
92 | /** | 97 | /** |
93 | * vmw_resource_release_id - release a resource id to the id manager. | 98 | * vmw_resource_release_id - release a resource id to the id manager. |
@@ -136,8 +141,12 @@ static void vmw_resource_release(struct kref *kref) | |||
136 | vmw_dmabuf_unreference(&res->backup); | 141 | vmw_dmabuf_unreference(&res->backup); |
137 | } | 142 | } |
138 | 143 | ||
139 | if (likely(res->hw_destroy != NULL)) | 144 | if (likely(res->hw_destroy != NULL)) { |
140 | res->hw_destroy(res); | 145 | res->hw_destroy(res); |
146 | mutex_lock(&dev_priv->binding_mutex); | ||
147 | vmw_context_binding_res_list_kill(&res->binding_head); | ||
148 | mutex_unlock(&dev_priv->binding_mutex); | ||
149 | } | ||
141 | 150 | ||
142 | id = res->id; | 151 | id = res->id; |
143 | if (res->res_free != NULL) | 152 | if (res->res_free != NULL) |
@@ -418,8 +427,7 @@ int vmw_dmabuf_init(struct vmw_private *dev_priv, | |||
418 | INIT_LIST_HEAD(&vmw_bo->res_list); | 427 | INIT_LIST_HEAD(&vmw_bo->res_list); |
419 | 428 | ||
420 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, | 429 | ret = ttm_bo_init(bdev, &vmw_bo->base, size, |
421 | (user) ? ttm_bo_type_device : | 430 | ttm_bo_type_device, placement, |
422 | ttm_bo_type_kernel, placement, | ||
423 | 0, interruptible, | 431 | 0, interruptible, |
424 | NULL, acc_size, NULL, bo_free); | 432 | NULL, acc_size, NULL, bo_free); |
425 | return ret; | 433 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index 1457ec4b7125..ee3856578a12 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "vmwgfx_resource_priv.h" | 29 | #include "vmwgfx_resource_priv.h" |
30 | #include "ttm/ttm_placement.h" | 30 | #include "ttm/ttm_placement.h" |
31 | 31 | ||
32 | #define VMW_COMPAT_SHADER_HT_ORDER 12 | ||
33 | |||
32 | struct vmw_shader { | 34 | struct vmw_shader { |
33 | struct vmw_resource res; | 35 | struct vmw_resource res; |
34 | SVGA3dShaderType type; | 36 | SVGA3dShaderType type; |
@@ -40,6 +42,50 @@ struct vmw_user_shader { | |||
40 | struct vmw_shader shader; | 42 | struct vmw_shader shader; |
41 | }; | 43 | }; |
42 | 44 | ||
45 | /** | ||
46 | * enum vmw_compat_shader_state - Staging state for compat shaders | ||
47 | */ | ||
48 | enum vmw_compat_shader_state { | ||
49 | VMW_COMPAT_COMMITED, | ||
50 | VMW_COMPAT_ADD, | ||
51 | VMW_COMPAT_DEL | ||
52 | }; | ||
53 | |||
54 | /** | ||
55 | * struct vmw_compat_shader - Metadata for compat shaders. | ||
56 | * | ||
57 | * @handle: The TTM handle of the guest backed shader. | ||
58 | * @tfile: The struct ttm_object_file the guest backed shader is registered | ||
59 | * with. | ||
60 | * @hash: Hash item for lookup. | ||
61 | * @head: List head for staging lists or the compat shader manager list. | ||
62 | * @state: Staging state. | ||
63 | * | ||
64 | * The structure is protected by the cmdbuf lock. | ||
65 | */ | ||
66 | struct vmw_compat_shader { | ||
67 | u32 handle; | ||
68 | struct ttm_object_file *tfile; | ||
69 | struct drm_hash_item hash; | ||
70 | struct list_head head; | ||
71 | enum vmw_compat_shader_state state; | ||
72 | }; | ||
73 | |||
74 | /** | ||
75 | * struct vmw_compat_shader_manager - Compat shader manager. | ||
76 | * | ||
77 | * @shaders: Hash table containing staged and commited compat shaders | ||
78 | * @list: List of commited shaders. | ||
79 | * @dev_priv: Pointer to a device private structure. | ||
80 | * | ||
81 | * @shaders and @list are protected by the cmdbuf mutex for now. | ||
82 | */ | ||
83 | struct vmw_compat_shader_manager { | ||
84 | struct drm_open_hash shaders; | ||
85 | struct list_head list; | ||
86 | struct vmw_private *dev_priv; | ||
87 | }; | ||
88 | |||
43 | static void vmw_user_shader_free(struct vmw_resource *res); | 89 | static void vmw_user_shader_free(struct vmw_resource *res); |
44 | static struct vmw_resource * | 90 | static struct vmw_resource * |
45 | vmw_user_shader_base_to_res(struct ttm_base_object *base); | 91 | vmw_user_shader_base_to_res(struct ttm_base_object *base); |
@@ -258,7 +304,7 @@ static int vmw_gb_shader_destroy(struct vmw_resource *res) | |||
258 | return 0; | 304 | return 0; |
259 | 305 | ||
260 | mutex_lock(&dev_priv->binding_mutex); | 306 | mutex_lock(&dev_priv->binding_mutex); |
261 | vmw_context_binding_res_list_kill(&res->binding_head); | 307 | vmw_context_binding_res_list_scrub(&res->binding_head); |
262 | 308 | ||
263 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 309 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
264 | if (unlikely(cmd == NULL)) { | 310 | if (unlikely(cmd == NULL)) { |
@@ -325,13 +371,81 @@ int vmw_shader_destroy_ioctl(struct drm_device *dev, void *data, | |||
325 | TTM_REF_USAGE); | 371 | TTM_REF_USAGE); |
326 | } | 372 | } |
327 | 373 | ||
374 | static int vmw_shader_alloc(struct vmw_private *dev_priv, | ||
375 | struct vmw_dma_buffer *buffer, | ||
376 | size_t shader_size, | ||
377 | size_t offset, | ||
378 | SVGA3dShaderType shader_type, | ||
379 | struct ttm_object_file *tfile, | ||
380 | u32 *handle) | ||
381 | { | ||
382 | struct vmw_user_shader *ushader; | ||
383 | struct vmw_resource *res, *tmp; | ||
384 | int ret; | ||
385 | |||
386 | /* | ||
387 | * Approximate idr memory usage with 128 bytes. It will be limited | ||
388 | * by maximum number_of shaders anyway. | ||
389 | */ | ||
390 | if (unlikely(vmw_user_shader_size == 0)) | ||
391 | vmw_user_shader_size = | ||
392 | ttm_round_pot(sizeof(struct vmw_user_shader)) + 128; | ||
393 | |||
394 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), | ||
395 | vmw_user_shader_size, | ||
396 | false, true); | ||
397 | if (unlikely(ret != 0)) { | ||
398 | if (ret != -ERESTARTSYS) | ||
399 | DRM_ERROR("Out of graphics memory for shader " | ||
400 | "creation.\n"); | ||
401 | goto out; | ||
402 | } | ||
403 | |||
404 | ushader = kzalloc(sizeof(*ushader), GFP_KERNEL); | ||
405 | if (unlikely(ushader == NULL)) { | ||
406 | ttm_mem_global_free(vmw_mem_glob(dev_priv), | ||
407 | vmw_user_shader_size); | ||
408 | ret = -ENOMEM; | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | res = &ushader->shader.res; | ||
413 | ushader->base.shareable = false; | ||
414 | ushader->base.tfile = NULL; | ||
415 | |||
416 | /* | ||
417 | * From here on, the destructor takes over resource freeing. | ||
418 | */ | ||
419 | |||
420 | ret = vmw_gb_shader_init(dev_priv, res, shader_size, | ||
421 | offset, shader_type, buffer, | ||
422 | vmw_user_shader_free); | ||
423 | if (unlikely(ret != 0)) | ||
424 | goto out; | ||
425 | |||
426 | tmp = vmw_resource_reference(res); | ||
427 | ret = ttm_base_object_init(tfile, &ushader->base, false, | ||
428 | VMW_RES_SHADER, | ||
429 | &vmw_user_shader_base_release, NULL); | ||
430 | |||
431 | if (unlikely(ret != 0)) { | ||
432 | vmw_resource_unreference(&tmp); | ||
433 | goto out_err; | ||
434 | } | ||
435 | |||
436 | if (handle) | ||
437 | *handle = ushader->base.hash.key; | ||
438 | out_err: | ||
439 | vmw_resource_unreference(&res); | ||
440 | out: | ||
441 | return ret; | ||
442 | } | ||
443 | |||
444 | |||
328 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | 445 | int vmw_shader_define_ioctl(struct drm_device *dev, void *data, |
329 | struct drm_file *file_priv) | 446 | struct drm_file *file_priv) |
330 | { | 447 | { |
331 | struct vmw_private *dev_priv = vmw_priv(dev); | 448 | struct vmw_private *dev_priv = vmw_priv(dev); |
332 | struct vmw_user_shader *ushader; | ||
333 | struct vmw_resource *res; | ||
334 | struct vmw_resource *tmp; | ||
335 | struct drm_vmw_shader_create_arg *arg = | 449 | struct drm_vmw_shader_create_arg *arg = |
336 | (struct drm_vmw_shader_create_arg *)data; | 450 | (struct drm_vmw_shader_create_arg *)data; |
337 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | 451 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; |
@@ -373,69 +487,326 @@ int vmw_shader_define_ioctl(struct drm_device *dev, void *data, | |||
373 | goto out_bad_arg; | 487 | goto out_bad_arg; |
374 | } | 488 | } |
375 | 489 | ||
376 | /* | 490 | ret = ttm_read_lock(&vmaster->lock, true); |
377 | * Approximate idr memory usage with 128 bytes. It will be limited | 491 | if (unlikely(ret != 0)) |
378 | * by maximum number_of shaders anyway. | 492 | goto out_bad_arg; |
379 | */ | ||
380 | 493 | ||
381 | if (unlikely(vmw_user_shader_size == 0)) | 494 | ret = vmw_shader_alloc(dev_priv, buffer, arg->size, arg->offset, |
382 | vmw_user_shader_size = ttm_round_pot(sizeof(*ushader)) | 495 | shader_type, tfile, &arg->shader_handle); |
383 | + 128; | ||
384 | 496 | ||
385 | ret = ttm_read_lock(&vmaster->lock, true); | 497 | ttm_read_unlock(&vmaster->lock); |
498 | out_bad_arg: | ||
499 | vmw_dmabuf_unreference(&buffer); | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * vmw_compat_shader_lookup - Look up a compat shader | ||
505 | * | ||
506 | * @man: Pointer to the compat shader manager. | ||
507 | * @shader_type: The shader type, that combined with the user_key identifies | ||
508 | * the shader. | ||
509 | * @user_key: On entry, this should be a pointer to the user_key. | ||
510 | * On successful exit, it will contain the guest-backed shader's TTM handle. | ||
511 | * | ||
512 | * Returns 0 on success. Non-zero on failure, in which case the value pointed | ||
513 | * to by @user_key is unmodified. | ||
514 | */ | ||
515 | int vmw_compat_shader_lookup(struct vmw_compat_shader_manager *man, | ||
516 | SVGA3dShaderType shader_type, | ||
517 | u32 *user_key) | ||
518 | { | ||
519 | struct drm_hash_item *hash; | ||
520 | int ret; | ||
521 | unsigned long key = *user_key | (shader_type << 24); | ||
522 | |||
523 | ret = drm_ht_find_item(&man->shaders, key, &hash); | ||
386 | if (unlikely(ret != 0)) | 524 | if (unlikely(ret != 0)) |
387 | return ret; | 525 | return ret; |
388 | 526 | ||
389 | ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), | 527 | *user_key = drm_hash_entry(hash, struct vmw_compat_shader, |
390 | vmw_user_shader_size, | 528 | hash)->handle; |
391 | false, true); | 529 | |
392 | if (unlikely(ret != 0)) { | 530 | return 0; |
393 | if (ret != -ERESTARTSYS) | 531 | } |
394 | DRM_ERROR("Out of graphics memory for shader" | 532 | |
395 | " creation.\n"); | 533 | /** |
396 | goto out_unlock; | 534 | * vmw_compat_shader_free - Free a compat shader. |
535 | * | ||
536 | * @man: Pointer to the compat shader manager. | ||
537 | * @entry: Pointer to a struct vmw_compat_shader. | ||
538 | * | ||
539 | * Frees a struct vmw_compat_shder entry and drops its reference to the | ||
540 | * guest backed shader. | ||
541 | */ | ||
542 | static void vmw_compat_shader_free(struct vmw_compat_shader_manager *man, | ||
543 | struct vmw_compat_shader *entry) | ||
544 | { | ||
545 | list_del(&entry->head); | ||
546 | WARN_ON(drm_ht_remove_item(&man->shaders, &entry->hash)); | ||
547 | WARN_ON(ttm_ref_object_base_unref(entry->tfile, entry->handle, | ||
548 | TTM_REF_USAGE)); | ||
549 | kfree(entry); | ||
550 | } | ||
551 | |||
552 | /** | ||
553 | * vmw_compat_shaders_commit - Commit a list of compat shader actions. | ||
554 | * | ||
555 | * @man: Pointer to the compat shader manager. | ||
556 | * @list: Caller's list of compat shader actions. | ||
557 | * | ||
558 | * This function commits a list of compat shader additions or removals. | ||
559 | * It is typically called when the execbuf ioctl call triggering these | ||
560 | * actions has commited the fifo contents to the device. | ||
561 | */ | ||
562 | void vmw_compat_shaders_commit(struct vmw_compat_shader_manager *man, | ||
563 | struct list_head *list) | ||
564 | { | ||
565 | struct vmw_compat_shader *entry, *next; | ||
566 | |||
567 | list_for_each_entry_safe(entry, next, list, head) { | ||
568 | list_del(&entry->head); | ||
569 | switch (entry->state) { | ||
570 | case VMW_COMPAT_ADD: | ||
571 | entry->state = VMW_COMPAT_COMMITED; | ||
572 | list_add_tail(&entry->head, &man->list); | ||
573 | break; | ||
574 | case VMW_COMPAT_DEL: | ||
575 | ttm_ref_object_base_unref(entry->tfile, entry->handle, | ||
576 | TTM_REF_USAGE); | ||
577 | kfree(entry); | ||
578 | break; | ||
579 | default: | ||
580 | BUG(); | ||
581 | break; | ||
582 | } | ||
397 | } | 583 | } |
584 | } | ||
398 | 585 | ||
399 | ushader = kzalloc(sizeof(*ushader), GFP_KERNEL); | 586 | /** |
400 | if (unlikely(ushader == NULL)) { | 587 | * vmw_compat_shaders_revert - Revert a list of compat shader actions |
401 | ttm_mem_global_free(vmw_mem_glob(dev_priv), | 588 | * |
402 | vmw_user_shader_size); | 589 | * @man: Pointer to the compat shader manager. |
403 | ret = -ENOMEM; | 590 | * @list: Caller's list of compat shader actions. |
404 | goto out_unlock; | 591 | * |
592 | * This function reverts a list of compat shader additions or removals. | ||
593 | * It is typically called when the execbuf ioctl call triggering these | ||
594 | * actions failed for some reason, and the command stream was never | ||
595 | * submitted. | ||
596 | */ | ||
597 | void vmw_compat_shaders_revert(struct vmw_compat_shader_manager *man, | ||
598 | struct list_head *list) | ||
599 | { | ||
600 | struct vmw_compat_shader *entry, *next; | ||
601 | int ret; | ||
602 | |||
603 | list_for_each_entry_safe(entry, next, list, head) { | ||
604 | switch (entry->state) { | ||
605 | case VMW_COMPAT_ADD: | ||
606 | vmw_compat_shader_free(man, entry); | ||
607 | break; | ||
608 | case VMW_COMPAT_DEL: | ||
609 | ret = drm_ht_insert_item(&man->shaders, &entry->hash); | ||
610 | list_del(&entry->head); | ||
611 | list_add_tail(&entry->head, &man->list); | ||
612 | entry->state = VMW_COMPAT_COMMITED; | ||
613 | break; | ||
614 | default: | ||
615 | BUG(); | ||
616 | break; | ||
617 | } | ||
405 | } | 618 | } |
619 | } | ||
406 | 620 | ||
407 | res = &ushader->shader.res; | 621 | /** |
408 | ushader->base.shareable = false; | 622 | * vmw_compat_shader_remove - Stage a compat shader for removal. |
409 | ushader->base.tfile = NULL; | 623 | * |
624 | * @man: Pointer to the compat shader manager | ||
625 | * @user_key: The key that is used to identify the shader. The key is | ||
626 | * unique to the shader type. | ||
627 | * @shader_type: Shader type. | ||
628 | * @list: Caller's list of staged shader actions. | ||
629 | * | ||
630 | * This function stages a compat shader for removal and removes the key from | ||
631 | * the shader manager's hash table. If the shader was previously only staged | ||
632 | * for addition it is completely removed (But the execbuf code may keep a | ||
633 | * reference if it was bound to a context between addition and removal). If | ||
634 | * it was previously commited to the manager, it is staged for removal. | ||
635 | */ | ||
636 | int vmw_compat_shader_remove(struct vmw_compat_shader_manager *man, | ||
637 | u32 user_key, SVGA3dShaderType shader_type, | ||
638 | struct list_head *list) | ||
639 | { | ||
640 | struct vmw_compat_shader *entry; | ||
641 | struct drm_hash_item *hash; | ||
642 | int ret; | ||
410 | 643 | ||
411 | /* | 644 | ret = drm_ht_find_item(&man->shaders, user_key | (shader_type << 24), |
412 | * From here on, the destructor takes over resource freeing. | 645 | &hash); |
413 | */ | 646 | if (likely(ret != 0)) |
647 | return -EINVAL; | ||
414 | 648 | ||
415 | ret = vmw_gb_shader_init(dev_priv, res, arg->size, | 649 | entry = drm_hash_entry(hash, struct vmw_compat_shader, hash); |
416 | arg->offset, shader_type, buffer, | 650 | |
417 | vmw_user_shader_free); | 651 | switch (entry->state) { |
652 | case VMW_COMPAT_ADD: | ||
653 | vmw_compat_shader_free(man, entry); | ||
654 | break; | ||
655 | case VMW_COMPAT_COMMITED: | ||
656 | (void) drm_ht_remove_item(&man->shaders, &entry->hash); | ||
657 | list_del(&entry->head); | ||
658 | entry->state = VMW_COMPAT_DEL; | ||
659 | list_add_tail(&entry->head, list); | ||
660 | break; | ||
661 | default: | ||
662 | BUG(); | ||
663 | break; | ||
664 | } | ||
665 | |||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | /** | ||
670 | * vmw_compat_shader_add - Create a compat shader and add the | ||
671 | * key to the manager | ||
672 | * | ||
673 | * @man: Pointer to the compat shader manager | ||
674 | * @user_key: The key that is used to identify the shader. The key is | ||
675 | * unique to the shader type. | ||
676 | * @bytecode: Pointer to the bytecode of the shader. | ||
677 | * @shader_type: Shader type. | ||
678 | * @tfile: Pointer to a struct ttm_object_file that the guest-backed shader is | ||
679 | * to be created with. | ||
680 | * @list: Caller's list of staged shader actions. | ||
681 | * | ||
682 | * Note that only the key is added to the shader manager's hash table. | ||
683 | * The shader is not yet added to the shader manager's list of shaders. | ||
684 | */ | ||
685 | int vmw_compat_shader_add(struct vmw_compat_shader_manager *man, | ||
686 | u32 user_key, const void *bytecode, | ||
687 | SVGA3dShaderType shader_type, | ||
688 | size_t size, | ||
689 | struct ttm_object_file *tfile, | ||
690 | struct list_head *list) | ||
691 | { | ||
692 | struct vmw_dma_buffer *buf; | ||
693 | struct ttm_bo_kmap_obj map; | ||
694 | bool is_iomem; | ||
695 | struct vmw_compat_shader *compat; | ||
696 | u32 handle; | ||
697 | int ret; | ||
698 | |||
699 | if (user_key > ((1 << 24) - 1) || (unsigned) shader_type > 16) | ||
700 | return -EINVAL; | ||
701 | |||
702 | /* Allocate and pin a DMA buffer */ | ||
703 | buf = kzalloc(sizeof(*buf), GFP_KERNEL); | ||
704 | if (unlikely(buf == NULL)) | ||
705 | return -ENOMEM; | ||
706 | |||
707 | ret = vmw_dmabuf_init(man->dev_priv, buf, size, &vmw_sys_ne_placement, | ||
708 | true, vmw_dmabuf_bo_free); | ||
418 | if (unlikely(ret != 0)) | 709 | if (unlikely(ret != 0)) |
419 | goto out_unlock; | 710 | goto out; |
420 | 711 | ||
421 | tmp = vmw_resource_reference(res); | 712 | ret = ttm_bo_reserve(&buf->base, false, true, false, NULL); |
422 | ret = ttm_base_object_init(tfile, &ushader->base, false, | 713 | if (unlikely(ret != 0)) |
423 | VMW_RES_SHADER, | 714 | goto no_reserve; |
424 | &vmw_user_shader_base_release, NULL); | ||
425 | 715 | ||
716 | /* Map and copy shader bytecode. */ | ||
717 | ret = ttm_bo_kmap(&buf->base, 0, PAGE_ALIGN(size) >> PAGE_SHIFT, | ||
718 | &map); | ||
426 | if (unlikely(ret != 0)) { | 719 | if (unlikely(ret != 0)) { |
427 | vmw_resource_unreference(&tmp); | 720 | ttm_bo_unreserve(&buf->base); |
428 | goto out_err; | 721 | goto no_reserve; |
429 | } | 722 | } |
430 | 723 | ||
431 | arg->shader_handle = ushader->base.hash.key; | 724 | memcpy(ttm_kmap_obj_virtual(&map, &is_iomem), bytecode, size); |
432 | out_err: | 725 | WARN_ON(is_iomem); |
433 | vmw_resource_unreference(&res); | 726 | |
434 | out_unlock: | 727 | ttm_bo_kunmap(&map); |
435 | ttm_read_unlock(&vmaster->lock); | 728 | ret = ttm_bo_validate(&buf->base, &vmw_sys_placement, false, true); |
436 | out_bad_arg: | 729 | WARN_ON(ret != 0); |
437 | vmw_dmabuf_unreference(&buffer); | 730 | ttm_bo_unreserve(&buf->base); |
731 | |||
732 | /* Create a guest-backed shader container backed by the dma buffer */ | ||
733 | ret = vmw_shader_alloc(man->dev_priv, buf, size, 0, shader_type, | ||
734 | tfile, &handle); | ||
735 | vmw_dmabuf_unreference(&buf); | ||
736 | if (unlikely(ret != 0)) | ||
737 | goto no_reserve; | ||
738 | /* | ||
739 | * Create a compat shader structure and stage it for insertion | ||
740 | * in the manager | ||
741 | */ | ||
742 | compat = kzalloc(sizeof(*compat), GFP_KERNEL); | ||
743 | if (compat == NULL) | ||
744 | goto no_compat; | ||
745 | |||
746 | compat->hash.key = user_key | (shader_type << 24); | ||
747 | ret = drm_ht_insert_item(&man->shaders, &compat->hash); | ||
748 | if (unlikely(ret != 0)) | ||
749 | goto out_invalid_key; | ||
750 | |||
751 | compat->state = VMW_COMPAT_ADD; | ||
752 | compat->handle = handle; | ||
753 | compat->tfile = tfile; | ||
754 | list_add_tail(&compat->head, list); | ||
438 | 755 | ||
756 | return 0; | ||
757 | |||
758 | out_invalid_key: | ||
759 | kfree(compat); | ||
760 | no_compat: | ||
761 | ttm_ref_object_base_unref(tfile, handle, TTM_REF_USAGE); | ||
762 | no_reserve: | ||
763 | out: | ||
439 | return ret; | 764 | return ret; |
765 | } | ||
766 | |||
767 | /** | ||
768 | * vmw_compat_shader_man_create - Create a compat shader manager | ||
769 | * | ||
770 | * @dev_priv: Pointer to a device private structure. | ||
771 | * | ||
772 | * Typically done at file open time. If successful returns a pointer to a | ||
773 | * compat shader manager. Otherwise returns an error pointer. | ||
774 | */ | ||
775 | struct vmw_compat_shader_manager * | ||
776 | vmw_compat_shader_man_create(struct vmw_private *dev_priv) | ||
777 | { | ||
778 | struct vmw_compat_shader_manager *man; | ||
779 | int ret; | ||
780 | |||
781 | man = kzalloc(sizeof(*man), GFP_KERNEL); | ||
782 | if (man == NULL) | ||
783 | return ERR_PTR(-ENOMEM); | ||
784 | |||
785 | man->dev_priv = dev_priv; | ||
786 | INIT_LIST_HEAD(&man->list); | ||
787 | ret = drm_ht_create(&man->shaders, VMW_COMPAT_SHADER_HT_ORDER); | ||
788 | if (ret == 0) | ||
789 | return man; | ||
790 | |||
791 | kfree(man); | ||
792 | return ERR_PTR(ret); | ||
793 | } | ||
794 | |||
795 | /** | ||
796 | * vmw_compat_shader_man_destroy - Destroy a compat shader manager | ||
797 | * | ||
798 | * @man: Pointer to the shader manager to destroy. | ||
799 | * | ||
800 | * Typically done at file close time. | ||
801 | */ | ||
802 | void vmw_compat_shader_man_destroy(struct vmw_compat_shader_manager *man) | ||
803 | { | ||
804 | struct vmw_compat_shader *entry, *next; | ||
805 | |||
806 | mutex_lock(&man->dev_priv->cmdbuf_mutex); | ||
807 | list_for_each_entry_safe(entry, next, &man->list, head) | ||
808 | vmw_compat_shader_free(man, entry); | ||
440 | 809 | ||
810 | mutex_unlock(&man->dev_priv->cmdbuf_mutex); | ||
811 | kfree(man); | ||
441 | } | 812 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 979da1c246a5..e7af580ab977 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | |||
@@ -830,6 +830,24 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, | |||
830 | if (unlikely(ret != 0)) | 830 | if (unlikely(ret != 0)) |
831 | goto out_unlock; | 831 | goto out_unlock; |
832 | 832 | ||
833 | /* | ||
834 | * A gb-aware client referencing a shared surface will | ||
835 | * expect a backup buffer to be present. | ||
836 | */ | ||
837 | if (dev_priv->has_mob && req->shareable) { | ||
838 | uint32_t backup_handle; | ||
839 | |||
840 | ret = vmw_user_dmabuf_alloc(dev_priv, tfile, | ||
841 | res->backup_size, | ||
842 | true, | ||
843 | &backup_handle, | ||
844 | &res->backup); | ||
845 | if (unlikely(ret != 0)) { | ||
846 | vmw_resource_unreference(&res); | ||
847 | goto out_unlock; | ||
848 | } | ||
849 | } | ||
850 | |||
833 | tmp = vmw_resource_reference(&srf->res); | 851 | tmp = vmw_resource_reference(&srf->res); |
834 | ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime, | 852 | ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime, |
835 | req->shareable, VMW_RES_SURFACE, | 853 | req->shareable, VMW_RES_SURFACE, |
@@ -908,8 +926,8 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, | |||
908 | rep->size_addr; | 926 | rep->size_addr; |
909 | 927 | ||
910 | if (user_sizes) | 928 | if (user_sizes) |
911 | ret = copy_to_user(user_sizes, srf->sizes, | 929 | ret = copy_to_user(user_sizes, &srf->base_size, |
912 | srf->num_sizes * sizeof(*srf->sizes)); | 930 | sizeof(srf->base_size)); |
913 | if (unlikely(ret != 0)) { | 931 | if (unlikely(ret != 0)) { |
914 | DRM_ERROR("copy_to_user failed %p %u\n", | 932 | DRM_ERROR("copy_to_user failed %p %u\n", |
915 | user_sizes, srf->num_sizes); | 933 | user_sizes, srf->num_sizes); |
@@ -1111,7 +1129,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) | |||
1111 | return 0; | 1129 | return 0; |
1112 | 1130 | ||
1113 | mutex_lock(&dev_priv->binding_mutex); | 1131 | mutex_lock(&dev_priv->binding_mutex); |
1114 | vmw_context_binding_res_list_kill(&res->binding_head); | 1132 | vmw_context_binding_res_list_scrub(&res->binding_head); |
1115 | 1133 | ||
1116 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); | 1134 | cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd)); |
1117 | if (unlikely(cmd == NULL)) { | 1135 | if (unlikely(cmd == NULL)) { |
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 1146e3bba6e1..112f27e51bc7 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
@@ -538,7 +538,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) | |||
538 | 538 | ||
539 | g->base = job->gather_addr_phys[i]; | 539 | g->base = job->gather_addr_phys[i]; |
540 | 540 | ||
541 | for (j = 0; j < job->num_gathers; j++) | 541 | for (j = i + 1; j < job->num_gathers; j++) |
542 | if (job->gathers[j].bo == g->bo) | 542 | if (job->gathers[j].bo == g->bo) |
543 | job->gathers[j].handled = true; | 543 | job->gathers[j].handled = true; |
544 | 544 | ||
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 497558127bb3..f822fd2a1ada 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c | |||
@@ -469,6 +469,9 @@ static const struct hid_device_id apple_devices[] = { | |||
469 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 469 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
470 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 470 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
471 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 471 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
472 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
473 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS), | ||
474 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | ||
472 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), | 475 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), |
473 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, | 476 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
474 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 477 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3bfac3accd22..cc32a6f96c64 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1679,6 +1679,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1679 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1679 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
1680 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, | 1680 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, |
1681 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, | 1681 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, |
1682 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) }, | ||
1682 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1683 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1683 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1684 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1684 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, | 1685 | { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) }, |
@@ -1779,6 +1780,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1779 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1780 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
1780 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1781 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
1781 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, | 1782 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, |
1783 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2) }, | ||
1784 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) }, | ||
1782 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, | 1785 | { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, |
1783 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, | 1786 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, |
1784 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, | 1787 | { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) }, |
diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 8fae6d1414cc..c24908f14934 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c | |||
@@ -157,6 +157,7 @@ struct mousevsc_dev { | |||
157 | u32 report_desc_size; | 157 | u32 report_desc_size; |
158 | struct hv_input_dev_info hid_dev_info; | 158 | struct hv_input_dev_info hid_dev_info; |
159 | struct hid_device *hid_device; | 159 | struct hid_device *hid_device; |
160 | u8 input_buf[HID_MAX_BUFFER_SIZE]; | ||
160 | }; | 161 | }; |
161 | 162 | ||
162 | 163 | ||
@@ -256,6 +257,7 @@ static void mousevsc_on_receive(struct hv_device *device, | |||
256 | struct synthhid_msg *hid_msg; | 257 | struct synthhid_msg *hid_msg; |
257 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); | 258 | struct mousevsc_dev *input_dev = hv_get_drvdata(device); |
258 | struct synthhid_input_report *input_report; | 259 | struct synthhid_input_report *input_report; |
260 | size_t len; | ||
259 | 261 | ||
260 | pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet + | 262 | pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet + |
261 | (packet->offset8 << 3)); | 263 | (packet->offset8 << 3)); |
@@ -300,9 +302,12 @@ static void mousevsc_on_receive(struct hv_device *device, | |||
300 | (struct synthhid_input_report *)pipe_msg->data; | 302 | (struct synthhid_input_report *)pipe_msg->data; |
301 | if (!input_dev->init_complete) | 303 | if (!input_dev->init_complete) |
302 | break; | 304 | break; |
303 | hid_input_report(input_dev->hid_device, | 305 | |
304 | HID_INPUT_REPORT, input_report->buffer, | 306 | len = min(input_report->header.size, |
305 | input_report->header.size, 1); | 307 | (u32)sizeof(input_dev->input_buf)); |
308 | memcpy(input_dev->input_buf, input_report->buffer, len); | ||
309 | hid_input_report(input_dev->hid_device, HID_INPUT_REPORT, | ||
310 | input_dev->input_buf, len, 1); | ||
306 | break; | 311 | break; |
307 | default: | 312 | default: |
308 | pr_err("unsupported hid msg type - type %d len %d", | 313 | pr_err("unsupported hid msg type - type %d len %d", |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5a5248f2cc07..22f28d6b33a8 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -135,6 +135,7 @@ | |||
135 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b | 135 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b |
136 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 | 136 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 |
137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 | 137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 |
138 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257 | ||
138 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 | 139 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 |
139 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 | 140 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 |
140 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 | 141 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 |
@@ -240,6 +241,7 @@ | |||
240 | 241 | ||
241 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | 242 | #define USB_VENDOR_ID_CYGNAL 0x10c4 |
242 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | 243 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a |
244 | #define USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH 0x81b9 | ||
243 | 245 | ||
244 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244 | 246 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI4713 0x8244 |
245 | 247 | ||
@@ -451,6 +453,9 @@ | |||
451 | #define USB_VENDOR_ID_INTEL_1 0x8087 | 453 | #define USB_VENDOR_ID_INTEL_1 0x8087 |
452 | #define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa | 454 | #define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa |
453 | 455 | ||
456 | #define USB_VENDOR_ID_STM_0 0x0483 | ||
457 | #define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1 | ||
458 | |||
454 | #define USB_VENDOR_ID_ION 0x15e4 | 459 | #define USB_VENDOR_ID_ION 0x15e4 |
455 | #define USB_DEVICE_ID_ICADE 0x0132 | 460 | #define USB_DEVICE_ID_ICADE 0x0132 |
456 | 461 | ||
@@ -619,6 +624,8 @@ | |||
619 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 624 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
620 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 | 625 | #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 |
621 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c | 626 | #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c |
627 | #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 | ||
628 | #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 | ||
622 | 629 | ||
623 | #define USB_VENDOR_ID_MOJO 0x8282 | 630 | #define USB_VENDOR_ID_MOJO 0x8282 |
624 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 | 631 | #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 |
@@ -644,6 +651,7 @@ | |||
644 | 651 | ||
645 | #define USB_VENDOR_ID_NEXIO 0x1870 | 652 | #define USB_VENDOR_ID_NEXIO 0x1870 |
646 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d | 653 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_420 0x010d |
654 | #define USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750 0x0110 | ||
647 | 655 | ||
648 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 | 656 | #define USB_VENDOR_ID_NEXTWINDOW 0x1926 |
649 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 | 657 | #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d50e7313b171..a713e6211419 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1178,7 +1178,7 @@ static void hidinput_led_worker(struct work_struct *work) | |||
1178 | 1178 | ||
1179 | /* fall back to generic raw-output-report */ | 1179 | /* fall back to generic raw-output-report */ |
1180 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 1180 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
1181 | buf = kmalloc(len, GFP_KERNEL); | 1181 | buf = hid_alloc_report_buf(report, GFP_KERNEL); |
1182 | if (!buf) | 1182 | if (!buf) |
1183 | return; | 1183 | return; |
1184 | 1184 | ||
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index befe0e336471..24883b4d1a49 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #define G25_REV_MIN 0x22 | 43 | #define G25_REV_MIN 0x22 |
44 | #define G27_REV_MAJ 0x12 | 44 | #define G27_REV_MAJ 0x12 |
45 | #define G27_REV_MIN 0x38 | 45 | #define G27_REV_MIN 0x38 |
46 | #define G27_2_REV_MIN 0x39 | ||
46 | 47 | ||
47 | #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) | 48 | #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) |
48 | 49 | ||
@@ -130,6 +131,7 @@ static const struct lg4ff_usb_revision lg4ff_revs[] = { | |||
130 | {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */ | 131 | {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */ |
131 | {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */ | 132 | {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */ |
132 | {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */ | 133 | {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */ |
134 | {G27_REV_MAJ, G27_2_REV_MIN, &native_g27}, /* G27 v2 */ | ||
133 | }; | 135 | }; |
134 | 136 | ||
135 | /* Recalculates X axis value accordingly to currently selected range */ | 137 | /* Recalculates X axis value accordingly to currently selected range */ |
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index c6ef6eed3091..404a3a8a82f1 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c | |||
@@ -208,6 +208,10 @@ static const struct hid_device_id ms_devices[] = { | |||
208 | .driver_data = MS_NOGET }, | 208 | .driver_data = MS_NOGET }, |
209 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), | 209 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
210 | .driver_data = MS_DUPLICATE_USAGES }, | 210 | .driver_data = MS_DUPLICATE_USAGES }, |
211 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), | ||
212 | .driver_data = 0 }, | ||
213 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), | ||
214 | .driver_data = 0 }, | ||
211 | 215 | ||
212 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), | 216 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), |
213 | .driver_data = MS_PRESENTER }, | 217 | .driver_data = MS_PRESENTER }, |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index f134d73beca1..221d503f1c24 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1166,6 +1166,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1166 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, | 1166 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, |
1167 | USB_DEVICE_ID_MULTITOUCH_3200) }, | 1167 | USB_DEVICE_ID_MULTITOUCH_3200) }, |
1168 | 1168 | ||
1169 | /* FocalTech Panels */ | ||
1170 | { .driver_data = MT_CLS_SERIAL, | ||
1171 | MT_USB_DEVICE(USB_VENDOR_ID_CYGNAL, | ||
1172 | USB_DEVICE_ID_FOCALTECH_FTXXXX_MULTITOUCH) }, | ||
1173 | |||
1169 | /* GeneralTouch panel */ | 1174 | /* GeneralTouch panel */ |
1170 | { .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS, | 1175 | { .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS, |
1171 | MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, | 1176 | MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 46f4480035bc..9c22e14c57f0 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -665,6 +665,9 @@ static const struct hid_device_id sensor_hub_devices[] = { | |||
665 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, | 665 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, |
666 | USB_DEVICE_ID_INTEL_HID_SENSOR), | 666 | USB_DEVICE_ID_INTEL_HID_SENSOR), |
667 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 667 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | ||
669 | USB_DEVICE_ID_STM_HID_SENSOR), | ||
670 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
668 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 671 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
669 | HID_ANY_ID) }, | 672 | HID_ANY_ID) }, |
670 | { } | 673 | { } |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 12354055d474..2f19b15f47f2 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #define DUALSHOCK4_CONTROLLER_BT BIT(6) | 42 | #define DUALSHOCK4_CONTROLLER_BT BIT(6) |
43 | 43 | ||
44 | #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) | 44 | #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) |
45 | #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_USB) | ||
45 | 46 | ||
46 | #define MAX_LEDS 4 | 47 | #define MAX_LEDS 4 |
47 | 48 | ||
@@ -499,6 +500,7 @@ struct sony_sc { | |||
499 | __u8 right; | 500 | __u8 right; |
500 | #endif | 501 | #endif |
501 | 502 | ||
503 | __u8 worker_initialized; | ||
502 | __u8 led_state[MAX_LEDS]; | 504 | __u8 led_state[MAX_LEDS]; |
503 | __u8 led_count; | 505 | __u8 led_count; |
504 | }; | 506 | }; |
@@ -993,22 +995,11 @@ static int sony_init_ff(struct hid_device *hdev) | |||
993 | return input_ff_create_memless(input_dev, NULL, sony_play_effect); | 995 | return input_ff_create_memless(input_dev, NULL, sony_play_effect); |
994 | } | 996 | } |
995 | 997 | ||
996 | static void sony_destroy_ff(struct hid_device *hdev) | ||
997 | { | ||
998 | struct sony_sc *sc = hid_get_drvdata(hdev); | ||
999 | |||
1000 | cancel_work_sync(&sc->state_worker); | ||
1001 | } | ||
1002 | |||
1003 | #else | 998 | #else |
1004 | static int sony_init_ff(struct hid_device *hdev) | 999 | static int sony_init_ff(struct hid_device *hdev) |
1005 | { | 1000 | { |
1006 | return 0; | 1001 | return 0; |
1007 | } | 1002 | } |
1008 | |||
1009 | static void sony_destroy_ff(struct hid_device *hdev) | ||
1010 | { | ||
1011 | } | ||
1012 | #endif | 1003 | #endif |
1013 | 1004 | ||
1014 | static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) | 1005 | static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) |
@@ -1077,6 +1068,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1077 | if (sc->quirks & SIXAXIS_CONTROLLER_USB) { | 1068 | if (sc->quirks & SIXAXIS_CONTROLLER_USB) { |
1078 | hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; | 1069 | hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; |
1079 | ret = sixaxis_set_operational_usb(hdev); | 1070 | ret = sixaxis_set_operational_usb(hdev); |
1071 | |||
1072 | sc->worker_initialized = 1; | ||
1080 | INIT_WORK(&sc->state_worker, sixaxis_state_worker); | 1073 | INIT_WORK(&sc->state_worker, sixaxis_state_worker); |
1081 | } | 1074 | } |
1082 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) | 1075 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) |
@@ -1087,6 +1080,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1087 | if (ret < 0) | 1080 | if (ret < 0) |
1088 | goto err_stop; | 1081 | goto err_stop; |
1089 | 1082 | ||
1083 | sc->worker_initialized = 1; | ||
1090 | INIT_WORK(&sc->state_worker, dualshock4_state_worker); | 1084 | INIT_WORK(&sc->state_worker, dualshock4_state_worker); |
1091 | } else { | 1085 | } else { |
1092 | ret = 0; | 1086 | ret = 0; |
@@ -1101,9 +1095,11 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
1101 | goto err_stop; | 1095 | goto err_stop; |
1102 | } | 1096 | } |
1103 | 1097 | ||
1104 | ret = sony_init_ff(hdev); | 1098 | if (sc->quirks & SONY_FF_SUPPORT) { |
1105 | if (ret < 0) | 1099 | ret = sony_init_ff(hdev); |
1106 | goto err_stop; | 1100 | if (ret < 0) |
1101 | goto err_stop; | ||
1102 | } | ||
1107 | 1103 | ||
1108 | return 0; | 1104 | return 0; |
1109 | err_stop: | 1105 | err_stop: |
@@ -1120,7 +1116,8 @@ static void sony_remove(struct hid_device *hdev) | |||
1120 | if (sc->quirks & SONY_LED_SUPPORT) | 1116 | if (sc->quirks & SONY_LED_SUPPORT) |
1121 | sony_leds_remove(hdev); | 1117 | sony_leds_remove(hdev); |
1122 | 1118 | ||
1123 | sony_destroy_ff(hdev); | 1119 | if (sc->worker_initialized) |
1120 | cancel_work_sync(&sc->state_worker); | ||
1124 | 1121 | ||
1125 | hid_hw_stop(hdev); | 1122 | hid_hw_stop(hdev); |
1126 | } | 1123 | } |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index cb0137b3718d..ab24ce2eb28f 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -320,13 +320,13 @@ static void drop_ref(struct hidraw *hidraw, int exists_bit) | |||
320 | hid_hw_close(hidraw->hid); | 320 | hid_hw_close(hidraw->hid); |
321 | wake_up_interruptible(&hidraw->wait); | 321 | wake_up_interruptible(&hidraw->wait); |
322 | } | 322 | } |
323 | device_destroy(hidraw_class, | ||
324 | MKDEV(hidraw_major, hidraw->minor)); | ||
323 | } else { | 325 | } else { |
324 | --hidraw->open; | 326 | --hidraw->open; |
325 | } | 327 | } |
326 | if (!hidraw->open) { | 328 | if (!hidraw->open) { |
327 | if (!hidraw->exist) { | 329 | if (!hidraw->exist) { |
328 | device_destroy(hidraw_class, | ||
329 | MKDEV(hidraw_major, hidraw->minor)); | ||
330 | hidraw_table[hidraw->minor] = NULL; | 330 | hidraw_table[hidraw->minor] = NULL; |
331 | kfree(hidraw); | 331 | kfree(hidraw); |
332 | } else { | 332 | } else { |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d1f81f52481a..42eebd14de1f 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -582,7 +582,7 @@ static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, | |||
582 | int ret; | 582 | int ret; |
583 | int len = i2c_hid_get_report_length(rep) - 2; | 583 | int len = i2c_hid_get_report_length(rep) - 2; |
584 | 584 | ||
585 | buf = kzalloc(len, GFP_KERNEL); | 585 | buf = hid_alloc_report_buf(rep, GFP_KERNEL); |
586 | if (!buf) | 586 | if (!buf) |
587 | return; | 587 | return; |
588 | 588 | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 175ec0afb70c..dbd83878ff99 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -74,6 +74,7 @@ static const struct hid_blacklist { | |||
74 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, | 74 | { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, |
75 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | 75 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, |
76 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, |
77 | { USB_VENDOR_ID_NEXIO, USB_DEVICE_ID_NEXIO_MULTITOUCH_PTI0750, HID_QUIRK_NO_INIT_REPORTS }, | ||
77 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, | 78 | { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, |
78 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 79 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
79 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 80 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index af6edf9b1936..f2d7bf90c9fe 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c | |||
@@ -67,7 +67,6 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, | |||
67 | int ret = 0; | 67 | int ret = 0; |
68 | struct vmbus_channel_initiate_contact *msg; | 68 | struct vmbus_channel_initiate_contact *msg; |
69 | unsigned long flags; | 69 | unsigned long flags; |
70 | int t; | ||
71 | 70 | ||
72 | init_completion(&msginfo->waitevent); | 71 | init_completion(&msginfo->waitevent); |
73 | 72 | ||
@@ -78,6 +77,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, | |||
78 | msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); | 77 | msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); |
79 | msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); | 78 | msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); |
80 | msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); | 79 | msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); |
80 | if (version == VERSION_WIN8) | ||
81 | msg->target_vcpu = hv_context.vp_index[smp_processor_id()]; | ||
81 | 82 | ||
82 | /* | 83 | /* |
83 | * Add to list before we send the request since we may | 84 | * Add to list before we send the request since we may |
@@ -100,15 +101,7 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, | |||
100 | } | 101 | } |
101 | 102 | ||
102 | /* Wait for the connection response */ | 103 | /* Wait for the connection response */ |
103 | t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ); | 104 | wait_for_completion(&msginfo->waitevent); |
104 | if (t == 0) { | ||
105 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, | ||
106 | flags); | ||
107 | list_del(&msginfo->msglistentry); | ||
108 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, | ||
109 | flags); | ||
110 | return -ETIMEDOUT; | ||
111 | } | ||
112 | 105 | ||
113 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | 106 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
114 | list_del(&msginfo->msglistentry); | 107 | list_del(&msginfo->msglistentry); |
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c index 029ecabc4380..73b3865f1207 100644 --- a/drivers/hwmon/da9055-hwmon.c +++ b/drivers/hwmon/da9055-hwmon.c | |||
@@ -278,10 +278,6 @@ static int da9055_hwmon_probe(struct platform_device *pdev) | |||
278 | if (hwmon_irq < 0) | 278 | if (hwmon_irq < 0) |
279 | return hwmon_irq; | 279 | return hwmon_irq; |
280 | 280 | ||
281 | hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data, hwmon_irq); | ||
282 | if (hwmon_irq < 0) | ||
283 | return hwmon_irq; | ||
284 | |||
285 | ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq, | 281 | ret = devm_request_threaded_irq(&pdev->dev, hwmon_irq, |
286 | NULL, da9055_auxadc_irq, | 282 | NULL, da9055_auxadc_irq, |
287 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | 283 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, |
diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c index a7626358c95d..029b65e6c589 100644 --- a/drivers/hwmon/max1668.c +++ b/drivers/hwmon/max1668.c | |||
@@ -243,7 +243,7 @@ static ssize_t set_temp_min(struct device *dev, | |||
243 | data->temp_min[index] = clamp_val(temp/1000, -128, 127); | 243 | data->temp_min[index] = clamp_val(temp/1000, -128, 127); |
244 | if (i2c_smbus_write_byte_data(client, | 244 | if (i2c_smbus_write_byte_data(client, |
245 | MAX1668_REG_LIML_WR(index), | 245 | MAX1668_REG_LIML_WR(index), |
246 | data->temp_max[index])) | 246 | data->temp_min[index])) |
247 | count = -EIO; | 247 | count = -EIO; |
248 | mutex_unlock(&data->update_lock); | 248 | mutex_unlock(&data->update_lock); |
249 | 249 | ||
diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c index 8c23203915af..8a17f01e8672 100644 --- a/drivers/hwmon/ntc_thermistor.c +++ b/drivers/hwmon/ntc_thermistor.c | |||
@@ -145,7 +145,7 @@ struct ntc_data { | |||
145 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | 145 | static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) |
146 | { | 146 | { |
147 | struct iio_channel *channel = pdata->chan; | 147 | struct iio_channel *channel = pdata->chan; |
148 | unsigned int result; | 148 | s64 result; |
149 | int val, ret; | 149 | int val, ret; |
150 | 150 | ||
151 | ret = iio_read_channel_raw(channel, &val); | 151 | ret = iio_read_channel_raw(channel, &val); |
@@ -155,10 +155,10 @@ static int ntc_adc_iio_read(struct ntc_thermistor_platform_data *pdata) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | /* unit: mV */ | 157 | /* unit: mV */ |
158 | result = pdata->pullup_uv * val; | 158 | result = pdata->pullup_uv * (s64) val; |
159 | result >>= 12; | 159 | result >>= 12; |
160 | 160 | ||
161 | return result; | 161 | return (int)result; |
162 | } | 162 | } |
163 | 163 | ||
164 | static const struct of_device_id ntc_match[] = { | 164 | static const struct of_device_id ntc_match[] = { |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 3cbf66e9d861..291d11fe93e7 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -90,7 +90,8 @@ struct pmbus_data { | |||
90 | 90 | ||
91 | u32 flags; /* from platform data */ | 91 | u32 flags; /* from platform data */ |
92 | 92 | ||
93 | int exponent; /* linear mode: exponent for output voltages */ | 93 | int exponent[PMBUS_PAGES]; |
94 | /* linear mode: exponent for output voltages */ | ||
94 | 95 | ||
95 | const struct pmbus_driver_info *info; | 96 | const struct pmbus_driver_info *info; |
96 | 97 | ||
@@ -410,7 +411,7 @@ static long pmbus_reg2data_linear(struct pmbus_data *data, | |||
410 | long val; | 411 | long val; |
411 | 412 | ||
412 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ | 413 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ |
413 | exponent = data->exponent; | 414 | exponent = data->exponent[sensor->page]; |
414 | mantissa = (u16) sensor->data; | 415 | mantissa = (u16) sensor->data; |
415 | } else { /* LINEAR11 */ | 416 | } else { /* LINEAR11 */ |
416 | exponent = ((s16)sensor->data) >> 11; | 417 | exponent = ((s16)sensor->data) >> 11; |
@@ -516,7 +517,7 @@ static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) | |||
516 | #define MIN_MANTISSA (511 * 1000) | 517 | #define MIN_MANTISSA (511 * 1000) |
517 | 518 | ||
518 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, | 519 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, |
519 | enum pmbus_sensor_classes class, long val) | 520 | struct pmbus_sensor *sensor, long val) |
520 | { | 521 | { |
521 | s16 exponent = 0, mantissa; | 522 | s16 exponent = 0, mantissa; |
522 | bool negative = false; | 523 | bool negative = false; |
@@ -525,7 +526,7 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
525 | if (val == 0) | 526 | if (val == 0) |
526 | return 0; | 527 | return 0; |
527 | 528 | ||
528 | if (class == PSC_VOLTAGE_OUT) { | 529 | if (sensor->class == PSC_VOLTAGE_OUT) { |
529 | /* LINEAR16 does not support negative voltages */ | 530 | /* LINEAR16 does not support negative voltages */ |
530 | if (val < 0) | 531 | if (val < 0) |
531 | return 0; | 532 | return 0; |
@@ -534,10 +535,10 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
534 | * For a static exponents, we don't have a choice | 535 | * For a static exponents, we don't have a choice |
535 | * but to adjust the value to it. | 536 | * but to adjust the value to it. |
536 | */ | 537 | */ |
537 | if (data->exponent < 0) | 538 | if (data->exponent[sensor->page] < 0) |
538 | val <<= -data->exponent; | 539 | val <<= -data->exponent[sensor->page]; |
539 | else | 540 | else |
540 | val >>= data->exponent; | 541 | val >>= data->exponent[sensor->page]; |
541 | val = DIV_ROUND_CLOSEST(val, 1000); | 542 | val = DIV_ROUND_CLOSEST(val, 1000); |
542 | return val & 0xffff; | 543 | return val & 0xffff; |
543 | } | 544 | } |
@@ -548,14 +549,14 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
548 | } | 549 | } |
549 | 550 | ||
550 | /* Power is in uW. Convert to mW before converting. */ | 551 | /* Power is in uW. Convert to mW before converting. */ |
551 | if (class == PSC_POWER) | 552 | if (sensor->class == PSC_POWER) |
552 | val = DIV_ROUND_CLOSEST(val, 1000L); | 553 | val = DIV_ROUND_CLOSEST(val, 1000L); |
553 | 554 | ||
554 | /* | 555 | /* |
555 | * For simplicity, convert fan data to milli-units | 556 | * For simplicity, convert fan data to milli-units |
556 | * before calculating the exponent. | 557 | * before calculating the exponent. |
557 | */ | 558 | */ |
558 | if (class == PSC_FAN) | 559 | if (sensor->class == PSC_FAN) |
559 | val = val * 1000; | 560 | val = val * 1000; |
560 | 561 | ||
561 | /* Reduce large mantissa until it fits into 10 bit */ | 562 | /* Reduce large mantissa until it fits into 10 bit */ |
@@ -585,22 +586,22 @@ static u16 pmbus_data2reg_linear(struct pmbus_data *data, | |||
585 | } | 586 | } |
586 | 587 | ||
587 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, | 588 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, |
588 | enum pmbus_sensor_classes class, long val) | 589 | struct pmbus_sensor *sensor, long val) |
589 | { | 590 | { |
590 | long m, b, R; | 591 | long m, b, R; |
591 | 592 | ||
592 | m = data->info->m[class]; | 593 | m = data->info->m[sensor->class]; |
593 | b = data->info->b[class]; | 594 | b = data->info->b[sensor->class]; |
594 | R = data->info->R[class]; | 595 | R = data->info->R[sensor->class]; |
595 | 596 | ||
596 | /* Power is in uW. Adjust R and b. */ | 597 | /* Power is in uW. Adjust R and b. */ |
597 | if (class == PSC_POWER) { | 598 | if (sensor->class == PSC_POWER) { |
598 | R -= 3; | 599 | R -= 3; |
599 | b *= 1000; | 600 | b *= 1000; |
600 | } | 601 | } |
601 | 602 | ||
602 | /* Calculate Y = (m * X + b) * 10^R */ | 603 | /* Calculate Y = (m * X + b) * 10^R */ |
603 | if (class != PSC_FAN) { | 604 | if (sensor->class != PSC_FAN) { |
604 | R -= 3; /* Adjust R and b for data in milli-units */ | 605 | R -= 3; /* Adjust R and b for data in milli-units */ |
605 | b *= 1000; | 606 | b *= 1000; |
606 | } | 607 | } |
@@ -619,7 +620,7 @@ static u16 pmbus_data2reg_direct(struct pmbus_data *data, | |||
619 | } | 620 | } |
620 | 621 | ||
621 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, | 622 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, |
622 | enum pmbus_sensor_classes class, long val) | 623 | struct pmbus_sensor *sensor, long val) |
623 | { | 624 | { |
624 | val = clamp_val(val, 500, 1600); | 625 | val = clamp_val(val, 500, 1600); |
625 | 626 | ||
@@ -627,20 +628,20 @@ static u16 pmbus_data2reg_vid(struct pmbus_data *data, | |||
627 | } | 628 | } |
628 | 629 | ||
629 | static u16 pmbus_data2reg(struct pmbus_data *data, | 630 | static u16 pmbus_data2reg(struct pmbus_data *data, |
630 | enum pmbus_sensor_classes class, long val) | 631 | struct pmbus_sensor *sensor, long val) |
631 | { | 632 | { |
632 | u16 regval; | 633 | u16 regval; |
633 | 634 | ||
634 | switch (data->info->format[class]) { | 635 | switch (data->info->format[sensor->class]) { |
635 | case direct: | 636 | case direct: |
636 | regval = pmbus_data2reg_direct(data, class, val); | 637 | regval = pmbus_data2reg_direct(data, sensor, val); |
637 | break; | 638 | break; |
638 | case vid: | 639 | case vid: |
639 | regval = pmbus_data2reg_vid(data, class, val); | 640 | regval = pmbus_data2reg_vid(data, sensor, val); |
640 | break; | 641 | break; |
641 | case linear: | 642 | case linear: |
642 | default: | 643 | default: |
643 | regval = pmbus_data2reg_linear(data, class, val); | 644 | regval = pmbus_data2reg_linear(data, sensor, val); |
644 | break; | 645 | break; |
645 | } | 646 | } |
646 | return regval; | 647 | return regval; |
@@ -746,7 +747,7 @@ static ssize_t pmbus_set_sensor(struct device *dev, | |||
746 | return -EINVAL; | 747 | return -EINVAL; |
747 | 748 | ||
748 | mutex_lock(&data->update_lock); | 749 | mutex_lock(&data->update_lock); |
749 | regval = pmbus_data2reg(data, sensor->class, val); | 750 | regval = pmbus_data2reg(data, sensor, val); |
750 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); | 751 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); |
751 | if (ret < 0) | 752 | if (ret < 0) |
752 | rv = ret; | 753 | rv = ret; |
@@ -1643,12 +1644,13 @@ static int pmbus_find_attributes(struct i2c_client *client, | |||
1643 | * This function is called for all chips. | 1644 | * This function is called for all chips. |
1644 | */ | 1645 | */ |
1645 | static int pmbus_identify_common(struct i2c_client *client, | 1646 | static int pmbus_identify_common(struct i2c_client *client, |
1646 | struct pmbus_data *data) | 1647 | struct pmbus_data *data, int page) |
1647 | { | 1648 | { |
1648 | int vout_mode = -1; | 1649 | int vout_mode = -1; |
1649 | 1650 | ||
1650 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) | 1651 | if (pmbus_check_byte_register(client, page, PMBUS_VOUT_MODE)) |
1651 | vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); | 1652 | vout_mode = _pmbus_read_byte_data(client, page, |
1653 | PMBUS_VOUT_MODE); | ||
1652 | if (vout_mode >= 0 && vout_mode != 0xff) { | 1654 | if (vout_mode >= 0 && vout_mode != 0xff) { |
1653 | /* | 1655 | /* |
1654 | * Not all chips support the VOUT_MODE command, | 1656 | * Not all chips support the VOUT_MODE command, |
@@ -1659,7 +1661,7 @@ static int pmbus_identify_common(struct i2c_client *client, | |||
1659 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) | 1661 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) |
1660 | return -ENODEV; | 1662 | return -ENODEV; |
1661 | 1663 | ||
1662 | data->exponent = ((s8)(vout_mode << 3)) >> 3; | 1664 | data->exponent[page] = ((s8)(vout_mode << 3)) >> 3; |
1663 | break; | 1665 | break; |
1664 | case 1: /* VID mode */ | 1666 | case 1: /* VID mode */ |
1665 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) | 1667 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) |
@@ -1674,7 +1676,7 @@ static int pmbus_identify_common(struct i2c_client *client, | |||
1674 | } | 1676 | } |
1675 | } | 1677 | } |
1676 | 1678 | ||
1677 | pmbus_clear_fault_page(client, 0); | 1679 | pmbus_clear_fault_page(client, page); |
1678 | return 0; | 1680 | return 0; |
1679 | } | 1681 | } |
1680 | 1682 | ||
@@ -1682,7 +1684,7 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, | |||
1682 | struct pmbus_driver_info *info) | 1684 | struct pmbus_driver_info *info) |
1683 | { | 1685 | { |
1684 | struct device *dev = &client->dev; | 1686 | struct device *dev = &client->dev; |
1685 | int ret; | 1687 | int page, ret; |
1686 | 1688 | ||
1687 | /* | 1689 | /* |
1688 | * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try | 1690 | * Some PMBus chips don't support PMBUS_STATUS_BYTE, so try |
@@ -1715,10 +1717,12 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, | |||
1715 | return -ENODEV; | 1717 | return -ENODEV; |
1716 | } | 1718 | } |
1717 | 1719 | ||
1718 | ret = pmbus_identify_common(client, data); | 1720 | for (page = 0; page < info->pages; page++) { |
1719 | if (ret < 0) { | 1721 | ret = pmbus_identify_common(client, data, page); |
1720 | dev_err(dev, "Failed to identify chip capabilities\n"); | 1722 | if (ret < 0) { |
1721 | return ret; | 1723 | dev_err(dev, "Failed to identify chip capabilities\n"); |
1724 | return ret; | ||
1725 | } | ||
1722 | } | 1726 | } |
1723 | return 0; | 1727 | return 0; |
1724 | } | 1728 | } |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index f5ed03164d86..de17c5593d97 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -387,7 +387,7 @@ config I2C_CBUS_GPIO | |||
387 | 387 | ||
388 | config I2C_CPM | 388 | config I2C_CPM |
389 | tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" | 389 | tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)" |
390 | depends on (CPM1 || CPM2) && OF_I2C | 390 | depends on CPM1 || CPM2 |
391 | help | 391 | help |
392 | This supports the use of the I2C interface on Freescale | 392 | This supports the use of the I2C interface on Freescale |
393 | processors with CPM1 or CPM2. | 393 | processors with CPM1 or CPM2. |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index b8c5187b9ee0..d52d84937ad3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -97,7 +97,6 @@ enum { | |||
97 | enum { | 97 | enum { |
98 | MV64XXX_I2C_ACTION_INVALID, | 98 | MV64XXX_I2C_ACTION_INVALID, |
99 | MV64XXX_I2C_ACTION_CONTINUE, | 99 | MV64XXX_I2C_ACTION_CONTINUE, |
100 | MV64XXX_I2C_ACTION_OFFLOAD_SEND_START, | ||
101 | MV64XXX_I2C_ACTION_SEND_START, | 100 | MV64XXX_I2C_ACTION_SEND_START, |
102 | MV64XXX_I2C_ACTION_SEND_RESTART, | 101 | MV64XXX_I2C_ACTION_SEND_RESTART, |
103 | MV64XXX_I2C_ACTION_OFFLOAD_RESTART, | 102 | MV64XXX_I2C_ACTION_OFFLOAD_RESTART, |
@@ -204,6 +203,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) | |||
204 | unsigned long ctrl_reg; | 203 | unsigned long ctrl_reg; |
205 | struct i2c_msg *msg = drv_data->msgs; | 204 | struct i2c_msg *msg = drv_data->msgs; |
206 | 205 | ||
206 | if (!drv_data->offload_enabled) | ||
207 | return -EOPNOTSUPP; | ||
208 | |||
207 | drv_data->msg = msg; | 209 | drv_data->msg = msg; |
208 | drv_data->byte_posn = 0; | 210 | drv_data->byte_posn = 0; |
209 | drv_data->bytes_left = msg->len; | 211 | drv_data->bytes_left = msg->len; |
@@ -433,8 +435,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
433 | 435 | ||
434 | drv_data->msgs++; | 436 | drv_data->msgs++; |
435 | drv_data->num_msgs--; | 437 | drv_data->num_msgs--; |
436 | if (!(drv_data->offload_enabled && | 438 | if (mv64xxx_i2c_offload_msg(drv_data) < 0) { |
437 | mv64xxx_i2c_offload_msg(drv_data))) { | ||
438 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; | 439 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; |
439 | writel(drv_data->cntl_bits, | 440 | writel(drv_data->cntl_bits, |
440 | drv_data->reg_base + drv_data->reg_offsets.control); | 441 | drv_data->reg_base + drv_data->reg_offsets.control); |
@@ -458,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
458 | drv_data->reg_base + drv_data->reg_offsets.control); | 459 | drv_data->reg_base + drv_data->reg_offsets.control); |
459 | break; | 460 | break; |
460 | 461 | ||
461 | case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START: | ||
462 | if (!mv64xxx_i2c_offload_msg(drv_data)) | ||
463 | break; | ||
464 | else | ||
465 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | ||
466 | /* FALLTHRU */ | ||
467 | case MV64XXX_I2C_ACTION_SEND_START: | 462 | case MV64XXX_I2C_ACTION_SEND_START: |
468 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | 463 | /* Can we offload this msg ? */ |
469 | drv_data->reg_base + drv_data->reg_offsets.control); | 464 | if (mv64xxx_i2c_offload_msg(drv_data) < 0) { |
465 | /* No, switch to standard path */ | ||
466 | mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); | ||
467 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | ||
468 | drv_data->reg_base + drv_data->reg_offsets.control); | ||
469 | } | ||
470 | break; | 470 | break; |
471 | 471 | ||
472 | case MV64XXX_I2C_ACTION_SEND_ADDR_1: | 472 | case MV64XXX_I2C_ACTION_SEND_ADDR_1: |
@@ -625,15 +625,10 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg, | |||
625 | unsigned long flags; | 625 | unsigned long flags; |
626 | 626 | ||
627 | spin_lock_irqsave(&drv_data->lock, flags); | 627 | spin_lock_irqsave(&drv_data->lock, flags); |
628 | if (drv_data->offload_enabled) { | ||
629 | drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START; | ||
630 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | ||
631 | } else { | ||
632 | mv64xxx_i2c_prepare_for_io(drv_data, msg); | ||
633 | 628 | ||
634 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | 629 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; |
635 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | 630 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; |
636 | } | 631 | |
637 | drv_data->send_stop = is_last; | 632 | drv_data->send_stop = is_last; |
638 | drv_data->block = 1; | 633 | drv_data->block = 1; |
639 | mv64xxx_i2c_do_action(drv_data); | 634 | mv64xxx_i2c_do_action(drv_data); |
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 3bec9220df04..bfec313492b3 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c | |||
@@ -447,14 +447,14 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = { | |||
447 | { }, | 447 | { }, |
448 | }; | 448 | }; |
449 | 449 | ||
450 | #define BMA180_CHANNEL(_index) { \ | 450 | #define BMA180_CHANNEL(_axis) { \ |
451 | .type = IIO_ACCEL, \ | 451 | .type = IIO_ACCEL, \ |
452 | .indexed = 1, \ | 452 | .modified = 1, \ |
453 | .channel = (_index), \ | 453 | .channel2 = IIO_MOD_##_axis, \ |
454 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | 454 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
455 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ | 455 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ |
456 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | 456 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
457 | .scan_index = (_index), \ | 457 | .scan_index = AXIS_##_axis, \ |
458 | .scan_type = { \ | 458 | .scan_type = { \ |
459 | .sign = 's', \ | 459 | .sign = 's', \ |
460 | .realbits = 14, \ | 460 | .realbits = 14, \ |
@@ -465,10 +465,10 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = { | |||
465 | } | 465 | } |
466 | 466 | ||
467 | static const struct iio_chan_spec bma180_channels[] = { | 467 | static const struct iio_chan_spec bma180_channels[] = { |
468 | BMA180_CHANNEL(AXIS_X), | 468 | BMA180_CHANNEL(X), |
469 | BMA180_CHANNEL(AXIS_Y), | 469 | BMA180_CHANNEL(Y), |
470 | BMA180_CHANNEL(AXIS_Z), | 470 | BMA180_CHANNEL(Z), |
471 | IIO_CHAN_SOFT_TIMESTAMP(4), | 471 | IIO_CHAN_SOFT_TIMESTAMP(3), |
472 | }; | 472 | }; |
473 | 473 | ||
474 | static irqreturn_t bma180_trigger_handler(int irq, void *p) | 474 | static irqreturn_t bma180_trigger_handler(int irq, void *p) |
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index e283f2f2ee2f..360259266d4f 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c | |||
@@ -1560,7 +1560,7 @@ static int max1363_probe(struct i2c_client *client, | |||
1560 | st->client = client; | 1560 | st->client = client; |
1561 | 1561 | ||
1562 | st->vref_uv = st->chip_info->int_vref_mv * 1000; | 1562 | st->vref_uv = st->chip_info->int_vref_mv * 1000; |
1563 | vref = devm_regulator_get(&client->dev, "vref"); | 1563 | vref = devm_regulator_get_optional(&client->dev, "vref"); |
1564 | if (!IS_ERR(vref)) { | 1564 | if (!IS_ERR(vref)) { |
1565 | int vref_uv; | 1565 | int vref_uv; |
1566 | 1566 | ||
diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 41c64a43bcab..ac2d69e34c8c 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig | |||
@@ -70,7 +70,7 @@ config IIO_ST_GYRO_3AXIS | |||
70 | select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) | 70 | select IIO_TRIGGERED_BUFFER if (IIO_BUFFER) |
71 | help | 71 | help |
72 | Say yes here to build support for STMicroelectronics gyroscopes: | 72 | Say yes here to build support for STMicroelectronics gyroscopes: |
73 | L3G4200D, LSM330DL, L3GD20, L3GD20H, LSM330DLC, L3G4IS, LSM330. | 73 | L3G4200D, LSM330DL, L3GD20, LSM330DLC, L3G4IS, LSM330. |
74 | 74 | ||
75 | This driver can also be built as a module. If so, these modules | 75 | This driver can also be built as a module. If so, these modules |
76 | will be created: | 76 | will be created: |
diff --git a/drivers/iio/gyro/st_gyro.h b/drivers/iio/gyro/st_gyro.h index f8f2bf84a5a2..c197360c450b 100644 --- a/drivers/iio/gyro/st_gyro.h +++ b/drivers/iio/gyro/st_gyro.h | |||
@@ -19,7 +19,6 @@ | |||
19 | #define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro" | 19 | #define LSM330DL_GYRO_DEV_NAME "lsm330dl_gyro" |
20 | #define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro" | 20 | #define LSM330DLC_GYRO_DEV_NAME "lsm330dlc_gyro" |
21 | #define L3GD20_GYRO_DEV_NAME "l3gd20" | 21 | #define L3GD20_GYRO_DEV_NAME "l3gd20" |
22 | #define L3GD20H_GYRO_DEV_NAME "l3gd20h" | ||
23 | #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui" | 22 | #define L3G4IS_GYRO_DEV_NAME "l3g4is_ui" |
24 | #define LSM330_GYRO_DEV_NAME "lsm330_gyro" | 23 | #define LSM330_GYRO_DEV_NAME "lsm330_gyro" |
25 | 24 | ||
diff --git a/drivers/iio/gyro/st_gyro_core.c b/drivers/iio/gyro/st_gyro_core.c index d53d91adfb55..a8e174a47bc4 100644 --- a/drivers/iio/gyro/st_gyro_core.c +++ b/drivers/iio/gyro/st_gyro_core.c | |||
@@ -167,11 +167,10 @@ static const struct st_sensors st_gyro_sensors[] = { | |||
167 | .wai = ST_GYRO_2_WAI_EXP, | 167 | .wai = ST_GYRO_2_WAI_EXP, |
168 | .sensors_supported = { | 168 | .sensors_supported = { |
169 | [0] = L3GD20_GYRO_DEV_NAME, | 169 | [0] = L3GD20_GYRO_DEV_NAME, |
170 | [1] = L3GD20H_GYRO_DEV_NAME, | 170 | [1] = LSM330D_GYRO_DEV_NAME, |
171 | [2] = LSM330D_GYRO_DEV_NAME, | 171 | [2] = LSM330DLC_GYRO_DEV_NAME, |
172 | [3] = LSM330DLC_GYRO_DEV_NAME, | 172 | [3] = L3G4IS_GYRO_DEV_NAME, |
173 | [4] = L3G4IS_GYRO_DEV_NAME, | 173 | [4] = LSM330_GYRO_DEV_NAME, |
174 | [5] = LSM330_GYRO_DEV_NAME, | ||
175 | }, | 174 | }, |
176 | .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, | 175 | .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, |
177 | .odr = { | 176 | .odr = { |
diff --git a/drivers/iio/gyro/st_gyro_i2c.c b/drivers/iio/gyro/st_gyro_i2c.c index 16b8b8d70bf1..23c12f361b05 100644 --- a/drivers/iio/gyro/st_gyro_i2c.c +++ b/drivers/iio/gyro/st_gyro_i2c.c | |||
@@ -55,7 +55,6 @@ static const struct i2c_device_id st_gyro_id_table[] = { | |||
55 | { LSM330DL_GYRO_DEV_NAME }, | 55 | { LSM330DL_GYRO_DEV_NAME }, |
56 | { LSM330DLC_GYRO_DEV_NAME }, | 56 | { LSM330DLC_GYRO_DEV_NAME }, |
57 | { L3GD20_GYRO_DEV_NAME }, | 57 | { L3GD20_GYRO_DEV_NAME }, |
58 | { L3GD20H_GYRO_DEV_NAME }, | ||
59 | { L3G4IS_GYRO_DEV_NAME }, | 58 | { L3G4IS_GYRO_DEV_NAME }, |
60 | { LSM330_GYRO_DEV_NAME }, | 59 | { LSM330_GYRO_DEV_NAME }, |
61 | {}, | 60 | {}, |
diff --git a/drivers/iio/gyro/st_gyro_spi.c b/drivers/iio/gyro/st_gyro_spi.c index 94763e25caf9..b4ad3be26687 100644 --- a/drivers/iio/gyro/st_gyro_spi.c +++ b/drivers/iio/gyro/st_gyro_spi.c | |||
@@ -54,7 +54,6 @@ static const struct spi_device_id st_gyro_id_table[] = { | |||
54 | { LSM330DL_GYRO_DEV_NAME }, | 54 | { LSM330DL_GYRO_DEV_NAME }, |
55 | { LSM330DLC_GYRO_DEV_NAME }, | 55 | { LSM330DLC_GYRO_DEV_NAME }, |
56 | { L3GD20_GYRO_DEV_NAME }, | 56 | { L3GD20_GYRO_DEV_NAME }, |
57 | { L3GD20H_GYRO_DEV_NAME }, | ||
58 | { L3G4IS_GYRO_DEV_NAME }, | 57 | { L3G4IS_GYRO_DEV_NAME }, |
59 | { LSM330_GYRO_DEV_NAME }, | 58 | { LSM330_GYRO_DEV_NAME }, |
60 | {}, | 59 | {}, |
diff --git a/drivers/iio/imu/adis16400.h b/drivers/iio/imu/adis16400.h index 2f8f9d632386..0916bf6b6c31 100644 --- a/drivers/iio/imu/adis16400.h +++ b/drivers/iio/imu/adis16400.h | |||
@@ -189,6 +189,7 @@ enum { | |||
189 | ADIS16300_SCAN_INCLI_X, | 189 | ADIS16300_SCAN_INCLI_X, |
190 | ADIS16300_SCAN_INCLI_Y, | 190 | ADIS16300_SCAN_INCLI_Y, |
191 | ADIS16400_SCAN_ADC, | 191 | ADIS16400_SCAN_ADC, |
192 | ADIS16400_SCAN_TIMESTAMP, | ||
192 | }; | 193 | }; |
193 | 194 | ||
194 | #ifdef CONFIG_IIO_BUFFER | 195 | #ifdef CONFIG_IIO_BUFFER |
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c index 368660dfe135..7c582f7ae34e 100644 --- a/drivers/iio/imu/adis16400_core.c +++ b/drivers/iio/imu/adis16400_core.c | |||
@@ -632,7 +632,7 @@ static const struct iio_chan_spec adis16400_channels[] = { | |||
632 | ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14), | 632 | ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14), |
633 | ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12), | 633 | ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12), |
634 | ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12), | 634 | ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12), |
635 | IIO_CHAN_SOFT_TIMESTAMP(12) | 635 | IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), |
636 | }; | 636 | }; |
637 | 637 | ||
638 | static const struct iio_chan_spec adis16448_channels[] = { | 638 | static const struct iio_chan_spec adis16448_channels[] = { |
@@ -659,7 +659,7 @@ static const struct iio_chan_spec adis16448_channels[] = { | |||
659 | }, | 659 | }, |
660 | }, | 660 | }, |
661 | ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12), | 661 | ADIS16400_TEMP_CHAN(ADIS16448_TEMP_OUT, 12), |
662 | IIO_CHAN_SOFT_TIMESTAMP(11) | 662 | IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), |
663 | }; | 663 | }; |
664 | 664 | ||
665 | static const struct iio_chan_spec adis16350_channels[] = { | 665 | static const struct iio_chan_spec adis16350_channels[] = { |
@@ -677,7 +677,7 @@ static const struct iio_chan_spec adis16350_channels[] = { | |||
677 | ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12), | 677 | ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12), |
678 | ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12), | 678 | ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12), |
679 | ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12), | 679 | ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12), |
680 | IIO_CHAN_SOFT_TIMESTAMP(11) | 680 | IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), |
681 | }; | 681 | }; |
682 | 682 | ||
683 | static const struct iio_chan_spec adis16300_channels[] = { | 683 | static const struct iio_chan_spec adis16300_channels[] = { |
@@ -690,7 +690,7 @@ static const struct iio_chan_spec adis16300_channels[] = { | |||
690 | ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12), | 690 | ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12), |
691 | ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13), | 691 | ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13), |
692 | ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13), | 692 | ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13), |
693 | IIO_CHAN_SOFT_TIMESTAMP(14) | 693 | IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), |
694 | }; | 694 | }; |
695 | 695 | ||
696 | static const struct iio_chan_spec adis16334_channels[] = { | 696 | static const struct iio_chan_spec adis16334_channels[] = { |
@@ -701,7 +701,7 @@ static const struct iio_chan_spec adis16334_channels[] = { | |||
701 | ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14), | 701 | ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14), |
702 | ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14), | 702 | ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14), |
703 | ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12), | 703 | ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12), |
704 | IIO_CHAN_SOFT_TIMESTAMP(8) | 704 | IIO_CHAN_SOFT_TIMESTAMP(ADIS16400_SCAN_TIMESTAMP), |
705 | }; | 705 | }; |
706 | 706 | ||
707 | static struct attribute *adis16400_attributes[] = { | 707 | static struct attribute *adis16400_attributes[] = { |
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index f17b4e6183c6..47a6dbac2d0c 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c | |||
@@ -103,13 +103,13 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181) | |||
103 | /** | 103 | /** |
104 | * cm32181_read_als_it() - Get sensor integration time (ms) | 104 | * cm32181_read_als_it() - Get sensor integration time (ms) |
105 | * @cm32181: pointer of struct cm32181 | 105 | * @cm32181: pointer of struct cm32181 |
106 | * @val: pointer of int to load the als_it value. | 106 | * @val2: pointer of int to load the als_it value. |
107 | * | 107 | * |
108 | * Report the current integartion time by millisecond. | 108 | * Report the current integartion time by millisecond. |
109 | * | 109 | * |
110 | * Return: IIO_VAL_INT for success, otherwise -EINVAL. | 110 | * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL. |
111 | */ | 111 | */ |
112 | static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val) | 112 | static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2) |
113 | { | 113 | { |
114 | u16 als_it; | 114 | u16 als_it; |
115 | int i; | 115 | int i; |
@@ -119,8 +119,8 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val) | |||
119 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; | 119 | als_it >>= CM32181_CMD_ALS_IT_SHIFT; |
120 | for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { | 120 | for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { |
121 | if (als_it == als_it_bits[i]) { | 121 | if (als_it == als_it_bits[i]) { |
122 | *val = als_it_value[i]; | 122 | *val2 = als_it_value[i]; |
123 | return IIO_VAL_INT; | 123 | return IIO_VAL_INT_PLUS_MICRO; |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
@@ -221,7 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, | |||
221 | *val = cm32181->calibscale; | 221 | *val = cm32181->calibscale; |
222 | return IIO_VAL_INT; | 222 | return IIO_VAL_INT; |
223 | case IIO_CHAN_INFO_INT_TIME: | 223 | case IIO_CHAN_INFO_INT_TIME: |
224 | ret = cm32181_read_als_it(cm32181, val); | 224 | ret = cm32181_read_als_it(cm32181, val2); |
225 | return ret; | 225 | return ret; |
226 | } | 226 | } |
227 | 227 | ||
@@ -240,7 +240,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev, | |||
240 | cm32181->calibscale = val; | 240 | cm32181->calibscale = val; |
241 | return val; | 241 | return val; |
242 | case IIO_CHAN_INFO_INT_TIME: | 242 | case IIO_CHAN_INFO_INT_TIME: |
243 | ret = cm32181_write_als_it(cm32181, val); | 243 | ret = cm32181_write_als_it(cm32181, val2); |
244 | return ret; | 244 | return ret; |
245 | } | 245 | } |
246 | 246 | ||
@@ -264,7 +264,7 @@ static ssize_t cm32181_get_it_available(struct device *dev, | |||
264 | 264 | ||
265 | n = ARRAY_SIZE(als_it_value); | 265 | n = ARRAY_SIZE(als_it_value); |
266 | for (i = 0, len = 0; i < n; i++) | 266 | for (i = 0, len = 0; i < n; i++) |
267 | len += sprintf(buf + len, "%d ", als_it_value[i]); | 267 | len += sprintf(buf + len, "0.%06u ", als_it_value[i]); |
268 | return len + sprintf(buf + len, "\n"); | 268 | return len + sprintf(buf + len, "\n"); |
269 | } | 269 | } |
270 | 270 | ||
diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 0a142af83e25..a45e07492db3 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c | |||
@@ -50,10 +50,10 @@ | |||
50 | #define CM36651_CS_CONF2_DEFAULT_BIT 0x08 | 50 | #define CM36651_CS_CONF2_DEFAULT_BIT 0x08 |
51 | 51 | ||
52 | /* CS_CONF3 channel integration time */ | 52 | /* CS_CONF3 channel integration time */ |
53 | #define CM36651_CS_IT1 0x00 /* Integration time 80000 usec */ | 53 | #define CM36651_CS_IT1 0x00 /* Integration time 80 msec */ |
54 | #define CM36651_CS_IT2 0x40 /* Integration time 160000 usec */ | 54 | #define CM36651_CS_IT2 0x40 /* Integration time 160 msec */ |
55 | #define CM36651_CS_IT3 0x80 /* Integration time 320000 usec */ | 55 | #define CM36651_CS_IT3 0x80 /* Integration time 320 msec */ |
56 | #define CM36651_CS_IT4 0xC0 /* Integration time 640000 usec */ | 56 | #define CM36651_CS_IT4 0xC0 /* Integration time 640 msec */ |
57 | 57 | ||
58 | /* PS_CONF1 command code */ | 58 | /* PS_CONF1 command code */ |
59 | #define CM36651_PS_ENABLE 0x00 | 59 | #define CM36651_PS_ENABLE 0x00 |
@@ -64,10 +64,10 @@ | |||
64 | #define CM36651_PS_PERS4 0x0C | 64 | #define CM36651_PS_PERS4 0x0C |
65 | 65 | ||
66 | /* PS_CONF1 command code: integration time */ | 66 | /* PS_CONF1 command code: integration time */ |
67 | #define CM36651_PS_IT1 0x00 /* Integration time 320 usec */ | 67 | #define CM36651_PS_IT1 0x00 /* Integration time 0.32 msec */ |
68 | #define CM36651_PS_IT2 0x10 /* Integration time 420 usec */ | 68 | #define CM36651_PS_IT2 0x10 /* Integration time 0.42 msec */ |
69 | #define CM36651_PS_IT3 0x20 /* Integration time 520 usec */ | 69 | #define CM36651_PS_IT3 0x20 /* Integration time 0.52 msec */ |
70 | #define CM36651_PS_IT4 0x30 /* Integration time 640 usec */ | 70 | #define CM36651_PS_IT4 0x30 /* Integration time 0.64 msec */ |
71 | 71 | ||
72 | /* PS_CONF1 command code: duty ratio */ | 72 | /* PS_CONF1 command code: duty ratio */ |
73 | #define CM36651_PS_DR1 0x00 /* Duty ratio 1/80 */ | 73 | #define CM36651_PS_DR1 0x00 /* Duty ratio 1/80 */ |
@@ -93,8 +93,8 @@ | |||
93 | #define CM36651_CLOSE_PROXIMITY 0x32 | 93 | #define CM36651_CLOSE_PROXIMITY 0x32 |
94 | #define CM36651_FAR_PROXIMITY 0x33 | 94 | #define CM36651_FAR_PROXIMITY 0x33 |
95 | 95 | ||
96 | #define CM36651_CS_INT_TIME_AVAIL "80000 160000 320000 640000" | 96 | #define CM36651_CS_INT_TIME_AVAIL "0.08 0.16 0.32 0.64" |
97 | #define CM36651_PS_INT_TIME_AVAIL "320 420 520 640" | 97 | #define CM36651_PS_INT_TIME_AVAIL "0.000320 0.000420 0.000520 0.000640" |
98 | 98 | ||
99 | enum cm36651_operation_mode { | 99 | enum cm36651_operation_mode { |
100 | CM36651_LIGHT_EN, | 100 | CM36651_LIGHT_EN, |
@@ -356,30 +356,30 @@ static int cm36651_read_channel(struct cm36651_data *cm36651, | |||
356 | } | 356 | } |
357 | 357 | ||
358 | static int cm36651_read_int_time(struct cm36651_data *cm36651, | 358 | static int cm36651_read_int_time(struct cm36651_data *cm36651, |
359 | struct iio_chan_spec const *chan, int *val) | 359 | struct iio_chan_spec const *chan, int *val2) |
360 | { | 360 | { |
361 | switch (chan->type) { | 361 | switch (chan->type) { |
362 | case IIO_LIGHT: | 362 | case IIO_LIGHT: |
363 | if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1) | 363 | if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1) |
364 | *val = 80000; | 364 | *val2 = 80000; |
365 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2) | 365 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2) |
366 | *val = 160000; | 366 | *val2 = 160000; |
367 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3) | 367 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3) |
368 | *val = 320000; | 368 | *val2 = 320000; |
369 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4) | 369 | else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4) |
370 | *val = 640000; | 370 | *val2 = 640000; |
371 | else | 371 | else |
372 | return -EINVAL; | 372 | return -EINVAL; |
373 | break; | 373 | break; |
374 | case IIO_PROXIMITY: | 374 | case IIO_PROXIMITY: |
375 | if (cm36651->ps_int_time == CM36651_PS_IT1) | 375 | if (cm36651->ps_int_time == CM36651_PS_IT1) |
376 | *val = 320; | 376 | *val2 = 320; |
377 | else if (cm36651->ps_int_time == CM36651_PS_IT2) | 377 | else if (cm36651->ps_int_time == CM36651_PS_IT2) |
378 | *val = 420; | 378 | *val2 = 420; |
379 | else if (cm36651->ps_int_time == CM36651_PS_IT3) | 379 | else if (cm36651->ps_int_time == CM36651_PS_IT3) |
380 | *val = 520; | 380 | *val2 = 520; |
381 | else if (cm36651->ps_int_time == CM36651_PS_IT4) | 381 | else if (cm36651->ps_int_time == CM36651_PS_IT4) |
382 | *val = 640; | 382 | *val2 = 640; |
383 | else | 383 | else |
384 | return -EINVAL; | 384 | return -EINVAL; |
385 | break; | 385 | break; |
@@ -387,7 +387,7 @@ static int cm36651_read_int_time(struct cm36651_data *cm36651, | |||
387 | return -EINVAL; | 387 | return -EINVAL; |
388 | } | 388 | } |
389 | 389 | ||
390 | return IIO_VAL_INT; | 390 | return IIO_VAL_INT_PLUS_MICRO; |
391 | } | 391 | } |
392 | 392 | ||
393 | static int cm36651_write_int_time(struct cm36651_data *cm36651, | 393 | static int cm36651_write_int_time(struct cm36651_data *cm36651, |
@@ -459,7 +459,8 @@ static int cm36651_read_raw(struct iio_dev *indio_dev, | |||
459 | ret = cm36651_read_channel(cm36651, chan, val); | 459 | ret = cm36651_read_channel(cm36651, chan, val); |
460 | break; | 460 | break; |
461 | case IIO_CHAN_INFO_INT_TIME: | 461 | case IIO_CHAN_INFO_INT_TIME: |
462 | ret = cm36651_read_int_time(cm36651, chan, val); | 462 | *val = 0; |
463 | ret = cm36651_read_int_time(cm36651, chan, val2); | ||
463 | break; | 464 | break; |
464 | default: | 465 | default: |
465 | ret = -EINVAL; | 466 | ret = -EINVAL; |
@@ -479,7 +480,7 @@ static int cm36651_write_raw(struct iio_dev *indio_dev, | |||
479 | int ret = -EINVAL; | 480 | int ret = -EINVAL; |
480 | 481 | ||
481 | if (mask == IIO_CHAN_INFO_INT_TIME) { | 482 | if (mask == IIO_CHAN_INFO_INT_TIME) { |
482 | ret = cm36651_write_int_time(cm36651, chan, val); | 483 | ret = cm36651_write_int_time(cm36651, chan, val2); |
483 | if (ret < 0) | 484 | if (ret < 0) |
484 | dev_err(&client->dev, "Integration time write failed\n"); | 485 | dev_err(&client->dev, "Integration time write failed\n"); |
485 | } | 486 | } |
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 3d8110157f2d..94daa9fc1247 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c | |||
@@ -460,10 +460,14 @@ static int tsl2563_write_raw(struct iio_dev *indio_dev, | |||
460 | { | 460 | { |
461 | struct tsl2563_chip *chip = iio_priv(indio_dev); | 461 | struct tsl2563_chip *chip = iio_priv(indio_dev); |
462 | 462 | ||
463 | if (chan->channel == IIO_MOD_LIGHT_BOTH) | 463 | if (mask != IIO_CHAN_INFO_CALIBSCALE) |
464 | return -EINVAL; | ||
465 | if (chan->channel2 == IIO_MOD_LIGHT_BOTH) | ||
464 | chip->calib0 = calib_from_sysfs(val); | 466 | chip->calib0 = calib_from_sysfs(val); |
465 | else | 467 | else if (chan->channel2 == IIO_MOD_LIGHT_IR) |
466 | chip->calib1 = calib_from_sysfs(val); | 468 | chip->calib1 = calib_from_sysfs(val); |
469 | else | ||
470 | return -EINVAL; | ||
467 | 471 | ||
468 | return 0; | 472 | return 0; |
469 | } | 473 | } |
@@ -472,14 +476,14 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, | |||
472 | struct iio_chan_spec const *chan, | 476 | struct iio_chan_spec const *chan, |
473 | int *val, | 477 | int *val, |
474 | int *val2, | 478 | int *val2, |
475 | long m) | 479 | long mask) |
476 | { | 480 | { |
477 | int ret = -EINVAL; | 481 | int ret = -EINVAL; |
478 | u32 calib0, calib1; | 482 | u32 calib0, calib1; |
479 | struct tsl2563_chip *chip = iio_priv(indio_dev); | 483 | struct tsl2563_chip *chip = iio_priv(indio_dev); |
480 | 484 | ||
481 | mutex_lock(&chip->lock); | 485 | mutex_lock(&chip->lock); |
482 | switch (m) { | 486 | switch (mask) { |
483 | case IIO_CHAN_INFO_RAW: | 487 | case IIO_CHAN_INFO_RAW: |
484 | case IIO_CHAN_INFO_PROCESSED: | 488 | case IIO_CHAN_INFO_PROCESSED: |
485 | switch (chan->type) { | 489 | switch (chan->type) { |
@@ -498,7 +502,7 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, | |||
498 | ret = tsl2563_get_adc(chip); | 502 | ret = tsl2563_get_adc(chip); |
499 | if (ret) | 503 | if (ret) |
500 | goto error_ret; | 504 | goto error_ret; |
501 | if (chan->channel == 0) | 505 | if (chan->channel2 == IIO_MOD_LIGHT_BOTH) |
502 | *val = chip->data0; | 506 | *val = chip->data0; |
503 | else | 507 | else |
504 | *val = chip->data1; | 508 | *val = chip->data1; |
@@ -510,7 +514,7 @@ static int tsl2563_read_raw(struct iio_dev *indio_dev, | |||
510 | break; | 514 | break; |
511 | 515 | ||
512 | case IIO_CHAN_INFO_CALIBSCALE: | 516 | case IIO_CHAN_INFO_CALIBSCALE: |
513 | if (chan->channel == 0) | 517 | if (chan->channel2 == IIO_MOD_LIGHT_BOTH) |
514 | *val = calib_to_sysfs(chip->calib0); | 518 | *val = calib_to_sysfs(chip->calib0); |
515 | else | 519 | else |
516 | *val = calib_to_sysfs(chip->calib1); | 520 | *val = calib_to_sysfs(chip->calib1); |
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index ff284e5afd95..05423543f89d 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #define AK8975_MAX_CONVERSION_TIMEOUT 500 | 85 | #define AK8975_MAX_CONVERSION_TIMEOUT 500 |
86 | #define AK8975_CONVERSION_DONE_POLL_TIME 10 | 86 | #define AK8975_CONVERSION_DONE_POLL_TIME 10 |
87 | #define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000) | 87 | #define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000) |
88 | #define RAW_TO_GAUSS(asa) ((((asa) + 128) * 3000) / 256) | ||
88 | 89 | ||
89 | /* | 90 | /* |
90 | * Per-instance context data for the device. | 91 | * Per-instance context data for the device. |
@@ -265,15 +266,15 @@ static int ak8975_setup(struct i2c_client *client) | |||
265 | * | 266 | * |
266 | * Since 1uT = 0.01 gauss, our final scale factor becomes: | 267 | * Since 1uT = 0.01 gauss, our final scale factor becomes: |
267 | * | 268 | * |
268 | * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100 | 269 | * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100 |
269 | * Hadj = H * ((ASA + 128) * 30 / 256 | 270 | * Hadj = H * ((ASA + 128) * 0.003) / 256 |
270 | * | 271 | * |
271 | * Since ASA doesn't change, we cache the resultant scale factor into the | 272 | * Since ASA doesn't change, we cache the resultant scale factor into the |
272 | * device context in ak8975_setup(). | 273 | * device context in ak8975_setup(). |
273 | */ | 274 | */ |
274 | data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8; | 275 | data->raw_to_gauss[0] = RAW_TO_GAUSS(data->asa[0]); |
275 | data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8; | 276 | data->raw_to_gauss[1] = RAW_TO_GAUSS(data->asa[1]); |
276 | data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8; | 277 | data->raw_to_gauss[2] = RAW_TO_GAUSS(data->asa[2]); |
277 | 278 | ||
278 | return 0; | 279 | return 0; |
279 | } | 280 | } |
@@ -428,8 +429,9 @@ static int ak8975_read_raw(struct iio_dev *indio_dev, | |||
428 | case IIO_CHAN_INFO_RAW: | 429 | case IIO_CHAN_INFO_RAW: |
429 | return ak8975_read_axis(indio_dev, chan->address, val); | 430 | return ak8975_read_axis(indio_dev, chan->address, val); |
430 | case IIO_CHAN_INFO_SCALE: | 431 | case IIO_CHAN_INFO_SCALE: |
431 | *val = data->raw_to_gauss[chan->address]; | 432 | *val = 0; |
432 | return IIO_VAL_INT; | 433 | *val2 = data->raw_to_gauss[chan->address]; |
434 | return IIO_VAL_INT_PLUS_MICRO; | ||
433 | } | 435 | } |
434 | return -EINVAL; | 436 | return -EINVAL; |
435 | } | 437 | } |
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index 4b65b6d3bdb1..f66955fb3509 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c | |||
@@ -106,7 +106,7 @@ static ssize_t mag3110_show_int_plus_micros(char *buf, | |||
106 | 106 | ||
107 | while (n-- > 0) | 107 | while (n-- > 0) |
108 | len += scnprintf(buf + len, PAGE_SIZE - len, | 108 | len += scnprintf(buf + len, PAGE_SIZE - len, |
109 | "%d.%d ", vals[n][0], vals[n][1]); | 109 | "%d.%06d ", vals[n][0], vals[n][1]); |
110 | 110 | ||
111 | /* replace trailing space by newline */ | 111 | /* replace trailing space by newline */ |
112 | buf[len - 1] = '\n'; | 112 | buf[len - 1] = '\n'; |
@@ -154,6 +154,9 @@ static int mag3110_read_raw(struct iio_dev *indio_dev, | |||
154 | 154 | ||
155 | switch (mask) { | 155 | switch (mask) { |
156 | case IIO_CHAN_INFO_RAW: | 156 | case IIO_CHAN_INFO_RAW: |
157 | if (iio_buffer_enabled(indio_dev)) | ||
158 | return -EBUSY; | ||
159 | |||
157 | switch (chan->type) { | 160 | switch (chan->type) { |
158 | case IIO_MAGN: /* in 0.1 uT / LSB */ | 161 | case IIO_MAGN: /* in 0.1 uT / LSB */ |
159 | ret = mag3110_read(data, buffer); | 162 | ret = mag3110_read(data, buffer); |
@@ -199,6 +202,9 @@ static int mag3110_write_raw(struct iio_dev *indio_dev, | |||
199 | struct mag3110_data *data = iio_priv(indio_dev); | 202 | struct mag3110_data *data = iio_priv(indio_dev); |
200 | int rate; | 203 | int rate; |
201 | 204 | ||
205 | if (iio_buffer_enabled(indio_dev)) | ||
206 | return -EBUSY; | ||
207 | |||
202 | switch (mask) { | 208 | switch (mask) { |
203 | case IIO_CHAN_INFO_SAMP_FREQ: | 209 | case IIO_CHAN_INFO_SAMP_FREQ: |
204 | rate = mag3110_get_samp_freq_index(data, val, val2); | 210 | rate = mag3110_get_samp_freq_index(data, val, val2); |
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index d53cf519f42a..00400c352c1a 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c | |||
@@ -1082,6 +1082,7 @@ static int c2_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1082 | 1082 | ||
1083 | /* Initialize network device */ | 1083 | /* Initialize network device */ |
1084 | if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) { | 1084 | if ((netdev = c2_devinit(c2dev, mmio_regs)) == NULL) { |
1085 | ret = -ENOMEM; | ||
1085 | iounmap(mmio_regs); | 1086 | iounmap(mmio_regs); |
1086 | goto bail4; | 1087 | goto bail4; |
1087 | } | 1088 | } |
@@ -1151,7 +1152,8 @@ static int c2_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
1151 | goto bail10; | 1152 | goto bail10; |
1152 | } | 1153 | } |
1153 | 1154 | ||
1154 | if (c2_register_device(c2dev)) | 1155 | ret = c2_register_device(c2dev); |
1156 | if (ret) | ||
1155 | goto bail10; | 1157 | goto bail10; |
1156 | 1158 | ||
1157 | return 0; | 1159 | return 0; |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index b7c986990053..d2a6d961344b 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -576,7 +576,8 @@ int c2_rnic_init(struct c2_dev *c2dev) | |||
576 | goto bail4; | 576 | goto bail4; |
577 | 577 | ||
578 | /* Initialize cached the adapter limits */ | 578 | /* Initialize cached the adapter limits */ |
579 | if (c2_rnic_query(c2dev, &c2dev->props)) | 579 | err = c2_rnic_query(c2dev, &c2dev->props); |
580 | if (err) | ||
580 | goto bail5; | 581 | goto bail5; |
581 | 582 | ||
582 | /* Initialize the PD pool */ | 583 | /* Initialize the PD pool */ |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 45126879ad28..d286bdebe2ab 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -3352,6 +3352,7 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) | |||
3352 | goto free_dst; | 3352 | goto free_dst; |
3353 | } | 3353 | } |
3354 | 3354 | ||
3355 | neigh_release(neigh); | ||
3355 | step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; | 3356 | step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan; |
3356 | rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step]; | 3357 | rss_qid = dev->rdev.lldi.rxq_ids[pi->port_id * step]; |
3357 | window = (__force u16) htons((__force u16)tcph->window); | 3358 | window = (__force u16) htons((__force u16)tcph->window); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index c2702f549f10..f9c12e92fdd6 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -53,8 +53,8 @@ | |||
53 | #include "user.h" | 53 | #include "user.h" |
54 | 54 | ||
55 | #define DRV_NAME MLX4_IB_DRV_NAME | 55 | #define DRV_NAME MLX4_IB_DRV_NAME |
56 | #define DRV_VERSION "1.0" | 56 | #define DRV_VERSION "2.2-1" |
57 | #define DRV_RELDATE "April 4, 2008" | 57 | #define DRV_RELDATE "Feb 2014" |
58 | 58 | ||
59 | #define MLX4_IB_FLOW_MAX_PRIO 0xFFF | 59 | #define MLX4_IB_FLOW_MAX_PRIO 0xFFF |
60 | #define MLX4_IB_FLOW_QPN_MASK 0xFFFFFF | 60 | #define MLX4_IB_FLOW_QPN_MASK 0xFFFFFF |
@@ -347,7 +347,7 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port, | |||
347 | props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ? | 347 | props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ? |
348 | IB_WIDTH_4X : IB_WIDTH_1X; | 348 | IB_WIDTH_4X : IB_WIDTH_1X; |
349 | props->active_speed = IB_SPEED_QDR; | 349 | props->active_speed = IB_SPEED_QDR; |
350 | props->port_cap_flags = IB_PORT_CM_SUP; | 350 | props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_IP_BASED_GIDS; |
351 | props->gid_tbl_len = mdev->dev->caps.gid_table_len[port]; | 351 | props->gid_tbl_len = mdev->dev->caps.gid_table_len[port]; |
352 | props->max_msg_sz = mdev->dev->caps.max_msg_sz; | 352 | props->max_msg_sz = mdev->dev->caps.max_msg_sz; |
353 | props->pkey_tbl_len = 1; | 353 | props->pkey_tbl_len = 1; |
@@ -1357,6 +1357,21 @@ static struct device_attribute *mlx4_class_attributes[] = { | |||
1357 | &dev_attr_board_id | 1357 | &dev_attr_board_id |
1358 | }; | 1358 | }; |
1359 | 1359 | ||
1360 | static void mlx4_addrconf_ifid_eui48(u8 *eui, u16 vlan_id, | ||
1361 | struct net_device *dev) | ||
1362 | { | ||
1363 | memcpy(eui, dev->dev_addr, 3); | ||
1364 | memcpy(eui + 5, dev->dev_addr + 3, 3); | ||
1365 | if (vlan_id < 0x1000) { | ||
1366 | eui[3] = vlan_id >> 8; | ||
1367 | eui[4] = vlan_id & 0xff; | ||
1368 | } else { | ||
1369 | eui[3] = 0xff; | ||
1370 | eui[4] = 0xfe; | ||
1371 | } | ||
1372 | eui[0] ^= 2; | ||
1373 | } | ||
1374 | |||
1360 | static void update_gids_task(struct work_struct *work) | 1375 | static void update_gids_task(struct work_struct *work) |
1361 | { | 1376 | { |
1362 | struct update_gid_work *gw = container_of(work, struct update_gid_work, work); | 1377 | struct update_gid_work *gw = container_of(work, struct update_gid_work, work); |
@@ -1393,7 +1408,6 @@ static void reset_gids_task(struct work_struct *work) | |||
1393 | struct mlx4_cmd_mailbox *mailbox; | 1408 | struct mlx4_cmd_mailbox *mailbox; |
1394 | union ib_gid *gids; | 1409 | union ib_gid *gids; |
1395 | int err; | 1410 | int err; |
1396 | int i; | ||
1397 | struct mlx4_dev *dev = gw->dev->dev; | 1411 | struct mlx4_dev *dev = gw->dev->dev; |
1398 | 1412 | ||
1399 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 1413 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
@@ -1405,18 +1419,16 @@ static void reset_gids_task(struct work_struct *work) | |||
1405 | gids = mailbox->buf; | 1419 | gids = mailbox->buf; |
1406 | memcpy(gids, gw->gids, sizeof(gw->gids)); | 1420 | memcpy(gids, gw->gids, sizeof(gw->gids)); |
1407 | 1421 | ||
1408 | for (i = 1; i < gw->dev->num_ports + 1; i++) { | 1422 | if (mlx4_ib_port_link_layer(&gw->dev->ib_dev, gw->port) == |
1409 | if (mlx4_ib_port_link_layer(&gw->dev->ib_dev, i) == | 1423 | IB_LINK_LAYER_ETHERNET) { |
1410 | IB_LINK_LAYER_ETHERNET) { | 1424 | err = mlx4_cmd(dev, mailbox->dma, |
1411 | err = mlx4_cmd(dev, mailbox->dma, | 1425 | MLX4_SET_PORT_GID_TABLE << 8 | gw->port, |
1412 | MLX4_SET_PORT_GID_TABLE << 8 | i, | 1426 | 1, MLX4_CMD_SET_PORT, |
1413 | 1, MLX4_CMD_SET_PORT, | 1427 | MLX4_CMD_TIME_CLASS_B, |
1414 | MLX4_CMD_TIME_CLASS_B, | 1428 | MLX4_CMD_WRAPPED); |
1415 | MLX4_CMD_WRAPPED); | 1429 | if (err) |
1416 | if (err) | 1430 | pr_warn(KERN_WARNING |
1417 | pr_warn(KERN_WARNING | 1431 | "set port %d command failed\n", gw->port); |
1418 | "set port %d command failed\n", i); | ||
1419 | } | ||
1420 | } | 1432 | } |
1421 | 1433 | ||
1422 | mlx4_free_cmd_mailbox(dev, mailbox); | 1434 | mlx4_free_cmd_mailbox(dev, mailbox); |
@@ -1425,7 +1437,8 @@ free: | |||
1425 | } | 1437 | } |
1426 | 1438 | ||
1427 | static int update_gid_table(struct mlx4_ib_dev *dev, int port, | 1439 | static int update_gid_table(struct mlx4_ib_dev *dev, int port, |
1428 | union ib_gid *gid, int clear) | 1440 | union ib_gid *gid, int clear, |
1441 | int default_gid) | ||
1429 | { | 1442 | { |
1430 | struct update_gid_work *work; | 1443 | struct update_gid_work *work; |
1431 | int i; | 1444 | int i; |
@@ -1434,26 +1447,31 @@ static int update_gid_table(struct mlx4_ib_dev *dev, int port, | |||
1434 | int found = -1; | 1447 | int found = -1; |
1435 | int max_gids; | 1448 | int max_gids; |
1436 | 1449 | ||
1437 | max_gids = dev->dev->caps.gid_table_len[port]; | 1450 | if (default_gid) { |
1438 | for (i = 0; i < max_gids; ++i) { | 1451 | free = 0; |
1439 | if (!memcmp(&dev->iboe.gid_table[port - 1][i], gid, | 1452 | } else { |
1440 | sizeof(*gid))) | 1453 | max_gids = dev->dev->caps.gid_table_len[port]; |
1441 | found = i; | 1454 | for (i = 1; i < max_gids; ++i) { |
1442 | 1455 | if (!memcmp(&dev->iboe.gid_table[port - 1][i], gid, | |
1443 | if (clear) { | ||
1444 | if (found >= 0) { | ||
1445 | need_update = 1; | ||
1446 | dev->iboe.gid_table[port - 1][found] = zgid; | ||
1447 | break; | ||
1448 | } | ||
1449 | } else { | ||
1450 | if (found >= 0) | ||
1451 | break; | ||
1452 | |||
1453 | if (free < 0 && | ||
1454 | !memcmp(&dev->iboe.gid_table[port - 1][i], &zgid, | ||
1455 | sizeof(*gid))) | 1456 | sizeof(*gid))) |
1456 | free = i; | 1457 | found = i; |
1458 | |||
1459 | if (clear) { | ||
1460 | if (found >= 0) { | ||
1461 | need_update = 1; | ||
1462 | dev->iboe.gid_table[port - 1][found] = | ||
1463 | zgid; | ||
1464 | break; | ||
1465 | } | ||
1466 | } else { | ||
1467 | if (found >= 0) | ||
1468 | break; | ||
1469 | |||
1470 | if (free < 0 && | ||
1471 | !memcmp(&dev->iboe.gid_table[port - 1][i], | ||
1472 | &zgid, sizeof(*gid))) | ||
1473 | free = i; | ||
1474 | } | ||
1457 | } | 1475 | } |
1458 | } | 1476 | } |
1459 | 1477 | ||
@@ -1478,18 +1496,26 @@ static int update_gid_table(struct mlx4_ib_dev *dev, int port, | |||
1478 | return 0; | 1496 | return 0; |
1479 | } | 1497 | } |
1480 | 1498 | ||
1481 | static int reset_gid_table(struct mlx4_ib_dev *dev) | 1499 | static void mlx4_make_default_gid(struct net_device *dev, union ib_gid *gid) |
1482 | { | 1500 | { |
1483 | struct update_gid_work *work; | 1501 | gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL); |
1502 | mlx4_addrconf_ifid_eui48(&gid->raw[8], 0xffff, dev); | ||
1503 | } | ||
1504 | |||
1484 | 1505 | ||
1506 | static int reset_gid_table(struct mlx4_ib_dev *dev, u8 port) | ||
1507 | { | ||
1508 | struct update_gid_work *work; | ||
1485 | 1509 | ||
1486 | work = kzalloc(sizeof(*work), GFP_ATOMIC); | 1510 | work = kzalloc(sizeof(*work), GFP_ATOMIC); |
1487 | if (!work) | 1511 | if (!work) |
1488 | return -ENOMEM; | 1512 | return -ENOMEM; |
1489 | memset(dev->iboe.gid_table, 0, sizeof(dev->iboe.gid_table)); | 1513 | |
1514 | memset(dev->iboe.gid_table[port - 1], 0, sizeof(work->gids)); | ||
1490 | memset(work->gids, 0, sizeof(work->gids)); | 1515 | memset(work->gids, 0, sizeof(work->gids)); |
1491 | INIT_WORK(&work->work, reset_gids_task); | 1516 | INIT_WORK(&work->work, reset_gids_task); |
1492 | work->dev = dev; | 1517 | work->dev = dev; |
1518 | work->port = port; | ||
1493 | queue_work(wq, &work->work); | 1519 | queue_work(wq, &work->work); |
1494 | return 0; | 1520 | return 0; |
1495 | } | 1521 | } |
@@ -1502,6 +1528,12 @@ static int mlx4_ib_addr_event(int event, struct net_device *event_netdev, | |||
1502 | struct net_device *real_dev = rdma_vlan_dev_real_dev(event_netdev) ? | 1528 | struct net_device *real_dev = rdma_vlan_dev_real_dev(event_netdev) ? |
1503 | rdma_vlan_dev_real_dev(event_netdev) : | 1529 | rdma_vlan_dev_real_dev(event_netdev) : |
1504 | event_netdev; | 1530 | event_netdev; |
1531 | union ib_gid default_gid; | ||
1532 | |||
1533 | mlx4_make_default_gid(real_dev, &default_gid); | ||
1534 | |||
1535 | if (!memcmp(gid, &default_gid, sizeof(*gid))) | ||
1536 | return 0; | ||
1505 | 1537 | ||
1506 | if (event != NETDEV_DOWN && event != NETDEV_UP) | 1538 | if (event != NETDEV_DOWN && event != NETDEV_UP) |
1507 | return 0; | 1539 | return 0; |
@@ -1520,7 +1552,7 @@ static int mlx4_ib_addr_event(int event, struct net_device *event_netdev, | |||
1520 | (!netif_is_bond_master(real_dev) && | 1552 | (!netif_is_bond_master(real_dev) && |
1521 | (real_dev == iboe->netdevs[port - 1]))) | 1553 | (real_dev == iboe->netdevs[port - 1]))) |
1522 | update_gid_table(ibdev, port, gid, | 1554 | update_gid_table(ibdev, port, gid, |
1523 | event == NETDEV_DOWN); | 1555 | event == NETDEV_DOWN, 0); |
1524 | 1556 | ||
1525 | spin_unlock(&iboe->lock); | 1557 | spin_unlock(&iboe->lock); |
1526 | return 0; | 1558 | return 0; |
@@ -1536,7 +1568,6 @@ static u8 mlx4_ib_get_dev_port(struct net_device *dev, | |||
1536 | rdma_vlan_dev_real_dev(dev) : dev; | 1568 | rdma_vlan_dev_real_dev(dev) : dev; |
1537 | 1569 | ||
1538 | iboe = &ibdev->iboe; | 1570 | iboe = &ibdev->iboe; |
1539 | spin_lock(&iboe->lock); | ||
1540 | 1571 | ||
1541 | for (port = 1; port <= MLX4_MAX_PORTS; ++port) | 1572 | for (port = 1; port <= MLX4_MAX_PORTS; ++port) |
1542 | if ((netif_is_bond_master(real_dev) && | 1573 | if ((netif_is_bond_master(real_dev) && |
@@ -1545,8 +1576,6 @@ static u8 mlx4_ib_get_dev_port(struct net_device *dev, | |||
1545 | (real_dev == iboe->netdevs[port - 1]))) | 1576 | (real_dev == iboe->netdevs[port - 1]))) |
1546 | break; | 1577 | break; |
1547 | 1578 | ||
1548 | spin_unlock(&iboe->lock); | ||
1549 | |||
1550 | if ((port == 0) || (port > MLX4_MAX_PORTS)) | 1579 | if ((port == 0) || (port > MLX4_MAX_PORTS)) |
1551 | return 0; | 1580 | return 0; |
1552 | else | 1581 | else |
@@ -1607,7 +1636,7 @@ static void mlx4_ib_get_dev_addr(struct net_device *dev, | |||
1607 | /*ifa->ifa_address;*/ | 1636 | /*ifa->ifa_address;*/ |
1608 | ipv6_addr_set_v4mapped(ifa->ifa_address, | 1637 | ipv6_addr_set_v4mapped(ifa->ifa_address, |
1609 | (struct in6_addr *)&gid); | 1638 | (struct in6_addr *)&gid); |
1610 | update_gid_table(ibdev, port, &gid, 0); | 1639 | update_gid_table(ibdev, port, &gid, 0, 0); |
1611 | } | 1640 | } |
1612 | endfor_ifa(in_dev); | 1641 | endfor_ifa(in_dev); |
1613 | in_dev_put(in_dev); | 1642 | in_dev_put(in_dev); |
@@ -1619,7 +1648,7 @@ static void mlx4_ib_get_dev_addr(struct net_device *dev, | |||
1619 | read_lock_bh(&in6_dev->lock); | 1648 | read_lock_bh(&in6_dev->lock); |
1620 | list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { | 1649 | list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { |
1621 | pgid = (union ib_gid *)&ifp->addr; | 1650 | pgid = (union ib_gid *)&ifp->addr; |
1622 | update_gid_table(ibdev, port, pgid, 0); | 1651 | update_gid_table(ibdev, port, pgid, 0, 0); |
1623 | } | 1652 | } |
1624 | read_unlock_bh(&in6_dev->lock); | 1653 | read_unlock_bh(&in6_dev->lock); |
1625 | in6_dev_put(in6_dev); | 1654 | in6_dev_put(in6_dev); |
@@ -1627,14 +1656,26 @@ static void mlx4_ib_get_dev_addr(struct net_device *dev, | |||
1627 | #endif | 1656 | #endif |
1628 | } | 1657 | } |
1629 | 1658 | ||
1659 | static void mlx4_ib_set_default_gid(struct mlx4_ib_dev *ibdev, | ||
1660 | struct net_device *dev, u8 port) | ||
1661 | { | ||
1662 | union ib_gid gid; | ||
1663 | mlx4_make_default_gid(dev, &gid); | ||
1664 | update_gid_table(ibdev, port, &gid, 0, 1); | ||
1665 | } | ||
1666 | |||
1630 | static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev) | 1667 | static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev) |
1631 | { | 1668 | { |
1632 | struct net_device *dev; | 1669 | struct net_device *dev; |
1670 | struct mlx4_ib_iboe *iboe = &ibdev->iboe; | ||
1671 | int i; | ||
1633 | 1672 | ||
1634 | if (reset_gid_table(ibdev)) | 1673 | for (i = 1; i <= ibdev->num_ports; ++i) |
1635 | return -1; | 1674 | if (reset_gid_table(ibdev, i)) |
1675 | return -1; | ||
1636 | 1676 | ||
1637 | read_lock(&dev_base_lock); | 1677 | read_lock(&dev_base_lock); |
1678 | spin_lock(&iboe->lock); | ||
1638 | 1679 | ||
1639 | for_each_netdev(&init_net, dev) { | 1680 | for_each_netdev(&init_net, dev) { |
1640 | u8 port = mlx4_ib_get_dev_port(dev, ibdev); | 1681 | u8 port = mlx4_ib_get_dev_port(dev, ibdev); |
@@ -1642,6 +1683,7 @@ static int mlx4_ib_init_gid_table(struct mlx4_ib_dev *ibdev) | |||
1642 | mlx4_ib_get_dev_addr(dev, ibdev, port); | 1683 | mlx4_ib_get_dev_addr(dev, ibdev, port); |
1643 | } | 1684 | } |
1644 | 1685 | ||
1686 | spin_unlock(&iboe->lock); | ||
1645 | read_unlock(&dev_base_lock); | 1687 | read_unlock(&dev_base_lock); |
1646 | 1688 | ||
1647 | return 0; | 1689 | return 0; |
@@ -1656,25 +1698,57 @@ static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev) | |||
1656 | 1698 | ||
1657 | spin_lock(&iboe->lock); | 1699 | spin_lock(&iboe->lock); |
1658 | mlx4_foreach_ib_transport_port(port, ibdev->dev) { | 1700 | mlx4_foreach_ib_transport_port(port, ibdev->dev) { |
1701 | enum ib_port_state port_state = IB_PORT_NOP; | ||
1659 | struct net_device *old_master = iboe->masters[port - 1]; | 1702 | struct net_device *old_master = iboe->masters[port - 1]; |
1703 | struct net_device *curr_netdev; | ||
1660 | struct net_device *curr_master; | 1704 | struct net_device *curr_master; |
1705 | |||
1661 | iboe->netdevs[port - 1] = | 1706 | iboe->netdevs[port - 1] = |
1662 | mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port); | 1707 | mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port); |
1708 | if (iboe->netdevs[port - 1]) | ||
1709 | mlx4_ib_set_default_gid(ibdev, | ||
1710 | iboe->netdevs[port - 1], port); | ||
1711 | curr_netdev = iboe->netdevs[port - 1]; | ||
1663 | 1712 | ||
1664 | if (iboe->netdevs[port - 1] && | 1713 | if (iboe->netdevs[port - 1] && |
1665 | netif_is_bond_slave(iboe->netdevs[port - 1])) { | 1714 | netif_is_bond_slave(iboe->netdevs[port - 1])) { |
1666 | rtnl_lock(); | ||
1667 | iboe->masters[port - 1] = netdev_master_upper_dev_get( | 1715 | iboe->masters[port - 1] = netdev_master_upper_dev_get( |
1668 | iboe->netdevs[port - 1]); | 1716 | iboe->netdevs[port - 1]); |
1669 | rtnl_unlock(); | 1717 | } else { |
1718 | iboe->masters[port - 1] = NULL; | ||
1670 | } | 1719 | } |
1671 | curr_master = iboe->masters[port - 1]; | 1720 | curr_master = iboe->masters[port - 1]; |
1672 | 1721 | ||
1722 | if (curr_netdev) { | ||
1723 | port_state = (netif_running(curr_netdev) && netif_carrier_ok(curr_netdev)) ? | ||
1724 | IB_PORT_ACTIVE : IB_PORT_DOWN; | ||
1725 | mlx4_ib_set_default_gid(ibdev, curr_netdev, port); | ||
1726 | } else { | ||
1727 | reset_gid_table(ibdev, port); | ||
1728 | } | ||
1729 | /* if using bonding/team and a slave port is down, we don't the bond IP | ||
1730 | * based gids in the table since flows that select port by gid may get | ||
1731 | * the down port. | ||
1732 | */ | ||
1733 | if (curr_master && (port_state == IB_PORT_DOWN)) { | ||
1734 | reset_gid_table(ibdev, port); | ||
1735 | mlx4_ib_set_default_gid(ibdev, curr_netdev, port); | ||
1736 | } | ||
1673 | /* if bonding is used it is possible that we add it to masters | 1737 | /* if bonding is used it is possible that we add it to masters |
1674 | only after IP address is assigned to the net bonding | 1738 | * only after IP address is assigned to the net bonding |
1675 | interface */ | 1739 | * interface. |
1676 | if (curr_master && (old_master != curr_master)) | 1740 | */ |
1741 | if (curr_master && (old_master != curr_master)) { | ||
1742 | reset_gid_table(ibdev, port); | ||
1743 | mlx4_ib_set_default_gid(ibdev, curr_netdev, port); | ||
1677 | mlx4_ib_get_dev_addr(curr_master, ibdev, port); | 1744 | mlx4_ib_get_dev_addr(curr_master, ibdev, port); |
1745 | } | ||
1746 | |||
1747 | if (!curr_master && (old_master != curr_master)) { | ||
1748 | reset_gid_table(ibdev, port); | ||
1749 | mlx4_ib_set_default_gid(ibdev, curr_netdev, port); | ||
1750 | mlx4_ib_get_dev_addr(curr_netdev, ibdev, port); | ||
1751 | } | ||
1678 | } | 1752 | } |
1679 | 1753 | ||
1680 | spin_unlock(&iboe->lock); | 1754 | spin_unlock(&iboe->lock); |
@@ -1810,6 +1884,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
1810 | int i, j; | 1884 | int i, j; |
1811 | int err; | 1885 | int err; |
1812 | struct mlx4_ib_iboe *iboe; | 1886 | struct mlx4_ib_iboe *iboe; |
1887 | int ib_num_ports = 0; | ||
1813 | 1888 | ||
1814 | pr_info_once("%s", mlx4_ib_version); | 1889 | pr_info_once("%s", mlx4_ib_version); |
1815 | 1890 | ||
@@ -1985,10 +2060,14 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
1985 | ibdev->counters[i] = -1; | 2060 | ibdev->counters[i] = -1; |
1986 | } | 2061 | } |
1987 | 2062 | ||
2063 | mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB) | ||
2064 | ib_num_ports++; | ||
2065 | |||
1988 | spin_lock_init(&ibdev->sm_lock); | 2066 | spin_lock_init(&ibdev->sm_lock); |
1989 | mutex_init(&ibdev->cap_mask_mutex); | 2067 | mutex_init(&ibdev->cap_mask_mutex); |
1990 | 2068 | ||
1991 | if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) { | 2069 | if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED && |
2070 | ib_num_ports) { | ||
1992 | ibdev->steer_qpn_count = MLX4_IB_UC_MAX_NUM_QPS; | 2071 | ibdev->steer_qpn_count = MLX4_IB_UC_MAX_NUM_QPS; |
1993 | err = mlx4_qp_reserve_range(dev, ibdev->steer_qpn_count, | 2072 | err = mlx4_qp_reserve_range(dev, ibdev->steer_qpn_count, |
1994 | MLX4_IB_UC_STEER_QPN_ALIGN, | 2073 | MLX4_IB_UC_STEER_QPN_ALIGN, |
@@ -2051,7 +2130,11 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2051 | } | 2130 | } |
2052 | } | 2131 | } |
2053 | #endif | 2132 | #endif |
2133 | for (i = 1 ; i <= ibdev->num_ports ; ++i) | ||
2134 | reset_gid_table(ibdev, i); | ||
2135 | rtnl_lock(); | ||
2054 | mlx4_ib_scan_netdevs(ibdev); | 2136 | mlx4_ib_scan_netdevs(ibdev); |
2137 | rtnl_unlock(); | ||
2055 | mlx4_ib_init_gid_table(ibdev); | 2138 | mlx4_ib_init_gid_table(ibdev); |
2056 | } | 2139 | } |
2057 | 2140 | ||
diff --git a/drivers/infiniband/hw/mlx5/Kconfig b/drivers/infiniband/hw/mlx5/Kconfig index 8e6aebfaf8a4..10df386c6344 100644 --- a/drivers/infiniband/hw/mlx5/Kconfig +++ b/drivers/infiniband/hw/mlx5/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MLX5_INFINIBAND | 1 | config MLX5_INFINIBAND |
2 | tristate "Mellanox Connect-IB HCA support" | 2 | tristate "Mellanox Connect-IB HCA support" |
3 | depends on NETDEVICES && ETHERNET && PCI && X86 | 3 | depends on NETDEVICES && ETHERNET && PCI |
4 | select NET_VENDOR_MELLANOX | 4 | select NET_VENDOR_MELLANOX |
5 | select MLX5_CORE | 5 | select MLX5_CORE |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 9660d093f8cf..bf900579ac08 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -46,8 +46,8 @@ | |||
46 | #include "mlx5_ib.h" | 46 | #include "mlx5_ib.h" |
47 | 47 | ||
48 | #define DRIVER_NAME "mlx5_ib" | 48 | #define DRIVER_NAME "mlx5_ib" |
49 | #define DRIVER_VERSION "1.0" | 49 | #define DRIVER_VERSION "2.2-1" |
50 | #define DRIVER_RELDATE "June 2013" | 50 | #define DRIVER_RELDATE "Feb 2014" |
51 | 51 | ||
52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); | 52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); |
53 | MODULE_DESCRIPTION("Mellanox Connect-IB HCA IB driver"); | 53 | MODULE_DESCRIPTION("Mellanox Connect-IB HCA IB driver"); |
@@ -261,8 +261,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, | |||
261 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | | 261 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | |
262 | IB_DEVICE_PORT_ACTIVE_EVENT | | 262 | IB_DEVICE_PORT_ACTIVE_EVENT | |
263 | IB_DEVICE_SYS_IMAGE_GUID | | 263 | IB_DEVICE_SYS_IMAGE_GUID | |
264 | IB_DEVICE_RC_RNR_NAK_GEN | | 264 | IB_DEVICE_RC_RNR_NAK_GEN; |
265 | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; | ||
266 | flags = dev->mdev.caps.flags; | 265 | flags = dev->mdev.caps.flags; |
267 | if (flags & MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR) | 266 | if (flags & MLX5_DEV_CAP_FLAG_BAD_PKEY_CNTR) |
268 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; | 267 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; |
@@ -536,24 +535,38 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
536 | struct ib_udata *udata) | 535 | struct ib_udata *udata) |
537 | { | 536 | { |
538 | struct mlx5_ib_dev *dev = to_mdev(ibdev); | 537 | struct mlx5_ib_dev *dev = to_mdev(ibdev); |
539 | struct mlx5_ib_alloc_ucontext_req req; | 538 | struct mlx5_ib_alloc_ucontext_req_v2 req; |
540 | struct mlx5_ib_alloc_ucontext_resp resp; | 539 | struct mlx5_ib_alloc_ucontext_resp resp; |
541 | struct mlx5_ib_ucontext *context; | 540 | struct mlx5_ib_ucontext *context; |
542 | struct mlx5_uuar_info *uuari; | 541 | struct mlx5_uuar_info *uuari; |
543 | struct mlx5_uar *uars; | 542 | struct mlx5_uar *uars; |
544 | int gross_uuars; | 543 | int gross_uuars; |
545 | int num_uars; | 544 | int num_uars; |
545 | int ver; | ||
546 | int uuarn; | 546 | int uuarn; |
547 | int err; | 547 | int err; |
548 | int i; | 548 | int i; |
549 | int reqlen; | ||
549 | 550 | ||
550 | if (!dev->ib_active) | 551 | if (!dev->ib_active) |
551 | return ERR_PTR(-EAGAIN); | 552 | return ERR_PTR(-EAGAIN); |
552 | 553 | ||
553 | err = ib_copy_from_udata(&req, udata, sizeof(req)); | 554 | memset(&req, 0, sizeof(req)); |
555 | reqlen = udata->inlen - sizeof(struct ib_uverbs_cmd_hdr); | ||
556 | if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req)) | ||
557 | ver = 0; | ||
558 | else if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req_v2)) | ||
559 | ver = 2; | ||
560 | else | ||
561 | return ERR_PTR(-EINVAL); | ||
562 | |||
563 | err = ib_copy_from_udata(&req, udata, reqlen); | ||
554 | if (err) | 564 | if (err) |
555 | return ERR_PTR(err); | 565 | return ERR_PTR(err); |
556 | 566 | ||
567 | if (req.flags || req.reserved) | ||
568 | return ERR_PTR(-EINVAL); | ||
569 | |||
557 | if (req.total_num_uuars > MLX5_MAX_UUARS) | 570 | if (req.total_num_uuars > MLX5_MAX_UUARS) |
558 | return ERR_PTR(-ENOMEM); | 571 | return ERR_PTR(-ENOMEM); |
559 | 572 | ||
@@ -626,6 +639,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
626 | if (err) | 639 | if (err) |
627 | goto out_uars; | 640 | goto out_uars; |
628 | 641 | ||
642 | uuari->ver = ver; | ||
629 | uuari->num_low_latency_uuars = req.num_low_latency_uuars; | 643 | uuari->num_low_latency_uuars = req.num_low_latency_uuars; |
630 | uuari->uars = uars; | 644 | uuari->uars = uars; |
631 | uuari->num_uars = num_uars; | 645 | uuari->num_uars = num_uars; |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index ae37fb9bf262..7dfe8a1c84cf 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -216,7 +216,9 @@ static int sq_overhead(enum ib_qp_type qp_type) | |||
216 | 216 | ||
217 | case IB_QPT_UC: | 217 | case IB_QPT_UC: |
218 | size += sizeof(struct mlx5_wqe_ctrl_seg) + | 218 | size += sizeof(struct mlx5_wqe_ctrl_seg) + |
219 | sizeof(struct mlx5_wqe_raddr_seg); | 219 | sizeof(struct mlx5_wqe_raddr_seg) + |
220 | sizeof(struct mlx5_wqe_umr_ctrl_seg) + | ||
221 | sizeof(struct mlx5_mkey_seg); | ||
220 | break; | 222 | break; |
221 | 223 | ||
222 | case IB_QPT_UD: | 224 | case IB_QPT_UD: |
@@ -428,11 +430,17 @@ static int alloc_uuar(struct mlx5_uuar_info *uuari, | |||
428 | break; | 430 | break; |
429 | 431 | ||
430 | case MLX5_IB_LATENCY_CLASS_MEDIUM: | 432 | case MLX5_IB_LATENCY_CLASS_MEDIUM: |
431 | uuarn = alloc_med_class_uuar(uuari); | 433 | if (uuari->ver < 2) |
434 | uuarn = -ENOMEM; | ||
435 | else | ||
436 | uuarn = alloc_med_class_uuar(uuari); | ||
432 | break; | 437 | break; |
433 | 438 | ||
434 | case MLX5_IB_LATENCY_CLASS_HIGH: | 439 | case MLX5_IB_LATENCY_CLASS_HIGH: |
435 | uuarn = alloc_high_class_uuar(uuari); | 440 | if (uuari->ver < 2) |
441 | uuarn = -ENOMEM; | ||
442 | else | ||
443 | uuarn = alloc_high_class_uuar(uuari); | ||
436 | break; | 444 | break; |
437 | 445 | ||
438 | case MLX5_IB_LATENCY_CLASS_FAST_PATH: | 446 | case MLX5_IB_LATENCY_CLASS_FAST_PATH: |
@@ -657,8 +665,8 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev, | |||
657 | int err; | 665 | int err; |
658 | 666 | ||
659 | uuari = &dev->mdev.priv.uuari; | 667 | uuari = &dev->mdev.priv.uuari; |
660 | if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) | 668 | if (init_attr->create_flags) |
661 | qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK; | 669 | return -EINVAL; |
662 | 670 | ||
663 | if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR) | 671 | if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR) |
664 | lc = MLX5_IB_LATENCY_CLASS_FAST_PATH; | 672 | lc = MLX5_IB_LATENCY_CLASS_FAST_PATH; |
diff --git a/drivers/infiniband/hw/mlx5/user.h b/drivers/infiniband/hw/mlx5/user.h index 32a2a5dfc523..0f4f8e42a17f 100644 --- a/drivers/infiniband/hw/mlx5/user.h +++ b/drivers/infiniband/hw/mlx5/user.h | |||
@@ -62,6 +62,13 @@ struct mlx5_ib_alloc_ucontext_req { | |||
62 | __u32 num_low_latency_uuars; | 62 | __u32 num_low_latency_uuars; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | struct mlx5_ib_alloc_ucontext_req_v2 { | ||
66 | __u32 total_num_uuars; | ||
67 | __u32 num_low_latency_uuars; | ||
68 | __u32 flags; | ||
69 | __u32 reserved; | ||
70 | }; | ||
71 | |||
65 | struct mlx5_ib_alloc_ucontext_resp { | 72 | struct mlx5_ib_alloc_ucontext_resp { |
66 | __u32 qp_tab_size; | 73 | __u32 qp_tab_size; |
67 | __u32 bf_reg_size; | 74 | __u32 bf_reg_size; |
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 429141078eec..353c7b05a90a 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -675,8 +675,11 @@ static int nes_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | |||
675 | INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status); | 675 | INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status); |
676 | 676 | ||
677 | /* Initialize network devices */ | 677 | /* Initialize network devices */ |
678 | if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) | 678 | netdev = nes_netdev_init(nesdev, mmio_regs); |
679 | if (netdev == NULL) { | ||
680 | ret = -ENOMEM; | ||
679 | goto bail7; | 681 | goto bail7; |
682 | } | ||
680 | 683 | ||
681 | /* Register network device */ | 684 | /* Register network device */ |
682 | ret = register_netdev(netdev); | 685 | ret = register_netdev(netdev); |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 2ca86ca818bd..1a8a945efa60 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
@@ -127,7 +127,7 @@ static int ocrdma_addr_event(unsigned long event, struct net_device *netdev, | |||
127 | 127 | ||
128 | is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; | 128 | is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; |
129 | if (is_vlan) | 129 | if (is_vlan) |
130 | netdev = vlan_dev_real_dev(netdev); | 130 | netdev = rdma_vlan_dev_real_dev(netdev); |
131 | 131 | ||
132 | rcu_read_lock(); | 132 | rcu_read_lock(); |
133 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { | 133 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index aa92f40c9d50..e0cc201be41a 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
@@ -176,7 +176,7 @@ int ocrdma_query_port(struct ib_device *ibdev, | |||
176 | props->port_cap_flags = | 176 | props->port_cap_flags = |
177 | IB_PORT_CM_SUP | | 177 | IB_PORT_CM_SUP | |
178 | IB_PORT_REINIT_SUP | | 178 | IB_PORT_REINIT_SUP | |
179 | IB_PORT_DEVICE_MGMT_SUP | IB_PORT_VENDOR_CLASS_SUP; | 179 | IB_PORT_DEVICE_MGMT_SUP | IB_PORT_VENDOR_CLASS_SUP | IB_PORT_IP_BASED_GIDS; |
180 | props->gid_tbl_len = OCRDMA_MAX_SGID; | 180 | props->gid_tbl_len = OCRDMA_MAX_SGID; |
181 | props->pkey_tbl_len = 1; | 181 | props->pkey_tbl_len = 1; |
182 | props->bad_pkey_cntr = 0; | 182 | props->bad_pkey_cntr = 0; |
@@ -1416,7 +1416,7 @@ int ocrdma_query_qp(struct ib_qp *ibqp, | |||
1416 | OCRDMA_QP_PARAMS_HOP_LMT_MASK) >> | 1416 | OCRDMA_QP_PARAMS_HOP_LMT_MASK) >> |
1417 | OCRDMA_QP_PARAMS_HOP_LMT_SHIFT; | 1417 | OCRDMA_QP_PARAMS_HOP_LMT_SHIFT; |
1418 | qp_attr->ah_attr.grh.traffic_class = (params.tclass_sq_psn & | 1418 | qp_attr->ah_attr.grh.traffic_class = (params.tclass_sq_psn & |
1419 | OCRDMA_QP_PARAMS_SQ_PSN_MASK) >> | 1419 | OCRDMA_QP_PARAMS_TCLASS_MASK) >> |
1420 | OCRDMA_QP_PARAMS_TCLASS_SHIFT; | 1420 | OCRDMA_QP_PARAMS_TCLASS_SHIFT; |
1421 | 1421 | ||
1422 | qp_attr->ah_attr.ah_flags = IB_AH_GRH; | 1422 | qp_attr->ah_attr.ah_flags = IB_AH_GRH; |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 5bfc02f450e6..d1bd21319d7d 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -2395,6 +2395,11 @@ static int qib_7322_bringup_serdes(struct qib_pportdata *ppd) | |||
2395 | qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); | 2395 | qib_write_kreg_port(ppd, krp_ibcctrl_a, ppd->cpspec->ibcctrl_a); |
2396 | qib_write_kreg(dd, kr_scratch, 0ULL); | 2396 | qib_write_kreg(dd, kr_scratch, 0ULL); |
2397 | 2397 | ||
2398 | /* ensure previous Tx parameters are not still forced */ | ||
2399 | qib_write_kreg_port(ppd, krp_tx_deemph_override, | ||
2400 | SYM_MASK(IBSD_TX_DEEMPHASIS_OVERRIDE_0, | ||
2401 | reset_tx_deemphasis_override)); | ||
2402 | |||
2398 | if (qib_compat_ddr_negotiate) { | 2403 | if (qib_compat_ddr_negotiate) { |
2399 | ppd->cpspec->ibdeltainprog = 1; | 2404 | ppd->cpspec->ibdeltainprog = 1; |
2400 | ppd->cpspec->ibsymsnap = read_7322_creg32_port(ppd, | 2405 | ppd->cpspec->ibsymsnap = read_7322_creg32_port(ppd, |
diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c index 7ecc6061f1f4..f8dfd76be89f 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c | |||
@@ -629,6 +629,7 @@ static int qp_grp_id_from_flow(struct usnic_ib_qp_grp_flow *qp_flow, | |||
629 | { | 629 | { |
630 | enum usnic_transport_type trans_type = qp_flow->trans_type; | 630 | enum usnic_transport_type trans_type = qp_flow->trans_type; |
631 | int err; | 631 | int err; |
632 | uint16_t port_num = 0; | ||
632 | 633 | ||
633 | switch (trans_type) { | 634 | switch (trans_type) { |
634 | case USNIC_TRANSPORT_ROCE_CUSTOM: | 635 | case USNIC_TRANSPORT_ROCE_CUSTOM: |
@@ -637,9 +638,15 @@ static int qp_grp_id_from_flow(struct usnic_ib_qp_grp_flow *qp_flow, | |||
637 | case USNIC_TRANSPORT_IPV4_UDP: | 638 | case USNIC_TRANSPORT_IPV4_UDP: |
638 | err = usnic_transport_sock_get_addr(qp_flow->udp.sock, | 639 | err = usnic_transport_sock_get_addr(qp_flow->udp.sock, |
639 | NULL, NULL, | 640 | NULL, NULL, |
640 | (uint16_t *) id); | 641 | &port_num); |
641 | if (err) | 642 | if (err) |
642 | return err; | 643 | return err; |
644 | /* | ||
645 | * Copy port_num to stack first and then to *id, | ||
646 | * so that the short to int cast works for little | ||
647 | * and big endian systems. | ||
648 | */ | ||
649 | *id = port_num; | ||
643 | break; | 650 | break; |
644 | default: | 651 | default: |
645 | usnic_err("Unsupported transport %u\n", trans_type); | 652 | usnic_err("Unsupported transport %u\n", trans_type); |
diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 538822684d5b..334f34b1cd46 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c | |||
@@ -610,11 +610,12 @@ void iser_snd_completion(struct iser_tx_desc *tx_desc, | |||
610 | ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr, | 610 | ib_dma_unmap_single(device->ib_device, tx_desc->dma_addr, |
611 | ISER_HEADERS_LEN, DMA_TO_DEVICE); | 611 | ISER_HEADERS_LEN, DMA_TO_DEVICE); |
612 | kmem_cache_free(ig.desc_cache, tx_desc); | 612 | kmem_cache_free(ig.desc_cache, tx_desc); |
613 | tx_desc = NULL; | ||
613 | } | 614 | } |
614 | 615 | ||
615 | atomic_dec(&ib_conn->post_send_buf_count); | 616 | atomic_dec(&ib_conn->post_send_buf_count); |
616 | 617 | ||
617 | if (tx_desc->type == ISCSI_TX_CONTROL) { | 618 | if (tx_desc && tx_desc->type == ISCSI_TX_CONTROL) { |
618 | /* this arithmetic is legal by libiscsi dd_data allocation */ | 619 | /* this arithmetic is legal by libiscsi dd_data allocation */ |
619 | task = (void *) ((long)(void *)tx_desc - | 620 | task = (void *) ((long)(void *)tx_desc - |
620 | sizeof(struct iscsi_task)); | 621 | sizeof(struct iscsi_task)); |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index afe95674008b..ca37edef2791 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -652,9 +652,13 @@ static int iser_disconnected_handler(struct rdma_cm_id *cma_id) | |||
652 | /* getting here when the state is UP means that the conn is being * | 652 | /* getting here when the state is UP means that the conn is being * |
653 | * terminated asynchronously from the iSCSI layer's perspective. */ | 653 | * terminated asynchronously from the iSCSI layer's perspective. */ |
654 | if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, | 654 | if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, |
655 | ISER_CONN_TERMINATING)) | 655 | ISER_CONN_TERMINATING)){ |
656 | iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn, | 656 | if (ib_conn->iser_conn) |
657 | ISCSI_ERR_CONN_FAILED); | 657 | iscsi_conn_failure(ib_conn->iser_conn->iscsi_conn, |
658 | ISCSI_ERR_CONN_FAILED); | ||
659 | else | ||
660 | iser_err("iscsi_iser connection isn't bound\n"); | ||
661 | } | ||
658 | 662 | ||
659 | /* Complete the termination process if no posts are pending */ | 663 | /* Complete the termination process if no posts are pending */ |
660 | if (ib_conn->post_recv_buf_count == 0 && | 664 | if (ib_conn->post_recv_buf_count == 0 && |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 2b161be3c1a3..8ee228e9ab5a 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -453,6 +453,7 @@ isert_conn_create_fastreg_pool(struct isert_conn *isert_conn) | |||
453 | if (ret) { | 453 | if (ret) { |
454 | pr_err("Failed to create fastreg descriptor err=%d\n", | 454 | pr_err("Failed to create fastreg descriptor err=%d\n", |
455 | ret); | 455 | ret); |
456 | kfree(fr_desc); | ||
456 | goto err; | 457 | goto err; |
457 | } | 458 | } |
458 | 459 | ||
@@ -491,12 +492,11 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | |||
491 | isert_conn->state = ISER_CONN_INIT; | 492 | isert_conn->state = ISER_CONN_INIT; |
492 | INIT_LIST_HEAD(&isert_conn->conn_accept_node); | 493 | INIT_LIST_HEAD(&isert_conn->conn_accept_node); |
493 | init_completion(&isert_conn->conn_login_comp); | 494 | init_completion(&isert_conn->conn_login_comp); |
494 | init_waitqueue_head(&isert_conn->conn_wait); | 495 | init_completion(&isert_conn->conn_wait); |
495 | init_waitqueue_head(&isert_conn->conn_wait_comp_err); | 496 | init_completion(&isert_conn->conn_wait_comp_err); |
496 | kref_init(&isert_conn->conn_kref); | 497 | kref_init(&isert_conn->conn_kref); |
497 | kref_get(&isert_conn->conn_kref); | 498 | kref_get(&isert_conn->conn_kref); |
498 | mutex_init(&isert_conn->conn_mutex); | 499 | mutex_init(&isert_conn->conn_mutex); |
499 | mutex_init(&isert_conn->conn_comp_mutex); | ||
500 | spin_lock_init(&isert_conn->conn_lock); | 500 | spin_lock_init(&isert_conn->conn_lock); |
501 | 501 | ||
502 | cma_id->context = isert_conn; | 502 | cma_id->context = isert_conn; |
@@ -687,11 +687,11 @@ isert_disconnect_work(struct work_struct *work) | |||
687 | 687 | ||
688 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 688 | pr_debug("isert_disconnect_work(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); |
689 | mutex_lock(&isert_conn->conn_mutex); | 689 | mutex_lock(&isert_conn->conn_mutex); |
690 | isert_conn->state = ISER_CONN_DOWN; | 690 | if (isert_conn->state == ISER_CONN_UP) |
691 | isert_conn->state = ISER_CONN_TERMINATING; | ||
691 | 692 | ||
692 | if (isert_conn->post_recv_buf_count == 0 && | 693 | if (isert_conn->post_recv_buf_count == 0 && |
693 | atomic_read(&isert_conn->post_send_buf_count) == 0) { | 694 | atomic_read(&isert_conn->post_send_buf_count) == 0) { |
694 | pr_debug("Calling wake_up(&isert_conn->conn_wait);\n"); | ||
695 | mutex_unlock(&isert_conn->conn_mutex); | 695 | mutex_unlock(&isert_conn->conn_mutex); |
696 | goto wake_up; | 696 | goto wake_up; |
697 | } | 697 | } |
@@ -711,7 +711,7 @@ isert_disconnect_work(struct work_struct *work) | |||
711 | mutex_unlock(&isert_conn->conn_mutex); | 711 | mutex_unlock(&isert_conn->conn_mutex); |
712 | 712 | ||
713 | wake_up: | 713 | wake_up: |
714 | wake_up(&isert_conn->conn_wait); | 714 | complete(&isert_conn->conn_wait); |
715 | isert_put_conn(isert_conn); | 715 | isert_put_conn(isert_conn); |
716 | } | 716 | } |
717 | 717 | ||
@@ -887,16 +887,17 @@ isert_init_send_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd, | |||
887 | * Coalesce send completion interrupts by only setting IB_SEND_SIGNALED | 887 | * Coalesce send completion interrupts by only setting IB_SEND_SIGNALED |
888 | * bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls. | 888 | * bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls. |
889 | */ | 889 | */ |
890 | mutex_lock(&isert_conn->conn_comp_mutex); | 890 | mutex_lock(&isert_conn->conn_mutex); |
891 | if (coalesce && | 891 | if (coalesce && isert_conn->state == ISER_CONN_UP && |
892 | ++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) { | 892 | ++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) { |
893 | tx_desc->llnode_active = true; | ||
893 | llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist); | 894 | llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist); |
894 | mutex_unlock(&isert_conn->conn_comp_mutex); | 895 | mutex_unlock(&isert_conn->conn_mutex); |
895 | return; | 896 | return; |
896 | } | 897 | } |
897 | isert_conn->conn_comp_batch = 0; | 898 | isert_conn->conn_comp_batch = 0; |
898 | tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist); | 899 | tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist); |
899 | mutex_unlock(&isert_conn->conn_comp_mutex); | 900 | mutex_unlock(&isert_conn->conn_mutex); |
900 | 901 | ||
901 | send_wr->send_flags = IB_SEND_SIGNALED; | 902 | send_wr->send_flags = IB_SEND_SIGNALED; |
902 | } | 903 | } |
@@ -1463,7 +1464,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1463 | case ISCSI_OP_SCSI_CMD: | 1464 | case ISCSI_OP_SCSI_CMD: |
1464 | spin_lock_bh(&conn->cmd_lock); | 1465 | spin_lock_bh(&conn->cmd_lock); |
1465 | if (!list_empty(&cmd->i_conn_node)) | 1466 | if (!list_empty(&cmd->i_conn_node)) |
1466 | list_del(&cmd->i_conn_node); | 1467 | list_del_init(&cmd->i_conn_node); |
1467 | spin_unlock_bh(&conn->cmd_lock); | 1468 | spin_unlock_bh(&conn->cmd_lock); |
1468 | 1469 | ||
1469 | if (cmd->data_direction == DMA_TO_DEVICE) | 1470 | if (cmd->data_direction == DMA_TO_DEVICE) |
@@ -1475,7 +1476,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1475 | case ISCSI_OP_SCSI_TMFUNC: | 1476 | case ISCSI_OP_SCSI_TMFUNC: |
1476 | spin_lock_bh(&conn->cmd_lock); | 1477 | spin_lock_bh(&conn->cmd_lock); |
1477 | if (!list_empty(&cmd->i_conn_node)) | 1478 | if (!list_empty(&cmd->i_conn_node)) |
1478 | list_del(&cmd->i_conn_node); | 1479 | list_del_init(&cmd->i_conn_node); |
1479 | spin_unlock_bh(&conn->cmd_lock); | 1480 | spin_unlock_bh(&conn->cmd_lock); |
1480 | 1481 | ||
1481 | transport_generic_free_cmd(&cmd->se_cmd, 0); | 1482 | transport_generic_free_cmd(&cmd->se_cmd, 0); |
@@ -1485,7 +1486,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd) | |||
1485 | case ISCSI_OP_TEXT: | 1486 | case ISCSI_OP_TEXT: |
1486 | spin_lock_bh(&conn->cmd_lock); | 1487 | spin_lock_bh(&conn->cmd_lock); |
1487 | if (!list_empty(&cmd->i_conn_node)) | 1488 | if (!list_empty(&cmd->i_conn_node)) |
1488 | list_del(&cmd->i_conn_node); | 1489 | list_del_init(&cmd->i_conn_node); |
1489 | spin_unlock_bh(&conn->cmd_lock); | 1490 | spin_unlock_bh(&conn->cmd_lock); |
1490 | 1491 | ||
1491 | /* | 1492 | /* |
@@ -1548,6 +1549,7 @@ isert_completion_rdma_read(struct iser_tx_desc *tx_desc, | |||
1548 | iscsit_stop_dataout_timer(cmd); | 1549 | iscsit_stop_dataout_timer(cmd); |
1549 | device->unreg_rdma_mem(isert_cmd, isert_conn); | 1550 | device->unreg_rdma_mem(isert_cmd, isert_conn); |
1550 | cmd->write_data_done = wr->cur_rdma_length; | 1551 | cmd->write_data_done = wr->cur_rdma_length; |
1552 | wr->send_wr_num = 0; | ||
1551 | 1553 | ||
1552 | pr_debug("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); | 1554 | pr_debug("Cmd: %p RDMA_READ comp calling execute_cmd\n", isert_cmd); |
1553 | spin_lock_bh(&cmd->istate_lock); | 1555 | spin_lock_bh(&cmd->istate_lock); |
@@ -1588,7 +1590,7 @@ isert_do_control_comp(struct work_struct *work) | |||
1588 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); | 1590 | pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); |
1589 | /* | 1591 | /* |
1590 | * Call atomic_dec(&isert_conn->post_send_buf_count) | 1592 | * Call atomic_dec(&isert_conn->post_send_buf_count) |
1591 | * from isert_free_conn() | 1593 | * from isert_wait_conn() |
1592 | */ | 1594 | */ |
1593 | isert_conn->logout_posted = true; | 1595 | isert_conn->logout_posted = true; |
1594 | iscsit_logout_post_handler(cmd, cmd->conn); | 1596 | iscsit_logout_post_handler(cmd, cmd->conn); |
@@ -1612,6 +1614,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc, | |||
1612 | struct ib_device *ib_dev) | 1614 | struct ib_device *ib_dev) |
1613 | { | 1615 | { |
1614 | struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; | 1616 | struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd; |
1617 | struct isert_rdma_wr *wr = &isert_cmd->rdma_wr; | ||
1615 | 1618 | ||
1616 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || | 1619 | if (cmd->i_state == ISTATE_SEND_TASKMGTRSP || |
1617 | cmd->i_state == ISTATE_SEND_LOGOUTRSP || | 1620 | cmd->i_state == ISTATE_SEND_LOGOUTRSP || |
@@ -1623,7 +1626,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc, | |||
1623 | queue_work(isert_comp_wq, &isert_cmd->comp_work); | 1626 | queue_work(isert_comp_wq, &isert_cmd->comp_work); |
1624 | return; | 1627 | return; |
1625 | } | 1628 | } |
1626 | atomic_dec(&isert_conn->post_send_buf_count); | 1629 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
1627 | 1630 | ||
1628 | cmd->i_state = ISTATE_SENT_STATUS; | 1631 | cmd->i_state = ISTATE_SENT_STATUS; |
1629 | isert_completion_put(tx_desc, isert_cmd, ib_dev); | 1632 | isert_completion_put(tx_desc, isert_cmd, ib_dev); |
@@ -1661,7 +1664,7 @@ __isert_send_completion(struct iser_tx_desc *tx_desc, | |||
1661 | case ISER_IB_RDMA_READ: | 1664 | case ISER_IB_RDMA_READ: |
1662 | pr_debug("isert_send_completion: Got ISER_IB_RDMA_READ:\n"); | 1665 | pr_debug("isert_send_completion: Got ISER_IB_RDMA_READ:\n"); |
1663 | 1666 | ||
1664 | atomic_dec(&isert_conn->post_send_buf_count); | 1667 | atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); |
1665 | isert_completion_rdma_read(tx_desc, isert_cmd); | 1668 | isert_completion_rdma_read(tx_desc, isert_cmd); |
1666 | break; | 1669 | break; |
1667 | default: | 1670 | default: |
@@ -1690,31 +1693,76 @@ isert_send_completion(struct iser_tx_desc *tx_desc, | |||
1690 | } | 1693 | } |
1691 | 1694 | ||
1692 | static void | 1695 | static void |
1693 | isert_cq_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | 1696 | isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_dev) |
1697 | { | ||
1698 | struct llist_node *llnode; | ||
1699 | struct isert_rdma_wr *wr; | ||
1700 | struct iser_tx_desc *t; | ||
1701 | |||
1702 | mutex_lock(&isert_conn->conn_mutex); | ||
1703 | llnode = llist_del_all(&isert_conn->conn_comp_llist); | ||
1704 | isert_conn->conn_comp_batch = 0; | ||
1705 | mutex_unlock(&isert_conn->conn_mutex); | ||
1706 | |||
1707 | while (llnode) { | ||
1708 | t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); | ||
1709 | llnode = llist_next(llnode); | ||
1710 | wr = &t->isert_cmd->rdma_wr; | ||
1711 | |||
1712 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); | ||
1713 | isert_completion_put(t, t->isert_cmd, ib_dev); | ||
1714 | } | ||
1715 | } | ||
1716 | |||
1717 | static void | ||
1718 | isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn) | ||
1694 | { | 1719 | { |
1695 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; | 1720 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; |
1721 | struct isert_cmd *isert_cmd = tx_desc->isert_cmd; | ||
1722 | struct llist_node *llnode = tx_desc->comp_llnode_batch; | ||
1723 | struct isert_rdma_wr *wr; | ||
1724 | struct iser_tx_desc *t; | ||
1696 | 1725 | ||
1697 | if (tx_desc) { | 1726 | while (llnode) { |
1698 | struct isert_cmd *isert_cmd = tx_desc->isert_cmd; | 1727 | t = llist_entry(llnode, struct iser_tx_desc, comp_llnode); |
1728 | llnode = llist_next(llnode); | ||
1729 | wr = &t->isert_cmd->rdma_wr; | ||
1699 | 1730 | ||
1700 | if (!isert_cmd) | 1731 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
1701 | isert_unmap_tx_desc(tx_desc, ib_dev); | 1732 | isert_completion_put(t, t->isert_cmd, ib_dev); |
1702 | else | ||
1703 | isert_completion_put(tx_desc, isert_cmd, ib_dev); | ||
1704 | } | 1733 | } |
1734 | tx_desc->comp_llnode_batch = NULL; | ||
1705 | 1735 | ||
1706 | if (isert_conn->post_recv_buf_count == 0 && | 1736 | if (!isert_cmd) |
1707 | atomic_read(&isert_conn->post_send_buf_count) == 0) { | 1737 | isert_unmap_tx_desc(tx_desc, ib_dev); |
1708 | pr_debug("isert_cq_comp_err >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); | 1738 | else |
1709 | pr_debug("Calling wake_up from isert_cq_comp_err\n"); | 1739 | isert_completion_put(tx_desc, isert_cmd, ib_dev); |
1740 | } | ||
1710 | 1741 | ||
1711 | mutex_lock(&isert_conn->conn_mutex); | 1742 | static void |
1712 | if (isert_conn->state != ISER_CONN_DOWN) | 1743 | isert_cq_rx_comp_err(struct isert_conn *isert_conn) |
1713 | isert_conn->state = ISER_CONN_TERMINATING; | 1744 | { |
1714 | mutex_unlock(&isert_conn->conn_mutex); | 1745 | struct ib_device *ib_dev = isert_conn->conn_cm_id->device; |
1746 | struct iscsi_conn *conn = isert_conn->conn; | ||
1715 | 1747 | ||
1716 | wake_up(&isert_conn->conn_wait_comp_err); | 1748 | if (isert_conn->post_recv_buf_count) |
1749 | return; | ||
1750 | |||
1751 | isert_cq_drain_comp_llist(isert_conn, ib_dev); | ||
1752 | |||
1753 | if (conn->sess) { | ||
1754 | target_sess_cmd_list_set_waiting(conn->sess->se_sess); | ||
1755 | target_wait_for_sess_cmds(conn->sess->se_sess); | ||
1717 | } | 1756 | } |
1757 | |||
1758 | while (atomic_read(&isert_conn->post_send_buf_count)) | ||
1759 | msleep(3000); | ||
1760 | |||
1761 | mutex_lock(&isert_conn->conn_mutex); | ||
1762 | isert_conn->state = ISER_CONN_DOWN; | ||
1763 | mutex_unlock(&isert_conn->conn_mutex); | ||
1764 | |||
1765 | complete(&isert_conn->conn_wait_comp_err); | ||
1718 | } | 1766 | } |
1719 | 1767 | ||
1720 | static void | 1768 | static void |
@@ -1739,8 +1787,14 @@ isert_cq_tx_work(struct work_struct *work) | |||
1739 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); | 1787 | pr_debug("TX wc.status != IB_WC_SUCCESS >>>>>>>>>>>>>>\n"); |
1740 | pr_debug("TX wc.status: 0x%08x\n", wc.status); | 1788 | pr_debug("TX wc.status: 0x%08x\n", wc.status); |
1741 | pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); | 1789 | pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err); |
1742 | atomic_dec(&isert_conn->post_send_buf_count); | 1790 | |
1743 | isert_cq_comp_err(tx_desc, isert_conn); | 1791 | if (wc.wr_id != ISER_FASTREG_LI_WRID) { |
1792 | if (tx_desc->llnode_active) | ||
1793 | continue; | ||
1794 | |||
1795 | atomic_dec(&isert_conn->post_send_buf_count); | ||
1796 | isert_cq_tx_comp_err(tx_desc, isert_conn); | ||
1797 | } | ||
1744 | } | 1798 | } |
1745 | } | 1799 | } |
1746 | 1800 | ||
@@ -1783,7 +1837,7 @@ isert_cq_rx_work(struct work_struct *work) | |||
1783 | wc.vendor_err); | 1837 | wc.vendor_err); |
1784 | } | 1838 | } |
1785 | isert_conn->post_recv_buf_count--; | 1839 | isert_conn->post_recv_buf_count--; |
1786 | isert_cq_comp_err(NULL, isert_conn); | 1840 | isert_cq_rx_comp_err(isert_conn); |
1787 | } | 1841 | } |
1788 | } | 1842 | } |
1789 | 1843 | ||
@@ -2201,6 +2255,7 @@ isert_fast_reg_mr(struct fast_reg_descriptor *fr_desc, | |||
2201 | 2255 | ||
2202 | if (!fr_desc->valid) { | 2256 | if (!fr_desc->valid) { |
2203 | memset(&inv_wr, 0, sizeof(inv_wr)); | 2257 | memset(&inv_wr, 0, sizeof(inv_wr)); |
2258 | inv_wr.wr_id = ISER_FASTREG_LI_WRID; | ||
2204 | inv_wr.opcode = IB_WR_LOCAL_INV; | 2259 | inv_wr.opcode = IB_WR_LOCAL_INV; |
2205 | inv_wr.ex.invalidate_rkey = fr_desc->data_mr->rkey; | 2260 | inv_wr.ex.invalidate_rkey = fr_desc->data_mr->rkey; |
2206 | wr = &inv_wr; | 2261 | wr = &inv_wr; |
@@ -2211,6 +2266,7 @@ isert_fast_reg_mr(struct fast_reg_descriptor *fr_desc, | |||
2211 | 2266 | ||
2212 | /* Prepare FASTREG WR */ | 2267 | /* Prepare FASTREG WR */ |
2213 | memset(&fr_wr, 0, sizeof(fr_wr)); | 2268 | memset(&fr_wr, 0, sizeof(fr_wr)); |
2269 | fr_wr.wr_id = ISER_FASTREG_LI_WRID; | ||
2214 | fr_wr.opcode = IB_WR_FAST_REG_MR; | 2270 | fr_wr.opcode = IB_WR_FAST_REG_MR; |
2215 | fr_wr.wr.fast_reg.iova_start = | 2271 | fr_wr.wr.fast_reg.iova_start = |
2216 | fr_desc->data_frpl->page_list[0] + page_off; | 2272 | fr_desc->data_frpl->page_list[0] + page_off; |
@@ -2376,12 +2432,12 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) | |||
2376 | isert_init_send_wr(isert_conn, isert_cmd, | 2432 | isert_init_send_wr(isert_conn, isert_cmd, |
2377 | &isert_cmd->tx_desc.send_wr, true); | 2433 | &isert_cmd->tx_desc.send_wr, true); |
2378 | 2434 | ||
2379 | atomic_inc(&isert_conn->post_send_buf_count); | 2435 | atomic_add(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
2380 | 2436 | ||
2381 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); | 2437 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); |
2382 | if (rc) { | 2438 | if (rc) { |
2383 | pr_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); | 2439 | pr_warn("ib_post_send() failed for IB_WR_RDMA_WRITE\n"); |
2384 | atomic_dec(&isert_conn->post_send_buf_count); | 2440 | atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); |
2385 | } | 2441 | } |
2386 | pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data READ\n", | 2442 | pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data READ\n", |
2387 | isert_cmd); | 2443 | isert_cmd); |
@@ -2409,12 +2465,12 @@ isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery) | |||
2409 | return rc; | 2465 | return rc; |
2410 | } | 2466 | } |
2411 | 2467 | ||
2412 | atomic_inc(&isert_conn->post_send_buf_count); | 2468 | atomic_add(wr->send_wr_num, &isert_conn->post_send_buf_count); |
2413 | 2469 | ||
2414 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); | 2470 | rc = ib_post_send(isert_conn->conn_qp, wr->send_wr, &wr_failed); |
2415 | if (rc) { | 2471 | if (rc) { |
2416 | pr_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); | 2472 | pr_warn("ib_post_send() failed for IB_WR_RDMA_READ\n"); |
2417 | atomic_dec(&isert_conn->post_send_buf_count); | 2473 | atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); |
2418 | } | 2474 | } |
2419 | pr_debug("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", | 2475 | pr_debug("Cmd: %p posted RDMA_READ memory for ISER Data WRITE\n", |
2420 | isert_cmd); | 2476 | isert_cmd); |
@@ -2701,22 +2757,11 @@ isert_free_np(struct iscsi_np *np) | |||
2701 | kfree(isert_np); | 2757 | kfree(isert_np); |
2702 | } | 2758 | } |
2703 | 2759 | ||
2704 | static int isert_check_state(struct isert_conn *isert_conn, int state) | 2760 | static void isert_wait_conn(struct iscsi_conn *conn) |
2705 | { | ||
2706 | int ret; | ||
2707 | |||
2708 | mutex_lock(&isert_conn->conn_mutex); | ||
2709 | ret = (isert_conn->state == state); | ||
2710 | mutex_unlock(&isert_conn->conn_mutex); | ||
2711 | |||
2712 | return ret; | ||
2713 | } | ||
2714 | |||
2715 | static void isert_free_conn(struct iscsi_conn *conn) | ||
2716 | { | 2761 | { |
2717 | struct isert_conn *isert_conn = conn->context; | 2762 | struct isert_conn *isert_conn = conn->context; |
2718 | 2763 | ||
2719 | pr_debug("isert_free_conn: Starting \n"); | 2764 | pr_debug("isert_wait_conn: Starting \n"); |
2720 | /* | 2765 | /* |
2721 | * Decrement post_send_buf_count for special case when called | 2766 | * Decrement post_send_buf_count for special case when called |
2722 | * from isert_do_control_comp() -> iscsit_logout_post_handler() | 2767 | * from isert_do_control_comp() -> iscsit_logout_post_handler() |
@@ -2726,38 +2771,29 @@ static void isert_free_conn(struct iscsi_conn *conn) | |||
2726 | atomic_dec(&isert_conn->post_send_buf_count); | 2771 | atomic_dec(&isert_conn->post_send_buf_count); |
2727 | 2772 | ||
2728 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { | 2773 | if (isert_conn->conn_cm_id && isert_conn->state != ISER_CONN_DOWN) { |
2729 | pr_debug("Calling rdma_disconnect from isert_free_conn\n"); | 2774 | pr_debug("Calling rdma_disconnect from isert_wait_conn\n"); |
2730 | rdma_disconnect(isert_conn->conn_cm_id); | 2775 | rdma_disconnect(isert_conn->conn_cm_id); |
2731 | } | 2776 | } |
2732 | /* | 2777 | /* |
2733 | * Only wait for conn_wait_comp_err if the isert_conn made it | 2778 | * Only wait for conn_wait_comp_err if the isert_conn made it |
2734 | * into full feature phase.. | 2779 | * into full feature phase.. |
2735 | */ | 2780 | */ |
2736 | if (isert_conn->state == ISER_CONN_UP) { | ||
2737 | pr_debug("isert_free_conn: Before wait_event comp_err %d\n", | ||
2738 | isert_conn->state); | ||
2739 | mutex_unlock(&isert_conn->conn_mutex); | ||
2740 | |||
2741 | wait_event(isert_conn->conn_wait_comp_err, | ||
2742 | (isert_check_state(isert_conn, ISER_CONN_TERMINATING))); | ||
2743 | |||
2744 | wait_event(isert_conn->conn_wait, | ||
2745 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); | ||
2746 | |||
2747 | isert_put_conn(isert_conn); | ||
2748 | return; | ||
2749 | } | ||
2750 | if (isert_conn->state == ISER_CONN_INIT) { | 2781 | if (isert_conn->state == ISER_CONN_INIT) { |
2751 | mutex_unlock(&isert_conn->conn_mutex); | 2782 | mutex_unlock(&isert_conn->conn_mutex); |
2752 | isert_put_conn(isert_conn); | ||
2753 | return; | 2783 | return; |
2754 | } | 2784 | } |
2755 | pr_debug("isert_free_conn: wait_event conn_wait %d\n", | 2785 | if (isert_conn->state == ISER_CONN_UP) |
2756 | isert_conn->state); | 2786 | isert_conn->state = ISER_CONN_TERMINATING; |
2757 | mutex_unlock(&isert_conn->conn_mutex); | 2787 | mutex_unlock(&isert_conn->conn_mutex); |
2758 | 2788 | ||
2759 | wait_event(isert_conn->conn_wait, | 2789 | wait_for_completion(&isert_conn->conn_wait_comp_err); |
2760 | (isert_check_state(isert_conn, ISER_CONN_DOWN))); | 2790 | |
2791 | wait_for_completion(&isert_conn->conn_wait); | ||
2792 | } | ||
2793 | |||
2794 | static void isert_free_conn(struct iscsi_conn *conn) | ||
2795 | { | ||
2796 | struct isert_conn *isert_conn = conn->context; | ||
2761 | 2797 | ||
2762 | isert_put_conn(isert_conn); | 2798 | isert_put_conn(isert_conn); |
2763 | } | 2799 | } |
@@ -2770,6 +2806,7 @@ static struct iscsit_transport iser_target_transport = { | |||
2770 | .iscsit_setup_np = isert_setup_np, | 2806 | .iscsit_setup_np = isert_setup_np, |
2771 | .iscsit_accept_np = isert_accept_np, | 2807 | .iscsit_accept_np = isert_accept_np, |
2772 | .iscsit_free_np = isert_free_np, | 2808 | .iscsit_free_np = isert_free_np, |
2809 | .iscsit_wait_conn = isert_wait_conn, | ||
2773 | .iscsit_free_conn = isert_free_conn, | 2810 | .iscsit_free_conn = isert_free_conn, |
2774 | .iscsit_get_login_rx = isert_get_login_rx, | 2811 | .iscsit_get_login_rx = isert_get_login_rx, |
2775 | .iscsit_put_login_tx = isert_put_login_tx, | 2812 | .iscsit_put_login_tx = isert_put_login_tx, |
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 708a069002f3..f6ae7f5dd408 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #define ISERT_RDMA_LISTEN_BACKLOG 10 | 7 | #define ISERT_RDMA_LISTEN_BACKLOG 10 |
8 | #define ISCSI_ISER_SG_TABLESIZE 256 | 8 | #define ISCSI_ISER_SG_TABLESIZE 256 |
9 | #define ISER_FASTREG_LI_WRID 0xffffffffffffffffULL | ||
9 | 10 | ||
10 | enum isert_desc_type { | 11 | enum isert_desc_type { |
11 | ISCSI_TX_CONTROL, | 12 | ISCSI_TX_CONTROL, |
@@ -45,6 +46,7 @@ struct iser_tx_desc { | |||
45 | struct isert_cmd *isert_cmd; | 46 | struct isert_cmd *isert_cmd; |
46 | struct llist_node *comp_llnode_batch; | 47 | struct llist_node *comp_llnode_batch; |
47 | struct llist_node comp_llnode; | 48 | struct llist_node comp_llnode; |
49 | bool llnode_active; | ||
48 | struct ib_send_wr send_wr; | 50 | struct ib_send_wr send_wr; |
49 | } __packed; | 51 | } __packed; |
50 | 52 | ||
@@ -116,8 +118,8 @@ struct isert_conn { | |||
116 | struct isert_device *conn_device; | 118 | struct isert_device *conn_device; |
117 | struct work_struct conn_logout_work; | 119 | struct work_struct conn_logout_work; |
118 | struct mutex conn_mutex; | 120 | struct mutex conn_mutex; |
119 | wait_queue_head_t conn_wait; | 121 | struct completion conn_wait; |
120 | wait_queue_head_t conn_wait_comp_err; | 122 | struct completion conn_wait_comp_err; |
121 | struct kref conn_kref; | 123 | struct kref conn_kref; |
122 | struct list_head conn_fr_pool; | 124 | struct list_head conn_fr_pool; |
123 | int conn_fr_pool_size; | 125 | int conn_fr_pool_size; |
@@ -126,7 +128,6 @@ struct isert_conn { | |||
126 | #define ISERT_COMP_BATCH_COUNT 8 | 128 | #define ISERT_COMP_BATCH_COUNT 8 |
127 | int conn_comp_batch; | 129 | int conn_comp_batch; |
128 | struct llist_head conn_comp_llist; | 130 | struct llist_head conn_comp_llist; |
129 | struct mutex conn_comp_mutex; | ||
130 | }; | 131 | }; |
131 | 132 | ||
132 | #define ISERT_MAX_CQ 64 | 133 | #define ISERT_MAX_CQ 64 |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 520a7e5a490b..0e537d8d0e47 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -3666,9 +3666,9 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rdma_size( | |||
3666 | unsigned long val; | 3666 | unsigned long val; |
3667 | int ret; | 3667 | int ret; |
3668 | 3668 | ||
3669 | ret = strict_strtoul(page, 0, &val); | 3669 | ret = kstrtoul(page, 0, &val); |
3670 | if (ret < 0) { | 3670 | if (ret < 0) { |
3671 | pr_err("strict_strtoul() failed with ret: %d\n", ret); | 3671 | pr_err("kstrtoul() failed with ret: %d\n", ret); |
3672 | return -EINVAL; | 3672 | return -EINVAL; |
3673 | } | 3673 | } |
3674 | if (val > MAX_SRPT_RDMA_SIZE) { | 3674 | if (val > MAX_SRPT_RDMA_SIZE) { |
@@ -3706,9 +3706,9 @@ static ssize_t srpt_tpg_attrib_store_srp_max_rsp_size( | |||
3706 | unsigned long val; | 3706 | unsigned long val; |
3707 | int ret; | 3707 | int ret; |
3708 | 3708 | ||
3709 | ret = strict_strtoul(page, 0, &val); | 3709 | ret = kstrtoul(page, 0, &val); |
3710 | if (ret < 0) { | 3710 | if (ret < 0) { |
3711 | pr_err("strict_strtoul() failed with ret: %d\n", ret); | 3711 | pr_err("kstrtoul() failed with ret: %d\n", ret); |
3712 | return -EINVAL; | 3712 | return -EINVAL; |
3713 | } | 3713 | } |
3714 | if (val > MAX_SRPT_RSP_SIZE) { | 3714 | if (val > MAX_SRPT_RSP_SIZE) { |
@@ -3746,9 +3746,9 @@ static ssize_t srpt_tpg_attrib_store_srp_sq_size( | |||
3746 | unsigned long val; | 3746 | unsigned long val; |
3747 | int ret; | 3747 | int ret; |
3748 | 3748 | ||
3749 | ret = strict_strtoul(page, 0, &val); | 3749 | ret = kstrtoul(page, 0, &val); |
3750 | if (ret < 0) { | 3750 | if (ret < 0) { |
3751 | pr_err("strict_strtoul() failed with ret: %d\n", ret); | 3751 | pr_err("kstrtoul() failed with ret: %d\n", ret); |
3752 | return -EINVAL; | 3752 | return -EINVAL; |
3753 | } | 3753 | } |
3754 | if (val > MAX_SRPT_SRQ_SIZE) { | 3754 | if (val > MAX_SRPT_SRQ_SIZE) { |
@@ -3793,7 +3793,7 @@ static ssize_t srpt_tpg_store_enable( | |||
3793 | unsigned long tmp; | 3793 | unsigned long tmp; |
3794 | int ret; | 3794 | int ret; |
3795 | 3795 | ||
3796 | ret = strict_strtoul(page, 0, &tmp); | 3796 | ret = kstrtoul(page, 0, &tmp); |
3797 | if (ret < 0) { | 3797 | if (ret < 0) { |
3798 | printk(KERN_ERR "Unable to extract srpt_tpg_store_enable\n"); | 3798 | printk(KERN_ERR "Unable to extract srpt_tpg_store_enable\n"); |
3799 | return -EINVAL; | 3799 | return -EINVAL; |
diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 7a04f54ef961..ef2e281b0a43 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c | |||
@@ -37,7 +37,6 @@ static void arizona_haptics_work(struct work_struct *work) | |||
37 | struct arizona_haptics, | 37 | struct arizona_haptics, |
38 | work); | 38 | work); |
39 | struct arizona *arizona = haptics->arizona; | 39 | struct arizona *arizona = haptics->arizona; |
40 | struct mutex *dapm_mutex = &arizona->dapm->card->dapm_mutex; | ||
41 | int ret; | 40 | int ret; |
42 | 41 | ||
43 | if (!haptics->arizona->dapm) { | 42 | if (!haptics->arizona->dapm) { |
@@ -67,13 +66,10 @@ static void arizona_haptics_work(struct work_struct *work) | |||
67 | return; | 66 | return; |
68 | } | 67 | } |
69 | 68 | ||
70 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
71 | |||
72 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); | 69 | ret = snd_soc_dapm_enable_pin(arizona->dapm, "HAPTICS"); |
73 | if (ret != 0) { | 70 | if (ret != 0) { |
74 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", | 71 | dev_err(arizona->dev, "Failed to start HAPTICS: %d\n", |
75 | ret); | 72 | ret); |
76 | mutex_unlock(dapm_mutex); | ||
77 | return; | 73 | return; |
78 | } | 74 | } |
79 | 75 | ||
@@ -81,21 +77,14 @@ static void arizona_haptics_work(struct work_struct *work) | |||
81 | if (ret != 0) { | 77 | if (ret != 0) { |
82 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 78 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
83 | ret); | 79 | ret); |
84 | mutex_unlock(dapm_mutex); | ||
85 | return; | 80 | return; |
86 | } | 81 | } |
87 | |||
88 | mutex_unlock(dapm_mutex); | ||
89 | |||
90 | } else { | 82 | } else { |
91 | /* This disable sequence will be a noop if already enabled */ | 83 | /* This disable sequence will be a noop if already enabled */ |
92 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
93 | |||
94 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); | 84 | ret = snd_soc_dapm_disable_pin(arizona->dapm, "HAPTICS"); |
95 | if (ret != 0) { | 85 | if (ret != 0) { |
96 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", | 86 | dev_err(arizona->dev, "Failed to disable HAPTICS: %d\n", |
97 | ret); | 87 | ret); |
98 | mutex_unlock(dapm_mutex); | ||
99 | return; | 88 | return; |
100 | } | 89 | } |
101 | 90 | ||
@@ -103,12 +92,9 @@ static void arizona_haptics_work(struct work_struct *work) | |||
103 | if (ret != 0) { | 92 | if (ret != 0) { |
104 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", | 93 | dev_err(arizona->dev, "Failed to sync DAPM: %d\n", |
105 | ret); | 94 | ret); |
106 | mutex_unlock(dapm_mutex); | ||
107 | return; | 95 | return; |
108 | } | 96 | } |
109 | 97 | ||
110 | mutex_unlock(dapm_mutex); | ||
111 | |||
112 | ret = regmap_update_bits(arizona->regmap, | 98 | ret = regmap_update_bits(arizona->regmap, |
113 | ARIZONA_HAPTICS_CONTROL_1, | 99 | ARIZONA_HAPTICS_CONTROL_1, |
114 | ARIZONA_HAP_CTRL_MASK, | 100 | ARIZONA_HAP_CTRL_MASK, |
@@ -155,16 +141,11 @@ static int arizona_haptics_play(struct input_dev *input, void *data, | |||
155 | static void arizona_haptics_close(struct input_dev *input) | 141 | static void arizona_haptics_close(struct input_dev *input) |
156 | { | 142 | { |
157 | struct arizona_haptics *haptics = input_get_drvdata(input); | 143 | struct arizona_haptics *haptics = input_get_drvdata(input); |
158 | struct mutex *dapm_mutex = &haptics->arizona->dapm->card->dapm_mutex; | ||
159 | 144 | ||
160 | cancel_work_sync(&haptics->work); | 145 | cancel_work_sync(&haptics->work); |
161 | 146 | ||
162 | mutex_lock_nested(dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | ||
163 | |||
164 | if (haptics->arizona->dapm) | 147 | if (haptics->arizona->dapm) |
165 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); | 148 | snd_soc_dapm_disable_pin(haptics->arizona->dapm, "HAPTICS"); |
166 | |||
167 | mutex_unlock(dapm_mutex); | ||
168 | } | 149 | } |
169 | 150 | ||
170 | static int arizona_haptics_probe(struct platform_device *pdev) | 151 | static int arizona_haptics_probe(struct platform_device *pdev) |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8911850c9444..1d9ab39af29f 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
@@ -79,7 +79,6 @@ | |||
79 | 79 | ||
80 | #define ARM_SMMU_PTE_CONT_SIZE (PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES) | 80 | #define ARM_SMMU_PTE_CONT_SIZE (PAGE_SIZE * ARM_SMMU_PTE_CONT_ENTRIES) |
81 | #define ARM_SMMU_PTE_CONT_MASK (~(ARM_SMMU_PTE_CONT_SIZE - 1)) | 81 | #define ARM_SMMU_PTE_CONT_MASK (~(ARM_SMMU_PTE_CONT_SIZE - 1)) |
82 | #define ARM_SMMU_PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t)) | ||
83 | 82 | ||
84 | /* Stage-1 PTE */ | 83 | /* Stage-1 PTE */ |
85 | #define ARM_SMMU_PTE_AP_UNPRIV (((pteval_t)1) << 6) | 84 | #define ARM_SMMU_PTE_AP_UNPRIV (((pteval_t)1) << 6) |
@@ -191,6 +190,9 @@ | |||
191 | #define ARM_SMMU_GR1_CBAR(n) (0x0 + ((n) << 2)) | 190 | #define ARM_SMMU_GR1_CBAR(n) (0x0 + ((n) << 2)) |
192 | #define CBAR_VMID_SHIFT 0 | 191 | #define CBAR_VMID_SHIFT 0 |
193 | #define CBAR_VMID_MASK 0xff | 192 | #define CBAR_VMID_MASK 0xff |
193 | #define CBAR_S1_BPSHCFG_SHIFT 8 | ||
194 | #define CBAR_S1_BPSHCFG_MASK 3 | ||
195 | #define CBAR_S1_BPSHCFG_NSH 3 | ||
194 | #define CBAR_S1_MEMATTR_SHIFT 12 | 196 | #define CBAR_S1_MEMATTR_SHIFT 12 |
195 | #define CBAR_S1_MEMATTR_MASK 0xf | 197 | #define CBAR_S1_MEMATTR_MASK 0xf |
196 | #define CBAR_S1_MEMATTR_WB 0xf | 198 | #define CBAR_S1_MEMATTR_WB 0xf |
@@ -393,7 +395,7 @@ struct arm_smmu_domain { | |||
393 | struct arm_smmu_cfg root_cfg; | 395 | struct arm_smmu_cfg root_cfg; |
394 | phys_addr_t output_mask; | 396 | phys_addr_t output_mask; |
395 | 397 | ||
396 | struct mutex lock; | 398 | spinlock_t lock; |
397 | }; | 399 | }; |
398 | 400 | ||
399 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); | 401 | static DEFINE_SPINLOCK(arm_smmu_devices_lock); |
@@ -632,6 +634,28 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev) | |||
632 | return IRQ_HANDLED; | 634 | return IRQ_HANDLED; |
633 | } | 635 | } |
634 | 636 | ||
637 | static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr, | ||
638 | size_t size) | ||
639 | { | ||
640 | unsigned long offset = (unsigned long)addr & ~PAGE_MASK; | ||
641 | |||
642 | |||
643 | /* Ensure new page tables are visible to the hardware walker */ | ||
644 | if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) { | ||
645 | dsb(); | ||
646 | } else { | ||
647 | /* | ||
648 | * If the SMMU can't walk tables in the CPU caches, treat them | ||
649 | * like non-coherent DMA since we need to flush the new entries | ||
650 | * all the way out to memory. There's no possibility of | ||
651 | * recursion here as the SMMU table walker will not be wired | ||
652 | * through another SMMU. | ||
653 | */ | ||
654 | dma_map_page(smmu->dev, virt_to_page(addr), offset, size, | ||
655 | DMA_TO_DEVICE); | ||
656 | } | ||
657 | } | ||
658 | |||
635 | static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | 659 | static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) |
636 | { | 660 | { |
637 | u32 reg; | 661 | u32 reg; |
@@ -650,11 +674,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
650 | if (smmu->version == 1) | 674 | if (smmu->version == 1) |
651 | reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT; | 675 | reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT; |
652 | 676 | ||
653 | /* Use the weakest memory type, so it is overridden by the pte */ | 677 | /* |
654 | if (stage1) | 678 | * Use the weakest shareability/memory types, so they are |
655 | reg |= (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | 679 | * overridden by the ttbcr/pte. |
656 | else | 680 | */ |
681 | if (stage1) { | ||
682 | reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | | ||
683 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | ||
684 | } else { | ||
657 | reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT; | 685 | reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT; |
686 | } | ||
658 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx)); | 687 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx)); |
659 | 688 | ||
660 | if (smmu->version > 1) { | 689 | if (smmu->version > 1) { |
@@ -715,6 +744,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
715 | } | 744 | } |
716 | 745 | ||
717 | /* TTBR0 */ | 746 | /* TTBR0 */ |
747 | arm_smmu_flush_pgtable(smmu, root_cfg->pgd, | ||
748 | PTRS_PER_PGD * sizeof(pgd_t)); | ||
718 | reg = __pa(root_cfg->pgd); | 749 | reg = __pa(root_cfg->pgd); |
719 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); | 750 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); |
720 | reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32; | 751 | reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32; |
@@ -901,7 +932,7 @@ static int arm_smmu_domain_init(struct iommu_domain *domain) | |||
901 | goto out_free_domain; | 932 | goto out_free_domain; |
902 | smmu_domain->root_cfg.pgd = pgd; | 933 | smmu_domain->root_cfg.pgd = pgd; |
903 | 934 | ||
904 | mutex_init(&smmu_domain->lock); | 935 | spin_lock_init(&smmu_domain->lock); |
905 | domain->priv = smmu_domain; | 936 | domain->priv = smmu_domain; |
906 | return 0; | 937 | return 0; |
907 | 938 | ||
@@ -1128,6 +1159,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1128 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1159 | struct arm_smmu_domain *smmu_domain = domain->priv; |
1129 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; | 1160 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; |
1130 | struct arm_smmu_master *master; | 1161 | struct arm_smmu_master *master; |
1162 | unsigned long flags; | ||
1131 | 1163 | ||
1132 | if (!device_smmu) { | 1164 | if (!device_smmu) { |
1133 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); | 1165 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); |
@@ -1138,7 +1170,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1138 | * Sanity check the domain. We don't currently support domains | 1170 | * Sanity check the domain. We don't currently support domains |
1139 | * that cross between different SMMU chains. | 1171 | * that cross between different SMMU chains. |
1140 | */ | 1172 | */ |
1141 | mutex_lock(&smmu_domain->lock); | 1173 | spin_lock_irqsave(&smmu_domain->lock, flags); |
1142 | if (!smmu_domain->leaf_smmu) { | 1174 | if (!smmu_domain->leaf_smmu) { |
1143 | /* Now that we have a master, we can finalise the domain */ | 1175 | /* Now that we have a master, we can finalise the domain */ |
1144 | ret = arm_smmu_init_domain_context(domain, dev); | 1176 | ret = arm_smmu_init_domain_context(domain, dev); |
@@ -1153,7 +1185,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1153 | dev_name(device_smmu->dev)); | 1185 | dev_name(device_smmu->dev)); |
1154 | goto err_unlock; | 1186 | goto err_unlock; |
1155 | } | 1187 | } |
1156 | mutex_unlock(&smmu_domain->lock); | 1188 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
1157 | 1189 | ||
1158 | /* Looks ok, so add the device to the domain */ | 1190 | /* Looks ok, so add the device to the domain */ |
1159 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1191 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); |
@@ -1163,7 +1195,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
1163 | return arm_smmu_domain_add_master(smmu_domain, master); | 1195 | return arm_smmu_domain_add_master(smmu_domain, master); |
1164 | 1196 | ||
1165 | err_unlock: | 1197 | err_unlock: |
1166 | mutex_unlock(&smmu_domain->lock); | 1198 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
1167 | return ret; | 1199 | return ret; |
1168 | } | 1200 | } |
1169 | 1201 | ||
@@ -1177,23 +1209,6 @@ static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | |||
1177 | arm_smmu_domain_remove_master(smmu_domain, master); | 1209 | arm_smmu_domain_remove_master(smmu_domain, master); |
1178 | } | 1210 | } |
1179 | 1211 | ||
1180 | static void arm_smmu_flush_pgtable(struct arm_smmu_device *smmu, void *addr, | ||
1181 | size_t size) | ||
1182 | { | ||
1183 | unsigned long offset = (unsigned long)addr & ~PAGE_MASK; | ||
1184 | |||
1185 | /* | ||
1186 | * If the SMMU can't walk tables in the CPU caches, treat them | ||
1187 | * like non-coherent DMA since we need to flush the new entries | ||
1188 | * all the way out to memory. There's no possibility of recursion | ||
1189 | * here as the SMMU table walker will not be wired through another | ||
1190 | * SMMU. | ||
1191 | */ | ||
1192 | if (!(smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)) | ||
1193 | dma_map_page(smmu->dev, virt_to_page(addr), offset, size, | ||
1194 | DMA_TO_DEVICE); | ||
1195 | } | ||
1196 | |||
1197 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, | 1212 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, |
1198 | unsigned long end) | 1213 | unsigned long end) |
1199 | { | 1214 | { |
@@ -1210,12 +1225,11 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
1210 | 1225 | ||
1211 | if (pmd_none(*pmd)) { | 1226 | if (pmd_none(*pmd)) { |
1212 | /* Allocate a new set of tables */ | 1227 | /* Allocate a new set of tables */ |
1213 | pgtable_t table = alloc_page(PGALLOC_GFP); | 1228 | pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO); |
1214 | if (!table) | 1229 | if (!table) |
1215 | return -ENOMEM; | 1230 | return -ENOMEM; |
1216 | 1231 | ||
1217 | arm_smmu_flush_pgtable(smmu, page_address(table), | 1232 | arm_smmu_flush_pgtable(smmu, page_address(table), PAGE_SIZE); |
1218 | ARM_SMMU_PTE_HWTABLE_SIZE); | ||
1219 | if (!pgtable_page_ctor(table)) { | 1233 | if (!pgtable_page_ctor(table)) { |
1220 | __free_page(table); | 1234 | __free_page(table); |
1221 | return -ENOMEM; | 1235 | return -ENOMEM; |
@@ -1317,9 +1331,15 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, | |||
1317 | 1331 | ||
1318 | #ifndef __PAGETABLE_PMD_FOLDED | 1332 | #ifndef __PAGETABLE_PMD_FOLDED |
1319 | if (pud_none(*pud)) { | 1333 | if (pud_none(*pud)) { |
1320 | pmd = pmd_alloc_one(NULL, addr); | 1334 | pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); |
1321 | if (!pmd) | 1335 | if (!pmd) |
1322 | return -ENOMEM; | 1336 | return -ENOMEM; |
1337 | |||
1338 | arm_smmu_flush_pgtable(smmu, pmd, PAGE_SIZE); | ||
1339 | pud_populate(NULL, pud, pmd); | ||
1340 | arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud)); | ||
1341 | |||
1342 | pmd += pmd_index(addr); | ||
1323 | } else | 1343 | } else |
1324 | #endif | 1344 | #endif |
1325 | pmd = pmd_offset(pud, addr); | 1345 | pmd = pmd_offset(pud, addr); |
@@ -1328,8 +1348,6 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, | |||
1328 | next = pmd_addr_end(addr, end); | 1348 | next = pmd_addr_end(addr, end); |
1329 | ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, | 1349 | ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, |
1330 | flags, stage); | 1350 | flags, stage); |
1331 | pud_populate(NULL, pud, pmd); | ||
1332 | arm_smmu_flush_pgtable(smmu, pud, sizeof(*pud)); | ||
1333 | phys += next - addr; | 1351 | phys += next - addr; |
1334 | } while (pmd++, addr = next, addr < end); | 1352 | } while (pmd++, addr = next, addr < end); |
1335 | 1353 | ||
@@ -1346,9 +1364,15 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd, | |||
1346 | 1364 | ||
1347 | #ifndef __PAGETABLE_PUD_FOLDED | 1365 | #ifndef __PAGETABLE_PUD_FOLDED |
1348 | if (pgd_none(*pgd)) { | 1366 | if (pgd_none(*pgd)) { |
1349 | pud = pud_alloc_one(NULL, addr); | 1367 | pud = (pud_t *)get_zeroed_page(GFP_ATOMIC); |
1350 | if (!pud) | 1368 | if (!pud) |
1351 | return -ENOMEM; | 1369 | return -ENOMEM; |
1370 | |||
1371 | arm_smmu_flush_pgtable(smmu, pud, PAGE_SIZE); | ||
1372 | pgd_populate(NULL, pgd, pud); | ||
1373 | arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd)); | ||
1374 | |||
1375 | pud += pud_index(addr); | ||
1352 | } else | 1376 | } else |
1353 | #endif | 1377 | #endif |
1354 | pud = pud_offset(pgd, addr); | 1378 | pud = pud_offset(pgd, addr); |
@@ -1357,8 +1381,6 @@ static int arm_smmu_alloc_init_pud(struct arm_smmu_device *smmu, pgd_t *pgd, | |||
1357 | next = pud_addr_end(addr, end); | 1381 | next = pud_addr_end(addr, end); |
1358 | ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys, | 1382 | ret = arm_smmu_alloc_init_pmd(smmu, pud, addr, next, phys, |
1359 | flags, stage); | 1383 | flags, stage); |
1360 | pgd_populate(NULL, pud, pgd); | ||
1361 | arm_smmu_flush_pgtable(smmu, pgd, sizeof(*pgd)); | ||
1362 | phys += next - addr; | 1384 | phys += next - addr; |
1363 | } while (pud++, addr = next, addr < end); | 1385 | } while (pud++, addr = next, addr < end); |
1364 | 1386 | ||
@@ -1375,6 +1397,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1375 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 1397 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; |
1376 | pgd_t *pgd = root_cfg->pgd; | 1398 | pgd_t *pgd = root_cfg->pgd; |
1377 | struct arm_smmu_device *smmu = root_cfg->smmu; | 1399 | struct arm_smmu_device *smmu = root_cfg->smmu; |
1400 | unsigned long irqflags; | ||
1378 | 1401 | ||
1379 | if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { | 1402 | if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { |
1380 | stage = 2; | 1403 | stage = 2; |
@@ -1397,7 +1420,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1397 | if (paddr & ~output_mask) | 1420 | if (paddr & ~output_mask) |
1398 | return -ERANGE; | 1421 | return -ERANGE; |
1399 | 1422 | ||
1400 | mutex_lock(&smmu_domain->lock); | 1423 | spin_lock_irqsave(&smmu_domain->lock, irqflags); |
1401 | pgd += pgd_index(iova); | 1424 | pgd += pgd_index(iova); |
1402 | end = iova + size; | 1425 | end = iova + size; |
1403 | do { | 1426 | do { |
@@ -1413,11 +1436,7 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
1413 | } while (pgd++, iova != end); | 1436 | } while (pgd++, iova != end); |
1414 | 1437 | ||
1415 | out_unlock: | 1438 | out_unlock: |
1416 | mutex_unlock(&smmu_domain->lock); | 1439 | spin_unlock_irqrestore(&smmu_domain->lock, irqflags); |
1417 | |||
1418 | /* Ensure new page tables are visible to the hardware walker */ | ||
1419 | if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) | ||
1420 | dsb(); | ||
1421 | 1440 | ||
1422 | return ret; | 1441 | return ret; |
1423 | } | 1442 | } |
@@ -1987,8 +2006,10 @@ static int __init arm_smmu_init(void) | |||
1987 | if (!iommu_present(&platform_bus_type)) | 2006 | if (!iommu_present(&platform_bus_type)) |
1988 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); | 2007 | bus_set_iommu(&platform_bus_type, &arm_smmu_ops); |
1989 | 2008 | ||
2009 | #ifdef CONFIG_ARM_AMBA | ||
1990 | if (!iommu_present(&amba_bustype)) | 2010 | if (!iommu_present(&amba_bustype)) |
1991 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); | 2011 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); |
2012 | #endif | ||
1992 | 2013 | ||
1993 | return 0; | 2014 | return 0; |
1994 | } | 2015 | } |
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index d97fbe4fb9b1..80fffba7f12d 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c | |||
@@ -354,8 +354,8 @@ DEBUG_FOPS(mem); | |||
354 | return -ENOMEM; \ | 354 | return -ENOMEM; \ |
355 | } | 355 | } |
356 | 356 | ||
357 | #define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 600) | 357 | #define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 0600) |
358 | #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 400) | 358 | #define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 0400) |
359 | 359 | ||
360 | static int iommu_debug_register(struct device *dev, void *data) | 360 | static int iommu_debug_register(struct device *dev, void *data) |
361 | { | 361 | { |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 86b484cb3ec2..5194afb39e78 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
@@ -21,6 +21,7 @@ obj-$(CONFIG_SIRF_IRQ) += irq-sirfsoc.o | |||
21 | obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o | 21 | obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o |
22 | obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o | 22 | obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o |
23 | obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o | 23 | obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o |
24 | obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o | ||
24 | obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o | 25 | obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o |
25 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o | 26 | obj-$(CONFIG_TB10X_IRQC) += irq-tb10x.o |
26 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o | 27 | obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o |
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 9300bc32784e..540956465ed2 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c | |||
@@ -381,7 +381,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
381 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | 381 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) |
382 | & PCI_MSI_DOORBELL_MASK; | 382 | & PCI_MSI_DOORBELL_MASK; |
383 | 383 | ||
384 | writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base + | 384 | writel(~msimask, per_cpu_int_base + |
385 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | 385 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); |
386 | 386 | ||
387 | for (msinr = PCI_MSI_DOORBELL_START; | 387 | for (msinr = PCI_MSI_DOORBELL_START; |
@@ -407,7 +407,7 @@ armada_370_xp_handle_irq(struct pt_regs *regs) | |||
407 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) | 407 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) |
408 | & IPI_DOORBELL_MASK; | 408 | & IPI_DOORBELL_MASK; |
409 | 409 | ||
410 | writel(~IPI_DOORBELL_MASK, per_cpu_int_base + | 410 | writel(~ipimask, per_cpu_int_base + |
411 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); | 411 | ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); |
412 | 412 | ||
413 | /* Handle all pending doorbells */ | 413 | /* Handle all pending doorbells */ |
diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c index 92c41ab4dbfd..2cb474ad8809 100644 --- a/drivers/irqchip/irq-metag-ext.c +++ b/drivers/irqchip/irq-metag-ext.c | |||
@@ -515,7 +515,7 @@ static int meta_intc_set_affinity(struct irq_data *data, | |||
515 | * one cpu (the interrupt code doesn't support it), so we just | 515 | * one cpu (the interrupt code doesn't support it), so we just |
516 | * pick the first cpu we find in 'cpumask'. | 516 | * pick the first cpu we find in 'cpumask'. |
517 | */ | 517 | */ |
518 | cpu = cpumask_any(cpumask); | 518 | cpu = cpumask_any_and(cpumask, cpu_online_mask); |
519 | thread = cpu_2_hwthread_id[cpu]; | 519 | thread = cpu_2_hwthread_id[cpu]; |
520 | 520 | ||
521 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); | 521 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); |
diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c index 8e94d7a3b20d..c16c186d97d3 100644 --- a/drivers/irqchip/irq-metag.c +++ b/drivers/irqchip/irq-metag.c | |||
@@ -201,7 +201,7 @@ static int metag_internal_irq_set_affinity(struct irq_data *data, | |||
201 | * one cpu (the interrupt code doesn't support it), so we just | 201 | * one cpu (the interrupt code doesn't support it), so we just |
202 | * pick the first cpu we find in 'cpumask'. | 202 | * pick the first cpu we find in 'cpumask'. |
203 | */ | 203 | */ |
204 | cpu = cpumask_any(cpumask); | 204 | cpu = cpumask_any_and(cpumask, cpu_online_mask); |
205 | thread = cpu_2_hwthread_id[cpu]; | 205 | thread = cpu_2_hwthread_id[cpu]; |
206 | 206 | ||
207 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), | 207 | metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), |
diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index e51d40031884..8e41be62812e 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c | |||
@@ -111,7 +111,8 @@ IRQCHIP_DECLARE(orion_intc, "marvell,orion-intc", orion_irq_init); | |||
111 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) | 111 | static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) |
112 | { | 112 | { |
113 | struct irq_domain *d = irq_get_handler_data(irq); | 113 | struct irq_domain *d = irq_get_handler_data(irq); |
114 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, irq); | 114 | |
115 | struct irq_chip_generic *gc = irq_get_domain_generic_chip(d, 0); | ||
115 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & | 116 | u32 stat = readl_relaxed(gc->reg_base + ORION_BRIDGE_IRQ_CAUSE) & |
116 | gc->mask_cache; | 117 | gc->mask_cache; |
117 | 118 | ||
@@ -123,6 +124,19 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
123 | } | 124 | } |
124 | } | 125 | } |
125 | 126 | ||
127 | /* | ||
128 | * Bridge IRQ_CAUSE is asserted regardless of IRQ_MASK register. | ||
129 | * To avoid interrupt events on stale irqs, we clear them before unmask. | ||
130 | */ | ||
131 | static unsigned int orion_bridge_irq_startup(struct irq_data *d) | ||
132 | { | ||
133 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | ||
134 | |||
135 | ct->chip.irq_ack(d); | ||
136 | ct->chip.irq_unmask(d); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
126 | static int __init orion_bridge_irq_init(struct device_node *np, | 140 | static int __init orion_bridge_irq_init(struct device_node *np, |
127 | struct device_node *parent) | 141 | struct device_node *parent) |
128 | { | 142 | { |
@@ -143,7 +157,7 @@ static int __init orion_bridge_irq_init(struct device_node *np, | |||
143 | } | 157 | } |
144 | 158 | ||
145 | ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, | 159 | ret = irq_alloc_domain_generic_chips(domain, nrirqs, 1, np->name, |
146 | handle_level_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); | 160 | handle_edge_irq, clr, 0, IRQ_GC_INIT_MASK_CACHE); |
147 | if (ret) { | 161 | if (ret) { |
148 | pr_err("%s: unable to alloc irq domain gc\n", np->name); | 162 | pr_err("%s: unable to alloc irq domain gc\n", np->name); |
149 | return ret; | 163 | return ret; |
@@ -176,12 +190,14 @@ static int __init orion_bridge_irq_init(struct device_node *np, | |||
176 | 190 | ||
177 | gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; | 191 | gc->chip_types[0].regs.ack = ORION_BRIDGE_IRQ_CAUSE; |
178 | gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; | 192 | gc->chip_types[0].regs.mask = ORION_BRIDGE_IRQ_MASK; |
193 | gc->chip_types[0].chip.irq_startup = orion_bridge_irq_startup; | ||
179 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; | 194 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_clr_bit; |
180 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | 195 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; |
181 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | 196 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; |
182 | 197 | ||
183 | /* mask all interrupts */ | 198 | /* mask and clear all interrupts */ |
184 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); | 199 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_MASK); |
200 | writel(0, gc->reg_base + ORION_BRIDGE_IRQ_CAUSE); | ||
185 | 201 | ||
186 | irq_set_handler_data(irq, domain); | 202 | irq_set_handler_data(irq, domain); |
187 | irq_set_chained_handler(irq, orion_bridge_irq_handler); | 203 | irq_set_chained_handler(irq, orion_bridge_irq_handler); |
diff --git a/drivers/irqchip/irq-zevio.c b/drivers/irqchip/irq-zevio.c new file mode 100644 index 000000000000..8ed04c4a43ee --- /dev/null +++ b/drivers/irqchip/irq-zevio.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * linux/drivers/irqchip/irq-zevio.c | ||
3 | * | ||
4 | * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/io.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | |||
18 | #include <asm/mach/irq.h> | ||
19 | #include <asm/exception.h> | ||
20 | |||
21 | #include "irqchip.h" | ||
22 | |||
23 | #define IO_STATUS 0x000 | ||
24 | #define IO_RAW_STATUS 0x004 | ||
25 | #define IO_ENABLE 0x008 | ||
26 | #define IO_DISABLE 0x00C | ||
27 | #define IO_CURRENT 0x020 | ||
28 | #define IO_RESET 0x028 | ||
29 | #define IO_MAX_PRIOTY 0x02C | ||
30 | |||
31 | #define IO_IRQ_BASE 0x000 | ||
32 | #define IO_FIQ_BASE 0x100 | ||
33 | |||
34 | #define IO_INVERT_SEL 0x200 | ||
35 | #define IO_STICKY_SEL 0x204 | ||
36 | #define IO_PRIORITY_SEL 0x300 | ||
37 | |||
38 | #define MAX_INTRS 32 | ||
39 | #define FIQ_START MAX_INTRS | ||
40 | |||
41 | static struct irq_domain *zevio_irq_domain; | ||
42 | static void __iomem *zevio_irq_io; | ||
43 | |||
44 | static void zevio_irq_ack(struct irq_data *irqd) | ||
45 | { | ||
46 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(irqd); | ||
47 | struct irq_chip_regs *regs = | ||
48 | &container_of(irqd->chip, struct irq_chip_type, chip)->regs; | ||
49 | |||
50 | readl(gc->reg_base + regs->ack); | ||
51 | } | ||
52 | |||
53 | static asmlinkage void __exception_irq_entry zevio_handle_irq(struct pt_regs *regs) | ||
54 | { | ||
55 | int irqnr; | ||
56 | |||
57 | while (readl(zevio_irq_io + IO_STATUS)) { | ||
58 | irqnr = readl(zevio_irq_io + IO_CURRENT); | ||
59 | irqnr = irq_find_mapping(zevio_irq_domain, irqnr); | ||
60 | handle_IRQ(irqnr, regs); | ||
61 | }; | ||
62 | } | ||
63 | |||
64 | static void __init zevio_init_irq_base(void __iomem *base) | ||
65 | { | ||
66 | /* Disable all interrupts */ | ||
67 | writel(~0, base + IO_DISABLE); | ||
68 | |||
69 | /* Accept interrupts of all priorities */ | ||
70 | writel(0xF, base + IO_MAX_PRIOTY); | ||
71 | |||
72 | /* Reset existing interrupts */ | ||
73 | readl(base + IO_RESET); | ||
74 | } | ||
75 | |||
76 | static int __init zevio_of_init(struct device_node *node, | ||
77 | struct device_node *parent) | ||
78 | { | ||
79 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
80 | struct irq_chip_generic *gc; | ||
81 | int ret; | ||
82 | |||
83 | if (WARN_ON(zevio_irq_io || zevio_irq_domain)) | ||
84 | return -EBUSY; | ||
85 | |||
86 | zevio_irq_io = of_iomap(node, 0); | ||
87 | BUG_ON(!zevio_irq_io); | ||
88 | |||
89 | /* Do not invert interrupt status bits */ | ||
90 | writel(~0, zevio_irq_io + IO_INVERT_SEL); | ||
91 | |||
92 | /* Disable sticky interrupts */ | ||
93 | writel(0, zevio_irq_io + IO_STICKY_SEL); | ||
94 | |||
95 | /* We don't use IRQ priorities. Set each IRQ to highest priority. */ | ||
96 | memset_io(zevio_irq_io + IO_PRIORITY_SEL, 0, MAX_INTRS * sizeof(u32)); | ||
97 | |||
98 | /* Init IRQ and FIQ */ | ||
99 | zevio_init_irq_base(zevio_irq_io + IO_IRQ_BASE); | ||
100 | zevio_init_irq_base(zevio_irq_io + IO_FIQ_BASE); | ||
101 | |||
102 | zevio_irq_domain = irq_domain_add_linear(node, MAX_INTRS, | ||
103 | &irq_generic_chip_ops, NULL); | ||
104 | BUG_ON(!zevio_irq_domain); | ||
105 | |||
106 | ret = irq_alloc_domain_generic_chips(zevio_irq_domain, MAX_INTRS, 1, | ||
107 | "zevio_intc", handle_level_irq, | ||
108 | clr, 0, IRQ_GC_INIT_MASK_CACHE); | ||
109 | BUG_ON(ret); | ||
110 | |||
111 | gc = irq_get_domain_generic_chip(zevio_irq_domain, 0); | ||
112 | gc->reg_base = zevio_irq_io; | ||
113 | gc->chip_types[0].chip.irq_ack = zevio_irq_ack; | ||
114 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; | ||
115 | gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; | ||
116 | gc->chip_types[0].regs.mask = IO_IRQ_BASE + IO_ENABLE; | ||
117 | gc->chip_types[0].regs.enable = IO_IRQ_BASE + IO_ENABLE; | ||
118 | gc->chip_types[0].regs.disable = IO_IRQ_BASE + IO_DISABLE; | ||
119 | gc->chip_types[0].regs.ack = IO_IRQ_BASE + IO_RESET; | ||
120 | |||
121 | set_handle_irq(zevio_handle_irq); | ||
122 | |||
123 | pr_info("TI-NSPIRE classic IRQ controller\n"); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | IRQCHIP_DECLARE(zevio_irq, "lsi,zevio-intc", zevio_of_init); | ||
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index f04686580040..9816c51eb5c2 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig | |||
@@ -16,9 +16,17 @@ config CAPI_TRACE | |||
16 | This will increase the size of the kernelcapi module by 20 KB. | 16 | This will increase the size of the kernelcapi module by 20 KB. |
17 | If unsure, say Y. | 17 | If unsure, say Y. |
18 | 18 | ||
19 | config ISDN_CAPI_CAPI20 | ||
20 | tristate "CAPI2.0 /dev/capi support" | ||
21 | help | ||
22 | This option will provide the CAPI 2.0 interface to userspace | ||
23 | applications via /dev/capi20. Applications should use the | ||
24 | standardized libcapi20 to access this functionality. You should say | ||
25 | Y/M here. | ||
26 | |||
19 | config ISDN_CAPI_MIDDLEWARE | 27 | config ISDN_CAPI_MIDDLEWARE |
20 | bool "CAPI2.0 Middleware support" | 28 | bool "CAPI2.0 Middleware support" |
21 | depends on TTY | 29 | depends on ISDN_CAPI_CAPI20 && TTY |
22 | help | 30 | help |
23 | This option will enhance the capabilities of the /dev/capi20 | 31 | This option will enhance the capabilities of the /dev/capi20 |
24 | interface. It will provide a means of moving a data connection, | 32 | interface. It will provide a means of moving a data connection, |
@@ -26,14 +34,6 @@ config ISDN_CAPI_MIDDLEWARE | |||
26 | device. If you want to use pppd with pppdcapiplugin to dial up to | 34 | device. If you want to use pppd with pppdcapiplugin to dial up to |
27 | your ISP, say Y here. | 35 | your ISP, say Y here. |
28 | 36 | ||
29 | config ISDN_CAPI_CAPI20 | ||
30 | tristate "CAPI2.0 /dev/capi support" | ||
31 | help | ||
32 | This option will provide the CAPI 2.0 interface to userspace | ||
33 | applications via /dev/capi20. Applications should use the | ||
34 | standardized libcapi20 to access this functionality. You should say | ||
35 | Y/M here. | ||
36 | |||
37 | config ISDN_CAPI_CAPIDRV | 37 | config ISDN_CAPI_CAPIDRV |
38 | tristate "CAPI2.0 capidrv interface support" | 38 | tristate "CAPI2.0 capidrv interface support" |
39 | depends on ISDN_I4L | 39 | depends on ISDN_I4L |
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index af1b020a81f1..b420f8bd862e 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c | |||
@@ -810,7 +810,7 @@ prfeatureind(char *dest, u_char *p) | |||
810 | dp += sprintf(dp, " octet 3 "); | 810 | dp += sprintf(dp, " octet 3 "); |
811 | dp += prbits(dp, *p, 8, 8); | 811 | dp += prbits(dp, *p, 8, 8); |
812 | *dp++ = '\n'; | 812 | *dp++ = '\n'; |
813 | if (!(*p++ & 80)) { | 813 | if (!(*p++ & 0x80)) { |
814 | dp += sprintf(dp, " octet 4 "); | 814 | dp += sprintf(dp, " octet 4 "); |
815 | dp += prbits(dp, *p++, 8, 8); | 815 | dp += prbits(dp, *p++, 8, 8); |
816 | *dp++ = '\n'; | 816 | *dp++ = '\n'; |
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 9a06fe883766..95ad936e6048 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -254,16 +254,6 @@ config DM_THIN_PROVISIONING | |||
254 | ---help--- | 254 | ---help--- |
255 | Provides thin provisioning and snapshots that share a data store. | 255 | Provides thin provisioning and snapshots that share a data store. |
256 | 256 | ||
257 | config DM_DEBUG_BLOCK_STACK_TRACING | ||
258 | boolean "Keep stack trace of persistent data block lock holders" | ||
259 | depends on STACKTRACE_SUPPORT && DM_PERSISTENT_DATA | ||
260 | select STACKTRACE | ||
261 | ---help--- | ||
262 | Enable this for messages that may help debug problems with the | ||
263 | block manager locking used by thin provisioning and caching. | ||
264 | |||
265 | If unsure, say N. | ||
266 | |||
267 | config DM_CACHE | 257 | config DM_CACHE |
268 | tristate "Cache target (EXPERIMENTAL)" | 258 | tristate "Cache target (EXPERIMENTAL)" |
269 | depends on BLK_DEV_DM | 259 | depends on BLK_DEV_DM |
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 0c707e4f4eaf..a4c7306ff43d 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h | |||
@@ -210,7 +210,9 @@ BITMASK(GC_MARK, struct bucket, gc_mark, 0, 2); | |||
210 | #define GC_MARK_RECLAIMABLE 0 | 210 | #define GC_MARK_RECLAIMABLE 0 |
211 | #define GC_MARK_DIRTY 1 | 211 | #define GC_MARK_DIRTY 1 |
212 | #define GC_MARK_METADATA 2 | 212 | #define GC_MARK_METADATA 2 |
213 | BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, 13); | 213 | #define GC_SECTORS_USED_SIZE 13 |
214 | #define MAX_GC_SECTORS_USED (~(~0ULL << GC_SECTORS_USED_SIZE)) | ||
215 | BITMASK(GC_SECTORS_USED, struct bucket, gc_mark, 2, GC_SECTORS_USED_SIZE); | ||
214 | BITMASK(GC_MOVE, struct bucket, gc_mark, 15, 1); | 216 | BITMASK(GC_MOVE, struct bucket, gc_mark, 15, 1); |
215 | 217 | ||
216 | #include "journal.h" | 218 | #include "journal.h" |
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 4f6b5940e609..3f74b4b0747b 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c | |||
@@ -23,7 +23,7 @@ void bch_dump_bset(struct btree_keys *b, struct bset *i, unsigned set) | |||
23 | for (k = i->start; k < bset_bkey_last(i); k = next) { | 23 | for (k = i->start; k < bset_bkey_last(i); k = next) { |
24 | next = bkey_next(k); | 24 | next = bkey_next(k); |
25 | 25 | ||
26 | printk(KERN_ERR "block %u key %zi/%u: ", set, | 26 | printk(KERN_ERR "block %u key %li/%u: ", set, |
27 | (uint64_t *) k - i->d, i->keys); | 27 | (uint64_t *) k - i->d, i->keys); |
28 | 28 | ||
29 | if (b->ops->key_dump) | 29 | if (b->ops->key_dump) |
@@ -1185,9 +1185,12 @@ static void __btree_sort(struct btree_keys *b, struct btree_iter *iter, | |||
1185 | struct bset *out = (void *) __get_free_pages(__GFP_NOWARN|GFP_NOIO, | 1185 | struct bset *out = (void *) __get_free_pages(__GFP_NOWARN|GFP_NOIO, |
1186 | order); | 1186 | order); |
1187 | if (!out) { | 1187 | if (!out) { |
1188 | struct page *outp; | ||
1189 | |||
1188 | BUG_ON(order > state->page_order); | 1190 | BUG_ON(order > state->page_order); |
1189 | 1191 | ||
1190 | out = page_address(mempool_alloc(state->pool, GFP_NOIO)); | 1192 | outp = mempool_alloc(state->pool, GFP_NOIO); |
1193 | out = page_address(outp); | ||
1191 | used_mempool = true; | 1194 | used_mempool = true; |
1192 | order = state->page_order; | 1195 | order = state->page_order; |
1193 | } | 1196 | } |
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 98cc0a810a36..5f9c2a665ca5 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -1167,7 +1167,7 @@ uint8_t __bch_btree_mark_key(struct cache_set *c, int level, struct bkey *k) | |||
1167 | /* guard against overflow */ | 1167 | /* guard against overflow */ |
1168 | SET_GC_SECTORS_USED(g, min_t(unsigned, | 1168 | SET_GC_SECTORS_USED(g, min_t(unsigned, |
1169 | GC_SECTORS_USED(g) + KEY_SIZE(k), | 1169 | GC_SECTORS_USED(g) + KEY_SIZE(k), |
1170 | (1 << 14) - 1)); | 1170 | MAX_GC_SECTORS_USED)); |
1171 | 1171 | ||
1172 | BUG_ON(!GC_SECTORS_USED(g)); | 1172 | BUG_ON(!GC_SECTORS_USED(g)); |
1173 | } | 1173 | } |
@@ -1805,7 +1805,7 @@ static bool btree_insert_key(struct btree *b, struct bkey *k, | |||
1805 | 1805 | ||
1806 | static size_t insert_u64s_remaining(struct btree *b) | 1806 | static size_t insert_u64s_remaining(struct btree *b) |
1807 | { | 1807 | { |
1808 | ssize_t ret = bch_btree_keys_u64s_remaining(&b->keys); | 1808 | long ret = bch_btree_keys_u64s_remaining(&b->keys); |
1809 | 1809 | ||
1810 | /* | 1810 | /* |
1811 | * Might land in the middle of an existing extent and have to split it | 1811 | * Might land in the middle of an existing extent and have to split it |
diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c index c3ead586dc27..416d1a3e028e 100644 --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c | |||
@@ -194,7 +194,7 @@ err: | |||
194 | mutex_unlock(&b->c->bucket_lock); | 194 | mutex_unlock(&b->c->bucket_lock); |
195 | bch_extent_to_text(buf, sizeof(buf), k); | 195 | bch_extent_to_text(buf, sizeof(buf), k); |
196 | btree_bug(b, | 196 | btree_bug(b, |
197 | "inconsistent btree pointer %s: bucket %li pin %i prio %i gen %i last_gc %i mark %llu gc_gen %i", | 197 | "inconsistent btree pointer %s: bucket %zi pin %i prio %i gen %i last_gc %i mark %llu gc_gen %i", |
198 | buf, PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin), | 198 | buf, PTR_BUCKET_NR(b->c, k, i), atomic_read(&g->pin), |
199 | g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen); | 199 | g->prio, g->gen, g->last_gc, GC_MARK(g), g->gc_gen); |
200 | return true; | 200 | return true; |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 72cd213f213f..5d5d031cf381 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -353,14 +353,14 @@ static void bch_data_insert_start(struct closure *cl) | |||
353 | struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | 353 | struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); |
354 | struct bio *bio = op->bio, *n; | 354 | struct bio *bio = op->bio, *n; |
355 | 355 | ||
356 | if (op->bypass) | ||
357 | return bch_data_invalidate(cl); | ||
358 | |||
359 | if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) { | 356 | if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) { |
360 | set_gc_sectors(op->c); | 357 | set_gc_sectors(op->c); |
361 | wake_up_gc(op->c); | 358 | wake_up_gc(op->c); |
362 | } | 359 | } |
363 | 360 | ||
361 | if (op->bypass) | ||
362 | return bch_data_invalidate(cl); | ||
363 | |||
364 | /* | 364 | /* |
365 | * Journal writes are marked REQ_FLUSH; if the original write was a | 365 | * Journal writes are marked REQ_FLUSH; if the original write was a |
366 | * flush, it'll wait on the journal write. | 366 | * flush, it'll wait on the journal write. |
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index c6ab69333a6d..d8458d477a12 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c | |||
@@ -416,7 +416,7 @@ static int btree_bset_stats(struct btree_op *b_op, struct btree *b) | |||
416 | return MAP_CONTINUE; | 416 | return MAP_CONTINUE; |
417 | } | 417 | } |
418 | 418 | ||
419 | int bch_bset_print_stats(struct cache_set *c, char *buf) | 419 | static int bch_bset_print_stats(struct cache_set *c, char *buf) |
420 | { | 420 | { |
421 | struct bset_stats_op op; | 421 | struct bset_stats_op op; |
422 | int ret; | 422 | int ret; |
diff --git a/drivers/md/dm-cache-policy-mq.c b/drivers/md/dm-cache-policy-mq.c index 1e018e986610..0e385e40909e 100644 --- a/drivers/md/dm-cache-policy-mq.c +++ b/drivers/md/dm-cache-policy-mq.c | |||
@@ -872,7 +872,7 @@ static void mq_destroy(struct dm_cache_policy *p) | |||
872 | { | 872 | { |
873 | struct mq_policy *mq = to_mq_policy(p); | 873 | struct mq_policy *mq = to_mq_policy(p); |
874 | 874 | ||
875 | kfree(mq->table); | 875 | vfree(mq->table); |
876 | epool_exit(&mq->cache_pool); | 876 | epool_exit(&mq->cache_pool); |
877 | epool_exit(&mq->pre_cache_pool); | 877 | epool_exit(&mq->pre_cache_pool); |
878 | kfree(mq); | 878 | kfree(mq); |
@@ -1245,7 +1245,7 @@ static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, | |||
1245 | 1245 | ||
1246 | mq->nr_buckets = next_power(from_cblock(cache_size) / 2, 16); | 1246 | mq->nr_buckets = next_power(from_cblock(cache_size) / 2, 16); |
1247 | mq->hash_bits = ffs(mq->nr_buckets) - 1; | 1247 | mq->hash_bits = ffs(mq->nr_buckets) - 1; |
1248 | mq->table = kzalloc(sizeof(*mq->table) * mq->nr_buckets, GFP_KERNEL); | 1248 | mq->table = vzalloc(sizeof(*mq->table) * mq->nr_buckets); |
1249 | if (!mq->table) | 1249 | if (!mq->table) |
1250 | goto bad_alloc_table; | 1250 | goto bad_alloc_table; |
1251 | 1251 | ||
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index ffd472e015ca..074b9c8e4cf0 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
@@ -289,6 +289,7 @@ struct per_bio_data { | |||
289 | bool tick:1; | 289 | bool tick:1; |
290 | unsigned req_nr:2; | 290 | unsigned req_nr:2; |
291 | struct dm_deferred_entry *all_io_entry; | 291 | struct dm_deferred_entry *all_io_entry; |
292 | struct dm_hook_info hook_info; | ||
292 | 293 | ||
293 | /* | 294 | /* |
294 | * writethrough fields. These MUST remain at the end of this | 295 | * writethrough fields. These MUST remain at the end of this |
@@ -297,7 +298,6 @@ struct per_bio_data { | |||
297 | */ | 298 | */ |
298 | struct cache *cache; | 299 | struct cache *cache; |
299 | dm_cblock_t cblock; | 300 | dm_cblock_t cblock; |
300 | struct dm_hook_info hook_info; | ||
301 | struct dm_bio_details bio_details; | 301 | struct dm_bio_details bio_details; |
302 | }; | 302 | }; |
303 | 303 | ||
@@ -671,15 +671,16 @@ static void remap_to_cache(struct cache *cache, struct bio *bio, | |||
671 | dm_cblock_t cblock) | 671 | dm_cblock_t cblock) |
672 | { | 672 | { |
673 | sector_t bi_sector = bio->bi_iter.bi_sector; | 673 | sector_t bi_sector = bio->bi_iter.bi_sector; |
674 | sector_t block = from_cblock(cblock); | ||
674 | 675 | ||
675 | bio->bi_bdev = cache->cache_dev->bdev; | 676 | bio->bi_bdev = cache->cache_dev->bdev; |
676 | if (!block_size_is_power_of_two(cache)) | 677 | if (!block_size_is_power_of_two(cache)) |
677 | bio->bi_iter.bi_sector = | 678 | bio->bi_iter.bi_sector = |
678 | (from_cblock(cblock) * cache->sectors_per_block) + | 679 | (block * cache->sectors_per_block) + |
679 | sector_div(bi_sector, cache->sectors_per_block); | 680 | sector_div(bi_sector, cache->sectors_per_block); |
680 | else | 681 | else |
681 | bio->bi_iter.bi_sector = | 682 | bio->bi_iter.bi_sector = |
682 | (from_cblock(cblock) << cache->sectors_per_block_shift) | | 683 | (block << cache->sectors_per_block_shift) | |
683 | (bi_sector & (cache->sectors_per_block - 1)); | 684 | (bi_sector & (cache->sectors_per_block - 1)); |
684 | } | 685 | } |
685 | 686 | ||
@@ -978,12 +979,13 @@ static void issue_copy_real(struct dm_cache_migration *mg) | |||
978 | int r; | 979 | int r; |
979 | struct dm_io_region o_region, c_region; | 980 | struct dm_io_region o_region, c_region; |
980 | struct cache *cache = mg->cache; | 981 | struct cache *cache = mg->cache; |
982 | sector_t cblock = from_cblock(mg->cblock); | ||
981 | 983 | ||
982 | o_region.bdev = cache->origin_dev->bdev; | 984 | o_region.bdev = cache->origin_dev->bdev; |
983 | o_region.count = cache->sectors_per_block; | 985 | o_region.count = cache->sectors_per_block; |
984 | 986 | ||
985 | c_region.bdev = cache->cache_dev->bdev; | 987 | c_region.bdev = cache->cache_dev->bdev; |
986 | c_region.sector = from_cblock(mg->cblock) * cache->sectors_per_block; | 988 | c_region.sector = cblock * cache->sectors_per_block; |
987 | c_region.count = cache->sectors_per_block; | 989 | c_region.count = cache->sectors_per_block; |
988 | 990 | ||
989 | if (mg->writeback || mg->demote) { | 991 | if (mg->writeback || mg->demote) { |
@@ -1010,13 +1012,15 @@ static void overwrite_endio(struct bio *bio, int err) | |||
1010 | struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); | 1012 | struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); |
1011 | unsigned long flags; | 1013 | unsigned long flags; |
1012 | 1014 | ||
1015 | dm_unhook_bio(&pb->hook_info, bio); | ||
1016 | |||
1013 | if (err) | 1017 | if (err) |
1014 | mg->err = true; | 1018 | mg->err = true; |
1015 | 1019 | ||
1020 | mg->requeue_holder = false; | ||
1021 | |||
1016 | spin_lock_irqsave(&cache->lock, flags); | 1022 | spin_lock_irqsave(&cache->lock, flags); |
1017 | list_add_tail(&mg->list, &cache->completed_migrations); | 1023 | list_add_tail(&mg->list, &cache->completed_migrations); |
1018 | dm_unhook_bio(&pb->hook_info, bio); | ||
1019 | mg->requeue_holder = false; | ||
1020 | spin_unlock_irqrestore(&cache->lock, flags); | 1024 | spin_unlock_irqrestore(&cache->lock, flags); |
1021 | 1025 | ||
1022 | wake_worker(cache); | 1026 | wake_worker(cache); |
@@ -2461,20 +2465,18 @@ static int cache_map(struct dm_target *ti, struct bio *bio) | |||
2461 | bool discarded_block; | 2465 | bool discarded_block; |
2462 | struct dm_bio_prison_cell *cell; | 2466 | struct dm_bio_prison_cell *cell; |
2463 | struct policy_result lookup_result; | 2467 | struct policy_result lookup_result; |
2464 | struct per_bio_data *pb; | 2468 | struct per_bio_data *pb = init_per_bio_data(bio, pb_data_size); |
2465 | 2469 | ||
2466 | if (from_oblock(block) > from_oblock(cache->origin_blocks)) { | 2470 | if (unlikely(from_oblock(block) >= from_oblock(cache->origin_blocks))) { |
2467 | /* | 2471 | /* |
2468 | * This can only occur if the io goes to a partial block at | 2472 | * This can only occur if the io goes to a partial block at |
2469 | * the end of the origin device. We don't cache these. | 2473 | * the end of the origin device. We don't cache these. |
2470 | * Just remap to the origin and carry on. | 2474 | * Just remap to the origin and carry on. |
2471 | */ | 2475 | */ |
2472 | remap_to_origin_clear_discard(cache, bio, block); | 2476 | remap_to_origin(cache, bio); |
2473 | return DM_MAPIO_REMAPPED; | 2477 | return DM_MAPIO_REMAPPED; |
2474 | } | 2478 | } |
2475 | 2479 | ||
2476 | pb = init_per_bio_data(bio, pb_data_size); | ||
2477 | |||
2478 | if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { | 2480 | if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { |
2479 | defer_bio(cache, bio); | 2481 | defer_bio(cache, bio); |
2480 | return DM_MAPIO_SUBMITTED; | 2482 | return DM_MAPIO_SUBMITTED; |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index b2b8a10e8427..3842ac738f98 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -201,29 +201,28 @@ static void list_dp_init(struct dpages *dp, struct page_list *pl, unsigned offse | |||
201 | /* | 201 | /* |
202 | * Functions for getting the pages from a bvec. | 202 | * Functions for getting the pages from a bvec. |
203 | */ | 203 | */ |
204 | static void bio_get_page(struct dpages *dp, | 204 | static void bio_get_page(struct dpages *dp, struct page **p, |
205 | struct page **p, unsigned long *len, unsigned *offset) | 205 | unsigned long *len, unsigned *offset) |
206 | { | 206 | { |
207 | struct bio *bio = dp->context_ptr; | 207 | struct bio_vec *bvec = dp->context_ptr; |
208 | struct bio_vec bvec = bio_iovec(bio); | 208 | *p = bvec->bv_page; |
209 | *p = bvec.bv_page; | 209 | *len = bvec->bv_len - dp->context_u; |
210 | *len = bvec.bv_len; | 210 | *offset = bvec->bv_offset + dp->context_u; |
211 | *offset = bvec.bv_offset; | ||
212 | } | 211 | } |
213 | 212 | ||
214 | static void bio_next_page(struct dpages *dp) | 213 | static void bio_next_page(struct dpages *dp) |
215 | { | 214 | { |
216 | struct bio *bio = dp->context_ptr; | 215 | struct bio_vec *bvec = dp->context_ptr; |
217 | struct bio_vec bvec = bio_iovec(bio); | 216 | dp->context_ptr = bvec + 1; |
218 | 217 | dp->context_u = 0; | |
219 | bio_advance(bio, bvec.bv_len); | ||
220 | } | 218 | } |
221 | 219 | ||
222 | static void bio_dp_init(struct dpages *dp, struct bio *bio) | 220 | static void bio_dp_init(struct dpages *dp, struct bio *bio) |
223 | { | 221 | { |
224 | dp->get_page = bio_get_page; | 222 | dp->get_page = bio_get_page; |
225 | dp->next_page = bio_next_page; | 223 | dp->next_page = bio_next_page; |
226 | dp->context_ptr = bio; | 224 | dp->context_ptr = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter); |
225 | dp->context_u = bio->bi_iter.bi_bvec_done; | ||
227 | } | 226 | } |
228 | 227 | ||
229 | /* | 228 | /* |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 6eb9dc9ef8f3..422a9fdeb53e 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -1626,8 +1626,11 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd, | |||
1626 | /* | 1626 | /* |
1627 | * Only pass ioctls through if the device sizes match exactly. | 1627 | * Only pass ioctls through if the device sizes match exactly. |
1628 | */ | 1628 | */ |
1629 | if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) | 1629 | if (!bdev || ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT) { |
1630 | r = scsi_verify_blk_ioctl(NULL, cmd); | 1630 | int err = scsi_verify_blk_ioctl(NULL, cmd); |
1631 | if (err) | ||
1632 | r = err; | ||
1633 | } | ||
1631 | 1634 | ||
1632 | if (r == -ENOTCONN && !fatal_signal_pending(current)) | 1635 | if (r == -ENOTCONN && !fatal_signal_pending(current)) |
1633 | queue_work(kmultipathd, &m->process_queued_ios); | 1636 | queue_work(kmultipathd, &m->process_queued_ios); |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index f284e0bfb25f..7dfdb5c746d6 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1244,6 +1244,9 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error) | |||
1244 | 1244 | ||
1245 | dm_bio_restore(bd, bio); | 1245 | dm_bio_restore(bd, bio); |
1246 | bio_record->details.bi_bdev = NULL; | 1246 | bio_record->details.bi_bdev = NULL; |
1247 | |||
1248 | atomic_inc(&bio->bi_remaining); | ||
1249 | |||
1247 | queue_bio(ms, bio, rw); | 1250 | queue_bio(ms, bio, rw); |
1248 | return DM_ENDIO_INCOMPLETE; | 1251 | return DM_ENDIO_INCOMPLETE; |
1249 | } | 1252 | } |
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index afc3d017de4c..d6e88178d22c 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c | |||
@@ -546,6 +546,9 @@ static int read_exceptions(struct pstore *ps, | |||
546 | r = insert_exceptions(ps, area, callback, callback_context, | 546 | r = insert_exceptions(ps, area, callback, callback_context, |
547 | &full); | 547 | &full); |
548 | 548 | ||
549 | if (!full) | ||
550 | memcpy(ps->area, area, ps->store->chunk_size << SECTOR_SHIFT); | ||
551 | |||
549 | dm_bufio_release(bp); | 552 | dm_bufio_release(bp); |
550 | 553 | ||
551 | dm_bufio_forget(client, chunk); | 554 | dm_bufio_forget(client, chunk); |
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 7da347665552..fb9efc829182 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -76,7 +76,7 @@ | |||
76 | 76 | ||
77 | #define THIN_SUPERBLOCK_MAGIC 27022010 | 77 | #define THIN_SUPERBLOCK_MAGIC 27022010 |
78 | #define THIN_SUPERBLOCK_LOCATION 0 | 78 | #define THIN_SUPERBLOCK_LOCATION 0 |
79 | #define THIN_VERSION 1 | 79 | #define THIN_VERSION 2 |
80 | #define THIN_METADATA_CACHE_SIZE 64 | 80 | #define THIN_METADATA_CACHE_SIZE 64 |
81 | #define SECTOR_TO_BLOCK_SHIFT 3 | 81 | #define SECTOR_TO_BLOCK_SHIFT 3 |
82 | 82 | ||
@@ -483,7 +483,7 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd) | |||
483 | 483 | ||
484 | disk_super->data_mapping_root = cpu_to_le64(pmd->root); | 484 | disk_super->data_mapping_root = cpu_to_le64(pmd->root); |
485 | disk_super->device_details_root = cpu_to_le64(pmd->details_root); | 485 | disk_super->device_details_root = cpu_to_le64(pmd->details_root); |
486 | disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | 486 | disk_super->metadata_block_size = cpu_to_le32(THIN_METADATA_BLOCK_SIZE); |
487 | disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT); | 487 | disk_super->metadata_nr_blocks = cpu_to_le64(bdev_size >> SECTOR_TO_BLOCK_SHIFT); |
488 | disk_super->data_block_size = cpu_to_le32(pmd->data_block_size); | 488 | disk_super->data_block_size = cpu_to_le32(pmd->data_block_size); |
489 | 489 | ||
@@ -651,7 +651,7 @@ static int __create_persistent_data_objects(struct dm_pool_metadata *pmd, bool f | |||
651 | { | 651 | { |
652 | int r; | 652 | int r; |
653 | 653 | ||
654 | pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE, | 654 | pmd->bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT, |
655 | THIN_METADATA_CACHE_SIZE, | 655 | THIN_METADATA_CACHE_SIZE, |
656 | THIN_MAX_CONCURRENT_LOCKS); | 656 | THIN_MAX_CONCURRENT_LOCKS); |
657 | if (IS_ERR(pmd->bm)) { | 657 | if (IS_ERR(pmd->bm)) { |
@@ -1489,6 +1489,23 @@ bool dm_thin_changed_this_transaction(struct dm_thin_device *td) | |||
1489 | return r; | 1489 | return r; |
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | bool dm_pool_changed_this_transaction(struct dm_pool_metadata *pmd) | ||
1493 | { | ||
1494 | bool r = false; | ||
1495 | struct dm_thin_device *td, *tmp; | ||
1496 | |||
1497 | down_read(&pmd->root_lock); | ||
1498 | list_for_each_entry_safe(td, tmp, &pmd->thin_devices, list) { | ||
1499 | if (td->changed) { | ||
1500 | r = td->changed; | ||
1501 | break; | ||
1502 | } | ||
1503 | } | ||
1504 | up_read(&pmd->root_lock); | ||
1505 | |||
1506 | return r; | ||
1507 | } | ||
1508 | |||
1492 | bool dm_thin_aborted_changes(struct dm_thin_device *td) | 1509 | bool dm_thin_aborted_changes(struct dm_thin_device *td) |
1493 | { | 1510 | { |
1494 | bool r; | 1511 | bool r; |
@@ -1738,3 +1755,38 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, | |||
1738 | 1755 | ||
1739 | return r; | 1756 | return r; |
1740 | } | 1757 | } |
1758 | |||
1759 | int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) | ||
1760 | { | ||
1761 | int r; | ||
1762 | struct dm_block *sblock; | ||
1763 | struct thin_disk_superblock *disk_super; | ||
1764 | |||
1765 | down_write(&pmd->root_lock); | ||
1766 | pmd->flags |= THIN_METADATA_NEEDS_CHECK_FLAG; | ||
1767 | |||
1768 | r = superblock_lock(pmd, &sblock); | ||
1769 | if (r) { | ||
1770 | DMERR("couldn't read superblock"); | ||
1771 | goto out; | ||
1772 | } | ||
1773 | |||
1774 | disk_super = dm_block_data(sblock); | ||
1775 | disk_super->flags = cpu_to_le32(pmd->flags); | ||
1776 | |||
1777 | dm_bm_unlock(sblock); | ||
1778 | out: | ||
1779 | up_write(&pmd->root_lock); | ||
1780 | return r; | ||
1781 | } | ||
1782 | |||
1783 | bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd) | ||
1784 | { | ||
1785 | bool needs_check; | ||
1786 | |||
1787 | down_read(&pmd->root_lock); | ||
1788 | needs_check = pmd->flags & THIN_METADATA_NEEDS_CHECK_FLAG; | ||
1789 | up_read(&pmd->root_lock); | ||
1790 | |||
1791 | return needs_check; | ||
1792 | } | ||
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index 9a368567632f..e3c857db195a 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
@@ -9,16 +9,14 @@ | |||
9 | 9 | ||
10 | #include "persistent-data/dm-block-manager.h" | 10 | #include "persistent-data/dm-block-manager.h" |
11 | #include "persistent-data/dm-space-map.h" | 11 | #include "persistent-data/dm-space-map.h" |
12 | #include "persistent-data/dm-space-map-metadata.h" | ||
12 | 13 | ||
13 | #define THIN_METADATA_BLOCK_SIZE 4096 | 14 | #define THIN_METADATA_BLOCK_SIZE DM_SM_METADATA_BLOCK_SIZE |
14 | 15 | ||
15 | /* | 16 | /* |
16 | * The metadata device is currently limited in size. | 17 | * The metadata device is currently limited in size. |
17 | * | ||
18 | * We have one block of index, which can hold 255 index entries. Each | ||
19 | * index entry contains allocation info about 16k metadata blocks. | ||
20 | */ | 18 | */ |
21 | #define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) | 19 | #define THIN_METADATA_MAX_SECTORS DM_SM_METADATA_MAX_SECTORS |
22 | 20 | ||
23 | /* | 21 | /* |
24 | * A metadata device larger than 16GB triggers a warning. | 22 | * A metadata device larger than 16GB triggers a warning. |
@@ -27,6 +25,11 @@ | |||
27 | 25 | ||
28 | /*----------------------------------------------------------------*/ | 26 | /*----------------------------------------------------------------*/ |
29 | 27 | ||
28 | /* | ||
29 | * Thin metadata superblock flags. | ||
30 | */ | ||
31 | #define THIN_METADATA_NEEDS_CHECK_FLAG (1 << 0) | ||
32 | |||
30 | struct dm_pool_metadata; | 33 | struct dm_pool_metadata; |
31 | struct dm_thin_device; | 34 | struct dm_thin_device; |
32 | 35 | ||
@@ -161,6 +164,8 @@ int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block); | |||
161 | */ | 164 | */ |
162 | bool dm_thin_changed_this_transaction(struct dm_thin_device *td); | 165 | bool dm_thin_changed_this_transaction(struct dm_thin_device *td); |
163 | 166 | ||
167 | bool dm_pool_changed_this_transaction(struct dm_pool_metadata *pmd); | ||
168 | |||
164 | bool dm_thin_aborted_changes(struct dm_thin_device *td); | 169 | bool dm_thin_aborted_changes(struct dm_thin_device *td); |
165 | 170 | ||
166 | int dm_thin_get_highest_mapped_block(struct dm_thin_device *td, | 171 | int dm_thin_get_highest_mapped_block(struct dm_thin_device *td, |
@@ -202,6 +207,12 @@ int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd, | |||
202 | dm_sm_threshold_fn fn, | 207 | dm_sm_threshold_fn fn, |
203 | void *context); | 208 | void *context); |
204 | 209 | ||
210 | /* | ||
211 | * Updates the superblock immediately. | ||
212 | */ | ||
213 | int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd); | ||
214 | bool dm_pool_metadata_needs_check(struct dm_pool_metadata *pmd); | ||
215 | |||
205 | /*----------------------------------------------------------------*/ | 216 | /*----------------------------------------------------------------*/ |
206 | 217 | ||
207 | #endif | 218 | #endif |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index faaf944597ab..be70d38745f7 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -130,10 +130,11 @@ static void build_virtual_key(struct dm_thin_device *td, dm_block_t b, | |||
130 | struct dm_thin_new_mapping; | 130 | struct dm_thin_new_mapping; |
131 | 131 | ||
132 | /* | 132 | /* |
133 | * The pool runs in 3 modes. Ordered in degraded order for comparisons. | 133 | * The pool runs in 4 modes. Ordered in degraded order for comparisons. |
134 | */ | 134 | */ |
135 | enum pool_mode { | 135 | enum pool_mode { |
136 | PM_WRITE, /* metadata may be changed */ | 136 | PM_WRITE, /* metadata may be changed */ |
137 | PM_OUT_OF_DATA_SPACE, /* metadata may be changed, though data may not be allocated */ | ||
137 | PM_READ_ONLY, /* metadata may not be changed */ | 138 | PM_READ_ONLY, /* metadata may not be changed */ |
138 | PM_FAIL, /* all I/O fails */ | 139 | PM_FAIL, /* all I/O fails */ |
139 | }; | 140 | }; |
@@ -198,7 +199,6 @@ struct pool { | |||
198 | }; | 199 | }; |
199 | 200 | ||
200 | static enum pool_mode get_pool_mode(struct pool *pool); | 201 | static enum pool_mode get_pool_mode(struct pool *pool); |
201 | static void out_of_data_space(struct pool *pool); | ||
202 | static void metadata_operation_failed(struct pool *pool, const char *op, int r); | 202 | static void metadata_operation_failed(struct pool *pool, const char *op, int r); |
203 | 203 | ||
204 | /* | 204 | /* |
@@ -226,6 +226,7 @@ struct thin_c { | |||
226 | 226 | ||
227 | struct pool *pool; | 227 | struct pool *pool; |
228 | struct dm_thin_device *td; | 228 | struct dm_thin_device *td; |
229 | bool requeue_mode:1; | ||
229 | }; | 230 | }; |
230 | 231 | ||
231 | /*----------------------------------------------------------------*/ | 232 | /*----------------------------------------------------------------*/ |
@@ -369,14 +370,18 @@ struct dm_thin_endio_hook { | |||
369 | struct dm_thin_new_mapping *overwrite_mapping; | 370 | struct dm_thin_new_mapping *overwrite_mapping; |
370 | }; | 371 | }; |
371 | 372 | ||
372 | static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master) | 373 | static void requeue_bio_list(struct thin_c *tc, struct bio_list *master) |
373 | { | 374 | { |
374 | struct bio *bio; | 375 | struct bio *bio; |
375 | struct bio_list bios; | 376 | struct bio_list bios; |
377 | unsigned long flags; | ||
376 | 378 | ||
377 | bio_list_init(&bios); | 379 | bio_list_init(&bios); |
380 | |||
381 | spin_lock_irqsave(&tc->pool->lock, flags); | ||
378 | bio_list_merge(&bios, master); | 382 | bio_list_merge(&bios, master); |
379 | bio_list_init(master); | 383 | bio_list_init(master); |
384 | spin_unlock_irqrestore(&tc->pool->lock, flags); | ||
380 | 385 | ||
381 | while ((bio = bio_list_pop(&bios))) { | 386 | while ((bio = bio_list_pop(&bios))) { |
382 | struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); | 387 | struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); |
@@ -391,12 +396,26 @@ static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master) | |||
391 | static void requeue_io(struct thin_c *tc) | 396 | static void requeue_io(struct thin_c *tc) |
392 | { | 397 | { |
393 | struct pool *pool = tc->pool; | 398 | struct pool *pool = tc->pool; |
399 | |||
400 | requeue_bio_list(tc, &pool->deferred_bios); | ||
401 | requeue_bio_list(tc, &pool->retry_on_resume_list); | ||
402 | } | ||
403 | |||
404 | static void error_retry_list(struct pool *pool) | ||
405 | { | ||
406 | struct bio *bio; | ||
394 | unsigned long flags; | 407 | unsigned long flags; |
408 | struct bio_list bios; | ||
409 | |||
410 | bio_list_init(&bios); | ||
395 | 411 | ||
396 | spin_lock_irqsave(&pool->lock, flags); | 412 | spin_lock_irqsave(&pool->lock, flags); |
397 | __requeue_bio_list(tc, &pool->deferred_bios); | 413 | bio_list_merge(&bios, &pool->retry_on_resume_list); |
398 | __requeue_bio_list(tc, &pool->retry_on_resume_list); | 414 | bio_list_init(&pool->retry_on_resume_list); |
399 | spin_unlock_irqrestore(&pool->lock, flags); | 415 | spin_unlock_irqrestore(&pool->lock, flags); |
416 | |||
417 | while ((bio = bio_list_pop(&bios))) | ||
418 | bio_io_error(bio); | ||
400 | } | 419 | } |
401 | 420 | ||
402 | /* | 421 | /* |
@@ -925,13 +944,15 @@ static void check_low_water_mark(struct pool *pool, dm_block_t free_blocks) | |||
925 | } | 944 | } |
926 | } | 945 | } |
927 | 946 | ||
947 | static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); | ||
948 | |||
928 | static int alloc_data_block(struct thin_c *tc, dm_block_t *result) | 949 | static int alloc_data_block(struct thin_c *tc, dm_block_t *result) |
929 | { | 950 | { |
930 | int r; | 951 | int r; |
931 | dm_block_t free_blocks; | 952 | dm_block_t free_blocks; |
932 | struct pool *pool = tc->pool; | 953 | struct pool *pool = tc->pool; |
933 | 954 | ||
934 | if (get_pool_mode(pool) != PM_WRITE) | 955 | if (WARN_ON(get_pool_mode(pool) != PM_WRITE)) |
935 | return -EINVAL; | 956 | return -EINVAL; |
936 | 957 | ||
937 | r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); | 958 | r = dm_pool_get_free_block_count(pool->pmd, &free_blocks); |
@@ -958,7 +979,7 @@ static int alloc_data_block(struct thin_c *tc, dm_block_t *result) | |||
958 | } | 979 | } |
959 | 980 | ||
960 | if (!free_blocks) { | 981 | if (!free_blocks) { |
961 | out_of_data_space(pool); | 982 | set_pool_mode(pool, PM_OUT_OF_DATA_SPACE); |
962 | return -ENOSPC; | 983 | return -ENOSPC; |
963 | } | 984 | } |
964 | } | 985 | } |
@@ -988,15 +1009,32 @@ static void retry_on_resume(struct bio *bio) | |||
988 | spin_unlock_irqrestore(&pool->lock, flags); | 1009 | spin_unlock_irqrestore(&pool->lock, flags); |
989 | } | 1010 | } |
990 | 1011 | ||
991 | static void handle_unserviceable_bio(struct pool *pool, struct bio *bio) | 1012 | static bool should_error_unserviceable_bio(struct pool *pool) |
992 | { | 1013 | { |
993 | /* | 1014 | enum pool_mode m = get_pool_mode(pool); |
994 | * When pool is read-only, no cell locking is needed because | ||
995 | * nothing is changing. | ||
996 | */ | ||
997 | WARN_ON_ONCE(get_pool_mode(pool) != PM_READ_ONLY); | ||
998 | 1015 | ||
999 | if (pool->pf.error_if_no_space) | 1016 | switch (m) { |
1017 | case PM_WRITE: | ||
1018 | /* Shouldn't get here */ | ||
1019 | DMERR_LIMIT("bio unserviceable, yet pool is in PM_WRITE mode"); | ||
1020 | return true; | ||
1021 | |||
1022 | case PM_OUT_OF_DATA_SPACE: | ||
1023 | return pool->pf.error_if_no_space; | ||
1024 | |||
1025 | case PM_READ_ONLY: | ||
1026 | case PM_FAIL: | ||
1027 | return true; | ||
1028 | default: | ||
1029 | /* Shouldn't get here */ | ||
1030 | DMERR_LIMIT("bio unserviceable, yet pool has an unknown mode"); | ||
1031 | return true; | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | static void handle_unserviceable_bio(struct pool *pool, struct bio *bio) | ||
1036 | { | ||
1037 | if (should_error_unserviceable_bio(pool)) | ||
1000 | bio_io_error(bio); | 1038 | bio_io_error(bio); |
1001 | else | 1039 | else |
1002 | retry_on_resume(bio); | 1040 | retry_on_resume(bio); |
@@ -1007,11 +1045,20 @@ static void retry_bios_on_resume(struct pool *pool, struct dm_bio_prison_cell *c | |||
1007 | struct bio *bio; | 1045 | struct bio *bio; |
1008 | struct bio_list bios; | 1046 | struct bio_list bios; |
1009 | 1047 | ||
1048 | if (should_error_unserviceable_bio(pool)) { | ||
1049 | cell_error(pool, cell); | ||
1050 | return; | ||
1051 | } | ||
1052 | |||
1010 | bio_list_init(&bios); | 1053 | bio_list_init(&bios); |
1011 | cell_release(pool, cell, &bios); | 1054 | cell_release(pool, cell, &bios); |
1012 | 1055 | ||
1013 | while ((bio = bio_list_pop(&bios))) | 1056 | if (should_error_unserviceable_bio(pool)) |
1014 | handle_unserviceable_bio(pool, bio); | 1057 | while ((bio = bio_list_pop(&bios))) |
1058 | bio_io_error(bio); | ||
1059 | else | ||
1060 | while ((bio = bio_list_pop(&bios))) | ||
1061 | retry_on_resume(bio); | ||
1015 | } | 1062 | } |
1016 | 1063 | ||
1017 | static void process_discard(struct thin_c *tc, struct bio *bio) | 1064 | static void process_discard(struct thin_c *tc, struct bio *bio) |
@@ -1296,6 +1343,11 @@ static void process_bio_read_only(struct thin_c *tc, struct bio *bio) | |||
1296 | } | 1343 | } |
1297 | } | 1344 | } |
1298 | 1345 | ||
1346 | static void process_bio_success(struct thin_c *tc, struct bio *bio) | ||
1347 | { | ||
1348 | bio_endio(bio, 0); | ||
1349 | } | ||
1350 | |||
1299 | static void process_bio_fail(struct thin_c *tc, struct bio *bio) | 1351 | static void process_bio_fail(struct thin_c *tc, struct bio *bio) |
1300 | { | 1352 | { |
1301 | bio_io_error(bio); | 1353 | bio_io_error(bio); |
@@ -1328,6 +1380,11 @@ static void process_deferred_bios(struct pool *pool) | |||
1328 | struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); | 1380 | struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); |
1329 | struct thin_c *tc = h->tc; | 1381 | struct thin_c *tc = h->tc; |
1330 | 1382 | ||
1383 | if (tc->requeue_mode) { | ||
1384 | bio_endio(bio, DM_ENDIO_REQUEUE); | ||
1385 | continue; | ||
1386 | } | ||
1387 | |||
1331 | /* | 1388 | /* |
1332 | * If we've got no free new_mapping structs, and processing | 1389 | * If we've got no free new_mapping structs, and processing |
1333 | * this bio might require one, we pause until there are some | 1390 | * this bio might require one, we pause until there are some |
@@ -1357,7 +1414,8 @@ static void process_deferred_bios(struct pool *pool) | |||
1357 | bio_list_init(&pool->deferred_flush_bios); | 1414 | bio_list_init(&pool->deferred_flush_bios); |
1358 | spin_unlock_irqrestore(&pool->lock, flags); | 1415 | spin_unlock_irqrestore(&pool->lock, flags); |
1359 | 1416 | ||
1360 | if (bio_list_empty(&bios) && !need_commit_due_to_time(pool)) | 1417 | if (bio_list_empty(&bios) && |
1418 | !(dm_pool_changed_this_transaction(pool->pmd) && need_commit_due_to_time(pool))) | ||
1361 | return; | 1419 | return; |
1362 | 1420 | ||
1363 | if (commit(pool)) { | 1421 | if (commit(pool)) { |
@@ -1393,51 +1451,134 @@ static void do_waker(struct work_struct *ws) | |||
1393 | 1451 | ||
1394 | /*----------------------------------------------------------------*/ | 1452 | /*----------------------------------------------------------------*/ |
1395 | 1453 | ||
1454 | struct noflush_work { | ||
1455 | struct work_struct worker; | ||
1456 | struct thin_c *tc; | ||
1457 | |||
1458 | atomic_t complete; | ||
1459 | wait_queue_head_t wait; | ||
1460 | }; | ||
1461 | |||
1462 | static void complete_noflush_work(struct noflush_work *w) | ||
1463 | { | ||
1464 | atomic_set(&w->complete, 1); | ||
1465 | wake_up(&w->wait); | ||
1466 | } | ||
1467 | |||
1468 | static void do_noflush_start(struct work_struct *ws) | ||
1469 | { | ||
1470 | struct noflush_work *w = container_of(ws, struct noflush_work, worker); | ||
1471 | w->tc->requeue_mode = true; | ||
1472 | requeue_io(w->tc); | ||
1473 | complete_noflush_work(w); | ||
1474 | } | ||
1475 | |||
1476 | static void do_noflush_stop(struct work_struct *ws) | ||
1477 | { | ||
1478 | struct noflush_work *w = container_of(ws, struct noflush_work, worker); | ||
1479 | w->tc->requeue_mode = false; | ||
1480 | complete_noflush_work(w); | ||
1481 | } | ||
1482 | |||
1483 | static void noflush_work(struct thin_c *tc, void (*fn)(struct work_struct *)) | ||
1484 | { | ||
1485 | struct noflush_work w; | ||
1486 | |||
1487 | INIT_WORK(&w.worker, fn); | ||
1488 | w.tc = tc; | ||
1489 | atomic_set(&w.complete, 0); | ||
1490 | init_waitqueue_head(&w.wait); | ||
1491 | |||
1492 | queue_work(tc->pool->wq, &w.worker); | ||
1493 | |||
1494 | wait_event(w.wait, atomic_read(&w.complete)); | ||
1495 | } | ||
1496 | |||
1497 | /*----------------------------------------------------------------*/ | ||
1498 | |||
1396 | static enum pool_mode get_pool_mode(struct pool *pool) | 1499 | static enum pool_mode get_pool_mode(struct pool *pool) |
1397 | { | 1500 | { |
1398 | return pool->pf.mode; | 1501 | return pool->pf.mode; |
1399 | } | 1502 | } |
1400 | 1503 | ||
1504 | static void notify_of_pool_mode_change(struct pool *pool, const char *new_mode) | ||
1505 | { | ||
1506 | dm_table_event(pool->ti->table); | ||
1507 | DMINFO("%s: switching pool to %s mode", | ||
1508 | dm_device_name(pool->pool_md), new_mode); | ||
1509 | } | ||
1510 | |||
1401 | static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | 1511 | static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) |
1402 | { | 1512 | { |
1403 | int r; | 1513 | struct pool_c *pt = pool->ti->private; |
1404 | enum pool_mode old_mode = pool->pf.mode; | 1514 | bool needs_check = dm_pool_metadata_needs_check(pool->pmd); |
1515 | enum pool_mode old_mode = get_pool_mode(pool); | ||
1516 | |||
1517 | /* | ||
1518 | * Never allow the pool to transition to PM_WRITE mode if user | ||
1519 | * intervention is required to verify metadata and data consistency. | ||
1520 | */ | ||
1521 | if (new_mode == PM_WRITE && needs_check) { | ||
1522 | DMERR("%s: unable to switch pool to write mode until repaired.", | ||
1523 | dm_device_name(pool->pool_md)); | ||
1524 | if (old_mode != new_mode) | ||
1525 | new_mode = old_mode; | ||
1526 | else | ||
1527 | new_mode = PM_READ_ONLY; | ||
1528 | } | ||
1529 | /* | ||
1530 | * If we were in PM_FAIL mode, rollback of metadata failed. We're | ||
1531 | * not going to recover without a thin_repair. So we never let the | ||
1532 | * pool move out of the old mode. | ||
1533 | */ | ||
1534 | if (old_mode == PM_FAIL) | ||
1535 | new_mode = old_mode; | ||
1405 | 1536 | ||
1406 | switch (new_mode) { | 1537 | switch (new_mode) { |
1407 | case PM_FAIL: | 1538 | case PM_FAIL: |
1408 | if (old_mode != new_mode) | 1539 | if (old_mode != new_mode) |
1409 | DMERR("%s: switching pool to failure mode", | 1540 | notify_of_pool_mode_change(pool, "failure"); |
1410 | dm_device_name(pool->pool_md)); | ||
1411 | dm_pool_metadata_read_only(pool->pmd); | 1541 | dm_pool_metadata_read_only(pool->pmd); |
1412 | pool->process_bio = process_bio_fail; | 1542 | pool->process_bio = process_bio_fail; |
1413 | pool->process_discard = process_bio_fail; | 1543 | pool->process_discard = process_bio_fail; |
1414 | pool->process_prepared_mapping = process_prepared_mapping_fail; | 1544 | pool->process_prepared_mapping = process_prepared_mapping_fail; |
1415 | pool->process_prepared_discard = process_prepared_discard_fail; | 1545 | pool->process_prepared_discard = process_prepared_discard_fail; |
1546 | |||
1547 | error_retry_list(pool); | ||
1416 | break; | 1548 | break; |
1417 | 1549 | ||
1418 | case PM_READ_ONLY: | 1550 | case PM_READ_ONLY: |
1419 | if (old_mode != new_mode) | 1551 | if (old_mode != new_mode) |
1420 | DMERR("%s: switching pool to read-only mode", | 1552 | notify_of_pool_mode_change(pool, "read-only"); |
1421 | dm_device_name(pool->pool_md)); | 1553 | dm_pool_metadata_read_only(pool->pmd); |
1422 | r = dm_pool_abort_metadata(pool->pmd); | 1554 | pool->process_bio = process_bio_read_only; |
1423 | if (r) { | 1555 | pool->process_discard = process_bio_success; |
1424 | DMERR("%s: aborting transaction failed", | 1556 | pool->process_prepared_mapping = process_prepared_mapping_fail; |
1425 | dm_device_name(pool->pool_md)); | 1557 | pool->process_prepared_discard = process_prepared_discard_passdown; |
1426 | new_mode = PM_FAIL; | 1558 | |
1427 | set_pool_mode(pool, new_mode); | 1559 | error_retry_list(pool); |
1428 | } else { | 1560 | break; |
1429 | dm_pool_metadata_read_only(pool->pmd); | 1561 | |
1430 | pool->process_bio = process_bio_read_only; | 1562 | case PM_OUT_OF_DATA_SPACE: |
1431 | pool->process_discard = process_discard; | 1563 | /* |
1432 | pool->process_prepared_mapping = process_prepared_mapping_fail; | 1564 | * Ideally we'd never hit this state; the low water mark |
1433 | pool->process_prepared_discard = process_prepared_discard_passdown; | 1565 | * would trigger userland to extend the pool before we |
1434 | } | 1566 | * completely run out of data space. However, many small |
1567 | * IOs to unprovisioned space can consume data space at an | ||
1568 | * alarming rate. Adjust your low water mark if you're | ||
1569 | * frequently seeing this mode. | ||
1570 | */ | ||
1571 | if (old_mode != new_mode) | ||
1572 | notify_of_pool_mode_change(pool, "out-of-data-space"); | ||
1573 | pool->process_bio = process_bio_read_only; | ||
1574 | pool->process_discard = process_discard; | ||
1575 | pool->process_prepared_mapping = process_prepared_mapping; | ||
1576 | pool->process_prepared_discard = process_prepared_discard_passdown; | ||
1435 | break; | 1577 | break; |
1436 | 1578 | ||
1437 | case PM_WRITE: | 1579 | case PM_WRITE: |
1438 | if (old_mode != new_mode) | 1580 | if (old_mode != new_mode) |
1439 | DMINFO("%s: switching pool to write mode", | 1581 | notify_of_pool_mode_change(pool, "write"); |
1440 | dm_device_name(pool->pool_md)); | ||
1441 | dm_pool_metadata_read_write(pool->pmd); | 1582 | dm_pool_metadata_read_write(pool->pmd); |
1442 | pool->process_bio = process_bio; | 1583 | pool->process_bio = process_bio; |
1443 | pool->process_discard = process_discard; | 1584 | pool->process_discard = process_discard; |
@@ -1447,32 +1588,35 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | |||
1447 | } | 1588 | } |
1448 | 1589 | ||
1449 | pool->pf.mode = new_mode; | 1590 | pool->pf.mode = new_mode; |
1591 | /* | ||
1592 | * The pool mode may have changed, sync it so bind_control_target() | ||
1593 | * doesn't cause an unexpected mode transition on resume. | ||
1594 | */ | ||
1595 | pt->adjusted_pf.mode = new_mode; | ||
1450 | } | 1596 | } |
1451 | 1597 | ||
1452 | /* | 1598 | static void abort_transaction(struct pool *pool) |
1453 | * Rather than calling set_pool_mode directly, use these which describe the | ||
1454 | * reason for mode degradation. | ||
1455 | */ | ||
1456 | static void out_of_data_space(struct pool *pool) | ||
1457 | { | 1599 | { |
1458 | DMERR_LIMIT("%s: no free data space available.", | 1600 | const char *dev_name = dm_device_name(pool->pool_md); |
1459 | dm_device_name(pool->pool_md)); | 1601 | |
1460 | set_pool_mode(pool, PM_READ_ONLY); | 1602 | DMERR_LIMIT("%s: aborting current metadata transaction", dev_name); |
1603 | if (dm_pool_abort_metadata(pool->pmd)) { | ||
1604 | DMERR("%s: failed to abort metadata transaction", dev_name); | ||
1605 | set_pool_mode(pool, PM_FAIL); | ||
1606 | } | ||
1607 | |||
1608 | if (dm_pool_metadata_set_needs_check(pool->pmd)) { | ||
1609 | DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name); | ||
1610 | set_pool_mode(pool, PM_FAIL); | ||
1611 | } | ||
1461 | } | 1612 | } |
1462 | 1613 | ||
1463 | static void metadata_operation_failed(struct pool *pool, const char *op, int r) | 1614 | static void metadata_operation_failed(struct pool *pool, const char *op, int r) |
1464 | { | 1615 | { |
1465 | dm_block_t free_blocks; | ||
1466 | |||
1467 | DMERR_LIMIT("%s: metadata operation '%s' failed: error = %d", | 1616 | DMERR_LIMIT("%s: metadata operation '%s' failed: error = %d", |
1468 | dm_device_name(pool->pool_md), op, r); | 1617 | dm_device_name(pool->pool_md), op, r); |
1469 | 1618 | ||
1470 | if (r == -ENOSPC && | 1619 | abort_transaction(pool); |
1471 | !dm_pool_get_free_metadata_block_count(pool->pmd, &free_blocks) && | ||
1472 | !free_blocks) | ||
1473 | DMERR_LIMIT("%s: no free metadata space available.", | ||
1474 | dm_device_name(pool->pool_md)); | ||
1475 | |||
1476 | set_pool_mode(pool, PM_READ_ONLY); | 1620 | set_pool_mode(pool, PM_READ_ONLY); |
1477 | } | 1621 | } |
1478 | 1622 | ||
@@ -1523,6 +1667,11 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio) | |||
1523 | 1667 | ||
1524 | thin_hook_bio(tc, bio); | 1668 | thin_hook_bio(tc, bio); |
1525 | 1669 | ||
1670 | if (tc->requeue_mode) { | ||
1671 | bio_endio(bio, DM_ENDIO_REQUEUE); | ||
1672 | return DM_MAPIO_SUBMITTED; | ||
1673 | } | ||
1674 | |||
1526 | if (get_pool_mode(tc->pool) == PM_FAIL) { | 1675 | if (get_pool_mode(tc->pool) == PM_FAIL) { |
1527 | bio_io_error(bio); | 1676 | bio_io_error(bio); |
1528 | return DM_MAPIO_SUBMITTED; | 1677 | return DM_MAPIO_SUBMITTED; |
@@ -1686,7 +1835,7 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti) | |||
1686 | /* | 1835 | /* |
1687 | * We want to make sure that a pool in PM_FAIL mode is never upgraded. | 1836 | * We want to make sure that a pool in PM_FAIL mode is never upgraded. |
1688 | */ | 1837 | */ |
1689 | enum pool_mode old_mode = pool->pf.mode; | 1838 | enum pool_mode old_mode = get_pool_mode(pool); |
1690 | enum pool_mode new_mode = pt->adjusted_pf.mode; | 1839 | enum pool_mode new_mode = pt->adjusted_pf.mode; |
1691 | 1840 | ||
1692 | /* | 1841 | /* |
@@ -1700,16 +1849,6 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti) | |||
1700 | pool->pf = pt->adjusted_pf; | 1849 | pool->pf = pt->adjusted_pf; |
1701 | pool->low_water_blocks = pt->low_water_blocks; | 1850 | pool->low_water_blocks = pt->low_water_blocks; |
1702 | 1851 | ||
1703 | /* | ||
1704 | * If we were in PM_FAIL mode, rollback of metadata failed. We're | ||
1705 | * not going to recover without a thin_repair. So we never let the | ||
1706 | * pool move out of the old mode. On the other hand a PM_READ_ONLY | ||
1707 | * may have been due to a lack of metadata or data space, and may | ||
1708 | * now work (ie. if the underlying devices have been resized). | ||
1709 | */ | ||
1710 | if (old_mode == PM_FAIL) | ||
1711 | new_mode = old_mode; | ||
1712 | |||
1713 | set_pool_mode(pool, new_mode); | 1852 | set_pool_mode(pool, new_mode); |
1714 | 1853 | ||
1715 | return 0; | 1854 | return 0; |
@@ -1999,16 +2138,27 @@ static void metadata_low_callback(void *context) | |||
1999 | dm_table_event(pool->ti->table); | 2138 | dm_table_event(pool->ti->table); |
2000 | } | 2139 | } |
2001 | 2140 | ||
2002 | static sector_t get_metadata_dev_size(struct block_device *bdev) | 2141 | static sector_t get_dev_size(struct block_device *bdev) |
2142 | { | ||
2143 | return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | ||
2144 | } | ||
2145 | |||
2146 | static void warn_if_metadata_device_too_big(struct block_device *bdev) | ||
2003 | { | 2147 | { |
2004 | sector_t metadata_dev_size = i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; | 2148 | sector_t metadata_dev_size = get_dev_size(bdev); |
2005 | char buffer[BDEVNAME_SIZE]; | 2149 | char buffer[BDEVNAME_SIZE]; |
2006 | 2150 | ||
2007 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) { | 2151 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS_WARNING) |
2008 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", | 2152 | DMWARN("Metadata device %s is larger than %u sectors: excess space will not be used.", |
2009 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); | 2153 | bdevname(bdev, buffer), THIN_METADATA_MAX_SECTORS); |
2010 | metadata_dev_size = THIN_METADATA_MAX_SECTORS_WARNING; | 2154 | } |
2011 | } | 2155 | |
2156 | static sector_t get_metadata_dev_size(struct block_device *bdev) | ||
2157 | { | ||
2158 | sector_t metadata_dev_size = get_dev_size(bdev); | ||
2159 | |||
2160 | if (metadata_dev_size > THIN_METADATA_MAX_SECTORS) | ||
2161 | metadata_dev_size = THIN_METADATA_MAX_SECTORS; | ||
2012 | 2162 | ||
2013 | return metadata_dev_size; | 2163 | return metadata_dev_size; |
2014 | } | 2164 | } |
@@ -2017,7 +2167,7 @@ static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev) | |||
2017 | { | 2167 | { |
2018 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); | 2168 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); |
2019 | 2169 | ||
2020 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | 2170 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE); |
2021 | 2171 | ||
2022 | return metadata_dev_size; | 2172 | return metadata_dev_size; |
2023 | } | 2173 | } |
@@ -2095,12 +2245,7 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2095 | ti->error = "Error opening metadata block device"; | 2245 | ti->error = "Error opening metadata block device"; |
2096 | goto out_unlock; | 2246 | goto out_unlock; |
2097 | } | 2247 | } |
2098 | 2248 | warn_if_metadata_device_too_big(metadata_dev->bdev); | |
2099 | /* | ||
2100 | * Run for the side-effect of possibly issuing a warning if the | ||
2101 | * device is too big. | ||
2102 | */ | ||
2103 | (void) get_metadata_dev_size(metadata_dev->bdev); | ||
2104 | 2249 | ||
2105 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); | 2250 | r = dm_get_device(ti, argv[1], FMODE_READ | FMODE_WRITE, &data_dev); |
2106 | if (r) { | 2251 | if (r) { |
@@ -2246,6 +2391,12 @@ static int maybe_resize_data_dev(struct dm_target *ti, bool *need_commit) | |||
2246 | return -EINVAL; | 2391 | return -EINVAL; |
2247 | 2392 | ||
2248 | } else if (data_size > sb_data_size) { | 2393 | } else if (data_size > sb_data_size) { |
2394 | if (dm_pool_metadata_needs_check(pool->pmd)) { | ||
2395 | DMERR("%s: unable to grow the data device until repaired.", | ||
2396 | dm_device_name(pool->pool_md)); | ||
2397 | return 0; | ||
2398 | } | ||
2399 | |||
2249 | if (sb_data_size) | 2400 | if (sb_data_size) |
2250 | DMINFO("%s: growing the data device from %llu to %llu blocks", | 2401 | DMINFO("%s: growing the data device from %llu to %llu blocks", |
2251 | dm_device_name(pool->pool_md), | 2402 | dm_device_name(pool->pool_md), |
@@ -2287,6 +2438,13 @@ static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) | |||
2287 | return -EINVAL; | 2438 | return -EINVAL; |
2288 | 2439 | ||
2289 | } else if (metadata_dev_size > sb_metadata_dev_size) { | 2440 | } else if (metadata_dev_size > sb_metadata_dev_size) { |
2441 | if (dm_pool_metadata_needs_check(pool->pmd)) { | ||
2442 | DMERR("%s: unable to grow the metadata device until repaired.", | ||
2443 | dm_device_name(pool->pool_md)); | ||
2444 | return 0; | ||
2445 | } | ||
2446 | |||
2447 | warn_if_metadata_device_too_big(pool->md_dev); | ||
2290 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", | 2448 | DMINFO("%s: growing the metadata device from %llu to %llu blocks", |
2291 | dm_device_name(pool->pool_md), | 2449 | dm_device_name(pool->pool_md), |
2292 | sb_metadata_dev_size, metadata_dev_size); | 2450 | sb_metadata_dev_size, metadata_dev_size); |
@@ -2673,7 +2831,9 @@ static void pool_status(struct dm_target *ti, status_type_t type, | |||
2673 | else | 2831 | else |
2674 | DMEMIT("- "); | 2832 | DMEMIT("- "); |
2675 | 2833 | ||
2676 | if (pool->pf.mode == PM_READ_ONLY) | 2834 | if (pool->pf.mode == PM_OUT_OF_DATA_SPACE) |
2835 | DMEMIT("out_of_data_space "); | ||
2836 | else if (pool->pf.mode == PM_READ_ONLY) | ||
2677 | DMEMIT("ro "); | 2837 | DMEMIT("ro "); |
2678 | else | 2838 | else |
2679 | DMEMIT("rw "); | 2839 | DMEMIT("rw "); |
@@ -2787,7 +2947,7 @@ static struct target_type pool_target = { | |||
2787 | .name = "thin-pool", | 2947 | .name = "thin-pool", |
2788 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | | 2948 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | |
2789 | DM_TARGET_IMMUTABLE, | 2949 | DM_TARGET_IMMUTABLE, |
2790 | .version = {1, 10, 0}, | 2950 | .version = {1, 11, 0}, |
2791 | .module = THIS_MODULE, | 2951 | .module = THIS_MODULE, |
2792 | .ctr = pool_ctr, | 2952 | .ctr = pool_ctr, |
2793 | .dtr = pool_dtr, | 2953 | .dtr = pool_dtr, |
@@ -2894,6 +3054,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2894 | 3054 | ||
2895 | if (get_pool_mode(tc->pool) == PM_FAIL) { | 3055 | if (get_pool_mode(tc->pool) == PM_FAIL) { |
2896 | ti->error = "Couldn't open thin device, Pool is in fail mode"; | 3056 | ti->error = "Couldn't open thin device, Pool is in fail mode"; |
3057 | r = -EINVAL; | ||
2897 | goto bad_thin_open; | 3058 | goto bad_thin_open; |
2898 | } | 3059 | } |
2899 | 3060 | ||
@@ -2905,7 +3066,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2905 | 3066 | ||
2906 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); | 3067 | r = dm_set_target_max_io_len(ti, tc->pool->sectors_per_block); |
2907 | if (r) | 3068 | if (r) |
2908 | goto bad_thin_open; | 3069 | goto bad_target_max_io_len; |
2909 | 3070 | ||
2910 | ti->num_flush_bios = 1; | 3071 | ti->num_flush_bios = 1; |
2911 | ti->flush_supported = true; | 3072 | ti->flush_supported = true; |
@@ -2926,6 +3087,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
2926 | 3087 | ||
2927 | return 0; | 3088 | return 0; |
2928 | 3089 | ||
3090 | bad_target_max_io_len: | ||
3091 | dm_pool_close_thin_device(tc->td); | ||
2929 | bad_thin_open: | 3092 | bad_thin_open: |
2930 | __pool_dec(tc->pool); | 3093 | __pool_dec(tc->pool); |
2931 | bad_pool_lookup: | 3094 | bad_pool_lookup: |
@@ -2986,10 +3149,23 @@ static int thin_endio(struct dm_target *ti, struct bio *bio, int err) | |||
2986 | return 0; | 3149 | return 0; |
2987 | } | 3150 | } |
2988 | 3151 | ||
2989 | static void thin_postsuspend(struct dm_target *ti) | 3152 | static void thin_presuspend(struct dm_target *ti) |
2990 | { | 3153 | { |
3154 | struct thin_c *tc = ti->private; | ||
3155 | |||
2991 | if (dm_noflush_suspending(ti)) | 3156 | if (dm_noflush_suspending(ti)) |
2992 | requeue_io((struct thin_c *)ti->private); | 3157 | noflush_work(tc, do_noflush_start); |
3158 | } | ||
3159 | |||
3160 | static void thin_postsuspend(struct dm_target *ti) | ||
3161 | { | ||
3162 | struct thin_c *tc = ti->private; | ||
3163 | |||
3164 | /* | ||
3165 | * The dm_noflush_suspending flag has been cleared by now, so | ||
3166 | * unfortunately we must always run this. | ||
3167 | */ | ||
3168 | noflush_work(tc, do_noflush_stop); | ||
2993 | } | 3169 | } |
2994 | 3170 | ||
2995 | /* | 3171 | /* |
@@ -3074,12 +3250,13 @@ static int thin_iterate_devices(struct dm_target *ti, | |||
3074 | 3250 | ||
3075 | static struct target_type thin_target = { | 3251 | static struct target_type thin_target = { |
3076 | .name = "thin", | 3252 | .name = "thin", |
3077 | .version = {1, 10, 0}, | 3253 | .version = {1, 11, 0}, |
3078 | .module = THIS_MODULE, | 3254 | .module = THIS_MODULE, |
3079 | .ctr = thin_ctr, | 3255 | .ctr = thin_ctr, |
3080 | .dtr = thin_dtr, | 3256 | .dtr = thin_dtr, |
3081 | .map = thin_map, | 3257 | .map = thin_map, |
3082 | .end_io = thin_endio, | 3258 | .end_io = thin_endio, |
3259 | .presuspend = thin_presuspend, | ||
3083 | .postsuspend = thin_postsuspend, | 3260 | .postsuspend = thin_postsuspend, |
3084 | .status = thin_status, | 3261 | .status = thin_status, |
3085 | .iterate_devices = thin_iterate_devices, | 3262 | .iterate_devices = thin_iterate_devices, |
diff --git a/drivers/md/persistent-data/Kconfig b/drivers/md/persistent-data/Kconfig index 19b268795415..0c2dec7aec20 100644 --- a/drivers/md/persistent-data/Kconfig +++ b/drivers/md/persistent-data/Kconfig | |||
@@ -6,3 +6,13 @@ config DM_PERSISTENT_DATA | |||
6 | ---help--- | 6 | ---help--- |
7 | Library providing immutable on-disk data structure support for | 7 | Library providing immutable on-disk data structure support for |
8 | device-mapper targets such as the thin provisioning target. | 8 | device-mapper targets such as the thin provisioning target. |
9 | |||
10 | config DM_DEBUG_BLOCK_STACK_TRACING | ||
11 | boolean "Keep stack trace of persistent data block lock holders" | ||
12 | depends on STACKTRACE_SUPPORT && DM_PERSISTENT_DATA | ||
13 | select STACKTRACE | ||
14 | ---help--- | ||
15 | Enable this for messages that may help debug problems with the | ||
16 | block manager locking used by thin provisioning and caching. | ||
17 | |||
18 | If unsure, say N. | ||
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index 536782e3bcb7..786b689bdfc7 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c | |||
@@ -91,6 +91,69 @@ struct block_op { | |||
91 | dm_block_t block; | 91 | dm_block_t block; |
92 | }; | 92 | }; |
93 | 93 | ||
94 | struct bop_ring_buffer { | ||
95 | unsigned begin; | ||
96 | unsigned end; | ||
97 | struct block_op bops[MAX_RECURSIVE_ALLOCATIONS + 1]; | ||
98 | }; | ||
99 | |||
100 | static void brb_init(struct bop_ring_buffer *brb) | ||
101 | { | ||
102 | brb->begin = 0; | ||
103 | brb->end = 0; | ||
104 | } | ||
105 | |||
106 | static bool brb_empty(struct bop_ring_buffer *brb) | ||
107 | { | ||
108 | return brb->begin == brb->end; | ||
109 | } | ||
110 | |||
111 | static unsigned brb_next(struct bop_ring_buffer *brb, unsigned old) | ||
112 | { | ||
113 | unsigned r = old + 1; | ||
114 | return (r >= (sizeof(brb->bops) / sizeof(*brb->bops))) ? 0 : r; | ||
115 | } | ||
116 | |||
117 | static int brb_push(struct bop_ring_buffer *brb, | ||
118 | enum block_op_type type, dm_block_t b) | ||
119 | { | ||
120 | struct block_op *bop; | ||
121 | unsigned next = brb_next(brb, brb->end); | ||
122 | |||
123 | /* | ||
124 | * We don't allow the last bop to be filled, this way we can | ||
125 | * differentiate between full and empty. | ||
126 | */ | ||
127 | if (next == brb->begin) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | bop = brb->bops + brb->end; | ||
131 | bop->type = type; | ||
132 | bop->block = b; | ||
133 | |||
134 | brb->end = next; | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int brb_pop(struct bop_ring_buffer *brb, struct block_op *result) | ||
140 | { | ||
141 | struct block_op *bop; | ||
142 | |||
143 | if (brb_empty(brb)) | ||
144 | return -ENODATA; | ||
145 | |||
146 | bop = brb->bops + brb->begin; | ||
147 | result->type = bop->type; | ||
148 | result->block = bop->block; | ||
149 | |||
150 | brb->begin = brb_next(brb, brb->begin); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | /*----------------------------------------------------------------*/ | ||
156 | |||
94 | struct sm_metadata { | 157 | struct sm_metadata { |
95 | struct dm_space_map sm; | 158 | struct dm_space_map sm; |
96 | 159 | ||
@@ -101,25 +164,20 @@ struct sm_metadata { | |||
101 | 164 | ||
102 | unsigned recursion_count; | 165 | unsigned recursion_count; |
103 | unsigned allocated_this_transaction; | 166 | unsigned allocated_this_transaction; |
104 | unsigned nr_uncommitted; | 167 | struct bop_ring_buffer uncommitted; |
105 | struct block_op uncommitted[MAX_RECURSIVE_ALLOCATIONS]; | ||
106 | 168 | ||
107 | struct threshold threshold; | 169 | struct threshold threshold; |
108 | }; | 170 | }; |
109 | 171 | ||
110 | static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b) | 172 | static int add_bop(struct sm_metadata *smm, enum block_op_type type, dm_block_t b) |
111 | { | 173 | { |
112 | struct block_op *op; | 174 | int r = brb_push(&smm->uncommitted, type, b); |
113 | 175 | ||
114 | if (smm->nr_uncommitted == MAX_RECURSIVE_ALLOCATIONS) { | 176 | if (r) { |
115 | DMERR("too many recursive allocations"); | 177 | DMERR("too many recursive allocations"); |
116 | return -ENOMEM; | 178 | return -ENOMEM; |
117 | } | 179 | } |
118 | 180 | ||
119 | op = smm->uncommitted + smm->nr_uncommitted++; | ||
120 | op->type = type; | ||
121 | op->block = b; | ||
122 | |||
123 | return 0; | 181 | return 0; |
124 | } | 182 | } |
125 | 183 | ||
@@ -158,11 +216,17 @@ static int out(struct sm_metadata *smm) | |||
158 | return -ENOMEM; | 216 | return -ENOMEM; |
159 | } | 217 | } |
160 | 218 | ||
161 | if (smm->recursion_count == 1 && smm->nr_uncommitted) { | 219 | if (smm->recursion_count == 1) { |
162 | while (smm->nr_uncommitted && !r) { | 220 | while (!brb_empty(&smm->uncommitted)) { |
163 | smm->nr_uncommitted--; | 221 | struct block_op bop; |
164 | r = commit_bop(smm, smm->uncommitted + | 222 | |
165 | smm->nr_uncommitted); | 223 | r = brb_pop(&smm->uncommitted, &bop); |
224 | if (r) { | ||
225 | DMERR("bug in bop ring buffer"); | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | r = commit_bop(smm, &bop); | ||
166 | if (r) | 230 | if (r) |
167 | break; | 231 | break; |
168 | } | 232 | } |
@@ -217,7 +281,8 @@ static int sm_metadata_get_nr_free(struct dm_space_map *sm, dm_block_t *count) | |||
217 | static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b, | 281 | static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b, |
218 | uint32_t *result) | 282 | uint32_t *result) |
219 | { | 283 | { |
220 | int r, i; | 284 | int r; |
285 | unsigned i; | ||
221 | struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); | 286 | struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); |
222 | unsigned adjustment = 0; | 287 | unsigned adjustment = 0; |
223 | 288 | ||
@@ -225,8 +290,10 @@ static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b, | |||
225 | * We may have some uncommitted adjustments to add. This list | 290 | * We may have some uncommitted adjustments to add. This list |
226 | * should always be really short. | 291 | * should always be really short. |
227 | */ | 292 | */ |
228 | for (i = 0; i < smm->nr_uncommitted; i++) { | 293 | for (i = smm->uncommitted.begin; |
229 | struct block_op *op = smm->uncommitted + i; | 294 | i != smm->uncommitted.end; |
295 | i = brb_next(&smm->uncommitted, i)) { | ||
296 | struct block_op *op = smm->uncommitted.bops + i; | ||
230 | 297 | ||
231 | if (op->block != b) | 298 | if (op->block != b) |
232 | continue; | 299 | continue; |
@@ -254,7 +321,8 @@ static int sm_metadata_get_count(struct dm_space_map *sm, dm_block_t b, | |||
254 | static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm, | 321 | static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm, |
255 | dm_block_t b, int *result) | 322 | dm_block_t b, int *result) |
256 | { | 323 | { |
257 | int r, i, adjustment = 0; | 324 | int r, adjustment = 0; |
325 | unsigned i; | ||
258 | struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); | 326 | struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); |
259 | uint32_t rc; | 327 | uint32_t rc; |
260 | 328 | ||
@@ -262,8 +330,11 @@ static int sm_metadata_count_is_more_than_one(struct dm_space_map *sm, | |||
262 | * We may have some uncommitted adjustments to add. This list | 330 | * We may have some uncommitted adjustments to add. This list |
263 | * should always be really short. | 331 | * should always be really short. |
264 | */ | 332 | */ |
265 | for (i = 0; i < smm->nr_uncommitted; i++) { | 333 | for (i = smm->uncommitted.begin; |
266 | struct block_op *op = smm->uncommitted + i; | 334 | i != smm->uncommitted.end; |
335 | i = brb_next(&smm->uncommitted, i)) { | ||
336 | |||
337 | struct block_op *op = smm->uncommitted.bops + i; | ||
267 | 338 | ||
268 | if (op->block != b) | 339 | if (op->block != b) |
269 | continue; | 340 | continue; |
@@ -671,7 +742,7 @@ int dm_sm_metadata_create(struct dm_space_map *sm, | |||
671 | smm->begin = superblock + 1; | 742 | smm->begin = superblock + 1; |
672 | smm->recursion_count = 0; | 743 | smm->recursion_count = 0; |
673 | smm->allocated_this_transaction = 0; | 744 | smm->allocated_this_transaction = 0; |
674 | smm->nr_uncommitted = 0; | 745 | brb_init(&smm->uncommitted); |
675 | threshold_init(&smm->threshold); | 746 | threshold_init(&smm->threshold); |
676 | 747 | ||
677 | memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm)); | 748 | memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm)); |
@@ -680,6 +751,8 @@ int dm_sm_metadata_create(struct dm_space_map *sm, | |||
680 | if (r) | 751 | if (r) |
681 | return r; | 752 | return r; |
682 | 753 | ||
754 | if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS) | ||
755 | nr_blocks = DM_SM_METADATA_MAX_BLOCKS; | ||
683 | r = sm_ll_extend(&smm->ll, nr_blocks); | 756 | r = sm_ll_extend(&smm->ll, nr_blocks); |
684 | if (r) | 757 | if (r) |
685 | return r; | 758 | return r; |
@@ -713,7 +786,7 @@ int dm_sm_metadata_open(struct dm_space_map *sm, | |||
713 | smm->begin = 0; | 786 | smm->begin = 0; |
714 | smm->recursion_count = 0; | 787 | smm->recursion_count = 0; |
715 | smm->allocated_this_transaction = 0; | 788 | smm->allocated_this_transaction = 0; |
716 | smm->nr_uncommitted = 0; | 789 | brb_init(&smm->uncommitted); |
717 | threshold_init(&smm->threshold); | 790 | threshold_init(&smm->threshold); |
718 | 791 | ||
719 | memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); | 792 | memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); |
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.h b/drivers/md/persistent-data/dm-space-map-metadata.h index 39bba0801cf2..64df923974d8 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.h +++ b/drivers/md/persistent-data/dm-space-map-metadata.h | |||
@@ -9,6 +9,17 @@ | |||
9 | 9 | ||
10 | #include "dm-transaction-manager.h" | 10 | #include "dm-transaction-manager.h" |
11 | 11 | ||
12 | #define DM_SM_METADATA_BLOCK_SIZE (4096 >> SECTOR_SHIFT) | ||
13 | |||
14 | /* | ||
15 | * The metadata device is currently limited in size. | ||
16 | * | ||
17 | * We have one block of index, which can hold 255 index entries. Each | ||
18 | * index entry contains allocation info about ~16k metadata blocks. | ||
19 | */ | ||
20 | #define DM_SM_METADATA_MAX_BLOCKS (255 * ((1 << 14) - 64)) | ||
21 | #define DM_SM_METADATA_MAX_SECTORS (DM_SM_METADATA_MAX_BLOCKS * DM_SM_METADATA_BLOCK_SIZE) | ||
22 | |||
12 | /* | 23 | /* |
13 | * Unfortunately we have to use two-phase construction due to the cycle | 24 | * Unfortunately we have to use two-phase construction due to the cycle |
14 | * between the tm and sm. | 25 | * between the tm and sm. |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index fd3a2a14b587..4a6ca1cb2e78 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1953,11 +1953,15 @@ static int process_checks(struct r1bio *r1_bio) | |||
1953 | for (i = 0; i < conf->raid_disks * 2; i++) { | 1953 | for (i = 0; i < conf->raid_disks * 2; i++) { |
1954 | int j; | 1954 | int j; |
1955 | int size; | 1955 | int size; |
1956 | int uptodate; | ||
1956 | struct bio *b = r1_bio->bios[i]; | 1957 | struct bio *b = r1_bio->bios[i]; |
1957 | if (b->bi_end_io != end_sync_read) | 1958 | if (b->bi_end_io != end_sync_read) |
1958 | continue; | 1959 | continue; |
1959 | /* fixup the bio for reuse */ | 1960 | /* fixup the bio for reuse, but preserve BIO_UPTODATE */ |
1961 | uptodate = test_bit(BIO_UPTODATE, &b->bi_flags); | ||
1960 | bio_reset(b); | 1962 | bio_reset(b); |
1963 | if (!uptodate) | ||
1964 | clear_bit(BIO_UPTODATE, &b->bi_flags); | ||
1961 | b->bi_vcnt = vcnt; | 1965 | b->bi_vcnt = vcnt; |
1962 | b->bi_iter.bi_size = r1_bio->sectors << 9; | 1966 | b->bi_iter.bi_size = r1_bio->sectors << 9; |
1963 | b->bi_iter.bi_sector = r1_bio->sector + | 1967 | b->bi_iter.bi_sector = r1_bio->sector + |
@@ -1990,11 +1994,14 @@ static int process_checks(struct r1bio *r1_bio) | |||
1990 | int j; | 1994 | int j; |
1991 | struct bio *pbio = r1_bio->bios[primary]; | 1995 | struct bio *pbio = r1_bio->bios[primary]; |
1992 | struct bio *sbio = r1_bio->bios[i]; | 1996 | struct bio *sbio = r1_bio->bios[i]; |
1997 | int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags); | ||
1993 | 1998 | ||
1994 | if (sbio->bi_end_io != end_sync_read) | 1999 | if (sbio->bi_end_io != end_sync_read) |
1995 | continue; | 2000 | continue; |
2001 | /* Now we can 'fixup' the BIO_UPTODATE flag */ | ||
2002 | set_bit(BIO_UPTODATE, &sbio->bi_flags); | ||
1996 | 2003 | ||
1997 | if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) { | 2004 | if (uptodate) { |
1998 | for (j = vcnt; j-- ; ) { | 2005 | for (j = vcnt; j-- ; ) { |
1999 | struct page *p, *s; | 2006 | struct page *p, *s; |
2000 | p = pbio->bi_io_vec[j].bv_page; | 2007 | p = pbio->bi_io_vec[j].bv_page; |
@@ -2009,7 +2016,7 @@ static int process_checks(struct r1bio *r1_bio) | |||
2009 | if (j >= 0) | 2016 | if (j >= 0) |
2010 | atomic64_add(r1_bio->sectors, &mddev->resync_mismatches); | 2017 | atomic64_add(r1_bio->sectors, &mddev->resync_mismatches); |
2011 | if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) | 2018 | if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery) |
2012 | && test_bit(BIO_UPTODATE, &sbio->bi_flags))) { | 2019 | && uptodate)) { |
2013 | /* No need to write to this device. */ | 2020 | /* No need to write to this device. */ |
2014 | sbio->bi_end_io = NULL; | 2021 | sbio->bi_end_io = NULL; |
2015 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); | 2022 | rdev_dec_pending(conf->mirrors[i].rdev, mddev); |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index f1feadeb7bb2..16f5c21963db 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -5514,23 +5514,43 @@ raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks) | |||
5514 | return sectors * (raid_disks - conf->max_degraded); | 5514 | return sectors * (raid_disks - conf->max_degraded); |
5515 | } | 5515 | } |
5516 | 5516 | ||
5517 | static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) | ||
5518 | { | ||
5519 | safe_put_page(percpu->spare_page); | ||
5520 | kfree(percpu->scribble); | ||
5521 | percpu->spare_page = NULL; | ||
5522 | percpu->scribble = NULL; | ||
5523 | } | ||
5524 | |||
5525 | static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) | ||
5526 | { | ||
5527 | if (conf->level == 6 && !percpu->spare_page) | ||
5528 | percpu->spare_page = alloc_page(GFP_KERNEL); | ||
5529 | if (!percpu->scribble) | ||
5530 | percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||
5531 | |||
5532 | if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { | ||
5533 | free_scratch_buffer(conf, percpu); | ||
5534 | return -ENOMEM; | ||
5535 | } | ||
5536 | |||
5537 | return 0; | ||
5538 | } | ||
5539 | |||
5517 | static void raid5_free_percpu(struct r5conf *conf) | 5540 | static void raid5_free_percpu(struct r5conf *conf) |
5518 | { | 5541 | { |
5519 | struct raid5_percpu *percpu; | ||
5520 | unsigned long cpu; | 5542 | unsigned long cpu; |
5521 | 5543 | ||
5522 | if (!conf->percpu) | 5544 | if (!conf->percpu) |
5523 | return; | 5545 | return; |
5524 | 5546 | ||
5525 | get_online_cpus(); | ||
5526 | for_each_possible_cpu(cpu) { | ||
5527 | percpu = per_cpu_ptr(conf->percpu, cpu); | ||
5528 | safe_put_page(percpu->spare_page); | ||
5529 | kfree(percpu->scribble); | ||
5530 | } | ||
5531 | #ifdef CONFIG_HOTPLUG_CPU | 5547 | #ifdef CONFIG_HOTPLUG_CPU |
5532 | unregister_cpu_notifier(&conf->cpu_notify); | 5548 | unregister_cpu_notifier(&conf->cpu_notify); |
5533 | #endif | 5549 | #endif |
5550 | |||
5551 | get_online_cpus(); | ||
5552 | for_each_possible_cpu(cpu) | ||
5553 | free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); | ||
5534 | put_online_cpus(); | 5554 | put_online_cpus(); |
5535 | 5555 | ||
5536 | free_percpu(conf->percpu); | 5556 | free_percpu(conf->percpu); |
@@ -5557,15 +5577,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
5557 | switch (action) { | 5577 | switch (action) { |
5558 | case CPU_UP_PREPARE: | 5578 | case CPU_UP_PREPARE: |
5559 | case CPU_UP_PREPARE_FROZEN: | 5579 | case CPU_UP_PREPARE_FROZEN: |
5560 | if (conf->level == 6 && !percpu->spare_page) | 5580 | if (alloc_scratch_buffer(conf, percpu)) { |
5561 | percpu->spare_page = alloc_page(GFP_KERNEL); | ||
5562 | if (!percpu->scribble) | ||
5563 | percpu->scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||
5564 | |||
5565 | if (!percpu->scribble || | ||
5566 | (conf->level == 6 && !percpu->spare_page)) { | ||
5567 | safe_put_page(percpu->spare_page); | ||
5568 | kfree(percpu->scribble); | ||
5569 | pr_err("%s: failed memory allocation for cpu%ld\n", | 5581 | pr_err("%s: failed memory allocation for cpu%ld\n", |
5570 | __func__, cpu); | 5582 | __func__, cpu); |
5571 | return notifier_from_errno(-ENOMEM); | 5583 | return notifier_from_errno(-ENOMEM); |
@@ -5573,10 +5585,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
5573 | break; | 5585 | break; |
5574 | case CPU_DEAD: | 5586 | case CPU_DEAD: |
5575 | case CPU_DEAD_FROZEN: | 5587 | case CPU_DEAD_FROZEN: |
5576 | safe_put_page(percpu->spare_page); | 5588 | free_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); |
5577 | kfree(percpu->scribble); | ||
5578 | percpu->spare_page = NULL; | ||
5579 | percpu->scribble = NULL; | ||
5580 | break; | 5589 | break; |
5581 | default: | 5590 | default: |
5582 | break; | 5591 | break; |
@@ -5588,40 +5597,29 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, | |||
5588 | static int raid5_alloc_percpu(struct r5conf *conf) | 5597 | static int raid5_alloc_percpu(struct r5conf *conf) |
5589 | { | 5598 | { |
5590 | unsigned long cpu; | 5599 | unsigned long cpu; |
5591 | struct page *spare_page; | 5600 | int err = 0; |
5592 | struct raid5_percpu __percpu *allcpus; | ||
5593 | void *scribble; | ||
5594 | int err; | ||
5595 | 5601 | ||
5596 | allcpus = alloc_percpu(struct raid5_percpu); | 5602 | conf->percpu = alloc_percpu(struct raid5_percpu); |
5597 | if (!allcpus) | 5603 | if (!conf->percpu) |
5598 | return -ENOMEM; | 5604 | return -ENOMEM; |
5599 | conf->percpu = allcpus; | 5605 | |
5606 | #ifdef CONFIG_HOTPLUG_CPU | ||
5607 | conf->cpu_notify.notifier_call = raid456_cpu_notify; | ||
5608 | conf->cpu_notify.priority = 0; | ||
5609 | err = register_cpu_notifier(&conf->cpu_notify); | ||
5610 | if (err) | ||
5611 | return err; | ||
5612 | #endif | ||
5600 | 5613 | ||
5601 | get_online_cpus(); | 5614 | get_online_cpus(); |
5602 | err = 0; | ||
5603 | for_each_present_cpu(cpu) { | 5615 | for_each_present_cpu(cpu) { |
5604 | if (conf->level == 6) { | 5616 | err = alloc_scratch_buffer(conf, per_cpu_ptr(conf->percpu, cpu)); |
5605 | spare_page = alloc_page(GFP_KERNEL); | 5617 | if (err) { |
5606 | if (!spare_page) { | 5618 | pr_err("%s: failed memory allocation for cpu%ld\n", |
5607 | err = -ENOMEM; | 5619 | __func__, cpu); |
5608 | break; | ||
5609 | } | ||
5610 | per_cpu_ptr(conf->percpu, cpu)->spare_page = spare_page; | ||
5611 | } | ||
5612 | scribble = kmalloc(conf->scribble_len, GFP_KERNEL); | ||
5613 | if (!scribble) { | ||
5614 | err = -ENOMEM; | ||
5615 | break; | 5620 | break; |
5616 | } | 5621 | } |
5617 | per_cpu_ptr(conf->percpu, cpu)->scribble = scribble; | ||
5618 | } | 5622 | } |
5619 | #ifdef CONFIG_HOTPLUG_CPU | ||
5620 | conf->cpu_notify.notifier_call = raid456_cpu_notify; | ||
5621 | conf->cpu_notify.priority = 0; | ||
5622 | if (err == 0) | ||
5623 | err = register_cpu_notifier(&conf->cpu_notify); | ||
5624 | #endif | ||
5625 | put_online_cpus(); | 5623 | put_online_cpus(); |
5626 | 5624 | ||
5627 | return err; | 5625 | return err; |
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index 68f768a5422d..a6c3c9e2e897 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c | |||
@@ -1176,7 +1176,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1176 | 1176 | ||
1177 | switch (demod) { | 1177 | switch (demod) { |
1178 | case 0: | 1178 | case 0: |
1179 | dev_err(&state->priv->i2c->dev, | 1179 | dev_err(&i2c->dev, |
1180 | "%s: Error attaching frontend %d\n", | 1180 | "%s: Error attaching frontend %d\n", |
1181 | KBUILD_MODNAME, demod); | 1181 | KBUILD_MODNAME, demod); |
1182 | goto error1; | 1182 | goto error1; |
@@ -1200,12 +1200,6 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1200 | state->demod = demod - 1; | 1200 | state->demod = demod - 1; |
1201 | state->priv = priv; | 1201 | state->priv = priv; |
1202 | 1202 | ||
1203 | /* test i2c bus for ack */ | ||
1204 | if (demod == 0) { | ||
1205 | if (cx24117_readreg(state, 0x00) < 0) | ||
1206 | goto error3; | ||
1207 | } | ||
1208 | |||
1209 | dev_info(&state->priv->i2c->dev, | 1203 | dev_info(&state->priv->i2c->dev, |
1210 | "%s: Attaching frontend %d\n", | 1204 | "%s: Attaching frontend %d\n", |
1211 | KBUILD_MODNAME, state->demod); | 1205 | KBUILD_MODNAME, state->demod); |
@@ -1216,8 +1210,6 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, | |||
1216 | state->frontend.demodulator_priv = state; | 1210 | state->frontend.demodulator_priv = state; |
1217 | return &state->frontend; | 1211 | return &state->frontend; |
1218 | 1212 | ||
1219 | error3: | ||
1220 | kfree(state); | ||
1221 | error2: | 1213 | error2: |
1222 | cx24117_release_priv(priv); | 1214 | cx24117_release_priv(priv); |
1223 | error1: | 1215 | error1: |
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 4bf057544607..8a8e1ecb762d 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Support for NXT2002 and NXT2004 - VSB/QAM | 2 | * Support for NXT2002 and NXT2004 - VSB/QAM |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> | 4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> |
5 | * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> | 5 | * Copyright (C) 2006-2014 Michael Krufky <mkrufky@linuxtv.org> |
6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | 6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> |
7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> | 7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> |
8 | * | 8 | * |
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c index 1effc21e1cdd..9bbd6656fb8f 100644 --- a/drivers/media/i2c/adv7842.c +++ b/drivers/media/i2c/adv7842.c | |||
@@ -2554,7 +2554,7 @@ static int adv7842_core_init(struct v4l2_subdev *sd) | |||
2554 | sdp_write_and_or(sd, 0xdd, 0xf0, pdata->sdp_free_run_force | | 2554 | sdp_write_and_or(sd, 0xdd, 0xf0, pdata->sdp_free_run_force | |
2555 | (pdata->sdp_free_run_cbar_en << 1) | | 2555 | (pdata->sdp_free_run_cbar_en << 1) | |
2556 | (pdata->sdp_free_run_man_col_en << 2) | | 2556 | (pdata->sdp_free_run_man_col_en << 2) | |
2557 | (pdata->sdp_free_run_force << 3)); | 2557 | (pdata->sdp_free_run_auto << 3)); |
2558 | 2558 | ||
2559 | /* TODO from platform data */ | 2559 | /* TODO from platform data */ |
2560 | cp_write(sd, 0x69, 0x14); /* Enable CP CSC */ | 2560 | cp_write(sd, 0x69, 0x14); /* Enable CP CSC */ |
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index 4b8381111cbd..77e10e0fd8d6 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c | |||
@@ -478,25 +478,33 @@ static void s5k5baf_write_arr_seq(struct s5k5baf *state, u16 addr, | |||
478 | u16 count, const u16 *seq) | 478 | u16 count, const u16 *seq) |
479 | { | 479 | { |
480 | struct i2c_client *c = v4l2_get_subdevdata(&state->sd); | 480 | struct i2c_client *c = v4l2_get_subdevdata(&state->sd); |
481 | __be16 buf[count + 1]; | 481 | __be16 buf[65]; |
482 | int ret, n; | ||
483 | 482 | ||
484 | s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr); | 483 | s5k5baf_i2c_write(state, REG_CMDWR_ADDR, addr); |
485 | if (state->error) | 484 | if (state->error) |
486 | return; | 485 | return; |
487 | 486 | ||
487 | v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count, | ||
488 | min(2 * count, 64), seq); | ||
489 | |||
488 | buf[0] = __constant_cpu_to_be16(REG_CMD_BUF); | 490 | buf[0] = __constant_cpu_to_be16(REG_CMD_BUF); |
489 | for (n = 1; n <= count; ++n) | ||
490 | buf[n] = cpu_to_be16(*seq++); | ||
491 | 491 | ||
492 | n *= 2; | 492 | while (count > 0) { |
493 | ret = i2c_master_send(c, (char *)buf, n); | 493 | int n = min_t(int, count, ARRAY_SIZE(buf) - 1); |
494 | v4l2_dbg(3, debug, c, "i2c_write_seq(count=%d): %*ph\n", count, | 494 | int ret, i; |
495 | min(2 * count, 64), seq - count); | ||
496 | 495 | ||
497 | if (ret != n) { | 496 | for (i = 1; i <= n; ++i) |
498 | v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret); | 497 | buf[i] = cpu_to_be16(*seq++); |
499 | state->error = ret; | 498 | |
499 | i *= 2; | ||
500 | ret = i2c_master_send(c, (char *)buf, i); | ||
501 | if (ret != i) { | ||
502 | v4l2_err(c, "i2c_write_seq: error during transfer (%d)\n", ret); | ||
503 | state->error = ret; | ||
504 | break; | ||
505 | } | ||
506 | |||
507 | count -= n; | ||
500 | } | 508 | } |
501 | } | 509 | } |
502 | 510 | ||
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index d85cb0ace4dc..6662b495b22c 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c | |||
@@ -2426,7 +2426,7 @@ struct tvcard bttv_tvcards[] = { | |||
2426 | }, | 2426 | }, |
2427 | /* ---- card 0x87---------------------------------- */ | 2427 | /* ---- card 0x87---------------------------------- */ |
2428 | [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { | 2428 | [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = { |
2429 | /* Michael Krufky <mkrufky@m1k.net> */ | 2429 | /* Michael Krufky <mkrufky@linuxtv.org> */ |
2430 | .name = "DViCO FusionHDTV 5 Lite", | 2430 | .name = "DViCO FusionHDTV 5 Lite", |
2431 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ | 2431 | .tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */ |
2432 | .tuner_addr = ADDR_UNSET, | 2432 | .tuner_addr = ADDR_UNSET, |
diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index 922e8233fd0b..3f364b7062b9 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c | |||
@@ -98,7 +98,7 @@ int bttv_sub_add_device(struct bttv_core *core, char *name) | |||
98 | 98 | ||
99 | err = device_register(&sub->dev); | 99 | err = device_register(&sub->dev); |
100 | if (0 != err) { | 100 | if (0 != err) { |
101 | kfree(sub); | 101 | put_device(&sub->dev); |
102 | return err; | 102 | return err; |
103 | } | 103 | } |
104 | pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); | 104 | pr_info("%d: add subdevice \"%s\"\n", core->nr, dev_name(&sub->dev)); |
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index d45e7f6ff332..c9b2350e92c8 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c | |||
@@ -2590,7 +2590,7 @@ struct saa7134_board saa7134_boards[] = { | |||
2590 | }}, | 2590 | }}, |
2591 | }, | 2591 | }, |
2592 | [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { | 2592 | [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = { |
2593 | /* Michael Krufky <mkrufky@m1k.net> | 2593 | /* Michael Krufky <mkrufky@linuxtv.org> |
2594 | * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder | 2594 | * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder |
2595 | * AFAIK, there is no analog demod, thus, | 2595 | * AFAIK, there is no analog demod, thus, |
2596 | * no support for analog television. | 2596 | * no support for analog television. |
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index a7dfd07e8389..da2fc86cc524 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c | |||
@@ -1027,7 +1027,8 @@ static int fimc_probe(struct platform_device *pdev) | |||
1027 | return 0; | 1027 | return 0; |
1028 | 1028 | ||
1029 | err_gclk: | 1029 | err_gclk: |
1030 | clk_disable(fimc->clock[CLK_GATE]); | 1030 | if (!pm_runtime_enabled(dev)) |
1031 | clk_disable(fimc->clock[CLK_GATE]); | ||
1031 | err_sd: | 1032 | err_sd: |
1032 | fimc_unregister_capture_subdev(fimc); | 1033 | fimc_unregister_capture_subdev(fimc); |
1033 | err_sclk: | 1034 | err_sclk: |
@@ -1036,6 +1037,7 @@ err_sclk: | |||
1036 | return ret; | 1037 | return ret; |
1037 | } | 1038 | } |
1038 | 1039 | ||
1040 | #ifdef CONFIG_PM_RUNTIME | ||
1039 | static int fimc_runtime_resume(struct device *dev) | 1041 | static int fimc_runtime_resume(struct device *dev) |
1040 | { | 1042 | { |
1041 | struct fimc_dev *fimc = dev_get_drvdata(dev); | 1043 | struct fimc_dev *fimc = dev_get_drvdata(dev); |
@@ -1068,6 +1070,7 @@ static int fimc_runtime_suspend(struct device *dev) | |||
1068 | dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state); | 1070 | dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state); |
1069 | return ret; | 1071 | return ret; |
1070 | } | 1072 | } |
1073 | #endif | ||
1071 | 1074 | ||
1072 | #ifdef CONFIG_PM_SLEEP | 1075 | #ifdef CONFIG_PM_SLEEP |
1073 | static int fimc_resume(struct device *dev) | 1076 | static int fimc_resume(struct device *dev) |
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index 1234734bccf4..779ec3cd259d 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c | |||
@@ -1563,7 +1563,7 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1563 | if (!pm_runtime_enabled(dev)) { | 1563 | if (!pm_runtime_enabled(dev)) { |
1564 | ret = clk_enable(fimc->clock); | 1564 | ret = clk_enable(fimc->clock); |
1565 | if (ret < 0) | 1565 | if (ret < 0) |
1566 | goto err_clk_put; | 1566 | goto err_sd; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); | 1569 | fimc->alloc_ctx = vb2_dma_contig_init_ctx(dev); |
@@ -1579,7 +1579,8 @@ static int fimc_lite_probe(struct platform_device *pdev) | |||
1579 | return 0; | 1579 | return 0; |
1580 | 1580 | ||
1581 | err_clk_dis: | 1581 | err_clk_dis: |
1582 | clk_disable(fimc->clock); | 1582 | if (!pm_runtime_enabled(dev)) |
1583 | clk_disable(fimc->clock); | ||
1583 | err_sd: | 1584 | err_sd: |
1584 | fimc_lite_unregister_capture_subdev(fimc); | 1585 | fimc_lite_unregister_capture_subdev(fimc); |
1585 | err_clk_put: | 1586 | err_clk_put: |
@@ -1587,6 +1588,7 @@ err_clk_put: | |||
1587 | return ret; | 1588 | return ret; |
1588 | } | 1589 | } |
1589 | 1590 | ||
1591 | #ifdef CONFIG_PM_RUNTIME | ||
1590 | static int fimc_lite_runtime_resume(struct device *dev) | 1592 | static int fimc_lite_runtime_resume(struct device *dev) |
1591 | { | 1593 | { |
1592 | struct fimc_lite *fimc = dev_get_drvdata(dev); | 1594 | struct fimc_lite *fimc = dev_get_drvdata(dev); |
@@ -1602,6 +1604,7 @@ static int fimc_lite_runtime_suspend(struct device *dev) | |||
1602 | clk_disable(fimc->clock); | 1604 | clk_disable(fimc->clock); |
1603 | return 0; | 1605 | return 0; |
1604 | } | 1606 | } |
1607 | #endif | ||
1605 | 1608 | ||
1606 | #ifdef CONFIG_PM_SLEEP | 1609 | #ifdef CONFIG_PM_SLEEP |
1607 | static int fimc_lite_resume(struct device *dev) | 1610 | static int fimc_lite_resume(struct device *dev) |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index a1c78c870b68..7d68d0b9966a 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
@@ -175,7 +175,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
175 | { | 175 | { |
176 | .name = "YUV 4:2:0 planar, Y/CbCr", | 176 | .name = "YUV 4:2:0 planar, Y/CbCr", |
177 | .fourcc = V4L2_PIX_FMT_NV12, | 177 | .fourcc = V4L2_PIX_FMT_NV12, |
178 | .depth = 16, | 178 | .depth = 12, |
179 | .colplanes = 2, | 179 | .colplanes = 2, |
180 | .h_align = 1, | 180 | .h_align = 1, |
181 | .v_align = 1, | 181 | .v_align = 1, |
@@ -188,10 +188,10 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
188 | { | 188 | { |
189 | .name = "YUV 4:2:0 planar, Y/CbCr", | 189 | .name = "YUV 4:2:0 planar, Y/CbCr", |
190 | .fourcc = V4L2_PIX_FMT_NV12, | 190 | .fourcc = V4L2_PIX_FMT_NV12, |
191 | .depth = 16, | 191 | .depth = 12, |
192 | .colplanes = 4, | 192 | .colplanes = 2, |
193 | .h_align = 4, | 193 | .h_align = 4, |
194 | .v_align = 1, | 194 | .v_align = 4, |
195 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | 195 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | |
196 | SJPEG_FMT_FLAG_DEC_CAPTURE | | 196 | SJPEG_FMT_FLAG_DEC_CAPTURE | |
197 | SJPEG_FMT_FLAG_S5P | | 197 | SJPEG_FMT_FLAG_S5P | |
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 8f9b2cea88f0..8ede8ea762e6 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c | |||
@@ -1539,6 +1539,8 @@ static const struct usb_device_id af9035_id_table[] = { | |||
1539 | &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) }, | 1539 | &af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)", NULL) }, |
1540 | { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05, | 1540 | { DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05, |
1541 | &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) }, | 1541 | &af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) }, |
1542 | { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xf900, | ||
1543 | &af9035_props, "Hauppauge WinTV-MiniStick 2", NULL) }, | ||
1542 | { } | 1544 | { } |
1543 | }; | 1545 | }; |
1544 | MODULE_DEVICE_TABLE(usb, af9035_id_table); | 1546 | MODULE_DEVICE_TABLE(usb, af9035_id_table); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c index d83df4bb72d3..0a98d04c53e4 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator | 2 | * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -601,7 +601,7 @@ struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state, | |||
601 | EXPORT_SYMBOL_GPL(mxl111sf_demod_attach); | 601 | EXPORT_SYMBOL_GPL(mxl111sf_demod_attach); |
602 | 602 | ||
603 | MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver"); | 603 | MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver"); |
604 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 604 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
605 | MODULE_LICENSE("GPL"); | 605 | MODULE_LICENSE("GPL"); |
606 | MODULE_VERSION("0.1"); | 606 | MODULE_VERSION("0.1"); |
607 | 607 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h index 3f3f8bfd190b..2d4530f5be54 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator | 2 | * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c index e4121cb8f5ef..a619410adde4 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h index 0220f54299a5..b85a5772d771 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-gpio.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-gpio.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c index 34434557ef65..a101d06eb143 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-i2c.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-i2c.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h index a57a45ffb9e4..465762145ad2 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-i2c.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-i2c.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c index b741b3a7a325..f6b348024bec 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-phy.c - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-phy.c - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h index f0756071d347..0643738de7de 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-phy.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-phy.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h index 17831b0fb9db..89bf115e927e 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-reg.h - driver for the MaxLinear MXL111SF | 2 | * mxl111sf-reg.h - driver for the MaxLinear MXL111SF |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c index 879c529640f7..a8d2c7053674 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner | 2 | * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -512,7 +512,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | |||
512 | EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach); | 512 | EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach); |
513 | 513 | ||
514 | MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver"); | 514 | MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver"); |
515 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 515 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
516 | MODULE_LICENSE("GPL"); | 516 | MODULE_LICENSE("GPL"); |
517 | MODULE_VERSION("0.1"); | 517 | MODULE_VERSION("0.1"); |
518 | 518 | ||
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h index 90f583e5d6a6..2046db22519e 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner | 2 | * mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com> | 4 | * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -68,7 +68,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | |||
68 | #else | 68 | #else |
69 | static inline | 69 | static inline |
70 | struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, | 70 | struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, |
71 | struct mxl111sf_state *mxl_state | 71 | struct mxl111sf_state *mxl_state, |
72 | struct mxl111sf_tuner_config *cfg) | 72 | struct mxl111sf_tuner_config *cfg) |
73 | { | 73 | { |
74 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 74 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c index 08240e498451..c7304fa8ab73 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com) | 2 | * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org) |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the Free | 5 | * under the terms of the GNU General Public License as published by the Free |
@@ -105,7 +105,7 @@ int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data) | |||
105 | ret = -EINVAL; | 105 | ret = -EINVAL; |
106 | } | 106 | } |
107 | 107 | ||
108 | pr_debug("R: (0x%02x, 0x%02x)\n", addr, *data); | 108 | pr_debug("R: (0x%02x, 0x%02x)\n", addr, buf[1]); |
109 | fail: | 109 | fail: |
110 | return ret; | 110 | return ret; |
111 | } | 111 | } |
@@ -1421,7 +1421,7 @@ static struct usb_driver mxl111sf_usb_driver = { | |||
1421 | 1421 | ||
1422 | module_usb_driver(mxl111sf_usb_driver); | 1422 | module_usb_driver(mxl111sf_usb_driver); |
1423 | 1423 | ||
1424 | MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>"); | 1424 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
1425 | MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); | 1425 | MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF"); |
1426 | MODULE_VERSION("1.0"); | 1426 | MODULE_VERSION("1.0"); |
1427 | MODULE_LICENSE("GPL"); | 1427 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h index 9816de86e48c..8516c011b7cc 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf.h +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com) | 2 | * Copyright (C) 2010-2014 Michael Krufky (mkrufky@linuxtv.org) |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of the GNU General Public License as published by the Free | 5 | * under the terms of the GNU General Public License as published by the Free |
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 2f0c89cbac76..c5638964c3f2 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c | |||
@@ -198,7 +198,6 @@ static int device_authorization(struct hdpvr_device *dev) | |||
198 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); | 198 | hex_dump_to_buffer(response, 8, 16, 1, print_buf, 5*buf_size+1, 0); |
199 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", | 199 | v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n", |
200 | print_buf); | 200 | print_buf); |
201 | kfree(print_buf); | ||
202 | #endif | 201 | #endif |
203 | 202 | ||
204 | msleep(100); | 203 | msleep(100); |
@@ -214,6 +213,9 @@ static int device_authorization(struct hdpvr_device *dev) | |||
214 | retval = ret != 8; | 213 | retval = ret != 8; |
215 | unlock: | 214 | unlock: |
216 | mutex_unlock(&dev->usbc_mutex); | 215 | mutex_unlock(&dev->usbc_mutex); |
216 | #ifdef HDPVR_DEBUG | ||
217 | kfree(print_buf); | ||
218 | #endif | ||
217 | return retval; | 219 | return retval; |
218 | } | 220 | } |
219 | 221 | ||
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index ee52b9f4a944..f7902fe8a526 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c | |||
@@ -515,6 +515,7 @@ bool v4l2_detect_gtf(unsigned frame_height, | |||
515 | aspect.denominator = 9; | 515 | aspect.denominator = 9; |
516 | } | 516 | } |
517 | image_width = ((image_height * aspect.numerator) / aspect.denominator); | 517 | image_width = ((image_height * aspect.numerator) / aspect.denominator); |
518 | image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1); | ||
518 | 519 | ||
519 | /* Horizontal */ | 520 | /* Horizontal */ |
520 | if (default_gtf) | 521 | if (default_gtf) |
diff --git a/drivers/media/v4l2-core/videobuf-dma-contig.c b/drivers/media/v4l2-core/videobuf-dma-contig.c index 65411adcd0ea..7e6b209b7002 100644 --- a/drivers/media/v4l2-core/videobuf-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf-dma-contig.c | |||
@@ -66,14 +66,11 @@ static void __videobuf_dc_free(struct device *dev, | |||
66 | static void videobuf_vm_open(struct vm_area_struct *vma) | 66 | static void videobuf_vm_open(struct vm_area_struct *vma) |
67 | { | 67 | { |
68 | struct videobuf_mapping *map = vma->vm_private_data; | 68 | struct videobuf_mapping *map = vma->vm_private_data; |
69 | struct videobuf_queue *q = map->q; | ||
70 | 69 | ||
71 | dev_dbg(q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", | 70 | dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", |
72 | map, map->count, vma->vm_start, vma->vm_end); | 71 | map, map->count, vma->vm_start, vma->vm_end); |
73 | 72 | ||
74 | videobuf_queue_lock(q); | ||
75 | map->count++; | 73 | map->count++; |
76 | videobuf_queue_unlock(q); | ||
77 | } | 74 | } |
78 | 75 | ||
79 | static void videobuf_vm_close(struct vm_area_struct *vma) | 76 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -85,11 +82,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
85 | dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", | 82 | dev_dbg(q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", |
86 | map, map->count, vma->vm_start, vma->vm_end); | 83 | map, map->count, vma->vm_start, vma->vm_end); |
87 | 84 | ||
88 | videobuf_queue_lock(q); | 85 | map->count--; |
89 | if (!--map->count) { | 86 | if (0 == map->count) { |
90 | struct videobuf_dma_contig_memory *mem; | 87 | struct videobuf_dma_contig_memory *mem; |
91 | 88 | ||
92 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); | 89 | dev_dbg(q->dev, "munmap %p q=%p\n", map, q); |
90 | videobuf_queue_lock(q); | ||
93 | 91 | ||
94 | /* We need first to cancel streams, before unmapping */ | 92 | /* We need first to cancel streams, before unmapping */ |
95 | if (q->streaming) | 93 | if (q->streaming) |
@@ -128,8 +126,8 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
128 | 126 | ||
129 | kfree(map); | 127 | kfree(map); |
130 | 128 | ||
129 | videobuf_queue_unlock(q); | ||
131 | } | 130 | } |
132 | videobuf_queue_unlock(q); | ||
133 | } | 131 | } |
134 | 132 | ||
135 | static const struct vm_operations_struct videobuf_vm_ops = { | 133 | static const struct vm_operations_struct videobuf_vm_ops = { |
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c index 9db674ccdc68..828e7c10bd70 100644 --- a/drivers/media/v4l2-core/videobuf-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf-dma-sg.c | |||
@@ -338,14 +338,11 @@ EXPORT_SYMBOL_GPL(videobuf_dma_free); | |||
338 | static void videobuf_vm_open(struct vm_area_struct *vma) | 338 | static void videobuf_vm_open(struct vm_area_struct *vma) |
339 | { | 339 | { |
340 | struct videobuf_mapping *map = vma->vm_private_data; | 340 | struct videobuf_mapping *map = vma->vm_private_data; |
341 | struct videobuf_queue *q = map->q; | ||
342 | 341 | ||
343 | dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map, | 342 | dprintk(2, "vm_open %p [count=%d,vma=%08lx-%08lx]\n", map, |
344 | map->count, vma->vm_start, vma->vm_end); | 343 | map->count, vma->vm_start, vma->vm_end); |
345 | 344 | ||
346 | videobuf_queue_lock(q); | ||
347 | map->count++; | 345 | map->count++; |
348 | videobuf_queue_unlock(q); | ||
349 | } | 346 | } |
350 | 347 | ||
351 | static void videobuf_vm_close(struct vm_area_struct *vma) | 348 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -358,9 +355,10 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
358 | dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map, | 355 | dprintk(2, "vm_close %p [count=%d,vma=%08lx-%08lx]\n", map, |
359 | map->count, vma->vm_start, vma->vm_end); | 356 | map->count, vma->vm_start, vma->vm_end); |
360 | 357 | ||
361 | videobuf_queue_lock(q); | 358 | map->count--; |
362 | if (!--map->count) { | 359 | if (0 == map->count) { |
363 | dprintk(1, "munmap %p q=%p\n", map, q); | 360 | dprintk(1, "munmap %p q=%p\n", map, q); |
361 | videobuf_queue_lock(q); | ||
364 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 362 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
365 | if (NULL == q->bufs[i]) | 363 | if (NULL == q->bufs[i]) |
366 | continue; | 364 | continue; |
@@ -376,9 +374,9 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
376 | q->bufs[i]->baddr = 0; | 374 | q->bufs[i]->baddr = 0; |
377 | q->ops->buf_release(q, q->bufs[i]); | 375 | q->ops->buf_release(q, q->bufs[i]); |
378 | } | 376 | } |
377 | videobuf_queue_unlock(q); | ||
379 | kfree(map); | 378 | kfree(map); |
380 | } | 379 | } |
381 | videobuf_queue_unlock(q); | ||
382 | return; | 380 | return; |
383 | } | 381 | } |
384 | 382 | ||
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c index 1365c651c177..2ff7fcc77b11 100644 --- a/drivers/media/v4l2-core/videobuf-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf-vmalloc.c | |||
@@ -54,14 +54,11 @@ MODULE_LICENSE("GPL"); | |||
54 | static void videobuf_vm_open(struct vm_area_struct *vma) | 54 | static void videobuf_vm_open(struct vm_area_struct *vma) |
55 | { | 55 | { |
56 | struct videobuf_mapping *map = vma->vm_private_data; | 56 | struct videobuf_mapping *map = vma->vm_private_data; |
57 | struct videobuf_queue *q = map->q; | ||
58 | 57 | ||
59 | dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map, | 58 | dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", map, |
60 | map->count, vma->vm_start, vma->vm_end); | 59 | map->count, vma->vm_start, vma->vm_end); |
61 | 60 | ||
62 | videobuf_queue_lock(q); | ||
63 | map->count++; | 61 | map->count++; |
64 | videobuf_queue_unlock(q); | ||
65 | } | 62 | } |
66 | 63 | ||
67 | static void videobuf_vm_close(struct vm_area_struct *vma) | 64 | static void videobuf_vm_close(struct vm_area_struct *vma) |
@@ -73,11 +70,12 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
73 | dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, | 70 | dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", map, |
74 | map->count, vma->vm_start, vma->vm_end); | 71 | map->count, vma->vm_start, vma->vm_end); |
75 | 72 | ||
76 | videobuf_queue_lock(q); | 73 | map->count--; |
77 | if (!--map->count) { | 74 | if (0 == map->count) { |
78 | struct videobuf_vmalloc_memory *mem; | 75 | struct videobuf_vmalloc_memory *mem; |
79 | 76 | ||
80 | dprintk(1, "munmap %p q=%p\n", map, q); | 77 | dprintk(1, "munmap %p q=%p\n", map, q); |
78 | videobuf_queue_lock(q); | ||
81 | 79 | ||
82 | /* We need first to cancel streams, before unmapping */ | 80 | /* We need first to cancel streams, before unmapping */ |
83 | if (q->streaming) | 81 | if (q->streaming) |
@@ -116,8 +114,8 @@ static void videobuf_vm_close(struct vm_area_struct *vma) | |||
116 | 114 | ||
117 | kfree(map); | 115 | kfree(map); |
118 | 116 | ||
117 | videobuf_queue_unlock(q); | ||
119 | } | 118 | } |
120 | videobuf_queue_unlock(q); | ||
121 | 119 | ||
122 | return; | 120 | return; |
123 | } | 121 | } |
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 5a5fb7f09b7b..a127925c9d61 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -1776,6 +1776,11 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
1776 | return 0; | 1776 | return 0; |
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | if (!q->num_buffers) { | ||
1780 | dprintk(1, "streamon: no buffers have been allocated\n"); | ||
1781 | return -EINVAL; | ||
1782 | } | ||
1783 | |||
1779 | /* | 1784 | /* |
1780 | * If any buffers were queued before streamon, | 1785 | * If any buffers were queued before streamon, |
1781 | * we can now pass them to driver for processing. | 1786 | * we can now pass them to driver for processing. |
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c index a60c188c2bd9..04bd3b6de401 100644 --- a/drivers/message/i2o/i2o_config.c +++ b/drivers/message/i2o/i2o_config.c | |||
@@ -754,19 +754,19 @@ static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, | |||
754 | unsigned long arg) | 754 | unsigned long arg) |
755 | { | 755 | { |
756 | int ret; | 756 | int ret; |
757 | mutex_lock(&i2o_cfg_mutex); | ||
758 | switch (cmd) { | 757 | switch (cmd) { |
759 | case I2OGETIOPS: | 758 | case I2OGETIOPS: |
760 | ret = i2o_cfg_ioctl(file, cmd, arg); | 759 | ret = i2o_cfg_ioctl(file, cmd, arg); |
761 | break; | 760 | break; |
762 | case I2OPASSTHRU32: | 761 | case I2OPASSTHRU32: |
762 | mutex_lock(&i2o_cfg_mutex); | ||
763 | ret = i2o_cfg_passthru32(file, cmd, arg); | 763 | ret = i2o_cfg_passthru32(file, cmd, arg); |
764 | mutex_unlock(&i2o_cfg_mutex); | ||
764 | break; | 765 | break; |
765 | default: | 766 | default: |
766 | ret = -ENOIOCTLCMD; | 767 | ret = -ENOIOCTLCMD; |
767 | break; | 768 | break; |
768 | } | 769 | } |
769 | mutex_unlock(&i2o_cfg_mutex); | ||
770 | return ret; | 770 | return ret; |
771 | } | 771 | } |
772 | 772 | ||
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c index 13af7e50021e..8103e4362132 100644 --- a/drivers/mfd/da9055-i2c.c +++ b/drivers/mfd/da9055-i2c.c | |||
@@ -53,17 +53,25 @@ static int da9055_i2c_remove(struct i2c_client *i2c) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* | ||
57 | * DO NOT change the device Ids. The naming is intentionally specific as both | ||
58 | * the PMIC and CODEC parts of this chip are instantiated separately as I2C | ||
59 | * devices (both have configurable I2C addresses, and are to all intents and | ||
60 | * purposes separate). As a result there are specific DA9055 ids for PMIC | ||
61 | * and CODEC, which must be different to operate together. | ||
62 | */ | ||
56 | static struct i2c_device_id da9055_i2c_id[] = { | 63 | static struct i2c_device_id da9055_i2c_id[] = { |
57 | {"da9055", 0}, | 64 | {"da9055-pmic", 0}, |
58 | { } | 65 | { } |
59 | }; | 66 | }; |
67 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | ||
60 | 68 | ||
61 | static struct i2c_driver da9055_i2c_driver = { | 69 | static struct i2c_driver da9055_i2c_driver = { |
62 | .probe = da9055_i2c_probe, | 70 | .probe = da9055_i2c_probe, |
63 | .remove = da9055_i2c_remove, | 71 | .remove = da9055_i2c_remove, |
64 | .id_table = da9055_i2c_id, | 72 | .id_table = da9055_i2c_id, |
65 | .driver = { | 73 | .driver = { |
66 | .name = "da9055", | 74 | .name = "da9055-pmic", |
67 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
68 | }, | 76 | }, |
69 | }; | 77 | }; |
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index ac514fb2b877..71aa14a6bfbb 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c | |||
@@ -173,6 +173,7 @@ static const struct i2c_device_id max14577_i2c_id[] = { | |||
173 | }; | 173 | }; |
174 | MODULE_DEVICE_TABLE(i2c, max14577_i2c_id); | 174 | MODULE_DEVICE_TABLE(i2c, max14577_i2c_id); |
175 | 175 | ||
176 | #ifdef CONFIG_PM_SLEEP | ||
176 | static int max14577_suspend(struct device *dev) | 177 | static int max14577_suspend(struct device *dev) |
177 | { | 178 | { |
178 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 179 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
@@ -208,6 +209,7 @@ static int max14577_resume(struct device *dev) | |||
208 | 209 | ||
209 | return 0; | 210 | return 0; |
210 | } | 211 | } |
212 | #endif /* CONFIG_PM_SLEEP */ | ||
211 | 213 | ||
212 | static struct of_device_id max14577_dt_match[] = { | 214 | static struct of_device_id max14577_dt_match[] = { |
213 | { .compatible = "maxim,max14577", }, | 215 | { .compatible = "maxim,max14577", }, |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index be88a3bf7b85..5adede0fb04c 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -164,15 +164,15 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( | |||
164 | return pd; | 164 | return pd; |
165 | } | 165 | } |
166 | 166 | ||
167 | static inline int max8997_i2c_get_driver_data(struct i2c_client *i2c, | 167 | static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c, |
168 | const struct i2c_device_id *id) | 168 | const struct i2c_device_id *id) |
169 | { | 169 | { |
170 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { | 170 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { |
171 | const struct of_device_id *match; | 171 | const struct of_device_id *match; |
172 | match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); | 172 | match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); |
173 | return (int)match->data; | 173 | return (unsigned long)match->data; |
174 | } | 174 | } |
175 | return (int)id->driver_data; | 175 | return id->driver_data; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int max8997_i2c_probe(struct i2c_client *i2c, | 178 | static int max8997_i2c_probe(struct i2c_client *i2c, |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 612ca404e150..5d5e186b5d8b 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -169,16 +169,16 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata( | |||
169 | return pd; | 169 | return pd; |
170 | } | 170 | } |
171 | 171 | ||
172 | static inline int max8998_i2c_get_driver_data(struct i2c_client *i2c, | 172 | static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c, |
173 | const struct i2c_device_id *id) | 173 | const struct i2c_device_id *id) |
174 | { | 174 | { |
175 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { | 175 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { |
176 | const struct of_device_id *match; | 176 | const struct of_device_id *match; |
177 | match = of_match_node(max8998_dt_match, i2c->dev.of_node); | 177 | match = of_match_node(max8998_dt_match, i2c->dev.of_node); |
178 | return (int)(long)match->data; | 178 | return (unsigned long)match->data; |
179 | } | 179 | } |
180 | 180 | ||
181 | return (int)id->driver_data; | 181 | return id->driver_data; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int max8998_i2c_probe(struct i2c_client *i2c, | 184 | static int max8998_i2c_probe(struct i2c_client *i2c, |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index a139798b8065..714e2135210e 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -315,6 +315,7 @@ static int sec_pmic_remove(struct i2c_client *i2c) | |||
315 | return 0; | 315 | return 0; |
316 | } | 316 | } |
317 | 317 | ||
318 | #ifdef CONFIG_PM_SLEEP | ||
318 | static int sec_pmic_suspend(struct device *dev) | 319 | static int sec_pmic_suspend(struct device *dev) |
319 | { | 320 | { |
320 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 321 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
@@ -349,6 +350,7 @@ static int sec_pmic_resume(struct device *dev) | |||
349 | 350 | ||
350 | return 0; | 351 | return 0; |
351 | } | 352 | } |
353 | #endif /* CONFIG_PM_SLEEP */ | ||
352 | 354 | ||
353 | static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); | 355 | static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); |
354 | 356 | ||
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 966cf65c5c36..3cc4c7084b92 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -158,7 +158,7 @@ static int tps65217_probe(struct i2c_client *client, | |||
158 | { | 158 | { |
159 | struct tps65217 *tps; | 159 | struct tps65217 *tps; |
160 | unsigned int version; | 160 | unsigned int version; |
161 | unsigned int chip_id = ids->driver_data; | 161 | unsigned long chip_id = ids->driver_data; |
162 | const struct of_device_id *match; | 162 | const struct of_device_id *match; |
163 | bool status_off = false; | 163 | bool status_off = false; |
164 | int ret; | 164 | int ret; |
@@ -170,7 +170,7 @@ static int tps65217_probe(struct i2c_client *client, | |||
170 | "Failed to find matching dt id\n"); | 170 | "Failed to find matching dt id\n"); |
171 | return -EINVAL; | 171 | return -EINVAL; |
172 | } | 172 | } |
173 | chip_id = (unsigned int)(unsigned long)match->data; | 173 | chip_id = (unsigned long)match->data; |
174 | status_off = of_property_read_bool(client->dev.of_node, | 174 | status_off = of_property_read_bool(client->dev.of_node, |
175 | "ti,pmic-shutdown-controller"); | 175 | "ti,pmic-shutdown-controller"); |
176 | } | 176 | } |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index ba04f1bc70eb..e6fab94e2c8a 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -636,7 +636,7 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, | |||
636 | if (i2c->dev.of_node) { | 636 | if (i2c->dev.of_node) { |
637 | of_id = of_match_device(wm8994_of_match, &i2c->dev); | 637 | of_id = of_match_device(wm8994_of_match, &i2c->dev); |
638 | if (of_id) | 638 | if (of_id) |
639 | wm8994->type = (int)of_id->data; | 639 | wm8994->type = (enum wm8994_type)of_id->data; |
640 | } else { | 640 | } else { |
641 | wm8994->type = id->driver_data; | 641 | wm8994->type = id->driver_data; |
642 | } | 642 | } |
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 8f8a6b327cdb..2c2c9cc75231 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c | |||
@@ -787,6 +787,7 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m) | |||
787 | if (rc != 0) { | 787 | if (rc != 0) { |
788 | dev_err(&pci_dev->dev, | 788 | dev_err(&pci_dev->dev, |
789 | "[%s] genwqe_user_vmap rc=%d\n", __func__, rc); | 789 | "[%s] genwqe_user_vmap rc=%d\n", __func__, rc); |
790 | kfree(dma_map); | ||
790 | return rc; | 791 | return rc; |
791 | } | 792 | } |
792 | 793 | ||
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 1ee2b9492a82..89a557972d1b 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -666,7 +666,6 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
666 | goto err; | 666 | goto err; |
667 | 667 | ||
668 | cb->fop_type = MEI_FOP_READ; | 668 | cb->fop_type = MEI_FOP_READ; |
669 | cl->read_cb = cb; | ||
670 | if (dev->hbuf_is_ready) { | 669 | if (dev->hbuf_is_ready) { |
671 | dev->hbuf_is_ready = false; | 670 | dev->hbuf_is_ready = false; |
672 | if (mei_hbm_cl_flow_control_req(dev, cl)) { | 671 | if (mei_hbm_cl_flow_control_req(dev, cl)) { |
@@ -678,6 +677,9 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
678 | } else { | 677 | } else { |
679 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | 678 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); |
680 | } | 679 | } |
680 | |||
681 | cl->read_cb = cb; | ||
682 | |||
681 | return rets; | 683 | return rets; |
682 | err: | 684 | err: |
683 | mei_io_cb_free(cb); | 685 | mei_io_cb_free(cb); |
@@ -908,7 +910,6 @@ void mei_cl_all_disconnect(struct mei_device *dev) | |||
908 | list_for_each_entry_safe(cl, next, &dev->file_list, link) { | 910 | list_for_each_entry_safe(cl, next, &dev->file_list, link) { |
909 | cl->state = MEI_FILE_DISCONNECTED; | 911 | cl->state = MEI_FILE_DISCONNECTED; |
910 | cl->mei_flow_ctrl_creds = 0; | 912 | cl->mei_flow_ctrl_creds = 0; |
911 | cl->read_cb = NULL; | ||
912 | cl->timer_count = 0; | 913 | cl->timer_count = 0; |
913 | } | 914 | } |
914 | } | 915 | } |
@@ -942,8 +943,16 @@ void mei_cl_all_wakeup(struct mei_device *dev) | |||
942 | void mei_cl_all_write_clear(struct mei_device *dev) | 943 | void mei_cl_all_write_clear(struct mei_device *dev) |
943 | { | 944 | { |
944 | struct mei_cl_cb *cb, *next; | 945 | struct mei_cl_cb *cb, *next; |
946 | struct list_head *list; | ||
947 | |||
948 | list = &dev->write_list.list; | ||
949 | list_for_each_entry_safe(cb, next, list, list) { | ||
950 | list_del(&cb->list); | ||
951 | mei_io_cb_free(cb); | ||
952 | } | ||
945 | 953 | ||
946 | list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { | 954 | list = &dev->write_waiting_list.list; |
955 | list_for_each_entry_safe(cb, next, list, list) { | ||
947 | list_del(&cb->list); | 956 | list_del(&cb->list); |
948 | mei_io_cb_free(cb); | 957 | mei_io_cb_free(cb); |
949 | } | 958 | } |
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c index 752ff873f891..7e1ef0ebbb80 100644 --- a/drivers/misc/mic/host/mic_virtio.c +++ b/drivers/misc/mic/host/mic_virtio.c | |||
@@ -156,7 +156,8 @@ static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov, | |||
156 | static int _mic_virtio_copy(struct mic_vdev *mvdev, | 156 | static int _mic_virtio_copy(struct mic_vdev *mvdev, |
157 | struct mic_copy_desc *copy) | 157 | struct mic_copy_desc *copy) |
158 | { | 158 | { |
159 | int ret = 0, iovcnt = copy->iovcnt; | 159 | int ret = 0; |
160 | u32 iovcnt = copy->iovcnt; | ||
160 | struct iovec iov; | 161 | struct iovec iov; |
161 | struct iovec __user *u_iov = copy->iov; | 162 | struct iovec __user *u_iov = copy->iov; |
162 | void __user *ubuf = NULL; | 163 | void __user *ubuf = NULL; |
diff --git a/drivers/misc/sgi-gru/grukdump.c b/drivers/misc/sgi-gru/grukdump.c index 9b2062d17327..2bef3f76032a 100644 --- a/drivers/misc/sgi-gru/grukdump.c +++ b/drivers/misc/sgi-gru/grukdump.c | |||
@@ -139,8 +139,11 @@ static int gru_dump_context(struct gru_state *gru, int ctxnum, | |||
139 | 139 | ||
140 | ubuf += sizeof(hdr); | 140 | ubuf += sizeof(hdr); |
141 | ubufcch = ubuf; | 141 | ubufcch = ubuf; |
142 | if (gru_user_copy_handle(&ubuf, cch)) | 142 | if (gru_user_copy_handle(&ubuf, cch)) { |
143 | goto fail; | 143 | if (cch_locked) |
144 | unlock_cch_handle(cch); | ||
145 | return -EFAULT; | ||
146 | } | ||
144 | if (cch_locked) | 147 | if (cch_locked) |
145 | ubufcch->delresp = 0; | 148 | ubufcch->delresp = 0; |
146 | bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES; | 149 | bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES; |
@@ -179,10 +182,6 @@ static int gru_dump_context(struct gru_state *gru, int ctxnum, | |||
179 | ret = -EFAULT; | 182 | ret = -EFAULT; |
180 | 183 | ||
181 | return ret ? ret : bytes; | 184 | return ret ? ret : bytes; |
182 | |||
183 | fail: | ||
184 | unlock_cch_handle(cch); | ||
185 | return -EFAULT; | ||
186 | } | 185 | } |
187 | 186 | ||
188 | int gru_dump_chiplet_request(unsigned long arg) | 187 | int gru_dump_chiplet_request(unsigned long arg) |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index b9e2000969f0..95c894482fdd 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -240,7 +240,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, | |||
240 | 240 | ||
241 | nid = cpu_to_node(cpu); | 241 | nid = cpu_to_node(cpu); |
242 | page = alloc_pages_exact_node(nid, | 242 | page = alloc_pages_exact_node(nid, |
243 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 243 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE, |
244 | pg_order); | 244 | pg_order); |
245 | if (page == NULL) { | 245 | if (page == NULL) { |
246 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " | 246 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 357bbc54fe4b..3e049c13429c 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -197,7 +197,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, | |||
197 | struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; | 197 | struct mmc_queue_req *mqrq_prev = &mq->mqrq[1]; |
198 | 198 | ||
199 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) | 199 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) |
200 | limit = dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; | 200 | limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT; |
201 | 201 | ||
202 | mq->card = card; | 202 | mq->card = card; |
203 | mq->queue = blk_init_queue(mmc_request_fn, lock); | 203 | mq->queue = blk_init_queue(mmc_request_fn, lock); |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 59eba5d2c685..9715a7ba164a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -1584,7 +1584,7 @@ read_retry: | |||
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | if (mtd->ecc_stats.failed - ecc_failures) { | 1586 | if (mtd->ecc_stats.failed - ecc_failures) { |
1587 | if (retry_mode + 1 <= chip->read_retries) { | 1587 | if (retry_mode + 1 < chip->read_retries) { |
1588 | retry_mode++; | 1588 | retry_mode++; |
1589 | ret = nand_setup_read_retry(mtd, | 1589 | ret = nand_setup_read_retry(mtd, |
1590 | retry_mode); | 1590 | retry_mode); |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index ef4190a02b7b..bf642ceef681 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1633,6 +1633,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1633 | int i; | 1633 | int i; |
1634 | dma_cap_mask_t mask; | 1634 | dma_cap_mask_t mask; |
1635 | unsigned sig; | 1635 | unsigned sig; |
1636 | unsigned oob_index; | ||
1636 | struct resource *res; | 1637 | struct resource *res; |
1637 | struct mtd_part_parser_data ppdata = {}; | 1638 | struct mtd_part_parser_data ppdata = {}; |
1638 | 1639 | ||
@@ -1826,11 +1827,14 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1826 | (mtd->writesize / | 1827 | (mtd->writesize / |
1827 | nand_chip->ecc.size); | 1828 | nand_chip->ecc.size); |
1828 | if (nand_chip->options & NAND_BUSWIDTH_16) | 1829 | if (nand_chip->options & NAND_BUSWIDTH_16) |
1829 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1830 | oob_index = BADBLOCK_MARKER_LENGTH; |
1830 | else | 1831 | else |
1831 | ecclayout->eccpos[0] = 1; | 1832 | oob_index = 1; |
1832 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1833 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1833 | ecclayout->eccbytes; | 1834 | ecclayout->eccpos[i] = oob_index; |
1835 | /* no reserved-marker in ecclayout for this ecc-scheme */ | ||
1836 | ecclayout->oobfree->offset = | ||
1837 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1834 | break; | 1838 | break; |
1835 | 1839 | ||
1836 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: | 1840 | case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW: |
@@ -1847,9 +1851,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1847 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1851 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1848 | (mtd->writesize / | 1852 | (mtd->writesize / |
1849 | nand_chip->ecc.size); | 1853 | nand_chip->ecc.size); |
1850 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1854 | oob_index = BADBLOCK_MARKER_LENGTH; |
1851 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1855 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1852 | ecclayout->eccbytes; | 1856 | ecclayout->eccpos[i] = oob_index; |
1857 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1858 | oob_index++; | ||
1859 | } | ||
1860 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1861 | ecclayout->oobfree->offset = 1 + | ||
1862 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1853 | /* software bch library is used for locating errors */ | 1863 | /* software bch library is used for locating errors */ |
1854 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1864 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1855 | nand_chip->ecc.size, | 1865 | nand_chip->ecc.size, |
@@ -1883,9 +1893,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1883 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1893 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1884 | (mtd->writesize / | 1894 | (mtd->writesize / |
1885 | nand_chip->ecc.size); | 1895 | nand_chip->ecc.size); |
1886 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1896 | oob_index = BADBLOCK_MARKER_LENGTH; |
1887 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1897 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1888 | ecclayout->eccbytes; | 1898 | ecclayout->eccpos[i] = oob_index; |
1899 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1900 | ecclayout->oobfree->offset = | ||
1901 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1889 | /* This ECC scheme requires ELM H/W block */ | 1902 | /* This ECC scheme requires ELM H/W block */ |
1890 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { | 1903 | if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) { |
1891 | pr_err("nand: error: could not initialize ELM\n"); | 1904 | pr_err("nand: error: could not initialize ELM\n"); |
@@ -1913,9 +1926,15 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1913 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1926 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1914 | (mtd->writesize / | 1927 | (mtd->writesize / |
1915 | nand_chip->ecc.size); | 1928 | nand_chip->ecc.size); |
1916 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1929 | oob_index = BADBLOCK_MARKER_LENGTH; |
1917 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1930 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) { |
1918 | ecclayout->eccbytes; | 1931 | ecclayout->eccpos[i] = oob_index; |
1932 | if (((i + 1) % nand_chip->ecc.bytes) == 0) | ||
1933 | oob_index++; | ||
1934 | } | ||
1935 | /* include reserved-marker in ecclayout->oobfree calculation */ | ||
1936 | ecclayout->oobfree->offset = 1 + | ||
1937 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1919 | /* software bch library is used for locating errors */ | 1938 | /* software bch library is used for locating errors */ |
1920 | nand_chip->ecc.priv = nand_bch_init(mtd, | 1939 | nand_chip->ecc.priv = nand_bch_init(mtd, |
1921 | nand_chip->ecc.size, | 1940 | nand_chip->ecc.size, |
@@ -1956,9 +1975,12 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1956 | ecclayout->eccbytes = nand_chip->ecc.bytes * | 1975 | ecclayout->eccbytes = nand_chip->ecc.bytes * |
1957 | (mtd->writesize / | 1976 | (mtd->writesize / |
1958 | nand_chip->ecc.size); | 1977 | nand_chip->ecc.size); |
1959 | ecclayout->eccpos[0] = BADBLOCK_MARKER_LENGTH; | 1978 | oob_index = BADBLOCK_MARKER_LENGTH; |
1960 | ecclayout->oobfree->offset = ecclayout->eccpos[0] + | 1979 | for (i = 0; i < ecclayout->eccbytes; i++, oob_index++) |
1961 | ecclayout->eccbytes; | 1980 | ecclayout->eccpos[i] = oob_index; |
1981 | /* reserved marker already included in ecclayout->eccbytes */ | ||
1982 | ecclayout->oobfree->offset = | ||
1983 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | ||
1962 | break; | 1984 | break; |
1963 | #else | 1985 | #else |
1964 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); | 1986 | pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n"); |
@@ -1972,11 +1994,8 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1972 | goto return_error; | 1994 | goto return_error; |
1973 | } | 1995 | } |
1974 | 1996 | ||
1975 | /* populate remaining ECC layout data */ | 1997 | /* all OOB bytes from oobfree->offset till end off OOB are free */ |
1976 | ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH + | 1998 | ecclayout->oobfree->length = mtd->oobsize - ecclayout->oobfree->offset; |
1977 | ecclayout->eccbytes); | ||
1978 | for (i = 1; i < ecclayout->eccbytes; i++) | ||
1979 | ecclayout->eccpos[i] = ecclayout->eccpos[0] + i; | ||
1980 | /* check if NAND device's OOB is enough to store ECC signatures */ | 1999 | /* check if NAND device's OOB is enough to store ECC signatures */ |
1981 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { | 2000 | if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) { |
1982 | pr_err("not enough OOB bytes required = %d, available=%d\n", | 2001 | pr_err("not enough OOB bytes required = %d, available=%d\n", |
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index ead861307b3c..c5dad652614d 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c | |||
@@ -463,8 +463,8 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai, | |||
463 | } | 463 | } |
464 | } | 464 | } |
465 | if (found_orphan) { | 465 | if (found_orphan) { |
466 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
467 | list_del(&tmp_aeb->u.list); | 466 | list_del(&tmp_aeb->u.list); |
467 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
468 | } | 468 | } |
469 | 469 | ||
470 | new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, | 470 | new_aeb = kmem_cache_alloc(ai->aeb_slab_cache, |
@@ -846,16 +846,16 @@ fail_bad: | |||
846 | ret = UBI_BAD_FASTMAP; | 846 | ret = UBI_BAD_FASTMAP; |
847 | fail: | 847 | fail: |
848 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { | 848 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &used, u.list) { |
849 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
850 | list_del(&tmp_aeb->u.list); | 849 | list_del(&tmp_aeb->u.list); |
850 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
851 | } | 851 | } |
852 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { | 852 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans, u.list) { |
853 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
854 | list_del(&tmp_aeb->u.list); | 853 | list_del(&tmp_aeb->u.list); |
854 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
855 | } | 855 | } |
856 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { | 856 | list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) { |
857 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
858 | list_del(&tmp_aeb->u.list); | 857 | list_del(&tmp_aeb->u.list); |
858 | kmem_cache_free(ai->aeb_slab_cache, tmp_aeb); | ||
859 | } | 859 | } |
860 | 860 | ||
861 | return ret; | 861 | return ret; |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f342278539d5..494b888a6568 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -139,7 +139,7 @@ config MACVTAP | |||
139 | This adds a specialized tap character device driver that is based | 139 | This adds a specialized tap character device driver that is based |
140 | on the MAC-VLAN network interface, called macvtap. A macvtap device | 140 | on the MAC-VLAN network interface, called macvtap. A macvtap device |
141 | can be added in the same way as a macvlan device, using 'type | 141 | can be added in the same way as a macvlan device, using 'type |
142 | macvlan', and then be accessed through the tap user space interface. | 142 | macvtap', and then be accessed through the tap user space interface. |
143 | 143 | ||
144 | To compile this driver as a module, choose M here: the module | 144 | To compile this driver as a module, choose M here: the module |
145 | will be called macvtap. | 145 | will be called macvtap. |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index cce1f1bf90b4..dcde56057fe1 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -181,7 +181,7 @@ static inline int __agg_has_partner(struct aggregator *agg) | |||
181 | */ | 181 | */ |
182 | static inline void __disable_port(struct port *port) | 182 | static inline void __disable_port(struct port *port) |
183 | { | 183 | { |
184 | bond_set_slave_inactive_flags(port->slave); | 184 | bond_set_slave_inactive_flags(port->slave, BOND_SLAVE_NOTIFY_LATER); |
185 | } | 185 | } |
186 | 186 | ||
187 | /** | 187 | /** |
@@ -193,7 +193,7 @@ static inline void __enable_port(struct port *port) | |||
193 | struct slave *slave = port->slave; | 193 | struct slave *slave = port->slave; |
194 | 194 | ||
195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) | 195 | if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) |
196 | bond_set_slave_active_flags(slave); | 196 | bond_set_slave_active_flags(slave, BOND_SLAVE_NOTIFY_LATER); |
197 | } | 197 | } |
198 | 198 | ||
199 | /** | 199 | /** |
@@ -1796,8 +1796,6 @@ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) | |||
1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; | 1796 | BOND_AD_INFO(bond).agg_select_timer = timeout; |
1797 | } | 1797 | } |
1798 | 1798 | ||
1799 | static u16 aggregator_identifier; | ||
1800 | |||
1801 | /** | 1799 | /** |
1802 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures | 1800 | * bond_3ad_initialize - initialize a bond's 802.3ad parameters and structures |
1803 | * @bond: bonding struct to work on | 1801 | * @bond: bonding struct to work on |
@@ -1811,7 +1809,7 @@ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) | |||
1811 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), | 1809 | if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), |
1812 | bond->dev->dev_addr)) { | 1810 | bond->dev->dev_addr)) { |
1813 | 1811 | ||
1814 | aggregator_identifier = 0; | 1812 | BOND_AD_INFO(bond).aggregator_identifier = 0; |
1815 | 1813 | ||
1816 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; | 1814 | BOND_AD_INFO(bond).system.sys_priority = 0xFFFF; |
1817 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); | 1815 | BOND_AD_INFO(bond).system.sys_mac_addr = *((struct mac_addr *)bond->dev->dev_addr); |
@@ -1880,7 +1878,7 @@ void bond_3ad_bind_slave(struct slave *slave) | |||
1880 | ad_initialize_agg(aggregator); | 1878 | ad_initialize_agg(aggregator); |
1881 | 1879 | ||
1882 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); | 1880 | aggregator->aggregator_mac_address = *((struct mac_addr *)bond->dev->dev_addr); |
1883 | aggregator->aggregator_identifier = (++aggregator_identifier); | 1881 | aggregator->aggregator_identifier = ++BOND_AD_INFO(bond).aggregator_identifier; |
1884 | aggregator->slave = slave; | 1882 | aggregator->slave = slave; |
1885 | aggregator->is_active = 0; | 1883 | aggregator->is_active = 0; |
1886 | aggregator->num_of_ports = 0; | 1884 | aggregator->num_of_ports = 0; |
@@ -2064,6 +2062,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2064 | struct list_head *iter; | 2062 | struct list_head *iter; |
2065 | struct slave *slave; | 2063 | struct slave *slave; |
2066 | struct port *port; | 2064 | struct port *port; |
2065 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | ||
2067 | 2066 | ||
2068 | read_lock(&bond->lock); | 2067 | read_lock(&bond->lock); |
2069 | rcu_read_lock(); | 2068 | rcu_read_lock(); |
@@ -2121,8 +2120,19 @@ void bond_3ad_state_machine_handler(struct work_struct *work) | |||
2121 | } | 2120 | } |
2122 | 2121 | ||
2123 | re_arm: | 2122 | re_arm: |
2123 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
2124 | if (slave->should_notify) { | ||
2125 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
2126 | break; | ||
2127 | } | ||
2128 | } | ||
2124 | rcu_read_unlock(); | 2129 | rcu_read_unlock(); |
2125 | read_unlock(&bond->lock); | 2130 | read_unlock(&bond->lock); |
2131 | |||
2132 | if (should_notify_rtnl && rtnl_trylock()) { | ||
2133 | bond_slave_state_notify(bond); | ||
2134 | rtnl_unlock(); | ||
2135 | } | ||
2126 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); | 2136 | queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks); |
2127 | } | 2137 | } |
2128 | 2138 | ||
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index 13dc9d3c5e34..f4dd9592ac62 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -253,6 +253,7 @@ struct ad_system { | |||
253 | struct ad_bond_info { | 253 | struct ad_bond_info { |
254 | struct ad_system system; /* 802.3ad system structure */ | 254 | struct ad_system system; /* 802.3ad system structure */ |
255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes | 255 | u32 agg_select_timer; // Timer to select aggregator after all adapter's hand shakes |
256 | u16 aggregator_identifier; | ||
256 | }; | 257 | }; |
257 | 258 | ||
258 | struct ad_slave_info { | 259 | struct ad_slave_info { |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index a2c47476804d..e8f133e926aa 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -730,7 +730,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon | |||
730 | client_info->ntt = 0; | 730 | client_info->ntt = 0; |
731 | } | 731 | } |
732 | 732 | ||
733 | if (!vlan_get_tag(skb, &client_info->vlan_id)) | 733 | if (vlan_get_tag(skb, &client_info->vlan_id)) |
734 | client_info->vlan_id = 0; | 734 | client_info->vlan_id = 0; |
735 | 735 | ||
736 | if (!client_info->assigned) { | 736 | if (!client_info->assigned) { |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4c08018d7333..e5628fc725c3 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -829,21 +829,25 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
829 | if (bond_is_lb(bond)) { | 829 | if (bond_is_lb(bond)) { |
830 | bond_alb_handle_active_change(bond, new_active); | 830 | bond_alb_handle_active_change(bond, new_active); |
831 | if (old_active) | 831 | if (old_active) |
832 | bond_set_slave_inactive_flags(old_active); | 832 | bond_set_slave_inactive_flags(old_active, |
833 | BOND_SLAVE_NOTIFY_NOW); | ||
833 | if (new_active) | 834 | if (new_active) |
834 | bond_set_slave_active_flags(new_active); | 835 | bond_set_slave_active_flags(new_active, |
836 | BOND_SLAVE_NOTIFY_NOW); | ||
835 | } else { | 837 | } else { |
836 | rcu_assign_pointer(bond->curr_active_slave, new_active); | 838 | rcu_assign_pointer(bond->curr_active_slave, new_active); |
837 | } | 839 | } |
838 | 840 | ||
839 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | 841 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
840 | if (old_active) | 842 | if (old_active) |
841 | bond_set_slave_inactive_flags(old_active); | 843 | bond_set_slave_inactive_flags(old_active, |
844 | BOND_SLAVE_NOTIFY_NOW); | ||
842 | 845 | ||
843 | if (new_active) { | 846 | if (new_active) { |
844 | bool should_notify_peers = false; | 847 | bool should_notify_peers = false; |
845 | 848 | ||
846 | bond_set_slave_active_flags(new_active); | 849 | bond_set_slave_active_flags(new_active, |
850 | BOND_SLAVE_NOTIFY_NOW); | ||
847 | 851 | ||
848 | if (bond->params.fail_over_mac) | 852 | if (bond->params.fail_over_mac) |
849 | bond_do_fail_over_mac(bond, new_active, | 853 | bond_do_fail_over_mac(bond, new_active, |
@@ -1193,6 +1197,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1193 | return -EBUSY; | 1197 | return -EBUSY; |
1194 | } | 1198 | } |
1195 | 1199 | ||
1200 | if (bond_dev == slave_dev) { | ||
1201 | pr_err("%s: cannot enslave bond to itself.\n", bond_dev->name); | ||
1202 | return -EPERM; | ||
1203 | } | ||
1204 | |||
1196 | /* vlan challenged mutual exclusion */ | 1205 | /* vlan challenged mutual exclusion */ |
1197 | /* no need to lock since we're protected by rtnl_lock */ | 1206 | /* no need to lock since we're protected by rtnl_lock */ |
1198 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { | 1207 | if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { |
@@ -1270,9 +1279,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1270 | 1279 | ||
1271 | if (slave_ops->ndo_set_mac_address == NULL) { | 1280 | if (slave_ops->ndo_set_mac_address == NULL) { |
1272 | if (!bond_has_slaves(bond)) { | 1281 | if (!bond_has_slaves(bond)) { |
1273 | pr_warning("%s: Warning: The first slave device specified does not support setting the MAC address. Setting fail_over_mac to active.", | 1282 | pr_warn("%s: Warning: The first slave device specified does not support setting the MAC address.\n", |
1274 | bond_dev->name); | 1283 | bond_dev->name); |
1275 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | 1284 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { |
1285 | bond->params.fail_over_mac = BOND_FOM_ACTIVE; | ||
1286 | pr_warn("%s: Setting fail_over_mac to active for active-backup mode.\n", | ||
1287 | bond_dev->name); | ||
1288 | } | ||
1276 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1289 | } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { |
1277 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", | 1290 | pr_err("%s: Error: The slave device specified does not support setting the MAC address, but fail_over_mac is not set to active.\n", |
1278 | bond_dev->name); | 1291 | bond_dev->name); |
@@ -1315,7 +1328,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1315 | */ | 1328 | */ |
1316 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); | 1329 | memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN); |
1317 | 1330 | ||
1318 | if (!bond->params.fail_over_mac) { | 1331 | if (!bond->params.fail_over_mac || |
1332 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1319 | /* | 1333 | /* |
1320 | * Set slave to master's mac address. The application already | 1334 | * Set slave to master's mac address. The application already |
1321 | * set the master's mac address to that of the first slave | 1335 | * set the master's mac address to that of the first slave |
@@ -1458,14 +1472,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1458 | 1472 | ||
1459 | switch (bond->params.mode) { | 1473 | switch (bond->params.mode) { |
1460 | case BOND_MODE_ACTIVEBACKUP: | 1474 | case BOND_MODE_ACTIVEBACKUP: |
1461 | bond_set_slave_inactive_flags(new_slave); | 1475 | bond_set_slave_inactive_flags(new_slave, |
1476 | BOND_SLAVE_NOTIFY_NOW); | ||
1462 | break; | 1477 | break; |
1463 | case BOND_MODE_8023AD: | 1478 | case BOND_MODE_8023AD: |
1464 | /* in 802.3ad mode, the internal mechanism | 1479 | /* in 802.3ad mode, the internal mechanism |
1465 | * will activate the slaves in the selected | 1480 | * will activate the slaves in the selected |
1466 | * aggregator | 1481 | * aggregator |
1467 | */ | 1482 | */ |
1468 | bond_set_slave_inactive_flags(new_slave); | 1483 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
1469 | /* if this is the first slave */ | 1484 | /* if this is the first slave */ |
1470 | if (!prev_slave) { | 1485 | if (!prev_slave) { |
1471 | SLAVE_AD_INFO(new_slave).id = 1; | 1486 | SLAVE_AD_INFO(new_slave).id = 1; |
@@ -1483,7 +1498,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1483 | case BOND_MODE_TLB: | 1498 | case BOND_MODE_TLB: |
1484 | case BOND_MODE_ALB: | 1499 | case BOND_MODE_ALB: |
1485 | bond_set_active_slave(new_slave); | 1500 | bond_set_active_slave(new_slave); |
1486 | bond_set_slave_inactive_flags(new_slave); | 1501 | bond_set_slave_inactive_flags(new_slave, BOND_SLAVE_NOTIFY_NOW); |
1487 | break; | 1502 | break; |
1488 | default: | 1503 | default: |
1489 | pr_debug("This slave is always active in trunk mode\n"); | 1504 | pr_debug("This slave is always active in trunk mode\n"); |
@@ -1505,7 +1520,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1505 | slave_dev->npinfo = bond->dev->npinfo; | 1520 | slave_dev->npinfo = bond->dev->npinfo; |
1506 | if (slave_dev->npinfo) { | 1521 | if (slave_dev->npinfo) { |
1507 | if (slave_enable_netpoll(new_slave)) { | 1522 | if (slave_enable_netpoll(new_slave)) { |
1508 | read_unlock(&bond->lock); | ||
1509 | pr_info("Error, %s: master_dev is using netpoll, " | 1523 | pr_info("Error, %s: master_dev is using netpoll, " |
1510 | "but new slave device does not support netpoll.\n", | 1524 | "but new slave device does not support netpoll.\n", |
1511 | bond_dev->name); | 1525 | bond_dev->name); |
@@ -1539,9 +1553,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1539 | bond_set_carrier(bond); | 1553 | bond_set_carrier(bond); |
1540 | 1554 | ||
1541 | if (USES_PRIMARY(bond->params.mode)) { | 1555 | if (USES_PRIMARY(bond->params.mode)) { |
1556 | block_netpoll_tx(); | ||
1542 | write_lock_bh(&bond->curr_slave_lock); | 1557 | write_lock_bh(&bond->curr_slave_lock); |
1543 | bond_select_active_slave(bond); | 1558 | bond_select_active_slave(bond); |
1544 | write_unlock_bh(&bond->curr_slave_lock); | 1559 | write_unlock_bh(&bond->curr_slave_lock); |
1560 | unblock_netpoll_tx(); | ||
1545 | } | 1561 | } |
1546 | 1562 | ||
1547 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | 1563 | pr_info("%s: enslaving %s as a%s interface with a%s link.\n", |
@@ -1567,10 +1583,12 @@ err_detach: | |||
1567 | if (bond->primary_slave == new_slave) | 1583 | if (bond->primary_slave == new_slave) |
1568 | bond->primary_slave = NULL; | 1584 | bond->primary_slave = NULL; |
1569 | if (bond->curr_active_slave == new_slave) { | 1585 | if (bond->curr_active_slave == new_slave) { |
1586 | block_netpoll_tx(); | ||
1570 | write_lock_bh(&bond->curr_slave_lock); | 1587 | write_lock_bh(&bond->curr_slave_lock); |
1571 | bond_change_active_slave(bond, NULL); | 1588 | bond_change_active_slave(bond, NULL); |
1572 | bond_select_active_slave(bond); | 1589 | bond_select_active_slave(bond); |
1573 | write_unlock_bh(&bond->curr_slave_lock); | 1590 | write_unlock_bh(&bond->curr_slave_lock); |
1591 | unblock_netpoll_tx(); | ||
1574 | } | 1592 | } |
1575 | slave_disable_netpoll(new_slave); | 1593 | slave_disable_netpoll(new_slave); |
1576 | 1594 | ||
@@ -1579,7 +1597,8 @@ err_close: | |||
1579 | dev_close(slave_dev); | 1597 | dev_close(slave_dev); |
1580 | 1598 | ||
1581 | err_restore_mac: | 1599 | err_restore_mac: |
1582 | if (!bond->params.fail_over_mac) { | 1600 | if (!bond->params.fail_over_mac || |
1601 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1583 | /* XXX TODO - fom follow mode needs to change master's | 1602 | /* XXX TODO - fom follow mode needs to change master's |
1584 | * MAC if this slave's MAC is in use by the bond, or at | 1603 | * MAC if this slave's MAC is in use by the bond, or at |
1585 | * least print a warning. | 1604 | * least print a warning. |
@@ -1645,9 +1664,6 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1645 | return -EINVAL; | 1664 | return -EINVAL; |
1646 | } | 1665 | } |
1647 | 1666 | ||
1648 | /* release the slave from its bond */ | ||
1649 | bond->slave_cnt--; | ||
1650 | |||
1651 | bond_sysfs_slave_del(slave); | 1667 | bond_sysfs_slave_del(slave); |
1652 | 1668 | ||
1653 | bond_upper_dev_unlink(bond_dev, slave_dev); | 1669 | bond_upper_dev_unlink(bond_dev, slave_dev); |
@@ -1672,7 +1688,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1672 | 1688 | ||
1673 | bond->current_arp_slave = NULL; | 1689 | bond->current_arp_slave = NULL; |
1674 | 1690 | ||
1675 | if (!all && !bond->params.fail_over_mac) { | 1691 | if (!all && (!bond->params.fail_over_mac || |
1692 | bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
1676 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && | 1693 | if (ether_addr_equal_64bits(bond_dev->dev_addr, slave->perm_hwaddr) && |
1677 | bond_has_slaves(bond)) | 1694 | bond_has_slaves(bond)) |
1678 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", | 1695 | pr_warn("%s: Warning: the permanent HWaddr of %s - %pM - is still in use by %s. Set the HWaddr of %s to a different address to avoid conflicts.\n", |
@@ -1728,6 +1745,7 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1728 | 1745 | ||
1729 | unblock_netpoll_tx(); | 1746 | unblock_netpoll_tx(); |
1730 | synchronize_rcu(); | 1747 | synchronize_rcu(); |
1748 | bond->slave_cnt--; | ||
1731 | 1749 | ||
1732 | if (!bond_has_slaves(bond)) { | 1750 | if (!bond_has_slaves(bond)) { |
1733 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); | 1751 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); |
@@ -1769,7 +1787,8 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1769 | /* close slave before restoring its mac address */ | 1787 | /* close slave before restoring its mac address */ |
1770 | dev_close(slave_dev); | 1788 | dev_close(slave_dev); |
1771 | 1789 | ||
1772 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) { | 1790 | if (bond->params.fail_over_mac != BOND_FOM_ACTIVE || |
1791 | bond->params.mode != BOND_MODE_ACTIVEBACKUP) { | ||
1773 | /* restore original ("permanent") mac address */ | 1792 | /* restore original ("permanent") mac address */ |
1774 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); | 1793 | memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); |
1775 | addr.sa_family = slave_dev->type; | 1794 | addr.sa_family = slave_dev->type; |
@@ -2004,7 +2023,8 @@ static void bond_miimon_commit(struct bonding *bond) | |||
2004 | 2023 | ||
2005 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || | 2024 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP || |
2006 | bond->params.mode == BOND_MODE_8023AD) | 2025 | bond->params.mode == BOND_MODE_8023AD) |
2007 | bond_set_slave_inactive_flags(slave); | 2026 | bond_set_slave_inactive_flags(slave, |
2027 | BOND_SLAVE_NOTIFY_NOW); | ||
2008 | 2028 | ||
2009 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2029 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
2010 | bond->dev->name, slave->dev->name); | 2030 | bond->dev->name, slave->dev->name); |
@@ -2551,7 +2571,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
2551 | slave->link = BOND_LINK_UP; | 2571 | slave->link = BOND_LINK_UP; |
2552 | if (bond->current_arp_slave) { | 2572 | if (bond->current_arp_slave) { |
2553 | bond_set_slave_inactive_flags( | 2573 | bond_set_slave_inactive_flags( |
2554 | bond->current_arp_slave); | 2574 | bond->current_arp_slave, |
2575 | BOND_SLAVE_NOTIFY_NOW); | ||
2555 | bond->current_arp_slave = NULL; | 2576 | bond->current_arp_slave = NULL; |
2556 | } | 2577 | } |
2557 | 2578 | ||
@@ -2571,7 +2592,8 @@ static void bond_ab_arp_commit(struct bonding *bond) | |||
2571 | slave->link_failure_count++; | 2592 | slave->link_failure_count++; |
2572 | 2593 | ||
2573 | slave->link = BOND_LINK_DOWN; | 2594 | slave->link = BOND_LINK_DOWN; |
2574 | bond_set_slave_inactive_flags(slave); | 2595 | bond_set_slave_inactive_flags(slave, |
2596 | BOND_SLAVE_NOTIFY_NOW); | ||
2575 | 2597 | ||
2576 | pr_info("%s: link status definitely down for interface %s, disabling it\n", | 2598 | pr_info("%s: link status definitely down for interface %s, disabling it\n", |
2577 | bond->dev->name, slave->dev->name); | 2599 | bond->dev->name, slave->dev->name); |
@@ -2604,17 +2626,17 @@ do_failover: | |||
2604 | 2626 | ||
2605 | /* | 2627 | /* |
2606 | * Send ARP probes for active-backup mode ARP monitor. | 2628 | * Send ARP probes for active-backup mode ARP monitor. |
2629 | * | ||
2630 | * Called with rcu_read_lock hold. | ||
2607 | */ | 2631 | */ |
2608 | static bool bond_ab_arp_probe(struct bonding *bond) | 2632 | static bool bond_ab_arp_probe(struct bonding *bond) |
2609 | { | 2633 | { |
2610 | struct slave *slave, *before = NULL, *new_slave = NULL, | 2634 | struct slave *slave, *before = NULL, *new_slave = NULL, |
2611 | *curr_arp_slave, *curr_active_slave; | 2635 | *curr_arp_slave = rcu_dereference(bond->current_arp_slave), |
2636 | *curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
2612 | struct list_head *iter; | 2637 | struct list_head *iter; |
2613 | bool found = false; | 2638 | bool found = false; |
2614 | 2639 | bool should_notify_rtnl = BOND_SLAVE_NOTIFY_LATER; | |
2615 | rcu_read_lock(); | ||
2616 | curr_arp_slave = rcu_dereference(bond->current_arp_slave); | ||
2617 | curr_active_slave = rcu_dereference(bond->curr_active_slave); | ||
2618 | 2640 | ||
2619 | if (curr_arp_slave && curr_active_slave) | 2641 | if (curr_arp_slave && curr_active_slave) |
2620 | pr_info("PROBE: c_arp %s && cas %s BAD\n", | 2642 | pr_info("PROBE: c_arp %s && cas %s BAD\n", |
@@ -2623,32 +2645,23 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2623 | 2645 | ||
2624 | if (curr_active_slave) { | 2646 | if (curr_active_slave) { |
2625 | bond_arp_send_all(bond, curr_active_slave); | 2647 | bond_arp_send_all(bond, curr_active_slave); |
2626 | rcu_read_unlock(); | 2648 | return should_notify_rtnl; |
2627 | return true; | ||
2628 | } | 2649 | } |
2629 | rcu_read_unlock(); | ||
2630 | 2650 | ||
2631 | /* if we don't have a curr_active_slave, search for the next available | 2651 | /* if we don't have a curr_active_slave, search for the next available |
2632 | * backup slave from the current_arp_slave and make it the candidate | 2652 | * backup slave from the current_arp_slave and make it the candidate |
2633 | * for becoming the curr_active_slave | 2653 | * for becoming the curr_active_slave |
2634 | */ | 2654 | */ |
2635 | 2655 | ||
2636 | if (!rtnl_trylock()) | ||
2637 | return false; | ||
2638 | /* curr_arp_slave might have gone away */ | ||
2639 | curr_arp_slave = ACCESS_ONCE(bond->current_arp_slave); | ||
2640 | |||
2641 | if (!curr_arp_slave) { | 2656 | if (!curr_arp_slave) { |
2642 | curr_arp_slave = bond_first_slave(bond); | 2657 | curr_arp_slave = bond_first_slave_rcu(bond); |
2643 | if (!curr_arp_slave) { | 2658 | if (!curr_arp_slave) |
2644 | rtnl_unlock(); | 2659 | return should_notify_rtnl; |
2645 | return true; | ||
2646 | } | ||
2647 | } | 2660 | } |
2648 | 2661 | ||
2649 | bond_set_slave_inactive_flags(curr_arp_slave); | 2662 | bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER); |
2650 | 2663 | ||
2651 | bond_for_each_slave(bond, slave, iter) { | 2664 | bond_for_each_slave_rcu(bond, slave, iter) { |
2652 | if (!found && !before && IS_UP(slave->dev)) | 2665 | if (!found && !before && IS_UP(slave->dev)) |
2653 | before = slave; | 2666 | before = slave; |
2654 | 2667 | ||
@@ -2666,7 +2679,8 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2666 | if (slave->link_failure_count < UINT_MAX) | 2679 | if (slave->link_failure_count < UINT_MAX) |
2667 | slave->link_failure_count++; | 2680 | slave->link_failure_count++; |
2668 | 2681 | ||
2669 | bond_set_slave_inactive_flags(slave); | 2682 | bond_set_slave_inactive_flags(slave, |
2683 | BOND_SLAVE_NOTIFY_LATER); | ||
2670 | 2684 | ||
2671 | pr_info("%s: backup interface %s is now down.\n", | 2685 | pr_info("%s: backup interface %s is now down.\n", |
2672 | bond->dev->name, slave->dev->name); | 2686 | bond->dev->name, slave->dev->name); |
@@ -2678,26 +2692,31 @@ static bool bond_ab_arp_probe(struct bonding *bond) | |||
2678 | if (!new_slave && before) | 2692 | if (!new_slave && before) |
2679 | new_slave = before; | 2693 | new_slave = before; |
2680 | 2694 | ||
2681 | if (!new_slave) { | 2695 | if (!new_slave) |
2682 | rtnl_unlock(); | 2696 | goto check_state; |
2683 | return true; | ||
2684 | } | ||
2685 | 2697 | ||
2686 | new_slave->link = BOND_LINK_BACK; | 2698 | new_slave->link = BOND_LINK_BACK; |
2687 | bond_set_slave_active_flags(new_slave); | 2699 | bond_set_slave_active_flags(new_slave, BOND_SLAVE_NOTIFY_LATER); |
2688 | bond_arp_send_all(bond, new_slave); | 2700 | bond_arp_send_all(bond, new_slave); |
2689 | new_slave->jiffies = jiffies; | 2701 | new_slave->jiffies = jiffies; |
2690 | rcu_assign_pointer(bond->current_arp_slave, new_slave); | 2702 | rcu_assign_pointer(bond->current_arp_slave, new_slave); |
2691 | rtnl_unlock(); | ||
2692 | 2703 | ||
2693 | return true; | 2704 | check_state: |
2705 | bond_for_each_slave_rcu(bond, slave, iter) { | ||
2706 | if (slave->should_notify) { | ||
2707 | should_notify_rtnl = BOND_SLAVE_NOTIFY_NOW; | ||
2708 | break; | ||
2709 | } | ||
2710 | } | ||
2711 | return should_notify_rtnl; | ||
2694 | } | 2712 | } |
2695 | 2713 | ||
2696 | static void bond_activebackup_arp_mon(struct work_struct *work) | 2714 | static void bond_activebackup_arp_mon(struct work_struct *work) |
2697 | { | 2715 | { |
2698 | struct bonding *bond = container_of(work, struct bonding, | 2716 | struct bonding *bond = container_of(work, struct bonding, |
2699 | arp_work.work); | 2717 | arp_work.work); |
2700 | bool should_notify_peers = false, should_commit = false; | 2718 | bool should_notify_peers = false; |
2719 | bool should_notify_rtnl = false; | ||
2701 | int delta_in_ticks; | 2720 | int delta_in_ticks; |
2702 | 2721 | ||
2703 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); | 2722 | delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval); |
@@ -2706,11 +2725,12 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
2706 | goto re_arm; | 2725 | goto re_arm; |
2707 | 2726 | ||
2708 | rcu_read_lock(); | 2727 | rcu_read_lock(); |
2728 | |||
2709 | should_notify_peers = bond_should_notify_peers(bond); | 2729 | should_notify_peers = bond_should_notify_peers(bond); |
2710 | should_commit = bond_ab_arp_inspect(bond); | ||
2711 | rcu_read_unlock(); | ||
2712 | 2730 | ||
2713 | if (should_commit) { | 2731 | if (bond_ab_arp_inspect(bond)) { |
2732 | rcu_read_unlock(); | ||
2733 | |||
2714 | /* Race avoidance with bond_close flush of workqueue */ | 2734 | /* Race avoidance with bond_close flush of workqueue */ |
2715 | if (!rtnl_trylock()) { | 2735 | if (!rtnl_trylock()) { |
2716 | delta_in_ticks = 1; | 2736 | delta_in_ticks = 1; |
@@ -2719,23 +2739,28 @@ static void bond_activebackup_arp_mon(struct work_struct *work) | |||
2719 | } | 2739 | } |
2720 | 2740 | ||
2721 | bond_ab_arp_commit(bond); | 2741 | bond_ab_arp_commit(bond); |
2742 | |||
2722 | rtnl_unlock(); | 2743 | rtnl_unlock(); |
2744 | rcu_read_lock(); | ||
2723 | } | 2745 | } |
2724 | 2746 | ||
2725 | if (!bond_ab_arp_probe(bond)) { | 2747 | should_notify_rtnl = bond_ab_arp_probe(bond); |
2726 | /* rtnl locking failed, re-arm */ | 2748 | rcu_read_unlock(); |
2727 | delta_in_ticks = 1; | ||
2728 | should_notify_peers = false; | ||
2729 | } | ||
2730 | 2749 | ||
2731 | re_arm: | 2750 | re_arm: |
2732 | if (bond->params.arp_interval) | 2751 | if (bond->params.arp_interval) |
2733 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); | 2752 | queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks); |
2734 | 2753 | ||
2735 | if (should_notify_peers) { | 2754 | if (should_notify_peers || should_notify_rtnl) { |
2736 | if (!rtnl_trylock()) | 2755 | if (!rtnl_trylock()) |
2737 | return; | 2756 | return; |
2738 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); | 2757 | |
2758 | if (should_notify_peers) | ||
2759 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, | ||
2760 | bond->dev); | ||
2761 | if (should_notify_rtnl) | ||
2762 | bond_slave_state_notify(bond); | ||
2763 | |||
2739 | rtnl_unlock(); | 2764 | rtnl_unlock(); |
2740 | } | 2765 | } |
2741 | } | 2766 | } |
@@ -2857,9 +2882,12 @@ static int bond_slave_netdev_event(unsigned long event, | |||
2857 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", | 2882 | pr_info("%s: Primary slave changed to %s, reselecting active slave.\n", |
2858 | bond->dev->name, bond->primary_slave ? slave_dev->name : | 2883 | bond->dev->name, bond->primary_slave ? slave_dev->name : |
2859 | "none"); | 2884 | "none"); |
2885 | |||
2886 | block_netpoll_tx(); | ||
2860 | write_lock_bh(&bond->curr_slave_lock); | 2887 | write_lock_bh(&bond->curr_slave_lock); |
2861 | bond_select_active_slave(bond); | 2888 | bond_select_active_slave(bond); |
2862 | write_unlock_bh(&bond->curr_slave_lock); | 2889 | write_unlock_bh(&bond->curr_slave_lock); |
2890 | unblock_netpoll_tx(); | ||
2863 | break; | 2891 | break; |
2864 | case NETDEV_FEAT_CHANGE: | 2892 | case NETDEV_FEAT_CHANGE: |
2865 | bond_compute_features(bond); | 2893 | bond_compute_features(bond); |
@@ -3032,9 +3060,11 @@ static int bond_open(struct net_device *bond_dev) | |||
3032 | bond_for_each_slave(bond, slave, iter) { | 3060 | bond_for_each_slave(bond, slave, iter) { |
3033 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) | 3061 | if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) |
3034 | && (slave != bond->curr_active_slave)) { | 3062 | && (slave != bond->curr_active_slave)) { |
3035 | bond_set_slave_inactive_flags(slave); | 3063 | bond_set_slave_inactive_flags(slave, |
3064 | BOND_SLAVE_NOTIFY_NOW); | ||
3036 | } else { | 3065 | } else { |
3037 | bond_set_slave_active_flags(slave); | 3066 | bond_set_slave_active_flags(slave, |
3067 | BOND_SLAVE_NOTIFY_NOW); | ||
3038 | } | 3068 | } |
3039 | } | 3069 | } |
3040 | read_unlock(&bond->curr_slave_lock); | 3070 | read_unlock(&bond->curr_slave_lock); |
@@ -3431,7 +3461,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr) | |||
3431 | /* If fail_over_mac is enabled, do nothing and return success. | 3461 | /* If fail_over_mac is enabled, do nothing and return success. |
3432 | * Returning an error causes ifenslave to fail. | 3462 | * Returning an error causes ifenslave to fail. |
3433 | */ | 3463 | */ |
3434 | if (bond->params.fail_over_mac) | 3464 | if (bond->params.fail_over_mac && |
3465 | bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3435 | return 0; | 3466 | return 0; |
3436 | 3467 | ||
3437 | if (!is_valid_ether_addr(sa->sa_data)) | 3468 | if (!is_valid_ether_addr(sa->sa_data)) |
@@ -3692,7 +3723,7 @@ static inline int bond_slave_override(struct bonding *bond, | |||
3692 | 3723 | ||
3693 | 3724 | ||
3694 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, | 3725 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb, |
3695 | void *accel_priv) | 3726 | void *accel_priv, select_queue_fallback_t fallback) |
3696 | { | 3727 | { |
3697 | /* | 3728 | /* |
3698 | * This helper function exists to help dev_pick_tx get the correct | 3729 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 11cb943222d5..298c26509095 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/if.h> | 15 | #include <linux/if.h> |
16 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
17 | #include <linux/rwlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
19 | #include <linux/ctype.h> | 19 | #include <linux/ctype.h> |
20 | #include <linux/inet.h> | 20 | #include <linux/inet.h> |
@@ -121,6 +121,7 @@ static struct bond_opt_value bond_resend_igmp_tbl[] = { | |||
121 | static struct bond_opt_value bond_lp_interval_tbl[] = { | 121 | static struct bond_opt_value bond_lp_interval_tbl[] = { |
122 | { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, | 122 | { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, |
123 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, | 123 | { "maxval", INT_MAX, BOND_VALFLAG_MAX}, |
124 | { NULL, -1, 0}, | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | static struct bond_option bond_opts[] = { | 127 | static struct bond_option bond_opts[] = { |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 86ccfb9f71cc..2b0fdec695f7 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -195,7 +195,8 @@ struct slave { | |||
195 | s8 new_link; | 195 | s8 new_link; |
196 | u8 backup:1, /* indicates backup slave. Value corresponds with | 196 | u8 backup:1, /* indicates backup slave. Value corresponds with |
197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ | 197 | BOND_STATE_ACTIVE and BOND_STATE_BACKUP */ |
198 | inactive:1; /* indicates inactive slave */ | 198 | inactive:1, /* indicates inactive slave */ |
199 | should_notify:1; /* indicateds whether the state changed */ | ||
199 | u8 duplex; | 200 | u8 duplex; |
200 | u32 original_mtu; | 201 | u32 original_mtu; |
201 | u32 link_failure_count; | 202 | u32 link_failure_count; |
@@ -303,6 +304,24 @@ static inline void bond_set_backup_slave(struct slave *slave) | |||
303 | } | 304 | } |
304 | } | 305 | } |
305 | 306 | ||
307 | static inline void bond_set_slave_state(struct slave *slave, | ||
308 | int slave_state, bool notify) | ||
309 | { | ||
310 | if (slave->backup == slave_state) | ||
311 | return; | ||
312 | |||
313 | slave->backup = slave_state; | ||
314 | if (notify) { | ||
315 | rtmsg_ifinfo(RTM_NEWLINK, slave->dev, 0, GFP_KERNEL); | ||
316 | slave->should_notify = 0; | ||
317 | } else { | ||
318 | if (slave->should_notify) | ||
319 | slave->should_notify = 0; | ||
320 | else | ||
321 | slave->should_notify = 1; | ||
322 | } | ||
323 | } | ||
324 | |||
306 | static inline void bond_slave_state_change(struct bonding *bond) | 325 | static inline void bond_slave_state_change(struct bonding *bond) |
307 | { | 326 | { |
308 | struct list_head *iter; | 327 | struct list_head *iter; |
@@ -316,6 +335,19 @@ static inline void bond_slave_state_change(struct bonding *bond) | |||
316 | } | 335 | } |
317 | } | 336 | } |
318 | 337 | ||
338 | static inline void bond_slave_state_notify(struct bonding *bond) | ||
339 | { | ||
340 | struct list_head *iter; | ||
341 | struct slave *tmp; | ||
342 | |||
343 | bond_for_each_slave(bond, tmp, iter) { | ||
344 | if (tmp->should_notify) { | ||
345 | rtmsg_ifinfo(RTM_NEWLINK, tmp->dev, 0, GFP_KERNEL); | ||
346 | tmp->should_notify = 0; | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
319 | static inline int bond_slave_state(struct slave *slave) | 351 | static inline int bond_slave_state(struct slave *slave) |
320 | { | 352 | { |
321 | return slave->backup; | 353 | return slave->backup; |
@@ -343,6 +375,9 @@ static inline bool bond_is_active_slave(struct slave *slave) | |||
343 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | 375 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ |
344 | BOND_ARP_VALIDATE_BACKUP) | 376 | BOND_ARP_VALIDATE_BACKUP) |
345 | 377 | ||
378 | #define BOND_SLAVE_NOTIFY_NOW true | ||
379 | #define BOND_SLAVE_NOTIFY_LATER false | ||
380 | |||
346 | static inline int slave_do_arp_validate(struct bonding *bond, | 381 | static inline int slave_do_arp_validate(struct bonding *bond, |
347 | struct slave *slave) | 382 | struct slave *slave) |
348 | { | 383 | { |
@@ -394,17 +429,19 @@ static inline void bond_netpoll_send_skb(const struct slave *slave, | |||
394 | } | 429 | } |
395 | #endif | 430 | #endif |
396 | 431 | ||
397 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 432 | static inline void bond_set_slave_inactive_flags(struct slave *slave, |
433 | bool notify) | ||
398 | { | 434 | { |
399 | if (!bond_is_lb(slave->bond)) | 435 | if (!bond_is_lb(slave->bond)) |
400 | bond_set_backup_slave(slave); | 436 | bond_set_slave_state(slave, BOND_STATE_BACKUP, notify); |
401 | if (!slave->bond->params.all_slaves_active) | 437 | if (!slave->bond->params.all_slaves_active) |
402 | slave->inactive = 1; | 438 | slave->inactive = 1; |
403 | } | 439 | } |
404 | 440 | ||
405 | static inline void bond_set_slave_active_flags(struct slave *slave) | 441 | static inline void bond_set_slave_active_flags(struct slave *slave, |
442 | bool notify) | ||
406 | { | 443 | { |
407 | bond_set_active_slave(slave); | 444 | bond_set_slave_state(slave, BOND_STATE_ACTIVE, notify); |
408 | slave->inactive = 0; | 445 | slave->inactive = 0; |
409 | } | 446 | } |
410 | 447 | ||
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d447b881bbde..9e7d95dae2c7 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig | |||
@@ -104,7 +104,7 @@ config CAN_JANZ_ICAN3 | |||
104 | 104 | ||
105 | config CAN_FLEXCAN | 105 | config CAN_FLEXCAN |
106 | tristate "Support for Freescale FLEXCAN based chips" | 106 | tristate "Support for Freescale FLEXCAN based chips" |
107 | depends on (ARM && CPU_LITTLE_ENDIAN) || PPC | 107 | depends on ARM || PPC |
108 | ---help--- | 108 | ---help--- |
109 | Say Y here if you want to support for Freescale FlexCAN. | 109 | Say Y here if you want to support for Freescale FlexCAN. |
110 | 110 | ||
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 13a909822e25..fc59bc6f040b 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -323,19 +323,10 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, | |||
323 | } | 323 | } |
324 | 324 | ||
325 | if (!priv->echo_skb[idx]) { | 325 | if (!priv->echo_skb[idx]) { |
326 | struct sock *srcsk = skb->sk; | ||
327 | 326 | ||
328 | if (atomic_read(&skb->users) != 1) { | 327 | skb = can_create_echo_skb(skb); |
329 | struct sk_buff *old_skb = skb; | 328 | if (!skb) |
330 | 329 | return; | |
331 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
332 | kfree_skb(old_skb); | ||
333 | if (!skb) | ||
334 | return; | ||
335 | } else | ||
336 | skb_orphan(skb); | ||
337 | |||
338 | skb->sk = srcsk; | ||
339 | 330 | ||
340 | /* make settings for echo to reduce code in irq context */ | 331 | /* make settings for echo to reduce code in irq context */ |
341 | skb->protocol = htons(ETH_P_CAN); | 332 | skb->protocol = htons(ETH_P_CAN); |
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index aaed97bee471..61376abdab39 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c | |||
@@ -144,6 +144,8 @@ | |||
144 | 144 | ||
145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
146 | 146 | ||
147 | #define FLEXCAN_TIMEOUT_US (50) | ||
148 | |||
147 | /* | 149 | /* |
148 | * FLEXCAN hardware feature flags | 150 | * FLEXCAN hardware feature flags |
149 | * | 151 | * |
@@ -235,9 +237,12 @@ static const struct can_bittiming_const flexcan_bittiming_const = { | |||
235 | }; | 237 | }; |
236 | 238 | ||
237 | /* | 239 | /* |
238 | * Abstract off the read/write for arm versus ppc. | 240 | * Abstract off the read/write for arm versus ppc. This |
241 | * assumes that PPC uses big-endian registers and everything | ||
242 | * else uses little-endian registers, independent of CPU | ||
243 | * endianess. | ||
239 | */ | 244 | */ |
240 | #if defined(__BIG_ENDIAN) | 245 | #if defined(CONFIG_PPC) |
241 | static inline u32 flexcan_read(void __iomem *addr) | 246 | static inline u32 flexcan_read(void __iomem *addr) |
242 | { | 247 | { |
243 | return in_be32(addr); | 248 | return in_be32(addr); |
@@ -259,6 +264,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr) | |||
259 | } | 264 | } |
260 | #endif | 265 | #endif |
261 | 266 | ||
267 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) | ||
268 | { | ||
269 | if (!priv->reg_xceiver) | ||
270 | return 0; | ||
271 | |||
272 | return regulator_enable(priv->reg_xceiver); | ||
273 | } | ||
274 | |||
275 | static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv) | ||
276 | { | ||
277 | if (!priv->reg_xceiver) | ||
278 | return 0; | ||
279 | |||
280 | return regulator_disable(priv->reg_xceiver); | ||
281 | } | ||
282 | |||
262 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | 283 | static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, |
263 | u32 reg_esr) | 284 | u32 reg_esr) |
264 | { | 285 | { |
@@ -266,26 +287,95 @@ static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv, | |||
266 | (reg_esr & FLEXCAN_ESR_ERR_BUS); | 287 | (reg_esr & FLEXCAN_ESR_ERR_BUS); |
267 | } | 288 | } |
268 | 289 | ||
269 | static inline void flexcan_chip_enable(struct flexcan_priv *priv) | 290 | static int flexcan_chip_enable(struct flexcan_priv *priv) |
270 | { | 291 | { |
271 | struct flexcan_regs __iomem *regs = priv->base; | 292 | struct flexcan_regs __iomem *regs = priv->base; |
293 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
272 | u32 reg; | 294 | u32 reg; |
273 | 295 | ||
274 | reg = flexcan_read(®s->mcr); | 296 | reg = flexcan_read(®s->mcr); |
275 | reg &= ~FLEXCAN_MCR_MDIS; | 297 | reg &= ~FLEXCAN_MCR_MDIS; |
276 | flexcan_write(reg, ®s->mcr); | 298 | flexcan_write(reg, ®s->mcr); |
277 | 299 | ||
278 | udelay(10); | 300 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
301 | usleep_range(10, 20); | ||
302 | |||
303 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) | ||
304 | return -ETIMEDOUT; | ||
305 | |||
306 | return 0; | ||
279 | } | 307 | } |
280 | 308 | ||
281 | static inline void flexcan_chip_disable(struct flexcan_priv *priv) | 309 | static int flexcan_chip_disable(struct flexcan_priv *priv) |
282 | { | 310 | { |
283 | struct flexcan_regs __iomem *regs = priv->base; | 311 | struct flexcan_regs __iomem *regs = priv->base; |
312 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
284 | u32 reg; | 313 | u32 reg; |
285 | 314 | ||
286 | reg = flexcan_read(®s->mcr); | 315 | reg = flexcan_read(®s->mcr); |
287 | reg |= FLEXCAN_MCR_MDIS; | 316 | reg |= FLEXCAN_MCR_MDIS; |
288 | flexcan_write(reg, ®s->mcr); | 317 | flexcan_write(reg, ®s->mcr); |
318 | |||
319 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
320 | usleep_range(10, 20); | ||
321 | |||
322 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) | ||
323 | return -ETIMEDOUT; | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int flexcan_chip_freeze(struct flexcan_priv *priv) | ||
329 | { | ||
330 | struct flexcan_regs __iomem *regs = priv->base; | ||
331 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; | ||
332 | u32 reg; | ||
333 | |||
334 | reg = flexcan_read(®s->mcr); | ||
335 | reg |= FLEXCAN_MCR_HALT; | ||
336 | flexcan_write(reg, ®s->mcr); | ||
337 | |||
338 | while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
339 | usleep_range(100, 200); | ||
340 | |||
341 | if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
342 | return -ETIMEDOUT; | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | static int flexcan_chip_unfreeze(struct flexcan_priv *priv) | ||
348 | { | ||
349 | struct flexcan_regs __iomem *regs = priv->base; | ||
350 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
351 | u32 reg; | ||
352 | |||
353 | reg = flexcan_read(®s->mcr); | ||
354 | reg &= ~FLEXCAN_MCR_HALT; | ||
355 | flexcan_write(reg, ®s->mcr); | ||
356 | |||
357 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) | ||
358 | usleep_range(10, 20); | ||
359 | |||
360 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) | ||
361 | return -ETIMEDOUT; | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int flexcan_chip_softreset(struct flexcan_priv *priv) | ||
367 | { | ||
368 | struct flexcan_regs __iomem *regs = priv->base; | ||
369 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; | ||
370 | |||
371 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | ||
372 | while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) | ||
373 | usleep_range(10, 20); | ||
374 | |||
375 | if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) | ||
376 | return -ETIMEDOUT; | ||
377 | |||
378 | return 0; | ||
289 | } | 379 | } |
290 | 380 | ||
291 | static int flexcan_get_berr_counter(const struct net_device *dev, | 381 | static int flexcan_get_berr_counter(const struct net_device *dev, |
@@ -706,19 +796,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
706 | u32 reg_mcr, reg_ctrl; | 796 | u32 reg_mcr, reg_ctrl; |
707 | 797 | ||
708 | /* enable module */ | 798 | /* enable module */ |
709 | flexcan_chip_enable(priv); | 799 | err = flexcan_chip_enable(priv); |
800 | if (err) | ||
801 | return err; | ||
710 | 802 | ||
711 | /* soft reset */ | 803 | /* soft reset */ |
712 | flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); | 804 | err = flexcan_chip_softreset(priv); |
713 | udelay(10); | 805 | if (err) |
714 | 806 | goto out_chip_disable; | |
715 | reg_mcr = flexcan_read(®s->mcr); | ||
716 | if (reg_mcr & FLEXCAN_MCR_SOFTRST) { | ||
717 | netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", | ||
718 | reg_mcr); | ||
719 | err = -ENODEV; | ||
720 | goto out; | ||
721 | } | ||
722 | 807 | ||
723 | flexcan_set_bittiming(dev); | 808 | flexcan_set_bittiming(dev); |
724 | 809 | ||
@@ -785,16 +870,14 @@ static int flexcan_chip_start(struct net_device *dev) | |||
785 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) | 870 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) |
786 | flexcan_write(0x0, ®s->rxfgmask); | 871 | flexcan_write(0x0, ®s->rxfgmask); |
787 | 872 | ||
788 | if (priv->reg_xceiver) { | 873 | err = flexcan_transceiver_enable(priv); |
789 | err = regulator_enable(priv->reg_xceiver); | 874 | if (err) |
790 | if (err) | 875 | goto out_chip_disable; |
791 | goto out; | ||
792 | } | ||
793 | 876 | ||
794 | /* synchronize with the can bus */ | 877 | /* synchronize with the can bus */ |
795 | reg_mcr = flexcan_read(®s->mcr); | 878 | err = flexcan_chip_unfreeze(priv); |
796 | reg_mcr &= ~FLEXCAN_MCR_HALT; | 879 | if (err) |
797 | flexcan_write(reg_mcr, ®s->mcr); | 880 | goto out_transceiver_disable; |
798 | 881 | ||
799 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 882 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
800 | 883 | ||
@@ -807,7 +890,9 @@ static int flexcan_chip_start(struct net_device *dev) | |||
807 | 890 | ||
808 | return 0; | 891 | return 0; |
809 | 892 | ||
810 | out: | 893 | out_transceiver_disable: |
894 | flexcan_transceiver_disable(priv); | ||
895 | out_chip_disable: | ||
811 | flexcan_chip_disable(priv); | 896 | flexcan_chip_disable(priv); |
812 | return err; | 897 | return err; |
813 | } | 898 | } |
@@ -822,18 +907,17 @@ static void flexcan_chip_stop(struct net_device *dev) | |||
822 | { | 907 | { |
823 | struct flexcan_priv *priv = netdev_priv(dev); | 908 | struct flexcan_priv *priv = netdev_priv(dev); |
824 | struct flexcan_regs __iomem *regs = priv->base; | 909 | struct flexcan_regs __iomem *regs = priv->base; |
825 | u32 reg; | 910 | |
911 | /* freeze + disable module */ | ||
912 | flexcan_chip_freeze(priv); | ||
913 | flexcan_chip_disable(priv); | ||
826 | 914 | ||
827 | /* Disable all interrupts */ | 915 | /* Disable all interrupts */ |
828 | flexcan_write(0, ®s->imask1); | 916 | flexcan_write(0, ®s->imask1); |
917 | flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, | ||
918 | ®s->ctrl); | ||
829 | 919 | ||
830 | /* Disable + halt module */ | 920 | flexcan_transceiver_disable(priv); |
831 | reg = flexcan_read(®s->mcr); | ||
832 | reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT; | ||
833 | flexcan_write(reg, ®s->mcr); | ||
834 | |||
835 | if (priv->reg_xceiver) | ||
836 | regulator_disable(priv->reg_xceiver); | ||
837 | priv->can.state = CAN_STATE_STOPPED; | 921 | priv->can.state = CAN_STATE_STOPPED; |
838 | 922 | ||
839 | return; | 923 | return; |
@@ -863,7 +947,7 @@ static int flexcan_open(struct net_device *dev) | |||
863 | /* start chip and queuing */ | 947 | /* start chip and queuing */ |
864 | err = flexcan_chip_start(dev); | 948 | err = flexcan_chip_start(dev); |
865 | if (err) | 949 | if (err) |
866 | goto out_close; | 950 | goto out_free_irq; |
867 | 951 | ||
868 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 952 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
869 | 953 | ||
@@ -872,6 +956,8 @@ static int flexcan_open(struct net_device *dev) | |||
872 | 956 | ||
873 | return 0; | 957 | return 0; |
874 | 958 | ||
959 | out_free_irq: | ||
960 | free_irq(dev->irq, dev); | ||
875 | out_close: | 961 | out_close: |
876 | close_candev(dev); | 962 | close_candev(dev); |
877 | out_disable_per: | 963 | out_disable_per: |
@@ -942,12 +1028,16 @@ static int register_flexcandev(struct net_device *dev) | |||
942 | goto out_disable_ipg; | 1028 | goto out_disable_ipg; |
943 | 1029 | ||
944 | /* select "bus clock", chip must be disabled */ | 1030 | /* select "bus clock", chip must be disabled */ |
945 | flexcan_chip_disable(priv); | 1031 | err = flexcan_chip_disable(priv); |
1032 | if (err) | ||
1033 | goto out_disable_per; | ||
946 | reg = flexcan_read(®s->ctrl); | 1034 | reg = flexcan_read(®s->ctrl); |
947 | reg |= FLEXCAN_CTRL_CLK_SRC; | 1035 | reg |= FLEXCAN_CTRL_CLK_SRC; |
948 | flexcan_write(reg, ®s->ctrl); | 1036 | flexcan_write(reg, ®s->ctrl); |
949 | 1037 | ||
950 | flexcan_chip_enable(priv); | 1038 | err = flexcan_chip_enable(priv); |
1039 | if (err) | ||
1040 | goto out_chip_disable; | ||
951 | 1041 | ||
952 | /* set freeze, halt and activate FIFO, restrict register access */ | 1042 | /* set freeze, halt and activate FIFO, restrict register access */ |
953 | reg = flexcan_read(®s->mcr); | 1043 | reg = flexcan_read(®s->mcr); |
@@ -964,14 +1054,15 @@ static int register_flexcandev(struct net_device *dev) | |||
964 | if (!(reg & FLEXCAN_MCR_FEN)) { | 1054 | if (!(reg & FLEXCAN_MCR_FEN)) { |
965 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); | 1055 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
966 | err = -ENODEV; | 1056 | err = -ENODEV; |
967 | goto out_disable_per; | 1057 | goto out_chip_disable; |
968 | } | 1058 | } |
969 | 1059 | ||
970 | err = register_candev(dev); | 1060 | err = register_candev(dev); |
971 | 1061 | ||
972 | out_disable_per: | ||
973 | /* disable core and turn off clocks */ | 1062 | /* disable core and turn off clocks */ |
1063 | out_chip_disable: | ||
974 | flexcan_chip_disable(priv); | 1064 | flexcan_chip_disable(priv); |
1065 | out_disable_per: | ||
975 | clk_disable_unprepare(priv->clk_per); | 1066 | clk_disable_unprepare(priv->clk_per); |
976 | out_disable_ipg: | 1067 | out_disable_ipg: |
977 | clk_disable_unprepare(priv->clk_ipg); | 1068 | clk_disable_unprepare(priv->clk_ipg); |
@@ -1101,9 +1192,10 @@ static int flexcan_probe(struct platform_device *pdev) | |||
1101 | static int flexcan_remove(struct platform_device *pdev) | 1192 | static int flexcan_remove(struct platform_device *pdev) |
1102 | { | 1193 | { |
1103 | struct net_device *dev = platform_get_drvdata(pdev); | 1194 | struct net_device *dev = platform_get_drvdata(pdev); |
1195 | struct flexcan_priv *priv = netdev_priv(dev); | ||
1104 | 1196 | ||
1105 | unregister_flexcandev(dev); | 1197 | unregister_flexcandev(dev); |
1106 | 1198 | netif_napi_del(&priv->napi); | |
1107 | free_candev(dev); | 1199 | free_candev(dev); |
1108 | 1200 | ||
1109 | return 0; | 1201 | return 0; |
@@ -1114,8 +1206,11 @@ static int flexcan_suspend(struct device *device) | |||
1114 | { | 1206 | { |
1115 | struct net_device *dev = dev_get_drvdata(device); | 1207 | struct net_device *dev = dev_get_drvdata(device); |
1116 | struct flexcan_priv *priv = netdev_priv(dev); | 1208 | struct flexcan_priv *priv = netdev_priv(dev); |
1209 | int err; | ||
1117 | 1210 | ||
1118 | flexcan_chip_disable(priv); | 1211 | err = flexcan_chip_disable(priv); |
1212 | if (err) | ||
1213 | return err; | ||
1119 | 1214 | ||
1120 | if (netif_running(dev)) { | 1215 | if (netif_running(dev)) { |
1121 | netif_stop_queue(dev); | 1216 | netif_stop_queue(dev); |
@@ -1136,9 +1231,7 @@ static int flexcan_resume(struct device *device) | |||
1136 | netif_device_attach(dev); | 1231 | netif_device_attach(dev); |
1137 | netif_start_queue(dev); | 1232 | netif_start_queue(dev); |
1138 | } | 1233 | } |
1139 | flexcan_chip_enable(priv); | 1234 | return flexcan_chip_enable(priv); |
1140 | |||
1141 | return 0; | ||
1142 | } | 1235 | } |
1143 | #endif /* CONFIG_PM_SLEEP */ | 1236 | #endif /* CONFIG_PM_SLEEP */ |
1144 | 1237 | ||
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index e24e6690d672..71594e5676fd 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/netdevice.h> | 18 | #include <linux/netdevice.h> |
19 | #include <linux/can.h> | 19 | #include <linux/can.h> |
20 | #include <linux/can/dev.h> | 20 | #include <linux/can/dev.h> |
21 | #include <linux/can/skb.h> | ||
21 | #include <linux/can/error.h> | 22 | #include <linux/can/error.h> |
22 | 23 | ||
23 | #include <linux/mfd/janz.h> | 24 | #include <linux/mfd/janz.h> |
@@ -1133,20 +1134,9 @@ static void ican3_handle_message(struct ican3_dev *mod, struct ican3_msg *msg) | |||
1133 | */ | 1134 | */ |
1134 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) | 1135 | static void ican3_put_echo_skb(struct ican3_dev *mod, struct sk_buff *skb) |
1135 | { | 1136 | { |
1136 | struct sock *srcsk = skb->sk; | 1137 | skb = can_create_echo_skb(skb); |
1137 | 1138 | if (!skb) | |
1138 | if (atomic_read(&skb->users) != 1) { | 1139 | return; |
1139 | struct sk_buff *old_skb = skb; | ||
1140 | |||
1141 | skb = skb_clone(old_skb, GFP_ATOMIC); | ||
1142 | kfree_skb(old_skb); | ||
1143 | if (!skb) | ||
1144 | return; | ||
1145 | } else { | ||
1146 | skb_orphan(skb); | ||
1147 | } | ||
1148 | |||
1149 | skb->sk = srcsk; | ||
1150 | 1140 | ||
1151 | /* save this skb for tx interrupt echo handling */ | 1141 | /* save this skb for tx interrupt echo handling */ |
1152 | skb_queue_tail(&mod->echoq, skb); | 1142 | skb_queue_tail(&mod->echoq, skb); |
@@ -1322,7 +1312,7 @@ static int ican3_napi(struct napi_struct *napi, int budget) | |||
1322 | 1312 | ||
1323 | /* process all communication messages */ | 1313 | /* process all communication messages */ |
1324 | while (true) { | 1314 | while (true) { |
1325 | struct ican3_msg msg; | 1315 | struct ican3_msg uninitialized_var(msg); |
1326 | ret = ican3_recv_msg(mod, &msg); | 1316 | ret = ican3_recv_msg(mod, &msg); |
1327 | if (ret) | 1317 | if (ret) |
1328 | break; | 1318 | break; |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 6c859bba8b65..e77d11049747 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
@@ -473,6 +473,8 @@ static int kvaser_usb_get_card_info(struct kvaser_usb *dev) | |||
473 | return err; | 473 | return err; |
474 | 474 | ||
475 | dev->nchannels = msg.u.cardinfo.nchannels; | 475 | dev->nchannels = msg.u.cardinfo.nchannels; |
476 | if (dev->nchannels > MAX_NET_DEVICES) | ||
477 | return -EINVAL; | ||
476 | 478 | ||
477 | return 0; | 479 | return 0; |
478 | } | 480 | } |
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 0a2a5ee79a17..4e94057ef5cf 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/if_ether.h> | 46 | #include <linux/if_ether.h> |
47 | #include <linux/can.h> | 47 | #include <linux/can.h> |
48 | #include <linux/can/dev.h> | 48 | #include <linux/can/dev.h> |
49 | #include <linux/can/skb.h> | ||
49 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
50 | #include <net/rtnetlink.h> | 51 | #include <net/rtnetlink.h> |
51 | 52 | ||
@@ -109,25 +110,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) | |||
109 | stats->rx_packets++; | 110 | stats->rx_packets++; |
110 | stats->rx_bytes += cfd->len; | 111 | stats->rx_bytes += cfd->len; |
111 | } | 112 | } |
112 | kfree_skb(skb); | 113 | consume_skb(skb); |
113 | return NETDEV_TX_OK; | 114 | return NETDEV_TX_OK; |
114 | } | 115 | } |
115 | 116 | ||
116 | /* perform standard echo handling for CAN network interfaces */ | 117 | /* perform standard echo handling for CAN network interfaces */ |
117 | 118 | ||
118 | if (loop) { | 119 | if (loop) { |
119 | struct sock *srcsk = skb->sk; | ||
120 | 120 | ||
121 | skb = skb_share_check(skb, GFP_ATOMIC); | 121 | skb = can_create_echo_skb(skb); |
122 | if (!skb) | 122 | if (!skb) |
123 | return NETDEV_TX_OK; | 123 | return NETDEV_TX_OK; |
124 | 124 | ||
125 | /* receive with packet counting */ | 125 | /* receive with packet counting */ |
126 | skb->sk = srcsk; | ||
127 | vcan_rx(skb, dev); | 126 | vcan_rx(skb, dev); |
128 | } else { | 127 | } else { |
129 | /* no looped packets => no counting */ | 128 | /* no looped packets => no counting */ |
130 | kfree_skb(skb); | 129 | consume_skb(skb); |
131 | } | 130 | } |
132 | return NETDEV_TX_OK; | 131 | return NETDEV_TX_OK; |
133 | } | 132 | } |
diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 0f4241c6e97e..238ccea965c8 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c | |||
@@ -3294,7 +3294,6 @@ static int __init vortex_init(void) | |||
3294 | 3294 | ||
3295 | static void __exit vortex_eisa_cleanup(void) | 3295 | static void __exit vortex_eisa_cleanup(void) |
3296 | { | 3296 | { |
3297 | struct vortex_private *vp; | ||
3298 | void __iomem *ioaddr; | 3297 | void __iomem *ioaddr; |
3299 | 3298 | ||
3300 | #ifdef CONFIG_EISA | 3299 | #ifdef CONFIG_EISA |
@@ -3303,7 +3302,6 @@ static void __exit vortex_eisa_cleanup(void) | |||
3303 | #endif | 3302 | #endif |
3304 | 3303 | ||
3305 | if (compaq_net_device) { | 3304 | if (compaq_net_device) { |
3306 | vp = netdev_priv(compaq_net_device); | ||
3307 | ioaddr = ioport_map(compaq_net_device->base_addr, | 3305 | ioaddr = ioport_map(compaq_net_device->base_addr, |
3308 | VORTEX_TOTAL_SIZE); | 3306 | VORTEX_TOTAL_SIZE); |
3309 | 3307 | ||
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 0cc21437478c..511f6eecd58b 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
@@ -929,6 +929,9 @@ static int emac_resume(struct platform_device *dev) | |||
929 | } | 929 | } |
930 | 930 | ||
931 | static const struct of_device_id emac_of_match[] = { | 931 | static const struct of_device_id emac_of_match[] = { |
932 | {.compatible = "allwinner,sun4i-a10-emac",}, | ||
933 | |||
934 | /* Deprecated */ | ||
932 | {.compatible = "allwinner,sun4i-emac",}, | 935 | {.compatible = "allwinner,sun4i-emac",}, |
933 | {}, | 936 | {}, |
934 | }; | 937 | }; |
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e92ffd6e1c15..380d24922049 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -1248,19 +1248,13 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1248 | * shared register for the high 32 bits, so only a single, aligned, | 1248 | * shared register for the high 32 bits, so only a single, aligned, |
1249 | * 4 GB physical address range can be used for descriptors. | 1249 | * 4 GB physical address range can be used for descriptors. |
1250 | */ | 1250 | */ |
1251 | if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && | 1251 | if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) { |
1252 | !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { | ||
1253 | dev_dbg(&pdev->dev, "DMA to 64-BIT addresses\n"); | 1252 | dev_dbg(&pdev->dev, "DMA to 64-BIT addresses\n"); |
1254 | } else { | 1253 | } else { |
1255 | err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); | 1254 | err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); |
1256 | if (err) { | 1255 | if (err) { |
1257 | err = dma_set_coherent_mask(&pdev->dev, | 1256 | dev_err(&pdev->dev, "No usable DMA config, aborting\n"); |
1258 | DMA_BIT_MASK(32)); | 1257 | goto out_pci_disable; |
1259 | if (err) { | ||
1260 | dev_err(&pdev->dev, | ||
1261 | "No usable DMA config, aborting\n"); | ||
1262 | goto out_pci_disable; | ||
1263 | } | ||
1264 | } | 1258 | } |
1265 | } | 1259 | } |
1266 | 1260 | ||
@@ -1292,6 +1286,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1292 | alx = netdev_priv(netdev); | 1286 | alx = netdev_priv(netdev); |
1293 | spin_lock_init(&alx->hw.mdio_lock); | 1287 | spin_lock_init(&alx->hw.mdio_lock); |
1294 | spin_lock_init(&alx->irq_lock); | 1288 | spin_lock_init(&alx->irq_lock); |
1289 | spin_lock_init(&alx->stats_lock); | ||
1295 | alx->dev = netdev; | 1290 | alx->dev = netdev; |
1296 | alx->hw.pdev = pdev; | 1291 | alx->hw.pdev = pdev; |
1297 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | | 1292 | alx->msg_enable = NETIF_MSG_LINK | NETIF_MSG_HW | NETIF_MSG_IFUP | |
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index d5c2d3e912e5..422aab27ea1b 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c | |||
@@ -2436,7 +2436,7 @@ err_reset: | |||
2436 | err_register: | 2436 | err_register: |
2437 | err_sw_init: | 2437 | err_sw_init: |
2438 | err_eeprom: | 2438 | err_eeprom: |
2439 | iounmap(adapter->hw.hw_addr); | 2439 | pci_iounmap(pdev, adapter->hw.hw_addr); |
2440 | err_init_netdev: | 2440 | err_init_netdev: |
2441 | err_ioremap: | 2441 | err_ioremap: |
2442 | free_netdev(netdev); | 2442 | free_netdev(netdev); |
@@ -2474,7 +2474,7 @@ static void atl1e_remove(struct pci_dev *pdev) | |||
2474 | unregister_netdev(netdev); | 2474 | unregister_netdev(netdev); |
2475 | atl1e_free_ring_resources(adapter); | 2475 | atl1e_free_ring_resources(adapter); |
2476 | atl1e_force_ps(&adapter->hw); | 2476 | atl1e_force_ps(&adapter->hw); |
2477 | iounmap(adapter->hw.hw_addr); | 2477 | pci_iounmap(pdev, adapter->hw.hw_addr); |
2478 | pci_release_regions(pdev); | 2478 | pci_release_regions(pdev); |
2479 | free_netdev(netdev); | 2479 | free_netdev(netdev); |
2480 | pci_disable_device(pdev); | 2480 | pci_disable_device(pdev); |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 1f7b5aa114fa..8a7bf7dad898 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
@@ -1484,6 +1484,10 @@ static int b44_open(struct net_device *dev) | |||
1484 | add_timer(&bp->timer); | 1484 | add_timer(&bp->timer); |
1485 | 1485 | ||
1486 | b44_enable_ints(bp); | 1486 | b44_enable_ints(bp); |
1487 | |||
1488 | if (bp->flags & B44_FLAG_EXTERNAL_PHY) | ||
1489 | phy_start(bp->phydev); | ||
1490 | |||
1487 | netif_start_queue(dev); | 1491 | netif_start_queue(dev); |
1488 | out: | 1492 | out: |
1489 | return err; | 1493 | return err; |
@@ -1646,6 +1650,9 @@ static int b44_close(struct net_device *dev) | |||
1646 | 1650 | ||
1647 | netif_stop_queue(dev); | 1651 | netif_stop_queue(dev); |
1648 | 1652 | ||
1653 | if (bp->flags & B44_FLAG_EXTERNAL_PHY) | ||
1654 | phy_stop(bp->phydev); | ||
1655 | |||
1649 | napi_disable(&bp->napi); | 1656 | napi_disable(&bp->napi); |
1650 | 1657 | ||
1651 | del_timer_sync(&bp->timer); | 1658 | del_timer_sync(&bp->timer); |
@@ -2222,7 +2229,12 @@ static void b44_adjust_link(struct net_device *dev) | |||
2222 | } | 2229 | } |
2223 | 2230 | ||
2224 | if (status_changed) { | 2231 | if (status_changed) { |
2225 | b44_check_phy(bp); | 2232 | u32 val = br32(bp, B44_TX_CTRL); |
2233 | if (bp->flags & B44_FLAG_FULL_DUPLEX) | ||
2234 | val |= TX_CTRL_DUPLEX; | ||
2235 | else | ||
2236 | val &= ~TX_CTRL_DUPLEX; | ||
2237 | bw32(bp, B44_TX_CTRL, val); | ||
2226 | phy_print_status(phydev); | 2238 | phy_print_status(phydev); |
2227 | } | 2239 | } |
2228 | } | 2240 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 9d2dedadf2df..6c9e1c9bdeb8 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c | |||
@@ -85,7 +85,7 @@ MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax); | |||
85 | 85 | ||
86 | static int disable_msi = 0; | 86 | static int disable_msi = 0; |
87 | 87 | ||
88 | module_param(disable_msi, int, 0); | 88 | module_param(disable_msi, int, S_IRUGO); |
89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | 89 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
90 | 90 | ||
91 | typedef enum { | 91 | typedef enum { |
@@ -2507,6 +2507,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int ack, int silent) | |||
2507 | 2507 | ||
2508 | bp->fw_wr_seq++; | 2508 | bp->fw_wr_seq++; |
2509 | msg_data |= bp->fw_wr_seq; | 2509 | msg_data |= bp->fw_wr_seq; |
2510 | bp->fw_last_msg = msg_data; | ||
2510 | 2511 | ||
2511 | bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data); | 2512 | bnx2_shmem_wr(bp, BNX2_DRV_MB, msg_data); |
2512 | 2513 | ||
@@ -4000,8 +4001,23 @@ bnx2_setup_wol(struct bnx2 *bp) | |||
4000 | wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; | 4001 | wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; |
4001 | } | 4002 | } |
4002 | 4003 | ||
4003 | if (!(bp->flags & BNX2_FLAG_NO_WOL)) | 4004 | if (!(bp->flags & BNX2_FLAG_NO_WOL)) { |
4004 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 1, 0); | 4005 | u32 val; |
4006 | |||
4007 | wol_msg |= BNX2_DRV_MSG_DATA_WAIT3; | ||
4008 | if (bp->fw_last_msg || BNX2_CHIP(bp) != BNX2_CHIP_5709) { | ||
4009 | bnx2_fw_sync(bp, wol_msg, 1, 0); | ||
4010 | return; | ||
4011 | } | ||
4012 | /* Tell firmware not to power down the PHY yet, otherwise | ||
4013 | * the chip will take a long time to respond to MMIO reads. | ||
4014 | */ | ||
4015 | val = bnx2_shmem_rd(bp, BNX2_PORT_FEATURE); | ||
4016 | bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, | ||
4017 | val | BNX2_PORT_FEATURE_ASF_ENABLED); | ||
4018 | bnx2_fw_sync(bp, wol_msg, 1, 0); | ||
4019 | bnx2_shmem_wr(bp, BNX2_PORT_FEATURE, val); | ||
4020 | } | ||
4005 | 4021 | ||
4006 | } | 4022 | } |
4007 | 4023 | ||
@@ -4033,9 +4049,22 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) | |||
4033 | 4049 | ||
4034 | if (bp->wol) | 4050 | if (bp->wol) |
4035 | pci_set_power_state(bp->pdev, PCI_D3hot); | 4051 | pci_set_power_state(bp->pdev, PCI_D3hot); |
4036 | } else { | 4052 | break; |
4037 | pci_set_power_state(bp->pdev, PCI_D3hot); | 4053 | |
4054 | } | ||
4055 | if (!bp->fw_last_msg && BNX2_CHIP(bp) == BNX2_CHIP_5709) { | ||
4056 | u32 val; | ||
4057 | |||
4058 | /* Tell firmware not to power down the PHY yet, | ||
4059 | * otherwise the other port may not respond to | ||
4060 | * MMIO reads. | ||
4061 | */ | ||
4062 | val = bnx2_shmem_rd(bp, BNX2_BC_STATE_CONDITION); | ||
4063 | val &= ~BNX2_CONDITION_PM_STATE_MASK; | ||
4064 | val |= BNX2_CONDITION_PM_STATE_UNPREP; | ||
4065 | bnx2_shmem_wr(bp, BNX2_BC_STATE_CONDITION, val); | ||
4038 | } | 4066 | } |
4067 | pci_set_power_state(bp->pdev, PCI_D3hot); | ||
4039 | 4068 | ||
4040 | /* No more memory access after this point until | 4069 | /* No more memory access after this point until |
4041 | * device is brought back to D0. | 4070 | * device is brought back to D0. |
diff --git a/drivers/net/ethernet/broadcom/bnx2.h b/drivers/net/ethernet/broadcom/bnx2.h index f1cf2c44e7ed..e341bc366fa5 100644 --- a/drivers/net/ethernet/broadcom/bnx2.h +++ b/drivers/net/ethernet/broadcom/bnx2.h | |||
@@ -6900,6 +6900,7 @@ struct bnx2 { | |||
6900 | 6900 | ||
6901 | u16 fw_wr_seq; | 6901 | u16 fw_wr_seq; |
6902 | u16 fw_drv_pulse_wr_seq; | 6902 | u16 fw_drv_pulse_wr_seq; |
6903 | u32 fw_last_msg; | ||
6903 | 6904 | ||
6904 | int rx_max_ring; | 6905 | int rx_max_ring; |
6905 | int rx_ring_size; | 6906 | int rx_ring_size; |
@@ -7406,6 +7407,10 @@ struct bnx2_rv2p_fw_file { | |||
7406 | #define BNX2_CONDITION_MFW_RUN_NCSI 0x00006000 | 7407 | #define BNX2_CONDITION_MFW_RUN_NCSI 0x00006000 |
7407 | #define BNX2_CONDITION_MFW_RUN_NONE 0x0000e000 | 7408 | #define BNX2_CONDITION_MFW_RUN_NONE 0x0000e000 |
7408 | #define BNX2_CONDITION_MFW_RUN_MASK 0x0000e000 | 7409 | #define BNX2_CONDITION_MFW_RUN_MASK 0x0000e000 |
7410 | #define BNX2_CONDITION_PM_STATE_MASK 0x00030000 | ||
7411 | #define BNX2_CONDITION_PM_STATE_FULL 0x00030000 | ||
7412 | #define BNX2_CONDITION_PM_STATE_PREP 0x00020000 | ||
7413 | #define BNX2_CONDITION_PM_STATE_UNPREP 0x00010000 | ||
7409 | 7414 | ||
7410 | #define BNX2_BC_STATE_DEBUG_CMD 0x1dc | 7415 | #define BNX2_BC_STATE_DEBUG_CMD 0x1dc |
7411 | #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 | 7416 | #define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 9d7419e0390b..dbcff509dc3f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1873,7 +1873,7 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) | |||
1873 | } | 1873 | } |
1874 | 1874 | ||
1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 1875 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
1876 | void *accel_priv) | 1876 | void *accel_priv, select_queue_fallback_t fallback) |
1877 | { | 1877 | { |
1878 | struct bnx2x *bp = netdev_priv(dev); | 1878 | struct bnx2x *bp = netdev_priv(dev); |
1879 | 1879 | ||
@@ -1895,7 +1895,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
1895 | } | 1895 | } |
1896 | 1896 | ||
1897 | /* select a non-FCoE queue */ | 1897 | /* select a non-FCoE queue */ |
1898 | return __netdev_pick_tx(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); | 1898 | return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp); |
1899 | } | 1899 | } |
1900 | 1900 | ||
1901 | void bnx2x_set_num_queues(struct bnx2x *bp) | 1901 | void bnx2x_set_num_queues(struct bnx2x *bp) |
@@ -3875,7 +3875,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3875 | xmit_type); | 3875 | xmit_type); |
3876 | } | 3876 | } |
3877 | 3877 | ||
3878 | /* Add the macs to the parsing BD this is a vf */ | 3878 | /* Add the macs to the parsing BD if this is a vf or if |
3879 | * Tx Switching is enabled. | ||
3880 | */ | ||
3879 | if (IS_VF(bp)) { | 3881 | if (IS_VF(bp)) { |
3880 | /* override GRE parameters in BD */ | 3882 | /* override GRE parameters in BD */ |
3881 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, | 3883 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.src_hi, |
@@ -3887,6 +3889,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3887 | &pbd_e2->data.mac_addr.dst_mid, | 3889 | &pbd_e2->data.mac_addr.dst_mid, |
3888 | &pbd_e2->data.mac_addr.dst_lo, | 3890 | &pbd_e2->data.mac_addr.dst_lo, |
3889 | eth->h_dest); | 3891 | eth->h_dest); |
3892 | } else if (bp->flags & TX_SWITCHING) { | ||
3893 | bnx2x_set_fw_mac_addr(&pbd_e2->data.mac_addr.dst_hi, | ||
3894 | &pbd_e2->data.mac_addr.dst_mid, | ||
3895 | &pbd_e2->data.mac_addr.dst_lo, | ||
3896 | eth->h_dest); | ||
3890 | } | 3897 | } |
3891 | 3898 | ||
3892 | SET_FLAG(pbd_e2_parsing_data, | 3899 | SET_FLAG(pbd_e2_parsing_data, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 17d1689aec6b..a89a40f88c25 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -496,7 +496,7 @@ int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos); | |||
496 | 496 | ||
497 | /* select_queue callback */ | 497 | /* select_queue callback */ |
498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, | 498 | u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb, |
499 | void *accel_priv); | 499 | void *accel_priv, select_queue_fallback_t fallback); |
500 | 500 | ||
501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, | 501 | static inline void bnx2x_update_rx_prod(struct bnx2x *bp, |
502 | struct bnx2x_fastpath *fp, | 502 | struct bnx2x_fastpath *fp, |
@@ -936,7 +936,7 @@ static inline int bnx2x_func_start(struct bnx2x *bp) | |||
936 | else /* CHIP_IS_E1X */ | 936 | else /* CHIP_IS_E1X */ |
937 | start_params->network_cos_mode = FW_WRR; | 937 | start_params->network_cos_mode = FW_WRR; |
938 | 938 | ||
939 | start_params->gre_tunnel_mode = IPGRE_TUNNEL; | 939 | start_params->gre_tunnel_mode = L2GRE_TUNNEL; |
940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; | 940 | start_params->gre_tunnel_rss = GRE_INNER_HEADERS_RSS; |
941 | 941 | ||
942 | return bnx2x_func_state_change(bp, &func_params); | 942 | return bnx2x_func_state_change(bp, &func_params); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c9c445e7b4a5..7d4382286457 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -95,29 +95,29 @@ MODULE_FIRMWARE(FW_FILE_NAME_E1H); | |||
95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); | 95 | MODULE_FIRMWARE(FW_FILE_NAME_E2); |
96 | 96 | ||
97 | int bnx2x_num_queues; | 97 | int bnx2x_num_queues; |
98 | module_param_named(num_queues, bnx2x_num_queues, int, 0); | 98 | module_param_named(num_queues, bnx2x_num_queues, int, S_IRUGO); |
99 | MODULE_PARM_DESC(num_queues, | 99 | MODULE_PARM_DESC(num_queues, |
100 | " Set number of queues (default is as a number of CPUs)"); | 100 | " Set number of queues (default is as a number of CPUs)"); |
101 | 101 | ||
102 | static int disable_tpa; | 102 | static int disable_tpa; |
103 | module_param(disable_tpa, int, 0); | 103 | module_param(disable_tpa, int, S_IRUGO); |
104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); | 104 | MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature"); |
105 | 105 | ||
106 | static int int_mode; | 106 | static int int_mode; |
107 | module_param(int_mode, int, 0); | 107 | module_param(int_mode, int, S_IRUGO); |
108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " | 108 | MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X " |
109 | "(1 INT#x; 2 MSI)"); | 109 | "(1 INT#x; 2 MSI)"); |
110 | 110 | ||
111 | static int dropless_fc; | 111 | static int dropless_fc; |
112 | module_param(dropless_fc, int, 0); | 112 | module_param(dropless_fc, int, S_IRUGO); |
113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); | 113 | MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); |
114 | 114 | ||
115 | static int mrrs = -1; | 115 | static int mrrs = -1; |
116 | module_param(mrrs, int, 0); | 116 | module_param(mrrs, int, S_IRUGO); |
117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); | 117 | MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); |
118 | 118 | ||
119 | static int debug; | 119 | static int debug; |
120 | module_param(debug, int, 0); | 120 | module_param(debug, int, S_IRUGO); |
121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); | 121 | MODULE_PARM_DESC(debug, " Default debug msglevel"); |
122 | 122 | ||
123 | struct workqueue_struct *bnx2x_wq; | 123 | struct workqueue_struct *bnx2x_wq; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index aec5ef2ed7ce..e42f48df6e94 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -1446,12 +1446,12 @@ static void bnx2x_vf_igu_reset(struct bnx2x *bp, struct bnx2x_virtf *vf) | |||
1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) | 1446 | if (vf->cfg_flags & VF_CFG_INT_SIMD) |
1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; | 1447 | val |= IGU_VF_CONF_SINGLE_ISR_EN; |
1448 | val &= ~IGU_VF_CONF_PARENT_MASK; | 1448 | val &= ~IGU_VF_CONF_PARENT_MASK; |
1449 | val |= BP_FUNC(bp) << IGU_VF_CONF_PARENT_SHIFT; /* parent PF */ | 1449 | val |= (BP_ABS_FUNC(bp) >> 1) << IGU_VF_CONF_PARENT_SHIFT; |
1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); | 1450 | REG_WR(bp, IGU_REG_VF_CONFIGURATION, val); |
1451 | 1451 | ||
1452 | DP(BNX2X_MSG_IOV, | 1452 | DP(BNX2X_MSG_IOV, |
1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write %x\n", | 1453 | "value in IGU_REG_VF_CONFIGURATION of vf %d after write is 0x%08x\n", |
1454 | vf->abs_vfid, REG_RD(bp, IGU_REG_VF_CONFIGURATION)); | 1454 | vf->abs_vfid, val); |
1455 | 1455 | ||
1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); | 1456 | bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); |
1457 | 1457 | ||
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index fcf9105a5476..09f3fefcbf9c 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* cnic.c: Broadcom CNIC core network driver. | 1 | /* cnic.c: Broadcom CNIC core network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2006-2013 Broadcom Corporation | 3 | * Copyright (c) 2006-2014 Broadcom Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -342,7 +342,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, | |||
342 | while (retry < 3) { | 342 | while (retry < 3) { |
343 | rc = 0; | 343 | rc = 0; |
344 | rcu_read_lock(); | 344 | rcu_read_lock(); |
345 | ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]); | 345 | ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]); |
346 | if (ulp_ops) | 346 | if (ulp_ops) |
347 | rc = ulp_ops->iscsi_nl_send_msg( | 347 | rc = ulp_ops->iscsi_nl_send_msg( |
348 | cp->ulp_handle[CNIC_ULP_ISCSI], | 348 | cp->ulp_handle[CNIC_ULP_ISCSI], |
@@ -726,7 +726,7 @@ static void cnic_free_dma(struct cnic_dev *dev, struct cnic_dma *dma) | |||
726 | 726 | ||
727 | for (i = 0; i < dma->num_pages; i++) { | 727 | for (i = 0; i < dma->num_pages; i++) { |
728 | if (dma->pg_arr[i]) { | 728 | if (dma->pg_arr[i]) { |
729 | dma_free_coherent(&dev->pcidev->dev, BNX2_PAGE_SIZE, | 729 | dma_free_coherent(&dev->pcidev->dev, CNIC_PAGE_SIZE, |
730 | dma->pg_arr[i], dma->pg_map_arr[i]); | 730 | dma->pg_arr[i], dma->pg_map_arr[i]); |
731 | dma->pg_arr[i] = NULL; | 731 | dma->pg_arr[i] = NULL; |
732 | } | 732 | } |
@@ -785,7 +785,7 @@ static int cnic_alloc_dma(struct cnic_dev *dev, struct cnic_dma *dma, | |||
785 | 785 | ||
786 | for (i = 0; i < pages; i++) { | 786 | for (i = 0; i < pages; i++) { |
787 | dma->pg_arr[i] = dma_alloc_coherent(&dev->pcidev->dev, | 787 | dma->pg_arr[i] = dma_alloc_coherent(&dev->pcidev->dev, |
788 | BNX2_PAGE_SIZE, | 788 | CNIC_PAGE_SIZE, |
789 | &dma->pg_map_arr[i], | 789 | &dma->pg_map_arr[i], |
790 | GFP_ATOMIC); | 790 | GFP_ATOMIC); |
791 | if (dma->pg_arr[i] == NULL) | 791 | if (dma->pg_arr[i] == NULL) |
@@ -794,8 +794,8 @@ static int cnic_alloc_dma(struct cnic_dev *dev, struct cnic_dma *dma, | |||
794 | if (!use_pg_tbl) | 794 | if (!use_pg_tbl) |
795 | return 0; | 795 | return 0; |
796 | 796 | ||
797 | dma->pgtbl_size = ((pages * 8) + BNX2_PAGE_SIZE - 1) & | 797 | dma->pgtbl_size = ((pages * 8) + CNIC_PAGE_SIZE - 1) & |
798 | ~(BNX2_PAGE_SIZE - 1); | 798 | ~(CNIC_PAGE_SIZE - 1); |
799 | dma->pgtbl = dma_alloc_coherent(&dev->pcidev->dev, dma->pgtbl_size, | 799 | dma->pgtbl = dma_alloc_coherent(&dev->pcidev->dev, dma->pgtbl_size, |
800 | &dma->pgtbl_map, GFP_ATOMIC); | 800 | &dma->pgtbl_map, GFP_ATOMIC); |
801 | if (dma->pgtbl == NULL) | 801 | if (dma->pgtbl == NULL) |
@@ -900,8 +900,8 @@ static int cnic_alloc_context(struct cnic_dev *dev) | |||
900 | if (BNX2_CHIP(cp) == BNX2_CHIP_5709) { | 900 | if (BNX2_CHIP(cp) == BNX2_CHIP_5709) { |
901 | int i, k, arr_size; | 901 | int i, k, arr_size; |
902 | 902 | ||
903 | cp->ctx_blk_size = BNX2_PAGE_SIZE; | 903 | cp->ctx_blk_size = CNIC_PAGE_SIZE; |
904 | cp->cids_per_blk = BNX2_PAGE_SIZE / 128; | 904 | cp->cids_per_blk = CNIC_PAGE_SIZE / 128; |
905 | arr_size = BNX2_MAX_CID / cp->cids_per_blk * | 905 | arr_size = BNX2_MAX_CID / cp->cids_per_blk * |
906 | sizeof(struct cnic_ctx); | 906 | sizeof(struct cnic_ctx); |
907 | cp->ctx_arr = kzalloc(arr_size, GFP_KERNEL); | 907 | cp->ctx_arr = kzalloc(arr_size, GFP_KERNEL); |
@@ -933,7 +933,7 @@ static int cnic_alloc_context(struct cnic_dev *dev) | |||
933 | for (i = 0; i < cp->ctx_blks; i++) { | 933 | for (i = 0; i < cp->ctx_blks; i++) { |
934 | cp->ctx_arr[i].ctx = | 934 | cp->ctx_arr[i].ctx = |
935 | dma_alloc_coherent(&dev->pcidev->dev, | 935 | dma_alloc_coherent(&dev->pcidev->dev, |
936 | BNX2_PAGE_SIZE, | 936 | CNIC_PAGE_SIZE, |
937 | &cp->ctx_arr[i].mapping, | 937 | &cp->ctx_arr[i].mapping, |
938 | GFP_KERNEL); | 938 | GFP_KERNEL); |
939 | if (cp->ctx_arr[i].ctx == NULL) | 939 | if (cp->ctx_arr[i].ctx == NULL) |
@@ -1013,7 +1013,7 @@ static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages) | |||
1013 | if (udev->l2_ring) | 1013 | if (udev->l2_ring) |
1014 | return 0; | 1014 | return 0; |
1015 | 1015 | ||
1016 | udev->l2_ring_size = pages * BNX2_PAGE_SIZE; | 1016 | udev->l2_ring_size = pages * CNIC_PAGE_SIZE; |
1017 | udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, | 1017 | udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, |
1018 | &udev->l2_ring_map, | 1018 | &udev->l2_ring_map, |
1019 | GFP_KERNEL | __GFP_COMP); | 1019 | GFP_KERNEL | __GFP_COMP); |
@@ -1021,7 +1021,7 @@ static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages) | |||
1021 | return -ENOMEM; | 1021 | return -ENOMEM; |
1022 | 1022 | ||
1023 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; | 1023 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; |
1024 | udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); | 1024 | udev->l2_buf_size = CNIC_PAGE_ALIGN(udev->l2_buf_size); |
1025 | udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, | 1025 | udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, |
1026 | &udev->l2_buf_map, | 1026 | &udev->l2_buf_map, |
1027 | GFP_KERNEL | __GFP_COMP); | 1027 | GFP_KERNEL | __GFP_COMP); |
@@ -1102,7 +1102,7 @@ static int cnic_init_uio(struct cnic_dev *dev) | |||
1102 | uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + | 1102 | uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + |
1103 | TX_MAX_TSS_RINGS + 1); | 1103 | TX_MAX_TSS_RINGS + 1); |
1104 | uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & | 1104 | uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & |
1105 | PAGE_MASK; | 1105 | CNIC_PAGE_MASK; |
1106 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) | 1106 | if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) |
1107 | uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; | 1107 | uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; |
1108 | else | 1108 | else |
@@ -1113,7 +1113,7 @@ static int cnic_init_uio(struct cnic_dev *dev) | |||
1113 | uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); | 1113 | uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); |
1114 | 1114 | ||
1115 | uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & | 1115 | uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & |
1116 | PAGE_MASK; | 1116 | CNIC_PAGE_MASK; |
1117 | uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); | 1117 | uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); |
1118 | 1118 | ||
1119 | uinfo->name = "bnx2x_cnic"; | 1119 | uinfo->name = "bnx2x_cnic"; |
@@ -1267,14 +1267,14 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) | |||
1267 | for (i = MAX_ISCSI_TBL_SZ; i < cp->max_cid_space; i++) | 1267 | for (i = MAX_ISCSI_TBL_SZ; i < cp->max_cid_space; i++) |
1268 | cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_FCOE; | 1268 | cp->ctx_tbl[i].ulp_proto_id = CNIC_ULP_FCOE; |
1269 | 1269 | ||
1270 | pages = PAGE_ALIGN(cp->max_cid_space * CNIC_KWQ16_DATA_SIZE) / | 1270 | pages = CNIC_PAGE_ALIGN(cp->max_cid_space * CNIC_KWQ16_DATA_SIZE) / |
1271 | PAGE_SIZE; | 1271 | CNIC_PAGE_SIZE; |
1272 | 1272 | ||
1273 | ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0); | 1273 | ret = cnic_alloc_dma(dev, kwq_16_dma, pages, 0); |
1274 | if (ret) | 1274 | if (ret) |
1275 | return -ENOMEM; | 1275 | return -ENOMEM; |
1276 | 1276 | ||
1277 | n = PAGE_SIZE / CNIC_KWQ16_DATA_SIZE; | 1277 | n = CNIC_PAGE_SIZE / CNIC_KWQ16_DATA_SIZE; |
1278 | for (i = 0, j = 0; i < cp->max_cid_space; i++) { | 1278 | for (i = 0, j = 0; i < cp->max_cid_space; i++) { |
1279 | long off = CNIC_KWQ16_DATA_SIZE * (i % n); | 1279 | long off = CNIC_KWQ16_DATA_SIZE * (i % n); |
1280 | 1280 | ||
@@ -1296,7 +1296,7 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) | |||
1296 | goto error; | 1296 | goto error; |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | pages = PAGE_ALIGN(BNX2X_ISCSI_GLB_BUF_SIZE) / PAGE_SIZE; | 1299 | pages = CNIC_PAGE_ALIGN(BNX2X_ISCSI_GLB_BUF_SIZE) / CNIC_PAGE_SIZE; |
1300 | ret = cnic_alloc_dma(dev, &cp->gbl_buf_info, pages, 0); | 1300 | ret = cnic_alloc_dma(dev, &cp->gbl_buf_info, pages, 0); |
1301 | if (ret) | 1301 | if (ret) |
1302 | goto error; | 1302 | goto error; |
@@ -1466,8 +1466,8 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) | |||
1466 | cp->r2tq_size = cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS * | 1466 | cp->r2tq_size = cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS * |
1467 | BNX2X_ISCSI_R2TQE_SIZE; | 1467 | BNX2X_ISCSI_R2TQE_SIZE; |
1468 | cp->hq_size = cp->num_ccells * BNX2X_ISCSI_HQ_BD_SIZE; | 1468 | cp->hq_size = cp->num_ccells * BNX2X_ISCSI_HQ_BD_SIZE; |
1469 | pages = PAGE_ALIGN(cp->hq_size) / PAGE_SIZE; | 1469 | pages = CNIC_PAGE_ALIGN(cp->hq_size) / CNIC_PAGE_SIZE; |
1470 | hq_bds = pages * (PAGE_SIZE / BNX2X_ISCSI_HQ_BD_SIZE); | 1470 | hq_bds = pages * (CNIC_PAGE_SIZE / BNX2X_ISCSI_HQ_BD_SIZE); |
1471 | cp->num_cqs = req1->num_cqs; | 1471 | cp->num_cqs = req1->num_cqs; |
1472 | 1472 | ||
1473 | if (!dev->max_iscsi_conn) | 1473 | if (!dev->max_iscsi_conn) |
@@ -1477,9 +1477,9 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) | |||
1477 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(pfid), | 1477 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(pfid), |
1478 | req1->rq_num_wqes); | 1478 | req1->rq_num_wqes); |
1479 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), | 1479 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), |
1480 | PAGE_SIZE); | 1480 | CNIC_PAGE_SIZE); |
1481 | CNIC_WR8(dev, BAR_TSTRORM_INTMEM + | 1481 | CNIC_WR8(dev, BAR_TSTRORM_INTMEM + |
1482 | TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); | 1482 | TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), CNIC_PAGE_BITS); |
1483 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + | 1483 | CNIC_WR16(dev, BAR_TSTRORM_INTMEM + |
1484 | TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), | 1484 | TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), |
1485 | req1->num_tasks_per_conn); | 1485 | req1->num_tasks_per_conn); |
@@ -1489,9 +1489,9 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) | |||
1489 | USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfid), | 1489 | USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfid), |
1490 | req1->rq_buffer_size); | 1490 | req1->rq_buffer_size); |
1491 | CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), | 1491 | CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), |
1492 | PAGE_SIZE); | 1492 | CNIC_PAGE_SIZE); |
1493 | CNIC_WR8(dev, BAR_USTRORM_INTMEM + | 1493 | CNIC_WR8(dev, BAR_USTRORM_INTMEM + |
1494 | USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); | 1494 | USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), CNIC_PAGE_BITS); |
1495 | CNIC_WR16(dev, BAR_USTRORM_INTMEM + | 1495 | CNIC_WR16(dev, BAR_USTRORM_INTMEM + |
1496 | USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), | 1496 | USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), |
1497 | req1->num_tasks_per_conn); | 1497 | req1->num_tasks_per_conn); |
@@ -1504,9 +1504,9 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) | |||
1504 | 1504 | ||
1505 | /* init Xstorm RAM */ | 1505 | /* init Xstorm RAM */ |
1506 | CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), | 1506 | CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), |
1507 | PAGE_SIZE); | 1507 | CNIC_PAGE_SIZE); |
1508 | CNIC_WR8(dev, BAR_XSTRORM_INTMEM + | 1508 | CNIC_WR8(dev, BAR_XSTRORM_INTMEM + |
1509 | XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); | 1509 | XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), CNIC_PAGE_BITS); |
1510 | CNIC_WR16(dev, BAR_XSTRORM_INTMEM + | 1510 | CNIC_WR16(dev, BAR_XSTRORM_INTMEM + |
1511 | XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), | 1511 | XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), |
1512 | req1->num_tasks_per_conn); | 1512 | req1->num_tasks_per_conn); |
@@ -1519,9 +1519,9 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) | |||
1519 | 1519 | ||
1520 | /* init Cstorm RAM */ | 1520 | /* init Cstorm RAM */ |
1521 | CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), | 1521 | CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), |
1522 | PAGE_SIZE); | 1522 | CNIC_PAGE_SIZE); |
1523 | CNIC_WR8(dev, BAR_CSTRORM_INTMEM + | 1523 | CNIC_WR8(dev, BAR_CSTRORM_INTMEM + |
1524 | CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); | 1524 | CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), CNIC_PAGE_BITS); |
1525 | CNIC_WR16(dev, BAR_CSTRORM_INTMEM + | 1525 | CNIC_WR16(dev, BAR_CSTRORM_INTMEM + |
1526 | CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), | 1526 | CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), |
1527 | req1->num_tasks_per_conn); | 1527 | req1->num_tasks_per_conn); |
@@ -1623,18 +1623,18 @@ static int cnic_alloc_bnx2x_conn_resc(struct cnic_dev *dev, u32 l5_cid) | |||
1623 | } | 1623 | } |
1624 | 1624 | ||
1625 | ctx->cid = cid; | 1625 | ctx->cid = cid; |
1626 | pages = PAGE_ALIGN(cp->task_array_size) / PAGE_SIZE; | 1626 | pages = CNIC_PAGE_ALIGN(cp->task_array_size) / CNIC_PAGE_SIZE; |
1627 | 1627 | ||
1628 | ret = cnic_alloc_dma(dev, &iscsi->task_array_info, pages, 1); | 1628 | ret = cnic_alloc_dma(dev, &iscsi->task_array_info, pages, 1); |
1629 | if (ret) | 1629 | if (ret) |
1630 | goto error; | 1630 | goto error; |
1631 | 1631 | ||
1632 | pages = PAGE_ALIGN(cp->r2tq_size) / PAGE_SIZE; | 1632 | pages = CNIC_PAGE_ALIGN(cp->r2tq_size) / CNIC_PAGE_SIZE; |
1633 | ret = cnic_alloc_dma(dev, &iscsi->r2tq_info, pages, 1); | 1633 | ret = cnic_alloc_dma(dev, &iscsi->r2tq_info, pages, 1); |
1634 | if (ret) | 1634 | if (ret) |
1635 | goto error; | 1635 | goto error; |
1636 | 1636 | ||
1637 | pages = PAGE_ALIGN(cp->hq_size) / PAGE_SIZE; | 1637 | pages = CNIC_PAGE_ALIGN(cp->hq_size) / CNIC_PAGE_SIZE; |
1638 | ret = cnic_alloc_dma(dev, &iscsi->hq_info, pages, 1); | 1638 | ret = cnic_alloc_dma(dev, &iscsi->hq_info, pages, 1); |
1639 | if (ret) | 1639 | if (ret) |
1640 | goto error; | 1640 | goto error; |
@@ -1760,7 +1760,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], | |||
1760 | ictx->tstorm_st_context.iscsi.hdr_bytes_2_fetch = ISCSI_HEADER_SIZE; | 1760 | ictx->tstorm_st_context.iscsi.hdr_bytes_2_fetch = ISCSI_HEADER_SIZE; |
1761 | /* TSTORM requires the base address of RQ DB & not PTE */ | 1761 | /* TSTORM requires the base address of RQ DB & not PTE */ |
1762 | ictx->tstorm_st_context.iscsi.rq_db_phy_addr.lo = | 1762 | ictx->tstorm_st_context.iscsi.rq_db_phy_addr.lo = |
1763 | req2->rq_page_table_addr_lo & PAGE_MASK; | 1763 | req2->rq_page_table_addr_lo & CNIC_PAGE_MASK; |
1764 | ictx->tstorm_st_context.iscsi.rq_db_phy_addr.hi = | 1764 | ictx->tstorm_st_context.iscsi.rq_db_phy_addr.hi = |
1765 | req2->rq_page_table_addr_hi; | 1765 | req2->rq_page_table_addr_hi; |
1766 | ictx->tstorm_st_context.iscsi.iscsi_conn_id = req1->iscsi_conn_id; | 1766 | ictx->tstorm_st_context.iscsi.iscsi_conn_id = req1->iscsi_conn_id; |
@@ -1842,7 +1842,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], | |||
1842 | /* CSTORM and USTORM initialization is different, CSTORM requires | 1842 | /* CSTORM and USTORM initialization is different, CSTORM requires |
1843 | * CQ DB base & not PTE addr */ | 1843 | * CQ DB base & not PTE addr */ |
1844 | ictx->cstorm_st_context.cq_db_base.lo = | 1844 | ictx->cstorm_st_context.cq_db_base.lo = |
1845 | req1->cq_page_table_addr_lo & PAGE_MASK; | 1845 | req1->cq_page_table_addr_lo & CNIC_PAGE_MASK; |
1846 | ictx->cstorm_st_context.cq_db_base.hi = req1->cq_page_table_addr_hi; | 1846 | ictx->cstorm_st_context.cq_db_base.hi = req1->cq_page_table_addr_hi; |
1847 | ictx->cstorm_st_context.iscsi_conn_id = req1->iscsi_conn_id; | 1847 | ictx->cstorm_st_context.iscsi_conn_id = req1->iscsi_conn_id; |
1848 | ictx->cstorm_st_context.cq_proc_en_bit_map = (1 << cp->num_cqs) - 1; | 1848 | ictx->cstorm_st_context.cq_proc_en_bit_map = (1 << cp->num_cqs) - 1; |
@@ -2911,7 +2911,7 @@ static int cnic_l2_completion(struct cnic_local *cp) | |||
2911 | u16 hw_cons, sw_cons; | 2911 | u16 hw_cons, sw_cons; |
2912 | struct cnic_uio_dev *udev = cp->udev; | 2912 | struct cnic_uio_dev *udev = cp->udev; |
2913 | union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *) | 2913 | union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *) |
2914 | (udev->l2_ring + (2 * BNX2_PAGE_SIZE)); | 2914 | (udev->l2_ring + (2 * CNIC_PAGE_SIZE)); |
2915 | u32 cmd; | 2915 | u32 cmd; |
2916 | int comp = 0; | 2916 | int comp = 0; |
2917 | 2917 | ||
@@ -3244,7 +3244,8 @@ static int cnic_copy_ulp_stats(struct cnic_dev *dev, int ulp_type) | |||
3244 | int rc; | 3244 | int rc; |
3245 | 3245 | ||
3246 | mutex_lock(&cnic_lock); | 3246 | mutex_lock(&cnic_lock); |
3247 | ulp_ops = cnic_ulp_tbl_prot(ulp_type); | 3247 | ulp_ops = rcu_dereference_protected(cp->ulp_ops[ulp_type], |
3248 | lockdep_is_held(&cnic_lock)); | ||
3248 | if (ulp_ops && ulp_ops->cnic_get_stats) | 3249 | if (ulp_ops && ulp_ops->cnic_get_stats) |
3249 | rc = ulp_ops->cnic_get_stats(cp->ulp_handle[ulp_type]); | 3250 | rc = ulp_ops->cnic_get_stats(cp->ulp_handle[ulp_type]); |
3250 | else | 3251 | else |
@@ -4384,7 +4385,7 @@ static int cnic_setup_5709_context(struct cnic_dev *dev, int valid) | |||
4384 | u32 idx = cp->ctx_arr[i].cid / cp->cids_per_blk; | 4385 | u32 idx = cp->ctx_arr[i].cid / cp->cids_per_blk; |
4385 | u32 val; | 4386 | u32 val; |
4386 | 4387 | ||
4387 | memset(cp->ctx_arr[i].ctx, 0, BNX2_PAGE_SIZE); | 4388 | memset(cp->ctx_arr[i].ctx, 0, CNIC_PAGE_SIZE); |
4388 | 4389 | ||
4389 | CNIC_WR(dev, BNX2_CTX_HOST_PAGE_TBL_DATA0, | 4390 | CNIC_WR(dev, BNX2_CTX_HOST_PAGE_TBL_DATA0, |
4390 | (cp->ctx_arr[i].mapping & 0xffffffff) | valid_bit); | 4391 | (cp->ctx_arr[i].mapping & 0xffffffff) | valid_bit); |
@@ -4628,7 +4629,7 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) | |||
4628 | val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); | 4629 | val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); |
4629 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); | 4630 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); |
4630 | 4631 | ||
4631 | rxbd = udev->l2_ring + BNX2_PAGE_SIZE; | 4632 | rxbd = udev->l2_ring + CNIC_PAGE_SIZE; |
4632 | for (i = 0; i < BNX2_MAX_RX_DESC_CNT; i++, rxbd++) { | 4633 | for (i = 0; i < BNX2_MAX_RX_DESC_CNT; i++, rxbd++) { |
4633 | dma_addr_t buf_map; | 4634 | dma_addr_t buf_map; |
4634 | int n = (i % cp->l2_rx_ring_size) + 1; | 4635 | int n = (i % cp->l2_rx_ring_size) + 1; |
@@ -4639,11 +4640,11 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) | |||
4639 | rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32; | 4640 | rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32; |
4640 | rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff; | 4641 | rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff; |
4641 | } | 4642 | } |
4642 | val = (u64) (ring_map + BNX2_PAGE_SIZE) >> 32; | 4643 | val = (u64) (ring_map + CNIC_PAGE_SIZE) >> 32; |
4643 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); | 4644 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); |
4644 | rxbd->rx_bd_haddr_hi = val; | 4645 | rxbd->rx_bd_haddr_hi = val; |
4645 | 4646 | ||
4646 | val = (u64) (ring_map + BNX2_PAGE_SIZE) & 0xffffffff; | 4647 | val = (u64) (ring_map + CNIC_PAGE_SIZE) & 0xffffffff; |
4647 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); | 4648 | cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); |
4648 | rxbd->rx_bd_haddr_lo = val; | 4649 | rxbd->rx_bd_haddr_lo = val; |
4649 | 4650 | ||
@@ -4709,10 +4710,10 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
4709 | 4710 | ||
4710 | val = CNIC_RD(dev, BNX2_MQ_CONFIG); | 4711 | val = CNIC_RD(dev, BNX2_MQ_CONFIG); |
4711 | val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; | 4712 | val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; |
4712 | if (BNX2_PAGE_BITS > 12) | 4713 | if (CNIC_PAGE_BITS > 12) |
4713 | val |= (12 - 8) << 4; | 4714 | val |= (12 - 8) << 4; |
4714 | else | 4715 | else |
4715 | val |= (BNX2_PAGE_BITS - 8) << 4; | 4716 | val |= (CNIC_PAGE_BITS - 8) << 4; |
4716 | 4717 | ||
4717 | CNIC_WR(dev, BNX2_MQ_CONFIG, val); | 4718 | CNIC_WR(dev, BNX2_MQ_CONFIG, val); |
4718 | 4719 | ||
@@ -4742,13 +4743,13 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
4742 | 4743 | ||
4743 | /* Initialize the kernel work queue context. */ | 4744 | /* Initialize the kernel work queue context. */ |
4744 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | | 4745 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | |
4745 | (BNX2_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ; | 4746 | (CNIC_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ; |
4746 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_TYPE, val); | 4747 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_TYPE, val); |
4747 | 4748 | ||
4748 | val = (BNX2_PAGE_SIZE / sizeof(struct kwqe) - 1) << 16; | 4749 | val = (CNIC_PAGE_SIZE / sizeof(struct kwqe) - 1) << 16; |
4749 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val); | 4750 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val); |
4750 | 4751 | ||
4751 | val = ((BNX2_PAGE_SIZE / sizeof(struct kwqe)) << 16) | KWQ_PAGE_CNT; | 4752 | val = ((CNIC_PAGE_SIZE / sizeof(struct kwqe)) << 16) | KWQ_PAGE_CNT; |
4752 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val); | 4753 | cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val); |
4753 | 4754 | ||
4754 | val = (u32) ((u64) cp->kwq_info.pgtbl_map >> 32); | 4755 | val = (u32) ((u64) cp->kwq_info.pgtbl_map >> 32); |
@@ -4768,13 +4769,13 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev) | |||
4768 | 4769 | ||
4769 | /* Initialize the kernel complete queue context. */ | 4770 | /* Initialize the kernel complete queue context. */ |
4770 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | | 4771 | val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | |
4771 | (BNX2_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ; | 4772 | (CNIC_PAGE_BITS - 8) | KRNLQ_FLAGS_QE_SELF_SEQ; |
4772 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_TYPE, val); | 4773 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_TYPE, val); |
4773 | 4774 | ||
4774 | val = (BNX2_PAGE_SIZE / sizeof(struct kcqe) - 1) << 16; | 4775 | val = (CNIC_PAGE_SIZE / sizeof(struct kcqe) - 1) << 16; |
4775 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val); | 4776 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_QE_SELF_SEQ_MAX, val); |
4776 | 4777 | ||
4777 | val = ((BNX2_PAGE_SIZE / sizeof(struct kcqe)) << 16) | KCQ_PAGE_CNT; | 4778 | val = ((CNIC_PAGE_SIZE / sizeof(struct kcqe)) << 16) | KCQ_PAGE_CNT; |
4778 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val); | 4779 | cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_PGTBL_NPAGES, val); |
4779 | 4780 | ||
4780 | val = (u32) ((u64) cp->kcq1.dma.pgtbl_map >> 32); | 4781 | val = (u32) ((u64) cp->kcq1.dma.pgtbl_map >> 32); |
@@ -4918,7 +4919,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, | |||
4918 | u32 cli = cp->ethdev->iscsi_l2_client_id; | 4919 | u32 cli = cp->ethdev->iscsi_l2_client_id; |
4919 | u32 val; | 4920 | u32 val; |
4920 | 4921 | ||
4921 | memset(txbd, 0, BNX2_PAGE_SIZE); | 4922 | memset(txbd, 0, CNIC_PAGE_SIZE); |
4922 | 4923 | ||
4923 | buf_map = udev->l2_buf_map; | 4924 | buf_map = udev->l2_buf_map; |
4924 | for (i = 0; i < BNX2_MAX_TX_DESC_CNT; i += 3, txbd += 3) { | 4925 | for (i = 0; i < BNX2_MAX_TX_DESC_CNT; i += 3, txbd += 3) { |
@@ -4978,9 +4979,9 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, | |||
4978 | struct bnx2x *bp = netdev_priv(dev->netdev); | 4979 | struct bnx2x *bp = netdev_priv(dev->netdev); |
4979 | struct cnic_uio_dev *udev = cp->udev; | 4980 | struct cnic_uio_dev *udev = cp->udev; |
4980 | struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring + | 4981 | struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring + |
4981 | BNX2_PAGE_SIZE); | 4982 | CNIC_PAGE_SIZE); |
4982 | struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) | 4983 | struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) |
4983 | (udev->l2_ring + (2 * BNX2_PAGE_SIZE)); | 4984 | (udev->l2_ring + (2 * CNIC_PAGE_SIZE)); |
4984 | struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; | 4985 | struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; |
4985 | int i; | 4986 | int i; |
4986 | u32 cli = cp->ethdev->iscsi_l2_client_id; | 4987 | u32 cli = cp->ethdev->iscsi_l2_client_id; |
@@ -5004,20 +5005,20 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, | |||
5004 | rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); | 5005 | rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); |
5005 | } | 5006 | } |
5006 | 5007 | ||
5007 | val = (u64) (ring_map + BNX2_PAGE_SIZE) >> 32; | 5008 | val = (u64) (ring_map + CNIC_PAGE_SIZE) >> 32; |
5008 | rxbd->addr_hi = cpu_to_le32(val); | 5009 | rxbd->addr_hi = cpu_to_le32(val); |
5009 | data->rx.bd_page_base.hi = cpu_to_le32(val); | 5010 | data->rx.bd_page_base.hi = cpu_to_le32(val); |
5010 | 5011 | ||
5011 | val = (u64) (ring_map + BNX2_PAGE_SIZE) & 0xffffffff; | 5012 | val = (u64) (ring_map + CNIC_PAGE_SIZE) & 0xffffffff; |
5012 | rxbd->addr_lo = cpu_to_le32(val); | 5013 | rxbd->addr_lo = cpu_to_le32(val); |
5013 | data->rx.bd_page_base.lo = cpu_to_le32(val); | 5014 | data->rx.bd_page_base.lo = cpu_to_le32(val); |
5014 | 5015 | ||
5015 | rxcqe += BNX2X_MAX_RCQ_DESC_CNT; | 5016 | rxcqe += BNX2X_MAX_RCQ_DESC_CNT; |
5016 | val = (u64) (ring_map + (2 * BNX2_PAGE_SIZE)) >> 32; | 5017 | val = (u64) (ring_map + (2 * CNIC_PAGE_SIZE)) >> 32; |
5017 | rxcqe->addr_hi = cpu_to_le32(val); | 5018 | rxcqe->addr_hi = cpu_to_le32(val); |
5018 | data->rx.cqe_page_base.hi = cpu_to_le32(val); | 5019 | data->rx.cqe_page_base.hi = cpu_to_le32(val); |
5019 | 5020 | ||
5020 | val = (u64) (ring_map + (2 * BNX2_PAGE_SIZE)) & 0xffffffff; | 5021 | val = (u64) (ring_map + (2 * CNIC_PAGE_SIZE)) & 0xffffffff; |
5021 | rxcqe->addr_lo = cpu_to_le32(val); | 5022 | rxcqe->addr_lo = cpu_to_le32(val); |
5022 | data->rx.cqe_page_base.lo = cpu_to_le32(val); | 5023 | data->rx.cqe_page_base.lo = cpu_to_le32(val); |
5023 | 5024 | ||
@@ -5265,8 +5266,8 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) | |||
5265 | msleep(10); | 5266 | msleep(10); |
5266 | } | 5267 | } |
5267 | clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); | 5268 | clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); |
5268 | rx_ring = udev->l2_ring + BNX2_PAGE_SIZE; | 5269 | rx_ring = udev->l2_ring + CNIC_PAGE_SIZE; |
5269 | memset(rx_ring, 0, BNX2_PAGE_SIZE); | 5270 | memset(rx_ring, 0, CNIC_PAGE_SIZE); |
5270 | } | 5271 | } |
5271 | 5272 | ||
5272 | static int cnic_register_netdev(struct cnic_dev *dev) | 5273 | static int cnic_register_netdev(struct cnic_dev *dev) |
diff --git a/drivers/net/ethernet/broadcom/cnic.h b/drivers/net/ethernet/broadcom/cnic.h index 0d6b13f854d9..d535ae4228b4 100644 --- a/drivers/net/ethernet/broadcom/cnic.h +++ b/drivers/net/ethernet/broadcom/cnic.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* cnic.h: Broadcom CNIC core network driver. | 1 | /* cnic.h: Broadcom CNIC core network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2006-2013 Broadcom Corporation | 3 | * Copyright (c) 2006-2014 Broadcom Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/net/ethernet/broadcom/cnic_defs.h b/drivers/net/ethernet/broadcom/cnic_defs.h index 95a8e4b11c9f..dcbca6997e8f 100644 --- a/drivers/net/ethernet/broadcom/cnic_defs.h +++ b/drivers/net/ethernet/broadcom/cnic_defs.h | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | /* cnic.c: Broadcom CNIC core network driver. | 2 | /* cnic.c: Broadcom CNIC core network driver. |
3 | * | 3 | * |
4 | * Copyright (c) 2006-2013 Broadcom Corporation | 4 | * Copyright (c) 2006-2014 Broadcom Corporation |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/net/ethernet/broadcom/cnic_if.h b/drivers/net/ethernet/broadcom/cnic_if.h index 8cf6b1926069..5f4d5573a73d 100644 --- a/drivers/net/ethernet/broadcom/cnic_if.h +++ b/drivers/net/ethernet/broadcom/cnic_if.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* cnic_if.h: Broadcom CNIC core network driver. | 1 | /* cnic_if.h: Broadcom CNIC core network driver. |
2 | * | 2 | * |
3 | * Copyright (c) 2006-2013 Broadcom Corporation | 3 | * Copyright (c) 2006-2014 Broadcom Corporation |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -14,8 +14,8 @@ | |||
14 | 14 | ||
15 | #include "bnx2x/bnx2x_mfw_req.h" | 15 | #include "bnx2x/bnx2x_mfw_req.h" |
16 | 16 | ||
17 | #define CNIC_MODULE_VERSION "2.5.19" | 17 | #define CNIC_MODULE_VERSION "2.5.20" |
18 | #define CNIC_MODULE_RELDATE "December 19, 2013" | 18 | #define CNIC_MODULE_RELDATE "March 14, 2014" |
19 | 19 | ||
20 | #define CNIC_ULP_RDMA 0 | 20 | #define CNIC_ULP_RDMA 0 |
21 | #define CNIC_ULP_ISCSI 1 | 21 | #define CNIC_ULP_ISCSI 1 |
@@ -24,6 +24,16 @@ | |||
24 | #define MAX_CNIC_ULP_TYPE_EXT 3 | 24 | #define MAX_CNIC_ULP_TYPE_EXT 3 |
25 | #define MAX_CNIC_ULP_TYPE 4 | 25 | #define MAX_CNIC_ULP_TYPE 4 |
26 | 26 | ||
27 | /* Use CPU native page size up to 16K for cnic ring sizes. */ | ||
28 | #if (PAGE_SHIFT > 14) | ||
29 | #define CNIC_PAGE_BITS 14 | ||
30 | #else | ||
31 | #define CNIC_PAGE_BITS PAGE_SHIFT | ||
32 | #endif | ||
33 | #define CNIC_PAGE_SIZE (1 << (CNIC_PAGE_BITS)) | ||
34 | #define CNIC_PAGE_ALIGN(addr) ALIGN(addr, CNIC_PAGE_SIZE) | ||
35 | #define CNIC_PAGE_MASK (~((CNIC_PAGE_SIZE) - 1)) | ||
36 | |||
27 | struct kwqe { | 37 | struct kwqe { |
28 | u32 kwqe_op_flag; | 38 | u32 kwqe_op_flag; |
29 | 39 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index e2ca03e23dc1..3b6d0ba86c71 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -2609,13 +2609,14 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) | |||
2609 | 2609 | ||
2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); | 2610 | tg3_writephy(tp, MII_CTRL1000, phy9_orig); |
2611 | 2611 | ||
2612 | if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32)) { | 2612 | err = tg3_readphy(tp, MII_TG3_EXT_CTRL, ®32); |
2613 | reg32 &= ~0x3000; | 2613 | if (err) |
2614 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | 2614 | return err; |
2615 | } else if (!err) | ||
2616 | err = -EBUSY; | ||
2617 | 2615 | ||
2618 | return err; | 2616 | reg32 &= ~0x3000; |
2617 | tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32); | ||
2618 | |||
2619 | return 0; | ||
2619 | } | 2620 | } |
2620 | 2621 | ||
2621 | static void tg3_carrier_off(struct tg3 *tp) | 2622 | static void tg3_carrier_off(struct tg3 *tp) |
@@ -6842,8 +6843,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
6842 | 6843 | ||
6843 | work_mask |= opaque_key; | 6844 | work_mask |= opaque_key; |
6844 | 6845 | ||
6845 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | 6846 | if (desc->err_vlan & RXD_ERR_MASK) { |
6846 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) { | ||
6847 | drop_it: | 6847 | drop_it: |
6848 | tg3_recycle_rx(tnapi, tpr, opaque_key, | 6848 | tg3_recycle_rx(tnapi, tpr, opaque_key, |
6849 | desc_idx, *post_ptr); | 6849 | desc_idx, *post_ptr); |
@@ -14113,12 +14113,12 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
14113 | 14113 | ||
14114 | tg3_netif_stop(tp); | 14114 | tg3_netif_stop(tp); |
14115 | 14115 | ||
14116 | tg3_set_mtu(dev, tp, new_mtu); | ||
14117 | |||
14116 | tg3_full_lock(tp, 1); | 14118 | tg3_full_lock(tp, 1); |
14117 | 14119 | ||
14118 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 14120 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
14119 | 14121 | ||
14120 | tg3_set_mtu(dev, tp, new_mtu); | ||
14121 | |||
14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that | 14122 | /* Reset PHY, otherwise the read DMA engine will be in a mode that |
14123 | * breaks all requests to 256 bytes. | 14123 | * breaks all requests to 256 bytes. |
14124 | */ | 14124 | */ |
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index ef472385bce4..04321e5a356e 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h | |||
@@ -2608,7 +2608,11 @@ struct tg3_rx_buffer_desc { | |||
2608 | #define RXD_ERR_TOO_SMALL 0x00400000 | 2608 | #define RXD_ERR_TOO_SMALL 0x00400000 |
2609 | #define RXD_ERR_NO_RESOURCES 0x00800000 | 2609 | #define RXD_ERR_NO_RESOURCES 0x00800000 |
2610 | #define RXD_ERR_HUGE_FRAME 0x01000000 | 2610 | #define RXD_ERR_HUGE_FRAME 0x01000000 |
2611 | #define RXD_ERR_MASK 0xffff0000 | 2611 | |
2612 | #define RXD_ERR_MASK (RXD_ERR_BAD_CRC | RXD_ERR_COLLISION | \ | ||
2613 | RXD_ERR_LINK_LOST | RXD_ERR_PHY_DECODE | \ | ||
2614 | RXD_ERR_MAC_ABRT | RXD_ERR_TOO_SMALL | \ | ||
2615 | RXD_ERR_NO_RESOURCES | RXD_ERR_HUGE_FRAME) | ||
2612 | 2616 | ||
2613 | u32 reserved; | 2617 | u32 reserved; |
2614 | u32 opaque; | 2618 | u32 opaque; |
diff --git a/drivers/net/ethernet/brocade/bna/bfa_ioc.c b/drivers/net/ethernet/brocade/bna/bfa_ioc.c index 1803c3959044..354ae9792bad 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_ioc.c +++ b/drivers/net/ethernet/brocade/bna/bfa_ioc.c | |||
@@ -1704,7 +1704,7 @@ bfa_flash_sem_get(void __iomem *bar) | |||
1704 | while (!bfa_raw_sem_get(bar)) { | 1704 | while (!bfa_raw_sem_get(bar)) { |
1705 | if (--n <= 0) | 1705 | if (--n <= 0) |
1706 | return BFA_STATUS_BADFLASH; | 1706 | return BFA_STATUS_BADFLASH; |
1707 | udelay(10000); | 1707 | mdelay(10); |
1708 | } | 1708 | } |
1709 | return BFA_STATUS_OK; | 1709 | return BFA_STATUS_OK; |
1710 | } | 1710 | } |
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index cf64f3d0b60d..4ad1187e82fb 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
@@ -707,7 +707,8 @@ bnad_cq_process(struct bnad *bnad, struct bna_ccb *ccb, int budget) | |||
707 | else | 707 | else |
708 | skb_checksum_none_assert(skb); | 708 | skb_checksum_none_assert(skb); |
709 | 709 | ||
710 | if (flags & BNA_CQ_EF_VLAN) | 710 | if ((flags & BNA_CQ_EF_VLAN) && |
711 | (bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)) | ||
711 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(cmpl->vlan_tag)); | 712 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(cmpl->vlan_tag)); |
712 | 713 | ||
713 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) | 714 | if (BNAD_RXBUF_IS_SK_BUFF(unmap_q->type)) |
@@ -2094,7 +2095,9 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config) | |||
2094 | rx_config->q1_buf_size = BFI_SMALL_RXBUF_SIZE; | 2095 | rx_config->q1_buf_size = BFI_SMALL_RXBUF_SIZE; |
2095 | } | 2096 | } |
2096 | 2097 | ||
2097 | rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; | 2098 | rx_config->vlan_strip_status = |
2099 | (bnad->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) ? | ||
2100 | BNA_STATUS_T_ENABLED : BNA_STATUS_T_DISABLED; | ||
2098 | } | 2101 | } |
2099 | 2102 | ||
2100 | static void | 2103 | static void |
@@ -3245,11 +3248,6 @@ bnad_set_rx_mode(struct net_device *netdev) | |||
3245 | BNA_RXMODE_ALLMULTI; | 3248 | BNA_RXMODE_ALLMULTI; |
3246 | bna_rx_mode_set(bnad->rx_info[0].rx, new_mode, mode_mask, NULL); | 3249 | bna_rx_mode_set(bnad->rx_info[0].rx, new_mode, mode_mask, NULL); |
3247 | 3250 | ||
3248 | if (bnad->cfg_flags & BNAD_CF_PROMISC) | ||
3249 | bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); | ||
3250 | else | ||
3251 | bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); | ||
3252 | |||
3253 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | 3251 | spin_unlock_irqrestore(&bnad->bna_lock, flags); |
3254 | } | 3252 | } |
3255 | 3253 | ||
@@ -3374,6 +3372,27 @@ bnad_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid) | |||
3374 | return 0; | 3372 | return 0; |
3375 | } | 3373 | } |
3376 | 3374 | ||
3375 | static int bnad_set_features(struct net_device *dev, netdev_features_t features) | ||
3376 | { | ||
3377 | struct bnad *bnad = netdev_priv(dev); | ||
3378 | netdev_features_t changed = features ^ dev->features; | ||
3379 | |||
3380 | if ((changed & NETIF_F_HW_VLAN_CTAG_RX) && netif_running(dev)) { | ||
3381 | unsigned long flags; | ||
3382 | |||
3383 | spin_lock_irqsave(&bnad->bna_lock, flags); | ||
3384 | |||
3385 | if (features & NETIF_F_HW_VLAN_CTAG_RX) | ||
3386 | bna_rx_vlan_strip_enable(bnad->rx_info[0].rx); | ||
3387 | else | ||
3388 | bna_rx_vlan_strip_disable(bnad->rx_info[0].rx); | ||
3389 | |||
3390 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
3391 | } | ||
3392 | |||
3393 | return 0; | ||
3394 | } | ||
3395 | |||
3377 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3396 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3378 | static void | 3397 | static void |
3379 | bnad_netpoll(struct net_device *netdev) | 3398 | bnad_netpoll(struct net_device *netdev) |
@@ -3421,6 +3440,7 @@ static const struct net_device_ops bnad_netdev_ops = { | |||
3421 | .ndo_change_mtu = bnad_change_mtu, | 3440 | .ndo_change_mtu = bnad_change_mtu, |
3422 | .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, | 3441 | .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, |
3423 | .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, | 3442 | .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, |
3443 | .ndo_set_features = bnad_set_features, | ||
3424 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3444 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3425 | .ndo_poll_controller = bnad_netpoll | 3445 | .ndo_poll_controller = bnad_netpoll |
3426 | #endif | 3446 | #endif |
@@ -3433,14 +3453,14 @@ bnad_netdev_init(struct bnad *bnad, bool using_dac) | |||
3433 | 3453 | ||
3434 | netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | | 3454 | netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | |
3435 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 3455 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
3436 | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX; | 3456 | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_CTAG_TX | |
3457 | NETIF_F_HW_VLAN_CTAG_RX; | ||
3437 | 3458 | ||
3438 | netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | | 3459 | netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA | |
3439 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 3460 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
3440 | NETIF_F_TSO | NETIF_F_TSO6; | 3461 | NETIF_F_TSO | NETIF_F_TSO6; |
3441 | 3462 | ||
3442 | netdev->features |= netdev->hw_features | | 3463 | netdev->features |= netdev->hw_features | NETIF_F_HW_VLAN_CTAG_FILTER; |
3443 | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; | ||
3444 | 3464 | ||
3445 | if (using_dac) | 3465 | if (using_dac) |
3446 | netdev->features |= NETIF_F_HIGHDMA; | 3466 | netdev->features |= NETIF_F_HIGHDMA; |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 3190d38e16fb..d0c38e01e99f 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -632,11 +632,16 @@ static void gem_rx_refill(struct macb *bp) | |||
632 | "Unable to allocate sk_buff\n"); | 632 | "Unable to allocate sk_buff\n"); |
633 | break; | 633 | break; |
634 | } | 634 | } |
635 | bp->rx_skbuff[entry] = skb; | ||
636 | 635 | ||
637 | /* now fill corresponding descriptor entry */ | 636 | /* now fill corresponding descriptor entry */ |
638 | paddr = dma_map_single(&bp->pdev->dev, skb->data, | 637 | paddr = dma_map_single(&bp->pdev->dev, skb->data, |
639 | bp->rx_buffer_size, DMA_FROM_DEVICE); | 638 | bp->rx_buffer_size, DMA_FROM_DEVICE); |
639 | if (dma_mapping_error(&bp->pdev->dev, paddr)) { | ||
640 | dev_kfree_skb(skb); | ||
641 | break; | ||
642 | } | ||
643 | |||
644 | bp->rx_skbuff[entry] = skb; | ||
640 | 645 | ||
641 | if (entry == RX_RING_SIZE - 1) | 646 | if (entry == RX_RING_SIZE - 1) |
642 | paddr |= MACB_BIT(RX_WRAP); | 647 | paddr |= MACB_BIT(RX_WRAP); |
@@ -725,7 +730,7 @@ static int gem_rx(struct macb *bp, int budget) | |||
725 | skb_put(skb, len); | 730 | skb_put(skb, len); |
726 | addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr)); | 731 | addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, addr)); |
727 | dma_unmap_single(&bp->pdev->dev, addr, | 732 | dma_unmap_single(&bp->pdev->dev, addr, |
728 | len, DMA_FROM_DEVICE); | 733 | bp->rx_buffer_size, DMA_FROM_DEVICE); |
729 | 734 | ||
730 | skb->protocol = eth_type_trans(skb, bp->dev); | 735 | skb->protocol = eth_type_trans(skb, bp->dev); |
731 | skb_checksum_none_assert(skb); | 736 | skb_checksum_none_assert(skb); |
@@ -1036,11 +1041,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1036 | } | 1041 | } |
1037 | 1042 | ||
1038 | entry = macb_tx_ring_wrap(bp->tx_head); | 1043 | entry = macb_tx_ring_wrap(bp->tx_head); |
1039 | bp->tx_head++; | ||
1040 | netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry); | 1044 | netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry); |
1041 | mapping = dma_map_single(&bp->pdev->dev, skb->data, | 1045 | mapping = dma_map_single(&bp->pdev->dev, skb->data, |
1042 | len, DMA_TO_DEVICE); | 1046 | len, DMA_TO_DEVICE); |
1047 | if (dma_mapping_error(&bp->pdev->dev, mapping)) { | ||
1048 | kfree_skb(skb); | ||
1049 | goto unlock; | ||
1050 | } | ||
1043 | 1051 | ||
1052 | bp->tx_head++; | ||
1044 | tx_skb = &bp->tx_skb[entry]; | 1053 | tx_skb = &bp->tx_skb[entry]; |
1045 | tx_skb->skb = skb; | 1054 | tx_skb->skb = skb; |
1046 | tx_skb->mapping = mapping; | 1055 | tx_skb->mapping = mapping; |
@@ -1066,6 +1075,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1066 | if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) | 1075 | if (CIRC_SPACE(bp->tx_head, bp->tx_tail, TX_RING_SIZE) < 1) |
1067 | netif_stop_queue(dev); | 1076 | netif_stop_queue(dev); |
1068 | 1077 | ||
1078 | unlock: | ||
1069 | spin_unlock_irqrestore(&bp->lock, flags); | 1079 | spin_unlock_irqrestore(&bp->lock, flags); |
1070 | 1080 | ||
1071 | return NETDEV_TX_OK; | 1081 | return NETDEV_TX_OK; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 43ab35fea48d..34e2488767d9 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -6179,6 +6179,7 @@ static struct pci_driver cxgb4_driver = { | |||
6179 | .id_table = cxgb4_pci_tbl, | 6179 | .id_table = cxgb4_pci_tbl, |
6180 | .probe = init_one, | 6180 | .probe = init_one, |
6181 | .remove = remove_one, | 6181 | .remove = remove_one, |
6182 | .shutdown = remove_one, | ||
6182 | .err_handler = &cxgb4_eeh, | 6183 | .err_handler = &cxgb4_eeh, |
6183 | }; | 6184 | }; |
6184 | 6185 | ||
diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index add05f14b38b..1642de78aac8 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c | |||
@@ -1939,6 +1939,7 @@ static void tulip_remove_one(struct pci_dev *pdev) | |||
1939 | pci_iounmap(pdev, tp->base_addr); | 1939 | pci_iounmap(pdev, tp->base_addr); |
1940 | free_netdev (dev); | 1940 | free_netdev (dev); |
1941 | pci_release_regions (pdev); | 1941 | pci_release_regions (pdev); |
1942 | pci_disable_device(pdev); | ||
1942 | 1943 | ||
1943 | /* pci_power_off (pdev, -1); */ | 1944 | /* pci_power_off (pdev, -1); */ |
1944 | } | 1945 | } |
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 8d09615da585..05529e273050 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -350,11 +350,13 @@ struct be_drv_stats { | |||
350 | u32 roce_drops_crc; | 350 | u32 roce_drops_crc; |
351 | }; | 351 | }; |
352 | 352 | ||
353 | /* A vlan-id of 0xFFFF must be used to clear transparent vlan-tagging */ | ||
354 | #define BE_RESET_VLAN_TAG_ID 0xFFFF | ||
355 | |||
353 | struct be_vf_cfg { | 356 | struct be_vf_cfg { |
354 | unsigned char mac_addr[ETH_ALEN]; | 357 | unsigned char mac_addr[ETH_ALEN]; |
355 | int if_handle; | 358 | int if_handle; |
356 | int pmac_id; | 359 | int pmac_id; |
357 | u16 def_vid; | ||
358 | u16 vlan_tag; | 360 | u16 vlan_tag; |
359 | u32 tx_rate; | 361 | u32 tx_rate; |
360 | }; | 362 | }; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 04ac9c6a0d39..36c80612e21a 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -913,24 +913,14 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter, | |||
913 | return BE3_chip(adapter) && be_ipv6_exthdr_check(skb); | 913 | return BE3_chip(adapter) && be_ipv6_exthdr_check(skb); |
914 | } | 914 | } |
915 | 915 | ||
916 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | 916 | static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, |
917 | struct sk_buff *skb, | 917 | struct sk_buff *skb, |
918 | bool *skip_hw_vlan) | 918 | bool *skip_hw_vlan) |
919 | { | 919 | { |
920 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 920 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
921 | unsigned int eth_hdr_len; | 921 | unsigned int eth_hdr_len; |
922 | struct iphdr *ip; | 922 | struct iphdr *ip; |
923 | 923 | ||
924 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less | ||
925 | * may cause a transmit stall on that port. So the work-around is to | ||
926 | * pad short packets (<= 32 bytes) to a 36-byte length. | ||
927 | */ | ||
928 | if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { | ||
929 | if (skb_padto(skb, 36)) | ||
930 | goto tx_drop; | ||
931 | skb->len = 36; | ||
932 | } | ||
933 | |||
934 | /* For padded packets, BE HW modifies tot_len field in IP header | 924 | /* For padded packets, BE HW modifies tot_len field in IP header |
935 | * incorrecly when VLAN tag is inserted by HW. | 925 | * incorrecly when VLAN tag is inserted by HW. |
936 | * For padded packets, Lancer computes incorrect checksum. | 926 | * For padded packets, Lancer computes incorrect checksum. |
@@ -959,7 +949,7 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | |||
959 | vlan_tx_tag_present(skb)) { | 949 | vlan_tx_tag_present(skb)) { |
960 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 950 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); |
961 | if (unlikely(!skb)) | 951 | if (unlikely(!skb)) |
962 | goto tx_drop; | 952 | goto err; |
963 | } | 953 | } |
964 | 954 | ||
965 | /* HW may lockup when VLAN HW tagging is requested on | 955 | /* HW may lockup when VLAN HW tagging is requested on |
@@ -981,15 +971,39 @@ static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | |||
981 | be_vlan_tag_tx_chk(adapter, skb)) { | 971 | be_vlan_tag_tx_chk(adapter, skb)) { |
982 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); | 972 | skb = be_insert_vlan_in_pkt(adapter, skb, skip_hw_vlan); |
983 | if (unlikely(!skb)) | 973 | if (unlikely(!skb)) |
984 | goto tx_drop; | 974 | goto err; |
985 | } | 975 | } |
986 | 976 | ||
987 | return skb; | 977 | return skb; |
988 | tx_drop: | 978 | tx_drop: |
989 | dev_kfree_skb_any(skb); | 979 | dev_kfree_skb_any(skb); |
980 | err: | ||
990 | return NULL; | 981 | return NULL; |
991 | } | 982 | } |
992 | 983 | ||
984 | static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter, | ||
985 | struct sk_buff *skb, | ||
986 | bool *skip_hw_vlan) | ||
987 | { | ||
988 | /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or | ||
989 | * less may cause a transmit stall on that port. So the work-around is | ||
990 | * to pad short packets (<= 32 bytes) to a 36-byte length. | ||
991 | */ | ||
992 | if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) { | ||
993 | if (skb_padto(skb, 36)) | ||
994 | return NULL; | ||
995 | skb->len = 36; | ||
996 | } | ||
997 | |||
998 | if (BEx_chip(adapter) || lancer_chip(adapter)) { | ||
999 | skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan); | ||
1000 | if (!skb) | ||
1001 | return NULL; | ||
1002 | } | ||
1003 | |||
1004 | return skb; | ||
1005 | } | ||
1006 | |||
993 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) | 1007 | static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) |
994 | { | 1008 | { |
995 | struct be_adapter *adapter = netdev_priv(netdev); | 1009 | struct be_adapter *adapter = netdev_priv(netdev); |
@@ -1157,6 +1171,14 @@ ret: | |||
1157 | return status; | 1171 | return status; |
1158 | } | 1172 | } |
1159 | 1173 | ||
1174 | static void be_clear_promisc(struct be_adapter *adapter) | ||
1175 | { | ||
1176 | adapter->promiscuous = false; | ||
1177 | adapter->flags &= ~BE_FLAGS_VLAN_PROMISC; | ||
1178 | |||
1179 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); | ||
1180 | } | ||
1181 | |||
1160 | static void be_set_rx_mode(struct net_device *netdev) | 1182 | static void be_set_rx_mode(struct net_device *netdev) |
1161 | { | 1183 | { |
1162 | struct be_adapter *adapter = netdev_priv(netdev); | 1184 | struct be_adapter *adapter = netdev_priv(netdev); |
@@ -1170,9 +1192,7 @@ static void be_set_rx_mode(struct net_device *netdev) | |||
1170 | 1192 | ||
1171 | /* BE was previously in promiscuous mode; disable it */ | 1193 | /* BE was previously in promiscuous mode; disable it */ |
1172 | if (adapter->promiscuous) { | 1194 | if (adapter->promiscuous) { |
1173 | adapter->promiscuous = false; | 1195 | be_clear_promisc(adapter); |
1174 | be_cmd_rx_filter(adapter, IFF_PROMISC, OFF); | ||
1175 | |||
1176 | if (adapter->vlans_added) | 1196 | if (adapter->vlans_added) |
1177 | be_vid_config(adapter); | 1197 | be_vid_config(adapter); |
1178 | } | 1198 | } |
@@ -1287,24 +1307,20 @@ static int be_set_vf_vlan(struct net_device *netdev, | |||
1287 | 1307 | ||
1288 | if (vlan || qos) { | 1308 | if (vlan || qos) { |
1289 | vlan |= qos << VLAN_PRIO_SHIFT; | 1309 | vlan |= qos << VLAN_PRIO_SHIFT; |
1290 | if (vf_cfg->vlan_tag != vlan) { | 1310 | if (vf_cfg->vlan_tag != vlan) |
1291 | /* If this is new value, program it. Else skip. */ | ||
1292 | vf_cfg->vlan_tag = vlan; | ||
1293 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, | 1311 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, |
1294 | vf_cfg->if_handle, 0); | 1312 | vf_cfg->if_handle, 0); |
1295 | } | ||
1296 | } else { | 1313 | } else { |
1297 | /* Reset Transparent Vlan Tagging. */ | 1314 | /* Reset Transparent Vlan Tagging. */ |
1298 | vf_cfg->vlan_tag = 0; | 1315 | status = be_cmd_set_hsw_config(adapter, BE_RESET_VLAN_TAG_ID, |
1299 | vlan = vf_cfg->def_vid; | 1316 | vf + 1, vf_cfg->if_handle, 0); |
1300 | status = be_cmd_set_hsw_config(adapter, vlan, vf + 1, | ||
1301 | vf_cfg->if_handle, 0); | ||
1302 | } | 1317 | } |
1303 | 1318 | ||
1304 | 1319 | if (!status) | |
1305 | if (status) | 1320 | vf_cfg->vlan_tag = vlan; |
1321 | else | ||
1306 | dev_info(&adapter->pdev->dev, | 1322 | dev_info(&adapter->pdev->dev, |
1307 | "VLAN %d config on VF %d failed\n", vlan, vf); | 1323 | "VLAN %d config on VF %d failed\n", vlan, vf); |
1308 | return status; | 1324 | return status; |
1309 | } | 1325 | } |
1310 | 1326 | ||
@@ -3013,11 +3029,11 @@ static int be_vf_setup_init(struct be_adapter *adapter) | |||
3013 | 3029 | ||
3014 | static int be_vf_setup(struct be_adapter *adapter) | 3030 | static int be_vf_setup(struct be_adapter *adapter) |
3015 | { | 3031 | { |
3032 | struct device *dev = &adapter->pdev->dev; | ||
3016 | struct be_vf_cfg *vf_cfg; | 3033 | struct be_vf_cfg *vf_cfg; |
3017 | u16 def_vlan, lnk_speed; | ||
3018 | int status, old_vfs, vf; | 3034 | int status, old_vfs, vf; |
3019 | struct device *dev = &adapter->pdev->dev; | ||
3020 | u32 privileges; | 3035 | u32 privileges; |
3036 | u16 lnk_speed; | ||
3021 | 3037 | ||
3022 | old_vfs = pci_num_vf(adapter->pdev); | 3038 | old_vfs = pci_num_vf(adapter->pdev); |
3023 | if (old_vfs) { | 3039 | if (old_vfs) { |
@@ -3084,12 +3100,6 @@ static int be_vf_setup(struct be_adapter *adapter) | |||
3084 | if (!status) | 3100 | if (!status) |
3085 | vf_cfg->tx_rate = lnk_speed; | 3101 | vf_cfg->tx_rate = lnk_speed; |
3086 | 3102 | ||
3087 | status = be_cmd_get_hsw_config(adapter, &def_vlan, | ||
3088 | vf + 1, vf_cfg->if_handle, NULL); | ||
3089 | if (status) | ||
3090 | goto err; | ||
3091 | vf_cfg->def_vid = def_vlan; | ||
3092 | |||
3093 | if (!old_vfs) | 3103 | if (!old_vfs) |
3094 | be_cmd_enable_vf(adapter, vf + 1); | 3104 | be_cmd_enable_vf(adapter, vf + 1); |
3095 | } | 3105 | } |
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 4de8cfd149cf..55e0fa03dc90 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
15 | #include <linux/etherdevice.h> | 15 | #include <linux/etherdevice.h> |
16 | #include <linux/clk.h> | ||
16 | #include <linux/crc32.h> | 17 | #include <linux/crc32.h> |
17 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -51,6 +52,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
51 | #define ETH_HASH0 0x48 | 52 | #define ETH_HASH0 0x48 |
52 | #define ETH_HASH1 0x4c | 53 | #define ETH_HASH1 0x4c |
53 | #define ETH_TXCTRL 0x50 | 54 | #define ETH_TXCTRL 0x50 |
55 | #define ETH_END 0x54 | ||
54 | 56 | ||
55 | /* mode register */ | 57 | /* mode register */ |
56 | #define MODER_RXEN (1 << 0) /* receive enable */ | 58 | #define MODER_RXEN (1 << 0) /* receive enable */ |
@@ -179,6 +181,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size"); | |||
179 | * @membase: pointer to buffer memory region | 181 | * @membase: pointer to buffer memory region |
180 | * @dma_alloc: dma allocated buffer size | 182 | * @dma_alloc: dma allocated buffer size |
181 | * @io_region_size: I/O memory region size | 183 | * @io_region_size: I/O memory region size |
184 | * @num_bd: number of buffer descriptors | ||
182 | * @num_tx: number of send buffers | 185 | * @num_tx: number of send buffers |
183 | * @cur_tx: last send buffer written | 186 | * @cur_tx: last send buffer written |
184 | * @dty_tx: last buffer actually sent | 187 | * @dty_tx: last buffer actually sent |
@@ -199,6 +202,7 @@ struct ethoc { | |||
199 | int dma_alloc; | 202 | int dma_alloc; |
200 | resource_size_t io_region_size; | 203 | resource_size_t io_region_size; |
201 | 204 | ||
205 | unsigned int num_bd; | ||
202 | unsigned int num_tx; | 206 | unsigned int num_tx; |
203 | unsigned int cur_tx; | 207 | unsigned int cur_tx; |
204 | unsigned int dty_tx; | 208 | unsigned int dty_tx; |
@@ -216,6 +220,7 @@ struct ethoc { | |||
216 | 220 | ||
217 | struct phy_device *phy; | 221 | struct phy_device *phy; |
218 | struct mii_bus *mdio; | 222 | struct mii_bus *mdio; |
223 | struct clk *clk; | ||
219 | s8 phy_id; | 224 | s8 phy_id; |
220 | }; | 225 | }; |
221 | 226 | ||
@@ -688,6 +693,11 @@ static int ethoc_mdio_probe(struct net_device *dev) | |||
688 | } | 693 | } |
689 | 694 | ||
690 | priv->phy = phy; | 695 | priv->phy = phy; |
696 | phy->advertising &= ~(ADVERTISED_1000baseT_Full | | ||
697 | ADVERTISED_1000baseT_Half); | ||
698 | phy->supported &= ~(SUPPORTED_1000baseT_Full | | ||
699 | SUPPORTED_1000baseT_Half); | ||
700 | |||
691 | return 0; | 701 | return 0; |
692 | } | 702 | } |
693 | 703 | ||
@@ -890,6 +900,102 @@ out: | |||
890 | return NETDEV_TX_OK; | 900 | return NETDEV_TX_OK; |
891 | } | 901 | } |
892 | 902 | ||
903 | static int ethoc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
904 | { | ||
905 | struct ethoc *priv = netdev_priv(dev); | ||
906 | struct phy_device *phydev = priv->phy; | ||
907 | |||
908 | if (!phydev) | ||
909 | return -EOPNOTSUPP; | ||
910 | |||
911 | return phy_ethtool_gset(phydev, cmd); | ||
912 | } | ||
913 | |||
914 | static int ethoc_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
915 | { | ||
916 | struct ethoc *priv = netdev_priv(dev); | ||
917 | struct phy_device *phydev = priv->phy; | ||
918 | |||
919 | if (!phydev) | ||
920 | return -EOPNOTSUPP; | ||
921 | |||
922 | return phy_ethtool_sset(phydev, cmd); | ||
923 | } | ||
924 | |||
925 | static int ethoc_get_regs_len(struct net_device *netdev) | ||
926 | { | ||
927 | return ETH_END; | ||
928 | } | ||
929 | |||
930 | static void ethoc_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
931 | void *p) | ||
932 | { | ||
933 | struct ethoc *priv = netdev_priv(dev); | ||
934 | u32 *regs_buff = p; | ||
935 | unsigned i; | ||
936 | |||
937 | regs->version = 0; | ||
938 | for (i = 0; i < ETH_END / sizeof(u32); ++i) | ||
939 | regs_buff[i] = ethoc_read(priv, i * sizeof(u32)); | ||
940 | } | ||
941 | |||
942 | static void ethoc_get_ringparam(struct net_device *dev, | ||
943 | struct ethtool_ringparam *ring) | ||
944 | { | ||
945 | struct ethoc *priv = netdev_priv(dev); | ||
946 | |||
947 | ring->rx_max_pending = priv->num_bd - 1; | ||
948 | ring->rx_mini_max_pending = 0; | ||
949 | ring->rx_jumbo_max_pending = 0; | ||
950 | ring->tx_max_pending = priv->num_bd - 1; | ||
951 | |||
952 | ring->rx_pending = priv->num_rx; | ||
953 | ring->rx_mini_pending = 0; | ||
954 | ring->rx_jumbo_pending = 0; | ||
955 | ring->tx_pending = priv->num_tx; | ||
956 | } | ||
957 | |||
958 | static int ethoc_set_ringparam(struct net_device *dev, | ||
959 | struct ethtool_ringparam *ring) | ||
960 | { | ||
961 | struct ethoc *priv = netdev_priv(dev); | ||
962 | |||
963 | if (ring->tx_pending < 1 || ring->rx_pending < 1 || | ||
964 | ring->tx_pending + ring->rx_pending > priv->num_bd) | ||
965 | return -EINVAL; | ||
966 | if (ring->rx_mini_pending || ring->rx_jumbo_pending) | ||
967 | return -EINVAL; | ||
968 | |||
969 | if (netif_running(dev)) { | ||
970 | netif_tx_disable(dev); | ||
971 | ethoc_disable_rx_and_tx(priv); | ||
972 | ethoc_disable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
973 | synchronize_irq(dev->irq); | ||
974 | } | ||
975 | |||
976 | priv->num_tx = rounddown_pow_of_two(ring->tx_pending); | ||
977 | priv->num_rx = ring->rx_pending; | ||
978 | ethoc_init_ring(priv, dev->mem_start); | ||
979 | |||
980 | if (netif_running(dev)) { | ||
981 | ethoc_enable_irq(priv, INT_MASK_TX | INT_MASK_RX); | ||
982 | ethoc_enable_rx_and_tx(priv); | ||
983 | netif_wake_queue(dev); | ||
984 | } | ||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | const struct ethtool_ops ethoc_ethtool_ops = { | ||
989 | .get_settings = ethoc_get_settings, | ||
990 | .set_settings = ethoc_set_settings, | ||
991 | .get_regs_len = ethoc_get_regs_len, | ||
992 | .get_regs = ethoc_get_regs, | ||
993 | .get_link = ethtool_op_get_link, | ||
994 | .get_ringparam = ethoc_get_ringparam, | ||
995 | .set_ringparam = ethoc_set_ringparam, | ||
996 | .get_ts_info = ethtool_op_get_ts_info, | ||
997 | }; | ||
998 | |||
893 | static const struct net_device_ops ethoc_netdev_ops = { | 999 | static const struct net_device_ops ethoc_netdev_ops = { |
894 | .ndo_open = ethoc_open, | 1000 | .ndo_open = ethoc_open, |
895 | .ndo_stop = ethoc_stop, | 1001 | .ndo_stop = ethoc_stop, |
@@ -917,6 +1023,8 @@ static int ethoc_probe(struct platform_device *pdev) | |||
917 | int num_bd; | 1023 | int num_bd; |
918 | int ret = 0; | 1024 | int ret = 0; |
919 | bool random_mac = false; | 1025 | bool random_mac = false; |
1026 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
1027 | u32 eth_clkfreq = pdata ? pdata->eth_clkfreq : 0; | ||
920 | 1028 | ||
921 | /* allocate networking device */ | 1029 | /* allocate networking device */ |
922 | netdev = alloc_etherdev(sizeof(struct ethoc)); | 1030 | netdev = alloc_etherdev(sizeof(struct ethoc)); |
@@ -1016,6 +1124,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
1016 | ret = -ENODEV; | 1124 | ret = -ENODEV; |
1017 | goto error; | 1125 | goto error; |
1018 | } | 1126 | } |
1127 | priv->num_bd = num_bd; | ||
1019 | /* num_tx must be a power of two */ | 1128 | /* num_tx must be a power of two */ |
1020 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); | 1129 | priv->num_tx = rounddown_pow_of_two(num_bd >> 1); |
1021 | priv->num_rx = num_bd - priv->num_tx; | 1130 | priv->num_rx = num_bd - priv->num_tx; |
@@ -1030,8 +1139,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
1030 | } | 1139 | } |
1031 | 1140 | ||
1032 | /* Allow the platform setup code to pass in a MAC address. */ | 1141 | /* Allow the platform setup code to pass in a MAC address. */ |
1033 | if (dev_get_platdata(&pdev->dev)) { | 1142 | if (pdata) { |
1034 | struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
1035 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); | 1143 | memcpy(netdev->dev_addr, pdata->hwaddr, IFHWADDRLEN); |
1036 | priv->phy_id = pdata->phy_id; | 1144 | priv->phy_id = pdata->phy_id; |
1037 | } else { | 1145 | } else { |
@@ -1069,6 +1177,27 @@ static int ethoc_probe(struct platform_device *pdev) | |||
1069 | if (random_mac) | 1177 | if (random_mac) |
1070 | netdev->addr_assign_type = NET_ADDR_RANDOM; | 1178 | netdev->addr_assign_type = NET_ADDR_RANDOM; |
1071 | 1179 | ||
1180 | /* Allow the platform setup code to adjust MII management bus clock. */ | ||
1181 | if (!eth_clkfreq) { | ||
1182 | struct clk *clk = devm_clk_get(&pdev->dev, NULL); | ||
1183 | |||
1184 | if (!IS_ERR(clk)) { | ||
1185 | priv->clk = clk; | ||
1186 | clk_prepare_enable(clk); | ||
1187 | eth_clkfreq = clk_get_rate(clk); | ||
1188 | } | ||
1189 | } | ||
1190 | if (eth_clkfreq) { | ||
1191 | u32 clkdiv = MIIMODER_CLKDIV(eth_clkfreq / 2500000 + 1); | ||
1192 | |||
1193 | if (!clkdiv) | ||
1194 | clkdiv = 2; | ||
1195 | dev_dbg(&pdev->dev, "setting MII clkdiv to %u\n", clkdiv); | ||
1196 | ethoc_write(priv, MIIMODER, | ||
1197 | (ethoc_read(priv, MIIMODER) & MIIMODER_NOPRE) | | ||
1198 | clkdiv); | ||
1199 | } | ||
1200 | |||
1072 | /* register MII bus */ | 1201 | /* register MII bus */ |
1073 | priv->mdio = mdiobus_alloc(); | 1202 | priv->mdio = mdiobus_alloc(); |
1074 | if (!priv->mdio) { | 1203 | if (!priv->mdio) { |
@@ -1111,6 +1240,7 @@ static int ethoc_probe(struct platform_device *pdev) | |||
1111 | netdev->netdev_ops = ðoc_netdev_ops; | 1240 | netdev->netdev_ops = ðoc_netdev_ops; |
1112 | netdev->watchdog_timeo = ETHOC_TIMEOUT; | 1241 | netdev->watchdog_timeo = ETHOC_TIMEOUT; |
1113 | netdev->features |= 0; | 1242 | netdev->features |= 0; |
1243 | netdev->ethtool_ops = ðoc_ethtool_ops; | ||
1114 | 1244 | ||
1115 | /* setup NAPI */ | 1245 | /* setup NAPI */ |
1116 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); | 1246 | netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); |
@@ -1133,6 +1263,8 @@ free_mdio: | |||
1133 | kfree(priv->mdio->irq); | 1263 | kfree(priv->mdio->irq); |
1134 | mdiobus_free(priv->mdio); | 1264 | mdiobus_free(priv->mdio); |
1135 | free: | 1265 | free: |
1266 | if (priv->clk) | ||
1267 | clk_disable_unprepare(priv->clk); | ||
1136 | free_netdev(netdev); | 1268 | free_netdev(netdev); |
1137 | out: | 1269 | out: |
1138 | return ret; | 1270 | return ret; |
@@ -1157,6 +1289,8 @@ static int ethoc_remove(struct platform_device *pdev) | |||
1157 | kfree(priv->mdio->irq); | 1289 | kfree(priv->mdio->irq); |
1158 | mdiobus_free(priv->mdio); | 1290 | mdiobus_free(priv->mdio); |
1159 | } | 1291 | } |
1292 | if (priv->clk) | ||
1293 | clk_disable_unprepare(priv->clk); | ||
1160 | unregister_netdev(netdev); | 1294 | unregister_netdev(netdev); |
1161 | free_netdev(netdev); | 1295 | free_netdev(netdev); |
1162 | } | 1296 | } |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index d4782b42401b..03a351300013 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -389,12 +389,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
389 | netdev_err(ndev, "Tx DMA memory map failed\n"); | 389 | netdev_err(ndev, "Tx DMA memory map failed\n"); |
390 | return NETDEV_TX_OK; | 390 | return NETDEV_TX_OK; |
391 | } | 391 | } |
392 | /* Send it on its way. Tell FEC it's ready, interrupt when done, | ||
393 | * it's the last BD of the frame, and to put the CRC on the end. | ||
394 | */ | ||
395 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | ||
396 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | ||
397 | bdp->cbd_sc = status; | ||
398 | 392 | ||
399 | if (fep->bufdesc_ex) { | 393 | if (fep->bufdesc_ex) { |
400 | 394 | ||
@@ -416,6 +410,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
416 | } | 410 | } |
417 | } | 411 | } |
418 | 412 | ||
413 | /* Send it on its way. Tell FEC it's ready, interrupt when done, | ||
414 | * it's the last BD of the frame, and to put the CRC on the end. | ||
415 | */ | ||
416 | status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | ||
417 | | BD_ENET_TX_LAST | BD_ENET_TX_TC); | ||
418 | bdp->cbd_sc = status; | ||
419 | |||
419 | bdp_pre = fec_enet_get_prevdesc(bdp, fep); | 420 | bdp_pre = fec_enet_get_prevdesc(bdp, fep); |
420 | if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && | 421 | if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && |
421 | !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { | 422 | !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { |
@@ -527,13 +528,6 @@ fec_restart(struct net_device *ndev, int duplex) | |||
527 | /* Clear any outstanding interrupt. */ | 528 | /* Clear any outstanding interrupt. */ |
528 | writel(0xffc00000, fep->hwp + FEC_IEVENT); | 529 | writel(0xffc00000, fep->hwp + FEC_IEVENT); |
529 | 530 | ||
530 | /* Setup multicast filter. */ | ||
531 | set_multicast_list(ndev); | ||
532 | #ifndef CONFIG_M5272 | ||
533 | writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); | ||
534 | writel(0, fep->hwp + FEC_HASH_TABLE_LOW); | ||
535 | #endif | ||
536 | |||
537 | /* Set maximum receive buffer size. */ | 531 | /* Set maximum receive buffer size. */ |
538 | writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); | 532 | writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); |
539 | 533 | ||
@@ -654,6 +648,13 @@ fec_restart(struct net_device *ndev, int duplex) | |||
654 | 648 | ||
655 | writel(rcntl, fep->hwp + FEC_R_CNTRL); | 649 | writel(rcntl, fep->hwp + FEC_R_CNTRL); |
656 | 650 | ||
651 | /* Setup multicast filter. */ | ||
652 | set_multicast_list(ndev); | ||
653 | #ifndef CONFIG_M5272 | ||
654 | writel(0, fep->hwp + FEC_HASH_TABLE_HIGH); | ||
655 | writel(0, fep->hwp + FEC_HASH_TABLE_LOW); | ||
656 | #endif | ||
657 | |||
657 | if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { | 658 | if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { |
658 | /* enable ENET endian swap */ | 659 | /* enable ENET endian swap */ |
659 | ecntl |= (1 << 8); | 660 | ecntl |= (1 << 8); |
@@ -1778,8 +1779,6 @@ fec_enet_open(struct net_device *ndev) | |||
1778 | struct fec_enet_private *fep = netdev_priv(ndev); | 1779 | struct fec_enet_private *fep = netdev_priv(ndev); |
1779 | int ret; | 1780 | int ret; |
1780 | 1781 | ||
1781 | napi_enable(&fep->napi); | ||
1782 | |||
1783 | /* I should reset the ring buffers here, but I don't yet know | 1782 | /* I should reset the ring buffers here, but I don't yet know |
1784 | * a simple way to do that. | 1783 | * a simple way to do that. |
1785 | */ | 1784 | */ |
@@ -1794,6 +1793,8 @@ fec_enet_open(struct net_device *ndev) | |||
1794 | fec_enet_free_buffers(ndev); | 1793 | fec_enet_free_buffers(ndev); |
1795 | return ret; | 1794 | return ret; |
1796 | } | 1795 | } |
1796 | |||
1797 | napi_enable(&fep->napi); | ||
1797 | phy_start(fep->phy_dev); | 1798 | phy_start(fep->phy_dev); |
1798 | netif_start_queue(ndev); | 1799 | netif_start_queue(ndev); |
1799 | fep->opened = 1; | 1800 | fep->opened = 1; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 4be971590461..1fc8334fc181 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -522,10 +522,21 @@ retry: | |||
522 | return rc; | 522 | return rc; |
523 | } | 523 | } |
524 | 524 | ||
525 | static u64 ibmveth_encode_mac_addr(u8 *mac) | ||
526 | { | ||
527 | int i; | ||
528 | u64 encoded = 0; | ||
529 | |||
530 | for (i = 0; i < ETH_ALEN; i++) | ||
531 | encoded = (encoded << 8) | mac[i]; | ||
532 | |||
533 | return encoded; | ||
534 | } | ||
535 | |||
525 | static int ibmveth_open(struct net_device *netdev) | 536 | static int ibmveth_open(struct net_device *netdev) |
526 | { | 537 | { |
527 | struct ibmveth_adapter *adapter = netdev_priv(netdev); | 538 | struct ibmveth_adapter *adapter = netdev_priv(netdev); |
528 | u64 mac_address = 0; | 539 | u64 mac_address; |
529 | int rxq_entries = 1; | 540 | int rxq_entries = 1; |
530 | unsigned long lpar_rc; | 541 | unsigned long lpar_rc; |
531 | int rc; | 542 | int rc; |
@@ -579,8 +590,7 @@ static int ibmveth_open(struct net_device *netdev) | |||
579 | adapter->rx_queue.num_slots = rxq_entries; | 590 | adapter->rx_queue.num_slots = rxq_entries; |
580 | adapter->rx_queue.toggle = 1; | 591 | adapter->rx_queue.toggle = 1; |
581 | 592 | ||
582 | memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); | 593 | mac_address = ibmveth_encode_mac_addr(netdev->dev_addr); |
583 | mac_address = mac_address >> 16; | ||
584 | 594 | ||
585 | rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | | 595 | rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | |
586 | adapter->rx_queue.queue_len; | 596 | adapter->rx_queue.queue_len; |
@@ -1183,8 +1193,8 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) | |||
1183 | /* add the addresses to the filter table */ | 1193 | /* add the addresses to the filter table */ |
1184 | netdev_for_each_mc_addr(ha, netdev) { | 1194 | netdev_for_each_mc_addr(ha, netdev) { |
1185 | /* add the multicast address to the filter table */ | 1195 | /* add the multicast address to the filter table */ |
1186 | unsigned long mcast_addr = 0; | 1196 | u64 mcast_addr; |
1187 | memcpy(((char *)&mcast_addr)+2, ha->addr, ETH_ALEN); | 1197 | mcast_addr = ibmveth_encode_mac_addr(ha->addr); |
1188 | lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, | 1198 | lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, |
1189 | IbmVethMcastAddFilter, | 1199 | IbmVethMcastAddFilter, |
1190 | mcast_addr); | 1200 | mcast_addr); |
@@ -1372,9 +1382,6 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
1372 | 1382 | ||
1373 | netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); | 1383 | netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); |
1374 | 1384 | ||
1375 | adapter->mac_addr = 0; | ||
1376 | memcpy(&adapter->mac_addr, mac_addr_p, ETH_ALEN); | ||
1377 | |||
1378 | netdev->irq = dev->irq; | 1385 | netdev->irq = dev->irq; |
1379 | netdev->netdev_ops = &ibmveth_netdev_ops; | 1386 | netdev->netdev_ops = &ibmveth_netdev_ops; |
1380 | netdev->ethtool_ops = &netdev_ethtool_ops; | 1387 | netdev->ethtool_ops = &netdev_ethtool_ops; |
@@ -1383,7 +1390,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
1383 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; | 1390 | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; |
1384 | netdev->features |= netdev->hw_features; | 1391 | netdev->features |= netdev->hw_features; |
1385 | 1392 | ||
1386 | memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); | 1393 | memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN); |
1387 | 1394 | ||
1388 | for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { | 1395 | for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { |
1389 | struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; | 1396 | struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.h b/drivers/net/ethernet/ibm/ibmveth.h index 451ba7949e15..1f37499d4398 100644 --- a/drivers/net/ethernet/ibm/ibmveth.h +++ b/drivers/net/ethernet/ibm/ibmveth.h | |||
@@ -138,7 +138,6 @@ struct ibmveth_adapter { | |||
138 | struct napi_struct napi; | 138 | struct napi_struct napi; |
139 | struct net_device_stats stats; | 139 | struct net_device_stats stats; |
140 | unsigned int mcastFilterSize; | 140 | unsigned int mcastFilterSize; |
141 | unsigned long mac_addr; | ||
142 | void * buffer_list_addr; | 141 | void * buffer_list_addr; |
143 | void * filter_list_addr; | 142 | void * filter_list_addr; |
144 | dma_addr_t buffer_list_dma; | 143 | dma_addr_t buffer_list_dma; |
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index cbaba4442d4b..bf7a01ef9a57 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
@@ -3034,7 +3034,7 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
3034 | *enable_wake = false; | 3034 | *enable_wake = false; |
3035 | } | 3035 | } |
3036 | 3036 | ||
3037 | pci_disable_device(pdev); | 3037 | pci_clear_master(pdev); |
3038 | } | 3038 | } |
3039 | 3039 | ||
3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) | 3040 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 6d4ada72dfd0..18076c4178b4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -6881,7 +6881,7 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size) | |||
6881 | } | 6881 | } |
6882 | 6882 | ||
6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | 6883 | static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, |
6884 | void *accel_priv) | 6884 | void *accel_priv, select_queue_fallback_t fallback) |
6885 | { | 6885 | { |
6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; | 6886 | struct ixgbe_fwd_adapter *fwd_adapter = accel_priv; |
6887 | #ifdef IXGBE_FCOE | 6887 | #ifdef IXGBE_FCOE |
@@ -6907,7 +6907,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | 6907 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) |
6908 | break; | 6908 | break; |
6909 | default: | 6909 | default: |
6910 | return __netdev_pick_tx(dev, skb); | 6910 | return fallback(dev, skb); |
6911 | } | 6911 | } |
6912 | 6912 | ||
6913 | f = &adapter->ring_feature[RING_F_FCOE]; | 6913 | f = &adapter->ring_feature[RING_F_FCOE]; |
@@ -6920,7 +6920,7 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
6920 | 6920 | ||
6921 | return txq + f->offset; | 6921 | return txq + f->offset; |
6922 | #else | 6922 | #else |
6923 | return __netdev_pick_tx(dev, skb); | 6923 | return fallback(dev, skb); |
6924 | #endif | 6924 | #endif |
6925 | } | 6925 | } |
6926 | 6926 | ||
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 8f9266c64c75..fd4b6aecf6ee 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c | |||
@@ -619,7 +619,7 @@ ltq_etop_set_multicast_list(struct net_device *dev) | |||
619 | 619 | ||
620 | static u16 | 620 | static u16 |
621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, | 621 | ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb, |
622 | void *accel_priv) | 622 | void *accel_priv, select_queue_fallback_t fallback) |
623 | { | 623 | { |
624 | /* we are currently only using the first queue */ | 624 | /* we are currently only using the first queue */ |
625 | return 0; | 625 | return 0; |
diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig index 6300fd27f2db..68e6a6613e9a 100644 --- a/drivers/net/ethernet/marvell/Kconfig +++ b/drivers/net/ethernet/marvell/Kconfig | |||
@@ -43,12 +43,12 @@ config MVMDIO | |||
43 | This driver is used by the MV643XX_ETH and MVNETA drivers. | 43 | This driver is used by the MV643XX_ETH and MVNETA drivers. |
44 | 44 | ||
45 | config MVNETA | 45 | config MVNETA |
46 | tristate "Marvell Armada 370/XP network interface support" | 46 | tristate "Marvell Armada 370/38x/XP network interface support" |
47 | depends on MACH_ARMADA_370_XP | 47 | depends on PLAT_ORION |
48 | select MVMDIO | 48 | select MVMDIO |
49 | ---help--- | 49 | ---help--- |
50 | This driver supports the network interface units in the | 50 | This driver supports the network interface units in the |
51 | Marvell ARMADA XP and ARMADA 370 SoC family. | 51 | Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family. |
52 | 52 | ||
53 | Note that this driver is distinct from the mv643xx_eth | 53 | Note that this driver is distinct from the mv643xx_eth |
54 | driver, which should be used for the older Marvell SoCs | 54 | driver, which should be used for the older Marvell SoCs |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index fad45316200a..84a96f70dfb5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -742,6 +742,14 @@ static int mlx4_en_replace_mac(struct mlx4_en_priv *priv, int qpn, | |||
742 | err = mlx4_en_uc_steer_add(priv, new_mac, | 742 | err = mlx4_en_uc_steer_add(priv, new_mac, |
743 | &qpn, | 743 | &qpn, |
744 | &entry->reg_id); | 744 | &entry->reg_id); |
745 | if (err) | ||
746 | return err; | ||
747 | if (priv->tunnel_reg_id) { | ||
748 | mlx4_flow_detach(priv->mdev->dev, priv->tunnel_reg_id); | ||
749 | priv->tunnel_reg_id = 0; | ||
750 | } | ||
751 | err = mlx4_en_tunnel_steer_add(priv, new_mac, qpn, | ||
752 | &priv->tunnel_reg_id); | ||
745 | return err; | 753 | return err; |
746 | } | 754 | } |
747 | } | 755 | } |
@@ -1792,6 +1800,8 @@ void mlx4_en_stop_port(struct net_device *dev, int detach) | |||
1792 | mc_list[5] = priv->port; | 1800 | mc_list[5] = priv->port; |
1793 | mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, | 1801 | mlx4_multicast_detach(mdev->dev, &priv->rss_map.indir_qp, |
1794 | mc_list, MLX4_PROT_ETH, mclist->reg_id); | 1802 | mc_list, MLX4_PROT_ETH, mclist->reg_id); |
1803 | if (mclist->tunnel_reg_id) | ||
1804 | mlx4_flow_detach(mdev->dev, mclist->tunnel_reg_id); | ||
1795 | } | 1805 | } |
1796 | mlx4_en_clear_list(dev); | 1806 | mlx4_en_clear_list(dev); |
1797 | list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { | 1807 | list_for_each_entry_safe(mclist, tmp, &priv->curr_list, list) { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 8e8a7eb43a2c..13457032d15f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -629,7 +629,7 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk | |||
629 | } | 629 | } |
630 | 630 | ||
631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 631 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
632 | void *accel_priv) | 632 | void *accel_priv, select_queue_fallback_t fallback) |
633 | { | 633 | { |
634 | struct mlx4_en_priv *priv = netdev_priv(dev); | 634 | struct mlx4_en_priv *priv = netdev_priv(dev); |
635 | u16 rings_p_up = priv->num_tx_rings_p_up; | 635 | u16 rings_p_up = priv->num_tx_rings_p_up; |
@@ -641,7 +641,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
641 | if (vlan_tx_tag_present(skb)) | 641 | if (vlan_tx_tag_present(skb)) |
642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; | 642 | up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT; |
643 | 643 | ||
644 | return __netdev_pick_tx(dev, skb) % rings_p_up + up * rings_p_up; | 644 | return fallback(dev, skb) % rings_p_up + up * rings_p_up; |
645 | } | 645 | } |
646 | 646 | ||
647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) | 647 | static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 91b69ff4b4a2..7e2995ecea6f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -129,13 +129,14 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) | |||
129 | [0] = "RSS support", | 129 | [0] = "RSS support", |
130 | [1] = "RSS Toeplitz Hash Function support", | 130 | [1] = "RSS Toeplitz Hash Function support", |
131 | [2] = "RSS XOR Hash Function support", | 131 | [2] = "RSS XOR Hash Function support", |
132 | [3] = "Device manage flow steering support", | 132 | [3] = "Device managed flow steering support", |
133 | [4] = "Automatic MAC reassignment support", | 133 | [4] = "Automatic MAC reassignment support", |
134 | [5] = "Time stamping support", | 134 | [5] = "Time stamping support", |
135 | [6] = "VST (control vlan insertion/stripping) support", | 135 | [6] = "VST (control vlan insertion/stripping) support", |
136 | [7] = "FSM (MAC anti-spoofing) support", | 136 | [7] = "FSM (MAC anti-spoofing) support", |
137 | [8] = "Dynamic QP updates support", | 137 | [8] = "Dynamic QP updates support", |
138 | [9] = "TCP/IP offloads/flow-steering for VXLAN support" | 138 | [9] = "Device managed flow steering IPoIB support", |
139 | [10] = "TCP/IP offloads/flow-steering for VXLAN support" | ||
139 | }; | 140 | }; |
140 | int i; | 141 | int i; |
141 | 142 | ||
@@ -859,7 +860,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
859 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); | 860 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_CQ_TS_SUPPORT_OFFSET); |
860 | 861 | ||
861 | /* For guests, disable vxlan tunneling */ | 862 | /* For guests, disable vxlan tunneling */ |
862 | MLX4_GET(field, outbox, QUERY_DEV_CAP_VXLAN); | 863 | MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_VXLAN); |
863 | field &= 0xf7; | 864 | field &= 0xf7; |
864 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); | 865 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_VXLAN); |
865 | 866 | ||
@@ -869,7 +870,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
869 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); | 870 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); |
870 | 871 | ||
871 | /* For guests, disable mw type 2 */ | 872 | /* For guests, disable mw type 2 */ |
872 | MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); | 873 | MLX4_GET(bmme_flags, outbox->buf, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); |
873 | bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; | 874 | bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; |
874 | MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); | 875 | MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); |
875 | 876 | ||
@@ -883,7 +884,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
883 | } | 884 | } |
884 | 885 | ||
885 | /* turn off ipoib managed steering for guests */ | 886 | /* turn off ipoib managed steering for guests */ |
886 | MLX4_GET(field, outbox, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); | 887 | MLX4_GET(field, outbox->buf, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); |
887 | field &= ~0x80; | 888 | field &= ~0x80; |
888 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); | 889 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_FLOW_STEERING_IPOIB_OFFSET); |
889 | 890 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index d711158b0d4b..936c15364739 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -150,6 +150,8 @@ struct mlx4_port_config { | |||
150 | struct pci_dev *pdev; | 150 | struct pci_dev *pdev; |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static atomic_t pf_loading = ATOMIC_INIT(0); | ||
154 | |||
153 | int mlx4_check_port_params(struct mlx4_dev *dev, | 155 | int mlx4_check_port_params(struct mlx4_dev *dev, |
154 | enum mlx4_port_type *port_type) | 156 | enum mlx4_port_type *port_type) |
155 | { | 157 | { |
@@ -749,7 +751,7 @@ static void mlx4_request_modules(struct mlx4_dev *dev) | |||
749 | has_eth_port = true; | 751 | has_eth_port = true; |
750 | } | 752 | } |
751 | 753 | ||
752 | if (has_ib_port) | 754 | if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)) |
753 | request_module_nowait(IB_DRV_NAME); | 755 | request_module_nowait(IB_DRV_NAME); |
754 | if (has_eth_port) | 756 | if (has_eth_port) |
755 | request_module_nowait(EN_DRV_NAME); | 757 | request_module_nowait(EN_DRV_NAME); |
@@ -1407,6 +1409,11 @@ static int mlx4_init_slave(struct mlx4_dev *dev) | |||
1407 | u32 slave_read; | 1409 | u32 slave_read; |
1408 | u32 cmd_channel_ver; | 1410 | u32 cmd_channel_ver; |
1409 | 1411 | ||
1412 | if (atomic_read(&pf_loading)) { | ||
1413 | mlx4_warn(dev, "PF is not ready. Deferring probe\n"); | ||
1414 | return -EPROBE_DEFER; | ||
1415 | } | ||
1416 | |||
1410 | mutex_lock(&priv->cmd.slave_cmd_mutex); | 1417 | mutex_lock(&priv->cmd.slave_cmd_mutex); |
1411 | priv->cmd.max_cmds = 1; | 1418 | priv->cmd.max_cmds = 1; |
1412 | mlx4_warn(dev, "Sending reset\n"); | 1419 | mlx4_warn(dev, "Sending reset\n"); |
@@ -2319,7 +2326,11 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) | |||
2319 | 2326 | ||
2320 | if (num_vfs) { | 2327 | if (num_vfs) { |
2321 | mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs); | 2328 | mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs); |
2329 | |||
2330 | atomic_inc(&pf_loading); | ||
2322 | err = pci_enable_sriov(pdev, num_vfs); | 2331 | err = pci_enable_sriov(pdev, num_vfs); |
2332 | atomic_dec(&pf_loading); | ||
2333 | |||
2323 | if (err) { | 2334 | if (err) { |
2324 | mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", | 2335 | mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", |
2325 | err); | 2336 | err); |
@@ -2684,6 +2695,7 @@ static struct pci_driver mlx4_driver = { | |||
2684 | .name = DRV_NAME, | 2695 | .name = DRV_NAME, |
2685 | .id_table = mlx4_pci_table, | 2696 | .id_table = mlx4_pci_table, |
2686 | .probe = mlx4_init_one, | 2697 | .probe = mlx4_init_one, |
2698 | .shutdown = mlx4_remove_one, | ||
2687 | .remove = mlx4_remove_one, | 2699 | .remove = mlx4_remove_one, |
2688 | .err_handler = &mlx4_err_handler, | 2700 | .err_handler = &mlx4_err_handler, |
2689 | }; | 2701 | }; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 6b65f7795215..7aec6c833973 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -51,8 +51,8 @@ | |||
51 | 51 | ||
52 | #define DRV_NAME "mlx4_core" | 52 | #define DRV_NAME "mlx4_core" |
53 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
54 | #define DRV_VERSION "1.1" | 54 | #define DRV_VERSION "2.2-1" |
55 | #define DRV_RELDATE "Dec, 2011" | 55 | #define DRV_RELDATE "Feb, 2014" |
56 | 56 | ||
57 | #define MLX4_FS_UDP_UC_EN (1 << 1) | 57 | #define MLX4_FS_UDP_UC_EN (1 << 1) |
58 | #define MLX4_FS_TCP_UC_EN (1 << 2) | 58 | #define MLX4_FS_TCP_UC_EN (1 << 2) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 3af04c3f42ea..b57e8c87a34e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -57,8 +57,8 @@ | |||
57 | #include "en_port.h" | 57 | #include "en_port.h" |
58 | 58 | ||
59 | #define DRV_NAME "mlx4_en" | 59 | #define DRV_NAME "mlx4_en" |
60 | #define DRV_VERSION "2.0" | 60 | #define DRV_VERSION "2.2-1" |
61 | #define DRV_RELDATE "Dec 2011" | 61 | #define DRV_RELDATE "Feb 2014" |
62 | 62 | ||
63 | #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) | 63 | #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) |
64 | 64 | ||
@@ -723,7 +723,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | |||
723 | 723 | ||
724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); | 724 | void mlx4_en_tx_irq(struct mlx4_cq *mcq); |
725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, | 725 | u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb, |
726 | void *accel_priv); | 726 | void *accel_priv, select_queue_fallback_t fallback); |
727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); | 727 | netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev); |
728 | 728 | ||
729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, | 729 | int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig index 157fe8df2c3e..8ff57e8e3e91 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig +++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig | |||
@@ -4,5 +4,5 @@ | |||
4 | 4 | ||
5 | config MLX5_CORE | 5 | config MLX5_CORE |
6 | tristate | 6 | tristate |
7 | depends on PCI && X86 | 7 | depends on PCI |
8 | default n | 8 | default n |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index a064f06e0cb8..23b7e2d35a93 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c | |||
@@ -46,8 +46,8 @@ | |||
46 | #include "mlx5_core.h" | 46 | #include "mlx5_core.h" |
47 | 47 | ||
48 | #define DRIVER_NAME "mlx5_core" | 48 | #define DRIVER_NAME "mlx5_core" |
49 | #define DRIVER_VERSION "1.0" | 49 | #define DRIVER_VERSION "2.2-1" |
50 | #define DRIVER_RELDATE "June 2013" | 50 | #define DRIVER_RELDATE "Feb 2014" |
51 | 51 | ||
52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); | 52 | MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>"); |
53 | MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library"); | 53 | MODULE_DESCRIPTION("Mellanox ConnectX-IB HCA core library"); |
diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 727b546a9eb8..e0c92e0e5e1d 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
24 | #include <linux/mii.h> | 24 | #include <linux/mii.h> |
25 | #include <linux/eeprom_93cx6.h> | 25 | #include <linux/eeprom_93cx6.h> |
26 | #include <linux/regulator/consumer.h> | ||
26 | 27 | ||
27 | #include <linux/spi/spi.h> | 28 | #include <linux/spi/spi.h> |
28 | 29 | ||
@@ -83,6 +84,7 @@ union ks8851_tx_hdr { | |||
83 | * @rc_rxqcr: Cached copy of KS_RXQCR. | 84 | * @rc_rxqcr: Cached copy of KS_RXQCR. |
84 | * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom | 85 | * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom |
85 | * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. | 86 | * @eeprom: 93CX6 EEPROM state for accessing on-board EEPROM. |
87 | * @vdd_reg: Optional regulator supplying the chip | ||
86 | * | 88 | * |
87 | * The @lock ensures that the chip is protected when certain operations are | 89 | * The @lock ensures that the chip is protected when certain operations are |
88 | * in progress. When the read or write packet transfer is in progress, most | 90 | * in progress. When the read or write packet transfer is in progress, most |
@@ -130,6 +132,7 @@ struct ks8851_net { | |||
130 | struct spi_transfer spi_xfer2[2]; | 132 | struct spi_transfer spi_xfer2[2]; |
131 | 133 | ||
132 | struct eeprom_93cx6 eeprom; | 134 | struct eeprom_93cx6 eeprom; |
135 | struct regulator *vdd_reg; | ||
133 | }; | 136 | }; |
134 | 137 | ||
135 | static int msg_enable; | 138 | static int msg_enable; |
@@ -1414,6 +1417,21 @@ static int ks8851_probe(struct spi_device *spi) | |||
1414 | ks->spidev = spi; | 1417 | ks->spidev = spi; |
1415 | ks->tx_space = 6144; | 1418 | ks->tx_space = 6144; |
1416 | 1419 | ||
1420 | ks->vdd_reg = regulator_get_optional(&spi->dev, "vdd"); | ||
1421 | if (IS_ERR(ks->vdd_reg)) { | ||
1422 | ret = PTR_ERR(ks->vdd_reg); | ||
1423 | if (ret == -EPROBE_DEFER) | ||
1424 | goto err_reg; | ||
1425 | } else { | ||
1426 | ret = regulator_enable(ks->vdd_reg); | ||
1427 | if (ret) { | ||
1428 | dev_err(&spi->dev, "regulator enable fail: %d\n", | ||
1429 | ret); | ||
1430 | goto err_reg_en; | ||
1431 | } | ||
1432 | } | ||
1433 | |||
1434 | |||
1417 | mutex_init(&ks->lock); | 1435 | mutex_init(&ks->lock); |
1418 | spin_lock_init(&ks->statelock); | 1436 | spin_lock_init(&ks->statelock); |
1419 | 1437 | ||
@@ -1508,8 +1526,14 @@ static int ks8851_probe(struct spi_device *spi) | |||
1508 | err_netdev: | 1526 | err_netdev: |
1509 | free_irq(ndev->irq, ks); | 1527 | free_irq(ndev->irq, ks); |
1510 | 1528 | ||
1511 | err_id: | ||
1512 | err_irq: | 1529 | err_irq: |
1530 | err_id: | ||
1531 | if (!IS_ERR(ks->vdd_reg)) | ||
1532 | regulator_disable(ks->vdd_reg); | ||
1533 | err_reg_en: | ||
1534 | if (!IS_ERR(ks->vdd_reg)) | ||
1535 | regulator_put(ks->vdd_reg); | ||
1536 | err_reg: | ||
1513 | free_netdev(ndev); | 1537 | free_netdev(ndev); |
1514 | return ret; | 1538 | return ret; |
1515 | } | 1539 | } |
@@ -1523,6 +1547,10 @@ static int ks8851_remove(struct spi_device *spi) | |||
1523 | 1547 | ||
1524 | unregister_netdev(priv->netdev); | 1548 | unregister_netdev(priv->netdev); |
1525 | free_irq(spi->irq, priv); | 1549 | free_irq(spi->irq, priv); |
1550 | if (!IS_ERR(priv->vdd_reg)) { | ||
1551 | regulator_disable(priv->vdd_reg); | ||
1552 | regulator_put(priv->vdd_reg); | ||
1553 | } | ||
1526 | free_netdev(priv->netdev); | 1554 | free_netdev(priv->netdev); |
1527 | 1555 | ||
1528 | return 0; | 1556 | return 0; |
diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 1ded50ca1600..e46e8698e630 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c | |||
@@ -726,9 +726,6 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header) | |||
726 | int vpath_idx = 0; | 726 | int vpath_idx = 0; |
727 | enum vxge_hw_status status = VXGE_HW_OK; | 727 | enum vxge_hw_status status = VXGE_HW_OK; |
728 | struct vxge_vpath *vpath = NULL; | 728 | struct vxge_vpath *vpath = NULL; |
729 | struct __vxge_hw_device *hldev; | ||
730 | |||
731 | hldev = pci_get_drvdata(vdev->pdev); | ||
732 | 729 | ||
733 | mac_address = (u8 *)&mac_addr; | 730 | mac_address = (u8 *)&mac_addr; |
734 | memcpy(mac_address, mac_header, ETH_ALEN); | 731 | memcpy(mac_address, mac_header, ETH_ALEN); |
@@ -2443,9 +2440,6 @@ static void vxge_rem_msix_isr(struct vxgedev *vdev) | |||
2443 | 2440 | ||
2444 | static void vxge_rem_isr(struct vxgedev *vdev) | 2441 | static void vxge_rem_isr(struct vxgedev *vdev) |
2445 | { | 2442 | { |
2446 | struct __vxge_hw_device *hldev; | ||
2447 | hldev = pci_get_drvdata(vdev->pdev); | ||
2448 | |||
2449 | #ifdef CONFIG_PCI_MSI | 2443 | #ifdef CONFIG_PCI_MSI |
2450 | if (vdev->config.intr_type == MSI_X) { | 2444 | if (vdev->config.intr_type == MSI_X) { |
2451 | vxge_rem_msix_isr(vdev); | 2445 | vxge_rem_msix_isr(vdev); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 4146664d4d6a..27c4f131863b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -340,6 +340,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) | |||
340 | if (qlcnic_sriov_vf_check(adapter)) | 340 | if (qlcnic_sriov_vf_check(adapter)) |
341 | return -EINVAL; | 341 | return -EINVAL; |
342 | num_msix = 1; | 342 | num_msix = 1; |
343 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; | ||
343 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; | 344 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; |
344 | } | 345 | } |
345 | } | 346 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 77f1bce432d2..7d4f54912bad 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | |||
@@ -807,7 +807,7 @@ qlcnic_dcb_get_pg_tc_cfg_tx(struct net_device *netdev, int tc, u8 *prio, | |||
807 | !type->tc_param_valid) | 807 | !type->tc_param_valid) |
808 | return; | 808 | return; |
809 | 809 | ||
810 | if (tc < 0 || (tc > QLC_DCB_MAX_TC)) | 810 | if (tc < 0 || (tc >= QLC_DCB_MAX_TC)) |
811 | return; | 811 | return; |
812 | 812 | ||
813 | tc_cfg = &type->tc_cfg[tc]; | 813 | tc_cfg = &type->tc_cfg[tc]; |
@@ -843,7 +843,7 @@ static void qlcnic_dcb_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, | |||
843 | !type->tc_param_valid) | 843 | !type->tc_param_valid) |
844 | return; | 844 | return; |
845 | 845 | ||
846 | if (pgid < 0 || pgid > QLC_DCB_MAX_PG) | 846 | if (pgid < 0 || pgid >= QLC_DCB_MAX_PG) |
847 | return; | 847 | return; |
848 | 848 | ||
849 | pgcfg = &type->pg_cfg[pgid]; | 849 | pgcfg = &type->pg_cfg[pgid]; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index ba78c7481fa3..1222865cfb73 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -816,9 +816,10 @@ static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter) | |||
816 | 816 | ||
817 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { | 817 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { |
818 | qlcnic_disable_multi_tx(adapter); | 818 | qlcnic_disable_multi_tx(adapter); |
819 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; | ||
819 | 820 | ||
820 | err = qlcnic_enable_msi_legacy(adapter); | 821 | err = qlcnic_enable_msi_legacy(adapter); |
821 | if (!err) | 822 | if (err) |
822 | return err; | 823 | return err; |
823 | } | 824 | } |
824 | } | 825 | } |
@@ -3863,7 +3864,7 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt, | |||
3863 | strcpy(buf, "Tx"); | 3864 | strcpy(buf, "Tx"); |
3864 | } | 3865 | } |
3865 | 3866 | ||
3866 | if (!qlcnic_use_msi_x && !qlcnic_use_msi) { | 3867 | if (!QLCNIC_IS_MSI_FAMILY(adapter)) { |
3867 | netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); | 3868 | netdev_err(netdev, "No RSS/TSS support in INT-x mode\n"); |
3868 | return -EINVAL; | 3869 | return -EINVAL; |
3869 | } | 3870 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 09acf15c3a56..e5277a632671 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | |||
@@ -13,8 +13,6 @@ | |||
13 | #define QLC_VF_MIN_TX_RATE 100 | 13 | #define QLC_VF_MIN_TX_RATE 100 |
14 | #define QLC_VF_MAX_TX_RATE 9999 | 14 | #define QLC_VF_MAX_TX_RATE 9999 |
15 | #define QLC_MAC_OPCODE_MASK 0x7 | 15 | #define QLC_MAC_OPCODE_MASK 0x7 |
16 | #define QLC_MAC_STAR_ADD 6 | ||
17 | #define QLC_MAC_STAR_DEL 7 | ||
18 | #define QLC_VF_FLOOD_BIT BIT_16 | 16 | #define QLC_VF_FLOOD_BIT BIT_16 |
19 | #define QLC_FLOOD_MODE 0x5 | 17 | #define QLC_FLOOD_MODE 0x5 |
20 | 18 | ||
@@ -1206,13 +1204,6 @@ static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter, | |||
1206 | struct qlcnic_vport *vp = vf->vp; | 1204 | struct qlcnic_vport *vp = vf->vp; |
1207 | u8 op, new_op; | 1205 | u8 op, new_op; |
1208 | 1206 | ||
1209 | if (((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_ADD) || | ||
1210 | ((cmd->req.arg[1] & QLC_MAC_OPCODE_MASK) == QLC_MAC_STAR_DEL)) { | ||
1211 | netdev_err(adapter->netdev, "MAC + any VLAN filter not allowed from VF %d\n", | ||
1212 | vf->pci_func); | ||
1213 | return -EINVAL; | ||
1214 | } | ||
1215 | |||
1216 | if (!(cmd->req.arg[1] & BIT_8)) | 1207 | if (!(cmd->req.arg[1] & BIT_8)) |
1217 | return -EINVAL; | 1208 | return -EINVAL; |
1218 | 1209 | ||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 91a67ae8f17b..3ff7bc3e7a23 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -209,7 +209,7 @@ static const struct { | |||
209 | [RTL_GIGA_MAC_VER_16] = | 209 | [RTL_GIGA_MAC_VER_16] = |
210 | _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), | 210 | _R("RTL8101e", RTL_TD_0, NULL, JUMBO_1K, true), |
211 | [RTL_GIGA_MAC_VER_17] = | 211 | [RTL_GIGA_MAC_VER_17] = |
212 | _R("RTL8168b/8111b", RTL_TD_1, NULL, JUMBO_4K, false), | 212 | _R("RTL8168b/8111b", RTL_TD_0, NULL, JUMBO_4K, false), |
213 | [RTL_GIGA_MAC_VER_18] = | 213 | [RTL_GIGA_MAC_VER_18] = |
214 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), | 214 | _R("RTL8168cp/8111cp", RTL_TD_1, NULL, JUMBO_6K, false), |
215 | [RTL_GIGA_MAC_VER_19] = | 215 | [RTL_GIGA_MAC_VER_19] = |
@@ -7118,6 +7118,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
7118 | } | 7118 | } |
7119 | 7119 | ||
7120 | mutex_init(&tp->wk.mutex); | 7120 | mutex_init(&tp->wk.mutex); |
7121 | u64_stats_init(&tp->rx_stats.syncp); | ||
7122 | u64_stats_init(&tp->tx_stats.syncp); | ||
7121 | 7123 | ||
7122 | /* Get MAC address */ | 7124 | /* Get MAC address */ |
7123 | for (i = 0; i < ETH_ALEN; i++) | 7125 | for (i = 0; i < ETH_ALEN; i++) |
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index eb75fbd11a01..d7a36829649a 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c | |||
@@ -1668,6 +1668,13 @@ void efx_ptp_event(struct efx_nic *efx, efx_qword_t *ev) | |||
1668 | struct efx_ptp_data *ptp = efx->ptp_data; | 1668 | struct efx_ptp_data *ptp = efx->ptp_data; |
1669 | int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); | 1669 | int code = EFX_QWORD_FIELD(*ev, MCDI_EVENT_CODE); |
1670 | 1670 | ||
1671 | if (!ptp) { | ||
1672 | if (net_ratelimit()) | ||
1673 | netif_warn(efx, drv, efx->net_dev, | ||
1674 | "Received PTP event but PTP not set up\n"); | ||
1675 | return; | ||
1676 | } | ||
1677 | |||
1671 | if (!ptp->enabled) | 1678 | if (!ptp->enabled) |
1672 | return; | 1679 | return; |
1673 | 1680 | ||
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index c49d1fb16965..75d11fa4eb0a 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
@@ -429,7 +429,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) | |||
429 | } | 429 | } |
430 | 430 | ||
431 | /* Transfer ownership of the skb to the final buffer */ | 431 | /* Transfer ownership of the skb to the final buffer */ |
432 | #ifdef EFX_USE_PIO | ||
432 | finish_packet: | 433 | finish_packet: |
434 | #endif | ||
433 | buffer->skb = skb; | 435 | buffer->skb = skb; |
434 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; | 436 | buffer->flags = EFX_TX_BUF_SKB | dma_flags; |
435 | 437 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index e2f202e3932f..f2d7c702c77f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig | |||
@@ -37,6 +37,17 @@ config DWMAC_SUNXI | |||
37 | stmmac device driver. This driver is used for A20/A31 | 37 | stmmac device driver. This driver is used for A20/A31 |
38 | GMAC ethernet controller. | 38 | GMAC ethernet controller. |
39 | 39 | ||
40 | config DWMAC_STI | ||
41 | bool "STi GMAC support" | ||
42 | depends on STMMAC_PLATFORM && ARCH_STI | ||
43 | default y | ||
44 | ---help--- | ||
45 | Support for ethernet controller on STi SOCs. | ||
46 | |||
47 | This selects STi SoC glue layer support for the stmmac | ||
48 | device driver. This driver is used on for the STi series | ||
49 | SOCs GMAC ethernet controller. | ||
50 | |||
40 | config STMMAC_PCI | 51 | config STMMAC_PCI |
41 | bool "STMMAC PCI bus support" | 52 | bool "STMMAC PCI bus support" |
42 | depends on STMMAC_ETH && PCI | 53 | depends on STMMAC_ETH && PCI |
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index ecadecea79b2..dcef28775dad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
@@ -2,6 +2,7 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o | |||
2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o | 2 | stmmac-$(CONFIG_STMMAC_PLATFORM) += stmmac_platform.o |
3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o | 3 | stmmac-$(CONFIG_STMMAC_PCI) += stmmac_pci.o |
4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o | 4 | stmmac-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o |
5 | stmmac-$(CONFIG_DWMAC_STI) += dwmac-sti.o | ||
5 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | 6 | stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ |
6 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ | 7 | chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ |
7 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ | 8 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c index 72d282bf33a5..c553f6b5a913 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c | |||
@@ -151,7 +151,7 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p) | |||
151 | sizeof(struct dma_desc))); | 151 | sizeof(struct dma_desc))); |
152 | } | 152 | } |
153 | 153 | ||
154 | const struct stmmac_chain_mode_ops chain_mode_ops = { | 154 | const struct stmmac_mode_ops chain_mode_ops = { |
155 | .init = stmmac_init_dma_chain, | 155 | .init = stmmac_init_dma_chain, |
156 | .is_jumbo_frm = stmmac_is_jumbo_frm, | 156 | .is_jumbo_frm = stmmac_is_jumbo_frm, |
157 | .jumbo_frm = stmmac_jumbo_frm, | 157 | .jumbo_frm = stmmac_jumbo_frm, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 7834a3993946..74610f3aca9e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
@@ -419,20 +419,13 @@ struct mii_regs { | |||
419 | unsigned int data; /* MII Data */ | 419 | unsigned int data; /* MII Data */ |
420 | }; | 420 | }; |
421 | 421 | ||
422 | struct stmmac_ring_mode_ops { | 422 | struct stmmac_mode_ops { |
423 | unsigned int (*is_jumbo_frm) (int len, int ehn_desc); | ||
424 | unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); | ||
425 | void (*refill_desc3) (void *priv, struct dma_desc *p); | ||
426 | void (*init_desc3) (struct dma_desc *p); | ||
427 | void (*clean_desc3) (void *priv, struct dma_desc *p); | ||
428 | int (*set_16kib_bfsize) (int mtu); | ||
429 | }; | ||
430 | |||
431 | struct stmmac_chain_mode_ops { | ||
432 | void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, | 423 | void (*init) (void *des, dma_addr_t phy_addr, unsigned int size, |
433 | unsigned int extend_desc); | 424 | unsigned int extend_desc); |
434 | unsigned int (*is_jumbo_frm) (int len, int ehn_desc); | 425 | unsigned int (*is_jumbo_frm) (int len, int ehn_desc); |
435 | unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); | 426 | unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum); |
427 | int (*set_16kib_bfsize)(int mtu); | ||
428 | void (*init_desc3)(struct dma_desc *p); | ||
436 | void (*refill_desc3) (void *priv, struct dma_desc *p); | 429 | void (*refill_desc3) (void *priv, struct dma_desc *p); |
437 | void (*clean_desc3) (void *priv, struct dma_desc *p); | 430 | void (*clean_desc3) (void *priv, struct dma_desc *p); |
438 | }; | 431 | }; |
@@ -441,8 +434,7 @@ struct mac_device_info { | |||
441 | const struct stmmac_ops *mac; | 434 | const struct stmmac_ops *mac; |
442 | const struct stmmac_desc_ops *desc; | 435 | const struct stmmac_desc_ops *desc; |
443 | const struct stmmac_dma_ops *dma; | 436 | const struct stmmac_dma_ops *dma; |
444 | const struct stmmac_ring_mode_ops *ring; | 437 | const struct stmmac_mode_ops *mode; |
445 | const struct stmmac_chain_mode_ops *chain; | ||
446 | const struct stmmac_hwtimestamp *ptp; | 438 | const struct stmmac_hwtimestamp *ptp; |
447 | struct mii_regs mii; /* MII register Addresses */ | 439 | struct mii_regs mii; /* MII register Addresses */ |
448 | struct mac_link link; | 440 | struct mac_link link; |
@@ -460,7 +452,7 @@ void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, | |||
460 | void stmmac_set_mac(void __iomem *ioaddr, bool enable); | 452 | void stmmac_set_mac(void __iomem *ioaddr, bool enable); |
461 | 453 | ||
462 | void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); | 454 | void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); |
463 | extern const struct stmmac_ring_mode_ops ring_mode_ops; | 455 | extern const struct stmmac_mode_ops ring_mode_ops; |
464 | extern const struct stmmac_chain_mode_ops chain_mode_ops; | 456 | extern const struct stmmac_mode_ops chain_mode_ops; |
465 | 457 | ||
466 | #endif /* __COMMON_H__ */ | 458 | #endif /* __COMMON_H__ */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c new file mode 100644 index 000000000000..552bbc17863c --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | |||
@@ -0,0 +1,330 @@ | |||
1 | /** | ||
2 | * dwmac-sti.c - STMicroelectronics DWMAC Specific Glue layer | ||
3 | * | ||
4 | * Copyright (C) 2003-2014 STMicroelectronics (R&D) Limited | ||
5 | * Author: Srinivas Kandagatla <srinivas.kandagatla@st.com> | ||
6 | * | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/stmmac.h> | ||
18 | #include <linux/phy.h> | ||
19 | #include <linux/mfd/syscon.h> | ||
20 | #include <linux/regmap.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_net.h> | ||
24 | |||
25 | /** | ||
26 | * STi GMAC glue logic. | ||
27 | * -------------------- | ||
28 | * | ||
29 | * _ | ||
30 | * | \ | ||
31 | * --------|0 \ ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
32 | * phyclk | |___________________________________________ | ||
33 | * | | | (phyclk-in) | ||
34 | * --------|1 / | | ||
35 | * int-clk |_ / | | ||
36 | * | _ | ||
37 | * | | \ | ||
38 | * |_______|1 \ ETH_SEL_TX_RETIME_CLK | ||
39 | * | |___________________________ | ||
40 | * | | (tx-retime-clk) | ||
41 | * _______|0 / | ||
42 | * | |_ / | ||
43 | * _ | | ||
44 | * | \ | | ||
45 | * --------|0 \ | | ||
46 | * clk_125 | |__| | ||
47 | * | | ETH_SEL_TXCLK_NOT_CLK125 | ||
48 | * --------|1 / | ||
49 | * txclk |_ / | ||
50 | * | ||
51 | * | ||
52 | * ETH_SEL_INTERNAL_NOTEXT_PHYCLK is valid only for RMII where PHY can | ||
53 | * generate 50MHz clock or MAC can generate it. | ||
54 | * This bit is configured by "st,ext-phyclk" property. | ||
55 | * | ||
56 | * ETH_SEL_TXCLK_NOT_CLK125 is only valid for gigabit modes, where the 125Mhz | ||
57 | * clock either comes from clk-125 pin or txclk pin. This configuration is | ||
58 | * totally driven by the board wiring. This bit is configured by | ||
59 | * "st,tx-retime-src" property. | ||
60 | * | ||
61 | * TXCLK configuration is different for different phy interface modes | ||
62 | * and changes according to link speed in modes like RGMII. | ||
63 | * | ||
64 | * Below table summarizes the clock requirement and clock sources for | ||
65 | * supported phy interface modes with link speeds. | ||
66 | * ________________________________________________ | ||
67 | *| PHY_MODE | 1000 Mbit Link | 100 Mbit Link | | ||
68 | * ------------------------------------------------ | ||
69 | *| MII | n/a | 25Mhz | | ||
70 | *| | | txclk | | ||
71 | * ------------------------------------------------ | ||
72 | *| GMII | 125Mhz | 25Mhz | | ||
73 | *| | clk-125/txclk | txclk | | ||
74 | * ------------------------------------------------ | ||
75 | *| RGMII | 125Mhz | 25Mhz | | ||
76 | *| | clk-125/txclk | clkgen | | ||
77 | * ------------------------------------------------ | ||
78 | *| RMII | n/a | 25Mhz | | ||
79 | *| | |clkgen/phyclk-in | | ||
80 | * ------------------------------------------------ | ||
81 | * | ||
82 | * TX lines are always retimed with a clk, which can vary depending | ||
83 | * on the board configuration. Below is the table of these bits | ||
84 | * in eth configuration register depending on source of retime clk. | ||
85 | * | ||
86 | *--------------------------------------------------------------- | ||
87 | * src | tx_rt_clk | int_not_ext_phyclk | txclk_n_clk125| | ||
88 | *--------------------------------------------------------------- | ||
89 | * txclk | 0 | n/a | 1 | | ||
90 | *--------------------------------------------------------------- | ||
91 | * ck_125| 0 | n/a | 0 | | ||
92 | *--------------------------------------------------------------- | ||
93 | * phyclk| 1 | 0 | n/a | | ||
94 | *--------------------------------------------------------------- | ||
95 | * clkgen| 1 | 1 | n/a | | ||
96 | *--------------------------------------------------------------- | ||
97 | */ | ||
98 | |||
99 | /* Register definition */ | ||
100 | |||
101 | /* 3 bits [8:6] | ||
102 | * [6:6] ETH_SEL_TXCLK_NOT_CLK125 | ||
103 | * [7:7] ETH_SEL_INTERNAL_NOTEXT_PHYCLK | ||
104 | * [8:8] ETH_SEL_TX_RETIME_CLK | ||
105 | * | ||
106 | */ | ||
107 | |||
108 | #define TX_RETIME_SRC_MASK GENMASK(8, 6) | ||
109 | #define ETH_SEL_TX_RETIME_CLK BIT(8) | ||
110 | #define ETH_SEL_INTERNAL_NOTEXT_PHYCLK BIT(7) | ||
111 | #define ETH_SEL_TXCLK_NOT_CLK125 BIT(6) | ||
112 | |||
113 | #define ENMII_MASK GENMASK(5, 5) | ||
114 | #define ENMII BIT(5) | ||
115 | |||
116 | /** | ||
117 | * 3 bits [4:2] | ||
118 | * 000-GMII/MII | ||
119 | * 001-RGMII | ||
120 | * 010-SGMII | ||
121 | * 100-RMII | ||
122 | */ | ||
123 | #define MII_PHY_SEL_MASK GENMASK(4, 2) | ||
124 | #define ETH_PHY_SEL_RMII BIT(4) | ||
125 | #define ETH_PHY_SEL_SGMII BIT(3) | ||
126 | #define ETH_PHY_SEL_RGMII BIT(2) | ||
127 | #define ETH_PHY_SEL_GMII 0x0 | ||
128 | #define ETH_PHY_SEL_MII 0x0 | ||
129 | |||
130 | #define IS_PHY_IF_MODE_RGMII(iface) (iface == PHY_INTERFACE_MODE_RGMII || \ | ||
131 | iface == PHY_INTERFACE_MODE_RGMII_ID || \ | ||
132 | iface == PHY_INTERFACE_MODE_RGMII_RXID || \ | ||
133 | iface == PHY_INTERFACE_MODE_RGMII_TXID) | ||
134 | |||
135 | #define IS_PHY_IF_MODE_GBIT(iface) (IS_PHY_IF_MODE_RGMII(iface) || \ | ||
136 | iface == PHY_INTERFACE_MODE_GMII) | ||
137 | |||
138 | struct sti_dwmac { | ||
139 | int interface; | ||
140 | bool ext_phyclk; | ||
141 | bool is_tx_retime_src_clk_125; | ||
142 | struct clk *clk; | ||
143 | int reg; | ||
144 | struct device *dev; | ||
145 | struct regmap *regmap; | ||
146 | }; | ||
147 | |||
148 | static u32 phy_intf_sels[] = { | ||
149 | [PHY_INTERFACE_MODE_MII] = ETH_PHY_SEL_MII, | ||
150 | [PHY_INTERFACE_MODE_GMII] = ETH_PHY_SEL_GMII, | ||
151 | [PHY_INTERFACE_MODE_RGMII] = ETH_PHY_SEL_RGMII, | ||
152 | [PHY_INTERFACE_MODE_RGMII_ID] = ETH_PHY_SEL_RGMII, | ||
153 | [PHY_INTERFACE_MODE_SGMII] = ETH_PHY_SEL_SGMII, | ||
154 | [PHY_INTERFACE_MODE_RMII] = ETH_PHY_SEL_RMII, | ||
155 | }; | ||
156 | |||
157 | enum { | ||
158 | TX_RETIME_SRC_NA = 0, | ||
159 | TX_RETIME_SRC_TXCLK = 1, | ||
160 | TX_RETIME_SRC_CLK_125, | ||
161 | TX_RETIME_SRC_PHYCLK, | ||
162 | TX_RETIME_SRC_CLKGEN, | ||
163 | }; | ||
164 | |||
165 | static const char *const tx_retime_srcs[] = { | ||
166 | [TX_RETIME_SRC_NA] = "", | ||
167 | [TX_RETIME_SRC_TXCLK] = "txclk", | ||
168 | [TX_RETIME_SRC_CLK_125] = "clk_125", | ||
169 | [TX_RETIME_SRC_PHYCLK] = "phyclk", | ||
170 | [TX_RETIME_SRC_CLKGEN] = "clkgen", | ||
171 | }; | ||
172 | |||
173 | static u32 tx_retime_val[] = { | ||
174 | [TX_RETIME_SRC_TXCLK] = ETH_SEL_TXCLK_NOT_CLK125, | ||
175 | [TX_RETIME_SRC_CLK_125] = 0x0, | ||
176 | [TX_RETIME_SRC_PHYCLK] = ETH_SEL_TX_RETIME_CLK, | ||
177 | [TX_RETIME_SRC_CLKGEN] = ETH_SEL_TX_RETIME_CLK | | ||
178 | ETH_SEL_INTERNAL_NOTEXT_PHYCLK, | ||
179 | }; | ||
180 | |||
181 | static void setup_retime_src(struct sti_dwmac *dwmac, u32 spd) | ||
182 | { | ||
183 | u32 src = 0, freq = 0; | ||
184 | |||
185 | if (spd == SPEED_100) { | ||
186 | if (dwmac->interface == PHY_INTERFACE_MODE_MII || | ||
187 | dwmac->interface == PHY_INTERFACE_MODE_GMII) { | ||
188 | src = TX_RETIME_SRC_TXCLK; | ||
189 | } else if (dwmac->interface == PHY_INTERFACE_MODE_RMII) { | ||
190 | if (dwmac->ext_phyclk) { | ||
191 | src = TX_RETIME_SRC_PHYCLK; | ||
192 | } else { | ||
193 | src = TX_RETIME_SRC_CLKGEN; | ||
194 | freq = 50000000; | ||
195 | } | ||
196 | |||
197 | } else if (IS_PHY_IF_MODE_RGMII(dwmac->interface)) { | ||
198 | src = TX_RETIME_SRC_CLKGEN; | ||
199 | freq = 25000000; | ||
200 | } | ||
201 | |||
202 | if (src == TX_RETIME_SRC_CLKGEN && dwmac->clk) | ||
203 | clk_set_rate(dwmac->clk, freq); | ||
204 | |||
205 | } else if (spd == SPEED_1000) { | ||
206 | if (dwmac->is_tx_retime_src_clk_125) | ||
207 | src = TX_RETIME_SRC_CLK_125; | ||
208 | else | ||
209 | src = TX_RETIME_SRC_TXCLK; | ||
210 | } | ||
211 | |||
212 | regmap_update_bits(dwmac->regmap, dwmac->reg, | ||
213 | TX_RETIME_SRC_MASK, tx_retime_val[src]); | ||
214 | } | ||
215 | |||
216 | static void sti_dwmac_exit(struct platform_device *pdev, void *priv) | ||
217 | { | ||
218 | struct sti_dwmac *dwmac = priv; | ||
219 | |||
220 | if (dwmac->clk) | ||
221 | clk_disable_unprepare(dwmac->clk); | ||
222 | } | ||
223 | |||
224 | static void sti_fix_mac_speed(void *priv, unsigned int spd) | ||
225 | { | ||
226 | struct sti_dwmac *dwmac = priv; | ||
227 | |||
228 | setup_retime_src(dwmac, spd); | ||
229 | |||
230 | return; | ||
231 | } | ||
232 | |||
233 | static int sti_dwmac_parse_data(struct sti_dwmac *dwmac, | ||
234 | struct platform_device *pdev) | ||
235 | { | ||
236 | struct resource *res; | ||
237 | struct device *dev = &pdev->dev; | ||
238 | struct device_node *np = dev->of_node; | ||
239 | struct regmap *regmap; | ||
240 | int err; | ||
241 | |||
242 | if (!np) | ||
243 | return -EINVAL; | ||
244 | |||
245 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sti-ethconf"); | ||
246 | if (!res) | ||
247 | return -ENODATA; | ||
248 | |||
249 | regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); | ||
250 | if (IS_ERR(regmap)) | ||
251 | return PTR_ERR(regmap); | ||
252 | |||
253 | dwmac->dev = dev; | ||
254 | dwmac->interface = of_get_phy_mode(np); | ||
255 | dwmac->regmap = regmap; | ||
256 | dwmac->reg = res->start; | ||
257 | dwmac->ext_phyclk = of_property_read_bool(np, "st,ext-phyclk"); | ||
258 | dwmac->is_tx_retime_src_clk_125 = false; | ||
259 | |||
260 | if (IS_PHY_IF_MODE_GBIT(dwmac->interface)) { | ||
261 | const char *rs; | ||
262 | |||
263 | err = of_property_read_string(np, "st,tx-retime-src", &rs); | ||
264 | if (err < 0) { | ||
265 | dev_err(dev, "st,tx-retime-src not specified\n"); | ||
266 | return err; | ||
267 | } | ||
268 | |||
269 | if (!strcasecmp(rs, "clk_125")) | ||
270 | dwmac->is_tx_retime_src_clk_125 = true; | ||
271 | } | ||
272 | |||
273 | dwmac->clk = devm_clk_get(dev, "sti-ethclk"); | ||
274 | |||
275 | if (IS_ERR(dwmac->clk)) | ||
276 | dwmac->clk = NULL; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int sti_dwmac_init(struct platform_device *pdev, void *priv) | ||
282 | { | ||
283 | struct sti_dwmac *dwmac = priv; | ||
284 | struct regmap *regmap = dwmac->regmap; | ||
285 | int iface = dwmac->interface; | ||
286 | u32 reg = dwmac->reg; | ||
287 | u32 val, spd; | ||
288 | |||
289 | if (dwmac->clk) | ||
290 | clk_prepare_enable(dwmac->clk); | ||
291 | |||
292 | regmap_update_bits(regmap, reg, MII_PHY_SEL_MASK, phy_intf_sels[iface]); | ||
293 | |||
294 | val = (iface == PHY_INTERFACE_MODE_REVMII) ? 0 : ENMII; | ||
295 | regmap_update_bits(regmap, reg, ENMII_MASK, val); | ||
296 | |||
297 | if (IS_PHY_IF_MODE_GBIT(iface)) | ||
298 | spd = SPEED_1000; | ||
299 | else | ||
300 | spd = SPEED_100; | ||
301 | |||
302 | setup_retime_src(dwmac, spd); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void *sti_dwmac_setup(struct platform_device *pdev) | ||
308 | { | ||
309 | struct sti_dwmac *dwmac; | ||
310 | int ret; | ||
311 | |||
312 | dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); | ||
313 | if (!dwmac) | ||
314 | return ERR_PTR(-ENOMEM); | ||
315 | |||
316 | ret = sti_dwmac_parse_data(dwmac, pdev); | ||
317 | if (ret) { | ||
318 | dev_err(&pdev->dev, "Unable to parse OF data\n"); | ||
319 | return ERR_PTR(ret); | ||
320 | } | ||
321 | |||
322 | return dwmac; | ||
323 | } | ||
324 | |||
325 | const struct stmmac_of_data sti_gmac_data = { | ||
326 | .fix_mac_speed = sti_fix_mac_speed, | ||
327 | .setup = sti_dwmac_setup, | ||
328 | .init = sti_dwmac_init, | ||
329 | .exit = sti_dwmac_exit, | ||
330 | }; | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c index a96c7c2f5f3f..650a4be6bce5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c | |||
@@ -100,10 +100,9 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p) | |||
100 | { | 100 | { |
101 | struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; | 101 | struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; |
102 | 102 | ||
103 | if (unlikely(priv->plat->has_gmac)) | 103 | /* Fill DES3 in case of RING mode */ |
104 | /* Fill DES3 in case of RING mode */ | 104 | if (priv->dma_buf_sz >= BUF_SIZE_8KiB) |
105 | if (priv->dma_buf_sz >= BUF_SIZE_8KiB) | 105 | p->des3 = p->des2 + BUF_SIZE_8KiB; |
106 | p->des3 = p->des2 + BUF_SIZE_8KiB; | ||
107 | } | 106 | } |
108 | 107 | ||
109 | /* In ring mode we need to fill the desc3 because it is used as buffer */ | 108 | /* In ring mode we need to fill the desc3 because it is used as buffer */ |
@@ -126,7 +125,7 @@ static int stmmac_set_16kib_bfsize(int mtu) | |||
126 | return ret; | 125 | return ret; |
127 | } | 126 | } |
128 | 127 | ||
129 | const struct stmmac_ring_mode_ops ring_mode_ops = { | 128 | const struct stmmac_mode_ops ring_mode_ops = { |
130 | .is_jumbo_frm = stmmac_is_jumbo_frm, | 129 | .is_jumbo_frm = stmmac_is_jumbo_frm, |
131 | .jumbo_frm = stmmac_jumbo_frm, | 130 | .jumbo_frm = stmmac_jumbo_frm, |
132 | .refill_desc3 = stmmac_refill_desc3, | 131 | .refill_desc3 = stmmac_refill_desc3, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index d9af26ed58ee..f9e60d7918c4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
@@ -133,6 +133,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv); | |||
133 | #ifdef CONFIG_DWMAC_SUNXI | 133 | #ifdef CONFIG_DWMAC_SUNXI |
134 | extern const struct stmmac_of_data sun7i_gmac_data; | 134 | extern const struct stmmac_of_data sun7i_gmac_data; |
135 | #endif | 135 | #endif |
136 | #ifdef CONFIG_DWMAC_STI | ||
137 | extern const struct stmmac_of_data sti_gmac_data; | ||
138 | #endif | ||
136 | extern struct platform_driver stmmac_pltfr_driver; | 139 | extern struct platform_driver stmmac_pltfr_driver; |
137 | static inline int stmmac_register_platform(void) | 140 | static inline int stmmac_register_platform(void) |
138 | { | 141 | { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index a2e7d2c96e36..8543e1cfd55e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -92,8 +92,8 @@ static int tc = TC_DEFAULT; | |||
92 | module_param(tc, int, S_IRUGO | S_IWUSR); | 92 | module_param(tc, int, S_IRUGO | S_IWUSR); |
93 | MODULE_PARM_DESC(tc, "DMA threshold control value"); | 93 | MODULE_PARM_DESC(tc, "DMA threshold control value"); |
94 | 94 | ||
95 | #define DMA_BUFFER_SIZE BUF_SIZE_4KiB | 95 | #define DEFAULT_BUFSIZE 1536 |
96 | static int buf_sz = DMA_BUFFER_SIZE; | 96 | static int buf_sz = DEFAULT_BUFSIZE; |
97 | module_param(buf_sz, int, S_IRUGO | S_IWUSR); | 97 | module_param(buf_sz, int, S_IRUGO | S_IWUSR); |
98 | MODULE_PARM_DESC(buf_sz, "DMA buffer size"); | 98 | MODULE_PARM_DESC(buf_sz, "DMA buffer size"); |
99 | 99 | ||
@@ -136,8 +136,8 @@ static void stmmac_verify_args(void) | |||
136 | dma_rxsize = DMA_RX_SIZE; | 136 | dma_rxsize = DMA_RX_SIZE; |
137 | if (unlikely(dma_txsize < 0)) | 137 | if (unlikely(dma_txsize < 0)) |
138 | dma_txsize = DMA_TX_SIZE; | 138 | dma_txsize = DMA_TX_SIZE; |
139 | if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB))) | 139 | if (unlikely((buf_sz < DEFAULT_BUFSIZE) || (buf_sz > BUF_SIZE_16KiB))) |
140 | buf_sz = DMA_BUFFER_SIZE; | 140 | buf_sz = DEFAULT_BUFSIZE; |
141 | if (unlikely(flow_ctrl > 1)) | 141 | if (unlikely(flow_ctrl > 1)) |
142 | flow_ctrl = FLOW_AUTO; | 142 | flow_ctrl = FLOW_AUTO; |
143 | else if (likely(flow_ctrl < 0)) | 143 | else if (likely(flow_ctrl < 0)) |
@@ -286,10 +286,25 @@ bool stmmac_eee_init(struct stmmac_priv *priv) | |||
286 | 286 | ||
287 | /* MAC core supports the EEE feature. */ | 287 | /* MAC core supports the EEE feature. */ |
288 | if (priv->dma_cap.eee) { | 288 | if (priv->dma_cap.eee) { |
289 | int tx_lpi_timer = priv->tx_lpi_timer; | ||
290 | |||
289 | /* Check if the PHY supports EEE */ | 291 | /* Check if the PHY supports EEE */ |
290 | if (phy_init_eee(priv->phydev, 1)) | 292 | if (phy_init_eee(priv->phydev, 1)) { |
293 | /* To manage at run-time if the EEE cannot be supported | ||
294 | * anymore (for example because the lp caps have been | ||
295 | * changed). | ||
296 | * In that case the driver disable own timers. | ||
297 | */ | ||
298 | if (priv->eee_active) { | ||
299 | pr_debug("stmmac: disable EEE\n"); | ||
300 | del_timer_sync(&priv->eee_ctrl_timer); | ||
301 | priv->hw->mac->set_eee_timer(priv->ioaddr, 0, | ||
302 | tx_lpi_timer); | ||
303 | } | ||
304 | priv->eee_active = 0; | ||
291 | goto out; | 305 | goto out; |
292 | 306 | } | |
307 | /* Activate the EEE and start timers */ | ||
293 | if (!priv->eee_active) { | 308 | if (!priv->eee_active) { |
294 | priv->eee_active = 1; | 309 | priv->eee_active = 1; |
295 | init_timer(&priv->eee_ctrl_timer); | 310 | init_timer(&priv->eee_ctrl_timer); |
@@ -300,13 +315,13 @@ bool stmmac_eee_init(struct stmmac_priv *priv) | |||
300 | 315 | ||
301 | priv->hw->mac->set_eee_timer(priv->ioaddr, | 316 | priv->hw->mac->set_eee_timer(priv->ioaddr, |
302 | STMMAC_DEFAULT_LIT_LS, | 317 | STMMAC_DEFAULT_LIT_LS, |
303 | priv->tx_lpi_timer); | 318 | tx_lpi_timer); |
304 | } else | 319 | } else |
305 | /* Set HW EEE according to the speed */ | 320 | /* Set HW EEE according to the speed */ |
306 | priv->hw->mac->set_eee_pls(priv->ioaddr, | 321 | priv->hw->mac->set_eee_pls(priv->ioaddr, |
307 | priv->phydev->link); | 322 | priv->phydev->link); |
308 | 323 | ||
309 | pr_info("stmmac: Energy-Efficient Ethernet initialized\n"); | 324 | pr_debug("stmmac: Energy-Efficient Ethernet initialized\n"); |
310 | 325 | ||
311 | ret = true; | 326 | ret = true; |
312 | } | 327 | } |
@@ -886,10 +901,10 @@ static int stmmac_set_bfsize(int mtu, int bufsize) | |||
886 | ret = BUF_SIZE_8KiB; | 901 | ret = BUF_SIZE_8KiB; |
887 | else if (mtu >= BUF_SIZE_2KiB) | 902 | else if (mtu >= BUF_SIZE_2KiB) |
888 | ret = BUF_SIZE_4KiB; | 903 | ret = BUF_SIZE_4KiB; |
889 | else if (mtu >= DMA_BUFFER_SIZE) | 904 | else if (mtu > DEFAULT_BUFSIZE) |
890 | ret = BUF_SIZE_2KiB; | 905 | ret = BUF_SIZE_2KiB; |
891 | else | 906 | else |
892 | ret = DMA_BUFFER_SIZE; | 907 | ret = DEFAULT_BUFSIZE; |
893 | 908 | ||
894 | return ret; | 909 | return ret; |
895 | } | 910 | } |
@@ -951,9 +966,9 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p, | |||
951 | 966 | ||
952 | p->des2 = priv->rx_skbuff_dma[i]; | 967 | p->des2 = priv->rx_skbuff_dma[i]; |
953 | 968 | ||
954 | if ((priv->mode == STMMAC_RING_MODE) && | 969 | if ((priv->hw->mode->init_desc3) && |
955 | (priv->dma_buf_sz == BUF_SIZE_16KiB)) | 970 | (priv->dma_buf_sz == BUF_SIZE_16KiB)) |
956 | priv->hw->ring->init_desc3(p); | 971 | priv->hw->mode->init_desc3(p); |
957 | 972 | ||
958 | return 0; | 973 | return 0; |
959 | } | 974 | } |
@@ -984,11 +999,8 @@ static int init_dma_desc_rings(struct net_device *dev) | |||
984 | unsigned int bfsize = 0; | 999 | unsigned int bfsize = 0; |
985 | int ret = -ENOMEM; | 1000 | int ret = -ENOMEM; |
986 | 1001 | ||
987 | /* Set the max buffer size according to the DESC mode | 1002 | if (priv->hw->mode->set_16kib_bfsize) |
988 | * and the MTU. Note that RING mode allows 16KiB bsize. | 1003 | bfsize = priv->hw->mode->set_16kib_bfsize(dev->mtu); |
989 | */ | ||
990 | if (priv->mode == STMMAC_RING_MODE) | ||
991 | bfsize = priv->hw->ring->set_16kib_bfsize(dev->mtu); | ||
992 | 1004 | ||
993 | if (bfsize < BUF_SIZE_16KiB) | 1005 | if (bfsize < BUF_SIZE_16KiB) |
994 | bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); | 1006 | bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); |
@@ -1029,15 +1041,15 @@ static int init_dma_desc_rings(struct net_device *dev) | |||
1029 | /* Setup the chained descriptor addresses */ | 1041 | /* Setup the chained descriptor addresses */ |
1030 | if (priv->mode == STMMAC_CHAIN_MODE) { | 1042 | if (priv->mode == STMMAC_CHAIN_MODE) { |
1031 | if (priv->extend_desc) { | 1043 | if (priv->extend_desc) { |
1032 | priv->hw->chain->init(priv->dma_erx, priv->dma_rx_phy, | 1044 | priv->hw->mode->init(priv->dma_erx, priv->dma_rx_phy, |
1033 | rxsize, 1); | 1045 | rxsize, 1); |
1034 | priv->hw->chain->init(priv->dma_etx, priv->dma_tx_phy, | 1046 | priv->hw->mode->init(priv->dma_etx, priv->dma_tx_phy, |
1035 | txsize, 1); | 1047 | txsize, 1); |
1036 | } else { | 1048 | } else { |
1037 | priv->hw->chain->init(priv->dma_rx, priv->dma_rx_phy, | 1049 | priv->hw->mode->init(priv->dma_rx, priv->dma_rx_phy, |
1038 | rxsize, 0); | 1050 | rxsize, 0); |
1039 | priv->hw->chain->init(priv->dma_tx, priv->dma_tx_phy, | 1051 | priv->hw->mode->init(priv->dma_tx, priv->dma_tx_phy, |
1040 | txsize, 0); | 1052 | txsize, 0); |
1041 | } | 1053 | } |
1042 | } | 1054 | } |
1043 | 1055 | ||
@@ -1288,7 +1300,7 @@ static void stmmac_tx_clean(struct stmmac_priv *priv) | |||
1288 | DMA_TO_DEVICE); | 1300 | DMA_TO_DEVICE); |
1289 | priv->tx_skbuff_dma[entry] = 0; | 1301 | priv->tx_skbuff_dma[entry] = 0; |
1290 | } | 1302 | } |
1291 | priv->hw->ring->clean_desc3(priv, p); | 1303 | priv->hw->mode->clean_desc3(priv, p); |
1292 | 1304 | ||
1293 | if (likely(skb != NULL)) { | 1305 | if (likely(skb != NULL)) { |
1294 | dev_kfree_skb(skb); | 1306 | dev_kfree_skb(skb); |
@@ -1705,7 +1717,7 @@ static int stmmac_open(struct net_device *dev) | |||
1705 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); | 1717 | priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); |
1706 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); | 1718 | priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); |
1707 | 1719 | ||
1708 | alloc_dma_desc_resources(priv); | 1720 | ret = alloc_dma_desc_resources(priv); |
1709 | if (ret < 0) { | 1721 | if (ret < 0) { |
1710 | pr_err("%s: DMA descriptors allocation failed\n", __func__); | 1722 | pr_err("%s: DMA descriptors allocation failed\n", __func__); |
1711 | goto dma_desc_error; | 1723 | goto dma_desc_error; |
@@ -1844,6 +1856,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1844 | int nfrags = skb_shinfo(skb)->nr_frags; | 1856 | int nfrags = skb_shinfo(skb)->nr_frags; |
1845 | struct dma_desc *desc, *first; | 1857 | struct dma_desc *desc, *first; |
1846 | unsigned int nopaged_len = skb_headlen(skb); | 1858 | unsigned int nopaged_len = skb_headlen(skb); |
1859 | unsigned int enh_desc = priv->plat->enh_desc; | ||
1847 | 1860 | ||
1848 | if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { | 1861 | if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) { |
1849 | if (!netif_queue_stopped(dev)) { | 1862 | if (!netif_queue_stopped(dev)) { |
@@ -1871,27 +1884,19 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1871 | first = desc; | 1884 | first = desc; |
1872 | 1885 | ||
1873 | /* To program the descriptors according to the size of the frame */ | 1886 | /* To program the descriptors according to the size of the frame */ |
1874 | if (priv->mode == STMMAC_RING_MODE) { | 1887 | if (enh_desc) |
1875 | is_jumbo = priv->hw->ring->is_jumbo_frm(skb->len, | 1888 | is_jumbo = priv->hw->mode->is_jumbo_frm(skb->len, enh_desc); |
1876 | priv->plat->enh_desc); | 1889 | |
1877 | if (unlikely(is_jumbo)) | ||
1878 | entry = priv->hw->ring->jumbo_frm(priv, skb, | ||
1879 | csum_insertion); | ||
1880 | } else { | ||
1881 | is_jumbo = priv->hw->chain->is_jumbo_frm(skb->len, | ||
1882 | priv->plat->enh_desc); | ||
1883 | if (unlikely(is_jumbo)) | ||
1884 | entry = priv->hw->chain->jumbo_frm(priv, skb, | ||
1885 | csum_insertion); | ||
1886 | } | ||
1887 | if (likely(!is_jumbo)) { | 1890 | if (likely(!is_jumbo)) { |
1888 | desc->des2 = dma_map_single(priv->device, skb->data, | 1891 | desc->des2 = dma_map_single(priv->device, skb->data, |
1889 | nopaged_len, DMA_TO_DEVICE); | 1892 | nopaged_len, DMA_TO_DEVICE); |
1890 | priv->tx_skbuff_dma[entry] = desc->des2; | 1893 | priv->tx_skbuff_dma[entry] = desc->des2; |
1891 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, | 1894 | priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, |
1892 | csum_insertion, priv->mode); | 1895 | csum_insertion, priv->mode); |
1893 | } else | 1896 | } else { |
1894 | desc = first; | 1897 | desc = first; |
1898 | entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion); | ||
1899 | } | ||
1895 | 1900 | ||
1896 | for (i = 0; i < nfrags; i++) { | 1901 | for (i = 0; i < nfrags; i++) { |
1897 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 1902 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
@@ -2029,7 +2034,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv) | |||
2029 | 2034 | ||
2030 | p->des2 = priv->rx_skbuff_dma[entry]; | 2035 | p->des2 = priv->rx_skbuff_dma[entry]; |
2031 | 2036 | ||
2032 | priv->hw->ring->refill_desc3(priv, p); | 2037 | priv->hw->mode->refill_desc3(priv, p); |
2033 | 2038 | ||
2034 | if (netif_msg_rx_status(priv)) | 2039 | if (netif_msg_rx_status(priv)) |
2035 | pr_debug("\trefill entry #%d\n", entry); | 2040 | pr_debug("\trefill entry #%d\n", entry); |
@@ -2633,11 +2638,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv) | |||
2633 | 2638 | ||
2634 | /* To use the chained or ring mode */ | 2639 | /* To use the chained or ring mode */ |
2635 | if (chain_mode) { | 2640 | if (chain_mode) { |
2636 | priv->hw->chain = &chain_mode_ops; | 2641 | priv->hw->mode = &chain_mode_ops; |
2637 | pr_info(" Chain mode enabled\n"); | 2642 | pr_info(" Chain mode enabled\n"); |
2638 | priv->mode = STMMAC_CHAIN_MODE; | 2643 | priv->mode = STMMAC_CHAIN_MODE; |
2639 | } else { | 2644 | } else { |
2640 | priv->hw->ring = &ring_mode_ops; | 2645 | priv->hw->mode = &ring_mode_ops; |
2641 | pr_info(" Ring mode enabled\n"); | 2646 | pr_info(" Ring mode enabled\n"); |
2642 | priv->mode = STMMAC_RING_MODE; | 2647 | priv->mode = STMMAC_RING_MODE; |
2643 | } | 2648 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 5884a7d2063b..8fb32a80f1c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -33,6 +33,11 @@ static const struct of_device_id stmmac_dt_ids[] = { | |||
33 | #ifdef CONFIG_DWMAC_SUNXI | 33 | #ifdef CONFIG_DWMAC_SUNXI |
34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, | 34 | { .compatible = "allwinner,sun7i-a20-gmac", .data = &sun7i_gmac_data}, |
35 | #endif | 35 | #endif |
36 | #ifdef CONFIG_DWMAC_STI | ||
37 | { .compatible = "st,stih415-dwmac", .data = &sti_gmac_data}, | ||
38 | { .compatible = "st,stih416-dwmac", .data = &sti_gmac_data}, | ||
39 | { .compatible = "st,stid127-dwmac", .data = &sti_gmac_data}, | ||
40 | #endif | ||
36 | /* SoC specific glue layers should come before generic bindings */ | 41 | /* SoC specific glue layers should come before generic bindings */ |
37 | { .compatible = "st,spear600-gmac"}, | 42 | { .compatible = "st,spear600-gmac"}, |
38 | { .compatible = "snps,dwmac-3.610"}, | 43 | { .compatible = "snps,dwmac-3.610"}, |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index bde63e3af96f..7d6d8ec676c8 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -554,7 +554,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
554 | * common for both the interface as the interface shares | 554 | * common for both the interface as the interface shares |
555 | * the same hardware resource. | 555 | * the same hardware resource. |
556 | */ | 556 | */ |
557 | for (i = 0; i <= priv->data.slaves; i++) | 557 | for (i = 0; i < priv->data.slaves; i++) |
558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) | 558 | if (priv->slaves[i].ndev->flags & IFF_PROMISC) |
559 | flag = true; | 559 | flag = true; |
560 | 560 | ||
@@ -578,7 +578,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
578 | unsigned long timeout = jiffies + HZ; | 578 | unsigned long timeout = jiffies + HZ; |
579 | 579 | ||
580 | /* Disable Learn for all ports */ | 580 | /* Disable Learn for all ports */ |
581 | for (i = 0; i <= priv->data.slaves; i++) { | 581 | for (i = 0; i < priv->data.slaves; i++) { |
582 | cpsw_ale_control_set(ale, i, | 582 | cpsw_ale_control_set(ale, i, |
583 | ALE_PORT_NOLEARN, 1); | 583 | ALE_PORT_NOLEARN, 1); |
584 | cpsw_ale_control_set(ale, i, | 584 | cpsw_ale_control_set(ale, i, |
@@ -606,7 +606,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); | 606 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); |
607 | 607 | ||
608 | /* Enable Learn for all ports */ | 608 | /* Enable Learn for all ports */ |
609 | for (i = 0; i <= priv->data.slaves; i++) { | 609 | for (i = 0; i < priv->data.slaves; i++) { |
610 | cpsw_ale_control_set(ale, i, | 610 | cpsw_ale_control_set(ale, i, |
611 | ALE_PORT_NOLEARN, 0); | 611 | ALE_PORT_NOLEARN, 0); |
612 | cpsw_ale_control_set(ale, i, | 612 | cpsw_ale_control_set(ale, i, |
@@ -1164,11 +1164,17 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) | |||
1164 | 1164 | ||
1165 | static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) | 1165 | static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) |
1166 | { | 1166 | { |
1167 | u32 slave_port; | ||
1168 | |||
1169 | slave_port = cpsw_get_slave_port(priv, slave->slave_num); | ||
1170 | |||
1167 | if (!slave->phy) | 1171 | if (!slave->phy) |
1168 | return; | 1172 | return; |
1169 | phy_stop(slave->phy); | 1173 | phy_stop(slave->phy); |
1170 | phy_disconnect(slave->phy); | 1174 | phy_disconnect(slave->phy); |
1171 | slave->phy = NULL; | 1175 | slave->phy = NULL; |
1176 | cpsw_ale_control_set(priv->ale, slave_port, | ||
1177 | ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); | ||
1172 | } | 1178 | } |
1173 | 1179 | ||
1174 | static int cpsw_ndo_open(struct net_device *ndev) | 1180 | static int cpsw_ndo_open(struct net_device *ndev) |
@@ -1878,14 +1884,29 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, | |||
1878 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); | 1884 | mdio_node = of_find_node_by_phandle(be32_to_cpup(parp)); |
1879 | phyid = be32_to_cpup(parp+1); | 1885 | phyid = be32_to_cpup(parp+1); |
1880 | mdio = of_find_device_by_node(mdio_node); | 1886 | mdio = of_find_device_by_node(mdio_node); |
1881 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | 1887 | |
1882 | PHY_ID_FMT, mdio->name, phyid); | 1888 | if (strncmp(mdio->name, "gpio", 4) == 0) { |
1889 | /* GPIO bitbang MDIO driver attached */ | ||
1890 | struct mii_bus *bus = dev_get_drvdata(&mdio->dev); | ||
1891 | |||
1892 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
1893 | PHY_ID_FMT, bus->id, phyid); | ||
1894 | } else { | ||
1895 | /* davinci MDIO driver attached */ | ||
1896 | snprintf(slave_data->phy_id, sizeof(slave_data->phy_id), | ||
1897 | PHY_ID_FMT, mdio->name, phyid); | ||
1898 | } | ||
1883 | 1899 | ||
1884 | mac_addr = of_get_mac_address(slave_node); | 1900 | mac_addr = of_get_mac_address(slave_node); |
1885 | if (mac_addr) | 1901 | if (mac_addr) |
1886 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | 1902 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); |
1887 | 1903 | ||
1888 | slave_data->phy_if = of_get_phy_mode(slave_node); | 1904 | slave_data->phy_if = of_get_phy_mode(slave_node); |
1905 | if (slave_data->phy_if < 0) { | ||
1906 | pr_err("Missing or malformed slave[%d] phy-mode property\n", | ||
1907 | i); | ||
1908 | return slave_data->phy_if; | ||
1909 | } | ||
1889 | 1910 | ||
1890 | if (data->dual_emac) { | 1911 | if (data->dual_emac) { |
1891 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", | 1912 | if (of_property_read_u32(slave_node, "dual_emac_res_vlan", |
@@ -2208,10 +2229,6 @@ static int cpsw_probe(struct platform_device *pdev) | |||
2208 | goto clean_ale_ret; | 2229 | goto clean_ale_ret; |
2209 | } | 2230 | } |
2210 | 2231 | ||
2211 | if (cpts_register(&pdev->dev, priv->cpts, | ||
2212 | data->cpts_clock_mult, data->cpts_clock_shift)) | ||
2213 | dev_err(priv->dev, "error registering cpts device\n"); | ||
2214 | |||
2215 | cpsw_notice(priv, probe, "initialized device (regs %pa, irq %d)\n", | 2232 | cpsw_notice(priv, probe, "initialized device (regs %pa, irq %d)\n", |
2216 | &ss_res->start, ndev->irq); | 2233 | &ss_res->start, ndev->irq); |
2217 | 2234 | ||
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 364d0c7952c0..88ef27067bf2 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
@@ -355,7 +355,7 @@ int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) | |||
355 | int i; | 355 | int i; |
356 | 356 | ||
357 | spin_lock_irqsave(&ctlr->lock, flags); | 357 | spin_lock_irqsave(&ctlr->lock, flags); |
358 | if (ctlr->state != CPDMA_STATE_ACTIVE) { | 358 | if (ctlr->state == CPDMA_STATE_TEARDOWN) { |
359 | spin_unlock_irqrestore(&ctlr->lock, flags); | 359 | spin_unlock_irqrestore(&ctlr->lock, flags); |
360 | return -EINVAL; | 360 | return -EINVAL; |
361 | } | 361 | } |
@@ -891,7 +891,7 @@ int cpdma_chan_stop(struct cpdma_chan *chan) | |||
891 | unsigned timeout; | 891 | unsigned timeout; |
892 | 892 | ||
893 | spin_lock_irqsave(&chan->lock, flags); | 893 | spin_lock_irqsave(&chan->lock, flags); |
894 | if (chan->state != CPDMA_STATE_ACTIVE) { | 894 | if (chan->state == CPDMA_STATE_TEARDOWN) { |
895 | spin_unlock_irqrestore(&chan->lock, flags); | 895 | spin_unlock_irqrestore(&chan->lock, flags); |
896 | return -EINVAL; | 896 | return -EINVAL; |
897 | } | 897 | } |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index cd9b164a0434..8f0e69ce07ca 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -1532,9 +1532,9 @@ static int emac_dev_open(struct net_device *ndev) | |||
1532 | struct device *emac_dev = &ndev->dev; | 1532 | struct device *emac_dev = &ndev->dev; |
1533 | u32 cnt; | 1533 | u32 cnt; |
1534 | struct resource *res; | 1534 | struct resource *res; |
1535 | int ret; | 1535 | int q, m, ret; |
1536 | int res_num = 0, irq_num = 0; | ||
1536 | int i = 0; | 1537 | int i = 0; |
1537 | int k = 0; | ||
1538 | struct emac_priv *priv = netdev_priv(ndev); | 1538 | struct emac_priv *priv = netdev_priv(ndev); |
1539 | 1539 | ||
1540 | pm_runtime_get(&priv->pdev->dev); | 1540 | pm_runtime_get(&priv->pdev->dev); |
@@ -1564,15 +1564,24 @@ static int emac_dev_open(struct net_device *ndev) | |||
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | /* Request IRQ */ | 1566 | /* Request IRQ */ |
1567 | while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, | ||
1568 | res_num))) { | ||
1569 | for (irq_num = res->start; irq_num <= res->end; irq_num++) { | ||
1570 | dev_err(emac_dev, "Request IRQ %d\n", irq_num); | ||
1571 | if (request_irq(irq_num, emac_irq, 0, ndev->name, | ||
1572 | ndev)) { | ||
1573 | dev_err(emac_dev, | ||
1574 | "DaVinci EMAC: request_irq() failed\n"); | ||
1575 | ret = -EBUSY; | ||
1567 | 1576 | ||
1568 | while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) { | ||
1569 | for (i = res->start; i <= res->end; i++) { | ||
1570 | if (devm_request_irq(&priv->pdev->dev, i, emac_irq, | ||
1571 | 0, ndev->name, ndev)) | ||
1572 | goto rollback; | 1577 | goto rollback; |
1578 | } | ||
1573 | } | 1579 | } |
1574 | k++; | 1580 | res_num++; |
1575 | } | 1581 | } |
1582 | /* prepare counters for rollback in case of an error */ | ||
1583 | res_num--; | ||
1584 | irq_num--; | ||
1576 | 1585 | ||
1577 | /* Start/Enable EMAC hardware */ | 1586 | /* Start/Enable EMAC hardware */ |
1578 | emac_hw_enable(priv); | 1587 | emac_hw_enable(priv); |
@@ -1639,11 +1648,23 @@ static int emac_dev_open(struct net_device *ndev) | |||
1639 | 1648 | ||
1640 | return 0; | 1649 | return 0; |
1641 | 1650 | ||
1642 | rollback: | ||
1643 | |||
1644 | dev_err(emac_dev, "DaVinci EMAC: devm_request_irq() failed"); | ||
1645 | ret = -EBUSY; | ||
1646 | err: | 1651 | err: |
1652 | emac_int_disable(priv); | ||
1653 | napi_disable(&priv->napi); | ||
1654 | |||
1655 | rollback: | ||
1656 | for (q = res_num; q >= 0; q--) { | ||
1657 | res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, q); | ||
1658 | /* at the first iteration, irq_num is already set to the | ||
1659 | * right value | ||
1660 | */ | ||
1661 | if (q != res_num) | ||
1662 | irq_num = res->end; | ||
1663 | |||
1664 | for (m = irq_num; m >= res->start; m--) | ||
1665 | free_irq(m, ndev); | ||
1666 | } | ||
1667 | cpdma_ctlr_stop(priv->dma); | ||
1647 | pm_runtime_put(&priv->pdev->dev); | 1668 | pm_runtime_put(&priv->pdev->dev); |
1648 | return ret; | 1669 | return ret; |
1649 | } | 1670 | } |
@@ -1659,6 +1680,9 @@ err: | |||
1659 | */ | 1680 | */ |
1660 | static int emac_dev_stop(struct net_device *ndev) | 1681 | static int emac_dev_stop(struct net_device *ndev) |
1661 | { | 1682 | { |
1683 | struct resource *res; | ||
1684 | int i = 0; | ||
1685 | int irq_num; | ||
1662 | struct emac_priv *priv = netdev_priv(ndev); | 1686 | struct emac_priv *priv = netdev_priv(ndev); |
1663 | struct device *emac_dev = &ndev->dev; | 1687 | struct device *emac_dev = &ndev->dev; |
1664 | 1688 | ||
@@ -1674,6 +1698,13 @@ static int emac_dev_stop(struct net_device *ndev) | |||
1674 | if (priv->phydev) | 1698 | if (priv->phydev) |
1675 | phy_disconnect(priv->phydev); | 1699 | phy_disconnect(priv->phydev); |
1676 | 1700 | ||
1701 | /* Free IRQ */ | ||
1702 | while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, i))) { | ||
1703 | for (irq_num = res->start; irq_num <= res->end; irq_num++) | ||
1704 | free_irq(irq_num, priv->ndev); | ||
1705 | i++; | ||
1706 | } | ||
1707 | |||
1677 | if (netif_msg_drv(priv)) | 1708 | if (netif_msg_drv(priv)) |
1678 | dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name); | 1709 | dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name); |
1679 | 1710 | ||
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 023237a65720..17503da9f7a5 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c | |||
@@ -2071,7 +2071,7 @@ static int tile_net_tx(struct sk_buff *skb, struct net_device *dev) | |||
2071 | 2071 | ||
2072 | /* Return subqueue id on this core (one per core). */ | 2072 | /* Return subqueue id on this core (one per core). */ |
2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, | 2073 | static u16 tile_net_select_queue(struct net_device *dev, struct sk_buff *skb, |
2074 | void *accel_priv) | 2074 | void *accel_priv, select_queue_fallback_t fallback) |
2075 | { | 2075 | { |
2076 | return smp_processor_id(); | 2076 | return smp_processor_id(); |
2077 | } | 2077 | } |
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index ef312bc6b865..6ac20a6738f4 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c | |||
@@ -923,7 +923,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
923 | if (rc) { | 923 | if (rc) { |
924 | dev_err(&pdev->dev, | 924 | dev_err(&pdev->dev, |
925 | "32-bit PCI DMA addresses not supported by the card!?\n"); | 925 | "32-bit PCI DMA addresses not supported by the card!?\n"); |
926 | goto err_out; | 926 | goto err_out_pci_disable; |
927 | } | 927 | } |
928 | 928 | ||
929 | /* sanity check */ | 929 | /* sanity check */ |
@@ -931,7 +931,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
931 | (pci_resource_len(pdev, 1) < io_size)) { | 931 | (pci_resource_len(pdev, 1) < io_size)) { |
932 | rc = -EIO; | 932 | rc = -EIO; |
933 | dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); | 933 | dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n"); |
934 | goto err_out; | 934 | goto err_out_pci_disable; |
935 | } | 935 | } |
936 | 936 | ||
937 | pioaddr = pci_resource_start(pdev, 0); | 937 | pioaddr = pci_resource_start(pdev, 0); |
@@ -942,7 +942,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
942 | dev = alloc_etherdev(sizeof(struct rhine_private)); | 942 | dev = alloc_etherdev(sizeof(struct rhine_private)); |
943 | if (!dev) { | 943 | if (!dev) { |
944 | rc = -ENOMEM; | 944 | rc = -ENOMEM; |
945 | goto err_out; | 945 | goto err_out_pci_disable; |
946 | } | 946 | } |
947 | SET_NETDEV_DEV(dev, &pdev->dev); | 947 | SET_NETDEV_DEV(dev, &pdev->dev); |
948 | 948 | ||
@@ -1084,6 +1084,8 @@ err_out_free_res: | |||
1084 | pci_release_regions(pdev); | 1084 | pci_release_regions(pdev); |
1085 | err_out_free_netdev: | 1085 | err_out_free_netdev: |
1086 | free_netdev(dev); | 1086 | free_netdev(dev); |
1087 | err_out_pci_disable: | ||
1088 | pci_disable_device(pdev); | ||
1087 | err_out: | 1089 | err_out: |
1088 | return rc; | 1090 | return rc; |
1089 | } | 1091 | } |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1ec65feebb9e..4bfdf8c7ada0 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/of_mdio.h> | 27 | #include <linux/of_mdio.h> |
28 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
29 | #include <linux/of_irq.h> | ||
29 | #include <linux/of_address.h> | 30 | #include <linux/of_address.h> |
30 | #include <linux/skbuff.h> | 31 | #include <linux/skbuff.h> |
31 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
@@ -600,7 +601,8 @@ static void axienet_start_xmit_done(struct net_device *ndev) | |||
600 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; | 601 | size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; |
601 | packets++; | 602 | packets++; |
602 | 603 | ||
603 | lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; | 604 | ++lp->tx_bd_ci; |
605 | lp->tx_bd_ci %= TX_BD_NUM; | ||
604 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; | 606 | cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; |
605 | status = cur_p->status; | 607 | status = cur_p->status; |
606 | } | 608 | } |
@@ -686,7 +688,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
686 | skb_headlen(skb), DMA_TO_DEVICE); | 688 | skb_headlen(skb), DMA_TO_DEVICE); |
687 | 689 | ||
688 | for (ii = 0; ii < num_frag; ii++) { | 690 | for (ii = 0; ii < num_frag; ii++) { |
689 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 691 | ++lp->tx_bd_tail; |
692 | lp->tx_bd_tail %= TX_BD_NUM; | ||
690 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | 693 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
691 | frag = &skb_shinfo(skb)->frags[ii]; | 694 | frag = &skb_shinfo(skb)->frags[ii]; |
692 | cur_p->phys = dma_map_single(ndev->dev.parent, | 695 | cur_p->phys = dma_map_single(ndev->dev.parent, |
@@ -702,7 +705,8 @@ static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
702 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; | 705 | tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; |
703 | /* Start the transfer */ | 706 | /* Start the transfer */ |
704 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); | 707 | axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); |
705 | lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; | 708 | ++lp->tx_bd_tail; |
709 | lp->tx_bd_tail %= TX_BD_NUM; | ||
706 | 710 | ||
707 | return NETDEV_TX_OK; | 711 | return NETDEV_TX_OK; |
708 | } | 712 | } |
@@ -774,7 +778,8 @@ static void axienet_recv(struct net_device *ndev) | |||
774 | cur_p->status = 0; | 778 | cur_p->status = 0; |
775 | cur_p->sw_id_offset = (u32) new_skb; | 779 | cur_p->sw_id_offset = (u32) new_skb; |
776 | 780 | ||
777 | lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; | 781 | ++lp->rx_bd_ci; |
782 | lp->rx_bd_ci %= RX_BD_NUM; | ||
778 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | 783 | cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; |
779 | } | 784 | } |
780 | 785 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 7756118c2f0a..d6fce9750b95 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -88,8 +88,12 @@ static int netvsc_open(struct net_device *net) | |||
88 | { | 88 | { |
89 | struct net_device_context *net_device_ctx = netdev_priv(net); | 89 | struct net_device_context *net_device_ctx = netdev_priv(net); |
90 | struct hv_device *device_obj = net_device_ctx->device_ctx; | 90 | struct hv_device *device_obj = net_device_ctx->device_ctx; |
91 | struct netvsc_device *nvdev; | ||
92 | struct rndis_device *rdev; | ||
91 | int ret = 0; | 93 | int ret = 0; |
92 | 94 | ||
95 | netif_carrier_off(net); | ||
96 | |||
93 | /* Open up the device */ | 97 | /* Open up the device */ |
94 | ret = rndis_filter_open(device_obj); | 98 | ret = rndis_filter_open(device_obj); |
95 | if (ret != 0) { | 99 | if (ret != 0) { |
@@ -99,6 +103,11 @@ static int netvsc_open(struct net_device *net) | |||
99 | 103 | ||
100 | netif_start_queue(net); | 104 | netif_start_queue(net); |
101 | 105 | ||
106 | nvdev = hv_get_drvdata(device_obj); | ||
107 | rdev = nvdev->extension; | ||
108 | if (!rdev->link_state) | ||
109 | netif_carrier_on(net); | ||
110 | |||
102 | return ret; | 111 | return ret; |
103 | } | 112 | } |
104 | 113 | ||
@@ -229,23 +238,24 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, | |||
229 | struct net_device *net; | 238 | struct net_device *net; |
230 | struct net_device_context *ndev_ctx; | 239 | struct net_device_context *ndev_ctx; |
231 | struct netvsc_device *net_device; | 240 | struct netvsc_device *net_device; |
241 | struct rndis_device *rdev; | ||
232 | 242 | ||
233 | net_device = hv_get_drvdata(device_obj); | 243 | net_device = hv_get_drvdata(device_obj); |
244 | rdev = net_device->extension; | ||
245 | |||
246 | rdev->link_state = status != 1; | ||
247 | |||
234 | net = net_device->ndev; | 248 | net = net_device->ndev; |
235 | 249 | ||
236 | if (!net) { | 250 | if (!net || net->reg_state != NETREG_REGISTERED) |
237 | netdev_err(net, "got link status but net device " | ||
238 | "not initialized yet\n"); | ||
239 | return; | 251 | return; |
240 | } | ||
241 | 252 | ||
253 | ndev_ctx = netdev_priv(net); | ||
242 | if (status == 1) { | 254 | if (status == 1) { |
243 | netif_carrier_on(net); | ||
244 | ndev_ctx = netdev_priv(net); | ||
245 | schedule_delayed_work(&ndev_ctx->dwork, 0); | 255 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
246 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); | 256 | schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); |
247 | } else { | 257 | } else { |
248 | netif_carrier_off(net); | 258 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
249 | } | 259 | } |
250 | } | 260 | } |
251 | 261 | ||
@@ -388,17 +398,35 @@ static const struct net_device_ops device_ops = { | |||
388 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add | 398 | * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add |
389 | * another netif_notify_peers() into a delayed work, otherwise GARP packet | 399 | * another netif_notify_peers() into a delayed work, otherwise GARP packet |
390 | * will not be sent after quick migration, and cause network disconnection. | 400 | * will not be sent after quick migration, and cause network disconnection. |
401 | * Also, we update the carrier status here. | ||
391 | */ | 402 | */ |
392 | static void netvsc_send_garp(struct work_struct *w) | 403 | static void netvsc_link_change(struct work_struct *w) |
393 | { | 404 | { |
394 | struct net_device_context *ndev_ctx; | 405 | struct net_device_context *ndev_ctx; |
395 | struct net_device *net; | 406 | struct net_device *net; |
396 | struct netvsc_device *net_device; | 407 | struct netvsc_device *net_device; |
408 | struct rndis_device *rdev; | ||
409 | bool notify; | ||
410 | |||
411 | rtnl_lock(); | ||
397 | 412 | ||
398 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); | 413 | ndev_ctx = container_of(w, struct net_device_context, dwork.work); |
399 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); | 414 | net_device = hv_get_drvdata(ndev_ctx->device_ctx); |
415 | rdev = net_device->extension; | ||
400 | net = net_device->ndev; | 416 | net = net_device->ndev; |
401 | netdev_notify_peers(net); | 417 | |
418 | if (rdev->link_state) { | ||
419 | netif_carrier_off(net); | ||
420 | notify = false; | ||
421 | } else { | ||
422 | netif_carrier_on(net); | ||
423 | notify = true; | ||
424 | } | ||
425 | |||
426 | rtnl_unlock(); | ||
427 | |||
428 | if (notify) | ||
429 | netdev_notify_peers(net); | ||
402 | } | 430 | } |
403 | 431 | ||
404 | 432 | ||
@@ -414,13 +442,12 @@ static int netvsc_probe(struct hv_device *dev, | |||
414 | if (!net) | 442 | if (!net) |
415 | return -ENOMEM; | 443 | return -ENOMEM; |
416 | 444 | ||
417 | /* Set initial state */ | ||
418 | netif_carrier_off(net); | 445 | netif_carrier_off(net); |
419 | 446 | ||
420 | net_device_ctx = netdev_priv(net); | 447 | net_device_ctx = netdev_priv(net); |
421 | net_device_ctx->device_ctx = dev; | 448 | net_device_ctx->device_ctx = dev; |
422 | hv_set_drvdata(dev, net); | 449 | hv_set_drvdata(dev, net); |
423 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); | 450 | INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); |
424 | INIT_WORK(&net_device_ctx->work, do_set_multicast); | 451 | INIT_WORK(&net_device_ctx->work, do_set_multicast); |
425 | 452 | ||
426 | net->netdev_ops = &device_ops; | 453 | net->netdev_ops = &device_ops; |
@@ -443,13 +470,13 @@ static int netvsc_probe(struct hv_device *dev, | |||
443 | } | 470 | } |
444 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); | 471 | memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); |
445 | 472 | ||
446 | netif_carrier_on(net); | ||
447 | |||
448 | ret = register_netdev(net); | 473 | ret = register_netdev(net); |
449 | if (ret != 0) { | 474 | if (ret != 0) { |
450 | pr_err("Unable to register netdev.\n"); | 475 | pr_err("Unable to register netdev.\n"); |
451 | rndis_filter_device_remove(dev); | 476 | rndis_filter_device_remove(dev); |
452 | free_netdev(net); | 477 | free_netdev(net); |
478 | } else { | ||
479 | schedule_delayed_work(&net_device_ctx->dwork, 0); | ||
453 | } | 480 | } |
454 | 481 | ||
455 | return ret; | 482 | return ret; |
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index 1084e5de3ceb..b54fd257652b 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -243,6 +243,22 @@ static int rndis_filter_send_request(struct rndis_device *dev, | |||
243 | return ret; | 243 | return ret; |
244 | } | 244 | } |
245 | 245 | ||
246 | static void rndis_set_link_state(struct rndis_device *rdev, | ||
247 | struct rndis_request *request) | ||
248 | { | ||
249 | u32 link_status; | ||
250 | struct rndis_query_complete *query_complete; | ||
251 | |||
252 | query_complete = &request->response_msg.msg.query_complete; | ||
253 | |||
254 | if (query_complete->status == RNDIS_STATUS_SUCCESS && | ||
255 | query_complete->info_buflen == sizeof(u32)) { | ||
256 | memcpy(&link_status, (void *)((unsigned long)query_complete + | ||
257 | query_complete->info_buf_offset), sizeof(u32)); | ||
258 | rdev->link_state = link_status != 0; | ||
259 | } | ||
260 | } | ||
261 | |||
246 | static void rndis_filter_receive_response(struct rndis_device *dev, | 262 | static void rndis_filter_receive_response(struct rndis_device *dev, |
247 | struct rndis_message *resp) | 263 | struct rndis_message *resp) |
248 | { | 264 | { |
@@ -272,6 +288,10 @@ static void rndis_filter_receive_response(struct rndis_device *dev, | |||
272 | sizeof(struct rndis_message) + RNDIS_EXT_LEN) { | 288 | sizeof(struct rndis_message) + RNDIS_EXT_LEN) { |
273 | memcpy(&request->response_msg, resp, | 289 | memcpy(&request->response_msg, resp, |
274 | resp->msg_len); | 290 | resp->msg_len); |
291 | if (request->request_msg.ndis_msg_type == | ||
292 | RNDIS_MSG_QUERY && request->request_msg.msg. | ||
293 | query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS) | ||
294 | rndis_set_link_state(dev, request); | ||
275 | } else { | 295 | } else { |
276 | netdev_err(ndev, | 296 | netdev_err(ndev, |
277 | "rndis response buffer overflow " | 297 | "rndis response buffer overflow " |
@@ -620,7 +640,6 @@ static int rndis_filter_query_device_link_status(struct rndis_device *dev) | |||
620 | ret = rndis_filter_query_device(dev, | 640 | ret = rndis_filter_query_device(dev, |
621 | RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, | 641 | RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, |
622 | &link_status, &size); | 642 | &link_status, &size); |
623 | dev->link_state = (link_status != 0) ? true : false; | ||
624 | 643 | ||
625 | return ret; | 644 | return ret; |
626 | } | 645 | } |
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index ab31544bc254..a30258aad139 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c | |||
@@ -546,12 +546,12 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) | |||
546 | int rc; | 546 | int rc; |
547 | unsigned long flags; | 547 | unsigned long flags; |
548 | 548 | ||
549 | spin_lock(&lp->lock); | 549 | spin_lock_irqsave(&lp->lock, flags); |
550 | if (lp->irq_busy) { | 550 | if (lp->irq_busy) { |
551 | spin_unlock(&lp->lock); | 551 | spin_unlock_irqrestore(&lp->lock, flags); |
552 | return -EBUSY; | 552 | return -EBUSY; |
553 | } | 553 | } |
554 | spin_unlock(&lp->lock); | 554 | spin_unlock_irqrestore(&lp->lock, flags); |
555 | 555 | ||
556 | might_sleep(); | 556 | might_sleep(); |
557 | 557 | ||
@@ -725,10 +725,11 @@ static void at86rf230_irqwork_level(struct work_struct *work) | |||
725 | static irqreturn_t at86rf230_isr(int irq, void *data) | 725 | static irqreturn_t at86rf230_isr(int irq, void *data) |
726 | { | 726 | { |
727 | struct at86rf230_local *lp = data; | 727 | struct at86rf230_local *lp = data; |
728 | unsigned long flags; | ||
728 | 729 | ||
729 | spin_lock(&lp->lock); | 730 | spin_lock_irqsave(&lp->lock, flags); |
730 | lp->irq_busy = 1; | 731 | lp->irq_busy = 1; |
731 | spin_unlock(&lp->lock); | 732 | spin_unlock_irqrestore(&lp->lock, flags); |
732 | 733 | ||
733 | schedule_work(&lp->irqwork); | 734 | schedule_work(&lp->irqwork); |
734 | 735 | ||
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 2dc82f1d2e70..3da44d5d9149 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -210,13 +210,6 @@ config KINGSUN_DONGLE | |||
210 | To compile it as a module, choose M here: the module will be called | 210 | To compile it as a module, choose M here: the module will be called |
211 | kingsun-sir. | 211 | kingsun-sir. |
212 | 212 | ||
213 | config EP7211_DONGLE | ||
214 | tristate "Cirrus Logic clps711x I/R support" | ||
215 | depends on IRTTY_SIR && ARCH_CLPS711X && IRDA | ||
216 | help | ||
217 | Say Y here if you want to build support for the Cirrus logic | ||
218 | EP7211 chipset's infrared module. | ||
219 | |||
220 | config KSDAZZLE_DONGLE | 213 | config KSDAZZLE_DONGLE |
221 | tristate "KingSun Dazzle IrDA-USB dongle" | 214 | tristate "KingSun Dazzle IrDA-USB dongle" |
222 | depends on IRDA && USB | 215 | depends on IRDA && USB |
diff --git a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile index dfc64537f62f..be8ab5b9a4a2 100644 --- a/drivers/net/irda/Makefile +++ b/drivers/net/irda/Makefile | |||
@@ -35,7 +35,6 @@ obj-$(CONFIG_MCP2120_DONGLE) += mcp2120-sir.o | |||
35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o | 35 | obj-$(CONFIG_ACT200L_DONGLE) += act200l-sir.o |
36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o | 36 | obj-$(CONFIG_MA600_DONGLE) += ma600-sir.o |
37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o | 37 | obj-$(CONFIG_TOIM3232_DONGLE) += toim3232-sir.o |
38 | obj-$(CONFIG_EP7211_DONGLE) += ep7211-sir.o | ||
39 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o | 38 | obj-$(CONFIG_KINGSUN_DONGLE) += kingsun-sir.o |
40 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o | 39 | obj-$(CONFIG_KSDAZZLE_DONGLE) += ksdazzle-sir.o |
41 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o | 40 | obj-$(CONFIG_KS959_DONGLE) += ks959-sir.o |
diff --git a/drivers/net/irda/ep7211-sir.c b/drivers/net/irda/ep7211-sir.c deleted file mode 100644 index 5fe1f4dd3369..000000000000 --- a/drivers/net/irda/ep7211-sir.c +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | * IR port driver for the Cirrus Logic CLPS711X processors | ||
3 | * | ||
4 | * Copyright 2001, Blue Mug Inc. All rights reserved. | ||
5 | * Copyright 2007, Samuel Ortiz <samuel@sortiz.org> | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/platform_device.h> | ||
10 | |||
11 | #include <mach/hardware.h> | ||
12 | |||
13 | #include "sir-dev.h" | ||
14 | |||
15 | static int clps711x_dongle_open(struct sir_dev *dev) | ||
16 | { | ||
17 | unsigned int syscon; | ||
18 | |||
19 | /* Turn on the SIR encoder. */ | ||
20 | syscon = clps_readl(SYSCON1); | ||
21 | syscon |= SYSCON1_SIREN; | ||
22 | clps_writel(syscon, SYSCON1); | ||
23 | |||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static int clps711x_dongle_close(struct sir_dev *dev) | ||
28 | { | ||
29 | unsigned int syscon; | ||
30 | |||
31 | /* Turn off the SIR encoder. */ | ||
32 | syscon = clps_readl(SYSCON1); | ||
33 | syscon &= ~SYSCON1_SIREN; | ||
34 | clps_writel(syscon, SYSCON1); | ||
35 | |||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static struct dongle_driver clps711x_dongle = { | ||
40 | .owner = THIS_MODULE, | ||
41 | .driver_name = "EP7211 IR driver", | ||
42 | .type = IRDA_EP7211_DONGLE, | ||
43 | .open = clps711x_dongle_open, | ||
44 | .close = clps711x_dongle_close, | ||
45 | }; | ||
46 | |||
47 | static int clps711x_sir_probe(struct platform_device *pdev) | ||
48 | { | ||
49 | return irda_register_dongle(&clps711x_dongle); | ||
50 | } | ||
51 | |||
52 | static int clps711x_sir_remove(struct platform_device *pdev) | ||
53 | { | ||
54 | return irda_unregister_dongle(&clps711x_dongle); | ||
55 | } | ||
56 | |||
57 | static struct platform_driver clps711x_sir_driver = { | ||
58 | .driver = { | ||
59 | .name = "sir-clps711x", | ||
60 | .owner = THIS_MODULE, | ||
61 | }, | ||
62 | .probe = clps711x_sir_probe, | ||
63 | .remove = clps711x_sir_remove, | ||
64 | }; | ||
65 | module_platform_driver(clps711x_sir_driver); | ||
66 | |||
67 | MODULE_AUTHOR("Samuel Ortiz <samuel@sortiz.org>"); | ||
68 | MODULE_DESCRIPTION("EP7211 IR dongle driver"); | ||
69 | MODULE_LICENSE("GPL"); | ||
70 | MODULE_ALIAS("irda-dongle-13"); /* IRDA_EP7211_DONGLE */ | ||
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 177441afeb96..24b6dddd7f2f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -522,7 +522,6 @@ static void irtty_close(struct tty_struct *tty) | |||
522 | sirdev_put_instance(priv->dev); | 522 | sirdev_put_instance(priv->dev); |
523 | 523 | ||
524 | /* Stop tty */ | 524 | /* Stop tty */ |
525 | irtty_stop_receiver(tty, TRUE); | ||
526 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 525 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
527 | if (tty->ops->stop) | 526 | if (tty->ops->stop) |
528 | tty->ops->stop(tty); | 527 | tty->ops->stop(tty); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 8433de4509c7..1831fb7cd017 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -506,6 +506,9 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu) | |||
506 | static struct lock_class_key macvlan_netdev_xmit_lock_key; | 506 | static struct lock_class_key macvlan_netdev_xmit_lock_key; |
507 | static struct lock_class_key macvlan_netdev_addr_lock_key; | 507 | static struct lock_class_key macvlan_netdev_addr_lock_key; |
508 | 508 | ||
509 | #define ALWAYS_ON_FEATURES \ | ||
510 | (NETIF_F_SG | NETIF_F_GEN_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX) | ||
511 | |||
509 | #define MACVLAN_FEATURES \ | 512 | #define MACVLAN_FEATURES \ |
510 | (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ | 513 | (NETIF_F_SG | NETIF_F_ALL_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ |
511 | NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ | 514 | NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_GSO_ROBUST | \ |
@@ -539,7 +542,7 @@ static int macvlan_init(struct net_device *dev) | |||
539 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | | 542 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | |
540 | (lowerdev->state & MACVLAN_STATE_MASK); | 543 | (lowerdev->state & MACVLAN_STATE_MASK); |
541 | dev->features = lowerdev->features & MACVLAN_FEATURES; | 544 | dev->features = lowerdev->features & MACVLAN_FEATURES; |
542 | dev->features |= NETIF_F_LLTX; | 545 | dev->features |= ALWAYS_ON_FEATURES; |
543 | dev->gso_max_size = lowerdev->gso_max_size; | 546 | dev->gso_max_size = lowerdev->gso_max_size; |
544 | dev->iflink = lowerdev->ifindex; | 547 | dev->iflink = lowerdev->ifindex; |
545 | dev->hard_header_len = lowerdev->hard_header_len; | 548 | dev->hard_header_len = lowerdev->hard_header_len; |
@@ -699,7 +702,7 @@ static netdev_features_t macvlan_fix_features(struct net_device *dev, | |||
699 | features = netdev_increment_features(vlan->lowerdev->features, | 702 | features = netdev_increment_features(vlan->lowerdev->features, |
700 | features, | 703 | features, |
701 | mask); | 704 | mask); |
702 | features |= NETIF_F_LLTX; | 705 | features |= ALWAYS_ON_FEATURES; |
703 | 706 | ||
704 | return features; | 707 | return features; |
705 | } | 708 | } |
@@ -879,14 +882,15 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, | |||
879 | dev->priv_flags |= IFF_MACVLAN; | 882 | dev->priv_flags |= IFF_MACVLAN; |
880 | err = netdev_upper_dev_link(lowerdev, dev); | 883 | err = netdev_upper_dev_link(lowerdev, dev); |
881 | if (err) | 884 | if (err) |
882 | goto destroy_port; | 885 | goto unregister_netdev; |
883 | |||
884 | 886 | ||
885 | list_add_tail_rcu(&vlan->list, &port->vlans); | 887 | list_add_tail_rcu(&vlan->list, &port->vlans); |
886 | netif_stacked_transfer_operstate(lowerdev, dev); | 888 | netif_stacked_transfer_operstate(lowerdev, dev); |
887 | 889 | ||
888 | return 0; | 890 | return 0; |
889 | 891 | ||
892 | unregister_netdev: | ||
893 | unregister_netdevice(dev); | ||
890 | destroy_port: | 894 | destroy_port: |
891 | port->count -= 1; | 895 | port->count -= 1; |
892 | if (!port->count) | 896 | if (!port->count) |
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 547725fa8671..98e7cbf720a5 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
@@ -437,7 +437,10 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp, | |||
437 | if (on) { | 437 | if (on) { |
438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; | 438 | gpio_num = gpio_tab[EXTTS0_GPIO + index]; |
439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; | 439 | evnt |= (gpio_num & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT; |
440 | evnt |= EVNT_RISE; | 440 | if (rq->extts.flags & PTP_FALLING_EDGE) |
441 | evnt |= EVNT_FALL; | ||
442 | else | ||
443 | evnt |= EVNT_RISE; | ||
441 | } | 444 | } |
442 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); | 445 | ext_write(0, phydev, PAGE5, PTP_EVNT, evnt); |
443 | return 0; | 446 | return 0; |
@@ -1003,11 +1006,6 @@ static int dp83640_probe(struct phy_device *phydev) | |||
1003 | } else | 1006 | } else |
1004 | list_add_tail(&dp83640->list, &clock->phylist); | 1007 | list_add_tail(&dp83640->list, &clock->phylist); |
1005 | 1008 | ||
1006 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1007 | recalibrate(clock); | ||
1008 | else | ||
1009 | enable_broadcast(dp83640->phydev, clock->page, 1); | ||
1010 | |||
1011 | dp83640_clock_put(clock); | 1009 | dp83640_clock_put(clock); |
1012 | return 0; | 1010 | return 0; |
1013 | 1011 | ||
@@ -1058,6 +1056,21 @@ static void dp83640_remove(struct phy_device *phydev) | |||
1058 | kfree(dp83640); | 1056 | kfree(dp83640); |
1059 | } | 1057 | } |
1060 | 1058 | ||
1059 | static int dp83640_config_init(struct phy_device *phydev) | ||
1060 | { | ||
1061 | struct dp83640_private *dp83640 = phydev->priv; | ||
1062 | struct dp83640_clock *clock = dp83640->clock; | ||
1063 | |||
1064 | if (clock->chosen && !list_empty(&clock->phylist)) | ||
1065 | recalibrate(clock); | ||
1066 | else | ||
1067 | enable_broadcast(phydev, clock->page, 1); | ||
1068 | |||
1069 | enable_status_frames(phydev, true); | ||
1070 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
1071 | return 0; | ||
1072 | } | ||
1073 | |||
1061 | static int dp83640_ack_interrupt(struct phy_device *phydev) | 1074 | static int dp83640_ack_interrupt(struct phy_device *phydev) |
1062 | { | 1075 | { |
1063 | int err = phy_read(phydev, MII_DP83640_MISR); | 1076 | int err = phy_read(phydev, MII_DP83640_MISR); |
@@ -1195,11 +1208,6 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) | |||
1195 | 1208 | ||
1196 | mutex_lock(&dp83640->clock->extreg_lock); | 1209 | mutex_lock(&dp83640->clock->extreg_lock); |
1197 | 1210 | ||
1198 | if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) { | ||
1199 | enable_status_frames(phydev, true); | ||
1200 | ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE); | ||
1201 | } | ||
1202 | |||
1203 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); | 1211 | ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); |
1204 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); | 1212 | ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); |
1205 | 1213 | ||
@@ -1281,6 +1289,7 @@ static void dp83640_txtstamp(struct phy_device *phydev, | |||
1281 | } | 1289 | } |
1282 | /* fall through */ | 1290 | /* fall through */ |
1283 | case HWTSTAMP_TX_ON: | 1291 | case HWTSTAMP_TX_ON: |
1292 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; | ||
1284 | skb_queue_tail(&dp83640->tx_queue, skb); | 1293 | skb_queue_tail(&dp83640->tx_queue, skb); |
1285 | schedule_work(&dp83640->ts_work); | 1294 | schedule_work(&dp83640->ts_work); |
1286 | break; | 1295 | break; |
@@ -1330,6 +1339,7 @@ static struct phy_driver dp83640_driver = { | |||
1330 | .flags = PHY_HAS_INTERRUPT, | 1339 | .flags = PHY_HAS_INTERRUPT, |
1331 | .probe = dp83640_probe, | 1340 | .probe = dp83640_probe, |
1332 | .remove = dp83640_remove, | 1341 | .remove = dp83640_remove, |
1342 | .config_init = dp83640_config_init, | ||
1333 | .config_aneg = genphy_config_aneg, | 1343 | .config_aneg = genphy_config_aneg, |
1334 | .read_status = genphy_read_status, | 1344 | .read_status = genphy_read_status, |
1335 | .ack_interrupt = dp83640_ack_interrupt, | 1345 | .ack_interrupt = dp83640_ack_interrupt, |
diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c index bb88bc7d81fb..9367acc84fbb 100644 --- a/drivers/net/phy/mdio-sun4i.c +++ b/drivers/net/phy/mdio-sun4i.c | |||
@@ -170,6 +170,9 @@ static int sun4i_mdio_remove(struct platform_device *pdev) | |||
170 | } | 170 | } |
171 | 171 | ||
172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { | 172 | static const struct of_device_id sun4i_mdio_dt_ids[] = { |
173 | { .compatible = "allwinner,sun4i-a10-mdio" }, | ||
174 | |||
175 | /* Deprecated */ | ||
173 | { .compatible = "allwinner,sun4i-mdio" }, | 176 | { .compatible = "allwinner,sun4i-mdio" }, |
174 | { } | 177 | { } |
175 | }; | 178 | }; |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 19c9eca0ef26..76d96b9ebcdb 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -164,9 +164,9 @@ static const struct phy_setting settings[] = { | |||
164 | * of that setting. Returns the index of the last setting if | 164 | * of that setting. Returns the index of the last setting if |
165 | * none of the others match. | 165 | * none of the others match. |
166 | */ | 166 | */ |
167 | static inline int phy_find_setting(int speed, int duplex) | 167 | static inline unsigned int phy_find_setting(int speed, int duplex) |
168 | { | 168 | { |
169 | int idx = 0; | 169 | unsigned int idx = 0; |
170 | 170 | ||
171 | while (idx < ARRAY_SIZE(settings) && | 171 | while (idx < ARRAY_SIZE(settings) && |
172 | (settings[idx].speed != speed || settings[idx].duplex != duplex)) | 172 | (settings[idx].speed != speed || settings[idx].duplex != duplex)) |
@@ -185,7 +185,7 @@ static inline int phy_find_setting(int speed, int duplex) | |||
185 | * the mask in features. Returns the index of the last setting | 185 | * the mask in features. Returns the index of the last setting |
186 | * if nothing else matches. | 186 | * if nothing else matches. |
187 | */ | 187 | */ |
188 | static inline int phy_find_valid(int idx, u32 features) | 188 | static inline unsigned int phy_find_valid(unsigned int idx, u32 features) |
189 | { | 189 | { |
190 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) | 190 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) |
191 | idx++; | 191 | idx++; |
@@ -204,7 +204,7 @@ static inline int phy_find_valid(int idx, u32 features) | |||
204 | static void phy_sanitize_settings(struct phy_device *phydev) | 204 | static void phy_sanitize_settings(struct phy_device *phydev) |
205 | { | 205 | { |
206 | u32 features = phydev->supported; | 206 | u32 features = phydev->supported; |
207 | int idx; | 207 | unsigned int idx; |
208 | 208 | ||
209 | /* Sanitize settings based on PHY capabilities */ | 209 | /* Sanitize settings based on PHY capabilities */ |
210 | if ((features & SUPPORTED_Autoneg) == 0) | 210 | if ((features & SUPPORTED_Autoneg) == 0) |
@@ -954,7 +954,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | |||
954 | (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { | 954 | (phydev->interface == PHY_INTERFACE_MODE_RGMII))) { |
955 | int eee_lp, eee_cap, eee_adv; | 955 | int eee_lp, eee_cap, eee_adv; |
956 | u32 lp, cap, adv; | 956 | u32 lp, cap, adv; |
957 | int idx, status; | 957 | int status; |
958 | unsigned int idx; | ||
958 | 959 | ||
959 | /* Read phy status to properly get the right settings */ | 960 | /* Read phy status to properly get the right settings */ |
960 | status = phy_read_status(phydev); | 961 | status = phy_read_status(phydev); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 4b03e63639b7..2f6989b1e0dc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -683,10 +683,9 @@ EXPORT_SYMBOL(phy_detach); | |||
683 | int phy_suspend(struct phy_device *phydev) | 683 | int phy_suspend(struct phy_device *phydev) |
684 | { | 684 | { |
685 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); | 685 | struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver); |
686 | struct ethtool_wolinfo wol; | 686 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
687 | 687 | ||
688 | /* If the device has WOL enabled, we cannot suspend the PHY */ | 688 | /* If the device has WOL enabled, we cannot suspend the PHY */ |
689 | wol.cmd = ETHTOOL_GWOL; | ||
690 | phy_ethtool_get_wol(phydev, &wol); | 689 | phy_ethtool_get_wol(phydev, &wol); |
691 | if (wol.wolopts) | 690 | if (wol.wolopts) |
692 | return -EBUSY; | 691 | return -EBUSY; |
@@ -719,7 +718,7 @@ int phy_resume(struct phy_device *phydev) | |||
719 | static int genphy_config_advert(struct phy_device *phydev) | 718 | static int genphy_config_advert(struct phy_device *phydev) |
720 | { | 719 | { |
721 | u32 advertise; | 720 | u32 advertise; |
722 | int oldadv, adv; | 721 | int oldadv, adv, bmsr; |
723 | int err, changed = 0; | 722 | int err, changed = 0; |
724 | 723 | ||
725 | /* Only allow advertising what this PHY supports */ | 724 | /* Only allow advertising what this PHY supports */ |
@@ -744,26 +743,36 @@ static int genphy_config_advert(struct phy_device *phydev) | |||
744 | changed = 1; | 743 | changed = 1; |
745 | } | 744 | } |
746 | 745 | ||
746 | bmsr = phy_read(phydev, MII_BMSR); | ||
747 | if (bmsr < 0) | ||
748 | return bmsr; | ||
749 | |||
750 | /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all | ||
751 | * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a | ||
752 | * logical 1. | ||
753 | */ | ||
754 | if (!(bmsr & BMSR_ESTATEN)) | ||
755 | return changed; | ||
756 | |||
747 | /* Configure gigabit if it's supported */ | 757 | /* Configure gigabit if it's supported */ |
758 | adv = phy_read(phydev, MII_CTRL1000); | ||
759 | if (adv < 0) | ||
760 | return adv; | ||
761 | |||
762 | oldadv = adv; | ||
763 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
764 | |||
748 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | 765 | if (phydev->supported & (SUPPORTED_1000baseT_Half | |
749 | SUPPORTED_1000baseT_Full)) { | 766 | SUPPORTED_1000baseT_Full)) { |
750 | adv = phy_read(phydev, MII_CTRL1000); | ||
751 | if (adv < 0) | ||
752 | return adv; | ||
753 | |||
754 | oldadv = adv; | ||
755 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
756 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | 767 | adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); |
757 | 768 | if (adv != oldadv) | |
758 | if (adv != oldadv) { | ||
759 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
760 | |||
761 | if (err < 0) | ||
762 | return err; | ||
763 | changed = 1; | 769 | changed = 1; |
764 | } | ||
765 | } | 770 | } |
766 | 771 | ||
772 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
773 | if (err < 0) | ||
774 | return err; | ||
775 | |||
767 | return changed; | 776 | return changed; |
768 | } | 777 | } |
769 | 778 | ||
@@ -906,6 +915,8 @@ int genphy_read_status(struct phy_device *phydev) | |||
906 | int err; | 915 | int err; |
907 | int lpa; | 916 | int lpa; |
908 | int lpagb = 0; | 917 | int lpagb = 0; |
918 | int common_adv; | ||
919 | int common_adv_gb = 0; | ||
909 | 920 | ||
910 | /* Update the link, but return if there was an error */ | 921 | /* Update the link, but return if there was an error */ |
911 | err = genphy_update_link(phydev); | 922 | err = genphy_update_link(phydev); |
@@ -927,7 +938,7 @@ int genphy_read_status(struct phy_device *phydev) | |||
927 | 938 | ||
928 | phydev->lp_advertising = | 939 | phydev->lp_advertising = |
929 | mii_stat1000_to_ethtool_lpa_t(lpagb); | 940 | mii_stat1000_to_ethtool_lpa_t(lpagb); |
930 | lpagb &= adv << 2; | 941 | common_adv_gb = lpagb & adv << 2; |
931 | } | 942 | } |
932 | 943 | ||
933 | lpa = phy_read(phydev, MII_LPA); | 944 | lpa = phy_read(phydev, MII_LPA); |
@@ -940,25 +951,25 @@ int genphy_read_status(struct phy_device *phydev) | |||
940 | if (adv < 0) | 951 | if (adv < 0) |
941 | return adv; | 952 | return adv; |
942 | 953 | ||
943 | lpa &= adv; | 954 | common_adv = lpa & adv; |
944 | 955 | ||
945 | phydev->speed = SPEED_10; | 956 | phydev->speed = SPEED_10; |
946 | phydev->duplex = DUPLEX_HALF; | 957 | phydev->duplex = DUPLEX_HALF; |
947 | phydev->pause = 0; | 958 | phydev->pause = 0; |
948 | phydev->asym_pause = 0; | 959 | phydev->asym_pause = 0; |
949 | 960 | ||
950 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | 961 | if (common_adv_gb & (LPA_1000FULL | LPA_1000HALF)) { |
951 | phydev->speed = SPEED_1000; | 962 | phydev->speed = SPEED_1000; |
952 | 963 | ||
953 | if (lpagb & LPA_1000FULL) | 964 | if (common_adv_gb & LPA_1000FULL) |
954 | phydev->duplex = DUPLEX_FULL; | 965 | phydev->duplex = DUPLEX_FULL; |
955 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | 966 | } else if (common_adv & (LPA_100FULL | LPA_100HALF)) { |
956 | phydev->speed = SPEED_100; | 967 | phydev->speed = SPEED_100; |
957 | 968 | ||
958 | if (lpa & LPA_100FULL) | 969 | if (common_adv & LPA_100FULL) |
959 | phydev->duplex = DUPLEX_FULL; | 970 | phydev->duplex = DUPLEX_FULL; |
960 | } else | 971 | } else |
961 | if (lpa & LPA_10FULL) | 972 | if (common_adv & LPA_10FULL) |
962 | phydev->duplex = DUPLEX_FULL; | 973 | phydev->duplex = DUPLEX_FULL; |
963 | 974 | ||
964 | if (phydev->duplex == DUPLEX_FULL) { | 975 | if (phydev->duplex == DUPLEX_FULL) { |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 28407426fd6f..c8624a8235ab 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -1648,7 +1648,7 @@ static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, | 1650 | static u16 team_select_queue(struct net_device *dev, struct sk_buff *skb, |
1651 | void *accel_priv) | 1651 | void *accel_priv, select_queue_fallback_t fallback) |
1652 | { | 1652 | { |
1653 | /* | 1653 | /* |
1654 | * This helper function exists to help dev_pick_tx get the correct | 1654 | * This helper function exists to help dev_pick_tx get the correct |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 44c4db8450f0..26f8635b027d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -366,7 +366,7 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) | |||
366 | * hope the rxq no. may help here. | 366 | * hope the rxq no. may help here. |
367 | */ | 367 | */ |
368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, | 368 | static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, |
369 | void *accel_priv) | 369 | void *accel_priv, select_queue_fallback_t fallback) |
370 | { | 370 | { |
371 | struct tun_struct *tun = netdev_priv(dev); | 371 | struct tun_struct *tun = netdev_priv(dev); |
372 | struct tun_flow_entry *e; | 372 | struct tun_flow_entry *e; |
@@ -1686,7 +1686,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1686 | TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | | 1686 | TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | |
1687 | NETIF_F_HW_VLAN_STAG_TX; | 1687 | NETIF_F_HW_VLAN_STAG_TX; |
1688 | dev->features = dev->hw_features; | 1688 | dev->features = dev->hw_features; |
1689 | dev->vlan_features = dev->features; | 1689 | dev->vlan_features = dev->features & |
1690 | ~(NETIF_F_HW_VLAN_CTAG_TX | | ||
1691 | NETIF_F_HW_VLAN_STAG_TX); | ||
1690 | 1692 | ||
1691 | INIT_LIST_HEAD(&tun->disabled); | 1693 | INIT_LIST_HEAD(&tun->disabled); |
1692 | err = tun_attach(tun, file, false); | 1694 | err = tun_attach(tun, file, false); |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6b638a066c1d..7e7269fd3707 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -292,6 +292,21 @@ config USB_NET_SR9700 | |||
292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 | 292 | This option adds support for CoreChip-sz SR9700 based USB 1.1 |
293 | 10/100 Ethernet adapters. | 293 | 10/100 Ethernet adapters. |
294 | 294 | ||
295 | config USB_NET_SR9800 | ||
296 | tristate "CoreChip-sz SR9800 based USB 2.0 10/100 ethernet devices" | ||
297 | depends on USB_USBNET | ||
298 | select CRC32 | ||
299 | ---help--- | ||
300 | Say Y if you want to use one of the following 100Mbps USB Ethernet | ||
301 | device based on the CoreChip-sz SR9800 chip. | ||
302 | |||
303 | This driver makes the adapter appear as a normal Ethernet interface, | ||
304 | typically on eth0, if it is the only ethernet device, or perhaps on | ||
305 | eth1, if you have a PCI or ISA ethernet card installed. | ||
306 | |||
307 | To compile this driver as a module, choose M here: the | ||
308 | module will be called sr9800. | ||
309 | |||
295 | config USB_NET_SMSC75XX | 310 | config USB_NET_SMSC75XX |
296 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" | 311 | tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices" |
297 | depends on USB_USBNET | 312 | depends on USB_USBNET |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b17b5e88bbaf..e2797f1e1b31 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -11,10 +11,11 @@ obj-$(CONFIG_USB_HSO) += hso.o | |||
11 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o | 11 | obj-$(CONFIG_USB_NET_AX8817X) += asix.o |
12 | asix-y := asix_devices.o asix_common.o ax88172a.o | 12 | asix-y := asix_devices.o asix_common.o ax88172a.o |
13 | obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o | 13 | obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o |
14 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o | 14 | obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o |
15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o | 15 | obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o |
16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o | 16 | obj-$(CONFIG_USB_NET_DM9601) += dm9601.o |
17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o | 17 | obj-$(CONFIG_USB_NET_SR9700) += sr9700.o |
18 | obj-$(CONFIG_USB_NET_SR9800) += sr9800.o | ||
18 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o | 19 | obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o |
19 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o | 20 | obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o |
20 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o | 21 | obj-$(CONFIG_USB_NET_GL620A) += gl620a.o |
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 9765a7d4766d..5d194093f3e1 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c | |||
@@ -917,7 +917,8 @@ static const struct driver_info ax88178_info = { | |||
917 | .status = asix_status, | 917 | .status = asix_status, |
918 | .link_reset = ax88178_link_reset, | 918 | .link_reset = ax88178_link_reset, |
919 | .reset = ax88178_reset, | 919 | .reset = ax88178_reset, |
920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR, | 920 | .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | |
921 | FLAG_MULTI_PACKET, | ||
921 | .rx_fixup = asix_rx_fixup_common, | 922 | .rx_fixup = asix_rx_fixup_common, |
922 | .tx_fixup = asix_tx_fixup, | 923 | .tx_fixup = asix_tx_fixup, |
923 | }; | 924 | }; |
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index d6f64dad05bc..054e59ca6946 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c | |||
@@ -1029,20 +1029,12 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1029 | dev->mii.phy_id = 0x03; | 1029 | dev->mii.phy_id = 0x03; |
1030 | dev->mii.supports_gmii = 1; | 1030 | dev->mii.supports_gmii = 1; |
1031 | 1031 | ||
1032 | if (usb_device_no_sg_constraint(dev->udev)) | ||
1033 | dev->can_dma_sg = 1; | ||
1034 | |||
1035 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1032 | dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
1036 | NETIF_F_RXCSUM; | 1033 | NETIF_F_RXCSUM; |
1037 | 1034 | ||
1038 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | 1035 | dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | |
1039 | NETIF_F_RXCSUM; | 1036 | NETIF_F_RXCSUM; |
1040 | 1037 | ||
1041 | if (dev->can_dma_sg) { | ||
1042 | dev->net->features |= NETIF_F_SG | NETIF_F_TSO; | ||
1043 | dev->net->hw_features |= NETIF_F_SG | NETIF_F_TSO; | ||
1044 | } | ||
1045 | |||
1046 | /* Enable checksum offload */ | 1038 | /* Enable checksum offload */ |
1047 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | | 1039 | *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | |
1048 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; | 1040 | AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; |
@@ -1118,6 +1110,10 @@ static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
1118 | u16 hdr_off; | 1110 | u16 hdr_off; |
1119 | u32 *pkt_hdr; | 1111 | u32 *pkt_hdr; |
1120 | 1112 | ||
1113 | /* This check is no longer done by usbnet */ | ||
1114 | if (skb->len < dev->net->hard_header_len) | ||
1115 | return 0; | ||
1116 | |||
1121 | skb_trim(skb, skb->len - 4); | 1117 | skb_trim(skb, skb->len - 4); |
1122 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); | 1118 | memcpy(&rx_hdr, skb_tail_pointer(skb), 4); |
1123 | le32_to_cpus(&rx_hdr); | 1119 | le32_to_cpus(&rx_hdr); |
@@ -1391,6 +1387,19 @@ static const struct driver_info ax88178a_info = { | |||
1391 | .tx_fixup = ax88179_tx_fixup, | 1387 | .tx_fixup = ax88179_tx_fixup, |
1392 | }; | 1388 | }; |
1393 | 1389 | ||
1390 | static const struct driver_info dlink_dub1312_info = { | ||
1391 | .description = "D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter", | ||
1392 | .bind = ax88179_bind, | ||
1393 | .unbind = ax88179_unbind, | ||
1394 | .status = ax88179_status, | ||
1395 | .link_reset = ax88179_link_reset, | ||
1396 | .reset = ax88179_reset, | ||
1397 | .stop = ax88179_stop, | ||
1398 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
1399 | .rx_fixup = ax88179_rx_fixup, | ||
1400 | .tx_fixup = ax88179_tx_fixup, | ||
1401 | }; | ||
1402 | |||
1394 | static const struct driver_info sitecom_info = { | 1403 | static const struct driver_info sitecom_info = { |
1395 | .description = "Sitecom USB 3.0 to Gigabit Adapter", | 1404 | .description = "Sitecom USB 3.0 to Gigabit Adapter", |
1396 | .bind = ax88179_bind, | 1405 | .bind = ax88179_bind, |
@@ -1417,6 +1426,19 @@ static const struct driver_info samsung_info = { | |||
1417 | .tx_fixup = ax88179_tx_fixup, | 1426 | .tx_fixup = ax88179_tx_fixup, |
1418 | }; | 1427 | }; |
1419 | 1428 | ||
1429 | static const struct driver_info lenovo_info = { | ||
1430 | .description = "Lenovo OneLinkDock Gigabit LAN", | ||
1431 | .bind = ax88179_bind, | ||
1432 | .unbind = ax88179_unbind, | ||
1433 | .status = ax88179_status, | ||
1434 | .link_reset = ax88179_link_reset, | ||
1435 | .reset = ax88179_reset, | ||
1436 | .stop = ax88179_stop, | ||
1437 | .flags = FLAG_ETHER | FLAG_FRAMING_AX, | ||
1438 | .rx_fixup = ax88179_rx_fixup, | ||
1439 | .tx_fixup = ax88179_tx_fixup, | ||
1440 | }; | ||
1441 | |||
1420 | static const struct usb_device_id products[] = { | 1442 | static const struct usb_device_id products[] = { |
1421 | { | 1443 | { |
1422 | /* ASIX AX88179 10/100/1000 */ | 1444 | /* ASIX AX88179 10/100/1000 */ |
@@ -1427,6 +1449,10 @@ static const struct usb_device_id products[] = { | |||
1427 | USB_DEVICE(0x0b95, 0x178a), | 1449 | USB_DEVICE(0x0b95, 0x178a), |
1428 | .driver_info = (unsigned long)&ax88178a_info, | 1450 | .driver_info = (unsigned long)&ax88178a_info, |
1429 | }, { | 1451 | }, { |
1452 | /* D-Link DUB-1312 USB 3.0 to Gigabit Ethernet Adapter */ | ||
1453 | USB_DEVICE(0x2001, 0x4a00), | ||
1454 | .driver_info = (unsigned long)&dlink_dub1312_info, | ||
1455 | }, { | ||
1430 | /* Sitecom USB 3.0 to Gigabit Adapter */ | 1456 | /* Sitecom USB 3.0 to Gigabit Adapter */ |
1431 | USB_DEVICE(0x0df6, 0x0072), | 1457 | USB_DEVICE(0x0df6, 0x0072), |
1432 | .driver_info = (unsigned long)&sitecom_info, | 1458 | .driver_info = (unsigned long)&sitecom_info, |
@@ -1434,6 +1460,10 @@ static const struct usb_device_id products[] = { | |||
1434 | /* Samsung USB Ethernet Adapter */ | 1460 | /* Samsung USB Ethernet Adapter */ |
1435 | USB_DEVICE(0x04e8, 0xa100), | 1461 | USB_DEVICE(0x04e8, 0xa100), |
1436 | .driver_info = (unsigned long)&samsung_info, | 1462 | .driver_info = (unsigned long)&samsung_info, |
1463 | }, { | ||
1464 | /* Lenovo OneLinkDock Gigabit LAN */ | ||
1465 | USB_DEVICE(0x17ef, 0x304b), | ||
1466 | .driver_info = (unsigned long)&lenovo_info, | ||
1437 | }, | 1467 | }, |
1438 | { }, | 1468 | { }, |
1439 | }; | 1469 | }; |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 42e176912c8e..bd363b27e854 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -652,6 +652,13 @@ static const struct usb_device_id products[] = { | |||
652 | .driver_info = 0, | 652 | .driver_info = 0, |
653 | }, | 653 | }, |
654 | 654 | ||
655 | /* Samsung USB Ethernet Adapters */ | ||
656 | { | ||
657 | USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, 0xa101, USB_CLASS_COMM, | ||
658 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
659 | .driver_info = 0, | ||
660 | }, | ||
661 | |||
655 | /* WHITELIST!!! | 662 | /* WHITELIST!!! |
656 | * | 663 | * |
657 | * CDC Ether uses two interfaces, not necessarily consecutive. | 664 | * CDC Ether uses two interfaces, not necessarily consecutive. |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index dbff290ed0e4..d350d2795e10 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -68,7 +68,6 @@ static struct usb_driver cdc_ncm_driver; | |||
68 | static int cdc_ncm_setup(struct usbnet *dev) | 68 | static int cdc_ncm_setup(struct usbnet *dev) |
69 | { | 69 | { |
70 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; | 70 | struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; |
71 | struct usb_cdc_ncm_ntb_parameters ncm_parm; | ||
72 | u32 val; | 71 | u32 val; |
73 | u8 flags; | 72 | u8 flags; |
74 | u8 iface_no; | 73 | u8 iface_no; |
@@ -82,22 +81,22 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
82 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, | 81 | err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_PARAMETERS, |
83 | USB_TYPE_CLASS | USB_DIR_IN | 82 | USB_TYPE_CLASS | USB_DIR_IN |
84 | |USB_RECIP_INTERFACE, | 83 | |USB_RECIP_INTERFACE, |
85 | 0, iface_no, &ncm_parm, | 84 | 0, iface_no, &ctx->ncm_parm, |
86 | sizeof(ncm_parm)); | 85 | sizeof(ctx->ncm_parm)); |
87 | if (err < 0) { | 86 | if (err < 0) { |
88 | dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n"); | 87 | dev_err(&dev->intf->dev, "failed GET_NTB_PARAMETERS\n"); |
89 | return err; /* GET_NTB_PARAMETERS is required */ | 88 | return err; /* GET_NTB_PARAMETERS is required */ |
90 | } | 89 | } |
91 | 90 | ||
92 | /* read correct set of parameters according to device mode */ | 91 | /* read correct set of parameters according to device mode */ |
93 | ctx->rx_max = le32_to_cpu(ncm_parm.dwNtbInMaxSize); | 92 | ctx->rx_max = le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize); |
94 | ctx->tx_max = le32_to_cpu(ncm_parm.dwNtbOutMaxSize); | 93 | ctx->tx_max = le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize); |
95 | ctx->tx_remainder = le16_to_cpu(ncm_parm.wNdpOutPayloadRemainder); | 94 | ctx->tx_remainder = le16_to_cpu(ctx->ncm_parm.wNdpOutPayloadRemainder); |
96 | ctx->tx_modulus = le16_to_cpu(ncm_parm.wNdpOutDivisor); | 95 | ctx->tx_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutDivisor); |
97 | ctx->tx_ndp_modulus = le16_to_cpu(ncm_parm.wNdpOutAlignment); | 96 | ctx->tx_ndp_modulus = le16_to_cpu(ctx->ncm_parm.wNdpOutAlignment); |
98 | /* devices prior to NCM Errata shall set this field to zero */ | 97 | /* devices prior to NCM Errata shall set this field to zero */ |
99 | ctx->tx_max_datagrams = le16_to_cpu(ncm_parm.wNtbOutMaxDatagrams); | 98 | ctx->tx_max_datagrams = le16_to_cpu(ctx->ncm_parm.wNtbOutMaxDatagrams); |
100 | ntb_fmt_supported = le16_to_cpu(ncm_parm.bmNtbFormatsSupported); | 99 | ntb_fmt_supported = le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported); |
101 | 100 | ||
102 | /* there are some minor differences in NCM and MBIM defaults */ | 101 | /* there are some minor differences in NCM and MBIM defaults */ |
103 | if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) { | 102 | if (cdc_ncm_comm_intf_is_mbim(ctx->control->cur_altsetting)) { |
@@ -146,7 +145,7 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
146 | } | 145 | } |
147 | 146 | ||
148 | /* inform device about NTB input size changes */ | 147 | /* inform device about NTB input size changes */ |
149 | if (ctx->rx_max != le32_to_cpu(ncm_parm.dwNtbInMaxSize)) { | 148 | if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { |
150 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); | 149 | __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); |
151 | 150 | ||
152 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, | 151 | err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_INPUT_SIZE, |
@@ -162,14 +161,6 @@ static int cdc_ncm_setup(struct usbnet *dev) | |||
162 | dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n", | 161 | dev_dbg(&dev->intf->dev, "Using default maximum transmit length=%d\n", |
163 | CDC_NCM_NTB_MAX_SIZE_TX); | 162 | CDC_NCM_NTB_MAX_SIZE_TX); |
164 | ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; | 163 | ctx->tx_max = CDC_NCM_NTB_MAX_SIZE_TX; |
165 | |||
166 | /* Adding a pad byte here simplifies the handling in | ||
167 | * cdc_ncm_fill_tx_frame, by making tx_max always | ||
168 | * represent the real skb max size. | ||
169 | */ | ||
170 | if (ctx->tx_max % usb_maxpacket(dev->udev, dev->out, 1) == 0) | ||
171 | ctx->tx_max++; | ||
172 | |||
173 | } | 164 | } |
174 | 165 | ||
175 | /* | 166 | /* |
@@ -439,6 +430,10 @@ advance: | |||
439 | goto error2; | 430 | goto error2; |
440 | } | 431 | } |
441 | 432 | ||
433 | /* initialize data interface */ | ||
434 | if (cdc_ncm_setup(dev)) | ||
435 | goto error2; | ||
436 | |||
442 | /* configure data interface */ | 437 | /* configure data interface */ |
443 | temp = usb_set_interface(dev->udev, iface_no, data_altsetting); | 438 | temp = usb_set_interface(dev->udev, iface_no, data_altsetting); |
444 | if (temp) { | 439 | if (temp) { |
@@ -453,12 +448,6 @@ advance: | |||
453 | goto error2; | 448 | goto error2; |
454 | } | 449 | } |
455 | 450 | ||
456 | /* initialize data interface */ | ||
457 | if (cdc_ncm_setup(dev)) { | ||
458 | dev_dbg(&intf->dev, "cdc_ncm_setup() failed\n"); | ||
459 | goto error2; | ||
460 | } | ||
461 | |||
462 | usb_set_intfdata(ctx->data, dev); | 451 | usb_set_intfdata(ctx->data, dev); |
463 | usb_set_intfdata(ctx->control, dev); | 452 | usb_set_intfdata(ctx->control, dev); |
464 | 453 | ||
@@ -475,6 +464,15 @@ advance: | |||
475 | dev->hard_mtu = ctx->tx_max; | 464 | dev->hard_mtu = ctx->tx_max; |
476 | dev->rx_urb_size = ctx->rx_max; | 465 | dev->rx_urb_size = ctx->rx_max; |
477 | 466 | ||
467 | /* cdc_ncm_setup will override dwNtbOutMaxSize if it is | ||
468 | * outside the sane range. Adding a pad byte here if necessary | ||
469 | * simplifies the handling in cdc_ncm_fill_tx_frame, making | ||
470 | * tx_max always represent the real skb max size. | ||
471 | */ | ||
472 | if (ctx->tx_max != le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) && | ||
473 | ctx->tx_max % usb_maxpacket(dev->udev, dev->out, 1) == 0) | ||
474 | ctx->tx_max++; | ||
475 | |||
478 | return 0; | 476 | return 0; |
479 | 477 | ||
480 | error2: | 478 | error2: |
diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index e4a8a93fbaf7..1cc24e6f23e2 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c | |||
@@ -84,6 +84,10 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
84 | u32 size; | 84 | u32 size; |
85 | u32 count; | 85 | u32 count; |
86 | 86 | ||
87 | /* This check is no longer done by usbnet */ | ||
88 | if (skb->len < dev->net->hard_header_len) | ||
89 | return 0; | ||
90 | |||
87 | header = (struct gl_header *) skb->data; | 91 | header = (struct gl_header *) skb->data; |
88 | 92 | ||
89 | // get the packet count of the received skb | 93 | // get the packet count of the received skb |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1a482344b3f5..660bd5ea9fc0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1201,16 +1201,18 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1201 | struct hso_serial *serial = urb->context; | 1201 | struct hso_serial *serial = urb->context; |
1202 | int status = urb->status; | 1202 | int status = urb->status; |
1203 | 1203 | ||
1204 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
1205 | |||
1204 | /* sanity check */ | 1206 | /* sanity check */ |
1205 | if (!serial) { | 1207 | if (!serial) { |
1206 | D1("serial == NULL"); | 1208 | D1("serial == NULL"); |
1207 | return; | 1209 | return; |
1208 | } else if (status) { | 1210 | } |
1211 | if (status) { | ||
1209 | handle_usb_error(status, __func__, serial->parent); | 1212 | handle_usb_error(status, __func__, serial->parent); |
1210 | return; | 1213 | return; |
1211 | } | 1214 | } |
1212 | 1215 | ||
1213 | D4("\n--- Got serial_read_bulk callback %02x ---", status); | ||
1214 | D1("Actual length = %d\n", urb->actual_length); | 1216 | D1("Actual length = %d\n", urb->actual_length); |
1215 | DUMP1(urb->transfer_buffer, urb->actual_length); | 1217 | DUMP1(urb->transfer_buffer, urb->actual_length); |
1216 | 1218 | ||
@@ -1218,25 +1220,13 @@ static void hso_std_serial_read_bulk_callback(struct urb *urb) | |||
1218 | if (serial->port.count == 0) | 1220 | if (serial->port.count == 0) |
1219 | return; | 1221 | return; |
1220 | 1222 | ||
1221 | if (status == 0) { | 1223 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) |
1222 | if (serial->parent->port_spec & HSO_INFO_CRC_BUG) | 1224 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); |
1223 | fix_crc_bug(urb, serial->in_endp->wMaxPacketSize); | 1225 | /* Valid data, handle RX data */ |
1224 | /* Valid data, handle RX data */ | 1226 | spin_lock(&serial->serial_lock); |
1225 | spin_lock(&serial->serial_lock); | 1227 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; |
1226 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; | 1228 | put_rxbuf_data_and_resubmit_bulk_urb(serial); |
1227 | put_rxbuf_data_and_resubmit_bulk_urb(serial); | 1229 | spin_unlock(&serial->serial_lock); |
1228 | spin_unlock(&serial->serial_lock); | ||
1229 | } else if (status == -ENOENT || status == -ECONNRESET) { | ||
1230 | /* Unlinked - check for throttled port. */ | ||
1231 | D2("Port %d, successfully unlinked urb", serial->minor); | ||
1232 | spin_lock(&serial->serial_lock); | ||
1233 | serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; | ||
1234 | hso_resubmit_rx_bulk_urb(serial, urb); | ||
1235 | spin_unlock(&serial->serial_lock); | ||
1236 | } else { | ||
1237 | D2("Port %d, status = %d for read urb", serial->minor, status); | ||
1238 | return; | ||
1239 | } | ||
1240 | } | 1230 | } |
1241 | 1231 | ||
1242 | /* | 1232 | /* |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a305a7b2dae6..82d844a8ebd0 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -526,8 +526,9 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
526 | { | 526 | { |
527 | u8 status; | 527 | u8 status; |
528 | 528 | ||
529 | if (skb->len == 0) { | 529 | /* This check is no longer done by usbnet */ |
530 | dev_err(&dev->udev->dev, "unexpected empty rx frame\n"); | 530 | if (skb->len < dev->net->hard_header_len) { |
531 | dev_err(&dev->udev->dev, "unexpected tiny rx frame\n"); | ||
531 | return 0; | 532 | return 0; |
532 | } | 533 | } |
533 | 534 | ||
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index 0a85d9227775..4cbdb1307f3e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c | |||
@@ -364,6 +364,10 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
364 | struct nc_trailer *trailer; | 364 | struct nc_trailer *trailer; |
365 | u16 hdr_len, packet_len; | 365 | u16 hdr_len, packet_len; |
366 | 366 | ||
367 | /* This check is no longer done by usbnet */ | ||
368 | if (skb->len < dev->net->hard_header_len) | ||
369 | return 0; | ||
370 | |||
367 | if (!(skb->len & 0x01)) { | 371 | if (!(skb->len & 0x01)) { |
368 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", | 372 | netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", |
369 | skb->len, dev->net->hard_header_len, dev->hard_mtu, | 373 | skb->len, dev->net->hard_header_len, dev->hard_mtu, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 23bdd5b9274d..313cb6cd4848 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -80,10 +80,10 @@ static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
80 | { | 80 | { |
81 | __be16 proto; | 81 | __be16 proto; |
82 | 82 | ||
83 | /* usbnet rx_complete guarantees that skb->len is at least | 83 | /* This check is no longer done by usbnet */ |
84 | * hard_header_len, so we can inspect the dest address without | 84 | if (skb->len < dev->net->hard_header_len) |
85 | * checking skb->len | 85 | return 0; |
86 | */ | 86 | |
87 | switch (skb->data[0] & 0xf0) { | 87 | switch (skb->data[0] & 0xf0) { |
88 | case 0x40: | 88 | case 0x40: |
89 | proto = htons(ETH_P_IP); | 89 | proto = htons(ETH_P_IP); |
@@ -712,6 +712,7 @@ static const struct usb_device_id products[] = { | |||
712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, | 712 | {QMI_FIXED_INTF(0x19d2, 0x1255, 3)}, |
713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, | 713 | {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, |
714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, | 714 | {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, |
715 | {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ | ||
715 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, | 716 | {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, |
716 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | 717 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ |
717 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, | 718 | {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, |
@@ -723,6 +724,7 @@ static const struct usb_device_id products[] = { | |||
723 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
724 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 725 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
725 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 726 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
727 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | ||
726 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 728 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
727 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 729 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
728 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 730 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
@@ -730,6 +732,7 @@ static const struct usb_device_id products[] = { | |||
730 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 732 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
731 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 733 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
732 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 734 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
735 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | ||
733 | 736 | ||
734 | /* 4. Gobi 1000 devices */ | 737 | /* 4. Gobi 1000 devices */ |
735 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 738 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e8fac732c6f1..adb12f349a61 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -449,9 +449,6 @@ enum rtl8152_flags { | |||
449 | #define MCU_TYPE_PLA 0x0100 | 449 | #define MCU_TYPE_PLA 0x0100 |
450 | #define MCU_TYPE_USB 0x0000 | 450 | #define MCU_TYPE_USB 0x0000 |
451 | 451 | ||
452 | #define REALTEK_USB_DEVICE(vend, prod) \ | ||
453 | USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) | ||
454 | |||
455 | struct rx_desc { | 452 | struct rx_desc { |
456 | __le32 opts1; | 453 | __le32 opts1; |
457 | #define RX_LEN_MASK 0x7fff | 454 | #define RX_LEN_MASK 0x7fff |
@@ -2273,22 +2270,21 @@ static int rtl8152_open(struct net_device *netdev) | |||
2273 | struct r8152 *tp = netdev_priv(netdev); | 2270 | struct r8152 *tp = netdev_priv(netdev); |
2274 | int res = 0; | 2271 | int res = 0; |
2275 | 2272 | ||
2273 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
2274 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
2275 | DUPLEX_FULL); | ||
2276 | tp->speed = 0; | ||
2277 | netif_carrier_off(netdev); | ||
2278 | netif_start_queue(netdev); | ||
2279 | set_bit(WORK_ENABLE, &tp->flags); | ||
2276 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); | 2280 | res = usb_submit_urb(tp->intr_urb, GFP_KERNEL); |
2277 | if (res) { | 2281 | if (res) { |
2278 | if (res == -ENODEV) | 2282 | if (res == -ENODEV) |
2279 | netif_device_detach(tp->netdev); | 2283 | netif_device_detach(tp->netdev); |
2280 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", | 2284 | netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n", |
2281 | res); | 2285 | res); |
2282 | return res; | ||
2283 | } | 2286 | } |
2284 | 2287 | ||
2285 | rtl8152_set_speed(tp, AUTONEG_ENABLE, | ||
2286 | tp->mii.supports_gmii ? SPEED_1000 : SPEED_100, | ||
2287 | DUPLEX_FULL); | ||
2288 | tp->speed = 0; | ||
2289 | netif_carrier_off(netdev); | ||
2290 | netif_start_queue(netdev); | ||
2291 | set_bit(WORK_ENABLE, &tp->flags); | ||
2292 | 2288 | ||
2293 | return res; | 2289 | return res; |
2294 | } | 2290 | } |
@@ -2298,8 +2294,8 @@ static int rtl8152_close(struct net_device *netdev) | |||
2298 | struct r8152 *tp = netdev_priv(netdev); | 2294 | struct r8152 *tp = netdev_priv(netdev); |
2299 | int res = 0; | 2295 | int res = 0; |
2300 | 2296 | ||
2301 | usb_kill_urb(tp->intr_urb); | ||
2302 | clear_bit(WORK_ENABLE, &tp->flags); | 2297 | clear_bit(WORK_ENABLE, &tp->flags); |
2298 | usb_kill_urb(tp->intr_urb); | ||
2303 | cancel_delayed_work_sync(&tp->schedule); | 2299 | cancel_delayed_work_sync(&tp->schedule); |
2304 | netif_stop_queue(netdev); | 2300 | netif_stop_queue(netdev); |
2305 | tasklet_disable(&tp->tl); | 2301 | tasklet_disable(&tp->tl); |
@@ -2740,6 +2736,12 @@ static int rtl8152_probe(struct usb_interface *intf, | |||
2740 | struct net_device *netdev; | 2736 | struct net_device *netdev; |
2741 | int ret; | 2737 | int ret; |
2742 | 2738 | ||
2739 | if (udev->actconfig->desc.bConfigurationValue != 1) { | ||
2740 | usb_driver_set_configuration(udev, 1); | ||
2741 | return -ENODEV; | ||
2742 | } | ||
2743 | |||
2744 | usb_reset_device(udev); | ||
2743 | netdev = alloc_etherdev(sizeof(struct r8152)); | 2745 | netdev = alloc_etherdev(sizeof(struct r8152)); |
2744 | if (!netdev) { | 2746 | if (!netdev) { |
2745 | dev_err(&intf->dev, "Out of memory\n"); | 2747 | dev_err(&intf->dev, "Out of memory\n"); |
@@ -2820,9 +2822,9 @@ static void rtl8152_disconnect(struct usb_interface *intf) | |||
2820 | 2822 | ||
2821 | /* table of devices that work with this driver */ | 2823 | /* table of devices that work with this driver */ |
2822 | static struct usb_device_id rtl8152_table[] = { | 2824 | static struct usb_device_id rtl8152_table[] = { |
2823 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, | 2825 | {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8152)}, |
2824 | {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, | 2826 | {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8153)}, |
2825 | {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, | 2827 | {USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG)}, |
2826 | {} | 2828 | {} |
2827 | }; | 2829 | }; |
2828 | 2830 | ||
diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c deleted file mode 100644 index f0a8791b7636..000000000000 --- a/drivers/net/usb/r815x.c +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/netdevice.h> | ||
3 | #include <linux/mii.h> | ||
4 | #include <linux/usb.h> | ||
5 | #include <linux/usb/cdc.h> | ||
6 | #include <linux/usb/usbnet.h> | ||
7 | |||
8 | #define RTL815x_REQT_READ 0xc0 | ||
9 | #define RTL815x_REQT_WRITE 0x40 | ||
10 | #define RTL815x_REQ_GET_REGS 0x05 | ||
11 | #define RTL815x_REQ_SET_REGS 0x05 | ||
12 | |||
13 | #define MCU_TYPE_PLA 0x0100 | ||
14 | #define OCP_BASE 0xe86c | ||
15 | #define BASE_MII 0xa400 | ||
16 | |||
17 | #define BYTE_EN_DWORD 0xff | ||
18 | #define BYTE_EN_WORD 0x33 | ||
19 | #define BYTE_EN_BYTE 0x11 | ||
20 | |||
21 | #define R815x_PHY_ID 32 | ||
22 | #define REALTEK_VENDOR_ID 0x0bda | ||
23 | |||
24 | |||
25 | static int pla_read_word(struct usb_device *udev, u16 index) | ||
26 | { | ||
27 | int ret; | ||
28 | u8 shift = index & 2; | ||
29 | __le32 *tmp; | ||
30 | |||
31 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
32 | if (!tmp) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | index &= ~3; | ||
36 | |||
37 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
38 | RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, | ||
39 | index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); | ||
40 | if (ret < 0) | ||
41 | goto out2; | ||
42 | |||
43 | ret = __le32_to_cpu(*tmp); | ||
44 | ret >>= (shift * 8); | ||
45 | ret &= 0xffff; | ||
46 | |||
47 | out2: | ||
48 | kfree(tmp); | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | static int pla_write_word(struct usb_device *udev, u16 index, u32 data) | ||
53 | { | ||
54 | __le32 *tmp; | ||
55 | u32 mask = 0xffff; | ||
56 | u16 byen = BYTE_EN_WORD; | ||
57 | u8 shift = index & 2; | ||
58 | int ret; | ||
59 | |||
60 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
61 | if (!tmp) | ||
62 | return -ENOMEM; | ||
63 | |||
64 | data &= mask; | ||
65 | |||
66 | if (shift) { | ||
67 | byen <<= shift; | ||
68 | mask <<= (shift * 8); | ||
69 | data <<= (shift * 8); | ||
70 | index &= ~3; | ||
71 | } | ||
72 | |||
73 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
74 | RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, | ||
75 | index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); | ||
76 | if (ret < 0) | ||
77 | goto out3; | ||
78 | |||
79 | data |= __le32_to_cpu(*tmp) & ~mask; | ||
80 | *tmp = __cpu_to_le32(data); | ||
81 | |||
82 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
83 | RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, | ||
84 | index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), | ||
85 | 500); | ||
86 | |||
87 | out3: | ||
88 | kfree(tmp); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | static int ocp_reg_read(struct usbnet *dev, u16 addr) | ||
93 | { | ||
94 | u16 ocp_base, ocp_index; | ||
95 | int ret; | ||
96 | |||
97 | ocp_base = addr & 0xf000; | ||
98 | ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); | ||
99 | if (ret < 0) | ||
100 | goto out; | ||
101 | |||
102 | ocp_index = (addr & 0x0fff) | 0xb000; | ||
103 | ret = pla_read_word(dev->udev, ocp_index); | ||
104 | |||
105 | out: | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) | ||
110 | { | ||
111 | u16 ocp_base, ocp_index; | ||
112 | int ret; | ||
113 | |||
114 | ocp_base = addr & 0xf000; | ||
115 | ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); | ||
116 | if (ret < 0) | ||
117 | goto out1; | ||
118 | |||
119 | ocp_index = (addr & 0x0fff) | 0xb000; | ||
120 | ret = pla_write_word(dev->udev, ocp_index, data); | ||
121 | |||
122 | out1: | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) | ||
127 | { | ||
128 | struct usbnet *dev = netdev_priv(netdev); | ||
129 | int ret; | ||
130 | |||
131 | if (phy_id != R815x_PHY_ID) | ||
132 | return -EINVAL; | ||
133 | |||
134 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
135 | return -ENODEV; | ||
136 | |||
137 | ret = ocp_reg_read(dev, BASE_MII + reg * 2); | ||
138 | |||
139 | usb_autopm_put_interface(dev->intf); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static | ||
144 | void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) | ||
145 | { | ||
146 | struct usbnet *dev = netdev_priv(netdev); | ||
147 | |||
148 | if (phy_id != R815x_PHY_ID) | ||
149 | return; | ||
150 | |||
151 | if (usb_autopm_get_interface(dev->intf) < 0) | ||
152 | return; | ||
153 | |||
154 | ocp_reg_write(dev, BASE_MII + reg * 2, val); | ||
155 | |||
156 | usb_autopm_put_interface(dev->intf); | ||
157 | } | ||
158 | |||
159 | static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) | ||
160 | { | ||
161 | int status; | ||
162 | |||
163 | status = usbnet_cdc_bind(dev, intf); | ||
164 | if (status < 0) | ||
165 | return status; | ||
166 | |||
167 | dev->mii.dev = dev->net; | ||
168 | dev->mii.mdio_read = r815x_mdio_read; | ||
169 | dev->mii.mdio_write = r815x_mdio_write; | ||
170 | dev->mii.phy_id_mask = 0x3f; | ||
171 | dev->mii.reg_num_mask = 0x1f; | ||
172 | dev->mii.phy_id = R815x_PHY_ID; | ||
173 | dev->mii.supports_gmii = 1; | ||
174 | |||
175 | return status; | ||
176 | } | ||
177 | |||
178 | static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) | ||
179 | { | ||
180 | int status; | ||
181 | |||
182 | status = usbnet_cdc_bind(dev, intf); | ||
183 | if (status < 0) | ||
184 | return status; | ||
185 | |||
186 | dev->mii.dev = dev->net; | ||
187 | dev->mii.mdio_read = r815x_mdio_read; | ||
188 | dev->mii.mdio_write = r815x_mdio_write; | ||
189 | dev->mii.phy_id_mask = 0x3f; | ||
190 | dev->mii.reg_num_mask = 0x1f; | ||
191 | dev->mii.phy_id = R815x_PHY_ID; | ||
192 | dev->mii.supports_gmii = 0; | ||
193 | |||
194 | return status; | ||
195 | } | ||
196 | |||
197 | static const struct driver_info r8152_info = { | ||
198 | .description = "RTL8152 ECM Device", | ||
199 | .flags = FLAG_ETHER | FLAG_POINTTOPOINT, | ||
200 | .bind = r8152_bind, | ||
201 | .unbind = usbnet_cdc_unbind, | ||
202 | .status = usbnet_cdc_status, | ||
203 | .manage_power = usbnet_manage_power, | ||
204 | }; | ||
205 | |||
206 | static const struct driver_info r8153_info = { | ||
207 | .description = "RTL8153 ECM Device", | ||
208 | .flags = FLAG_ETHER | FLAG_POINTTOPOINT, | ||
209 | .bind = r8153_bind, | ||
210 | .unbind = usbnet_cdc_unbind, | ||
211 | .status = usbnet_cdc_status, | ||
212 | .manage_power = usbnet_manage_power, | ||
213 | }; | ||
214 | |||
215 | static const struct usb_device_id products[] = { | ||
216 | { | ||
217 | USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, | ||
218 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
219 | .driver_info = (unsigned long) &r8152_info, | ||
220 | }, | ||
221 | |||
222 | { | ||
223 | USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, | ||
224 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), | ||
225 | .driver_info = (unsigned long) &r8153_info, | ||
226 | }, | ||
227 | |||
228 | { }, /* END */ | ||
229 | }; | ||
230 | MODULE_DEVICE_TABLE(usb, products); | ||
231 | |||
232 | static struct usb_driver r815x_driver = { | ||
233 | .name = "r815x", | ||
234 | .id_table = products, | ||
235 | .probe = usbnet_probe, | ||
236 | .disconnect = usbnet_disconnect, | ||
237 | .suspend = usbnet_suspend, | ||
238 | .resume = usbnet_resume, | ||
239 | .reset_resume = usbnet_resume, | ||
240 | .supports_autosuspend = 1, | ||
241 | .disable_hub_initiated_lpm = 1, | ||
242 | }; | ||
243 | |||
244 | module_usb_driver(r815x_driver); | ||
245 | |||
246 | MODULE_AUTHOR("Hayes Wang"); | ||
247 | MODULE_DESCRIPTION("Realtek USB ECM device"); | ||
248 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index a48bc0f20c1a..524a47a28120 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c | |||
@@ -492,6 +492,10 @@ EXPORT_SYMBOL_GPL(rndis_unbind); | |||
492 | */ | 492 | */ |
493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 493 | int rndis_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
494 | { | 494 | { |
495 | /* This check is no longer done by usbnet */ | ||
496 | if (skb->len < dev->net->hard_header_len) | ||
497 | return 0; | ||
498 | |||
495 | /* peripheral may have batched packets to us... */ | 499 | /* peripheral may have batched packets to us... */ |
496 | while (likely(skb->len)) { | 500 | while (likely(skb->len)) { |
497 | struct rndis_data_hdr *hdr = (void *)skb->data; | 501 | struct rndis_data_hdr *hdr = (void *)skb->data; |
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index f17b9e02dd34..d9e7892262fa 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c | |||
@@ -2106,6 +2106,10 @@ static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb, | |||
2106 | 2106 | ||
2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 2107 | static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
2108 | { | 2108 | { |
2109 | /* This check is no longer done by usbnet */ | ||
2110 | if (skb->len < dev->net->hard_header_len) | ||
2111 | return 0; | ||
2112 | |||
2109 | while (skb->len > 0) { | 2113 | while (skb->len > 0) { |
2110 | u32 rx_cmd_a, rx_cmd_b, align_count, size; | 2114 | u32 rx_cmd_a, rx_cmd_b, align_count, size; |
2111 | struct sk_buff *ax_skb; | 2115 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 8dd54a0f7b29..424db65e4396 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -1723,6 +1723,10 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) | |||
1723 | 1723 | ||
1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 1724 | static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
1725 | { | 1725 | { |
1726 | /* This check is no longer done by usbnet */ | ||
1727 | if (skb->len < dev->net->hard_header_len) | ||
1728 | return 0; | ||
1729 | |||
1726 | while (skb->len > 0) { | 1730 | while (skb->len > 0) { |
1727 | u32 header, align_count; | 1731 | u32 header, align_count; |
1728 | struct sk_buff *ax_skb; | 1732 | struct sk_buff *ax_skb; |
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c new file mode 100644 index 000000000000..b94a0fbb8b3b --- /dev/null +++ b/drivers/net/usb/sr9800.c | |||
@@ -0,0 +1,874 @@ | |||
1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
2 | * | ||
3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
4 | * | ||
5 | * Based on asix_common.c, asix_devices.c | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public License | ||
8 | * version 2. This program is licensed "as is" without any warranty of any | ||
9 | * kind, whether express or implied.* | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kmod.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/ethtool.h> | ||
18 | #include <linux/workqueue.h> | ||
19 | #include <linux/mii.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <linux/usb/usbnet.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/if_vlan.h> | ||
25 | |||
26 | #include "sr9800.h" | ||
27 | |||
28 | static int sr_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
29 | u16 size, void *data) | ||
30 | { | ||
31 | int err; | ||
32 | |||
33 | err = usbnet_read_cmd(dev, cmd, SR_REQ_RD_REG, value, index, | ||
34 | data, size); | ||
35 | if ((err != size) && (err >= 0)) | ||
36 | err = -EINVAL; | ||
37 | |||
38 | return err; | ||
39 | } | ||
40 | |||
41 | static int sr_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
42 | u16 size, void *data) | ||
43 | { | ||
44 | int err; | ||
45 | |||
46 | err = usbnet_write_cmd(dev, cmd, SR_REQ_WR_REG, value, index, | ||
47 | data, size); | ||
48 | if ((err != size) && (err >= 0)) | ||
49 | err = -EINVAL; | ||
50 | |||
51 | return err; | ||
52 | } | ||
53 | |||
54 | static void | ||
55 | sr_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, | ||
56 | u16 size, void *data) | ||
57 | { | ||
58 | usbnet_write_cmd_async(dev, cmd, SR_REQ_WR_REG, value, index, data, | ||
59 | size); | ||
60 | } | ||
61 | |||
62 | static int sr_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | ||
63 | { | ||
64 | int offset = 0; | ||
65 | |||
66 | /* This check is no longer done by usbnet */ | ||
67 | if (skb->len < dev->net->hard_header_len) | ||
68 | return 0; | ||
69 | |||
70 | while (offset + sizeof(u32) < skb->len) { | ||
71 | struct sk_buff *sr_skb; | ||
72 | u16 size; | ||
73 | u32 header = get_unaligned_le32(skb->data + offset); | ||
74 | |||
75 | offset += sizeof(u32); | ||
76 | /* get the packet length */ | ||
77 | size = (u16) (header & 0x7ff); | ||
78 | if (size != ((~header >> 16) & 0x07ff)) { | ||
79 | netdev_err(dev->net, "%s : Bad Header Length\n", | ||
80 | __func__); | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | if ((size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) || | ||
85 | (size + offset > skb->len)) { | ||
86 | netdev_err(dev->net, "%s : Bad RX Length %d\n", | ||
87 | __func__, size); | ||
88 | return 0; | ||
89 | } | ||
90 | sr_skb = netdev_alloc_skb_ip_align(dev->net, size); | ||
91 | if (!sr_skb) | ||
92 | return 0; | ||
93 | |||
94 | skb_put(sr_skb, size); | ||
95 | memcpy(sr_skb->data, skb->data + offset, size); | ||
96 | usbnet_skb_return(dev, sr_skb); | ||
97 | |||
98 | offset += (size + 1) & 0xfffe; | ||
99 | } | ||
100 | |||
101 | if (skb->len != offset) { | ||
102 | netdev_err(dev->net, "%s : Bad SKB Length %d\n", __func__, | ||
103 | skb->len); | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | return 1; | ||
108 | } | ||
109 | |||
110 | static struct sk_buff *sr_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | ||
111 | gfp_t flags) | ||
112 | { | ||
113 | int headroom = skb_headroom(skb); | ||
114 | int tailroom = skb_tailroom(skb); | ||
115 | u32 padbytes = 0xffff0000; | ||
116 | u32 packet_len; | ||
117 | int padlen; | ||
118 | |||
119 | padlen = ((skb->len + 4) % (dev->maxpacket - 1)) ? 0 : 4; | ||
120 | |||
121 | if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { | ||
122 | if ((headroom < 4) || (tailroom < padlen)) { | ||
123 | skb->data = memmove(skb->head + 4, skb->data, | ||
124 | skb->len); | ||
125 | skb_set_tail_pointer(skb, skb->len); | ||
126 | } | ||
127 | } else { | ||
128 | struct sk_buff *skb2; | ||
129 | skb2 = skb_copy_expand(skb, 4, padlen, flags); | ||
130 | dev_kfree_skb_any(skb); | ||
131 | skb = skb2; | ||
132 | if (!skb) | ||
133 | return NULL; | ||
134 | } | ||
135 | |||
136 | skb_push(skb, 4); | ||
137 | packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); | ||
138 | cpu_to_le32s(&packet_len); | ||
139 | skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); | ||
140 | |||
141 | if (padlen) { | ||
142 | cpu_to_le32s(&padbytes); | ||
143 | memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); | ||
144 | skb_put(skb, sizeof(padbytes)); | ||
145 | } | ||
146 | |||
147 | return skb; | ||
148 | } | ||
149 | |||
150 | static void sr_status(struct usbnet *dev, struct urb *urb) | ||
151 | { | ||
152 | struct sr9800_int_data *event; | ||
153 | int link; | ||
154 | |||
155 | if (urb->actual_length < 8) | ||
156 | return; | ||
157 | |||
158 | event = urb->transfer_buffer; | ||
159 | link = event->link & 0x01; | ||
160 | if (netif_carrier_ok(dev->net) != link) { | ||
161 | usbnet_link_change(dev, link, 1); | ||
162 | netdev_dbg(dev->net, "Link Status is: %d\n", link); | ||
163 | } | ||
164 | |||
165 | return; | ||
166 | } | ||
167 | |||
168 | static inline int sr_set_sw_mii(struct usbnet *dev) | ||
169 | { | ||
170 | int ret; | ||
171 | |||
172 | ret = sr_write_cmd(dev, SR_CMD_SET_SW_MII, 0x0000, 0, 0, NULL); | ||
173 | if (ret < 0) | ||
174 | netdev_err(dev->net, "Failed to enable software MII access\n"); | ||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static inline int sr_set_hw_mii(struct usbnet *dev) | ||
179 | { | ||
180 | int ret; | ||
181 | |||
182 | ret = sr_write_cmd(dev, SR_CMD_SET_HW_MII, 0x0000, 0, 0, NULL); | ||
183 | if (ret < 0) | ||
184 | netdev_err(dev->net, "Failed to enable hardware MII access\n"); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static inline int sr_get_phy_addr(struct usbnet *dev) | ||
189 | { | ||
190 | u8 buf[2]; | ||
191 | int ret; | ||
192 | |||
193 | ret = sr_read_cmd(dev, SR_CMD_READ_PHY_ID, 0, 0, 2, buf); | ||
194 | if (ret < 0) { | ||
195 | netdev_err(dev->net, "%s : Error reading PHYID register:%02x\n", | ||
196 | __func__, ret); | ||
197 | goto out; | ||
198 | } | ||
199 | netdev_dbg(dev->net, "%s : returning 0x%04x\n", __func__, | ||
200 | *((__le16 *)buf)); | ||
201 | |||
202 | ret = buf[1]; | ||
203 | |||
204 | out: | ||
205 | return ret; | ||
206 | } | ||
207 | |||
208 | static int sr_sw_reset(struct usbnet *dev, u8 flags) | ||
209 | { | ||
210 | int ret; | ||
211 | |||
212 | ret = sr_write_cmd(dev, SR_CMD_SW_RESET, flags, 0, 0, NULL); | ||
213 | if (ret < 0) | ||
214 | netdev_err(dev->net, "Failed to send software reset:%02x\n", | ||
215 | ret); | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | static u16 sr_read_rx_ctl(struct usbnet *dev) | ||
221 | { | ||
222 | __le16 v; | ||
223 | int ret; | ||
224 | |||
225 | ret = sr_read_cmd(dev, SR_CMD_READ_RX_CTL, 0, 0, 2, &v); | ||
226 | if (ret < 0) { | ||
227 | netdev_err(dev->net, "Error reading RX_CTL register:%02x\n", | ||
228 | ret); | ||
229 | goto out; | ||
230 | } | ||
231 | |||
232 | ret = le16_to_cpu(v); | ||
233 | out: | ||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | static int sr_write_rx_ctl(struct usbnet *dev, u16 mode) | ||
238 | { | ||
239 | int ret; | ||
240 | |||
241 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
242 | ret = sr_write_cmd(dev, SR_CMD_WRITE_RX_CTL, mode, 0, 0, NULL); | ||
243 | if (ret < 0) | ||
244 | netdev_err(dev->net, | ||
245 | "Failed to write RX_CTL mode to 0x%04x:%02x\n", | ||
246 | mode, ret); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | static u16 sr_read_medium_status(struct usbnet *dev) | ||
252 | { | ||
253 | __le16 v; | ||
254 | int ret; | ||
255 | |||
256 | ret = sr_read_cmd(dev, SR_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); | ||
257 | if (ret < 0) { | ||
258 | netdev_err(dev->net, | ||
259 | "Error reading Medium Status register:%02x\n", ret); | ||
260 | return ret; /* TODO: callers not checking for error ret */ | ||
261 | } | ||
262 | |||
263 | return le16_to_cpu(v); | ||
264 | } | ||
265 | |||
266 | static int sr_write_medium_mode(struct usbnet *dev, u16 mode) | ||
267 | { | ||
268 | int ret; | ||
269 | |||
270 | netdev_dbg(dev->net, "%s : mode = 0x%04x\n", __func__, mode); | ||
271 | ret = sr_write_cmd(dev, SR_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); | ||
272 | if (ret < 0) | ||
273 | netdev_err(dev->net, | ||
274 | "Failed to write Medium Mode mode to 0x%04x:%02x\n", | ||
275 | mode, ret); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep) | ||
280 | { | ||
281 | int ret; | ||
282 | |||
283 | netdev_dbg(dev->net, "%s : value = 0x%04x\n", __func__, value); | ||
284 | ret = sr_write_cmd(dev, SR_CMD_WRITE_GPIOS, value, 0, 0, NULL); | ||
285 | if (ret < 0) | ||
286 | netdev_err(dev->net, "Failed to write GPIO value 0x%04x:%02x\n", | ||
287 | value, ret); | ||
288 | if (sleep) | ||
289 | msleep(sleep); | ||
290 | |||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | /* SR9800 have a 16-bit RX_CTL value */ | ||
295 | static void sr_set_multicast(struct net_device *net) | ||
296 | { | ||
297 | struct usbnet *dev = netdev_priv(net); | ||
298 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
299 | u16 rx_ctl = SR_DEFAULT_RX_CTL; | ||
300 | |||
301 | if (net->flags & IFF_PROMISC) { | ||
302 | rx_ctl |= SR_RX_CTL_PRO; | ||
303 | } else if (net->flags & IFF_ALLMULTI || | ||
304 | netdev_mc_count(net) > SR_MAX_MCAST) { | ||
305 | rx_ctl |= SR_RX_CTL_AMALL; | ||
306 | } else if (netdev_mc_empty(net)) { | ||
307 | /* just broadcast and directed */ | ||
308 | } else { | ||
309 | /* We use the 20 byte dev->data | ||
310 | * for our 8 byte filter buffer | ||
311 | * to avoid allocating memory that | ||
312 | * is tricky to free later | ||
313 | */ | ||
314 | struct netdev_hw_addr *ha; | ||
315 | u32 crc_bits; | ||
316 | |||
317 | memset(data->multi_filter, 0, SR_MCAST_FILTER_SIZE); | ||
318 | |||
319 | /* Build the multicast hash filter. */ | ||
320 | netdev_for_each_mc_addr(ha, net) { | ||
321 | crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; | ||
322 | data->multi_filter[crc_bits >> 3] |= | ||
323 | 1 << (crc_bits & 7); | ||
324 | } | ||
325 | |||
326 | sr_write_cmd_async(dev, SR_CMD_WRITE_MULTI_FILTER, 0, 0, | ||
327 | SR_MCAST_FILTER_SIZE, data->multi_filter); | ||
328 | |||
329 | rx_ctl |= SR_RX_CTL_AM; | ||
330 | } | ||
331 | |||
332 | sr_write_cmd_async(dev, SR_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); | ||
333 | } | ||
334 | |||
335 | static int sr_mdio_read(struct net_device *net, int phy_id, int loc) | ||
336 | { | ||
337 | struct usbnet *dev = netdev_priv(net); | ||
338 | __le16 res; | ||
339 | |||
340 | mutex_lock(&dev->phy_mutex); | ||
341 | sr_set_sw_mii(dev); | ||
342 | sr_read_cmd(dev, SR_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
343 | sr_set_hw_mii(dev); | ||
344 | mutex_unlock(&dev->phy_mutex); | ||
345 | |||
346 | netdev_dbg(dev->net, | ||
347 | "%s : phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", __func__, | ||
348 | phy_id, loc, le16_to_cpu(res)); | ||
349 | |||
350 | return le16_to_cpu(res); | ||
351 | } | ||
352 | |||
353 | static void | ||
354 | sr_mdio_write(struct net_device *net, int phy_id, int loc, int val) | ||
355 | { | ||
356 | struct usbnet *dev = netdev_priv(net); | ||
357 | __le16 res = cpu_to_le16(val); | ||
358 | |||
359 | netdev_dbg(dev->net, | ||
360 | "%s : phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", __func__, | ||
361 | phy_id, loc, val); | ||
362 | mutex_lock(&dev->phy_mutex); | ||
363 | sr_set_sw_mii(dev); | ||
364 | sr_write_cmd(dev, SR_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); | ||
365 | sr_set_hw_mii(dev); | ||
366 | mutex_unlock(&dev->phy_mutex); | ||
367 | } | ||
368 | |||
369 | /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ | ||
370 | static u32 sr_get_phyid(struct usbnet *dev) | ||
371 | { | ||
372 | int phy_reg; | ||
373 | u32 phy_id; | ||
374 | int i; | ||
375 | |||
376 | /* Poll for the rare case the FW or phy isn't ready yet. */ | ||
377 | for (i = 0; i < 100; i++) { | ||
378 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1); | ||
379 | if (phy_reg != 0 && phy_reg != 0xFFFF) | ||
380 | break; | ||
381 | mdelay(1); | ||
382 | } | ||
383 | |||
384 | if (phy_reg <= 0 || phy_reg == 0xFFFF) | ||
385 | return 0; | ||
386 | |||
387 | phy_id = (phy_reg & 0xffff) << 16; | ||
388 | |||
389 | phy_reg = sr_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID2); | ||
390 | if (phy_reg < 0) | ||
391 | return 0; | ||
392 | |||
393 | phy_id |= (phy_reg & 0xffff); | ||
394 | |||
395 | return phy_id; | ||
396 | } | ||
397 | |||
398 | static void | ||
399 | sr_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
400 | { | ||
401 | struct usbnet *dev = netdev_priv(net); | ||
402 | u8 opt; | ||
403 | |||
404 | if (sr_read_cmd(dev, SR_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { | ||
405 | wolinfo->supported = 0; | ||
406 | wolinfo->wolopts = 0; | ||
407 | return; | ||
408 | } | ||
409 | wolinfo->supported = WAKE_PHY | WAKE_MAGIC; | ||
410 | wolinfo->wolopts = 0; | ||
411 | if (opt & SR_MONITOR_LINK) | ||
412 | wolinfo->wolopts |= WAKE_PHY; | ||
413 | if (opt & SR_MONITOR_MAGIC) | ||
414 | wolinfo->wolopts |= WAKE_MAGIC; | ||
415 | } | ||
416 | |||
417 | static int | ||
418 | sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | ||
419 | { | ||
420 | struct usbnet *dev = netdev_priv(net); | ||
421 | u8 opt = 0; | ||
422 | |||
423 | if (wolinfo->wolopts & WAKE_PHY) | ||
424 | opt |= SR_MONITOR_LINK; | ||
425 | if (wolinfo->wolopts & WAKE_MAGIC) | ||
426 | opt |= SR_MONITOR_MAGIC; | ||
427 | |||
428 | if (sr_write_cmd(dev, SR_CMD_WRITE_MONITOR_MODE, | ||
429 | opt, 0, 0, NULL) < 0) | ||
430 | return -EINVAL; | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int sr_get_eeprom_len(struct net_device *net) | ||
436 | { | ||
437 | struct usbnet *dev = netdev_priv(net); | ||
438 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
439 | |||
440 | return data->eeprom_len; | ||
441 | } | ||
442 | |||
443 | static int sr_get_eeprom(struct net_device *net, | ||
444 | struct ethtool_eeprom *eeprom, u8 *data) | ||
445 | { | ||
446 | struct usbnet *dev = netdev_priv(net); | ||
447 | __le16 *ebuf = (__le16 *)data; | ||
448 | int ret; | ||
449 | int i; | ||
450 | |||
451 | /* Crude hack to ensure that we don't overwrite memory | ||
452 | * if an odd length is supplied | ||
453 | */ | ||
454 | if (eeprom->len % 2) | ||
455 | return -EINVAL; | ||
456 | |||
457 | eeprom->magic = SR_EEPROM_MAGIC; | ||
458 | |||
459 | /* sr9800 returns 2 bytes from eeprom on read */ | ||
460 | for (i = 0; i < eeprom->len / 2; i++) { | ||
461 | ret = sr_read_cmd(dev, SR_CMD_READ_EEPROM, eeprom->offset + i, | ||
462 | 0, 2, &ebuf[i]); | ||
463 | if (ret < 0) | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | static void sr_get_drvinfo(struct net_device *net, | ||
470 | struct ethtool_drvinfo *info) | ||
471 | { | ||
472 | struct usbnet *dev = netdev_priv(net); | ||
473 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
474 | |||
475 | /* Inherit standard device info */ | ||
476 | usbnet_get_drvinfo(net, info); | ||
477 | strncpy(info->driver, DRIVER_NAME, sizeof(info->driver)); | ||
478 | strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); | ||
479 | info->eedump_len = data->eeprom_len; | ||
480 | } | ||
481 | |||
482 | static u32 sr_get_link(struct net_device *net) | ||
483 | { | ||
484 | struct usbnet *dev = netdev_priv(net); | ||
485 | |||
486 | return mii_link_ok(&dev->mii); | ||
487 | } | ||
488 | |||
489 | static int sr_ioctl(struct net_device *net, struct ifreq *rq, int cmd) | ||
490 | { | ||
491 | struct usbnet *dev = netdev_priv(net); | ||
492 | |||
493 | return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); | ||
494 | } | ||
495 | |||
496 | static int sr_set_mac_address(struct net_device *net, void *p) | ||
497 | { | ||
498 | struct usbnet *dev = netdev_priv(net); | ||
499 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
500 | struct sockaddr *addr = p; | ||
501 | |||
502 | if (netif_running(net)) | ||
503 | return -EBUSY; | ||
504 | if (!is_valid_ether_addr(addr->sa_data)) | ||
505 | return -EADDRNOTAVAIL; | ||
506 | |||
507 | memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); | ||
508 | |||
509 | /* We use the 20 byte dev->data | ||
510 | * for our 6 byte mac buffer | ||
511 | * to avoid allocating memory that | ||
512 | * is tricky to free later | ||
513 | */ | ||
514 | memcpy(data->mac_addr, addr->sa_data, ETH_ALEN); | ||
515 | sr_write_cmd_async(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
516 | data->mac_addr); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static const struct ethtool_ops sr9800_ethtool_ops = { | ||
522 | .get_drvinfo = sr_get_drvinfo, | ||
523 | .get_link = sr_get_link, | ||
524 | .get_msglevel = usbnet_get_msglevel, | ||
525 | .set_msglevel = usbnet_set_msglevel, | ||
526 | .get_wol = sr_get_wol, | ||
527 | .set_wol = sr_set_wol, | ||
528 | .get_eeprom_len = sr_get_eeprom_len, | ||
529 | .get_eeprom = sr_get_eeprom, | ||
530 | .get_settings = usbnet_get_settings, | ||
531 | .set_settings = usbnet_set_settings, | ||
532 | .nway_reset = usbnet_nway_reset, | ||
533 | }; | ||
534 | |||
535 | static int sr9800_link_reset(struct usbnet *dev) | ||
536 | { | ||
537 | struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; | ||
538 | u16 mode; | ||
539 | |||
540 | mii_check_media(&dev->mii, 1, 1); | ||
541 | mii_ethtool_gset(&dev->mii, &ecmd); | ||
542 | mode = SR9800_MEDIUM_DEFAULT; | ||
543 | |||
544 | if (ethtool_cmd_speed(&ecmd) != SPEED_100) | ||
545 | mode &= ~SR_MEDIUM_PS; | ||
546 | |||
547 | if (ecmd.duplex != DUPLEX_FULL) | ||
548 | mode &= ~SR_MEDIUM_FD; | ||
549 | |||
550 | netdev_dbg(dev->net, "%s : speed: %u duplex: %d mode: 0x%04x\n", | ||
551 | __func__, ethtool_cmd_speed(&ecmd), ecmd.duplex, mode); | ||
552 | |||
553 | sr_write_medium_mode(dev, mode); | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | |||
559 | static int sr9800_set_default_mode(struct usbnet *dev) | ||
560 | { | ||
561 | u16 rx_ctl; | ||
562 | int ret; | ||
563 | |||
564 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); | ||
565 | sr_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, | ||
566 | ADVERTISE_ALL | ADVERTISE_CSMA); | ||
567 | mii_nway_restart(&dev->mii); | ||
568 | |||
569 | ret = sr_write_medium_mode(dev, SR9800_MEDIUM_DEFAULT); | ||
570 | if (ret < 0) | ||
571 | goto out; | ||
572 | |||
573 | ret = sr_write_cmd(dev, SR_CMD_WRITE_IPG012, | ||
574 | SR9800_IPG0_DEFAULT | SR9800_IPG1_DEFAULT, | ||
575 | SR9800_IPG2_DEFAULT, 0, NULL); | ||
576 | if (ret < 0) { | ||
577 | netdev_dbg(dev->net, "Write IPG,IPG1,IPG2 failed: %d\n", ret); | ||
578 | goto out; | ||
579 | } | ||
580 | |||
581 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | ||
582 | ret = sr_write_rx_ctl(dev, SR_DEFAULT_RX_CTL); | ||
583 | if (ret < 0) | ||
584 | goto out; | ||
585 | |||
586 | rx_ctl = sr_read_rx_ctl(dev); | ||
587 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after all initializations\n", | ||
588 | rx_ctl); | ||
589 | |||
590 | rx_ctl = sr_read_medium_status(dev); | ||
591 | netdev_dbg(dev->net, "Medium Status:0x%04x after all initializations\n", | ||
592 | rx_ctl); | ||
593 | |||
594 | return 0; | ||
595 | out: | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | static int sr9800_reset(struct usbnet *dev) | ||
600 | { | ||
601 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
602 | int ret, embd_phy; | ||
603 | u16 rx_ctl; | ||
604 | |||
605 | ret = sr_write_gpio(dev, | ||
606 | SR_GPIO_RSE | SR_GPIO_GPO_2 | SR_GPIO_GPO2EN, 5); | ||
607 | if (ret < 0) | ||
608 | goto out; | ||
609 | |||
610 | embd_phy = ((sr_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | ||
611 | |||
612 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
613 | if (ret < 0) { | ||
614 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
615 | goto out; | ||
616 | } | ||
617 | |||
618 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_PRL); | ||
619 | if (ret < 0) | ||
620 | goto out; | ||
621 | |||
622 | msleep(150); | ||
623 | |||
624 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
625 | if (ret < 0) | ||
626 | goto out; | ||
627 | |||
628 | msleep(150); | ||
629 | |||
630 | if (embd_phy) { | ||
631 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
632 | if (ret < 0) | ||
633 | goto out; | ||
634 | } else { | ||
635 | ret = sr_sw_reset(dev, SR_SWRESET_PRTE); | ||
636 | if (ret < 0) | ||
637 | goto out; | ||
638 | } | ||
639 | |||
640 | msleep(150); | ||
641 | rx_ctl = sr_read_rx_ctl(dev); | ||
642 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
643 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
644 | if (ret < 0) | ||
645 | goto out; | ||
646 | |||
647 | rx_ctl = sr_read_rx_ctl(dev); | ||
648 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
649 | |||
650 | ret = sr_sw_reset(dev, SR_SWRESET_PRL); | ||
651 | if (ret < 0) | ||
652 | goto out; | ||
653 | |||
654 | msleep(150); | ||
655 | |||
656 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL | SR_SWRESET_PRL); | ||
657 | if (ret < 0) | ||
658 | goto out; | ||
659 | |||
660 | msleep(150); | ||
661 | |||
662 | ret = sr9800_set_default_mode(dev); | ||
663 | if (ret < 0) | ||
664 | goto out; | ||
665 | |||
666 | /* Rewrite MAC address */ | ||
667 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
668 | ret = sr_write_cmd(dev, SR_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
669 | data->mac_addr); | ||
670 | if (ret < 0) | ||
671 | goto out; | ||
672 | |||
673 | return 0; | ||
674 | |||
675 | out: | ||
676 | return ret; | ||
677 | } | ||
678 | |||
679 | static const struct net_device_ops sr9800_netdev_ops = { | ||
680 | .ndo_open = usbnet_open, | ||
681 | .ndo_stop = usbnet_stop, | ||
682 | .ndo_start_xmit = usbnet_start_xmit, | ||
683 | .ndo_tx_timeout = usbnet_tx_timeout, | ||
684 | .ndo_change_mtu = usbnet_change_mtu, | ||
685 | .ndo_set_mac_address = sr_set_mac_address, | ||
686 | .ndo_validate_addr = eth_validate_addr, | ||
687 | .ndo_do_ioctl = sr_ioctl, | ||
688 | .ndo_set_rx_mode = sr_set_multicast, | ||
689 | }; | ||
690 | |||
691 | static int sr9800_phy_powerup(struct usbnet *dev) | ||
692 | { | ||
693 | int ret; | ||
694 | |||
695 | /* set the embedded Ethernet PHY in power-down state */ | ||
696 | ret = sr_sw_reset(dev, SR_SWRESET_IPPD | SR_SWRESET_IPRL); | ||
697 | if (ret < 0) { | ||
698 | netdev_err(dev->net, "Failed to power down PHY : %d\n", ret); | ||
699 | return ret; | ||
700 | } | ||
701 | msleep(20); | ||
702 | |||
703 | /* set the embedded Ethernet PHY in power-up state */ | ||
704 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
705 | if (ret < 0) { | ||
706 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
707 | return ret; | ||
708 | } | ||
709 | msleep(600); | ||
710 | |||
711 | /* set the embedded Ethernet PHY in reset state */ | ||
712 | ret = sr_sw_reset(dev, SR_SWRESET_CLEAR); | ||
713 | if (ret < 0) { | ||
714 | netdev_err(dev->net, "Failed to power up PHY: %d\n", ret); | ||
715 | return ret; | ||
716 | } | ||
717 | msleep(20); | ||
718 | |||
719 | /* set the embedded Ethernet PHY in power-up state */ | ||
720 | ret = sr_sw_reset(dev, SR_SWRESET_IPRL); | ||
721 | if (ret < 0) { | ||
722 | netdev_err(dev->net, "Failed to reset PHY: %d\n", ret); | ||
723 | return ret; | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf) | ||
730 | { | ||
731 | struct sr_data *data = (struct sr_data *)&dev->data; | ||
732 | u16 led01_mux, led23_mux; | ||
733 | int ret, embd_phy; | ||
734 | u32 phyid; | ||
735 | u16 rx_ctl; | ||
736 | |||
737 | data->eeprom_len = SR9800_EEPROM_LEN; | ||
738 | |||
739 | usbnet_get_endpoints(dev, intf); | ||
740 | |||
741 | /* LED Setting Rule : | ||
742 | * AABB:CCDD | ||
743 | * AA : MFA0(LED0) | ||
744 | * BB : MFA1(LED1) | ||
745 | * CC : MFA2(LED2), Reserved for SR9800 | ||
746 | * DD : MFA3(LED3), Reserved for SR9800 | ||
747 | */ | ||
748 | led01_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_LINK; | ||
749 | led23_mux = (SR_LED_MUX_LINK_ACTIVE << 8) | SR_LED_MUX_TX_ACTIVE; | ||
750 | ret = sr_write_cmd(dev, SR_CMD_LED_MUX, led01_mux, led23_mux, 0, NULL); | ||
751 | if (ret < 0) { | ||
752 | netdev_err(dev->net, "set LINK LED failed : %d\n", ret); | ||
753 | goto out; | ||
754 | } | ||
755 | |||
756 | /* Get the MAC address */ | ||
757 | ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, | ||
758 | dev->net->dev_addr); | ||
759 | if (ret < 0) { | ||
760 | netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); | ||
761 | return ret; | ||
762 | } | ||
763 | netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); | ||
764 | |||
765 | /* Initialize MII structure */ | ||
766 | dev->mii.dev = dev->net; | ||
767 | dev->mii.mdio_read = sr_mdio_read; | ||
768 | dev->mii.mdio_write = sr_mdio_write; | ||
769 | dev->mii.phy_id_mask = 0x1f; | ||
770 | dev->mii.reg_num_mask = 0x1f; | ||
771 | dev->mii.phy_id = sr_get_phy_addr(dev); | ||
772 | |||
773 | dev->net->netdev_ops = &sr9800_netdev_ops; | ||
774 | dev->net->ethtool_ops = &sr9800_ethtool_ops; | ||
775 | |||
776 | embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0); | ||
777 | /* Reset the PHY to normal operation mode */ | ||
778 | ret = sr_write_cmd(dev, SR_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL); | ||
779 | if (ret < 0) { | ||
780 | netdev_dbg(dev->net, "Select PHY #1 failed: %d\n", ret); | ||
781 | return ret; | ||
782 | } | ||
783 | |||
784 | /* Init PHY routine */ | ||
785 | ret = sr9800_phy_powerup(dev); | ||
786 | if (ret < 0) | ||
787 | goto out; | ||
788 | |||
789 | rx_ctl = sr_read_rx_ctl(dev); | ||
790 | netdev_dbg(dev->net, "RX_CTL is 0x%04x after software reset\n", rx_ctl); | ||
791 | ret = sr_write_rx_ctl(dev, 0x0000); | ||
792 | if (ret < 0) | ||
793 | goto out; | ||
794 | |||
795 | rx_ctl = sr_read_rx_ctl(dev); | ||
796 | netdev_dbg(dev->net, "RX_CTL is 0x%04x setting to 0x0000\n", rx_ctl); | ||
797 | |||
798 | /* Read PHYID register *AFTER* the PHY was reset properly */ | ||
799 | phyid = sr_get_phyid(dev); | ||
800 | netdev_dbg(dev->net, "PHYID=0x%08x\n", phyid); | ||
801 | |||
802 | /* medium mode setting */ | ||
803 | ret = sr9800_set_default_mode(dev); | ||
804 | if (ret < 0) | ||
805 | goto out; | ||
806 | |||
807 | if (dev->udev->speed == USB_SPEED_HIGH) { | ||
808 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
809 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].byte_cnt, | ||
810 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].threshold, | ||
811 | 0, NULL); | ||
812 | if (ret < 0) { | ||
813 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
814 | goto out; | ||
815 | } | ||
816 | dev->rx_urb_size = | ||
817 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_4K].size; | ||
818 | } else { | ||
819 | ret = sr_write_cmd(dev, SR_CMD_BULKIN_SIZE, | ||
820 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].byte_cnt, | ||
821 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].threshold, | ||
822 | 0, NULL); | ||
823 | if (ret < 0) { | ||
824 | netdev_err(dev->net, "Reset RX_CTL failed: %d\n", ret); | ||
825 | goto out; | ||
826 | } | ||
827 | dev->rx_urb_size = | ||
828 | SR9800_BULKIN_SIZE[SR9800_MAX_BULKIN_2K].size; | ||
829 | } | ||
830 | netdev_dbg(dev->net, "%s : setting rx_urb_size with : %zu\n", __func__, | ||
831 | dev->rx_urb_size); | ||
832 | return 0; | ||
833 | |||
834 | out: | ||
835 | return ret; | ||
836 | } | ||
837 | |||
838 | static const struct driver_info sr9800_driver_info = { | ||
839 | .description = "CoreChip SR9800 USB 2.0 Ethernet", | ||
840 | .bind = sr9800_bind, | ||
841 | .status = sr_status, | ||
842 | .link_reset = sr9800_link_reset, | ||
843 | .reset = sr9800_reset, | ||
844 | .flags = DRIVER_FLAG, | ||
845 | .rx_fixup = sr_rx_fixup, | ||
846 | .tx_fixup = sr_tx_fixup, | ||
847 | }; | ||
848 | |||
849 | static const struct usb_device_id products[] = { | ||
850 | { | ||
851 | USB_DEVICE(0x0fe6, 0x9800), /* SR9800 Device */ | ||
852 | .driver_info = (unsigned long) &sr9800_driver_info, | ||
853 | }, | ||
854 | {}, /* END */ | ||
855 | }; | ||
856 | |||
857 | MODULE_DEVICE_TABLE(usb, products); | ||
858 | |||
859 | static struct usb_driver sr_driver = { | ||
860 | .name = DRIVER_NAME, | ||
861 | .id_table = products, | ||
862 | .probe = usbnet_probe, | ||
863 | .suspend = usbnet_suspend, | ||
864 | .resume = usbnet_resume, | ||
865 | .disconnect = usbnet_disconnect, | ||
866 | .supports_autosuspend = 1, | ||
867 | }; | ||
868 | |||
869 | module_usb_driver(sr_driver); | ||
870 | |||
871 | MODULE_AUTHOR("Liu Junliang <liujunliang_ljl@163.com"); | ||
872 | MODULE_VERSION(DRIVER_VERSION); | ||
873 | MODULE_DESCRIPTION("SR9800 USB 2.0 USB2NET Dev : http://www.corechip-sz.com"); | ||
874 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/sr9800.h b/drivers/net/usb/sr9800.h new file mode 100644 index 000000000000..18f670251275 --- /dev/null +++ b/drivers/net/usb/sr9800.h | |||
@@ -0,0 +1,202 @@ | |||
1 | /* CoreChip-sz SR9800 one chip USB 2.0 Ethernet Devices | ||
2 | * | ||
3 | * Author : Liu Junliang <liujunliang_ljl@163.com> | ||
4 | * | ||
5 | * This file is licensed under the terms of the GNU General Public License | ||
6 | * version 2. This program is licensed "as is" without any warranty of any | ||
7 | * kind, whether express or implied. | ||
8 | */ | ||
9 | |||
10 | #ifndef _SR9800_H | ||
11 | #define _SR9800_H | ||
12 | |||
13 | /* SR9800 spec. command table on Linux Platform */ | ||
14 | |||
15 | /* command : Software Station Management Control Reg */ | ||
16 | #define SR_CMD_SET_SW_MII 0x06 | ||
17 | /* command : PHY Read Reg */ | ||
18 | #define SR_CMD_READ_MII_REG 0x07 | ||
19 | /* command : PHY Write Reg */ | ||
20 | #define SR_CMD_WRITE_MII_REG 0x08 | ||
21 | /* command : Hardware Station Management Control Reg */ | ||
22 | #define SR_CMD_SET_HW_MII 0x0a | ||
23 | /* command : SROM Read Reg */ | ||
24 | #define SR_CMD_READ_EEPROM 0x0b | ||
25 | /* command : SROM Write Reg */ | ||
26 | #define SR_CMD_WRITE_EEPROM 0x0c | ||
27 | /* command : SROM Write Enable Reg */ | ||
28 | #define SR_CMD_WRITE_ENABLE 0x0d | ||
29 | /* command : SROM Write Disable Reg */ | ||
30 | #define SR_CMD_WRITE_DISABLE 0x0e | ||
31 | /* command : RX Control Read Reg */ | ||
32 | #define SR_CMD_READ_RX_CTL 0x0f | ||
33 | #define SR_RX_CTL_PRO (1 << 0) | ||
34 | #define SR_RX_CTL_AMALL (1 << 1) | ||
35 | #define SR_RX_CTL_SEP (1 << 2) | ||
36 | #define SR_RX_CTL_AB (1 << 3) | ||
37 | #define SR_RX_CTL_AM (1 << 4) | ||
38 | #define SR_RX_CTL_AP (1 << 5) | ||
39 | #define SR_RX_CTL_ARP (1 << 6) | ||
40 | #define SR_RX_CTL_SO (1 << 7) | ||
41 | #define SR_RX_CTL_RH1M (1 << 8) | ||
42 | #define SR_RX_CTL_RH2M (1 << 9) | ||
43 | #define SR_RX_CTL_RH3M (1 << 10) | ||
44 | /* command : RX Control Write Reg */ | ||
45 | #define SR_CMD_WRITE_RX_CTL 0x10 | ||
46 | /* command : IPG0/IPG1/IPG2 Control Read Reg */ | ||
47 | #define SR_CMD_READ_IPG012 0x11 | ||
48 | /* command : IPG0/IPG1/IPG2 Control Write Reg */ | ||
49 | #define SR_CMD_WRITE_IPG012 0x12 | ||
50 | /* command : Node ID Read Reg */ | ||
51 | #define SR_CMD_READ_NODE_ID 0x13 | ||
52 | /* command : Node ID Write Reg */ | ||
53 | #define SR_CMD_WRITE_NODE_ID 0x14 | ||
54 | /* command : Multicast Filter Array Read Reg */ | ||
55 | #define SR_CMD_READ_MULTI_FILTER 0x15 | ||
56 | /* command : Multicast Filter Array Write Reg */ | ||
57 | #define SR_CMD_WRITE_MULTI_FILTER 0x16 | ||
58 | /* command : Eth/HomePNA PHY Address Reg */ | ||
59 | #define SR_CMD_READ_PHY_ID 0x19 | ||
60 | /* command : Medium Status Read Reg */ | ||
61 | #define SR_CMD_READ_MEDIUM_STATUS 0x1a | ||
62 | #define SR_MONITOR_LINK (1 << 1) | ||
63 | #define SR_MONITOR_MAGIC (1 << 2) | ||
64 | #define SR_MONITOR_HSFS (1 << 4) | ||
65 | /* command : Medium Status Write Reg */ | ||
66 | #define SR_CMD_WRITE_MEDIUM_MODE 0x1b | ||
67 | #define SR_MEDIUM_GM (1 << 0) | ||
68 | #define SR_MEDIUM_FD (1 << 1) | ||
69 | #define SR_MEDIUM_AC (1 << 2) | ||
70 | #define SR_MEDIUM_ENCK (1 << 3) | ||
71 | #define SR_MEDIUM_RFC (1 << 4) | ||
72 | #define SR_MEDIUM_TFC (1 << 5) | ||
73 | #define SR_MEDIUM_JFE (1 << 6) | ||
74 | #define SR_MEDIUM_PF (1 << 7) | ||
75 | #define SR_MEDIUM_RE (1 << 8) | ||
76 | #define SR_MEDIUM_PS (1 << 9) | ||
77 | #define SR_MEDIUM_RSV (1 << 10) | ||
78 | #define SR_MEDIUM_SBP (1 << 11) | ||
79 | #define SR_MEDIUM_SM (1 << 12) | ||
80 | /* command : Monitor Mode Status Read Reg */ | ||
81 | #define SR_CMD_READ_MONITOR_MODE 0x1c | ||
82 | /* command : Monitor Mode Status Write Reg */ | ||
83 | #define SR_CMD_WRITE_MONITOR_MODE 0x1d | ||
84 | /* command : GPIO Status Read Reg */ | ||
85 | #define SR_CMD_READ_GPIOS 0x1e | ||
86 | #define SR_GPIO_GPO0EN (1 << 0) /* GPIO0 Output enable */ | ||
87 | #define SR_GPIO_GPO_0 (1 << 1) /* GPIO0 Output value */ | ||
88 | #define SR_GPIO_GPO1EN (1 << 2) /* GPIO1 Output enable */ | ||
89 | #define SR_GPIO_GPO_1 (1 << 3) /* GPIO1 Output value */ | ||
90 | #define SR_GPIO_GPO2EN (1 << 4) /* GPIO2 Output enable */ | ||
91 | #define SR_GPIO_GPO_2 (1 << 5) /* GPIO2 Output value */ | ||
92 | #define SR_GPIO_RESERVED (1 << 6) /* Reserved */ | ||
93 | #define SR_GPIO_RSE (1 << 7) /* Reload serial EEPROM */ | ||
94 | /* command : GPIO Status Write Reg */ | ||
95 | #define SR_CMD_WRITE_GPIOS 0x1f | ||
96 | /* command : Eth PHY Power and Reset Control Reg */ | ||
97 | #define SR_CMD_SW_RESET 0x20 | ||
98 | #define SR_SWRESET_CLEAR 0x00 | ||
99 | #define SR_SWRESET_RR (1 << 0) | ||
100 | #define SR_SWRESET_RT (1 << 1) | ||
101 | #define SR_SWRESET_PRTE (1 << 2) | ||
102 | #define SR_SWRESET_PRL (1 << 3) | ||
103 | #define SR_SWRESET_BZ (1 << 4) | ||
104 | #define SR_SWRESET_IPRL (1 << 5) | ||
105 | #define SR_SWRESET_IPPD (1 << 6) | ||
106 | /* command : Software Interface Selection Status Read Reg */ | ||
107 | #define SR_CMD_SW_PHY_STATUS 0x21 | ||
108 | /* command : Software Interface Selection Status Write Reg */ | ||
109 | #define SR_CMD_SW_PHY_SELECT 0x22 | ||
110 | /* command : BULK in Buffer Size Reg */ | ||
111 | #define SR_CMD_BULKIN_SIZE 0x2A | ||
112 | /* command : LED_MUX Control Reg */ | ||
113 | #define SR_CMD_LED_MUX 0x70 | ||
114 | #define SR_LED_MUX_TX_ACTIVE (1 << 0) | ||
115 | #define SR_LED_MUX_RX_ACTIVE (1 << 1) | ||
116 | #define SR_LED_MUX_COLLISION (1 << 2) | ||
117 | #define SR_LED_MUX_DUP_COL (1 << 3) | ||
118 | #define SR_LED_MUX_DUP (1 << 4) | ||
119 | #define SR_LED_MUX_SPEED (1 << 5) | ||
120 | #define SR_LED_MUX_LINK_ACTIVE (1 << 6) | ||
121 | #define SR_LED_MUX_LINK (1 << 7) | ||
122 | |||
123 | /* Register Access Flags */ | ||
124 | #define SR_REQ_RD_REG (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
125 | #define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) | ||
126 | |||
127 | /* Multicast Filter Array size & Max Number */ | ||
128 | #define SR_MCAST_FILTER_SIZE 8 | ||
129 | #define SR_MAX_MCAST 64 | ||
130 | |||
131 | /* IPG0/1/2 Default Value */ | ||
132 | #define SR9800_IPG0_DEFAULT 0x15 | ||
133 | #define SR9800_IPG1_DEFAULT 0x0c | ||
134 | #define SR9800_IPG2_DEFAULT 0x12 | ||
135 | |||
136 | /* Medium Status Default Mode */ | ||
137 | #define SR9800_MEDIUM_DEFAULT \ | ||
138 | (SR_MEDIUM_FD | SR_MEDIUM_RFC | \ | ||
139 | SR_MEDIUM_TFC | SR_MEDIUM_PS | \ | ||
140 | SR_MEDIUM_AC | SR_MEDIUM_RE) | ||
141 | |||
142 | /* RX Control Default Setting */ | ||
143 | #define SR_DEFAULT_RX_CTL \ | ||
144 | (SR_RX_CTL_SO | SR_RX_CTL_AB | SR_RX_CTL_RH1M) | ||
145 | |||
146 | /* EEPROM Magic Number & EEPROM Size */ | ||
147 | #define SR_EEPROM_MAGIC 0xdeadbeef | ||
148 | #define SR9800_EEPROM_LEN 0xff | ||
149 | |||
150 | /* SR9800 Driver Version and Driver Name */ | ||
151 | #define DRIVER_VERSION "11-Nov-2013" | ||
152 | #define DRIVER_NAME "CoreChips" | ||
153 | #define DRIVER_FLAG \ | ||
154 | (FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | FLAG_MULTI_PACKET) | ||
155 | |||
156 | /* SR9800 BULKIN Buffer Size */ | ||
157 | #define SR9800_MAX_BULKIN_2K 0 | ||
158 | #define SR9800_MAX_BULKIN_4K 1 | ||
159 | #define SR9800_MAX_BULKIN_6K 2 | ||
160 | #define SR9800_MAX_BULKIN_8K 3 | ||
161 | #define SR9800_MAX_BULKIN_16K 4 | ||
162 | #define SR9800_MAX_BULKIN_20K 5 | ||
163 | #define SR9800_MAX_BULKIN_24K 6 | ||
164 | #define SR9800_MAX_BULKIN_32K 7 | ||
165 | |||
166 | struct {unsigned short size, byte_cnt, threshold; } SR9800_BULKIN_SIZE[] = { | ||
167 | /* 2k */ | ||
168 | {2048, 0x8000, 0x8001}, | ||
169 | /* 4k */ | ||
170 | {4096, 0x8100, 0x8147}, | ||
171 | /* 6k */ | ||
172 | {6144, 0x8200, 0x81EB}, | ||
173 | /* 8k */ | ||
174 | {8192, 0x8300, 0x83D7}, | ||
175 | /* 16 */ | ||
176 | {16384, 0x8400, 0x851E}, | ||
177 | /* 20k */ | ||
178 | {20480, 0x8500, 0x8666}, | ||
179 | /* 24k */ | ||
180 | {24576, 0x8600, 0x87AE}, | ||
181 | /* 32k */ | ||
182 | {32768, 0x8700, 0x8A3D}, | ||
183 | }; | ||
184 | |||
185 | /* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ | ||
186 | struct sr_data { | ||
187 | u8 multi_filter[SR_MCAST_FILTER_SIZE]; | ||
188 | u8 mac_addr[ETH_ALEN]; | ||
189 | u8 phymode; | ||
190 | u8 ledmode; | ||
191 | u8 eeprom_len; | ||
192 | }; | ||
193 | |||
194 | struct sr9800_int_data { | ||
195 | __le16 res1; | ||
196 | u8 link; | ||
197 | __le16 res2; | ||
198 | u8 status; | ||
199 | __le16 res3; | ||
200 | } __packed; | ||
201 | |||
202 | #endif /* _SR9800_H */ | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 4671da755e7b..dd10d5817d2a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -542,17 +542,19 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) | |||
542 | } | 542 | } |
543 | // else network stack removes extra byte if we forced a short packet | 543 | // else network stack removes extra byte if we forced a short packet |
544 | 544 | ||
545 | if (skb->len) { | 545 | /* all data was already cloned from skb inside the driver */ |
546 | /* all data was already cloned from skb inside the driver */ | 546 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) |
547 | if (dev->driver_info->flags & FLAG_MULTI_PACKET) | 547 | goto done; |
548 | dev_kfree_skb_any(skb); | 548 | |
549 | else | 549 | if (skb->len < ETH_HLEN) { |
550 | usbnet_skb_return(dev, skb); | 550 | dev->net->stats.rx_errors++; |
551 | dev->net->stats.rx_length_errors++; | ||
552 | netif_dbg(dev, rx_err, dev->net, "rx length %d\n", skb->len); | ||
553 | } else { | ||
554 | usbnet_skb_return(dev, skb); | ||
551 | return; | 555 | return; |
552 | } | 556 | } |
553 | 557 | ||
554 | netif_dbg(dev, rx_err, dev->net, "drop\n"); | ||
555 | dev->net->stats.rx_errors++; | ||
556 | done: | 558 | done: |
557 | skb_queue_tail(&dev->done, skb); | 559 | skb_queue_tail(&dev->done, skb); |
558 | } | 560 | } |
@@ -574,13 +576,6 @@ static void rx_complete (struct urb *urb) | |||
574 | switch (urb_status) { | 576 | switch (urb_status) { |
575 | /* success */ | 577 | /* success */ |
576 | case 0: | 578 | case 0: |
577 | if (skb->len < dev->net->hard_header_len) { | ||
578 | state = rx_cleanup; | ||
579 | dev->net->stats.rx_errors++; | ||
580 | dev->net->stats.rx_length_errors++; | ||
581 | netif_dbg(dev, rx_err, dev->net, | ||
582 | "rx length %d\n", skb->len); | ||
583 | } | ||
584 | break; | 579 | break; |
585 | 580 | ||
586 | /* stalls need manual reset. this is rare ... except that | 581 | /* stalls need manual reset. this is rare ... except that |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 2ec2041b62d4..5b374370f71c 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -285,7 +285,8 @@ static void veth_setup(struct net_device *dev) | |||
285 | dev->ethtool_ops = &veth_ethtool_ops; | 285 | dev->ethtool_ops = &veth_ethtool_ops; |
286 | dev->features |= NETIF_F_LLTX; | 286 | dev->features |= NETIF_F_LLTX; |
287 | dev->features |= VETH_FEATURES; | 287 | dev->features |= VETH_FEATURES; |
288 | dev->vlan_features = dev->features; | 288 | dev->vlan_features = dev->features & |
289 | ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX); | ||
289 | dev->destructor = veth_dev_free; | 290 | dev->destructor = veth_dev_free; |
290 | 291 | ||
291 | dev->hw_features = VETH_FEATURES; | 292 | dev->hw_features = VETH_FEATURES; |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d75f8edf4fb3..5632a99cbbd2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -1711,7 +1711,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1711 | /* If we can receive ANY GSO packets, we must allocate large ones. */ | 1711 | /* If we can receive ANY GSO packets, we must allocate large ones. */ |
1712 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || | 1712 | if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || |
1713 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || | 1713 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) || |
1714 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) | 1714 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) || |
1715 | virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO)) | ||
1715 | vi->big_packets = true; | 1716 | vi->big_packets = true; |
1716 | 1717 | ||
1717 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) | 1718 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 3be786faaaec..0fa3b44f7342 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -1762,11 +1762,20 @@ vmxnet3_netpoll(struct net_device *netdev) | |||
1762 | { | 1762 | { |
1763 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); | 1763 | struct vmxnet3_adapter *adapter = netdev_priv(netdev); |
1764 | 1764 | ||
1765 | if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE) | 1765 | switch (adapter->intr.type) { |
1766 | vmxnet3_disable_all_intrs(adapter); | 1766 | #ifdef CONFIG_PCI_MSI |
1767 | 1767 | case VMXNET3_IT_MSIX: { | |
1768 | vmxnet3_do_poll(adapter, adapter->rx_queue[0].rx_ring[0].size); | 1768 | int i; |
1769 | vmxnet3_enable_all_intrs(adapter); | 1769 | for (i = 0; i < adapter->num_rx_queues; i++) |
1770 | vmxnet3_msix_rx(0, &adapter->rx_queue[i]); | ||
1771 | break; | ||
1772 | } | ||
1773 | #endif | ||
1774 | case VMXNET3_IT_MSI: | ||
1775 | default: | ||
1776 | vmxnet3_intr(0, adapter->netdev); | ||
1777 | break; | ||
1778 | } | ||
1770 | 1779 | ||
1771 | } | 1780 | } |
1772 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 1781 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 026a313c2d2d..1236812c7be6 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -469,7 +469,6 @@ static inline struct hlist_head *vxlan_fdb_head(struct vxlan_dev *vxlan, | |||
469 | /* Look up Ethernet address in forwarding table */ | 469 | /* Look up Ethernet address in forwarding table */ |
470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, | 470 | static struct vxlan_fdb *__vxlan_find_mac(struct vxlan_dev *vxlan, |
471 | const u8 *mac) | 471 | const u8 *mac) |
472 | |||
473 | { | 472 | { |
474 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); | 473 | struct hlist_head *head = vxlan_fdb_head(vxlan, mac); |
475 | struct vxlan_fdb *f; | 474 | struct vxlan_fdb *f; |
@@ -596,10 +595,8 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, struct sk_buff | |||
596 | NAPI_GRO_CB(p)->same_flow = 0; | 595 | NAPI_GRO_CB(p)->same_flow = 0; |
597 | continue; | 596 | continue; |
598 | } | 597 | } |
599 | goto found; | ||
600 | } | 598 | } |
601 | 599 | ||
602 | found: | ||
603 | type = eh->h_proto; | 600 | type = eh->h_proto; |
604 | 601 | ||
605 | rcu_read_lock(); | 602 | rcu_read_lock(); |
@@ -1321,6 +1318,9 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb) | |||
1321 | 1318 | ||
1322 | neigh_release(n); | 1319 | neigh_release(n); |
1323 | 1320 | ||
1321 | if (reply == NULL) | ||
1322 | goto out; | ||
1323 | |||
1324 | skb_reset_mac_header(reply); | 1324 | skb_reset_mac_header(reply); |
1325 | __skb_pull(reply, skb_network_offset(reply)); | 1325 | __skb_pull(reply, skb_network_offset(reply)); |
1326 | reply->ip_summed = CHECKSUM_UNNECESSARY; | 1326 | reply->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -1342,15 +1342,103 @@ out: | |||
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | #if IS_ENABLED(CONFIG_IPV6) | 1344 | #if IS_ENABLED(CONFIG_IPV6) |
1345 | |||
1346 | static struct sk_buff *vxlan_na_create(struct sk_buff *request, | ||
1347 | struct neighbour *n, bool isrouter) | ||
1348 | { | ||
1349 | struct net_device *dev = request->dev; | ||
1350 | struct sk_buff *reply; | ||
1351 | struct nd_msg *ns, *na; | ||
1352 | struct ipv6hdr *pip6; | ||
1353 | u8 *daddr; | ||
1354 | int na_olen = 8; /* opt hdr + ETH_ALEN for target */ | ||
1355 | int ns_olen; | ||
1356 | int i, len; | ||
1357 | |||
1358 | if (dev == NULL) | ||
1359 | return NULL; | ||
1360 | |||
1361 | len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) + | ||
1362 | sizeof(*na) + na_olen + dev->needed_tailroom; | ||
1363 | reply = alloc_skb(len, GFP_ATOMIC); | ||
1364 | if (reply == NULL) | ||
1365 | return NULL; | ||
1366 | |||
1367 | reply->protocol = htons(ETH_P_IPV6); | ||
1368 | reply->dev = dev; | ||
1369 | skb_reserve(reply, LL_RESERVED_SPACE(request->dev)); | ||
1370 | skb_push(reply, sizeof(struct ethhdr)); | ||
1371 | skb_set_mac_header(reply, 0); | ||
1372 | |||
1373 | ns = (struct nd_msg *)skb_transport_header(request); | ||
1374 | |||
1375 | daddr = eth_hdr(request)->h_source; | ||
1376 | ns_olen = request->len - skb_transport_offset(request) - sizeof(*ns); | ||
1377 | for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) { | ||
1378 | if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { | ||
1379 | daddr = ns->opt + i + sizeof(struct nd_opt_hdr); | ||
1380 | break; | ||
1381 | } | ||
1382 | } | ||
1383 | |||
1384 | /* Ethernet header */ | ||
1385 | ether_addr_copy(eth_hdr(reply)->h_dest, daddr); | ||
1386 | ether_addr_copy(eth_hdr(reply)->h_source, n->ha); | ||
1387 | eth_hdr(reply)->h_proto = htons(ETH_P_IPV6); | ||
1388 | reply->protocol = htons(ETH_P_IPV6); | ||
1389 | |||
1390 | skb_pull(reply, sizeof(struct ethhdr)); | ||
1391 | skb_set_network_header(reply, 0); | ||
1392 | skb_put(reply, sizeof(struct ipv6hdr)); | ||
1393 | |||
1394 | /* IPv6 header */ | ||
1395 | |||
1396 | pip6 = ipv6_hdr(reply); | ||
1397 | memset(pip6, 0, sizeof(struct ipv6hdr)); | ||
1398 | pip6->version = 6; | ||
1399 | pip6->priority = ipv6_hdr(request)->priority; | ||
1400 | pip6->nexthdr = IPPROTO_ICMPV6; | ||
1401 | pip6->hop_limit = 255; | ||
1402 | pip6->daddr = ipv6_hdr(request)->saddr; | ||
1403 | pip6->saddr = *(struct in6_addr *)n->primary_key; | ||
1404 | |||
1405 | skb_pull(reply, sizeof(struct ipv6hdr)); | ||
1406 | skb_set_transport_header(reply, 0); | ||
1407 | |||
1408 | na = (struct nd_msg *)skb_put(reply, sizeof(*na) + na_olen); | ||
1409 | |||
1410 | /* Neighbor Advertisement */ | ||
1411 | memset(na, 0, sizeof(*na)+na_olen); | ||
1412 | na->icmph.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT; | ||
1413 | na->icmph.icmp6_router = isrouter; | ||
1414 | na->icmph.icmp6_override = 1; | ||
1415 | na->icmph.icmp6_solicited = 1; | ||
1416 | na->target = ns->target; | ||
1417 | ether_addr_copy(&na->opt[2], n->ha); | ||
1418 | na->opt[0] = ND_OPT_TARGET_LL_ADDR; | ||
1419 | na->opt[1] = na_olen >> 3; | ||
1420 | |||
1421 | na->icmph.icmp6_cksum = csum_ipv6_magic(&pip6->saddr, | ||
1422 | &pip6->daddr, sizeof(*na)+na_olen, IPPROTO_ICMPV6, | ||
1423 | csum_partial(na, sizeof(*na)+na_olen, 0)); | ||
1424 | |||
1425 | pip6->payload_len = htons(sizeof(*na)+na_olen); | ||
1426 | |||
1427 | skb_push(reply, sizeof(struct ipv6hdr)); | ||
1428 | |||
1429 | reply->ip_summed = CHECKSUM_UNNECESSARY; | ||
1430 | |||
1431 | return reply; | ||
1432 | } | ||
1433 | |||
1345 | static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) | 1434 | static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) |
1346 | { | 1435 | { |
1347 | struct vxlan_dev *vxlan = netdev_priv(dev); | 1436 | struct vxlan_dev *vxlan = netdev_priv(dev); |
1348 | struct neighbour *n; | 1437 | struct nd_msg *msg; |
1349 | union vxlan_addr ipa; | ||
1350 | const struct ipv6hdr *iphdr; | 1438 | const struct ipv6hdr *iphdr; |
1351 | const struct in6_addr *saddr, *daddr; | 1439 | const struct in6_addr *saddr, *daddr; |
1352 | struct nd_msg *msg; | 1440 | struct neighbour *n; |
1353 | struct inet6_dev *in6_dev = NULL; | 1441 | struct inet6_dev *in6_dev; |
1354 | 1442 | ||
1355 | in6_dev = __in6_dev_get(dev); | 1443 | in6_dev = __in6_dev_get(dev); |
1356 | if (!in6_dev) | 1444 | if (!in6_dev) |
@@ -1363,19 +1451,20 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) | |||
1363 | saddr = &iphdr->saddr; | 1451 | saddr = &iphdr->saddr; |
1364 | daddr = &iphdr->daddr; | 1452 | daddr = &iphdr->daddr; |
1365 | 1453 | ||
1366 | if (ipv6_addr_loopback(daddr) || | ||
1367 | ipv6_addr_is_multicast(daddr)) | ||
1368 | goto out; | ||
1369 | |||
1370 | msg = (struct nd_msg *)skb_transport_header(skb); | 1454 | msg = (struct nd_msg *)skb_transport_header(skb); |
1371 | if (msg->icmph.icmp6_code != 0 || | 1455 | if (msg->icmph.icmp6_code != 0 || |
1372 | msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION) | 1456 | msg->icmph.icmp6_type != NDISC_NEIGHBOUR_SOLICITATION) |
1373 | goto out; | 1457 | goto out; |
1374 | 1458 | ||
1375 | n = neigh_lookup(ipv6_stub->nd_tbl, daddr, dev); | 1459 | if (ipv6_addr_loopback(daddr) || |
1460 | ipv6_addr_is_multicast(&msg->target)) | ||
1461 | goto out; | ||
1462 | |||
1463 | n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, dev); | ||
1376 | 1464 | ||
1377 | if (n) { | 1465 | if (n) { |
1378 | struct vxlan_fdb *f; | 1466 | struct vxlan_fdb *f; |
1467 | struct sk_buff *reply; | ||
1379 | 1468 | ||
1380 | if (!(n->nud_state & NUD_CONNECTED)) { | 1469 | if (!(n->nud_state & NUD_CONNECTED)) { |
1381 | neigh_release(n); | 1470 | neigh_release(n); |
@@ -1389,13 +1478,23 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb) | |||
1389 | goto out; | 1478 | goto out; |
1390 | } | 1479 | } |
1391 | 1480 | ||
1392 | ipv6_stub->ndisc_send_na(dev, n, saddr, &msg->target, | 1481 | reply = vxlan_na_create(skb, n, |
1393 | !!in6_dev->cnf.forwarding, | 1482 | !!(f ? f->flags & NTF_ROUTER : 0)); |
1394 | true, false, false); | 1483 | |
1395 | neigh_release(n); | 1484 | neigh_release(n); |
1485 | |||
1486 | if (reply == NULL) | ||
1487 | goto out; | ||
1488 | |||
1489 | if (netif_rx_ni(reply) == NET_RX_DROP) | ||
1490 | dev->stats.rx_dropped++; | ||
1491 | |||
1396 | } else if (vxlan->flags & VXLAN_F_L3MISS) { | 1492 | } else if (vxlan->flags & VXLAN_F_L3MISS) { |
1397 | ipa.sin6.sin6_addr = *daddr; | 1493 | union vxlan_addr ipa = { |
1398 | ipa.sa.sa_family = AF_INET6; | 1494 | .sin6.sin6_addr = msg->target, |
1495 | .sa.sa_family = AF_INET6, | ||
1496 | }; | ||
1497 | |||
1399 | vxlan_ip_miss(dev, &ipa); | 1498 | vxlan_ip_miss(dev, &ipa); |
1400 | } | 1499 | } |
1401 | 1500 | ||
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 0d1c7592efa0..19f7cb2cdef3 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c | |||
@@ -71,12 +71,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
71 | const void *saddr, unsigned len) | 71 | const void *saddr, unsigned len) |
72 | { | 72 | { |
73 | struct frhdr hdr; | 73 | struct frhdr hdr; |
74 | struct dlci_local *dlp; | ||
75 | unsigned int hlen; | 74 | unsigned int hlen; |
76 | char *dest; | 75 | char *dest; |
77 | 76 | ||
78 | dlp = netdev_priv(dev); | ||
79 | |||
80 | hdr.control = FRAD_I_UI; | 77 | hdr.control = FRAD_I_UI; |
81 | switch (type) | 78 | switch (type) |
82 | { | 79 | { |
@@ -107,11 +104,9 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, | |||
107 | 104 | ||
108 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) | 105 | static void dlci_receive(struct sk_buff *skb, struct net_device *dev) |
109 | { | 106 | { |
110 | struct dlci_local *dlp; | ||
111 | struct frhdr *hdr; | 107 | struct frhdr *hdr; |
112 | int process, header; | 108 | int process, header; |
113 | 109 | ||
114 | dlp = netdev_priv(dev); | ||
115 | if (!pskb_may_pull(skb, sizeof(*hdr))) { | 110 | if (!pskb_may_pull(skb, sizeof(*hdr))) { |
116 | netdev_notice(dev, "invalid data no header\n"); | 111 | netdev_notice(dev, "invalid data no header\n"); |
117 | dev->stats.rx_errors++; | 112 | dev->stats.rx_errors++; |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 8aa20df55e50..507d9a9ee69a 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -1764,7 +1764,7 @@ static struct usb_device_id ar5523_id_table[] = { | |||
1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ | 1764 | AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ |
1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ | 1765 | AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ |
1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ | 1766 | AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ |
1767 | AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 | 1767 | AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108 |
1768 | (CyberTAN Technology) */ | 1768 | (CyberTAN Technology) */ |
1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ | 1769 | AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */ |
1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ | 1770 | AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index d6bc7cb61bfb..1a2973b7acf2 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -110,7 +110,7 @@ ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band) | |||
110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); | 110 | ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); |
111 | 111 | ||
112 | if (ah->ah_version == AR5K_AR5210) { | 112 | if (ah->ah_version == AR5K_AR5210) { |
113 | srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; | 113 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(256)) >> 28) & 0xf; |
114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; | 114 | ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; |
115 | } else { | 115 | } else { |
116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; | 116 | srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 25243cbc07f0..b8daff78b9d1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | |||
5065 | break; | 5065 | break; |
5066 | } | 5066 | } |
5067 | } | 5067 | } |
5068 | |||
5069 | if (is2GHz && !twiceMaxEdgePower) | ||
5070 | twiceMaxEdgePower = 60; | ||
5071 | |||
5068 | return twiceMaxEdgePower; | 5072 | return twiceMaxEdgePower; |
5069 | } | 5073 | } |
5070 | 5074 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 1cc13569b17b..1b6b4d0cfa97 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -57,7 +57,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, | 57 | {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, |
58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 58 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 59 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
60 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 60 | {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, |
61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | 61 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, |
62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, | 62 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, |
63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, | 63 | {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, |
@@ -96,7 +96,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, | 96 | {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, |
97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 97 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | 98 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, |
99 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | 99 | {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, |
100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, | 100 | {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, |
101 | }; | 101 | }; |
102 | 102 | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 58da3468d1f0..99a203174f45 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -262,6 +262,8 @@ enum tid_aggr_state { | |||
262 | struct ath9k_htc_sta { | 262 | struct ath9k_htc_sta { |
263 | u8 index; | 263 | u8 index; |
264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; | 264 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; |
265 | struct work_struct rc_update_work; | ||
266 | struct ath9k_htc_priv *htc_priv; | ||
265 | }; | 267 | }; |
266 | 268 | ||
267 | #define ATH9K_HTC_RXBUF 256 | 269 | #define ATH9K_HTC_RXBUF 256 |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index f4e1de20d99c..c57d6b859c04 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -34,6 +34,10 @@ static int ath9k_htc_btcoex_enable; | |||
34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); | 34 | module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); |
35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 35 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
36 | 36 | ||
37 | static int ath9k_ps_enable; | ||
38 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
39 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
40 | |||
37 | #define CHAN2G(_freq, _idx) { \ | 41 | #define CHAN2G(_freq, _idx) { \ |
38 | .center_freq = (_freq), \ | 42 | .center_freq = (_freq), \ |
39 | .hw_value = (_idx), \ | 43 | .hw_value = (_idx), \ |
@@ -725,12 +729,14 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
725 | IEEE80211_HW_SPECTRUM_MGMT | | 729 | IEEE80211_HW_SPECTRUM_MGMT | |
726 | IEEE80211_HW_HAS_RATE_CONTROL | | 730 | IEEE80211_HW_HAS_RATE_CONTROL | |
727 | IEEE80211_HW_RX_INCLUDES_FCS | | 731 | IEEE80211_HW_RX_INCLUDES_FCS | |
728 | IEEE80211_HW_SUPPORTS_PS | | ||
729 | IEEE80211_HW_PS_NULLFUNC_STACK | | 732 | IEEE80211_HW_PS_NULLFUNC_STACK | |
730 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 733 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
731 | IEEE80211_HW_MFP_CAPABLE | | 734 | IEEE80211_HW_MFP_CAPABLE | |
732 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 735 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; |
733 | 736 | ||
737 | if (ath9k_ps_enable) | ||
738 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
739 | |||
734 | hw->wiphy->interface_modes = | 740 | hw->wiphy->interface_modes = |
735 | BIT(NL80211_IFTYPE_STATION) | | 741 | BIT(NL80211_IFTYPE_STATION) | |
736 | BIT(NL80211_IFTYPE_ADHOC) | | 742 | BIT(NL80211_IFTYPE_ADHOC) | |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 608d739d1378..c9254a61ca52 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | |||
1270 | mutex_unlock(&priv->mutex); | 1270 | mutex_unlock(&priv->mutex); |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | static void ath9k_htc_sta_rc_update_work(struct work_struct *work) | ||
1274 | { | ||
1275 | struct ath9k_htc_sta *ista = | ||
1276 | container_of(work, struct ath9k_htc_sta, rc_update_work); | ||
1277 | struct ieee80211_sta *sta = | ||
1278 | container_of((void *)ista, struct ieee80211_sta, drv_priv); | ||
1279 | struct ath9k_htc_priv *priv = ista->htc_priv; | ||
1280 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1281 | struct ath9k_htc_target_rate trate; | ||
1282 | |||
1283 | mutex_lock(&priv->mutex); | ||
1284 | ath9k_htc_ps_wakeup(priv); | ||
1285 | |||
1286 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | ||
1287 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
1288 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
1289 | ath_dbg(common, CONFIG, | ||
1290 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
1291 | sta->addr, be32_to_cpu(trate.capflags)); | ||
1292 | else | ||
1293 | ath_dbg(common, CONFIG, | ||
1294 | "Unable to update supported rates for sta: %pM\n", | ||
1295 | sta->addr); | ||
1296 | |||
1297 | ath9k_htc_ps_restore(priv); | ||
1298 | mutex_unlock(&priv->mutex); | ||
1299 | } | ||
1300 | |||
1273 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, | 1301 | static int ath9k_htc_sta_add(struct ieee80211_hw *hw, |
1274 | struct ieee80211_vif *vif, | 1302 | struct ieee80211_vif *vif, |
1275 | struct ieee80211_sta *sta) | 1303 | struct ieee80211_sta *sta) |
1276 | { | 1304 | { |
1277 | struct ath9k_htc_priv *priv = hw->priv; | 1305 | struct ath9k_htc_priv *priv = hw->priv; |
1306 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1278 | int ret; | 1307 | int ret; |
1279 | 1308 | ||
1280 | mutex_lock(&priv->mutex); | 1309 | mutex_lock(&priv->mutex); |
1281 | ath9k_htc_ps_wakeup(priv); | 1310 | ath9k_htc_ps_wakeup(priv); |
1282 | ret = ath9k_htc_add_station(priv, vif, sta); | 1311 | ret = ath9k_htc_add_station(priv, vif, sta); |
1283 | if (!ret) | 1312 | if (!ret) { |
1313 | INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work); | ||
1314 | ista->htc_priv = priv; | ||
1284 | ath9k_htc_init_rate(priv, sta); | 1315 | ath9k_htc_init_rate(priv, sta); |
1316 | } | ||
1285 | ath9k_htc_ps_restore(priv); | 1317 | ath9k_htc_ps_restore(priv); |
1286 | mutex_unlock(&priv->mutex); | 1318 | mutex_unlock(&priv->mutex); |
1287 | 1319 | ||
@@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, | |||
1293 | struct ieee80211_sta *sta) | 1325 | struct ieee80211_sta *sta) |
1294 | { | 1326 | { |
1295 | struct ath9k_htc_priv *priv = hw->priv; | 1327 | struct ath9k_htc_priv *priv = hw->priv; |
1296 | struct ath9k_htc_sta *ista; | 1328 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
1297 | int ret; | 1329 | int ret; |
1298 | 1330 | ||
1331 | cancel_work_sync(&ista->rc_update_work); | ||
1332 | |||
1299 | mutex_lock(&priv->mutex); | 1333 | mutex_lock(&priv->mutex); |
1300 | ath9k_htc_ps_wakeup(priv); | 1334 | ath9k_htc_ps_wakeup(priv); |
1301 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1302 | htc_sta_drain(priv->htc, ista->index); | 1335 | htc_sta_drain(priv->htc, ista->index); |
1303 | ret = ath9k_htc_remove_station(priv, vif, sta); | 1336 | ret = ath9k_htc_remove_station(priv, vif, sta); |
1304 | ath9k_htc_ps_restore(priv); | 1337 | ath9k_htc_ps_restore(priv); |
@@ -1311,28 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, | |||
1311 | struct ieee80211_vif *vif, | 1344 | struct ieee80211_vif *vif, |
1312 | struct ieee80211_sta *sta, u32 changed) | 1345 | struct ieee80211_sta *sta, u32 changed) |
1313 | { | 1346 | { |
1314 | struct ath9k_htc_priv *priv = hw->priv; | 1347 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; |
1315 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1316 | struct ath9k_htc_target_rate trate; | ||
1317 | |||
1318 | mutex_lock(&priv->mutex); | ||
1319 | ath9k_htc_ps_wakeup(priv); | ||
1320 | 1348 | ||
1321 | if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { | 1349 | if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED)) |
1322 | memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); | 1350 | return; |
1323 | ath9k_htc_setup_rate(priv, sta, &trate); | ||
1324 | if (!ath9k_htc_send_rate_cmd(priv, &trate)) | ||
1325 | ath_dbg(common, CONFIG, | ||
1326 | "Supported rates for sta: %pM updated, rate caps: 0x%X\n", | ||
1327 | sta->addr, be32_to_cpu(trate.capflags)); | ||
1328 | else | ||
1329 | ath_dbg(common, CONFIG, | ||
1330 | "Unable to update supported rates for sta: %pM\n", | ||
1331 | sta->addr); | ||
1332 | } | ||
1333 | 1351 | ||
1334 | ath9k_htc_ps_restore(priv); | 1352 | schedule_work(&ista->rc_update_work); |
1335 | mutex_unlock(&priv->mutex); | ||
1336 | } | 1353 | } |
1337 | 1354 | ||
1338 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | 1355 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index fbf43c05713f..9078a6c5a74e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1316 | if (AR_SREV_9300_20_OR_LATER(ah)) | 1316 | if (AR_SREV_9300_20_OR_LATER(ah)) |
1317 | udelay(50); | 1317 | udelay(50); |
1318 | else if (AR_SREV_9100(ah)) | 1318 | else if (AR_SREV_9100(ah)) |
1319 | udelay(10000); | 1319 | mdelay(10); |
1320 | else | 1320 | else |
1321 | udelay(100); | 1321 | udelay(100); |
1322 | 1322 | ||
@@ -1534,7 +1534,7 @@ EXPORT_SYMBOL(ath9k_hw_check_nav); | |||
1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) | 1534 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
1535 | { | 1535 | { |
1536 | int count = 50; | 1536 | int count = 50; |
1537 | u32 reg; | 1537 | u32 reg, last_val; |
1538 | 1538 | ||
1539 | if (AR_SREV_9300(ah)) | 1539 | if (AR_SREV_9300(ah)) |
1540 | return !ath9k_hw_detect_mac_hang(ah); | 1540 | return !ath9k_hw_detect_mac_hang(ah); |
@@ -1542,9 +1542,14 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
1542 | if (AR_SREV_9285_12_OR_LATER(ah)) | 1542 | if (AR_SREV_9285_12_OR_LATER(ah)) |
1543 | return true; | 1543 | return true; |
1544 | 1544 | ||
1545 | last_val = REG_READ(ah, AR_OBS_BUS_1); | ||
1545 | do { | 1546 | do { |
1546 | reg = REG_READ(ah, AR_OBS_BUS_1); | 1547 | reg = REG_READ(ah, AR_OBS_BUS_1); |
1548 | if (reg != last_val) | ||
1549 | return true; | ||
1547 | 1550 | ||
1551 | udelay(1); | ||
1552 | last_val = reg; | ||
1548 | if ((reg & 0x7E7FFFEF) == 0x00702400) | 1553 | if ((reg & 0x7E7FFFEF) == 0x00702400) |
1549 | continue; | 1554 | continue; |
1550 | 1555 | ||
@@ -2051,9 +2056,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) | |||
2051 | 2056 | ||
2052 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, | 2057 | REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, |
2053 | AR_RTC_FORCE_WAKE_EN); | 2058 | AR_RTC_FORCE_WAKE_EN); |
2054 | |||
2055 | if (AR_SREV_9100(ah)) | 2059 | if (AR_SREV_9100(ah)) |
2056 | udelay(10000); | 2060 | mdelay(10); |
2057 | else | 2061 | else |
2058 | udelay(50); | 2062 | udelay(50); |
2059 | 2063 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c36de303c8f3..1fc2e5a26b52 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity; | |||
57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); | 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); |
58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); | 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); |
59 | 59 | ||
60 | static int ath9k_ps_enable; | ||
61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
63 | |||
60 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
61 | /* We use the hw_value as an index into our private channel structure */ | 65 | /* We use the hw_value as an index into our private channel structure */ |
62 | 66 | ||
@@ -903,13 +907,15 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
903 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
904 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 908 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
905 | IEEE80211_HW_SIGNAL_DBM | | 909 | IEEE80211_HW_SIGNAL_DBM | |
906 | IEEE80211_HW_SUPPORTS_PS | | ||
907 | IEEE80211_HW_PS_NULLFUNC_STACK | | 910 | IEEE80211_HW_PS_NULLFUNC_STACK | |
908 | IEEE80211_HW_SPECTRUM_MGMT | | 911 | IEEE80211_HW_SPECTRUM_MGMT | |
909 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 912 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
910 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 913 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
911 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 914 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
912 | 915 | ||
916 | if (ath9k_ps_enable) | ||
917 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
918 | |||
913 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 919 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
914 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 920 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
915 | 921 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a0ebdd000fc2..82e340d3ec60 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -732,11 +732,18 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, | |||
732 | return NULL; | 732 | return NULL; |
733 | 733 | ||
734 | /* | 734 | /* |
735 | * mark descriptor as zero-length and set the 'more' | 735 | * Re-check previous descriptor, in case it has been filled |
736 | * flag to ensure that both buffers get discarded | 736 | * in the mean time. |
737 | */ | 737 | */ |
738 | rs->rs_datalen = 0; | 738 | ret = ath9k_hw_rxprocdesc(ah, ds, rs); |
739 | rs->rs_more = true; | 739 | if (ret == -EINPROGRESS) { |
740 | /* | ||
741 | * mark descriptor as zero-length and set the 'more' | ||
742 | * flag to ensure that both buffers get discarded | ||
743 | */ | ||
744 | rs->rs_datalen = 0; | ||
745 | rs->rs_more = true; | ||
746 | } | ||
740 | } | 747 | } |
741 | 748 | ||
742 | list_del(&bf->list); | 749 | list_del(&bf->list); |
@@ -985,32 +992,32 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
985 | struct ath_common *common = ath9k_hw_common(ah); | 992 | struct ath_common *common = ath9k_hw_common(ah); |
986 | struct ieee80211_hdr *hdr; | 993 | struct ieee80211_hdr *hdr; |
987 | bool discard_current = sc->rx.discard_next; | 994 | bool discard_current = sc->rx.discard_next; |
988 | int ret = 0; | ||
989 | 995 | ||
990 | /* | 996 | /* |
991 | * Discard corrupt descriptors which are marked in | 997 | * Discard corrupt descriptors which are marked in |
992 | * ath_get_next_rx_buf(). | 998 | * ath_get_next_rx_buf(). |
993 | */ | 999 | */ |
994 | sc->rx.discard_next = rx_stats->rs_more; | ||
995 | if (discard_current) | 1000 | if (discard_current) |
996 | return -EINVAL; | 1001 | goto corrupt; |
1002 | |||
1003 | sc->rx.discard_next = false; | ||
997 | 1004 | ||
998 | /* | 1005 | /* |
999 | * Discard zero-length packets. | 1006 | * Discard zero-length packets. |
1000 | */ | 1007 | */ |
1001 | if (!rx_stats->rs_datalen) { | 1008 | if (!rx_stats->rs_datalen) { |
1002 | RX_STAT_INC(rx_len_err); | 1009 | RX_STAT_INC(rx_len_err); |
1003 | return -EINVAL; | 1010 | goto corrupt; |
1004 | } | 1011 | } |
1005 | 1012 | ||
1006 | /* | 1013 | /* |
1007 | * rs_status follows rs_datalen so if rs_datalen is too large | 1014 | * rs_status follows rs_datalen so if rs_datalen is too large |
1008 | * we can take a hint that hardware corrupted it, so ignore | 1015 | * we can take a hint that hardware corrupted it, so ignore |
1009 | * those frames. | 1016 | * those frames. |
1010 | */ | 1017 | */ |
1011 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { | 1018 | if (rx_stats->rs_datalen > (common->rx_bufsize - ah->caps.rx_status_len)) { |
1012 | RX_STAT_INC(rx_len_err); | 1019 | RX_STAT_INC(rx_len_err); |
1013 | return -EINVAL; | 1020 | goto corrupt; |
1014 | } | 1021 | } |
1015 | 1022 | ||
1016 | /* Only use status info from the last fragment */ | 1023 | /* Only use status info from the last fragment */ |
@@ -1024,10 +1031,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1024 | * This is different from the other corrupt descriptor | 1031 | * This is different from the other corrupt descriptor |
1025 | * condition handled above. | 1032 | * condition handled above. |
1026 | */ | 1033 | */ |
1027 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) { | 1034 | if (rx_stats->rs_status & ATH9K_RXERR_CORRUPT_DESC) |
1028 | ret = -EINVAL; | 1035 | goto corrupt; |
1029 | goto exit; | ||
1030 | } | ||
1031 | 1036 | ||
1032 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); | 1037 | hdr = (struct ieee80211_hdr *) (skb->data + ah->caps.rx_status_len); |
1033 | 1038 | ||
@@ -1043,18 +1048,15 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1043 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) | 1048 | if (ath_process_fft(sc, hdr, rx_stats, rx_status->mactime)) |
1044 | RX_STAT_INC(rx_spectral); | 1049 | RX_STAT_INC(rx_spectral); |
1045 | 1050 | ||
1046 | ret = -EINVAL; | 1051 | return -EINVAL; |
1047 | goto exit; | ||
1048 | } | 1052 | } |
1049 | 1053 | ||
1050 | /* | 1054 | /* |
1051 | * everything but the rate is checked here, the rate check is done | 1055 | * everything but the rate is checked here, the rate check is done |
1052 | * separately to avoid doing two lookups for a rate for each frame. | 1056 | * separately to avoid doing two lookups for a rate for each frame. |
1053 | */ | 1057 | */ |
1054 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) { | 1058 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) |
1055 | ret = -EINVAL; | 1059 | return -EINVAL; |
1056 | goto exit; | ||
1057 | } | ||
1058 | 1060 | ||
1059 | if (ath_is_mybeacon(common, hdr)) { | 1061 | if (ath_is_mybeacon(common, hdr)) { |
1060 | RX_STAT_INC(rx_beacons); | 1062 | RX_STAT_INC(rx_beacons); |
@@ -1064,15 +1066,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1064 | /* | 1066 | /* |
1065 | * This shouldn't happen, but have a safety check anyway. | 1067 | * This shouldn't happen, but have a safety check anyway. |
1066 | */ | 1068 | */ |
1067 | if (WARN_ON(!ah->curchan)) { | 1069 | if (WARN_ON(!ah->curchan)) |
1068 | ret = -EINVAL; | 1070 | return -EINVAL; |
1069 | goto exit; | ||
1070 | } | ||
1071 | 1071 | ||
1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1072 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
1073 | ret =-EINVAL; | 1073 | return -EINVAL; |
1074 | goto exit; | ||
1075 | } | ||
1076 | 1074 | ||
1077 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1075 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
1078 | 1076 | ||
@@ -1087,9 +1085,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1087 | sc->rx.num_pkts++; | 1085 | sc->rx.num_pkts++; |
1088 | #endif | 1086 | #endif |
1089 | 1087 | ||
1090 | exit: | 1088 | return 0; |
1091 | sc->rx.discard_next = false; | 1089 | |
1092 | return ret; | 1090 | corrupt: |
1091 | sc->rx.discard_next = rx_stats->rs_more; | ||
1092 | return -EINVAL; | ||
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, | 1095 | static void ath9k_rx_skb_postprocess(struct ath_common *common, |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 0a75e2f68c9d..55897d508a76 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1444,14 +1444,16 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
1444 | for (tidno = 0, tid = &an->tid[tidno]; | 1444 | for (tidno = 0, tid = &an->tid[tidno]; |
1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { | 1445 | tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { |
1446 | 1446 | ||
1447 | if (!tid->sched) | ||
1448 | continue; | ||
1449 | |||
1450 | ac = tid->ac; | 1447 | ac = tid->ac; |
1451 | txq = ac->txq; | 1448 | txq = ac->txq; |
1452 | 1449 | ||
1453 | ath_txq_lock(sc, txq); | 1450 | ath_txq_lock(sc, txq); |
1454 | 1451 | ||
1452 | if (!tid->sched) { | ||
1453 | ath_txq_unlock(sc, txq); | ||
1454 | continue; | ||
1455 | } | ||
1456 | |||
1455 | buffered = ath_tid_has_buffered(tid); | 1457 | buffered = ath_tid_has_buffered(tid); |
1456 | 1458 | ||
1457 | tid->sched = false; | 1459 | tid->sched = false; |
@@ -2061,7 +2063,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, | |||
2061 | 2063 | ||
2062 | ATH_TXBUF_RESET(bf); | 2064 | ATH_TXBUF_RESET(bf); |
2063 | 2065 | ||
2064 | if (tid) { | 2066 | if (tid && ieee80211_is_data_present(hdr->frame_control)) { |
2065 | fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 2067 | fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
2066 | seqno = tid->seq_next; | 2068 | seqno = tid->seq_next; |
2067 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); | 2069 | hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); |
@@ -2184,14 +2186,15 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2184 | txq->stopped = true; | 2186 | txq->stopped = true; |
2185 | } | 2187 | } |
2186 | 2188 | ||
2189 | if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) | ||
2190 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
2191 | |||
2187 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { | 2192 | if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { |
2188 | ath_txq_unlock(sc, txq); | 2193 | ath_txq_unlock(sc, txq); |
2189 | txq = sc->tx.uapsdq; | 2194 | txq = sc->tx.uapsdq; |
2190 | ath_txq_lock(sc, txq); | 2195 | ath_txq_lock(sc, txq); |
2191 | } else if (txctl->an && | 2196 | } else if (txctl->an && |
2192 | ieee80211_is_data_present(hdr->frame_control)) { | 2197 | ieee80211_is_data_present(hdr->frame_control)) { |
2193 | tid = ath_get_skb_tid(sc, txctl->an, skb); | ||
2194 | |||
2195 | WARN_ON(tid->ac->txq != txctl->txq); | 2198 | WARN_ON(tid->ac->txq != txctl->txq); |
2196 | 2199 | ||
2197 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) | 2200 | if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3e991897d7ca..ddaa9efd053d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -457,7 +457,6 @@ struct brcmf_sdio { | |||
457 | 457 | ||
458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ | 458 | u8 tx_hdrlen; /* sdio bus header length for tx packet */ |
459 | bool txglom; /* host tx glomming enable flag */ | 459 | bool txglom; /* host tx glomming enable flag */ |
460 | struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ | ||
461 | u16 head_align; /* buffer pointer alignment */ | 460 | u16 head_align; /* buffer pointer alignment */ |
462 | u16 sgentry_align; /* scatter-gather buffer alignment */ | 461 | u16 sgentry_align; /* scatter-gather buffer alignment */ |
463 | }; | 462 | }; |
@@ -1944,19 +1943,21 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, | |||
1944 | if (lastfrm && chain_pad) | 1943 | if (lastfrm && chain_pad) |
1945 | tail_pad += blksize - chain_pad; | 1944 | tail_pad += blksize - chain_pad; |
1946 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { | 1945 | if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { |
1947 | pkt_pad = bus->txglom_sgpad; | 1946 | pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop + |
1948 | if (pkt_pad == NULL) | 1947 | bus->head_align); |
1949 | brcmu_pkt_buf_get_skb(tail_pad + tail_chop); | ||
1950 | if (pkt_pad == NULL) | 1948 | if (pkt_pad == NULL) |
1951 | return -ENOMEM; | 1949 | return -ENOMEM; |
1952 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); | 1950 | ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); |
1953 | if (unlikely(ret < 0)) | 1951 | if (unlikely(ret < 0)) { |
1952 | kfree_skb(pkt_pad); | ||
1954 | return ret; | 1953 | return ret; |
1954 | } | ||
1955 | memcpy(pkt_pad->data, | 1955 | memcpy(pkt_pad->data, |
1956 | pkt->data + pkt->len - tail_chop, | 1956 | pkt->data + pkt->len - tail_chop, |
1957 | tail_chop); | 1957 | tail_chop); |
1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; | 1958 | *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; |
1959 | skb_trim(pkt, pkt->len - tail_chop); | 1959 | skb_trim(pkt, pkt->len - tail_chop); |
1960 | skb_trim(pkt_pad, tail_pad + tail_chop); | ||
1960 | __skb_queue_after(pktq, pkt, pkt_pad); | 1961 | __skb_queue_after(pktq, pkt, pkt_pad); |
1961 | } else { | 1962 | } else { |
1962 | ntail = pkt->data_len + tail_pad - | 1963 | ntail = pkt->data_len + tail_pad - |
@@ -2011,7 +2012,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
2011 | return ret; | 2012 | return ret; |
2012 | head_pad = (u16)ret; | 2013 | head_pad = (u16)ret; |
2013 | if (head_pad) | 2014 | if (head_pad) |
2014 | memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); | 2015 | memset(pkt_next->data + bus->tx_hdrlen, 0, head_pad); |
2015 | 2016 | ||
2016 | total_len += pkt_next->len; | 2017 | total_len += pkt_next->len; |
2017 | 2018 | ||
@@ -3486,10 +3487,6 @@ static int brcmf_sdio_bus_preinit(struct device *dev) | |||
3486 | bus->txglom = false; | 3487 | bus->txglom = false; |
3487 | value = 1; | 3488 | value = 1; |
3488 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; | 3489 | pad_size = bus->sdiodev->func[2]->cur_blksize << 1; |
3489 | bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); | ||
3490 | if (!bus->txglom_sgpad) | ||
3491 | brcmf_err("allocating txglom padding skb failed, reduced performance\n"); | ||
3492 | |||
3493 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", | 3490 | err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", |
3494 | &value, sizeof(u32)); | 3491 | &value, sizeof(u32)); |
3495 | if (err < 0) { | 3492 | if (err < 0) { |
@@ -4053,7 +4050,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
4053 | brcmf_sdio_chip_detach(&bus->ci); | 4050 | brcmf_sdio_chip_detach(&bus->ci); |
4054 | } | 4051 | } |
4055 | 4052 | ||
4056 | brcmu_pkt_buf_free_skb(bus->txglom_sgpad); | ||
4057 | kfree(bus->rxbuf); | 4053 | kfree(bus->rxbuf); |
4058 | kfree(bus->hdrbuf); | 4054 | kfree(bus->hdrbuf); |
4059 | kfree(bus); | 4055 | kfree(bus); |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index d36e252d2ccb..596525528f50 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
@@ -147,7 +147,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta) | |||
147 | 147 | ||
148 | if (!sta->ap && sta->u.sta.challenge) | 148 | if (!sta->ap && sta->u.sta.challenge) |
149 | kfree(sta->u.sta.challenge); | 149 | kfree(sta->u.sta.challenge); |
150 | del_timer(&sta->timer); | 150 | del_timer_sync(&sta->timer); |
151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 151 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
152 | 152 | ||
153 | kfree(sta); | 153 | kfree(sta); |
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index aa7ad3a7a69b..4e5c0f8c9496 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -496,7 +496,7 @@ void hostap_init_proc(local_info_t *local) | |||
496 | 496 | ||
497 | void hostap_remove_proc(local_info_t *local) | 497 | void hostap_remove_proc(local_info_t *local) |
498 | { | 498 | { |
499 | remove_proc_subtree(local->ddev->name, hostap_proc); | 499 | proc_remove(local->proc); |
500 | } | 500 | } |
501 | 501 | ||
502 | 502 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index c24d1d3d55f6..73086c1629ca 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -696,6 +696,24 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
696 | return ret; | 696 | return ret; |
697 | } | 697 | } |
698 | 698 | ||
699 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
700 | { | ||
701 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
702 | return false; | ||
703 | return true; | ||
704 | } | ||
705 | |||
706 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
707 | { | ||
708 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
709 | return false; | ||
710 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
711 | return true; | ||
712 | |||
713 | /* disabled by default */ | ||
714 | return false; | ||
715 | } | ||
716 | |||
699 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | 717 | static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, |
700 | struct ieee80211_vif *vif, | 718 | struct ieee80211_vif *vif, |
701 | enum ieee80211_ampdu_mlme_action action, | 719 | enum ieee80211_ampdu_mlme_action action, |
@@ -717,7 +735,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
717 | 735 | ||
718 | switch (action) { | 736 | switch (action) { |
719 | case IEEE80211_AMPDU_RX_START: | 737 | case IEEE80211_AMPDU_RX_START: |
720 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | 738 | if (!iwl_enable_rx_ampdu(priv->cfg)) |
721 | break; | 739 | break; |
722 | IWL_DEBUG_HT(priv, "start Rx\n"); | 740 | IWL_DEBUG_HT(priv, "start Rx\n"); |
723 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); | 741 | ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); |
@@ -729,7 +747,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
729 | case IEEE80211_AMPDU_TX_START: | 747 | case IEEE80211_AMPDU_TX_START: |
730 | if (!priv->trans->ops->txq_enable) | 748 | if (!priv->trans->ops->txq_enable) |
731 | break; | 749 | break; |
732 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | 750 | if (!iwl_enable_tx_ampdu(priv->cfg)) |
733 | break; | 751 | break; |
734 | IWL_DEBUG_HT(priv, "start Tx\n"); | 752 | IWL_DEBUG_HT(priv, "start Tx\n"); |
735 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); | 753 | ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index c0d070c5df5e..9cdd91cdf661 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c | |||
@@ -590,6 +590,7 @@ void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, | |||
590 | sizeof(priv->tid_data[sta_id][tid])); | 590 | sizeof(priv->tid_data[sta_id][tid])); |
591 | 591 | ||
592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | 592 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; |
593 | priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
593 | 594 | ||
594 | priv->num_stations--; | 595 | priv->num_stations--; |
595 | 596 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a6839dfcb82d..398dd096674c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -1291,8 +1291,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; | 1291 | struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; |
1292 | struct iwl_ht_agg *agg; | 1292 | struct iwl_ht_agg *agg; |
1293 | struct sk_buff_head reclaimed_skbs; | 1293 | struct sk_buff_head reclaimed_skbs; |
1294 | struct ieee80211_tx_info *info; | ||
1295 | struct ieee80211_hdr *hdr; | ||
1296 | struct sk_buff *skb; | 1294 | struct sk_buff *skb; |
1297 | int sta_id; | 1295 | int sta_id; |
1298 | int tid; | 1296 | int tid; |
@@ -1379,22 +1377,28 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1379 | freed = 0; | 1377 | freed = 0; |
1380 | 1378 | ||
1381 | skb_queue_walk(&reclaimed_skbs, skb) { | 1379 | skb_queue_walk(&reclaimed_skbs, skb) { |
1382 | hdr = (struct ieee80211_hdr *)skb->data; | 1380 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1381 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1383 | 1382 | ||
1384 | if (ieee80211_is_data_qos(hdr->frame_control)) | 1383 | if (ieee80211_is_data_qos(hdr->frame_control)) |
1385 | freed++; | 1384 | freed++; |
1386 | else | 1385 | else |
1387 | WARN_ON_ONCE(1); | 1386 | WARN_ON_ONCE(1); |
1388 | 1387 | ||
1389 | info = IEEE80211_SKB_CB(skb); | ||
1390 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); | 1388 | iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); |
1391 | 1389 | ||
1390 | memset(&info->status, 0, sizeof(info->status)); | ||
1391 | /* Packet was transmitted successfully, failures come as single | ||
1392 | * frames because before failing a frame the firmware transmits | ||
1393 | * it without aggregation at least once. | ||
1394 | */ | ||
1395 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
1396 | |||
1392 | if (freed == 1) { | 1397 | if (freed == 1) { |
1393 | /* this is the first skb we deliver in this batch */ | 1398 | /* this is the first skb we deliver in this batch */ |
1394 | /* put the rate scaling data there */ | 1399 | /* put the rate scaling data there */ |
1395 | info = IEEE80211_SKB_CB(skb); | 1400 | info = IEEE80211_SKB_CB(skb); |
1396 | memset(&info->status, 0, sizeof(info->status)); | 1401 | memset(&info->status, 0, sizeof(info->status)); |
1397 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
1398 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 1402 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
1399 | info->status.ampdu_ack_len = ba_resp->txed_2_done; | 1403 | info->status.ampdu_ack_len = ba_resp->txed_2_done; |
1400 | info->status.ampdu_len = ba_resp->txed; | 1404 | info->status.ampdu_len = ba_resp->txed; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index c3728163be46..75103554cd63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1286,7 +1286,7 @@ module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO); | |||
1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); | 1286 | MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); |
1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); | 1287 | module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO); |
1288 | MODULE_PARM_DESC(11n_disable, | 1288 | MODULE_PARM_DESC(11n_disable, |
1289 | "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); | 1289 | "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); |
1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, | 1290 | module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, |
1291 | int, S_IRUGO); | 1291 | int, S_IRUGO); |
1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); | 1292 | MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 0a84ade7edac..b29075c3da8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h | |||
@@ -79,9 +79,12 @@ enum iwl_power_level { | |||
79 | IWL_POWER_NUM | 79 | IWL_POWER_NUM |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #define IWL_DISABLE_HT_ALL BIT(0) | 82 | enum iwl_disable_11n { |
83 | #define IWL_DISABLE_HT_TXAGG BIT(1) | 83 | IWL_DISABLE_HT_ALL = BIT(0), |
84 | #define IWL_DISABLE_HT_RXAGG BIT(2) | 84 | IWL_DISABLE_HT_TXAGG = BIT(1), |
85 | IWL_DISABLE_HT_RXAGG = BIT(2), | ||
86 | IWL_ENABLE_HT_TXAGG = BIT(3), | ||
87 | }; | ||
85 | 88 | ||
86 | /** | 89 | /** |
87 | * struct iwl_mod_params | 90 | * struct iwl_mod_params |
@@ -90,7 +93,7 @@ enum iwl_power_level { | |||
90 | * | 93 | * |
91 | * @sw_crypto: using hardware encryption, default = 0 | 94 | * @sw_crypto: using hardware encryption, default = 0 |
92 | * @disable_11n: disable 11n capabilities, default = 0, | 95 | * @disable_11n: disable 11n capabilities, default = 0, |
93 | * use IWL_DISABLE_HT_* constants | 96 | * use IWL_[DIS,EN]ABLE_HT_* constants |
94 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 | 97 | * @amsdu_size_8K: enable 8K amsdu size, default = 0 |
95 | * @restart_fw: restart firmware, default = 1 | 98 | * @restart_fw: restart firmware, default = 1 |
96 | * @wd_disable: enable stuck queue check, default = 0 | 99 | * @wd_disable: enable stuck queue check, default = 0 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index f06f4cbe1317..725e954d8475 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -182,6 +182,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
182 | 182 | ||
183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { | 183 | for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) { |
184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); | 184 | ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx); |
185 | |||
186 | if (ch_idx >= NUM_2GHZ_CHANNELS && | ||
187 | !data->sku_cap_band_52GHz_enable) | ||
188 | ch_flags &= ~NVM_CHANNEL_VALID; | ||
189 | |||
185 | if (!(ch_flags & NVM_CHANNEL_VALID)) { | 190 | if (!(ch_flags & NVM_CHANNEL_VALID)) { |
186 | IWL_DEBUG_EEPROM(dev, | 191 | IWL_DEBUG_EEPROM(dev, |
187 | "Ch. %d Flags %x [%sGHz] - No traffic\n", | 192 | "Ch. %d Flags %x [%sGHz] - No traffic\n", |
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 76cde6ce6551..18a895a949d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c | |||
@@ -872,8 +872,11 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
872 | 872 | ||
873 | lockdep_assert_held(&mvm->mutex); | 873 | lockdep_assert_held(&mvm->mutex); |
874 | 874 | ||
875 | /* Rssi update while not associated ?! */ | 875 | /* |
876 | if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) | 876 | * Rssi update while not associated - can happen since the statistics |
877 | * are handled asynchronously | ||
878 | */ | ||
879 | if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) | ||
877 | return; | 880 | return; |
878 | 881 | ||
879 | /* No BT - reports should be disabled */ | 882 | /* No BT - reports should be disabled */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 73cbba7424f2..9426905de6b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -504,6 +504,7 @@ struct iwl_scan_offload_profile { | |||
504 | * @match_notify: clients waiting for match found notification | 504 | * @match_notify: clients waiting for match found notification |
505 | * @pass_match: clients waiting for the results | 505 | * @pass_match: clients waiting for the results |
506 | * @active_clients: active clients bitmap - enum scan_framework_client | 506 | * @active_clients: active clients bitmap - enum scan_framework_client |
507 | * @any_beacon_notify: clients waiting for match notification without match | ||
507 | */ | 508 | */ |
508 | struct iwl_scan_offload_profile_cfg { | 509 | struct iwl_scan_offload_profile_cfg { |
509 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; | 510 | struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; |
@@ -512,7 +513,8 @@ struct iwl_scan_offload_profile_cfg { | |||
512 | u8 match_notify; | 513 | u8 match_notify; |
513 | u8 pass_match; | 514 | u8 pass_match; |
514 | u8 active_clients; | 515 | u8 active_clients; |
515 | u8 reserved[3]; | 516 | u8 any_beacon_notify; |
517 | u8 reserved[2]; | ||
516 | } __packed; | 518 | } __packed; |
517 | 519 | ||
518 | /** | 520 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index c49b5073c251..c35b8661b395 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -246,7 +246,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
246 | else | 246 | else |
247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | 247 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
248 | 248 | ||
249 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { | 249 | if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { |
250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 250 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; | 251 | hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; |
252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; | 252 | hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; |
@@ -328,6 +328,24 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, | |||
328 | ieee80211_free_txskb(hw, skb); | 328 | ieee80211_free_txskb(hw, skb); |
329 | } | 329 | } |
330 | 330 | ||
331 | static inline bool iwl_enable_rx_ampdu(const struct iwl_cfg *cfg) | ||
332 | { | ||
333 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) | ||
334 | return false; | ||
335 | return true; | ||
336 | } | ||
337 | |||
338 | static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg) | ||
339 | { | ||
340 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) | ||
341 | return false; | ||
342 | if (iwlwifi_mod_params.disable_11n & IWL_ENABLE_HT_TXAGG) | ||
343 | return true; | ||
344 | |||
345 | /* enabled by default */ | ||
346 | return true; | ||
347 | } | ||
348 | |||
331 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | 349 | static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, |
332 | struct ieee80211_vif *vif, | 350 | struct ieee80211_vif *vif, |
333 | enum ieee80211_ampdu_mlme_action action, | 351 | enum ieee80211_ampdu_mlme_action action, |
@@ -347,7 +365,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
347 | 365 | ||
348 | switch (action) { | 366 | switch (action) { |
349 | case IEEE80211_AMPDU_RX_START: | 367 | case IEEE80211_AMPDU_RX_START: |
350 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) { | 368 | if (!iwl_enable_rx_ampdu(mvm->cfg)) { |
351 | ret = -EINVAL; | 369 | ret = -EINVAL; |
352 | break; | 370 | break; |
353 | } | 371 | } |
@@ -357,7 +375,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, | |||
357 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); | 375 | ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); |
358 | break; | 376 | break; |
359 | case IEEE80211_AMPDU_TX_START: | 377 | case IEEE80211_AMPDU_TX_START: |
360 | if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { | 378 | if (!iwl_enable_tx_ampdu(mvm->cfg)) { |
361 | ret = -EINVAL; | 379 | ret = -EINVAL; |
362 | break; | 380 | break; |
363 | } | 381 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e4ead86f06d6..2b0ba1fc3c82 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -152,7 +152,7 @@ enum iwl_power_scheme { | |||
152 | IWL_POWER_SCHEME_LP | 152 | IWL_POWER_SCHEME_LP |
153 | }; | 153 | }; |
154 | 154 | ||
155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 70 | 155 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ | 156 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ |
157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ | 157 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ |
158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ | 158 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 0e0007960612..742afc429c94 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -344,7 +344,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, | |||
344 | 344 | ||
345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); | 345 | iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); |
346 | 346 | ||
347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); | 347 | cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | |
348 | TX_CMD_FLG_BT_DIS); | ||
348 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; | 349 | cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; |
349 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 350 | cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
350 | cmd->tx_cmd.rate_n_flags = | 351 | cmd->tx_cmd.rate_n_flags = |
@@ -807,6 +808,8 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, | |||
807 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; | 808 | profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; |
808 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; | 809 | profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; |
809 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; | 810 | profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; |
811 | if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len) | ||
812 | profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN; | ||
810 | 813 | ||
811 | for (i = 0; i < req->n_match_sets; i++) { | 814 | for (i = 0; i < req->n_match_sets; i++) { |
812 | profile = &profile_cfg->profiles[i]; | 815 | profile = &profile_cfg->profiles[i]; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ec1812133235..3397f59cd4e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -652,7 +652,7 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
652 | { | 652 | { |
653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 653 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 654 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
655 | static const u8 *baddr = _baddr; | 655 | const u8 *baddr = _baddr; |
656 | 656 | ||
657 | lockdep_assert_held(&mvm->mutex); | 657 | lockdep_assert_held(&mvm->mutex); |
658 | 658 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 90378c217bc7..76ee486039d7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -659,8 +659,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
659 | rcu_read_lock(); | 659 | rcu_read_lock(); |
660 | 660 | ||
661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | 661 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); |
662 | /* | ||
663 | * sta can't be NULL otherwise it'd mean that the sta has been freed in | ||
664 | * the firmware while we still have packets for it in the Tx queues. | ||
665 | */ | ||
666 | if (WARN_ON_ONCE(!sta)) | ||
667 | goto out; | ||
662 | 668 | ||
663 | if (!IS_ERR_OR_NULL(sta)) { | 669 | if (!IS_ERR(sta)) { |
664 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | 670 | mvmsta = iwl_mvm_sta_from_mac80211(sta); |
665 | 671 | ||
666 | if (tid != IWL_TID_NON_QOS) { | 672 | if (tid != IWL_TID_NON_QOS) { |
@@ -675,7 +681,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
675 | spin_unlock_bh(&mvmsta->lock); | 681 | spin_unlock_bh(&mvmsta->lock); |
676 | } | 682 | } |
677 | } else { | 683 | } else { |
678 | sta = NULL; | ||
679 | mvmsta = NULL; | 684 | mvmsta = NULL; |
680 | } | 685 | } |
681 | 686 | ||
@@ -683,42 +688,38 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, | |||
683 | * If the txq is not an AMPDU queue, there is no chance we freed | 688 | * If the txq is not an AMPDU queue, there is no chance we freed |
684 | * several skbs. Check that out... | 689 | * several skbs. Check that out... |
685 | */ | 690 | */ |
686 | if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) && | 691 | if (txq_id >= mvm->first_agg_queue) |
687 | atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { | 692 | goto out; |
688 | if (mvmsta) { | 693 | |
689 | /* | 694 | /* We can't free more than one frame at once on a shared queue */ |
690 | * If there are no pending frames for this STA, notify | 695 | WARN_ON(skb_freed > 1); |
691 | * mac80211 that this station can go to sleep in its | 696 | |
692 | * STA table. | 697 | /* If we have still frames from this STA nothing to do here */ |
693 | */ | 698 | if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) |
694 | if (mvmsta->vif->type == NL80211_IFTYPE_AP) | 699 | goto out; |
695 | ieee80211_sta_block_awake(mvm->hw, sta, false); | 700 | |
696 | /* | 701 | if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) { |
697 | * We might very well have taken mvmsta pointer while | 702 | /* |
698 | * the station was being removed. The remove flow might | 703 | * If there are no pending frames for this STA, notify |
699 | * have seen a pending_frame (because we didn't take | 704 | * mac80211 that this station can go to sleep in its |
700 | * the lock) even if now the queues are drained. So make | 705 | * STA table. |
701 | * really sure now that this the station is not being | 706 | * If mvmsta is not NULL, sta is valid. |
702 | * removed. If it is, run the drain worker to remove it. | 707 | */ |
703 | */ | 708 | ieee80211_sta_block_awake(mvm->hw, sta, false); |
704 | spin_lock_bh(&mvmsta->lock); | ||
705 | sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); | ||
706 | if (!sta || PTR_ERR(sta) == -EBUSY) { | ||
707 | /* | ||
708 | * Station disappeared in the meantime: | ||
709 | * so we are draining. | ||
710 | */ | ||
711 | set_bit(sta_id, mvm->sta_drained); | ||
712 | schedule_work(&mvm->sta_drained_wk); | ||
713 | } | ||
714 | spin_unlock_bh(&mvmsta->lock); | ||
715 | } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) { | ||
716 | /* Tx response without STA, so we are draining */ | ||
717 | set_bit(sta_id, mvm->sta_drained); | ||
718 | schedule_work(&mvm->sta_drained_wk); | ||
719 | } | ||
720 | } | 709 | } |
721 | 710 | ||
711 | if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { | ||
712 | /* | ||
713 | * We are draining and this was the last packet - pre_rcu_remove | ||
714 | * has been called already. We might be after the | ||
715 | * synchronize_net already. | ||
716 | * Don't rely on iwl_mvm_rm_sta to see the empty Tx queues. | ||
717 | */ | ||
718 | set_bit(sta_id, mvm->sta_drained); | ||
719 | schedule_work(&mvm->sta_drained_wk); | ||
720 | } | ||
721 | |||
722 | out: | ||
722 | rcu_read_unlock(); | 723 | rcu_read_unlock(); |
723 | } | 724 | } |
724 | 725 | ||
@@ -821,16 +822,12 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
821 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; | 822 | struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data; |
822 | struct sk_buff_head reclaimed_skbs; | 823 | struct sk_buff_head reclaimed_skbs; |
823 | struct iwl_mvm_tid_data *tid_data; | 824 | struct iwl_mvm_tid_data *tid_data; |
824 | struct ieee80211_tx_info *info; | ||
825 | struct ieee80211_sta *sta; | 825 | struct ieee80211_sta *sta; |
826 | struct iwl_mvm_sta *mvmsta; | 826 | struct iwl_mvm_sta *mvmsta; |
827 | struct ieee80211_hdr *hdr; | ||
828 | struct sk_buff *skb; | 827 | struct sk_buff *skb; |
829 | int sta_id, tid, freed; | 828 | int sta_id, tid, freed; |
830 | |||
831 | /* "flow" corresponds to Tx queue */ | 829 | /* "flow" corresponds to Tx queue */ |
832 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); | 830 | u16 scd_flow = le16_to_cpu(ba_notif->scd_flow); |
833 | |||
834 | /* "ssn" is start of block-ack Tx window, corresponds to index | 831 | /* "ssn" is start of block-ack Tx window, corresponds to index |
835 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 832 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
836 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); | 833 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn); |
@@ -887,22 +884,26 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, | |||
887 | freed = 0; | 884 | freed = 0; |
888 | 885 | ||
889 | skb_queue_walk(&reclaimed_skbs, skb) { | 886 | skb_queue_walk(&reclaimed_skbs, skb) { |
890 | hdr = (struct ieee80211_hdr *)skb->data; | 887 | struct ieee80211_hdr *hdr = (void *)skb->data; |
888 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
891 | 889 | ||
892 | if (ieee80211_is_data_qos(hdr->frame_control)) | 890 | if (ieee80211_is_data_qos(hdr->frame_control)) |
893 | freed++; | 891 | freed++; |
894 | else | 892 | else |
895 | WARN_ON_ONCE(1); | 893 | WARN_ON_ONCE(1); |
896 | 894 | ||
897 | info = IEEE80211_SKB_CB(skb); | ||
898 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); | 895 | iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]); |
899 | 896 | ||
897 | memset(&info->status, 0, sizeof(info->status)); | ||
898 | /* Packet was transmitted successfully, failures come as single | ||
899 | * frames because before failing a frame the firmware transmits | ||
900 | * it without aggregation at least once. | ||
901 | */ | ||
902 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
903 | |||
900 | if (freed == 1) { | 904 | if (freed == 1) { |
901 | /* this is the first skb we deliver in this batch */ | 905 | /* this is the first skb we deliver in this batch */ |
902 | /* put the rate scaling data there */ | 906 | /* put the rate scaling data there */ |
903 | info = IEEE80211_SKB_CB(skb); | ||
904 | memset(&info->status, 0, sizeof(info->status)); | ||
905 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
906 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 907 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
907 | info->status.ampdu_ack_len = ba_notif->txed_2_done; | 908 | info->status.ampdu_ack_len = ba_notif->txed_2_done; |
908 | info->status.ampdu_len = ba_notif->txed; | 909 | info->status.ampdu_len = ba_notif->txed; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index a4a5e25623c3..86989df69356 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -411,6 +411,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) | |||
411 | mvm->status, table.valid); | 411 | mvm->status, table.valid); |
412 | } | 412 | } |
413 | 413 | ||
414 | IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version); | ||
415 | |||
414 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, | 416 | trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, |
415 | table.data1, table.data2, table.data3, | 417 | table.data1, table.data2, table.data3, |
416 | table.blink1, table.blink2, table.ilink1, | 418 | table.blink1, table.blink2, table.ilink1, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3040924f5f3c..3872ead75488 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -359,20 +359,24 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
359 | /* 7265 Series */ | 359 | /* 7265 Series */ |
360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 360 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, | 361 | {IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)}, |
362 | {IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)}, | ||
362 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, | 363 | {IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)}, |
363 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)}, | 364 | {IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_n_cfg)}, |
364 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, | 365 | {IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)}, |
365 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, | 366 | {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, |
366 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2ac_cfg)}, | 367 | {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)}, |
367 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, | 368 | {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, |
368 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, |
369 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, | 370 | {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, |
370 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, | 371 | {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, |
372 | {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, | ||
371 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, | 373 | {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, |
372 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, | 374 | {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, |
373 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, | 375 | {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, |
374 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, | 376 | {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, |
377 | {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, | ||
375 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, | 378 | {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, |
379 | {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, | ||
376 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, | 380 | {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, |
377 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, | 381 | {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, |
378 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, | 382 | {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 32f75007a825..cb6d189bc3e6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -621,7 +621,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
621 | id = *pos++; | 621 | id = *pos++; |
622 | elen = *pos++; | 622 | elen = *pos++; |
623 | left -= 2; | 623 | left -= 2; |
624 | if (elen > left || elen == 0) { | 624 | if (elen > left) { |
625 | lbs_deb_scan("scan response: invalid IE fmt\n"); | 625 | lbs_deb_scan("scan response: invalid IE fmt\n"); |
626 | goto done; | 626 | goto done; |
627 | } | 627 | } |
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c index 5e0eec4d71c7..5d9a8084665d 100644 --- a/drivers/net/wireless/mwifiex/11ac.c +++ b/drivers/net/wireless/mwifiex/11ac.c | |||
@@ -189,8 +189,7 @@ int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv, | |||
189 | vht_cap->header.len = | 189 | vht_cap->header.len = |
190 | cpu_to_le16(sizeof(struct ieee80211_vht_cap)); | 190 | cpu_to_le16(sizeof(struct ieee80211_vht_cap)); |
191 | memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header), | 191 | memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header), |
192 | (u8 *)bss_desc->bcn_vht_cap + | 192 | (u8 *)bss_desc->bcn_vht_cap, |
193 | sizeof(struct ieee_types_header), | ||
194 | le16_to_cpu(vht_cap->header.len)); | 193 | le16_to_cpu(vht_cap->header.len)); |
195 | 194 | ||
196 | mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); | 195 | mwifiex_fill_vht_cap_tlv(priv, vht_cap, bss_desc->bss_band); |
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 6261f8c53d44..7db1a89fdd95 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c | |||
@@ -308,8 +308,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, | |||
308 | ht_cap->header.len = | 308 | ht_cap->header.len = |
309 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); | 309 | cpu_to_le16(sizeof(struct ieee80211_ht_cap)); |
310 | memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), | 310 | memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header), |
311 | (u8 *) bss_desc->bcn_ht_cap + | 311 | (u8 *)bss_desc->bcn_ht_cap, |
312 | sizeof(struct ieee_types_header), | ||
313 | le16_to_cpu(ht_cap->header.len)); | 312 | le16_to_cpu(ht_cap->header.len)); |
314 | 313 | ||
315 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); | 314 | mwifiex_fill_cap_info(priv, radio_type, ht_cap); |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 4d79761b9c87..9d3d2758ec35 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -748,7 +748,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
748 | 748 | ||
749 | static u16 | 749 | static u16 |
750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, | 750 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb, |
751 | void *accel_priv) | 751 | void *accel_priv, select_queue_fallback_t fallback) |
752 | { | 752 | { |
753 | skb->priority = cfg80211_classify8021d(skb, NULL); | 753 | skb->priority = cfg80211_classify8021d(skb, NULL); |
754 | return mwifiex_1d_to_wmm_queue[skb->priority]; | 754 | return mwifiex_1d_to_wmm_queue[skb->priority]; |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 03688aa14e8a..7fe7b53fb17a 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -1211,6 +1211,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; | 1211 | rd_index = card->rxbd_rdptr & reg->rx_mask; |
1212 | skb_data = card->rx_buf_list[rd_index]; | 1212 | skb_data = card->rx_buf_list[rd_index]; |
1213 | 1213 | ||
1214 | /* If skb allocation was failed earlier for Rx packet, | ||
1215 | * rx_buf_list[rd_index] would have been left with a NULL. | ||
1216 | */ | ||
1217 | if (!skb_data) | ||
1218 | return -ENOMEM; | ||
1219 | |||
1214 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); | 1220 | MWIFIEX_SKB_PACB(skb_data, &buf_pa); |
1215 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, | 1221 | pci_unmap_single(card->dev, buf_pa, MWIFIEX_RX_DATA_BUF_SIZE, |
1216 | PCI_DMA_FROMDEVICE); | 1222 | PCI_DMA_FROMDEVICE); |
@@ -1525,6 +1531,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) | |||
1525 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { | 1531 | if (adapter->ps_state == PS_STATE_SLEEP_CFM) { |
1526 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, | 1532 | mwifiex_process_sleep_confirm_resp(adapter, skb->data, |
1527 | skb->len); | 1533 | skb->len); |
1534 | mwifiex_pcie_enable_host_int(adapter); | ||
1535 | if (mwifiex_write_reg(adapter, | ||
1536 | PCIE_CPU_INT_EVENT, | ||
1537 | CPU_INTR_SLEEP_CFM_DONE)) { | ||
1538 | dev_warn(adapter->dev, | ||
1539 | "Write register failed\n"); | ||
1540 | return -1; | ||
1541 | } | ||
1528 | while (reg->sleep_cookie && (count++ < 10) && | 1542 | while (reg->sleep_cookie && (count++ < 10) && |
1529 | mwifiex_pcie_ok_to_access_hw(adapter)) | 1543 | mwifiex_pcie_ok_to_access_hw(adapter)) |
1530 | usleep_range(50, 60); | 1544 | usleep_range(50, 60); |
@@ -1993,23 +2007,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
1993 | adapter->int_status |= pcie_ireg; | 2007 | adapter->int_status |= pcie_ireg; |
1994 | spin_unlock_irqrestore(&adapter->int_lock, flags); | 2008 | spin_unlock_irqrestore(&adapter->int_lock, flags); |
1995 | 2009 | ||
1996 | if (pcie_ireg & HOST_INTR_CMD_DONE) { | 2010 | if (!adapter->pps_uapsd_mode && |
1997 | if ((adapter->ps_state == PS_STATE_SLEEP_CFM) || | 2011 | adapter->ps_state == PS_STATE_SLEEP && |
1998 | (adapter->ps_state == PS_STATE_SLEEP)) { | 2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { |
1999 | mwifiex_pcie_enable_host_int(adapter); | ||
2000 | if (mwifiex_write_reg(adapter, | ||
2001 | PCIE_CPU_INT_EVENT, | ||
2002 | CPU_INTR_SLEEP_CFM_DONE) | ||
2003 | ) { | ||
2004 | dev_warn(adapter->dev, | ||
2005 | "Write register failed\n"); | ||
2006 | return; | ||
2007 | |||
2008 | } | ||
2009 | } | ||
2010 | } else if (!adapter->pps_uapsd_mode && | ||
2011 | adapter->ps_state == PS_STATE_SLEEP && | ||
2012 | mwifiex_pcie_ok_to_access_hw(adapter)) { | ||
2013 | /* Potentially for PCIe we could get other | 2013 | /* Potentially for PCIe we could get other |
2014 | * interrupts like shared. Don't change power | 2014 | * interrupts like shared. Don't change power |
2015 | * state until cookie is set */ | 2015 | * state until cookie is set */ |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 0a8a26e10f01..668547c2de84 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -2101,12 +2101,12 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) | |||
2101 | curr_bss->ht_info_offset); | 2101 | curr_bss->ht_info_offset); |
2102 | 2102 | ||
2103 | if (curr_bss->bcn_vht_cap) | 2103 | if (curr_bss->bcn_vht_cap) |
2104 | curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf + | 2104 | curr_bss->bcn_vht_cap = (void *)(curr_bss->beacon_buf + |
2105 | curr_bss->vht_cap_offset); | 2105 | curr_bss->vht_cap_offset); |
2106 | 2106 | ||
2107 | if (curr_bss->bcn_vht_oper) | 2107 | if (curr_bss->bcn_vht_oper) |
2108 | curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf + | 2108 | curr_bss->bcn_vht_oper = (void *)(curr_bss->beacon_buf + |
2109 | curr_bss->vht_info_offset); | 2109 | curr_bss->vht_info_offset); |
2110 | 2110 | ||
2111 | if (curr_bss->bcn_bss_co_2040) | 2111 | if (curr_bss->bcn_bss_co_2040) |
2112 | curr_bss->bcn_bss_co_2040 = | 2112 | curr_bss->bcn_bss_co_2040 = |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index e8ebbd4bc3cd..208748804a55 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
@@ -22,8 +22,6 @@ | |||
22 | 22 | ||
23 | #define USB_VERSION "1.0" | 23 | #define USB_VERSION "1.0" |
24 | 24 | ||
25 | static const char usbdriver_name[] = "usb8xxx"; | ||
26 | |||
27 | static struct mwifiex_if_ops usb_ops; | 25 | static struct mwifiex_if_ops usb_ops; |
28 | static struct semaphore add_remove_card_sem; | 26 | static struct semaphore add_remove_card_sem; |
29 | static struct usb_card_rec *usb_card; | 27 | static struct usb_card_rec *usb_card; |
@@ -527,13 +525,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) | |||
527 | MWIFIEX_BSS_ROLE_ANY), | 525 | MWIFIEX_BSS_ROLE_ANY), |
528 | MWIFIEX_ASYNC_CMD); | 526 | MWIFIEX_ASYNC_CMD); |
529 | 527 | ||
530 | #ifdef CONFIG_PM | ||
531 | /* Resume handler may be called due to remote wakeup, | ||
532 | * force to exit suspend anyway | ||
533 | */ | ||
534 | usb_disable_autosuspend(card->udev); | ||
535 | #endif /* CONFIG_PM */ | ||
536 | |||
537 | return 0; | 528 | return 0; |
538 | } | 529 | } |
539 | 530 | ||
@@ -567,13 +558,12 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf) | |||
567 | } | 558 | } |
568 | 559 | ||
569 | static struct usb_driver mwifiex_usb_driver = { | 560 | static struct usb_driver mwifiex_usb_driver = { |
570 | .name = usbdriver_name, | 561 | .name = "mwifiex_usb", |
571 | .probe = mwifiex_usb_probe, | 562 | .probe = mwifiex_usb_probe, |
572 | .disconnect = mwifiex_usb_disconnect, | 563 | .disconnect = mwifiex_usb_disconnect, |
573 | .id_table = mwifiex_usb_table, | 564 | .id_table = mwifiex_usb_table, |
574 | .suspend = mwifiex_usb_suspend, | 565 | .suspend = mwifiex_usb_suspend, |
575 | .resume = mwifiex_usb_resume, | 566 | .resume = mwifiex_usb_resume, |
576 | .supports_autosuspend = 1, | ||
577 | }; | 567 | }; |
578 | 568 | ||
579 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) | 569 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) |
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 13eaeed03898..981cf6e7c73b 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -559,7 +559,8 @@ mwifiex_clean_txrx(struct mwifiex_private *priv) | |||
559 | mwifiex_wmm_delete_all_ralist(priv); | 559 | mwifiex_wmm_delete_all_ralist(priv); |
560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); | 560 | memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid)); |
561 | 561 | ||
562 | if (priv->adapter->if_ops.clean_pcie_ring) | 562 | if (priv->adapter->if_ops.clean_pcie_ring && |
563 | !priv->adapter->surprise_removed) | ||
563 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); | 564 | priv->adapter->if_ops.clean_pcie_ring(priv->adapter); |
564 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 565 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
565 | } | 566 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index abc5f56f29fe..2f1cd929c6f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1877,6 +1877,11 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1877 | EEPROM_MAC_ADDR_0)); | 1877 | EEPROM_MAC_ADDR_0)); |
1878 | 1878 | ||
1879 | /* | 1879 | /* |
1880 | * Disable powersaving as default. | ||
1881 | */ | ||
1882 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1883 | |||
1884 | /* | ||
1880 | * Initialize hw_mode information. | 1885 | * Initialize hw_mode information. |
1881 | */ | 1886 | */ |
1882 | spec->supported_bands = SUPPORT_BAND_2GHZ; | 1887 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9f16824cd1bc..d849d590de25 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1706,6 +1706,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1706 | IEEE80211_HW_SUPPORTS_PS | | 1706 | IEEE80211_HW_SUPPORTS_PS | |
1707 | IEEE80211_HW_PS_NULLFUNC_STACK; | 1707 | IEEE80211_HW_PS_NULLFUNC_STACK; |
1708 | 1708 | ||
1709 | /* | ||
1710 | * Disable powersaving as default. | ||
1711 | */ | ||
1712 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
1713 | |||
1709 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); | 1714 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1710 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1715 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1711 | rt2x00_eeprom_addr(rt2x00dev, | 1716 | rt2x00_eeprom_addr(rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b8f5b06006c4..41d4a8167dc3 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -5460,14 +5460,15 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) | |||
5460 | 5460 | ||
5461 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); | 5461 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); |
5462 | 5462 | ||
5463 | rt2800_bbp_write(rt2x00dev, 69, 0x0d); | 5463 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
5464 | rt2800_bbp_write(rt2x00dev, 70, 0x06); | ||
5465 | rt2800_bbp_write(rt2x00dev, 73, 0x13); | 5464 | rt2800_bbp_write(rt2x00dev, 73, 0x13); |
5466 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 5465 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
5467 | rt2800_bbp_write(rt2x00dev, 76, 0x28); | 5466 | rt2800_bbp_write(rt2x00dev, 76, 0x28); |
5468 | 5467 | ||
5469 | rt2800_bbp_write(rt2x00dev, 77, 0x59); | 5468 | rt2800_bbp_write(rt2x00dev, 77, 0x59); |
5470 | 5469 | ||
5470 | rt2800_bbp_write(rt2x00dev, 70, 0x0a); | ||
5471 | |||
5471 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 5472 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
5472 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 5473 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
5473 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 5474 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
@@ -5510,7 +5511,6 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) | |||
5510 | if (rt2x00_rt(rt2x00dev, RT5392)) { | 5511 | if (rt2x00_rt(rt2x00dev, RT5392)) { |
5511 | rt2800_bbp_write(rt2x00dev, 134, 0xd0); | 5512 | rt2800_bbp_write(rt2x00dev, 134, 0xd0); |
5512 | rt2800_bbp_write(rt2x00dev, 135, 0xf6); | 5513 | rt2800_bbp_write(rt2x00dev, 135, 0xf6); |
5513 | rt2800_bbp_write(rt2x00dev, 148, 0x84); | ||
5514 | } | 5514 | } |
5515 | 5515 | ||
5516 | rt2800_disable_unused_dac_adc(rt2x00dev); | 5516 | rt2800_disable_unused_dac_adc(rt2x00dev); |
@@ -7458,10 +7458,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
7458 | u32 reg; | 7458 | u32 reg; |
7459 | 7459 | ||
7460 | /* | 7460 | /* |
7461 | * Disable powersaving as default on PCI devices. | 7461 | * Disable powersaving as default. |
7462 | */ | 7462 | */ |
7463 | if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) | 7463 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; |
7464 | rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
7465 | 7464 | ||
7466 | /* | 7465 | /* |
7467 | * Initialize all hw fields. | 7466 | * Initialize all hw fields. |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 8ec17aad0e52..3867d1470b36 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
@@ -107,6 +107,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
107 | struct rtl8180_priv *priv = dev->priv; | 107 | struct rtl8180_priv *priv = dev->priv; |
108 | unsigned int count = 32; | 108 | unsigned int count = 32; |
109 | u8 signal, agc, sq; | 109 | u8 signal, agc, sq; |
110 | dma_addr_t mapping; | ||
110 | 111 | ||
111 | while (count--) { | 112 | while (count--) { |
112 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; | 113 | struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; |
@@ -128,6 +129,17 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
128 | if (unlikely(!new_skb)) | 129 | if (unlikely(!new_skb)) |
129 | goto done; | 130 | goto done; |
130 | 131 | ||
132 | mapping = pci_map_single(priv->pdev, | ||
133 | skb_tail_pointer(new_skb), | ||
134 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
135 | |||
136 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
137 | kfree_skb(new_skb); | ||
138 | dev_err(&priv->pdev->dev, "RX DMA map error\n"); | ||
139 | |||
140 | goto done; | ||
141 | } | ||
142 | |||
131 | pci_unmap_single(priv->pdev, | 143 | pci_unmap_single(priv->pdev, |
132 | *((dma_addr_t *)skb->cb), | 144 | *((dma_addr_t *)skb->cb), |
133 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | 145 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); |
@@ -158,9 +170,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
158 | 170 | ||
159 | skb = new_skb; | 171 | skb = new_skb; |
160 | priv->rx_buf[priv->rx_idx] = skb; | 172 | priv->rx_buf[priv->rx_idx] = skb; |
161 | *((dma_addr_t *) skb->cb) = | 173 | *((dma_addr_t *) skb->cb) = mapping; |
162 | pci_map_single(priv->pdev, skb_tail_pointer(skb), | ||
163 | MAX_RX_SIZE, PCI_DMA_FROMDEVICE); | ||
164 | } | 174 | } |
165 | 175 | ||
166 | done: | 176 | done: |
@@ -266,6 +276,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev, | |||
266 | mapping = pci_map_single(priv->pdev, skb->data, | 276 | mapping = pci_map_single(priv->pdev, skb->data, |
267 | skb->len, PCI_DMA_TODEVICE); | 277 | skb->len, PCI_DMA_TODEVICE); |
268 | 278 | ||
279 | if (pci_dma_mapping_error(priv->pdev, mapping)) { | ||
280 | kfree_skb(skb); | ||
281 | dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); | ||
282 | return; | ||
283 | |||
284 | } | ||
285 | |||
269 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | | 286 | tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS | |
270 | RTL818X_TX_DESC_FLAG_LS | | 287 | RTL818X_TX_DESC_FLAG_LS | |
271 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | | 288 | (ieee80211_get_tx_rate(dev, info)->hw_value << 24) | |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index 56aee067f324..a6ad79f61bf9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #ifndef RTL8187_H | 15 | #ifndef RTL8187_H |
16 | #define RTL8187_H | 16 | #define RTL8187_H |
17 | 17 | ||
18 | #include <linux/cache.h> | ||
19 | |||
18 | #include "rtl818x.h" | 20 | #include "rtl818x.h" |
19 | #include "leds.h" | 21 | #include "leds.h" |
20 | 22 | ||
@@ -139,7 +141,10 @@ struct rtl8187_priv { | |||
139 | u8 aifsn[4]; | 141 | u8 aifsn[4]; |
140 | u8 rfkill_mask; | 142 | u8 rfkill_mask; |
141 | struct { | 143 | struct { |
142 | __le64 buf; | 144 | union { |
145 | __le64 buf; | ||
146 | u8 dummy1[L1_CACHE_BYTES]; | ||
147 | } ____cacheline_aligned; | ||
143 | struct sk_buff_head queue; | 148 | struct sk_buff_head queue; |
144 | } b_tx_status; /* This queue is used by both -b and non-b devices */ | 149 | } b_tx_status; /* This queue is used by both -b and non-b devices */ |
145 | struct mutex io_mutex; | 150 | struct mutex io_mutex; |
@@ -147,7 +152,8 @@ struct rtl8187_priv { | |||
147 | u8 bits8; | 152 | u8 bits8; |
148 | __le16 bits16; | 153 | __le16 bits16; |
149 | __le32 bits32; | 154 | __le32 bits32; |
150 | } *io_dmabuf; | 155 | u8 dummy2[L1_CACHE_BYTES]; |
156 | } *io_dmabuf ____cacheline_aligned; | ||
151 | bool rfkill_off; | 157 | bool rfkill_off; |
152 | u16 seqno; | 158 | u16 seqno; |
153 | }; | 159 | }; |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index deedae3c5449..d1c0191a195b 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -48,7 +48,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) | |||
48 | 48 | ||
49 | /*<2> Enable Adapter */ | 49 | /*<2> Enable Adapter */ |
50 | if (rtlpriv->cfg->ops->hw_init(hw)) | 50 | if (rtlpriv->cfg->ops->hw_init(hw)) |
51 | return 1; | 51 | return false; |
52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | 52 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); |
53 | 53 | ||
54 | /*<3> Enable Interrupt */ | 54 | /*<3> Enable Interrupt */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a82b30a1996c..2eb0b38384dd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -937,14 +937,26 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
937 | bool is92c; | 937 | bool is92c; |
938 | int err; | 938 | int err; |
939 | u8 tmp_u1b; | 939 | u8 tmp_u1b; |
940 | unsigned long flags; | ||
940 | 941 | ||
941 | rtlpci->being_init_adapter = true; | 942 | rtlpci->being_init_adapter = true; |
943 | |||
944 | /* Since this function can take a very long time (up to 350 ms) | ||
945 | * and can be called with irqs disabled, reenable the irqs | ||
946 | * to let the other devices continue being serviced. | ||
947 | * | ||
948 | * It is safe doing so since our own interrupts will only be enabled | ||
949 | * in a subsequent step. | ||
950 | */ | ||
951 | local_save_flags(flags); | ||
952 | local_irq_enable(); | ||
953 | |||
942 | rtlpriv->intf_ops->disable_aspm(hw); | 954 | rtlpriv->intf_ops->disable_aspm(hw); |
943 | rtstatus = _rtl92ce_init_mac(hw); | 955 | rtstatus = _rtl92ce_init_mac(hw); |
944 | if (!rtstatus) { | 956 | if (!rtstatus) { |
945 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); | 957 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); |
946 | err = 1; | 958 | err = 1; |
947 | return err; | 959 | goto exit; |
948 | } | 960 | } |
949 | 961 | ||
950 | err = rtl92c_download_fw(hw); | 962 | err = rtl92c_download_fw(hw); |
@@ -952,7 +964,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
952 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
953 | "Failed to download FW. Init HW without FW now..\n"); | 965 | "Failed to download FW. Init HW without FW now..\n"); |
954 | err = 1; | 966 | err = 1; |
955 | return err; | 967 | goto exit; |
956 | } | 968 | } |
957 | 969 | ||
958 | rtlhal->last_hmeboxnum = 0; | 970 | rtlhal->last_hmeboxnum = 0; |
@@ -1032,6 +1044,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
1032 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); | 1044 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); |
1033 | } | 1045 | } |
1034 | rtl92c_dm_init(hw); | 1046 | rtl92c_dm_init(hw); |
1047 | exit: | ||
1048 | local_irq_restore(flags); | ||
1035 | rtlpci->being_init_adapter = false; | 1049 | rtlpci->being_init_adapter = false; |
1036 | return err; | 1050 | return err; |
1037 | } | 1051 | } |
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c index 123c4bb50e0a..cde0eaf99714 100644 --- a/drivers/net/wireless/ti/wl1251/rx.c +++ b/drivers/net/wireless/ti/wl1251/rx.c | |||
@@ -180,7 +180,7 @@ static void wl1251_rx_body(struct wl1251 *wl, | |||
180 | wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); | 180 | wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length); |
181 | 181 | ||
182 | /* The actual length doesn't include the target's alignment */ | 182 | /* The actual length doesn't include the target's alignment */ |
183 | skb->len = desc->length - PLCP_HEADER_LENGTH; | 183 | skb_trim(skb, desc->length - PLCP_HEADER_LENGTH); |
184 | 184 | ||
185 | fc = (u16 *)skb->data; | 185 | fc = (u16 *)skb->data; |
186 | 186 | ||
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 4c76bcb9a879..ae413a2cbee7 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
@@ -143,11 +143,7 @@ struct xenvif { | |||
143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ | 143 | char rx_irq_name[IFNAMSIZ+4]; /* DEVNAME-rx */ |
144 | struct xen_netif_rx_back_ring rx; | 144 | struct xen_netif_rx_back_ring rx; |
145 | struct sk_buff_head rx_queue; | 145 | struct sk_buff_head rx_queue; |
146 | bool rx_queue_stopped; | 146 | RING_IDX rx_last_skb_slots; |
147 | /* Set when the RX interrupt is triggered by the frontend. | ||
148 | * The worker thread may need to wake the queue. | ||
149 | */ | ||
150 | bool rx_event; | ||
151 | 147 | ||
152 | /* This array is allocated seperately as it is large */ | 148 | /* This array is allocated seperately as it is large */ |
153 | struct gnttab_copy *grant_copy_op; | 149 | struct gnttab_copy *grant_copy_op; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index b9de31ea7fc4..301cc037fda8 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -100,7 +100,6 @@ static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id) | |||
100 | { | 100 | { |
101 | struct xenvif *vif = dev_id; | 101 | struct xenvif *vif = dev_id; |
102 | 102 | ||
103 | vif->rx_event = true; | ||
104 | xenvif_kick_thread(vif); | 103 | xenvif_kick_thread(vif); |
105 | 104 | ||
106 | return IRQ_HANDLED; | 105 | return IRQ_HANDLED; |
@@ -133,8 +132,7 @@ static int xenvif_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
133 | /* If the skb is GSO then we'll also need an extra slot for the | 132 | /* If the skb is GSO then we'll also need an extra slot for the |
134 | * metadata. | 133 | * metadata. |
135 | */ | 134 | */ |
136 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || | 135 | if (skb_is_gso(skb)) |
137 | skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | ||
138 | min_slots_needed++; | 136 | min_slots_needed++; |
139 | 137 | ||
140 | /* If the skb can't possibly fit in the remaining slots | 138 | /* If the skb can't possibly fit in the remaining slots |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 6b62c3eb8e18..438d0c09b7e6 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -240,7 +240,7 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, | |||
240 | struct gnttab_copy *copy_gop; | 240 | struct gnttab_copy *copy_gop; |
241 | struct xenvif_rx_meta *meta; | 241 | struct xenvif_rx_meta *meta; |
242 | unsigned long bytes; | 242 | unsigned long bytes; |
243 | int gso_type; | 243 | int gso_type = XEN_NETIF_GSO_TYPE_NONE; |
244 | 244 | ||
245 | /* Data must not cross a page boundary. */ | 245 | /* Data must not cross a page boundary. */ |
246 | BUG_ON(size + offset > PAGE_SIZE<<compound_order(page)); | 246 | BUG_ON(size + offset > PAGE_SIZE<<compound_order(page)); |
@@ -299,12 +299,12 @@ static void xenvif_gop_frag_copy(struct xenvif *vif, struct sk_buff *skb, | |||
299 | } | 299 | } |
300 | 300 | ||
301 | /* Leave a gap for the GSO descriptor. */ | 301 | /* Leave a gap for the GSO descriptor. */ |
302 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) | 302 | if (skb_is_gso(skb)) { |
303 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; | 303 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) |
304 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | 304 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; |
305 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; | 305 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) |
306 | else | 306 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; |
307 | gso_type = XEN_NETIF_GSO_TYPE_NONE; | 307 | } |
308 | 308 | ||
309 | if (*head && ((1 << gso_type) & vif->gso_mask)) | 309 | if (*head && ((1 << gso_type) & vif->gso_mask)) |
310 | vif->rx.req_cons++; | 310 | vif->rx.req_cons++; |
@@ -338,19 +338,15 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
338 | int head = 1; | 338 | int head = 1; |
339 | int old_meta_prod; | 339 | int old_meta_prod; |
340 | int gso_type; | 340 | int gso_type; |
341 | int gso_size; | ||
342 | 341 | ||
343 | old_meta_prod = npo->meta_prod; | 342 | old_meta_prod = npo->meta_prod; |
344 | 343 | ||
345 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) { | 344 | gso_type = XEN_NETIF_GSO_TYPE_NONE; |
346 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; | 345 | if (skb_is_gso(skb)) { |
347 | gso_size = skb_shinfo(skb)->gso_size; | 346 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4) |
348 | } else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { | 347 | gso_type = XEN_NETIF_GSO_TYPE_TCPV4; |
349 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; | 348 | else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) |
350 | gso_size = skb_shinfo(skb)->gso_size; | 349 | gso_type = XEN_NETIF_GSO_TYPE_TCPV6; |
351 | } else { | ||
352 | gso_type = XEN_NETIF_GSO_TYPE_NONE; | ||
353 | gso_size = 0; | ||
354 | } | 350 | } |
355 | 351 | ||
356 | /* Set up a GSO prefix descriptor, if necessary */ | 352 | /* Set up a GSO prefix descriptor, if necessary */ |
@@ -358,7 +354,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
358 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 354 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
359 | meta = npo->meta + npo->meta_prod++; | 355 | meta = npo->meta + npo->meta_prod++; |
360 | meta->gso_type = gso_type; | 356 | meta->gso_type = gso_type; |
361 | meta->gso_size = gso_size; | 357 | meta->gso_size = skb_shinfo(skb)->gso_size; |
362 | meta->size = 0; | 358 | meta->size = 0; |
363 | meta->id = req->id; | 359 | meta->id = req->id; |
364 | } | 360 | } |
@@ -368,7 +364,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
368 | 364 | ||
369 | if ((1 << gso_type) & vif->gso_mask) { | 365 | if ((1 << gso_type) & vif->gso_mask) { |
370 | meta->gso_type = gso_type; | 366 | meta->gso_type = gso_type; |
371 | meta->gso_size = gso_size; | 367 | meta->gso_size = skb_shinfo(skb)->gso_size; |
372 | } else { | 368 | } else { |
373 | meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; | 369 | meta->gso_type = XEN_NETIF_GSO_TYPE_NONE; |
374 | meta->gso_size = 0; | 370 | meta->gso_size = 0; |
@@ -476,7 +472,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
476 | unsigned long offset; | 472 | unsigned long offset; |
477 | struct skb_cb_overlay *sco; | 473 | struct skb_cb_overlay *sco; |
478 | bool need_to_notify = false; | 474 | bool need_to_notify = false; |
479 | bool ring_full = false; | ||
480 | 475 | ||
481 | struct netrx_pending_operations npo = { | 476 | struct netrx_pending_operations npo = { |
482 | .copy = vif->grant_copy_op, | 477 | .copy = vif->grant_copy_op, |
@@ -486,7 +481,7 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
486 | skb_queue_head_init(&rxq); | 481 | skb_queue_head_init(&rxq); |
487 | 482 | ||
488 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { | 483 | while ((skb = skb_dequeue(&vif->rx_queue)) != NULL) { |
489 | int max_slots_needed; | 484 | RING_IDX max_slots_needed; |
490 | int i; | 485 | int i; |
491 | 486 | ||
492 | /* We need a cheap worse case estimate for the number of | 487 | /* We need a cheap worse case estimate for the number of |
@@ -501,17 +496,19 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
501 | size = skb_frag_size(&skb_shinfo(skb)->frags[i]); | 496 | size = skb_frag_size(&skb_shinfo(skb)->frags[i]); |
502 | max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE); | 497 | max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE); |
503 | } | 498 | } |
504 | if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || | 499 | if (skb_is_gso(skb) && |
505 | skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) | 500 | (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || |
501 | skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) | ||
506 | max_slots_needed++; | 502 | max_slots_needed++; |
507 | 503 | ||
508 | /* If the skb may not fit then bail out now */ | 504 | /* If the skb may not fit then bail out now */ |
509 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { | 505 | if (!xenvif_rx_ring_slots_available(vif, max_slots_needed)) { |
510 | skb_queue_head(&vif->rx_queue, skb); | 506 | skb_queue_head(&vif->rx_queue, skb); |
511 | need_to_notify = true; | 507 | need_to_notify = true; |
512 | ring_full = true; | 508 | vif->rx_last_skb_slots = max_slots_needed; |
513 | break; | 509 | break; |
514 | } | 510 | } else |
511 | vif->rx_last_skb_slots = 0; | ||
515 | 512 | ||
516 | sco = (struct skb_cb_overlay *)skb->cb; | 513 | sco = (struct skb_cb_overlay *)skb->cb; |
517 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); | 514 | sco->meta_slots_used = xenvif_gop_skb(skb, &npo); |
@@ -522,8 +519,6 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
522 | 519 | ||
523 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); | 520 | BUG_ON(npo.meta_prod > ARRAY_SIZE(vif->meta)); |
524 | 521 | ||
525 | vif->rx_queue_stopped = !npo.copy_prod && ring_full; | ||
526 | |||
527 | if (!npo.copy_prod) | 522 | if (!npo.copy_prod) |
528 | goto done; | 523 | goto done; |
529 | 524 | ||
@@ -1473,8 +1468,8 @@ static struct xen_netif_rx_response *make_rx_response(struct xenvif *vif, | |||
1473 | 1468 | ||
1474 | static inline int rx_work_todo(struct xenvif *vif) | 1469 | static inline int rx_work_todo(struct xenvif *vif) |
1475 | { | 1470 | { |
1476 | return (!skb_queue_empty(&vif->rx_queue) && !vif->rx_queue_stopped) || | 1471 | return !skb_queue_empty(&vif->rx_queue) && |
1477 | vif->rx_event; | 1472 | xenvif_rx_ring_slots_available(vif, vif->rx_last_skb_slots); |
1478 | } | 1473 | } |
1479 | 1474 | ||
1480 | static inline int tx_work_todo(struct xenvif *vif) | 1475 | static inline int tx_work_todo(struct xenvif *vif) |
@@ -1560,8 +1555,6 @@ int xenvif_kthread(void *data) | |||
1560 | if (!skb_queue_empty(&vif->rx_queue)) | 1555 | if (!skb_queue_empty(&vif->rx_queue)) |
1561 | xenvif_rx_action(vif); | 1556 | xenvif_rx_action(vif); |
1562 | 1557 | ||
1563 | vif->rx_event = false; | ||
1564 | |||
1565 | if (skb_queue_empty(&vif->rx_queue) && | 1558 | if (skb_queue_empty(&vif->rx_queue) && |
1566 | netif_queue_stopped(vif->dev)) | 1559 | netif_queue_stopped(vif->dev)) |
1567 | xenvif_start_queue(vif); | 1560 | xenvif_start_queue(vif); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ff04d4f95baa..e30d80033cbc 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -907,6 +907,7 @@ static int handle_incoming_queue(struct net_device *dev, | |||
907 | 907 | ||
908 | /* Ethernet work: Delayed to here as it peeks the header. */ | 908 | /* Ethernet work: Delayed to here as it peeks the header. */ |
909 | skb->protocol = eth_type_trans(skb, dev); | 909 | skb->protocol = eth_type_trans(skb, dev); |
910 | skb_reset_network_header(skb); | ||
910 | 911 | ||
911 | if (checksum_setup(dev, skb)) { | 912 | if (checksum_setup(dev, skb)) { |
912 | kfree_skb(skb); | 913 | kfree_skb(skb); |
@@ -1832,7 +1833,6 @@ static void netback_changed(struct xenbus_device *dev, | |||
1832 | case XenbusStateReconfiguring: | 1833 | case XenbusStateReconfiguring: |
1833 | case XenbusStateReconfigured: | 1834 | case XenbusStateReconfigured: |
1834 | case XenbusStateUnknown: | 1835 | case XenbusStateUnknown: |
1835 | case XenbusStateClosed: | ||
1836 | break; | 1836 | break; |
1837 | 1837 | ||
1838 | case XenbusStateInitWait: | 1838 | case XenbusStateInitWait: |
@@ -1847,6 +1847,10 @@ static void netback_changed(struct xenbus_device *dev, | |||
1847 | netdev_notify_peers(netdev); | 1847 | netdev_notify_peers(netdev); |
1848 | break; | 1848 | break; |
1849 | 1849 | ||
1850 | case XenbusStateClosed: | ||
1851 | if (dev->state == XenbusStateClosed) | ||
1852 | break; | ||
1853 | /* Missed the backend's CLOSING state -- fallthrough */ | ||
1850 | case XenbusStateClosing: | 1854 | case XenbusStateClosing: |
1851 | xenbus_frontend_closed(dev); | 1855 | xenbus_frontend_closed(dev); |
1852 | break; | 1856 | break; |
diff --git a/drivers/of/address.c b/drivers/of/address.c index d3dd41c840f1..1a54f1ffaadb 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -99,11 +99,12 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr) | |||
99 | static int of_bus_pci_match(struct device_node *np) | 99 | static int of_bus_pci_match(struct device_node *np) |
100 | { | 100 | { |
101 | /* | 101 | /* |
102 | * "pciex" is PCI Express | ||
102 | * "vci" is for the /chaos bridge on 1st-gen PCI powermacs | 103 | * "vci" is for the /chaos bridge on 1st-gen PCI powermacs |
103 | * "ht" is hypertransport | 104 | * "ht" is hypertransport |
104 | */ | 105 | */ |
105 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") || | 106 | return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") || |
106 | !strcmp(np->type, "ht"); | 107 | !strcmp(np->type, "vci") || !strcmp(np->type, "ht"); |
107 | } | 108 | } |
108 | 109 | ||
109 | static void of_bus_pci_count_cells(struct device_node *np, | 110 | static void of_bus_pci_count_cells(struct device_node *np, |
diff --git a/drivers/of/base.c b/drivers/of/base.c index ff85450d5683..89e888a78899 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -342,27 +342,72 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(of_get_cpu_node); | 343 | EXPORT_SYMBOL(of_get_cpu_node); |
344 | 344 | ||
345 | /** Checks if the given "compat" string matches one of the strings in | 345 | /** |
346 | * the device's "compatible" property | 346 | * __of_device_is_compatible() - Check if the node matches given constraints |
347 | * @device: pointer to node | ||
348 | * @compat: required compatible string, NULL or "" for any match | ||
349 | * @type: required device_type value, NULL or "" for any match | ||
350 | * @name: required node name, NULL or "" for any match | ||
351 | * | ||
352 | * Checks if the given @compat, @type and @name strings match the | ||
353 | * properties of the given @device. A constraints can be skipped by | ||
354 | * passing NULL or an empty string as the constraint. | ||
355 | * | ||
356 | * Returns 0 for no match, and a positive integer on match. The return | ||
357 | * value is a relative score with larger values indicating better | ||
358 | * matches. The score is weighted for the most specific compatible value | ||
359 | * to get the highest score. Matching type is next, followed by matching | ||
360 | * name. Practically speaking, this results in the following priority | ||
361 | * order for matches: | ||
362 | * | ||
363 | * 1. specific compatible && type && name | ||
364 | * 2. specific compatible && type | ||
365 | * 3. specific compatible && name | ||
366 | * 4. specific compatible | ||
367 | * 5. general compatible && type && name | ||
368 | * 6. general compatible && type | ||
369 | * 7. general compatible && name | ||
370 | * 8. general compatible | ||
371 | * 9. type && name | ||
372 | * 10. type | ||
373 | * 11. name | ||
347 | */ | 374 | */ |
348 | static int __of_device_is_compatible(const struct device_node *device, | 375 | static int __of_device_is_compatible(const struct device_node *device, |
349 | const char *compat) | 376 | const char *compat, const char *type, const char *name) |
350 | { | 377 | { |
351 | const char* cp; | 378 | struct property *prop; |
352 | int cplen, l; | 379 | const char *cp; |
380 | int index = 0, score = 0; | ||
381 | |||
382 | /* Compatible match has highest priority */ | ||
383 | if (compat && compat[0]) { | ||
384 | prop = __of_find_property(device, "compatible", NULL); | ||
385 | for (cp = of_prop_next_string(prop, NULL); cp; | ||
386 | cp = of_prop_next_string(prop, cp), index++) { | ||
387 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) { | ||
388 | score = INT_MAX/2 - (index << 2); | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | if (!score) | ||
393 | return 0; | ||
394 | } | ||
353 | 395 | ||
354 | cp = __of_get_property(device, "compatible", &cplen); | 396 | /* Matching type is better than matching name */ |
355 | if (cp == NULL) | 397 | if (type && type[0]) { |
356 | return 0; | 398 | if (!device->type || of_node_cmp(type, device->type)) |
357 | while (cplen > 0) { | 399 | return 0; |
358 | if (of_compat_cmp(cp, compat, strlen(compat)) == 0) | 400 | score += 2; |
359 | return 1; | ||
360 | l = strlen(cp) + 1; | ||
361 | cp += l; | ||
362 | cplen -= l; | ||
363 | } | 401 | } |
364 | 402 | ||
365 | return 0; | 403 | /* Matching name is a bit better than not */ |
404 | if (name && name[0]) { | ||
405 | if (!device->name || of_node_cmp(name, device->name)) | ||
406 | return 0; | ||
407 | score++; | ||
408 | } | ||
409 | |||
410 | return score; | ||
366 | } | 411 | } |
367 | 412 | ||
368 | /** Checks if the given "compat" string matches one of the strings in | 413 | /** Checks if the given "compat" string matches one of the strings in |
@@ -375,7 +420,7 @@ int of_device_is_compatible(const struct device_node *device, | |||
375 | int res; | 420 | int res; |
376 | 421 | ||
377 | raw_spin_lock_irqsave(&devtree_lock, flags); | 422 | raw_spin_lock_irqsave(&devtree_lock, flags); |
378 | res = __of_device_is_compatible(device, compat); | 423 | res = __of_device_is_compatible(device, compat, NULL, NULL); |
379 | raw_spin_unlock_irqrestore(&devtree_lock, flags); | 424 | raw_spin_unlock_irqrestore(&devtree_lock, flags); |
380 | return res; | 425 | return res; |
381 | } | 426 | } |
@@ -681,10 +726,7 @@ struct device_node *of_find_compatible_node(struct device_node *from, | |||
681 | raw_spin_lock_irqsave(&devtree_lock, flags); | 726 | raw_spin_lock_irqsave(&devtree_lock, flags); |
682 | np = from ? from->allnext : of_allnodes; | 727 | np = from ? from->allnext : of_allnodes; |
683 | for (; np; np = np->allnext) { | 728 | for (; np; np = np->allnext) { |
684 | if (type | 729 | if (__of_device_is_compatible(np, compatible, type, NULL) && |
685 | && !(np->type && (of_node_cmp(np->type, type) == 0))) | ||
686 | continue; | ||
687 | if (__of_device_is_compatible(np, compatible) && | ||
688 | of_node_get(np)) | 730 | of_node_get(np)) |
689 | break; | 731 | break; |
690 | } | 732 | } |
@@ -734,43 +776,22 @@ static | |||
734 | const struct of_device_id *__of_match_node(const struct of_device_id *matches, | 776 | const struct of_device_id *__of_match_node(const struct of_device_id *matches, |
735 | const struct device_node *node) | 777 | const struct device_node *node) |
736 | { | 778 | { |
737 | const char *cp; | 779 | const struct of_device_id *best_match = NULL; |
738 | int cplen, l; | 780 | int score, best_score = 0; |
739 | 781 | ||
740 | if (!matches) | 782 | if (!matches) |
741 | return NULL; | 783 | return NULL; |
742 | 784 | ||
743 | cp = __of_get_property(node, "compatible", &cplen); | 785 | for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) { |
744 | do { | 786 | score = __of_device_is_compatible(node, matches->compatible, |
745 | const struct of_device_id *m = matches; | 787 | matches->type, matches->name); |
746 | 788 | if (score > best_score) { | |
747 | /* Check against matches with current compatible string */ | 789 | best_match = matches; |
748 | while (m->name[0] || m->type[0] || m->compatible[0]) { | 790 | best_score = score; |
749 | int match = 1; | ||
750 | if (m->name[0]) | ||
751 | match &= node->name | ||
752 | && !strcmp(m->name, node->name); | ||
753 | if (m->type[0]) | ||
754 | match &= node->type | ||
755 | && !strcmp(m->type, node->type); | ||
756 | if (m->compatible[0]) | ||
757 | match &= cp | ||
758 | && !of_compat_cmp(m->compatible, cp, | ||
759 | strlen(m->compatible)); | ||
760 | if (match) | ||
761 | return m; | ||
762 | m++; | ||
763 | } | ||
764 | |||
765 | /* Get node's next compatible string */ | ||
766 | if (cp) { | ||
767 | l = strlen(cp) + 1; | ||
768 | cp += l; | ||
769 | cplen -= l; | ||
770 | } | 791 | } |
771 | } while (cp && (cplen > 0)); | 792 | } |
772 | 793 | ||
773 | return NULL; | 794 | return best_match; |
774 | } | 795 | } |
775 | 796 | ||
776 | /** | 797 | /** |
@@ -778,10 +799,7 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches, | |||
778 | * @matches: array of of device match structures to search in | 799 | * @matches: array of of device match structures to search in |
779 | * @node: the of device structure to match against | 800 | * @node: the of device structure to match against |
780 | * | 801 | * |
781 | * Low level utility function used by device matching. Matching order | 802 | * Low level utility function used by device matching. |
782 | * is to compare each of the node's compatibles with all given matches | ||
783 | * first. This implies node's compatible is sorted from specific to | ||
784 | * generic while matches can be in any order. | ||
785 | */ | 803 | */ |
786 | const struct of_device_id *of_match_node(const struct of_device_id *matches, | 804 | const struct of_device_id *of_match_node(const struct of_device_id *matches, |
787 | const struct device_node *node) | 805 | const struct device_node *node) |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 875b7b6f0d2a..5b3c24f3cde5 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -24,7 +24,11 @@ MODULE_LICENSE("GPL"); | |||
24 | 24 | ||
25 | static void of_set_phy_supported(struct phy_device *phydev, u32 max_speed) | 25 | static void of_set_phy_supported(struct phy_device *phydev, u32 max_speed) |
26 | { | 26 | { |
27 | phydev->supported |= PHY_DEFAULT_FEATURES; | 27 | /* The default values for phydev->supported are provided by the PHY |
28 | * driver "features" member, we want to reset to sane defaults fist | ||
29 | * before supporting higher speeds. | ||
30 | */ | ||
31 | phydev->supported &= PHY_DEFAULT_FEATURES; | ||
28 | 32 | ||
29 | switch (max_speed) { | 33 | switch (max_speed) { |
30 | default: | 34 | default: |
@@ -44,7 +48,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi | |||
44 | { | 48 | { |
45 | struct phy_device *phy; | 49 | struct phy_device *phy; |
46 | bool is_c45; | 50 | bool is_c45; |
47 | int rc, prev_irq; | 51 | int rc; |
48 | u32 max_speed = 0; | 52 | u32 max_speed = 0; |
49 | 53 | ||
50 | is_c45 = of_device_is_compatible(child, | 54 | is_c45 = of_device_is_compatible(child, |
@@ -54,12 +58,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *chi | |||
54 | if (!phy || IS_ERR(phy)) | 58 | if (!phy || IS_ERR(phy)) |
55 | return 1; | 59 | return 1; |
56 | 60 | ||
57 | if (mdio->irq) { | 61 | rc = irq_of_parse_and_map(child, 0); |
58 | prev_irq = mdio->irq[addr]; | 62 | if (rc > 0) { |
59 | mdio->irq[addr] = | 63 | phy->irq = rc; |
60 | irq_of_parse_and_map(child, 0); | 64 | if (mdio->irq) |
61 | if (!mdio->irq[addr]) | 65 | mdio->irq[addr] = rc; |
62 | mdio->irq[addr] = prev_irq; | 66 | } else { |
67 | if (mdio->irq) | ||
68 | phy->irq = mdio->irq[addr]; | ||
63 | } | 69 | } |
64 | 70 | ||
65 | /* Associate the OF node with the device structure so it | 71 | /* Associate the OF node with the device structure so it |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index e21012bde639..6643d1920985 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -300,6 +300,72 @@ static void __init of_selftest_parse_interrupts_extended(void) | |||
300 | of_node_put(np); | 300 | of_node_put(np); |
301 | } | 301 | } |
302 | 302 | ||
303 | static struct of_device_id match_node_table[] = { | ||
304 | { .data = "A", .name = "name0", }, /* Name alone is lowest priority */ | ||
305 | { .data = "B", .type = "type1", }, /* followed by type alone */ | ||
306 | |||
307 | { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */ | ||
308 | { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */ | ||
309 | { .data = "Cc", .name = "name2", .type = "type2", }, | ||
310 | |||
311 | { .data = "E", .compatible = "compat3" }, | ||
312 | { .data = "G", .compatible = "compat2", }, | ||
313 | { .data = "H", .compatible = "compat2", .name = "name5", }, | ||
314 | { .data = "I", .compatible = "compat2", .type = "type1", }, | ||
315 | { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", }, | ||
316 | { .data = "K", .compatible = "compat2", .name = "name9", }, | ||
317 | {} | ||
318 | }; | ||
319 | |||
320 | static struct { | ||
321 | const char *path; | ||
322 | const char *data; | ||
323 | } match_node_tests[] = { | ||
324 | { .path = "/testcase-data/match-node/name0", .data = "A", }, | ||
325 | { .path = "/testcase-data/match-node/name1", .data = "B", }, | ||
326 | { .path = "/testcase-data/match-node/a/name2", .data = "Ca", }, | ||
327 | { .path = "/testcase-data/match-node/b/name2", .data = "Cb", }, | ||
328 | { .path = "/testcase-data/match-node/c/name2", .data = "Cc", }, | ||
329 | { .path = "/testcase-data/match-node/name3", .data = "E", }, | ||
330 | { .path = "/testcase-data/match-node/name4", .data = "G", }, | ||
331 | { .path = "/testcase-data/match-node/name5", .data = "H", }, | ||
332 | { .path = "/testcase-data/match-node/name6", .data = "G", }, | ||
333 | { .path = "/testcase-data/match-node/name7", .data = "I", }, | ||
334 | { .path = "/testcase-data/match-node/name8", .data = "J", }, | ||
335 | { .path = "/testcase-data/match-node/name9", .data = "K", }, | ||
336 | }; | ||
337 | |||
338 | static void __init of_selftest_match_node(void) | ||
339 | { | ||
340 | struct device_node *np; | ||
341 | const struct of_device_id *match; | ||
342 | int i; | ||
343 | |||
344 | for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) { | ||
345 | np = of_find_node_by_path(match_node_tests[i].path); | ||
346 | if (!np) { | ||
347 | selftest(0, "missing testcase node %s\n", | ||
348 | match_node_tests[i].path); | ||
349 | continue; | ||
350 | } | ||
351 | |||
352 | match = of_match_node(match_node_table, np); | ||
353 | if (!match) { | ||
354 | selftest(0, "%s didn't match anything\n", | ||
355 | match_node_tests[i].path); | ||
356 | continue; | ||
357 | } | ||
358 | |||
359 | if (strcmp(match->data, match_node_tests[i].data) != 0) { | ||
360 | selftest(0, "%s got wrong match. expected %s, got %s\n", | ||
361 | match_node_tests[i].path, match_node_tests[i].data, | ||
362 | (const char *)match->data); | ||
363 | continue; | ||
364 | } | ||
365 | selftest(1, "passed"); | ||
366 | } | ||
367 | } | ||
368 | |||
303 | static int __init of_selftest(void) | 369 | static int __init of_selftest(void) |
304 | { | 370 | { |
305 | struct device_node *np; | 371 | struct device_node *np; |
@@ -316,6 +382,7 @@ static int __init of_selftest(void) | |||
316 | of_selftest_property_match_string(); | 382 | of_selftest_property_match_string(); |
317 | of_selftest_parse_interrupts(); | 383 | of_selftest_parse_interrupts(); |
318 | of_selftest_parse_interrupts_extended(); | 384 | of_selftest_parse_interrupts_extended(); |
385 | of_selftest_match_node(); | ||
319 | pr_info("end of selftest - %i passed, %i failed\n", | 386 | pr_info("end of selftest - %i passed, %i failed\n", |
320 | selftest_results.passed, selftest_results.failed); | 387 | selftest_results.passed, selftest_results.failed); |
321 | return 0; | 388 | return 0; |
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi new file mode 100644 index 000000000000..3a5b75a8e4d7 --- /dev/null +++ b/drivers/of/testcase-data/testcases.dtsi | |||
@@ -0,0 +1,3 @@ | |||
1 | #include "tests-phandle.dtsi" | ||
2 | #include "tests-interrupts.dtsi" | ||
3 | #include "tests-match.dtsi" | ||
diff --git a/drivers/of/testcase-data/tests-interrupts.dtsi b/drivers/of/testcase-data/tests-interrupts.dtsi new file mode 100644 index 000000000000..c843720bd3e5 --- /dev/null +++ b/drivers/of/testcase-data/tests-interrupts.dtsi | |||
@@ -0,0 +1,58 @@ | |||
1 | |||
2 | / { | ||
3 | testcase-data { | ||
4 | interrupts { | ||
5 | #address-cells = <1>; | ||
6 | #size-cells = <1>; | ||
7 | test_intc0: intc0 { | ||
8 | interrupt-controller; | ||
9 | #interrupt-cells = <1>; | ||
10 | }; | ||
11 | |||
12 | test_intc1: intc1 { | ||
13 | interrupt-controller; | ||
14 | #interrupt-cells = <3>; | ||
15 | }; | ||
16 | |||
17 | test_intc2: intc2 { | ||
18 | interrupt-controller; | ||
19 | #interrupt-cells = <2>; | ||
20 | }; | ||
21 | |||
22 | test_intmap0: intmap0 { | ||
23 | #interrupt-cells = <1>; | ||
24 | #address-cells = <0>; | ||
25 | interrupt-map = <1 &test_intc0 9>, | ||
26 | <2 &test_intc1 10 11 12>, | ||
27 | <3 &test_intc2 13 14>, | ||
28 | <4 &test_intc2 15 16>; | ||
29 | }; | ||
30 | |||
31 | test_intmap1: intmap1 { | ||
32 | #interrupt-cells = <2>; | ||
33 | interrupt-map = <0x5000 1 2 &test_intc0 15>; | ||
34 | }; | ||
35 | |||
36 | interrupts0 { | ||
37 | interrupt-parent = <&test_intc0>; | ||
38 | interrupts = <1>, <2>, <3>, <4>; | ||
39 | }; | ||
40 | |||
41 | interrupts1 { | ||
42 | interrupt-parent = <&test_intmap0>; | ||
43 | interrupts = <1>, <2>, <3>, <4>; | ||
44 | }; | ||
45 | |||
46 | interrupts-extended0 { | ||
47 | reg = <0x5000 0x100>; | ||
48 | interrupts-extended = <&test_intc0 1>, | ||
49 | <&test_intc1 2 3 4>, | ||
50 | <&test_intc2 5 6>, | ||
51 | <&test_intmap0 1>, | ||
52 | <&test_intmap0 2>, | ||
53 | <&test_intmap0 3>, | ||
54 | <&test_intmap1 1 2>; | ||
55 | }; | ||
56 | }; | ||
57 | }; | ||
58 | }; | ||
diff --git a/drivers/of/testcase-data/tests-match.dtsi b/drivers/of/testcase-data/tests-match.dtsi new file mode 100644 index 000000000000..c9e541129534 --- /dev/null +++ b/drivers/of/testcase-data/tests-match.dtsi | |||
@@ -0,0 +1,19 @@ | |||
1 | |||
2 | / { | ||
3 | testcase-data { | ||
4 | match-node { | ||
5 | name0 { }; | ||
6 | name1 { device_type = "type1"; }; | ||
7 | a { name2 { device_type = "type1"; }; }; | ||
8 | b { name2 { }; }; | ||
9 | c { name2 { device_type = "type2"; }; }; | ||
10 | name3 { compatible = "compat3"; }; | ||
11 | name4 { compatible = "compat2", "compat3"; }; | ||
12 | name5 { compatible = "compat2", "compat3"; }; | ||
13 | name6 { compatible = "compat1", "compat2", "compat3"; }; | ||
14 | name7 { compatible = "compat2"; device_type = "type1"; }; | ||
15 | name8 { compatible = "compat2"; device_type = "type1"; }; | ||
16 | name9 { compatible = "compat2"; }; | ||
17 | }; | ||
18 | }; | ||
19 | }; | ||
diff --git a/drivers/of/testcase-data/tests-phandle.dtsi b/drivers/of/testcase-data/tests-phandle.dtsi new file mode 100644 index 000000000000..0007d3cd7dc2 --- /dev/null +++ b/drivers/of/testcase-data/tests-phandle.dtsi | |||
@@ -0,0 +1,39 @@ | |||
1 | |||
2 | / { | ||
3 | testcase-data { | ||
4 | phandle-tests { | ||
5 | provider0: provider0 { | ||
6 | #phandle-cells = <0>; | ||
7 | }; | ||
8 | |||
9 | provider1: provider1 { | ||
10 | #phandle-cells = <1>; | ||
11 | }; | ||
12 | |||
13 | provider2: provider2 { | ||
14 | #phandle-cells = <2>; | ||
15 | }; | ||
16 | |||
17 | provider3: provider3 { | ||
18 | #phandle-cells = <3>; | ||
19 | }; | ||
20 | |||
21 | consumer-a { | ||
22 | phandle-list = <&provider1 1>, | ||
23 | <&provider2 2 0>, | ||
24 | <0>, | ||
25 | <&provider3 4 4 3>, | ||
26 | <&provider2 5 100>, | ||
27 | <&provider0>, | ||
28 | <&provider1 7>; | ||
29 | phandle-list-names = "first", "second", "third"; | ||
30 | |||
31 | phandle-list-bad-phandle = <12345678 0 0>; | ||
32 | phandle-list-bad-args = <&provider2 1 0>, | ||
33 | <&provider3 0>; | ||
34 | empty-property; | ||
35 | unterminated-string = [40 41 42 43]; | ||
36 | }; | ||
37 | }; | ||
38 | }; | ||
39 | }; | ||
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 00660cc502c5..38901665c770 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | |||
162 | 162 | ||
163 | avail = *r; | 163 | avail = *r; |
164 | pci_clip_resource_to_region(bus, &avail, region); | 164 | pci_clip_resource_to_region(bus, &avail, region); |
165 | if (!resource_size(&avail)) | ||
166 | continue; | ||
167 | 165 | ||
168 | /* | 166 | /* |
169 | * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to | 167 | * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 13478ecd4113..0e79665afd44 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -60,14 +60,6 @@ | |||
60 | #define PCIE_DEBUG_CTRL 0x1a60 | 60 | #define PCIE_DEBUG_CTRL 0x1a60 |
61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) | 61 | #define PCIE_DEBUG_SOFT_RESET BIT(20) |
62 | 62 | ||
63 | /* | ||
64 | * This product ID is registered by Marvell, and used when the Marvell | ||
65 | * SoC is not the root complex, but an endpoint on the PCIe bus. It is | ||
66 | * therefore safe to re-use this PCI ID for our emulated PCI-to-PCI | ||
67 | * bridge. | ||
68 | */ | ||
69 | #define MARVELL_EMULATED_PCI_PCI_BRIDGE_ID 0x7846 | ||
70 | |||
71 | /* PCI configuration space of a PCI-to-PCI bridge */ | 63 | /* PCI configuration space of a PCI-to-PCI bridge */ |
72 | struct mvebu_sw_pci_bridge { | 64 | struct mvebu_sw_pci_bridge { |
73 | u16 vendor; | 65 | u16 vendor; |
@@ -388,7 +380,8 @@ static void mvebu_sw_pci_bridge_init(struct mvebu_pcie_port *port) | |||
388 | 380 | ||
389 | bridge->class = PCI_CLASS_BRIDGE_PCI; | 381 | bridge->class = PCI_CLASS_BRIDGE_PCI; |
390 | bridge->vendor = PCI_VENDOR_ID_MARVELL; | 382 | bridge->vendor = PCI_VENDOR_ID_MARVELL; |
391 | bridge->device = MARVELL_EMULATED_PCI_PCI_BRIDGE_ID; | 383 | bridge->device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
384 | bridge->revision = mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; | ||
392 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; | 385 | bridge->header_type = PCI_HEADER_TYPE_BRIDGE; |
393 | bridge->cache_line_size = 0x10; | 386 | bridge->cache_line_size = 0x10; |
394 | 387 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cd929aed3613..7c7a388c85ab 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -210,10 +210,29 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | static void dock_event(acpi_handle handle, u32 type, void *data) | ||
214 | { | ||
215 | struct acpiphp_context *context; | ||
216 | |||
217 | mutex_lock(&acpiphp_context_lock); | ||
218 | context = acpiphp_get_context(handle); | ||
219 | if (!context || WARN_ON(context->handle != handle) | ||
220 | || context->func.parent->is_going_away) { | ||
221 | mutex_unlock(&acpiphp_context_lock); | ||
222 | return; | ||
223 | } | ||
224 | get_bridge(context->func.parent); | ||
225 | acpiphp_put_context(context); | ||
226 | mutex_unlock(&acpiphp_context_lock); | ||
227 | |||
228 | hotplug_event(handle, type, data); | ||
229 | |||
230 | put_bridge(context->func.parent); | ||
231 | } | ||
213 | 232 | ||
214 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 233 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
215 | .fixup = post_dock_fixups, | 234 | .fixup = post_dock_fixups, |
216 | .handler = hotplug_event, | 235 | .handler = dock_event, |
217 | }; | 236 | }; |
218 | 237 | ||
219 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 238 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
@@ -441,7 +460,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
441 | list_del(&bridge->list); | 460 | list_del(&bridge->list); |
442 | mutex_unlock(&bridge_mutex); | 461 | mutex_unlock(&bridge_mutex); |
443 | 462 | ||
463 | mutex_lock(&acpiphp_context_lock); | ||
444 | bridge->is_going_away = true; | 464 | bridge->is_going_away = true; |
465 | mutex_unlock(&acpiphp_context_lock); | ||
445 | } | 466 | } |
446 | 467 | ||
447 | /** | 468 | /** |
@@ -709,6 +730,17 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
709 | return (unsigned int)sta; | 730 | return (unsigned int)sta; |
710 | } | 731 | } |
711 | 732 | ||
733 | static inline bool device_status_valid(unsigned int sta) | ||
734 | { | ||
735 | /* | ||
736 | * ACPI spec says that _STA may return bit 0 clear with bit 3 set | ||
737 | * if the device is valid but does not require a device driver to be | ||
738 | * loaded (Section 6.3.7 of ACPI 5.0A). | ||
739 | */ | ||
740 | unsigned int mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING; | ||
741 | return (sta & mask) == mask; | ||
742 | } | ||
743 | |||
712 | /** | 744 | /** |
713 | * trim_stale_devices - remove PCI devices that are not responding. | 745 | * trim_stale_devices - remove PCI devices that are not responding. |
714 | * @dev: PCI device to start walking the hierarchy from. | 746 | * @dev: PCI device to start walking the hierarchy from. |
@@ -724,7 +756,7 @@ static void trim_stale_devices(struct pci_dev *dev) | |||
724 | unsigned long long sta; | 756 | unsigned long long sta; |
725 | 757 | ||
726 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | 758 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); |
727 | alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL) | 759 | alive = (ACPI_SUCCESS(status) && device_status_valid(sta)) |
728 | || acpiphp_no_hotplug(handle); | 760 | || acpiphp_no_hotplug(handle); |
729 | } | 761 | } |
730 | if (!alive) { | 762 | if (!alive) { |
@@ -742,7 +774,7 @@ static void trim_stale_devices(struct pci_dev *dev) | |||
742 | 774 | ||
743 | /* The device is a bridge. so check the bus below it. */ | 775 | /* The device is a bridge. so check the bus below it. */ |
744 | pm_runtime_get_sync(&dev->dev); | 776 | pm_runtime_get_sync(&dev->dev); |
745 | list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) | 777 | list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) |
746 | trim_stale_devices(child); | 778 | trim_stale_devices(child); |
747 | 779 | ||
748 | pm_runtime_put(&dev->dev); | 780 | pm_runtime_put(&dev->dev); |
@@ -771,10 +803,10 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) | |||
771 | mutex_lock(&slot->crit_sect); | 803 | mutex_lock(&slot->crit_sect); |
772 | if (slot_no_hotplug(slot)) { | 804 | if (slot_no_hotplug(slot)) { |
773 | ; /* do nothing */ | 805 | ; /* do nothing */ |
774 | } else if (get_slot_status(slot) == ACPI_STA_ALL) { | 806 | } else if (device_status_valid(get_slot_status(slot))) { |
775 | /* remove stale devices if any */ | 807 | /* remove stale devices if any */ |
776 | list_for_each_entry_safe(dev, tmp, &bus->devices, | 808 | list_for_each_entry_safe_reverse(dev, tmp, |
777 | bus_list) | 809 | &bus->devices, bus_list) |
778 | if (PCI_SLOT(dev->devfn) == slot->device) | 810 | if (PCI_SLOT(dev->devfn) == slot->device) |
779 | trim_stale_devices(dev); | 811 | trim_stale_devices(dev); |
780 | 812 | ||
@@ -805,7 +837,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
805 | int i; | 837 | int i; |
806 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 838 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
807 | 839 | ||
808 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 840 | list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { |
809 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { | 841 | for (i=0; i<PCI_BRIDGE_RESOURCES; i++) { |
810 | struct resource *res = &dev->resource[i]; | 842 | struct resource *res = &dev->resource[i]; |
811 | if ((res->flags & type_mask) && !res->start && | 843 | if ((res->flags & type_mask) && !res->start && |
@@ -829,7 +861,11 @@ void acpiphp_check_host_bridge(acpi_handle handle) | |||
829 | 861 | ||
830 | bridge = acpiphp_handle_to_bridge(handle); | 862 | bridge = acpiphp_handle_to_bridge(handle); |
831 | if (bridge) { | 863 | if (bridge) { |
864 | pci_lock_rescan_remove(); | ||
865 | |||
832 | acpiphp_check_bridge(bridge); | 866 | acpiphp_check_bridge(bridge); |
867 | |||
868 | pci_unlock_rescan_remove(); | ||
833 | put_bridge(bridge); | 869 | put_bridge(bridge); |
834 | } | 870 | } |
835 | } | 871 | } |
@@ -852,6 +888,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
852 | 888 | ||
853 | mutex_unlock(&acpiphp_context_lock); | 889 | mutex_unlock(&acpiphp_context_lock); |
854 | 890 | ||
891 | pci_lock_rescan_remove(); | ||
855 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 892 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
856 | 893 | ||
857 | switch (type) { | 894 | switch (type) { |
@@ -905,6 +942,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
905 | break; | 942 | break; |
906 | } | 943 | } |
907 | 944 | ||
945 | pci_unlock_rescan_remove(); | ||
908 | if (bridge) | 946 | if (bridge) |
909 | put_bridge(bridge); | 947 | put_bridge(bridge); |
910 | } | 948 | } |
@@ -915,11 +953,9 @@ static void hotplug_event_work(void *data, u32 type) | |||
915 | acpi_handle handle = context->handle; | 953 | acpi_handle handle = context->handle; |
916 | 954 | ||
917 | acpi_scan_lock_acquire(); | 955 | acpi_scan_lock_acquire(); |
918 | pci_lock_rescan_remove(); | ||
919 | 956 | ||
920 | hotplug_event(handle, type, context); | 957 | hotplug_event(handle, type, context); |
921 | 958 | ||
922 | pci_unlock_rescan_remove(); | ||
923 | acpi_scan_lock_release(); | 959 | acpi_scan_lock_release(); |
924 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); | 960 | acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); |
925 | put_bridge(context->func.parent); | 961 | put_bridge(context->func.parent); |
@@ -937,6 +973,7 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
937 | { | 973 | { |
938 | struct acpiphp_context *context; | 974 | struct acpiphp_context *context; |
939 | u32 ost_code = ACPI_OST_SC_SUCCESS; | 975 | u32 ost_code = ACPI_OST_SC_SUCCESS; |
976 | acpi_status status; | ||
940 | 977 | ||
941 | switch (type) { | 978 | switch (type) { |
942 | case ACPI_NOTIFY_BUS_CHECK: | 979 | case ACPI_NOTIFY_BUS_CHECK: |
@@ -972,13 +1009,20 @@ static void handle_hotplug_event(acpi_handle handle, u32 type, void *data) | |||
972 | 1009 | ||
973 | mutex_lock(&acpiphp_context_lock); | 1010 | mutex_lock(&acpiphp_context_lock); |
974 | context = acpiphp_get_context(handle); | 1011 | context = acpiphp_get_context(handle); |
975 | if (context && !WARN_ON(context->handle != handle)) { | 1012 | if (!context || WARN_ON(context->handle != handle) |
976 | get_bridge(context->func.parent); | 1013 | || context->func.parent->is_going_away) |
977 | acpiphp_put_context(context); | 1014 | goto err_out; |
978 | acpi_hotplug_execute(hotplug_event_work, context, type); | 1015 | |
1016 | get_bridge(context->func.parent); | ||
1017 | acpiphp_put_context(context); | ||
1018 | status = acpi_hotplug_execute(hotplug_event_work, context, type); | ||
1019 | if (ACPI_SUCCESS(status)) { | ||
979 | mutex_unlock(&acpiphp_context_lock); | 1020 | mutex_unlock(&acpiphp_context_lock); |
980 | return; | 1021 | return; |
981 | } | 1022 | } |
1023 | put_bridge(context->func.parent); | ||
1024 | |||
1025 | err_out: | ||
982 | mutex_unlock(&acpiphp_context_lock); | 1026 | mutex_unlock(&acpiphp_context_lock); |
983 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 1027 | ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
984 | 1028 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a0fec6ce571..955ab7990c5b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -545,9 +545,15 @@ static int populate_msi_sysfs(struct pci_dev *pdev) | |||
545 | return -ENOMEM; | 545 | return -ENOMEM; |
546 | list_for_each_entry(entry, &pdev->msi_list, list) { | 546 | list_for_each_entry(entry, &pdev->msi_list, list) { |
547 | char *name = kmalloc(20, GFP_KERNEL); | 547 | char *name = kmalloc(20, GFP_KERNEL); |
548 | if (!name) | ||
549 | goto error_attrs; | ||
550 | |||
548 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); | 551 | msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); |
549 | if (!msi_dev_attr) | 552 | if (!msi_dev_attr) { |
553 | kfree(name); | ||
550 | goto error_attrs; | 554 | goto error_attrs; |
555 | } | ||
556 | |||
551 | sprintf(name, "%d", entry->irq); | 557 | sprintf(name, "%d", entry->irq); |
552 | sysfs_attr_init(&msi_dev_attr->attr); | 558 | sysfs_attr_init(&msi_dev_attr->attr); |
553 | msi_dev_attr->attr.name = name; | 559 | msi_dev_attr->attr.name = name; |
@@ -589,6 +595,7 @@ error_attrs: | |||
589 | ++count; | 595 | ++count; |
590 | msi_attr = msi_attrs[count]; | 596 | msi_attr = msi_attrs[count]; |
591 | } | 597 | } |
598 | kfree(msi_attrs); | ||
592 | return ret; | 599 | return ret; |
593 | } | 600 | } |
594 | 601 | ||
@@ -959,7 +966,6 @@ EXPORT_SYMBOL(pci_disable_msi); | |||
959 | /** | 966 | /** |
960 | * pci_msix_vec_count - return the number of device's MSI-X table entries | 967 | * pci_msix_vec_count - return the number of device's MSI-X table entries |
961 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 968 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
962 | |||
963 | * This function returns the number of device's MSI-X table entries and | 969 | * This function returns the number of device's MSI-X table entries and |
964 | * therefore the number of MSI-X vectors device is capable of sending. | 970 | * therefore the number of MSI-X vectors device is capable of sending. |
965 | * It returns a negative errno if the device is not capable of sending MSI-X | 971 | * It returns a negative errno if the device is not capable of sending MSI-X |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1febe90831b4..fdbc294821e6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1181,6 +1181,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) |
1182 | { | 1182 | { |
1183 | int err; | 1183 | int err; |
1184 | u16 cmd; | ||
1185 | u8 pin; | ||
1184 | 1186 | ||
1185 | err = pci_set_power_state(dev, PCI_D0); | 1187 | err = pci_set_power_state(dev, PCI_D0); |
1186 | if (err < 0 && err != -EIO) | 1188 | if (err < 0 && err != -EIO) |
@@ -1190,6 +1192,17 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars) | |||
1190 | return err; | 1192 | return err; |
1191 | pci_fixup_device(pci_fixup_enable, dev); | 1193 | pci_fixup_device(pci_fixup_enable, dev); |
1192 | 1194 | ||
1195 | if (dev->msi_enabled || dev->msix_enabled) | ||
1196 | return 0; | ||
1197 | |||
1198 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | ||
1199 | if (pin) { | ||
1200 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
1201 | if (cmd & PCI_COMMAND_INTX_DISABLE) | ||
1202 | pci_write_config_word(dev, PCI_COMMAND, | ||
1203 | cmd & ~PCI_COMMAND_INTX_DISABLE); | ||
1204 | } | ||
1205 | |||
1193 | return 0; | 1206 | return 0; |
1194 | } | 1207 | } |
1195 | 1208 | ||
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index afa2354f6600..c7a551c2d5f1 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -5,7 +5,7 @@ | |||
5 | menu "PHY Subsystem" | 5 | menu "PHY Subsystem" |
6 | 6 | ||
7 | config GENERIC_PHY | 7 | config GENERIC_PHY |
8 | tristate "PHY Core" | 8 | bool "PHY Core" |
9 | help | 9 | help |
10 | Generic PHY support. | 10 | Generic PHY support. |
11 | 11 | ||
@@ -61,6 +61,7 @@ config PHY_EXYNOS_DP_VIDEO | |||
61 | config BCM_KONA_USB2_PHY | 61 | config BCM_KONA_USB2_PHY |
62 | tristate "Broadcom Kona USB2 PHY Driver" | 62 | tristate "Broadcom Kona USB2 PHY Driver" |
63 | depends on GENERIC_PHY | 63 | depends on GENERIC_PHY |
64 | depends on HAS_IOMEM | ||
64 | help | 65 | help |
65 | Enable this to support the Broadcom Kona USB 2.0 PHY. | 66 | Enable this to support the Broadcom Kona USB 2.0 PHY. |
66 | 67 | ||
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 645c867c1257..6c738376daff 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -162,6 +162,9 @@ int phy_init(struct phy *phy) | |||
162 | { | 162 | { |
163 | int ret; | 163 | int ret; |
164 | 164 | ||
165 | if (!phy) | ||
166 | return 0; | ||
167 | |||
165 | ret = phy_pm_runtime_get_sync(phy); | 168 | ret = phy_pm_runtime_get_sync(phy); |
166 | if (ret < 0 && ret != -ENOTSUPP) | 169 | if (ret < 0 && ret != -ENOTSUPP) |
167 | return ret; | 170 | return ret; |
@@ -173,6 +176,8 @@ int phy_init(struct phy *phy) | |||
173 | dev_err(&phy->dev, "phy init failed --> %d\n", ret); | 176 | dev_err(&phy->dev, "phy init failed --> %d\n", ret); |
174 | goto out; | 177 | goto out; |
175 | } | 178 | } |
179 | } else { | ||
180 | ret = 0; /* Override possible ret == -ENOTSUPP */ | ||
176 | } | 181 | } |
177 | ++phy->init_count; | 182 | ++phy->init_count; |
178 | 183 | ||
@@ -187,6 +192,9 @@ int phy_exit(struct phy *phy) | |||
187 | { | 192 | { |
188 | int ret; | 193 | int ret; |
189 | 194 | ||
195 | if (!phy) | ||
196 | return 0; | ||
197 | |||
190 | ret = phy_pm_runtime_get_sync(phy); | 198 | ret = phy_pm_runtime_get_sync(phy); |
191 | if (ret < 0 && ret != -ENOTSUPP) | 199 | if (ret < 0 && ret != -ENOTSUPP) |
192 | return ret; | 200 | return ret; |
@@ -212,6 +220,9 @@ int phy_power_on(struct phy *phy) | |||
212 | { | 220 | { |
213 | int ret; | 221 | int ret; |
214 | 222 | ||
223 | if (!phy) | ||
224 | return 0; | ||
225 | |||
215 | ret = phy_pm_runtime_get_sync(phy); | 226 | ret = phy_pm_runtime_get_sync(phy); |
216 | if (ret < 0 && ret != -ENOTSUPP) | 227 | if (ret < 0 && ret != -ENOTSUPP) |
217 | return ret; | 228 | return ret; |
@@ -223,6 +234,8 @@ int phy_power_on(struct phy *phy) | |||
223 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); | 234 | dev_err(&phy->dev, "phy poweron failed --> %d\n", ret); |
224 | goto out; | 235 | goto out; |
225 | } | 236 | } |
237 | } else { | ||
238 | ret = 0; /* Override possible ret == -ENOTSUPP */ | ||
226 | } | 239 | } |
227 | ++phy->power_count; | 240 | ++phy->power_count; |
228 | mutex_unlock(&phy->mutex); | 241 | mutex_unlock(&phy->mutex); |
@@ -240,6 +253,9 @@ int phy_power_off(struct phy *phy) | |||
240 | { | 253 | { |
241 | int ret; | 254 | int ret; |
242 | 255 | ||
256 | if (!phy) | ||
257 | return 0; | ||
258 | |||
243 | mutex_lock(&phy->mutex); | 259 | mutex_lock(&phy->mutex); |
244 | if (phy->power_count == 1 && phy->ops->power_off) { | 260 | if (phy->power_count == 1 && phy->ops->power_off) { |
245 | ret = phy->ops->power_off(phy); | 261 | ret = phy->ops->power_off(phy); |
@@ -308,7 +324,7 @@ err0: | |||
308 | */ | 324 | */ |
309 | void phy_put(struct phy *phy) | 325 | void phy_put(struct phy *phy) |
310 | { | 326 | { |
311 | if (IS_ERR(phy)) | 327 | if (!phy || IS_ERR(phy)) |
312 | return; | 328 | return; |
313 | 329 | ||
314 | module_put(phy->ops->owner); | 330 | module_put(phy->ops->owner); |
@@ -328,6 +344,9 @@ void devm_phy_put(struct device *dev, struct phy *phy) | |||
328 | { | 344 | { |
329 | int r; | 345 | int r; |
330 | 346 | ||
347 | if (!phy) | ||
348 | return; | ||
349 | |||
331 | r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); | 350 | r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); |
332 | dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); | 351 | dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); |
333 | } | 352 | } |
@@ -389,17 +408,11 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
389 | index = of_property_match_string(dev->of_node, "phy-names", | 408 | index = of_property_match_string(dev->of_node, "phy-names", |
390 | string); | 409 | string); |
391 | phy = of_phy_get(dev, index); | 410 | phy = of_phy_get(dev, index); |
392 | if (IS_ERR(phy)) { | ||
393 | dev_err(dev, "unable to find phy\n"); | ||
394 | return phy; | ||
395 | } | ||
396 | } else { | 411 | } else { |
397 | phy = phy_lookup(dev, string); | 412 | phy = phy_lookup(dev, string); |
398 | if (IS_ERR(phy)) { | ||
399 | dev_err(dev, "unable to find phy\n"); | ||
400 | return phy; | ||
401 | } | ||
402 | } | 413 | } |
414 | if (IS_ERR(phy)) | ||
415 | return phy; | ||
403 | 416 | ||
404 | if (!try_module_get(phy->ops->owner)) | 417 | if (!try_module_get(phy->ops->owner)) |
405 | return ERR_PTR(-EPROBE_DEFER); | 418 | return ERR_PTR(-EPROBE_DEFER); |
@@ -411,6 +424,27 @@ struct phy *phy_get(struct device *dev, const char *string) | |||
411 | EXPORT_SYMBOL_GPL(phy_get); | 424 | EXPORT_SYMBOL_GPL(phy_get); |
412 | 425 | ||
413 | /** | 426 | /** |
427 | * phy_optional_get() - lookup and obtain a reference to an optional phy. | ||
428 | * @dev: device that requests this phy | ||
429 | * @string: the phy name as given in the dt data or the name of the controller | ||
430 | * port for non-dt case | ||
431 | * | ||
432 | * Returns the phy driver, after getting a refcount to it; or | ||
433 | * NULL if there is no such phy. The caller is responsible for | ||
434 | * calling phy_put() to release that count. | ||
435 | */ | ||
436 | struct phy *phy_optional_get(struct device *dev, const char *string) | ||
437 | { | ||
438 | struct phy *phy = phy_get(dev, string); | ||
439 | |||
440 | if (PTR_ERR(phy) == -ENODEV) | ||
441 | phy = NULL; | ||
442 | |||
443 | return phy; | ||
444 | } | ||
445 | EXPORT_SYMBOL_GPL(phy_optional_get); | ||
446 | |||
447 | /** | ||
414 | * devm_phy_get() - lookup and obtain a reference to a phy. | 448 | * devm_phy_get() - lookup and obtain a reference to a phy. |
415 | * @dev: device that requests this phy | 449 | * @dev: device that requests this phy |
416 | * @string: the phy name as given in the dt data or phy device name | 450 | * @string: the phy name as given in the dt data or phy device name |
@@ -441,6 +475,30 @@ struct phy *devm_phy_get(struct device *dev, const char *string) | |||
441 | EXPORT_SYMBOL_GPL(devm_phy_get); | 475 | EXPORT_SYMBOL_GPL(devm_phy_get); |
442 | 476 | ||
443 | /** | 477 | /** |
478 | * devm_phy_optional_get() - lookup and obtain a reference to an optional phy. | ||
479 | * @dev: device that requests this phy | ||
480 | * @string: the phy name as given in the dt data or phy device name | ||
481 | * for non-dt case | ||
482 | * | ||
483 | * Gets the phy using phy_get(), and associates a device with it using | ||
484 | * devres. On driver detach, release function is invoked on the devres | ||
485 | * data, then, devres data is freed. This differs to devm_phy_get() in | ||
486 | * that if the phy does not exist, it is not considered an error and | ||
487 | * -ENODEV will not be returned. Instead the NULL phy is returned, | ||
488 | * which can be passed to all other phy consumer calls. | ||
489 | */ | ||
490 | struct phy *devm_phy_optional_get(struct device *dev, const char *string) | ||
491 | { | ||
492 | struct phy *phy = devm_phy_get(dev, string); | ||
493 | |||
494 | if (PTR_ERR(phy) == -ENODEV) | ||
495 | phy = NULL; | ||
496 | |||
497 | return phy; | ||
498 | } | ||
499 | EXPORT_SYMBOL_GPL(devm_phy_optional_get); | ||
500 | |||
501 | /** | ||
444 | * phy_create() - create a new phy | 502 | * phy_create() - create a new phy |
445 | * @dev: device that is creating the new phy | 503 | * @dev: device that is creating the new phy |
446 | * @ops: function pointers for performing phy operations | 504 | * @ops: function pointers for performing phy operations |
diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 1dbe6ce7b2ce..0786fef842e7 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c | |||
@@ -76,10 +76,6 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) | |||
76 | if (IS_ERR(state->regs)) | 76 | if (IS_ERR(state->regs)) |
77 | return PTR_ERR(state->regs); | 77 | return PTR_ERR(state->regs); |
78 | 78 | ||
79 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
80 | if (IS_ERR(phy_provider)) | ||
81 | return PTR_ERR(phy_provider); | ||
82 | |||
83 | phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL); | 79 | phy = devm_phy_create(dev, &exynos_dp_video_phy_ops, NULL); |
84 | if (IS_ERR(phy)) { | 80 | if (IS_ERR(phy)) { |
85 | dev_err(dev, "failed to create Display Port PHY\n"); | 81 | dev_err(dev, "failed to create Display Port PHY\n"); |
@@ -87,6 +83,10 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) | |||
87 | } | 83 | } |
88 | phy_set_drvdata(phy, state); | 84 | phy_set_drvdata(phy, state); |
89 | 85 | ||
86 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | ||
87 | if (IS_ERR(phy_provider)) | ||
88 | return PTR_ERR(phy_provider); | ||
89 | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
diff --git a/drivers/phy/phy-exynos-mipi-video.c b/drivers/phy/phy-exynos-mipi-video.c index 0c5efab11af1..7f139326a642 100644 --- a/drivers/phy/phy-exynos-mipi-video.c +++ b/drivers/phy/phy-exynos-mipi-video.c | |||
@@ -134,11 +134,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
134 | dev_set_drvdata(dev, state); | 134 | dev_set_drvdata(dev, state); |
135 | spin_lock_init(&state->slock); | 135 | spin_lock_init(&state->slock); |
136 | 136 | ||
137 | phy_provider = devm_of_phy_provider_register(dev, | ||
138 | exynos_mipi_video_phy_xlate); | ||
139 | if (IS_ERR(phy_provider)) | ||
140 | return PTR_ERR(phy_provider); | ||
141 | |||
142 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { | 137 | for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) { |
143 | struct phy *phy = devm_phy_create(dev, | 138 | struct phy *phy = devm_phy_create(dev, |
144 | &exynos_mipi_video_phy_ops, NULL); | 139 | &exynos_mipi_video_phy_ops, NULL); |
@@ -152,6 +147,11 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev) | |||
152 | phy_set_drvdata(phy, &state->phys[i]); | 147 | phy_set_drvdata(phy, &state->phys[i]); |
153 | } | 148 | } |
154 | 149 | ||
150 | phy_provider = devm_of_phy_provider_register(dev, | ||
151 | exynos_mipi_video_phy_xlate); | ||
152 | if (IS_ERR(phy_provider)) | ||
153 | return PTR_ERR(phy_provider); | ||
154 | |||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
157 | 157 | ||
diff --git a/drivers/phy/phy-mvebu-sata.c b/drivers/phy/phy-mvebu-sata.c index d43786f62437..d70ecd6a1b3f 100644 --- a/drivers/phy/phy-mvebu-sata.c +++ b/drivers/phy/phy-mvebu-sata.c | |||
@@ -99,17 +99,17 @@ static int phy_mvebu_sata_probe(struct platform_device *pdev) | |||
99 | if (IS_ERR(priv->clk)) | 99 | if (IS_ERR(priv->clk)) |
100 | return PTR_ERR(priv->clk); | 100 | return PTR_ERR(priv->clk); |
101 | 101 | ||
102 | phy_provider = devm_of_phy_provider_register(&pdev->dev, | ||
103 | of_phy_simple_xlate); | ||
104 | if (IS_ERR(phy_provider)) | ||
105 | return PTR_ERR(phy_provider); | ||
106 | |||
107 | phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL); | 102 | phy = devm_phy_create(&pdev->dev, &phy_mvebu_sata_ops, NULL); |
108 | if (IS_ERR(phy)) | 103 | if (IS_ERR(phy)) |
109 | return PTR_ERR(phy); | 104 | return PTR_ERR(phy); |
110 | 105 | ||
111 | phy_set_drvdata(phy, priv); | 106 | phy_set_drvdata(phy, priv); |
112 | 107 | ||
108 | phy_provider = devm_of_phy_provider_register(&pdev->dev, | ||
109 | of_phy_simple_xlate); | ||
110 | if (IS_ERR(phy_provider)) | ||
111 | return PTR_ERR(phy_provider); | ||
112 | |||
113 | /* The boot loader may of left it on. Turn it off. */ | 113 | /* The boot loader may of left it on. Turn it off. */ |
114 | phy_mvebu_sata_power_off(phy); | 114 | phy_mvebu_sata_power_off(phy); |
115 | 115 | ||
diff --git a/drivers/phy/phy-omap-usb2.c b/drivers/phy/phy-omap-usb2.c index bfc5c337f99a..7699752fba11 100644 --- a/drivers/phy/phy-omap-usb2.c +++ b/drivers/phy/phy-omap-usb2.c | |||
@@ -177,11 +177,6 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
177 | phy->phy.otg = otg; | 177 | phy->phy.otg = otg; |
178 | phy->phy.type = USB_PHY_TYPE_USB2; | 178 | phy->phy.type = USB_PHY_TYPE_USB2; |
179 | 179 | ||
180 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
181 | of_phy_simple_xlate); | ||
182 | if (IS_ERR(phy_provider)) | ||
183 | return PTR_ERR(phy_provider); | ||
184 | |||
185 | control_node = of_parse_phandle(node, "ctrl-module", 0); | 180 | control_node = of_parse_phandle(node, "ctrl-module", 0); |
186 | if (!control_node) { | 181 | if (!control_node) { |
187 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); | 182 | dev_err(&pdev->dev, "Failed to get control device phandle\n"); |
@@ -214,6 +209,11 @@ static int omap_usb2_probe(struct platform_device *pdev) | |||
214 | 209 | ||
215 | phy_set_drvdata(generic_phy, phy); | 210 | phy_set_drvdata(generic_phy, phy); |
216 | 211 | ||
212 | phy_provider = devm_of_phy_provider_register(phy->dev, | ||
213 | of_phy_simple_xlate); | ||
214 | if (IS_ERR(phy_provider)) | ||
215 | return PTR_ERR(phy_provider); | ||
216 | |||
217 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); | 217 | phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); |
218 | if (IS_ERR(phy->wkupclk)) { | 218 | if (IS_ERR(phy->wkupclk)) { |
219 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); | 219 | dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); |
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c index daf65e68aaab..c3ace1db8136 100644 --- a/drivers/phy/phy-twl4030-usb.c +++ b/drivers/phy/phy-twl4030-usb.c | |||
@@ -695,11 +695,6 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
695 | otg->set_host = twl4030_set_host; | 695 | otg->set_host = twl4030_set_host; |
696 | otg->set_peripheral = twl4030_set_peripheral; | 696 | otg->set_peripheral = twl4030_set_peripheral; |
697 | 697 | ||
698 | phy_provider = devm_of_phy_provider_register(twl->dev, | ||
699 | of_phy_simple_xlate); | ||
700 | if (IS_ERR(phy_provider)) | ||
701 | return PTR_ERR(phy_provider); | ||
702 | |||
703 | phy = devm_phy_create(twl->dev, &ops, init_data); | 698 | phy = devm_phy_create(twl->dev, &ops, init_data); |
704 | if (IS_ERR(phy)) { | 699 | if (IS_ERR(phy)) { |
705 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); | 700 | dev_dbg(&pdev->dev, "Failed to create PHY\n"); |
@@ -708,6 +703,11 @@ static int twl4030_usb_probe(struct platform_device *pdev) | |||
708 | 703 | ||
709 | phy_set_drvdata(phy, twl); | 704 | phy_set_drvdata(phy, twl); |
710 | 705 | ||
706 | phy_provider = devm_of_phy_provider_register(twl->dev, | ||
707 | of_phy_simple_xlate); | ||
708 | if (IS_ERR(phy_provider)) | ||
709 | return PTR_ERR(phy_provider); | ||
710 | |||
711 | /* init spinlock for workqueue */ | 711 | /* init spinlock for workqueue */ |
712 | spin_lock_init(&twl->lock); | 712 | spin_lock_init(&twl->lock); |
713 | 713 | ||
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index be361b7cd30f..1e4e69384baa 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -217,7 +217,7 @@ config PINCTRL_IMX28 | |||
217 | select PINCTRL_MXS | 217 | select PINCTRL_MXS |
218 | 218 | ||
219 | config PINCTRL_MSM | 219 | config PINCTRL_MSM |
220 | tristate | 220 | bool |
221 | select PINMUX | 221 | select PINMUX |
222 | select PINCONF | 222 | select PINCONF |
223 | select GENERIC_PINCONF | 223 | select GENERIC_PINCONF |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 5ee61a470016..c0fe6091566a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -851,7 +851,9 @@ static struct pinctrl *create_pinctrl(struct device *dev) | |||
851 | kref_init(&p->users); | 851 | kref_init(&p->users); |
852 | 852 | ||
853 | /* Add the pinctrl handle to the global list */ | 853 | /* Add the pinctrl handle to the global list */ |
854 | mutex_lock(&pinctrl_list_mutex); | ||
854 | list_add_tail(&p->node, &pinctrl_list); | 855 | list_add_tail(&p->node, &pinctrl_list); |
856 | mutex_unlock(&pinctrl_list_mutex); | ||
855 | 857 | ||
856 | return p; | 858 | return p; |
857 | } | 859 | } |
@@ -1642,8 +1644,10 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) | |||
1642 | device_root, pctldev, &pinctrl_groups_ops); | 1644 | device_root, pctldev, &pinctrl_groups_ops); |
1643 | debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, | 1645 | debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, |
1644 | device_root, pctldev, &pinctrl_gpioranges_ops); | 1646 | device_root, pctldev, &pinctrl_gpioranges_ops); |
1645 | pinmux_init_device_debugfs(device_root, pctldev); | 1647 | if (pctldev->desc->pmxops) |
1646 | pinconf_init_device_debugfs(device_root, pctldev); | 1648 | pinmux_init_device_debugfs(device_root, pctldev); |
1649 | if (pctldev->desc->confops) | ||
1650 | pinconf_init_device_debugfs(device_root, pctldev); | ||
1647 | } | 1651 | } |
1648 | 1652 | ||
1649 | static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) | 1653 | static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) |
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 38c6f8b9790e..d990e33d8aa7 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -1286,22 +1286,22 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type) | |||
1286 | 1286 | ||
1287 | switch (type) { | 1287 | switch (type) { |
1288 | case IRQ_TYPE_EDGE_RISING: | 1288 | case IRQ_TYPE_EDGE_RISING: |
1289 | irq_set_handler(d->irq, handle_simple_irq); | 1289 | __irq_set_handler_locked(d->irq, handle_simple_irq); |
1290 | writel_relaxed(mask, pio + PIO_ESR); | 1290 | writel_relaxed(mask, pio + PIO_ESR); |
1291 | writel_relaxed(mask, pio + PIO_REHLSR); | 1291 | writel_relaxed(mask, pio + PIO_REHLSR); |
1292 | break; | 1292 | break; |
1293 | case IRQ_TYPE_EDGE_FALLING: | 1293 | case IRQ_TYPE_EDGE_FALLING: |
1294 | irq_set_handler(d->irq, handle_simple_irq); | 1294 | __irq_set_handler_locked(d->irq, handle_simple_irq); |
1295 | writel_relaxed(mask, pio + PIO_ESR); | 1295 | writel_relaxed(mask, pio + PIO_ESR); |
1296 | writel_relaxed(mask, pio + PIO_FELLSR); | 1296 | writel_relaxed(mask, pio + PIO_FELLSR); |
1297 | break; | 1297 | break; |
1298 | case IRQ_TYPE_LEVEL_LOW: | 1298 | case IRQ_TYPE_LEVEL_LOW: |
1299 | irq_set_handler(d->irq, handle_level_irq); | 1299 | __irq_set_handler_locked(d->irq, handle_level_irq); |
1300 | writel_relaxed(mask, pio + PIO_LSR); | 1300 | writel_relaxed(mask, pio + PIO_LSR); |
1301 | writel_relaxed(mask, pio + PIO_FELLSR); | 1301 | writel_relaxed(mask, pio + PIO_FELLSR); |
1302 | break; | 1302 | break; |
1303 | case IRQ_TYPE_LEVEL_HIGH: | 1303 | case IRQ_TYPE_LEVEL_HIGH: |
1304 | irq_set_handler(d->irq, handle_level_irq); | 1304 | __irq_set_handler_locked(d->irq, handle_level_irq); |
1305 | writel_relaxed(mask, pio + PIO_LSR); | 1305 | writel_relaxed(mask, pio + PIO_LSR); |
1306 | writel_relaxed(mask, pio + PIO_REHLSR); | 1306 | writel_relaxed(mask, pio + PIO_REHLSR); |
1307 | break; | 1307 | break; |
@@ -1310,7 +1310,7 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type) | |||
1310 | * disable additional interrupt modes: | 1310 | * disable additional interrupt modes: |
1311 | * fall back to default behavior | 1311 | * fall back to default behavior |
1312 | */ | 1312 | */ |
1313 | irq_set_handler(d->irq, handle_simple_irq); | 1313 | __irq_set_handler_locked(d->irq, handle_simple_irq); |
1314 | writel_relaxed(mask, pio + PIO_AIMDR); | 1314 | writel_relaxed(mask, pio + PIO_AIMDR); |
1315 | return 0; | 1315 | return 0; |
1316 | case IRQ_TYPE_NONE: | 1316 | case IRQ_TYPE_NONE: |
diff --git a/drivers/pinctrl/pinctrl-capri.c b/drivers/pinctrl/pinctrl-capri.c index 4669c53f99b0..eb2500212147 100644 --- a/drivers/pinctrl/pinctrl-capri.c +++ b/drivers/pinctrl/pinctrl-capri.c | |||
@@ -1435,7 +1435,7 @@ int __init capri_pinctrl_probe(struct platform_device *pdev) | |||
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | static struct of_device_id capri_pinctrl_of_match[] = { | 1437 | static struct of_device_id capri_pinctrl_of_match[] = { |
1438 | { .compatible = "brcm,capri-pinctrl", }, | 1438 | { .compatible = "brcm,bcm11351-pinctrl", }, |
1439 | { }, | 1439 | { }, |
1440 | }; | 1440 | }; |
1441 | 1441 | ||
diff --git a/drivers/pinctrl/pinctrl-imx1-core.c b/drivers/pinctrl/pinctrl-imx1-core.c index 17aecde1b51d..815384b377b5 100644 --- a/drivers/pinctrl/pinctrl-imx1-core.c +++ b/drivers/pinctrl/pinctrl-imx1-core.c | |||
@@ -45,7 +45,7 @@ struct imx1_pinctrl { | |||
45 | #define MX1_DDIR 0x00 | 45 | #define MX1_DDIR 0x00 |
46 | #define MX1_OCR 0x04 | 46 | #define MX1_OCR 0x04 |
47 | #define MX1_ICONFA 0x0c | 47 | #define MX1_ICONFA 0x0c |
48 | #define MX1_ICONFB 0x10 | 48 | #define MX1_ICONFB 0x14 |
49 | #define MX1_GIUS 0x20 | 49 | #define MX1_GIUS 0x20 |
50 | #define MX1_GPR 0x38 | 50 | #define MX1_GPR 0x38 |
51 | #define MX1_PUEN 0x40 | 51 | #define MX1_PUEN 0x40 |
@@ -97,13 +97,13 @@ static void imx1_write_2bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |||
97 | u32 old_val; | 97 | u32 old_val; |
98 | u32 new_val; | 98 | u32 new_val; |
99 | 99 | ||
100 | dev_dbg(ipctl->dev, "write: register 0x%p offset %d value 0x%x\n", | ||
101 | reg, offset, value); | ||
102 | |||
103 | /* Use the next register if the pin's port pin number is >=16 */ | 100 | /* Use the next register if the pin's port pin number is >=16 */ |
104 | if (pin_id % 32 >= 16) | 101 | if (pin_id % 32 >= 16) |
105 | reg += 0x04; | 102 | reg += 0x04; |
106 | 103 | ||
104 | dev_dbg(ipctl->dev, "write: register 0x%p offset %d value 0x%x\n", | ||
105 | reg, offset, value); | ||
106 | |||
107 | /* Get current state of pins */ | 107 | /* Get current state of pins */ |
108 | old_val = readl(reg); | 108 | old_val = readl(reg); |
109 | old_val &= mask; | 109 | old_val &= mask; |
@@ -139,7 +139,7 @@ static int imx1_read_2bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, | |||
139 | u32 reg_offset) | 139 | u32 reg_offset) |
140 | { | 140 | { |
141 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; | 141 | void __iomem *reg = imx1_mem(ipctl, pin_id) + reg_offset; |
142 | int offset = pin_id % 16; | 142 | int offset = (pin_id % 16) * 2; |
143 | 143 | ||
144 | /* Use the next register if the pin's port pin number is >=16 */ | 144 | /* Use the next register if the pin's port pin number is >=16 */ |
145 | if (pin_id % 32 >= 16) | 145 | if (pin_id % 32 >= 16) |
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c index 9ccf681dad2f..f9fabe9bf47d 100644 --- a/drivers/pinctrl/pinctrl-sunxi.c +++ b/drivers/pinctrl/pinctrl-sunxi.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
16 | #include <linux/irqdomain.h> | 16 | #include <linux/irqdomain.h> |
17 | #include <linux/irqchip/chained_irq.h> | ||
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
18 | #include <linux/of.h> | 19 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
@@ -584,7 +585,7 @@ static int sunxi_pinctrl_irq_set_type(struct irq_data *d, | |||
584 | spin_lock_irqsave(&pctl->lock, flags); | 585 | spin_lock_irqsave(&pctl->lock, flags); |
585 | 586 | ||
586 | regval = readl(pctl->membase + reg); | 587 | regval = readl(pctl->membase + reg); |
587 | regval &= ~IRQ_CFG_IRQ_MASK; | 588 | regval &= ~(IRQ_CFG_IRQ_MASK << index); |
588 | writel(regval | (mode << index), pctl->membase + reg); | 589 | writel(regval | (mode << index), pctl->membase + reg); |
589 | 590 | ||
590 | spin_unlock_irqrestore(&pctl->lock, flags); | 591 | spin_unlock_irqrestore(&pctl->lock, flags); |
@@ -665,6 +666,7 @@ static struct irq_chip sunxi_pinctrl_irq_chip = { | |||
665 | 666 | ||
666 | static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) | 667 | static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) |
667 | { | 668 | { |
669 | struct irq_chip *chip = irq_get_chip(irq); | ||
668 | struct sunxi_pinctrl *pctl = irq_get_handler_data(irq); | 670 | struct sunxi_pinctrl *pctl = irq_get_handler_data(irq); |
669 | const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG); | 671 | const unsigned long reg = readl(pctl->membase + IRQ_STATUS_REG); |
670 | 672 | ||
@@ -674,10 +676,12 @@ static void sunxi_pinctrl_irq_handler(unsigned irq, struct irq_desc *desc) | |||
674 | if (reg) { | 676 | if (reg) { |
675 | int irqoffset; | 677 | int irqoffset; |
676 | 678 | ||
679 | chained_irq_enter(chip, desc); | ||
677 | for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) { | 680 | for_each_set_bit(irqoffset, ®, SUNXI_IRQ_NUMBER) { |
678 | int pin_irq = irq_find_mapping(pctl->domain, irqoffset); | 681 | int pin_irq = irq_find_mapping(pctl->domain, irqoffset); |
679 | generic_handle_irq(pin_irq); | 682 | generic_handle_irq(pin_irq); |
680 | } | 683 | } |
684 | chained_irq_exit(chip, desc); | ||
681 | } | 685 | } |
682 | } | 686 | } |
683 | 687 | ||
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h index 01c494f8a14f..552b0e97077a 100644 --- a/drivers/pinctrl/pinctrl-sunxi.h +++ b/drivers/pinctrl/pinctrl-sunxi.h | |||
@@ -511,7 +511,7 @@ static inline u32 sunxi_pull_offset(u16 pin) | |||
511 | 511 | ||
512 | static inline u32 sunxi_irq_cfg_reg(u16 irq) | 512 | static inline u32 sunxi_irq_cfg_reg(u16 irq) |
513 | { | 513 | { |
514 | u8 reg = irq / IRQ_CFG_IRQ_PER_REG; | 514 | u8 reg = irq / IRQ_CFG_IRQ_PER_REG * 0x04; |
515 | return reg + IRQ_CFG_REG; | 515 | return reg + IRQ_CFG_REG; |
516 | } | 516 | } |
517 | 517 | ||
@@ -523,7 +523,7 @@ static inline u32 sunxi_irq_cfg_offset(u16 irq) | |||
523 | 523 | ||
524 | static inline u32 sunxi_irq_ctrl_reg(u16 irq) | 524 | static inline u32 sunxi_irq_ctrl_reg(u16 irq) |
525 | { | 525 | { |
526 | u8 reg = irq / IRQ_CTRL_IRQ_PER_REG; | 526 | u8 reg = irq / IRQ_CTRL_IRQ_PER_REG * 0x04; |
527 | return reg + IRQ_CTRL_REG; | 527 | return reg + IRQ_CTRL_REG; |
528 | } | 528 | } |
529 | 529 | ||
@@ -535,7 +535,7 @@ static inline u32 sunxi_irq_ctrl_offset(u16 irq) | |||
535 | 535 | ||
536 | static inline u32 sunxi_irq_status_reg(u16 irq) | 536 | static inline u32 sunxi_irq_status_reg(u16 irq) |
537 | { | 537 | { |
538 | u8 reg = irq / IRQ_STATUS_IRQ_PER_REG; | 538 | u8 reg = irq / IRQ_STATUS_IRQ_PER_REG * 0x04; |
539 | return reg + IRQ_STATUS_REG; | 539 | return reg + IRQ_STATUS_REG; |
540 | } | 540 | } |
541 | 541 | ||
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index a2e93a2b5ff4..e767355ab0ad 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c | |||
@@ -645,7 +645,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev, | |||
645 | GFP_KERNEL); | 645 | GFP_KERNEL); |
646 | if (!pmx->regs) { | 646 | if (!pmx->regs) { |
647 | dev_err(&pdev->dev, "Can't alloc regs pointer\n"); | 647 | dev_err(&pdev->dev, "Can't alloc regs pointer\n"); |
648 | return -ENODEV; | 648 | return -ENOMEM; |
649 | } | 649 | } |
650 | 650 | ||
651 | for (i = 0; i < pmx->nbanks; i++) { | 651 | for (i = 0; i < pmx->nbanks; i++) { |
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 77d103fe39d9..567d6918d50b 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c | |||
@@ -89,7 +89,8 @@ enum { | |||
89 | 89 | ||
90 | /* GPSR6 */ | 90 | /* GPSR6 */ |
91 | FN_IP13_10, FN_IP13_11, FN_IP13_12, FN_IP13_13, FN_IP13_14, | 91 | FN_IP13_10, FN_IP13_11, FN_IP13_12, FN_IP13_13, FN_IP13_14, |
92 | FN_IP13_15, FN_IP13_18_16, FN_IP13_21_19, FN_IP13_22, FN_IP13_24_23, | 92 | FN_IP13_15, FN_IP13_18_16, FN_IP13_21_19, |
93 | FN_IP13_22, FN_IP13_24_23, FN_SD1_CLK, | ||
93 | FN_IP13_25, FN_IP13_26, FN_IP13_27, FN_IP13_30_28, FN_IP14_1_0, | 94 | FN_IP13_25, FN_IP13_26, FN_IP13_27, FN_IP13_30_28, FN_IP14_1_0, |
94 | FN_IP14_2, FN_IP14_3, FN_IP14_4, FN_IP14_5, FN_IP14_6, FN_IP14_7, | 95 | FN_IP14_2, FN_IP14_3, FN_IP14_4, FN_IP14_5, FN_IP14_6, FN_IP14_7, |
95 | FN_IP14_10_8, FN_IP14_13_11, FN_IP14_16_14, FN_IP14_19_17, | 96 | FN_IP14_10_8, FN_IP14_13_11, FN_IP14_16_14, FN_IP14_19_17, |
@@ -788,6 +789,7 @@ static const u16 pinmux_data[] = { | |||
788 | PINMUX_DATA(USB1_PWEN_MARK, FN_USB1_PWEN), | 789 | PINMUX_DATA(USB1_PWEN_MARK, FN_USB1_PWEN), |
789 | PINMUX_DATA(USB1_OVC_MARK, FN_USB1_OVC), | 790 | PINMUX_DATA(USB1_OVC_MARK, FN_USB1_OVC), |
790 | PINMUX_DATA(DU0_DOTCLKIN_MARK, FN_DU0_DOTCLKIN), | 791 | PINMUX_DATA(DU0_DOTCLKIN_MARK, FN_DU0_DOTCLKIN), |
792 | PINMUX_DATA(SD1_CLK_MARK, FN_SD1_CLK), | ||
791 | 793 | ||
792 | /* IPSR0 */ | 794 | /* IPSR0 */ |
793 | PINMUX_IPSR_DATA(IP0_0, D0), | 795 | PINMUX_IPSR_DATA(IP0_0, D0), |
@@ -3825,7 +3827,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { | |||
3825 | GP_6_11_FN, FN_IP13_25, | 3827 | GP_6_11_FN, FN_IP13_25, |
3826 | GP_6_10_FN, FN_IP13_24_23, | 3828 | GP_6_10_FN, FN_IP13_24_23, |
3827 | GP_6_9_FN, FN_IP13_22, | 3829 | GP_6_9_FN, FN_IP13_22, |
3828 | 0, 0, | 3830 | GP_6_8_FN, FN_SD1_CLK, |
3829 | GP_6_7_FN, FN_IP13_21_19, | 3831 | GP_6_7_FN, FN_IP13_21_19, |
3830 | GP_6_6_FN, FN_IP13_18_16, | 3832 | GP_6_6_FN, FN_IP13_18_16, |
3831 | GP_6_5_FN, FN_IP13_15, | 3833 | GP_6_5_FN, FN_IP13_15, |
diff --git a/drivers/pinctrl/sirf/pinctrl-prima2.c b/drivers/pinctrl/sirf/pinctrl-prima2.c index 37b42651d76a..dde0285544d6 100644 --- a/drivers/pinctrl/sirf/pinctrl-prima2.c +++ b/drivers/pinctrl/sirf/pinctrl-prima2.c | |||
@@ -413,7 +413,7 @@ static const struct sirfsoc_padmux ac97_padmux = { | |||
413 | .funcval = 0, | 413 | .funcval = 0, |
414 | }; | 414 | }; |
415 | 415 | ||
416 | static const unsigned ac97_pins[] = { 33, 34, 35, 36 }; | 416 | static const unsigned ac97_pins[] = { 43, 44, 45, 46 }; |
417 | 417 | ||
418 | static const struct sirfsoc_muxmask spi1_muxmask[] = { | 418 | static const struct sirfsoc_muxmask spi1_muxmask[] = { |
419 | { | 419 | { |
diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index a0d6152701cd..617a4916b50f 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c | |||
@@ -598,7 +598,7 @@ static unsigned int sirfsoc_gpio_irq_startup(struct irq_data *d) | |||
598 | { | 598 | { |
599 | struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d); | 599 | struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d); |
600 | 600 | ||
601 | if (gpio_lock_as_irq(&bank->chip.gc, d->hwirq)) | 601 | if (gpio_lock_as_irq(&bank->chip.gc, d->hwirq % SIRFSOC_GPIO_BANK_SIZE)) |
602 | dev_err(bank->chip.gc.dev, | 602 | dev_err(bank->chip.gc.dev, |
603 | "unable to lock HW IRQ %lu for IRQ\n", | 603 | "unable to lock HW IRQ %lu for IRQ\n", |
604 | d->hwirq); | 604 | d->hwirq); |
@@ -611,7 +611,7 @@ static void sirfsoc_gpio_irq_shutdown(struct irq_data *d) | |||
611 | struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d); | 611 | struct sirfsoc_gpio_bank *bank = irq_data_get_irq_chip_data(d); |
612 | 612 | ||
613 | sirfsoc_gpio_irq_mask(d); | 613 | sirfsoc_gpio_irq_mask(d); |
614 | gpio_unlock_as_irq(&bank->chip.gc, d->hwirq); | 614 | gpio_unlock_as_irq(&bank->chip.gc, d->hwirq % SIRFSOC_GPIO_BANK_SIZE); |
615 | } | 615 | } |
616 | 616 | ||
617 | static struct irq_chip sirfsoc_irq_chip = { | 617 | static struct irq_chip sirfsoc_irq_chip = { |
diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index b28d1af9c232..9802b67040cc 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c | |||
@@ -276,7 +276,20 @@ static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data, | |||
276 | if (!configs) | 276 | if (!configs) |
277 | return -ENOMEM; | 277 | return -ENOMEM; |
278 | 278 | ||
279 | configs[0] = pull; | 279 | switch (pull) { |
280 | case 0: | ||
281 | configs[0] = PIN_CONFIG_BIAS_DISABLE; | ||
282 | break; | ||
283 | case 1: | ||
284 | configs[0] = PIN_CONFIG_BIAS_PULL_DOWN; | ||
285 | break; | ||
286 | case 2: | ||
287 | configs[0] = PIN_CONFIG_BIAS_PULL_UP; | ||
288 | break; | ||
289 | default: | ||
290 | configs[0] = PIN_CONFIG_BIAS_DISABLE; | ||
291 | dev_err(data->dev, "invalid pull state %d - disabling\n", pull); | ||
292 | } | ||
280 | 293 | ||
281 | map->type = PIN_MAP_TYPE_CONFIGS_PIN; | 294 | map->type = PIN_MAP_TYPE_CONFIGS_PIN; |
282 | map->data.configs.group_or_pin = data->groups[group]; | 295 | map->data.configs.group_or_pin = data->groups[group]; |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 167f3d00c916..66977ebf13b3 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -183,9 +183,7 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
183 | struct resource r = {0}; | 183 | struct resource r = {0}; |
184 | int i, flags; | 184 | int i, flags; |
185 | 185 | ||
186 | if (acpi_dev_resource_memory(res, &r) | 186 | if (acpi_dev_resource_address_space(res, &r) |
187 | || acpi_dev_resource_io(res, &r) | ||
188 | || acpi_dev_resource_address_space(res, &r) | ||
189 | || acpi_dev_resource_ext_address_space(res, &r)) { | 187 | || acpi_dev_resource_ext_address_space(res, &r)) { |
190 | pnp_add_resource(dev, &r); | 188 | pnp_add_resource(dev, &r); |
191 | return AE_OK; | 189 | return AE_OK; |
@@ -217,6 +215,17 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, | |||
217 | } | 215 | } |
218 | 216 | ||
219 | switch (res->type) { | 217 | switch (res->type) { |
218 | case ACPI_RESOURCE_TYPE_MEMORY24: | ||
219 | case ACPI_RESOURCE_TYPE_MEMORY32: | ||
220 | case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: | ||
221 | if (acpi_dev_resource_memory(res, &r)) | ||
222 | pnp_add_resource(dev, &r); | ||
223 | break; | ||
224 | case ACPI_RESOURCE_TYPE_IO: | ||
225 | case ACPI_RESOURCE_TYPE_FIXED_IO: | ||
226 | if (acpi_dev_resource_io(res, &r)) | ||
227 | pnp_add_resource(dev, &r); | ||
228 | break; | ||
220 | case ACPI_RESOURCE_TYPE_DMA: | 229 | case ACPI_RESOURCE_TYPE_DMA: |
221 | dma = &res->data.dma; | 230 | dma = &res->data.dma; |
222 | if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) | 231 | if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) |
diff --git a/drivers/power/ds2782_battery.c b/drivers/power/ds2782_battery.c index 563174891c90..041f9b638d28 100644 --- a/drivers/power/ds2782_battery.c +++ b/drivers/power/ds2782_battery.c | |||
@@ -192,7 +192,7 @@ static int ds2786_get_voltage(struct ds278x_info *info, int *voltage_uV) | |||
192 | 192 | ||
193 | /* | 193 | /* |
194 | * Voltage is measured in units of 1.22mV. The voltage is stored as | 194 | * Voltage is measured in units of 1.22mV. The voltage is stored as |
195 | * a 10-bit number plus sign, in the upper bits of a 16-bit register | 195 | * a 12-bit number plus sign, in the upper bits of a 16-bit register |
196 | */ | 196 | */ |
197 | err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); | 197 | err = ds278x_read_reg16(info, DS278x_REG_VOLT_MSB, &raw); |
198 | if (err) | 198 | if (err) |
diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 80edb7d8cb54..0b4cf9d63291 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c | |||
@@ -444,8 +444,6 @@ static int isp1704_charger_probe(struct platform_device *pdev) | |||
444 | ret = PTR_ERR(isp->phy); | 444 | ret = PTR_ERR(isp->phy); |
445 | goto fail0; | 445 | goto fail0; |
446 | } | 446 | } |
447 | if (!isp->phy) | ||
448 | goto fail0; | ||
449 | 447 | ||
450 | isp->dev = &pdev->dev; | 448 | isp->dev = &pdev->dev; |
451 | platform_set_drvdata(pdev, isp); | 449 | platform_set_drvdata(pdev, isp); |
diff --git a/drivers/power/max17040_battery.c b/drivers/power/max17040_battery.c index c7ff6d67f158..0fbac861080d 100644 --- a/drivers/power/max17040_battery.c +++ b/drivers/power/max17040_battery.c | |||
@@ -148,7 +148,7 @@ static void max17040_get_online(struct i2c_client *client) | |||
148 | { | 148 | { |
149 | struct max17040_chip *chip = i2c_get_clientdata(client); | 149 | struct max17040_chip *chip = i2c_get_clientdata(client); |
150 | 150 | ||
151 | if (chip->pdata->battery_online) | 151 | if (chip->pdata && chip->pdata->battery_online) |
152 | chip->online = chip->pdata->battery_online(); | 152 | chip->online = chip->pdata->battery_online(); |
153 | else | 153 | else |
154 | chip->online = 1; | 154 | chip->online = 1; |
@@ -158,7 +158,8 @@ static void max17040_get_status(struct i2c_client *client) | |||
158 | { | 158 | { |
159 | struct max17040_chip *chip = i2c_get_clientdata(client); | 159 | struct max17040_chip *chip = i2c_get_clientdata(client); |
160 | 160 | ||
161 | if (!chip->pdata->charger_online || !chip->pdata->charger_enable) { | 161 | if (!chip->pdata || !chip->pdata->charger_online |
162 | || !chip->pdata->charger_enable) { | ||
162 | chip->status = POWER_SUPPLY_STATUS_UNKNOWN; | 163 | chip->status = POWER_SUPPLY_STATUS_UNKNOWN; |
163 | return; | 164 | return; |
164 | } | 165 | } |
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 8a843a04c224..a40b9c34e9ff 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c | |||
@@ -52,8 +52,10 @@ lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm) | |||
52 | offset = pwm_map->output[i]; | 52 | offset = pwm_map->output[i]; |
53 | 53 | ||
54 | /* Return an error if the pin is already assigned */ | 54 | /* Return an error if the pin is already assigned */ |
55 | if (test_and_set_bit(offset, &lp3943->pin_used)) | 55 | if (test_and_set_bit(offset, &lp3943->pin_used)) { |
56 | kfree(pwm_map); | ||
56 | return ERR_PTR(-EBUSY); | 57 | return ERR_PTR(-EBUSY); |
58 | } | ||
57 | } | 59 | } |
58 | 60 | ||
59 | return pwm_map; | 61 | return pwm_map; |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index b4b0d83f9ef6..7061ac0ad428 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -678,6 +678,7 @@ struct tsi721_bdma_chan { | |||
678 | struct list_head free_list; | 678 | struct list_head free_list; |
679 | dma_cookie_t completed_cookie; | 679 | dma_cookie_t completed_cookie; |
680 | struct tasklet_struct tasklet; | 680 | struct tasklet_struct tasklet; |
681 | bool active; | ||
681 | }; | 682 | }; |
682 | 683 | ||
683 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | 684 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ |
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c index 502663f5f7c6..91245f5dbe81 100644 --- a/drivers/rapidio/devices/tsi721_dma.c +++ b/drivers/rapidio/devices/tsi721_dma.c | |||
@@ -206,8 +206,8 @@ void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan) | |||
206 | { | 206 | { |
207 | /* Disable BDMA channel interrupts */ | 207 | /* Disable BDMA channel interrupts */ |
208 | iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); | 208 | iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); |
209 | 209 | if (bdma_chan->active) | |
210 | tasklet_schedule(&bdma_chan->tasklet); | 210 | tasklet_schedule(&bdma_chan->tasklet); |
211 | } | 211 | } |
212 | 212 | ||
213 | #ifdef CONFIG_PCI_MSI | 213 | #ifdef CONFIG_PCI_MSI |
@@ -562,7 +562,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan) | |||
562 | } | 562 | } |
563 | #endif /* CONFIG_PCI_MSI */ | 563 | #endif /* CONFIG_PCI_MSI */ |
564 | 564 | ||
565 | tasklet_enable(&bdma_chan->tasklet); | 565 | bdma_chan->active = true; |
566 | tsi721_bdma_interrupt_enable(bdma_chan, 1); | 566 | tsi721_bdma_interrupt_enable(bdma_chan, 1); |
567 | 567 | ||
568 | return bdma_chan->bd_num - 1; | 568 | return bdma_chan->bd_num - 1; |
@@ -576,9 +576,7 @@ err_out: | |||
576 | static void tsi721_free_chan_resources(struct dma_chan *dchan) | 576 | static void tsi721_free_chan_resources(struct dma_chan *dchan) |
577 | { | 577 | { |
578 | struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); | 578 | struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); |
579 | #ifdef CONFIG_PCI_MSI | ||
580 | struct tsi721_device *priv = to_tsi721(dchan->device); | 579 | struct tsi721_device *priv = to_tsi721(dchan->device); |
581 | #endif | ||
582 | LIST_HEAD(list); | 580 | LIST_HEAD(list); |
583 | 581 | ||
584 | dev_dbg(dchan->device->dev, "%s: Entry\n", __func__); | 582 | dev_dbg(dchan->device->dev, "%s: Entry\n", __func__); |
@@ -589,14 +587,25 @@ static void tsi721_free_chan_resources(struct dma_chan *dchan) | |||
589 | BUG_ON(!list_empty(&bdma_chan->active_list)); | 587 | BUG_ON(!list_empty(&bdma_chan->active_list)); |
590 | BUG_ON(!list_empty(&bdma_chan->queue)); | 588 | BUG_ON(!list_empty(&bdma_chan->queue)); |
591 | 589 | ||
592 | tasklet_disable(&bdma_chan->tasklet); | 590 | tsi721_bdma_interrupt_enable(bdma_chan, 0); |
591 | bdma_chan->active = false; | ||
592 | |||
593 | #ifdef CONFIG_PCI_MSI | ||
594 | if (priv->flags & TSI721_USING_MSIX) { | ||
595 | synchronize_irq(priv->msix[TSI721_VECT_DMA0_DONE + | ||
596 | bdma_chan->id].vector); | ||
597 | synchronize_irq(priv->msix[TSI721_VECT_DMA0_INT + | ||
598 | bdma_chan->id].vector); | ||
599 | } else | ||
600 | #endif | ||
601 | synchronize_irq(priv->pdev->irq); | ||
602 | |||
603 | tasklet_kill(&bdma_chan->tasklet); | ||
593 | 604 | ||
594 | spin_lock_bh(&bdma_chan->lock); | 605 | spin_lock_bh(&bdma_chan->lock); |
595 | list_splice_init(&bdma_chan->free_list, &list); | 606 | list_splice_init(&bdma_chan->free_list, &list); |
596 | spin_unlock_bh(&bdma_chan->lock); | 607 | spin_unlock_bh(&bdma_chan->lock); |
597 | 608 | ||
598 | tsi721_bdma_interrupt_enable(bdma_chan, 0); | ||
599 | |||
600 | #ifdef CONFIG_PCI_MSI | 609 | #ifdef CONFIG_PCI_MSI |
601 | if (priv->flags & TSI721_USING_MSIX) { | 610 | if (priv->flags & TSI721_USING_MSIX) { |
602 | free_irq(priv->msix[TSI721_VECT_DMA0_DONE + | 611 | free_irq(priv->msix[TSI721_VECT_DMA0_DONE + |
@@ -790,6 +799,7 @@ int tsi721_register_dma(struct tsi721_device *priv) | |||
790 | bdma_chan->dchan.cookie = 1; | 799 | bdma_chan->dchan.cookie = 1; |
791 | bdma_chan->dchan.chan_id = i; | 800 | bdma_chan->dchan.chan_id = i; |
792 | bdma_chan->id = i; | 801 | bdma_chan->id = i; |
802 | bdma_chan->active = false; | ||
793 | 803 | ||
794 | spin_lock_init(&bdma_chan->lock); | 804 | spin_lock_init(&bdma_chan->lock); |
795 | 805 | ||
@@ -799,7 +809,6 @@ int tsi721_register_dma(struct tsi721_device *priv) | |||
799 | 809 | ||
800 | tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet, | 810 | tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet, |
801 | (unsigned long)bdma_chan); | 811 | (unsigned long)bdma_chan); |
802 | tasklet_disable(&bdma_chan->tasklet); | ||
803 | list_add_tail(&bdma_chan->dchan.device_node, | 812 | list_add_tail(&bdma_chan->dchan.device_node, |
804 | &mport->dma.channels); | 813 | &mport->dma.channels); |
805 | } | 814 | } |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 77b46d0b37a6..e10febe9ec34 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -498,7 +498,7 @@ static int ab3100_regulator_register(struct platform_device *pdev, | |||
498 | struct ab3100_platform_data *plfdata, | 498 | struct ab3100_platform_data *plfdata, |
499 | struct regulator_init_data *init_data, | 499 | struct regulator_init_data *init_data, |
500 | struct device_node *np, | 500 | struct device_node *np, |
501 | int id) | 501 | unsigned long id) |
502 | { | 502 | { |
503 | struct regulator_desc *desc; | 503 | struct regulator_desc *desc; |
504 | struct ab3100_regulator *reg; | 504 | struct ab3100_regulator *reg; |
@@ -646,7 +646,7 @@ ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np) | |||
646 | err = ab3100_regulator_register( | 646 | err = ab3100_regulator_register( |
647 | pdev, NULL, ab3100_regulator_matches[i].init_data, | 647 | pdev, NULL, ab3100_regulator_matches[i].init_data, |
648 | ab3100_regulator_matches[i].of_node, | 648 | ab3100_regulator_matches[i].of_node, |
649 | (int) ab3100_regulator_matches[i].driver_data); | 649 | (unsigned long)ab3100_regulator_matches[i].driver_data); |
650 | if (err) { | 650 | if (err) { |
651 | ab3100_regulators_remove(pdev); | 651 | ab3100_regulators_remove(pdev); |
652 | return err; | 652 | return err; |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b38a6b669e8c..afca1bc24f26 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -953,6 +953,8 @@ static int machine_constraints_current(struct regulator_dev *rdev, | |||
953 | return 0; | 953 | return 0; |
954 | } | 954 | } |
955 | 955 | ||
956 | static int _regulator_do_enable(struct regulator_dev *rdev); | ||
957 | |||
956 | /** | 958 | /** |
957 | * set_machine_constraints - sets regulator constraints | 959 | * set_machine_constraints - sets regulator constraints |
958 | * @rdev: regulator source | 960 | * @rdev: regulator source |
@@ -1013,10 +1015,9 @@ static int set_machine_constraints(struct regulator_dev *rdev, | |||
1013 | /* If the constraints say the regulator should be on at this point | 1015 | /* If the constraints say the regulator should be on at this point |
1014 | * and we have control then make sure it is enabled. | 1016 | * and we have control then make sure it is enabled. |
1015 | */ | 1017 | */ |
1016 | if ((rdev->constraints->always_on || rdev->constraints->boot_on) && | 1018 | if (rdev->constraints->always_on || rdev->constraints->boot_on) { |
1017 | ops->enable) { | 1019 | ret = _regulator_do_enable(rdev); |
1018 | ret = ops->enable(rdev); | 1020 | if (ret < 0 && ret != -EINVAL) { |
1019 | if (ret < 0) { | ||
1020 | rdev_err(rdev, "failed to enable\n"); | 1021 | rdev_err(rdev, "failed to enable\n"); |
1021 | goto out; | 1022 | goto out; |
1022 | } | 1023 | } |
@@ -1272,6 +1273,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, | |||
1272 | if (r->dev.parent && | 1273 | if (r->dev.parent && |
1273 | node == r->dev.of_node) | 1274 | node == r->dev.of_node) |
1274 | return r; | 1275 | return r; |
1276 | *ret = -EPROBE_DEFER; | ||
1277 | return NULL; | ||
1275 | } else { | 1278 | } else { |
1276 | /* | 1279 | /* |
1277 | * If we couldn't even get the node then it's | 1280 | * If we couldn't even get the node then it's |
@@ -1312,7 +1315,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1312 | struct regulator_dev *rdev; | 1315 | struct regulator_dev *rdev; |
1313 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); | 1316 | struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); |
1314 | const char *devname = NULL; | 1317 | const char *devname = NULL; |
1315 | int ret = -EPROBE_DEFER; | 1318 | int ret; |
1316 | 1319 | ||
1317 | if (id == NULL) { | 1320 | if (id == NULL) { |
1318 | pr_err("get() with no identifier\n"); | 1321 | pr_err("get() with no identifier\n"); |
@@ -1322,6 +1325,11 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1322 | if (dev) | 1325 | if (dev) |
1323 | devname = dev_name(dev); | 1326 | devname = dev_name(dev); |
1324 | 1327 | ||
1328 | if (have_full_constraints()) | ||
1329 | ret = -ENODEV; | ||
1330 | else | ||
1331 | ret = -EPROBE_DEFER; | ||
1332 | |||
1325 | mutex_lock(®ulator_list_mutex); | 1333 | mutex_lock(®ulator_list_mutex); |
1326 | 1334 | ||
1327 | rdev = regulator_dev_lookup(dev, id, &ret); | 1335 | rdev = regulator_dev_lookup(dev, id, &ret); |
@@ -1352,7 +1360,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, | |||
1352 | goto found; | 1360 | goto found; |
1353 | /* Don't log an error when called from regulator_get_optional() */ | 1361 | /* Don't log an error when called from regulator_get_optional() */ |
1354 | } else if (!have_full_constraints() || exclusive) { | 1362 | } else if (!have_full_constraints() || exclusive) { |
1355 | dev_err(dev, "dummy supplies not allowed\n"); | 1363 | dev_warn(dev, "dummy supplies not allowed\n"); |
1356 | } | 1364 | } |
1357 | 1365 | ||
1358 | mutex_unlock(®ulator_list_mutex); | 1366 | mutex_unlock(®ulator_list_mutex); |
@@ -1900,8 +1908,6 @@ static int _regulator_do_disable(struct regulator_dev *rdev) | |||
1900 | 1908 | ||
1901 | trace_regulator_disable_complete(rdev_get_name(rdev)); | 1909 | trace_regulator_disable_complete(rdev_get_name(rdev)); |
1902 | 1910 | ||
1903 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | ||
1904 | NULL); | ||
1905 | return 0; | 1911 | return 0; |
1906 | } | 1912 | } |
1907 | 1913 | ||
@@ -1925,6 +1931,8 @@ static int _regulator_disable(struct regulator_dev *rdev) | |||
1925 | rdev_err(rdev, "failed to disable\n"); | 1931 | rdev_err(rdev, "failed to disable\n"); |
1926 | return ret; | 1932 | return ret; |
1927 | } | 1933 | } |
1934 | _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, | ||
1935 | NULL); | ||
1928 | } | 1936 | } |
1929 | 1937 | ||
1930 | rdev->use_count = 0; | 1938 | rdev->use_count = 0; |
@@ -1977,20 +1985,16 @@ static int _regulator_force_disable(struct regulator_dev *rdev) | |||
1977 | { | 1985 | { |
1978 | int ret = 0; | 1986 | int ret = 0; |
1979 | 1987 | ||
1980 | /* force disable */ | 1988 | ret = _regulator_do_disable(rdev); |
1981 | if (rdev->desc->ops->disable) { | 1989 | if (ret < 0) { |
1982 | /* ah well, who wants to live forever... */ | 1990 | rdev_err(rdev, "failed to force disable\n"); |
1983 | ret = rdev->desc->ops->disable(rdev); | 1991 | return ret; |
1984 | if (ret < 0) { | ||
1985 | rdev_err(rdev, "failed to force disable\n"); | ||
1986 | return ret; | ||
1987 | } | ||
1988 | /* notify other consumers that power has been forced off */ | ||
1989 | _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | | ||
1990 | REGULATOR_EVENT_DISABLE, NULL); | ||
1991 | } | 1992 | } |
1992 | 1993 | ||
1993 | return ret; | 1994 | _notifier_call_chain(rdev, REGULATOR_EVENT_FORCE_DISABLE | |
1995 | REGULATOR_EVENT_DISABLE, NULL); | ||
1996 | |||
1997 | return 0; | ||
1994 | } | 1998 | } |
1995 | 1999 | ||
1996 | /** | 2000 | /** |
@@ -3623,23 +3627,18 @@ int regulator_suspend_finish(void) | |||
3623 | 3627 | ||
3624 | mutex_lock(®ulator_list_mutex); | 3628 | mutex_lock(®ulator_list_mutex); |
3625 | list_for_each_entry(rdev, ®ulator_list, list) { | 3629 | list_for_each_entry(rdev, ®ulator_list, list) { |
3626 | struct regulator_ops *ops = rdev->desc->ops; | ||
3627 | |||
3628 | mutex_lock(&rdev->mutex); | 3630 | mutex_lock(&rdev->mutex); |
3629 | if ((rdev->use_count > 0 || rdev->constraints->always_on) && | 3631 | if (rdev->use_count > 0 || rdev->constraints->always_on) { |
3630 | ops->enable) { | 3632 | error = _regulator_do_enable(rdev); |
3631 | error = ops->enable(rdev); | ||
3632 | if (error) | 3633 | if (error) |
3633 | ret = error; | 3634 | ret = error; |
3634 | } else { | 3635 | } else { |
3635 | if (!have_full_constraints()) | 3636 | if (!have_full_constraints()) |
3636 | goto unlock; | 3637 | goto unlock; |
3637 | if (!ops->disable) | ||
3638 | goto unlock; | ||
3639 | if (!_regulator_is_enabled(rdev)) | 3638 | if (!_regulator_is_enabled(rdev)) |
3640 | goto unlock; | 3639 | goto unlock; |
3641 | 3640 | ||
3642 | error = ops->disable(rdev); | 3641 | error = _regulator_do_disable(rdev); |
3643 | if (error) | 3642 | if (error) |
3644 | ret = error; | 3643 | ret = error; |
3645 | } | 3644 | } |
@@ -3813,7 +3812,7 @@ static int __init regulator_init_complete(void) | |||
3813 | ops = rdev->desc->ops; | 3812 | ops = rdev->desc->ops; |
3814 | c = rdev->constraints; | 3813 | c = rdev->constraints; |
3815 | 3814 | ||
3816 | if (!ops->disable || (c && c->always_on)) | 3815 | if (c && c->always_on) |
3817 | continue; | 3816 | continue; |
3818 | 3817 | ||
3819 | mutex_lock(&rdev->mutex); | 3818 | mutex_lock(&rdev->mutex); |
@@ -3834,7 +3833,7 @@ static int __init regulator_init_complete(void) | |||
3834 | /* We log since this may kill the system if it | 3833 | /* We log since this may kill the system if it |
3835 | * goes wrong. */ | 3834 | * goes wrong. */ |
3836 | rdev_info(rdev, "disabling\n"); | 3835 | rdev_info(rdev, "disabling\n"); |
3837 | ret = ops->disable(rdev); | 3836 | ret = _regulator_do_disable(rdev); |
3838 | if (ret != 0) | 3837 | if (ret != 0) |
3839 | rdev_err(rdev, "couldn't disable: %d\n", ret); | 3838 | rdev_err(rdev, "couldn't disable: %d\n", ret); |
3840 | } else { | 3839 | } else { |
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 7f340206d329..b14ebdad5dd2 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c | |||
@@ -576,7 +576,9 @@ static int da9055_regulator_probe(struct platform_device *pdev) | |||
576 | /* Only LDO 5 and 6 has got the over current interrupt */ | 576 | /* Only LDO 5 and 6 has got the over current interrupt */ |
577 | if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { | 577 | if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) { |
578 | irq = platform_get_irq_byname(pdev, "REGULATOR"); | 578 | irq = platform_get_irq_byname(pdev, "REGULATOR"); |
579 | irq = regmap_irq_get_virq(da9055->irq_data, irq); | 579 | if (irq < 0) |
580 | return irq; | ||
581 | |||
580 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 582 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
581 | da9055_ldo5_6_oc_irq, | 583 | da9055_ldo5_6_oc_irq, |
582 | IRQF_TRIGGER_HIGH | | 584 | IRQF_TRIGGER_HIGH | |
diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 56727eb745df..91e99a2c8dc1 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * Regulator driver for DA9063 PMIC series | 3 | * Regulator driver for DA9063 PMIC series |
3 | * | 4 | * |
@@ -60,7 +61,8 @@ struct da9063_regulator_info { | |||
60 | .desc.ops = &da9063_ldo_ops, \ | 61 | .desc.ops = &da9063_ldo_ops, \ |
61 | .desc.min_uV = (min_mV) * 1000, \ | 62 | .desc.min_uV = (min_mV) * 1000, \ |
62 | .desc.uV_step = (step_mV) * 1000, \ | 63 | .desc.uV_step = (step_mV) * 1000, \ |
63 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1), \ | 64 | .desc.n_voltages = (((max_mV) - (min_mV))/(step_mV) + 1 \ |
65 | + (DA9063_V##regl_name##_BIAS)), \ | ||
64 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ | 66 | .desc.enable_reg = DA9063_REG_##regl_name##_CONT, \ |
65 | .desc.enable_mask = DA9063_LDO_EN, \ | 67 | .desc.enable_mask = DA9063_LDO_EN, \ |
66 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ | 68 | .desc.vsel_reg = DA9063_REG_V##regl_name##_A, \ |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index b1078ba3f393..e0619526708c 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
@@ -166,12 +166,14 @@ static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev) | |||
166 | 166 | ||
167 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, | 167 | ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches, |
168 | MAX14577_REG_MAX); | 168 | MAX14577_REG_MAX); |
169 | if (ret < 0) { | 169 | if (ret < 0) |
170 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); | 170 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); |
171 | return ret; | 171 | else |
172 | } | 172 | ret = 0; |
173 | 173 | ||
174 | return 0; | 174 | of_node_put(np); |
175 | |||
176 | return ret; | ||
175 | } | 177 | } |
176 | 178 | ||
177 | static inline struct regulator_init_data *match_init_data(int index) | 179 | static inline struct regulator_init_data *match_init_data(int index) |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index d9e557990577..cd0b9e35a56d 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -441,6 +441,7 @@ common_reg: | |||
441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { | 441 | for (i = 0; i < S2MPS11_REGULATOR_MAX; i++) { |
442 | if (!reg_np) { | 442 | if (!reg_np) { |
443 | config.init_data = pdata->regulators[i].initdata; | 443 | config.init_data = pdata->regulators[i].initdata; |
444 | config.of_node = pdata->regulators[i].reg_node; | ||
444 | } else { | 445 | } else { |
445 | config.init_data = rdata[i].init_data; | 446 | config.init_data = rdata[i].init_data; |
446 | config.of_node = rdata[i].of_node; | 447 | config.of_node = rdata[i].of_node; |
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index d7164bb75d3e..d958dfa05125 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c | |||
@@ -535,7 +535,7 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
535 | return -ENODEV; | 535 | return -ENODEV; |
536 | } | 536 | } |
537 | 537 | ||
538 | regulators_np = of_find_node_by_name(pmic_np, "regulators"); | 538 | regulators_np = of_get_child_by_name(pmic_np, "regulators"); |
539 | if (!regulators_np) { | 539 | if (!regulators_np) { |
540 | dev_err(iodev->dev, "could not find regulators sub-node\n"); | 540 | dev_err(iodev->dev, "could not find regulators sub-node\n"); |
541 | return -EINVAL; | 541 | return -EINVAL; |
@@ -591,6 +591,8 @@ static int s5m8767_pmic_dt_parse_pdata(struct platform_device *pdev, | |||
591 | rmode++; | 591 | rmode++; |
592 | } | 592 | } |
593 | 593 | ||
594 | of_node_put(regulators_np); | ||
595 | |||
594 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { | 596 | if (of_get_property(pmic_np, "s5m8767,pmic-buck2-uses-gpio-dvs", NULL)) { |
595 | pdata->buck2_gpiodvs = true; | 597 | pdata->buck2_gpiodvs = true; |
596 | 598 | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 7afd373b9595..c4cde9c08f1f 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -580,10 +580,12 @@ static int s3c_rtc_suspend(struct device *dev) | |||
580 | 580 | ||
581 | clk_enable(rtc_clk); | 581 | clk_enable(rtc_clk); |
582 | /* save TICNT for anyone using periodic interrupts */ | 582 | /* save TICNT for anyone using periodic interrupts */ |
583 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | ||
584 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { | 583 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
585 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); | 584 | ticnt_en_save = readw(s3c_rtc_base + S3C2410_RTCCON); |
586 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; | 585 | ticnt_en_save &= S3C64XX_RTCCON_TICEN; |
586 | ticnt_save = readl(s3c_rtc_base + S3C2410_TICNT); | ||
587 | } else { | ||
588 | ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); | ||
587 | } | 589 | } |
588 | s3c_rtc_enable(pdev, 0); | 590 | s3c_rtc_enable(pdev, 0); |
589 | 591 | ||
@@ -605,10 +607,15 @@ static int s3c_rtc_resume(struct device *dev) | |||
605 | 607 | ||
606 | clk_enable(rtc_clk); | 608 | clk_enable(rtc_clk); |
607 | s3c_rtc_enable(pdev, 1); | 609 | s3c_rtc_enable(pdev, 1); |
608 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | 610 | if (s3c_rtc_cpu_type == TYPE_S3C64XX) { |
609 | if (s3c_rtc_cpu_type == TYPE_S3C64XX && ticnt_en_save) { | 611 | writel(ticnt_save, s3c_rtc_base + S3C2410_TICNT); |
610 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); | 612 | if (ticnt_en_save) { |
611 | writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); | 613 | tmp = readw(s3c_rtc_base + S3C2410_RTCCON); |
614 | writew(tmp | ticnt_en_save, | ||
615 | s3c_rtc_base + S3C2410_RTCCON); | ||
616 | } | ||
617 | } else { | ||
618 | writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); | ||
612 | } | 619 | } |
613 | 620 | ||
614 | if (device_may_wakeup(dev) && wake_en) { | 621 | if (device_may_wakeup(dev) && wake_en) { |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index f6b9188c5af5..9f0ea6cb6922 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -610,6 +610,7 @@ void chsc_chp_online(struct chp_id chpid) | |||
610 | css_wait_for_slow_path(); | 610 | css_wait_for_slow_path(); |
611 | for_each_subchannel_staged(__s390_process_res_acc, NULL, | 611 | for_each_subchannel_staged(__s390_process_res_acc, NULL, |
612 | &link); | 612 | &link); |
613 | css_schedule_reprobe(); | ||
613 | } | 614 | } |
614 | } | 615 | } |
615 | 616 | ||
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 88e35d85d205..8ee88c4ebd83 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -342,8 +342,9 @@ static int cio_check_config(struct subchannel *sch, struct schib *schib) | |||
342 | */ | 342 | */ |
343 | int cio_commit_config(struct subchannel *sch) | 343 | int cio_commit_config(struct subchannel *sch) |
344 | { | 344 | { |
345 | struct schib schib; | ||
346 | int ccode, retry, ret = 0; | 345 | int ccode, retry, ret = 0; |
346 | struct schib schib; | ||
347 | struct irb irb; | ||
347 | 348 | ||
348 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 349 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
349 | return -ENODEV; | 350 | return -ENODEV; |
@@ -367,7 +368,10 @@ int cio_commit_config(struct subchannel *sch) | |||
367 | ret = -EAGAIN; | 368 | ret = -EAGAIN; |
368 | break; | 369 | break; |
369 | case 1: /* status pending */ | 370 | case 1: /* status pending */ |
370 | return -EBUSY; | 371 | ret = -EBUSY; |
372 | if (tsch(sch->schid, &irb)) | ||
373 | return ret; | ||
374 | break; | ||
371 | case 2: /* busy */ | 375 | case 2: /* busy */ |
372 | udelay(100); /* allow for recovery */ | 376 | udelay(100); /* allow for recovery */ |
373 | ret = -EBUSY; | 377 | ret = -EBUSY; |
@@ -403,7 +407,6 @@ EXPORT_SYMBOL_GPL(cio_update_schib); | |||
403 | */ | 407 | */ |
404 | int cio_enable_subchannel(struct subchannel *sch, u32 intparm) | 408 | int cio_enable_subchannel(struct subchannel *sch, u32 intparm) |
405 | { | 409 | { |
406 | int retry; | ||
407 | int ret; | 410 | int ret; |
408 | 411 | ||
409 | CIO_TRACE_EVENT(2, "ensch"); | 412 | CIO_TRACE_EVENT(2, "ensch"); |
@@ -418,20 +421,14 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) | |||
418 | sch->config.isc = sch->isc; | 421 | sch->config.isc = sch->isc; |
419 | sch->config.intparm = intparm; | 422 | sch->config.intparm = intparm; |
420 | 423 | ||
421 | for (retry = 0; retry < 3; retry++) { | 424 | ret = cio_commit_config(sch); |
425 | if (ret == -EIO) { | ||
426 | /* | ||
427 | * Got a program check in msch. Try without | ||
428 | * the concurrent sense bit the next time. | ||
429 | */ | ||
430 | sch->config.csense = 0; | ||
422 | ret = cio_commit_config(sch); | 431 | ret = cio_commit_config(sch); |
423 | if (ret == -EIO) { | ||
424 | /* | ||
425 | * Got a program check in msch. Try without | ||
426 | * the concurrent sense bit the next time. | ||
427 | */ | ||
428 | sch->config.csense = 0; | ||
429 | } else if (ret == -EBUSY) { | ||
430 | struct irb irb; | ||
431 | if (tsch(sch->schid, &irb) != 0) | ||
432 | break; | ||
433 | } else | ||
434 | break; | ||
435 | } | 432 | } |
436 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); | 433 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); |
437 | return ret; | 434 | return ret; |
@@ -444,7 +441,6 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel); | |||
444 | */ | 441 | */ |
445 | int cio_disable_subchannel(struct subchannel *sch) | 442 | int cio_disable_subchannel(struct subchannel *sch) |
446 | { | 443 | { |
447 | int retry; | ||
448 | int ret; | 444 | int ret; |
449 | 445 | ||
450 | CIO_TRACE_EVENT(2, "dissch"); | 446 | CIO_TRACE_EVENT(2, "dissch"); |
@@ -456,16 +452,8 @@ int cio_disable_subchannel(struct subchannel *sch) | |||
456 | return -ENODEV; | 452 | return -ENODEV; |
457 | 453 | ||
458 | sch->config.ena = 0; | 454 | sch->config.ena = 0; |
455 | ret = cio_commit_config(sch); | ||
459 | 456 | ||
460 | for (retry = 0; retry < 3; retry++) { | ||
461 | ret = cio_commit_config(sch); | ||
462 | if (ret == -EBUSY) { | ||
463 | struct irb irb; | ||
464 | if (tsch(sch->schid, &irb) != 0) | ||
465 | break; | ||
466 | } else | ||
467 | break; | ||
468 | } | ||
469 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); | 457 | CIO_HEX_EVENT(2, &ret, sizeof(ret)); |
470 | return ret; | 458 | return ret; |
471 | } | 459 | } |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 8acaae18bd11..a563e4c00590 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -359,14 +359,12 @@ static inline int multicast_outbound(struct qdio_q *q) | |||
359 | #define need_siga_sync_out_after_pci(q) \ | 359 | #define need_siga_sync_out_after_pci(q) \ |
360 | (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) | 360 | (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) |
361 | 361 | ||
362 | #define for_each_input_queue(irq_ptr, q, i) \ | 362 | #define for_each_input_queue(irq_ptr, q, i) \ |
363 | for (i = 0, q = irq_ptr->input_qs[0]; \ | 363 | for (i = 0; i < irq_ptr->nr_input_qs && \ |
364 | i < irq_ptr->nr_input_qs; \ | 364 | ({ q = irq_ptr->input_qs[i]; 1; }); i++) |
365 | q = irq_ptr->input_qs[++i]) | 365 | #define for_each_output_queue(irq_ptr, q, i) \ |
366 | #define for_each_output_queue(irq_ptr, q, i) \ | 366 | for (i = 0; i < irq_ptr->nr_output_qs && \ |
367 | for (i = 0, q = irq_ptr->output_qs[0]; \ | 367 | ({ q = irq_ptr->output_qs[i]; 1; }); i++) |
368 | i < irq_ptr->nr_output_qs; \ | ||
369 | q = irq_ptr->output_qs[++i]) | ||
370 | 368 | ||
371 | #define prev_buf(bufnr) \ | 369 | #define prev_buf(bufnr) \ |
372 | ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) | 370 | ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index c883a085c059..77466c4faabb 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -996,7 +996,7 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) | |||
996 | } | 996 | } |
997 | } | 997 | } |
998 | 998 | ||
999 | if (!pci_out_supported(q)) | 999 | if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) |
1000 | return; | 1000 | return; |
1001 | 1001 | ||
1002 | for_each_output_queue(irq_ptr, q, i) { | 1002 | for_each_output_queue(irq_ptr, q, i) { |
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index dc542e0a3055..0bc91e46395a 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c | |||
@@ -311,7 +311,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
311 | } __packed * msg = ap_msg->message; | 311 | } __packed * msg = ap_msg->message; |
312 | 312 | ||
313 | int rcblen = CEIL4(xcRB->request_control_blk_length); | 313 | int rcblen = CEIL4(xcRB->request_control_blk_length); |
314 | int replylen; | 314 | int replylen, req_sumlen, resp_sumlen; |
315 | char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; | 315 | char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; |
316 | char *function_code; | 316 | char *function_code; |
317 | 317 | ||
@@ -321,12 +321,34 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
321 | xcRB->request_data_length; | 321 | xcRB->request_data_length; |
322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) | 322 | if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) |
323 | return -EINVAL; | 323 | return -EINVAL; |
324 | |||
325 | /* Overflow check | ||
326 | sum must be greater (or equal) than the largest operand */ | ||
327 | req_sumlen = CEIL4(xcRB->request_control_blk_length) + | ||
328 | xcRB->request_data_length; | ||
329 | if ((CEIL4(xcRB->request_control_blk_length) <= | ||
330 | xcRB->request_data_length) ? | ||
331 | (req_sumlen < xcRB->request_data_length) : | ||
332 | (req_sumlen < CEIL4(xcRB->request_control_blk_length))) { | ||
333 | return -EINVAL; | ||
334 | } | ||
335 | |||
324 | replylen = sizeof(struct type86_fmt2_msg) + | 336 | replylen = sizeof(struct type86_fmt2_msg) + |
325 | CEIL4(xcRB->reply_control_blk_length) + | 337 | CEIL4(xcRB->reply_control_blk_length) + |
326 | xcRB->reply_data_length; | 338 | xcRB->reply_data_length; |
327 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) | 339 | if (replylen > MSGTYPE06_MAX_MSG_SIZE) |
328 | return -EINVAL; | 340 | return -EINVAL; |
329 | 341 | ||
342 | /* Overflow check | ||
343 | sum must be greater (or equal) than the largest operand */ | ||
344 | resp_sumlen = CEIL4(xcRB->reply_control_blk_length) + | ||
345 | xcRB->reply_data_length; | ||
346 | if ((CEIL4(xcRB->reply_control_blk_length) <= xcRB->reply_data_length) ? | ||
347 | (resp_sumlen < xcRB->reply_data_length) : | ||
348 | (resp_sumlen < CEIL4(xcRB->reply_control_blk_length))) { | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
330 | /* prepare type6 header */ | 352 | /* prepare type6 header */ |
331 | msg->hdr = static_type6_hdrX; | 353 | msg->hdr = static_type6_hdrX; |
332 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); | 354 | memcpy(msg->hdr.agent_id , &(xcRB->agent_ID), sizeof(xcRB->agent_ID)); |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c3a83df07894..795ed61a5496 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1660,7 +1660,6 @@ int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) | |||
1660 | QDIO_FLAG_CLEANUP_USING_CLEAR); | 1660 | QDIO_FLAG_CLEANUP_USING_CLEAR); |
1661 | if (rc) | 1661 | if (rc) |
1662 | QETH_CARD_TEXT_(card, 3, "1err%d", rc); | 1662 | QETH_CARD_TEXT_(card, 3, "1err%d", rc); |
1663 | qdio_free(CARD_DDEV(card)); | ||
1664 | atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); | 1663 | atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); |
1665 | break; | 1664 | break; |
1666 | case QETH_QDIO_CLEANING: | 1665 | case QETH_QDIO_CLEANING: |
@@ -2605,6 +2604,7 @@ static int qeth_mpc_initialize(struct qeth_card *card) | |||
2605 | return 0; | 2604 | return 0; |
2606 | out_qdio: | 2605 | out_qdio: |
2607 | qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD); | 2606 | qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD); |
2607 | qdio_free(CARD_DDEV(card)); | ||
2608 | return rc; | 2608 | return rc; |
2609 | } | 2609 | } |
2610 | 2610 | ||
@@ -4906,9 +4906,11 @@ retry: | |||
4906 | if (retries < 3) | 4906 | if (retries < 3) |
4907 | QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", | 4907 | QETH_DBF_MESSAGE(2, "%s Retrying to do IDX activates.\n", |
4908 | dev_name(&card->gdev->dev)); | 4908 | dev_name(&card->gdev->dev)); |
4909 | rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD); | ||
4909 | ccw_device_set_offline(CARD_DDEV(card)); | 4910 | ccw_device_set_offline(CARD_DDEV(card)); |
4910 | ccw_device_set_offline(CARD_WDEV(card)); | 4911 | ccw_device_set_offline(CARD_WDEV(card)); |
4911 | ccw_device_set_offline(CARD_RDEV(card)); | 4912 | ccw_device_set_offline(CARD_RDEV(card)); |
4913 | qdio_free(CARD_DDEV(card)); | ||
4912 | rc = ccw_device_set_online(CARD_RDEV(card)); | 4914 | rc = ccw_device_set_online(CARD_RDEV(card)); |
4913 | if (rc) | 4915 | if (rc) |
4914 | goto retriable; | 4916 | goto retriable; |
@@ -4918,7 +4920,6 @@ retry: | |||
4918 | rc = ccw_device_set_online(CARD_DDEV(card)); | 4920 | rc = ccw_device_set_online(CARD_DDEV(card)); |
4919 | if (rc) | 4921 | if (rc) |
4920 | goto retriable; | 4922 | goto retriable; |
4921 | rc = qeth_qdio_clear_card(card, card->info.type != QETH_CARD_TYPE_IQD); | ||
4922 | retriable: | 4923 | retriable: |
4923 | if (rc == -ERESTARTSYS) { | 4924 | if (rc == -ERESTARTSYS) { |
4924 | QETH_DBF_TEXT(SETUP, 2, "break1"); | 4925 | QETH_DBF_TEXT(SETUP, 2, "break1"); |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 0710550093ce..908d82529ee9 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -1091,6 +1091,7 @@ out_remove: | |||
1091 | ccw_device_set_offline(CARD_DDEV(card)); | 1091 | ccw_device_set_offline(CARD_DDEV(card)); |
1092 | ccw_device_set_offline(CARD_WDEV(card)); | 1092 | ccw_device_set_offline(CARD_WDEV(card)); |
1093 | ccw_device_set_offline(CARD_RDEV(card)); | 1093 | ccw_device_set_offline(CARD_RDEV(card)); |
1094 | qdio_free(CARD_DDEV(card)); | ||
1094 | if (recover_flag == CARD_STATE_RECOVER) | 1095 | if (recover_flag == CARD_STATE_RECOVER) |
1095 | card->state = CARD_STATE_RECOVER; | 1096 | card->state = CARD_STATE_RECOVER; |
1096 | else | 1097 | else |
@@ -1132,6 +1133,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1132 | rc = (rc2) ? rc2 : rc3; | 1133 | rc = (rc2) ? rc2 : rc3; |
1133 | if (rc) | 1134 | if (rc) |
1134 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 1135 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); |
1136 | qdio_free(CARD_DDEV(card)); | ||
1135 | if (recover_flag == CARD_STATE_UP) | 1137 | if (recover_flag == CARD_STATE_UP) |
1136 | card->state = CARD_STATE_RECOVER; | 1138 | card->state = CARD_STATE_RECOVER; |
1137 | /* let user_space know that device is offline */ | 1139 | /* let user_space know that device is offline */ |
@@ -1194,6 +1196,7 @@ static void qeth_l2_shutdown(struct ccwgroup_device *gdev) | |||
1194 | qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); | 1196 | qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); |
1195 | qeth_qdio_clear_card(card, 0); | 1197 | qeth_qdio_clear_card(card, 0); |
1196 | qeth_clear_qdio_buffers(card); | 1198 | qeth_clear_qdio_buffers(card); |
1199 | qdio_free(CARD_DDEV(card)); | ||
1197 | } | 1200 | } |
1198 | 1201 | ||
1199 | static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) | 1202 | static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 0f430424c3b8..3524d34ff694 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -3447,6 +3447,7 @@ out_remove: | |||
3447 | ccw_device_set_offline(CARD_DDEV(card)); | 3447 | ccw_device_set_offline(CARD_DDEV(card)); |
3448 | ccw_device_set_offline(CARD_WDEV(card)); | 3448 | ccw_device_set_offline(CARD_WDEV(card)); |
3449 | ccw_device_set_offline(CARD_RDEV(card)); | 3449 | ccw_device_set_offline(CARD_RDEV(card)); |
3450 | qdio_free(CARD_DDEV(card)); | ||
3450 | if (recover_flag == CARD_STATE_RECOVER) | 3451 | if (recover_flag == CARD_STATE_RECOVER) |
3451 | card->state = CARD_STATE_RECOVER; | 3452 | card->state = CARD_STATE_RECOVER; |
3452 | else | 3453 | else |
@@ -3493,6 +3494,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3493 | rc = (rc2) ? rc2 : rc3; | 3494 | rc = (rc2) ? rc2 : rc3; |
3494 | if (rc) | 3495 | if (rc) |
3495 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 3496 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); |
3497 | qdio_free(CARD_DDEV(card)); | ||
3496 | if (recover_flag == CARD_STATE_UP) | 3498 | if (recover_flag == CARD_STATE_UP) |
3497 | card->state = CARD_STATE_RECOVER; | 3499 | card->state = CARD_STATE_RECOVER; |
3498 | /* let user_space know that device is offline */ | 3500 | /* let user_space know that device is offline */ |
@@ -3545,6 +3547,7 @@ static void qeth_l3_shutdown(struct ccwgroup_device *gdev) | |||
3545 | qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); | 3547 | qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); |
3546 | qeth_qdio_clear_card(card, 0); | 3548 | qeth_qdio_clear_card(card, 0); |
3547 | qeth_clear_qdio_buffers(card); | 3549 | qeth_clear_qdio_buffers(card); |
3550 | qdio_free(CARD_DDEV(card)); | ||
3548 | } | 3551 | } |
3549 | 3552 | ||
3550 | static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) | 3553 | static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) |
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index 6b4678a7900a..4ccb5d869389 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c | |||
@@ -507,7 +507,6 @@ static int jsflash_init(void) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | /* Let us be really paranoid for modifications to probing code. */ | 509 | /* Let us be really paranoid for modifications to probing code. */ |
510 | /* extern enum sparc_cpu sparc_cpu_model; */ /* in <asm/system.h> */ | ||
511 | if (sparc_cpu_model != sun4m) { | 510 | if (sparc_cpu_model != sun4m) { |
512 | /* We must be on sun4m because we use MMU Bypass ASI. */ | 511 | /* We must be on sun4m because we use MMU Bypass ASI. */ |
513 | return -ENXIO; | 512 | return -ENXIO; |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 1f375051483a..5642a9b250c2 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -325,7 +325,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
325 | if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) | 325 | if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE) |
326 | continue; | 326 | continue; |
327 | 327 | ||
328 | if (abrt_task->sc->device->lun != abrt_task->sc->device->lun) | 328 | if (sc->device->lun != abrt_task->sc->device->lun) |
329 | continue; | 329 | continue; |
330 | 330 | ||
331 | /* Invalidate WRB Posted for this Task */ | 331 | /* Invalidate WRB Posted for this Task */ |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index ed880891cb7c..e9279a8c1e1c 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c | |||
@@ -594,13 +594,13 @@ static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req) | |||
594 | mp_req->mp_resp_bd = NULL; | 594 | mp_req->mp_resp_bd = NULL; |
595 | } | 595 | } |
596 | if (mp_req->req_buf) { | 596 | if (mp_req->req_buf) { |
597 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 597 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
598 | mp_req->req_buf, | 598 | mp_req->req_buf, |
599 | mp_req->req_buf_dma); | 599 | mp_req->req_buf_dma); |
600 | mp_req->req_buf = NULL; | 600 | mp_req->req_buf = NULL; |
601 | } | 601 | } |
602 | if (mp_req->resp_buf) { | 602 | if (mp_req->resp_buf) { |
603 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 603 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
604 | mp_req->resp_buf, | 604 | mp_req->resp_buf, |
605 | mp_req->resp_buf_dma); | 605 | mp_req->resp_buf_dma); |
606 | mp_req->resp_buf = NULL; | 606 | mp_req->resp_buf = NULL; |
@@ -622,7 +622,7 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) | |||
622 | 622 | ||
623 | mp_req->req_len = sizeof(struct fcp_cmnd); | 623 | mp_req->req_len = sizeof(struct fcp_cmnd); |
624 | io_req->data_xfer_len = mp_req->req_len; | 624 | io_req->data_xfer_len = mp_req->req_len; |
625 | mp_req->req_buf = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 625 | mp_req->req_buf = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
626 | &mp_req->req_buf_dma, | 626 | &mp_req->req_buf_dma, |
627 | GFP_ATOMIC); | 627 | GFP_ATOMIC); |
628 | if (!mp_req->req_buf) { | 628 | if (!mp_req->req_buf) { |
@@ -631,7 +631,7 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) | |||
631 | return FAILED; | 631 | return FAILED; |
632 | } | 632 | } |
633 | 633 | ||
634 | mp_req->resp_buf = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 634 | mp_req->resp_buf = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
635 | &mp_req->resp_buf_dma, | 635 | &mp_req->resp_buf_dma, |
636 | GFP_ATOMIC); | 636 | GFP_ATOMIC); |
637 | if (!mp_req->resp_buf) { | 637 | if (!mp_req->resp_buf) { |
@@ -639,8 +639,8 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) | |||
639 | bnx2fc_free_mp_resc(io_req); | 639 | bnx2fc_free_mp_resc(io_req); |
640 | return FAILED; | 640 | return FAILED; |
641 | } | 641 | } |
642 | memset(mp_req->req_buf, 0, PAGE_SIZE); | 642 | memset(mp_req->req_buf, 0, CNIC_PAGE_SIZE); |
643 | memset(mp_req->resp_buf, 0, PAGE_SIZE); | 643 | memset(mp_req->resp_buf, 0, CNIC_PAGE_SIZE); |
644 | 644 | ||
645 | /* Allocate and map mp_req_bd and mp_resp_bd */ | 645 | /* Allocate and map mp_req_bd and mp_resp_bd */ |
646 | sz = sizeof(struct fcoe_bd_ctx); | 646 | sz = sizeof(struct fcoe_bd_ctx); |
@@ -665,7 +665,7 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) | |||
665 | mp_req_bd = mp_req->mp_req_bd; | 665 | mp_req_bd = mp_req->mp_req_bd; |
666 | mp_req_bd->buf_addr_lo = (u32)addr & 0xffffffff; | 666 | mp_req_bd->buf_addr_lo = (u32)addr & 0xffffffff; |
667 | mp_req_bd->buf_addr_hi = (u32)((u64)addr >> 32); | 667 | mp_req_bd->buf_addr_hi = (u32)((u64)addr >> 32); |
668 | mp_req_bd->buf_len = PAGE_SIZE; | 668 | mp_req_bd->buf_len = CNIC_PAGE_SIZE; |
669 | mp_req_bd->flags = 0; | 669 | mp_req_bd->flags = 0; |
670 | 670 | ||
671 | /* | 671 | /* |
@@ -677,7 +677,7 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req) | |||
677 | addr = mp_req->resp_buf_dma; | 677 | addr = mp_req->resp_buf_dma; |
678 | mp_resp_bd->buf_addr_lo = (u32)addr & 0xffffffff; | 678 | mp_resp_bd->buf_addr_lo = (u32)addr & 0xffffffff; |
679 | mp_resp_bd->buf_addr_hi = (u32)((u64)addr >> 32); | 679 | mp_resp_bd->buf_addr_hi = (u32)((u64)addr >> 32); |
680 | mp_resp_bd->buf_len = PAGE_SIZE; | 680 | mp_resp_bd->buf_len = CNIC_PAGE_SIZE; |
681 | mp_resp_bd->flags = 0; | 681 | mp_resp_bd->flags = 0; |
682 | 682 | ||
683 | return SUCCESS; | 683 | return SUCCESS; |
diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 4d93177dfb53..d9bae5672273 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c | |||
@@ -673,7 +673,8 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
673 | 673 | ||
674 | /* Allocate and map SQ */ | 674 | /* Allocate and map SQ */ |
675 | tgt->sq_mem_size = tgt->max_sqes * BNX2FC_SQ_WQE_SIZE; | 675 | tgt->sq_mem_size = tgt->max_sqes * BNX2FC_SQ_WQE_SIZE; |
676 | tgt->sq_mem_size = (tgt->sq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 676 | tgt->sq_mem_size = (tgt->sq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
677 | CNIC_PAGE_MASK; | ||
677 | 678 | ||
678 | tgt->sq = dma_alloc_coherent(&hba->pcidev->dev, tgt->sq_mem_size, | 679 | tgt->sq = dma_alloc_coherent(&hba->pcidev->dev, tgt->sq_mem_size, |
679 | &tgt->sq_dma, GFP_KERNEL); | 680 | &tgt->sq_dma, GFP_KERNEL); |
@@ -686,7 +687,8 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
686 | 687 | ||
687 | /* Allocate and map CQ */ | 688 | /* Allocate and map CQ */ |
688 | tgt->cq_mem_size = tgt->max_cqes * BNX2FC_CQ_WQE_SIZE; | 689 | tgt->cq_mem_size = tgt->max_cqes * BNX2FC_CQ_WQE_SIZE; |
689 | tgt->cq_mem_size = (tgt->cq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 690 | tgt->cq_mem_size = (tgt->cq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
691 | CNIC_PAGE_MASK; | ||
690 | 692 | ||
691 | tgt->cq = dma_alloc_coherent(&hba->pcidev->dev, tgt->cq_mem_size, | 693 | tgt->cq = dma_alloc_coherent(&hba->pcidev->dev, tgt->cq_mem_size, |
692 | &tgt->cq_dma, GFP_KERNEL); | 694 | &tgt->cq_dma, GFP_KERNEL); |
@@ -699,7 +701,8 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
699 | 701 | ||
700 | /* Allocate and map RQ and RQ PBL */ | 702 | /* Allocate and map RQ and RQ PBL */ |
701 | tgt->rq_mem_size = tgt->max_rqes * BNX2FC_RQ_WQE_SIZE; | 703 | tgt->rq_mem_size = tgt->max_rqes * BNX2FC_RQ_WQE_SIZE; |
702 | tgt->rq_mem_size = (tgt->rq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 704 | tgt->rq_mem_size = (tgt->rq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
705 | CNIC_PAGE_MASK; | ||
703 | 706 | ||
704 | tgt->rq = dma_alloc_coherent(&hba->pcidev->dev, tgt->rq_mem_size, | 707 | tgt->rq = dma_alloc_coherent(&hba->pcidev->dev, tgt->rq_mem_size, |
705 | &tgt->rq_dma, GFP_KERNEL); | 708 | &tgt->rq_dma, GFP_KERNEL); |
@@ -710,8 +713,9 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
710 | } | 713 | } |
711 | memset(tgt->rq, 0, tgt->rq_mem_size); | 714 | memset(tgt->rq, 0, tgt->rq_mem_size); |
712 | 715 | ||
713 | tgt->rq_pbl_size = (tgt->rq_mem_size / PAGE_SIZE) * sizeof(void *); | 716 | tgt->rq_pbl_size = (tgt->rq_mem_size / CNIC_PAGE_SIZE) * sizeof(void *); |
714 | tgt->rq_pbl_size = (tgt->rq_pbl_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 717 | tgt->rq_pbl_size = (tgt->rq_pbl_size + (CNIC_PAGE_SIZE - 1)) & |
718 | CNIC_PAGE_MASK; | ||
715 | 719 | ||
716 | tgt->rq_pbl = dma_alloc_coherent(&hba->pcidev->dev, tgt->rq_pbl_size, | 720 | tgt->rq_pbl = dma_alloc_coherent(&hba->pcidev->dev, tgt->rq_pbl_size, |
717 | &tgt->rq_pbl_dma, GFP_KERNEL); | 721 | &tgt->rq_pbl_dma, GFP_KERNEL); |
@@ -722,7 +726,7 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
722 | } | 726 | } |
723 | 727 | ||
724 | memset(tgt->rq_pbl, 0, tgt->rq_pbl_size); | 728 | memset(tgt->rq_pbl, 0, tgt->rq_pbl_size); |
725 | num_pages = tgt->rq_mem_size / PAGE_SIZE; | 729 | num_pages = tgt->rq_mem_size / CNIC_PAGE_SIZE; |
726 | page = tgt->rq_dma; | 730 | page = tgt->rq_dma; |
727 | pbl = (u32 *)tgt->rq_pbl; | 731 | pbl = (u32 *)tgt->rq_pbl; |
728 | 732 | ||
@@ -731,13 +735,13 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
731 | pbl++; | 735 | pbl++; |
732 | *pbl = (u32)((u64)page >> 32); | 736 | *pbl = (u32)((u64)page >> 32); |
733 | pbl++; | 737 | pbl++; |
734 | page += PAGE_SIZE; | 738 | page += CNIC_PAGE_SIZE; |
735 | } | 739 | } |
736 | 740 | ||
737 | /* Allocate and map XFERQ */ | 741 | /* Allocate and map XFERQ */ |
738 | tgt->xferq_mem_size = tgt->max_sqes * BNX2FC_XFERQ_WQE_SIZE; | 742 | tgt->xferq_mem_size = tgt->max_sqes * BNX2FC_XFERQ_WQE_SIZE; |
739 | tgt->xferq_mem_size = (tgt->xferq_mem_size + (PAGE_SIZE - 1)) & | 743 | tgt->xferq_mem_size = (tgt->xferq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
740 | PAGE_MASK; | 744 | CNIC_PAGE_MASK; |
741 | 745 | ||
742 | tgt->xferq = dma_alloc_coherent(&hba->pcidev->dev, tgt->xferq_mem_size, | 746 | tgt->xferq = dma_alloc_coherent(&hba->pcidev->dev, tgt->xferq_mem_size, |
743 | &tgt->xferq_dma, GFP_KERNEL); | 747 | &tgt->xferq_dma, GFP_KERNEL); |
@@ -750,8 +754,8 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
750 | 754 | ||
751 | /* Allocate and map CONFQ & CONFQ PBL */ | 755 | /* Allocate and map CONFQ & CONFQ PBL */ |
752 | tgt->confq_mem_size = tgt->max_sqes * BNX2FC_CONFQ_WQE_SIZE; | 756 | tgt->confq_mem_size = tgt->max_sqes * BNX2FC_CONFQ_WQE_SIZE; |
753 | tgt->confq_mem_size = (tgt->confq_mem_size + (PAGE_SIZE - 1)) & | 757 | tgt->confq_mem_size = (tgt->confq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
754 | PAGE_MASK; | 758 | CNIC_PAGE_MASK; |
755 | 759 | ||
756 | tgt->confq = dma_alloc_coherent(&hba->pcidev->dev, tgt->confq_mem_size, | 760 | tgt->confq = dma_alloc_coherent(&hba->pcidev->dev, tgt->confq_mem_size, |
757 | &tgt->confq_dma, GFP_KERNEL); | 761 | &tgt->confq_dma, GFP_KERNEL); |
@@ -763,9 +767,9 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
763 | memset(tgt->confq, 0, tgt->confq_mem_size); | 767 | memset(tgt->confq, 0, tgt->confq_mem_size); |
764 | 768 | ||
765 | tgt->confq_pbl_size = | 769 | tgt->confq_pbl_size = |
766 | (tgt->confq_mem_size / PAGE_SIZE) * sizeof(void *); | 770 | (tgt->confq_mem_size / CNIC_PAGE_SIZE) * sizeof(void *); |
767 | tgt->confq_pbl_size = | 771 | tgt->confq_pbl_size = |
768 | (tgt->confq_pbl_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 772 | (tgt->confq_pbl_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
769 | 773 | ||
770 | tgt->confq_pbl = dma_alloc_coherent(&hba->pcidev->dev, | 774 | tgt->confq_pbl = dma_alloc_coherent(&hba->pcidev->dev, |
771 | tgt->confq_pbl_size, | 775 | tgt->confq_pbl_size, |
@@ -777,7 +781,7 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
777 | } | 781 | } |
778 | 782 | ||
779 | memset(tgt->confq_pbl, 0, tgt->confq_pbl_size); | 783 | memset(tgt->confq_pbl, 0, tgt->confq_pbl_size); |
780 | num_pages = tgt->confq_mem_size / PAGE_SIZE; | 784 | num_pages = tgt->confq_mem_size / CNIC_PAGE_SIZE; |
781 | page = tgt->confq_dma; | 785 | page = tgt->confq_dma; |
782 | pbl = (u32 *)tgt->confq_pbl; | 786 | pbl = (u32 *)tgt->confq_pbl; |
783 | 787 | ||
@@ -786,7 +790,7 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
786 | pbl++; | 790 | pbl++; |
787 | *pbl = (u32)((u64)page >> 32); | 791 | *pbl = (u32)((u64)page >> 32); |
788 | pbl++; | 792 | pbl++; |
789 | page += PAGE_SIZE; | 793 | page += CNIC_PAGE_SIZE; |
790 | } | 794 | } |
791 | 795 | ||
792 | /* Allocate and map ConnDB */ | 796 | /* Allocate and map ConnDB */ |
@@ -805,8 +809,8 @@ static int bnx2fc_alloc_session_resc(struct bnx2fc_hba *hba, | |||
805 | 809 | ||
806 | /* Allocate and map LCQ */ | 810 | /* Allocate and map LCQ */ |
807 | tgt->lcq_mem_size = (tgt->max_sqes + 8) * BNX2FC_SQ_WQE_SIZE; | 811 | tgt->lcq_mem_size = (tgt->max_sqes + 8) * BNX2FC_SQ_WQE_SIZE; |
808 | tgt->lcq_mem_size = (tgt->lcq_mem_size + (PAGE_SIZE - 1)) & | 812 | tgt->lcq_mem_size = (tgt->lcq_mem_size + (CNIC_PAGE_SIZE - 1)) & |
809 | PAGE_MASK; | 813 | CNIC_PAGE_MASK; |
810 | 814 | ||
811 | tgt->lcq = dma_alloc_coherent(&hba->pcidev->dev, tgt->lcq_mem_size, | 815 | tgt->lcq = dma_alloc_coherent(&hba->pcidev->dev, tgt->lcq_mem_size, |
812 | &tgt->lcq_dma, GFP_KERNEL); | 816 | &tgt->lcq_dma, GFP_KERNEL); |
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index e4cf23df4b4f..b87a1933f880 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -61,7 +61,7 @@ static void bnx2i_adjust_qp_size(struct bnx2i_hba *hba) | |||
61 | * yield integral num of page buffers | 61 | * yield integral num of page buffers |
62 | */ | 62 | */ |
63 | /* adjust SQ */ | 63 | /* adjust SQ */ |
64 | num_elements_per_pg = PAGE_SIZE / BNX2I_SQ_WQE_SIZE; | 64 | num_elements_per_pg = CNIC_PAGE_SIZE / BNX2I_SQ_WQE_SIZE; |
65 | if (hba->max_sqes < num_elements_per_pg) | 65 | if (hba->max_sqes < num_elements_per_pg) |
66 | hba->max_sqes = num_elements_per_pg; | 66 | hba->max_sqes = num_elements_per_pg; |
67 | else if (hba->max_sqes % num_elements_per_pg) | 67 | else if (hba->max_sqes % num_elements_per_pg) |
@@ -69,7 +69,7 @@ static void bnx2i_adjust_qp_size(struct bnx2i_hba *hba) | |||
69 | ~(num_elements_per_pg - 1); | 69 | ~(num_elements_per_pg - 1); |
70 | 70 | ||
71 | /* adjust CQ */ | 71 | /* adjust CQ */ |
72 | num_elements_per_pg = PAGE_SIZE / BNX2I_CQE_SIZE; | 72 | num_elements_per_pg = CNIC_PAGE_SIZE / BNX2I_CQE_SIZE; |
73 | if (hba->max_cqes < num_elements_per_pg) | 73 | if (hba->max_cqes < num_elements_per_pg) |
74 | hba->max_cqes = num_elements_per_pg; | 74 | hba->max_cqes = num_elements_per_pg; |
75 | else if (hba->max_cqes % num_elements_per_pg) | 75 | else if (hba->max_cqes % num_elements_per_pg) |
@@ -77,7 +77,7 @@ static void bnx2i_adjust_qp_size(struct bnx2i_hba *hba) | |||
77 | ~(num_elements_per_pg - 1); | 77 | ~(num_elements_per_pg - 1); |
78 | 78 | ||
79 | /* adjust RQ */ | 79 | /* adjust RQ */ |
80 | num_elements_per_pg = PAGE_SIZE / BNX2I_RQ_WQE_SIZE; | 80 | num_elements_per_pg = CNIC_PAGE_SIZE / BNX2I_RQ_WQE_SIZE; |
81 | if (hba->max_rqes < num_elements_per_pg) | 81 | if (hba->max_rqes < num_elements_per_pg) |
82 | hba->max_rqes = num_elements_per_pg; | 82 | hba->max_rqes = num_elements_per_pg; |
83 | else if (hba->max_rqes % num_elements_per_pg) | 83 | else if (hba->max_rqes % num_elements_per_pg) |
@@ -959,7 +959,7 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
959 | 959 | ||
960 | /* SQ page table */ | 960 | /* SQ page table */ |
961 | memset(ep->qp.sq_pgtbl_virt, 0, ep->qp.sq_pgtbl_size); | 961 | memset(ep->qp.sq_pgtbl_virt, 0, ep->qp.sq_pgtbl_size); |
962 | num_pages = ep->qp.sq_mem_size / PAGE_SIZE; | 962 | num_pages = ep->qp.sq_mem_size / CNIC_PAGE_SIZE; |
963 | page = ep->qp.sq_phys; | 963 | page = ep->qp.sq_phys; |
964 | 964 | ||
965 | if (cnic_dev_10g) | 965 | if (cnic_dev_10g) |
@@ -973,7 +973,7 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
973 | ptbl++; | 973 | ptbl++; |
974 | *ptbl = (u32) ((u64) page >> 32); | 974 | *ptbl = (u32) ((u64) page >> 32); |
975 | ptbl++; | 975 | ptbl++; |
976 | page += PAGE_SIZE; | 976 | page += CNIC_PAGE_SIZE; |
977 | } else { | 977 | } else { |
978 | /* PTE is written in big endian format for | 978 | /* PTE is written in big endian format for |
979 | * 5706/5708/5709 devices */ | 979 | * 5706/5708/5709 devices */ |
@@ -981,13 +981,13 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
981 | ptbl++; | 981 | ptbl++; |
982 | *ptbl = (u32) page; | 982 | *ptbl = (u32) page; |
983 | ptbl++; | 983 | ptbl++; |
984 | page += PAGE_SIZE; | 984 | page += CNIC_PAGE_SIZE; |
985 | } | 985 | } |
986 | } | 986 | } |
987 | 987 | ||
988 | /* RQ page table */ | 988 | /* RQ page table */ |
989 | memset(ep->qp.rq_pgtbl_virt, 0, ep->qp.rq_pgtbl_size); | 989 | memset(ep->qp.rq_pgtbl_virt, 0, ep->qp.rq_pgtbl_size); |
990 | num_pages = ep->qp.rq_mem_size / PAGE_SIZE; | 990 | num_pages = ep->qp.rq_mem_size / CNIC_PAGE_SIZE; |
991 | page = ep->qp.rq_phys; | 991 | page = ep->qp.rq_phys; |
992 | 992 | ||
993 | if (cnic_dev_10g) | 993 | if (cnic_dev_10g) |
@@ -1001,7 +1001,7 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
1001 | ptbl++; | 1001 | ptbl++; |
1002 | *ptbl = (u32) ((u64) page >> 32); | 1002 | *ptbl = (u32) ((u64) page >> 32); |
1003 | ptbl++; | 1003 | ptbl++; |
1004 | page += PAGE_SIZE; | 1004 | page += CNIC_PAGE_SIZE; |
1005 | } else { | 1005 | } else { |
1006 | /* PTE is written in big endian format for | 1006 | /* PTE is written in big endian format for |
1007 | * 5706/5708/5709 devices */ | 1007 | * 5706/5708/5709 devices */ |
@@ -1009,13 +1009,13 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
1009 | ptbl++; | 1009 | ptbl++; |
1010 | *ptbl = (u32) page; | 1010 | *ptbl = (u32) page; |
1011 | ptbl++; | 1011 | ptbl++; |
1012 | page += PAGE_SIZE; | 1012 | page += CNIC_PAGE_SIZE; |
1013 | } | 1013 | } |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | /* CQ page table */ | 1016 | /* CQ page table */ |
1017 | memset(ep->qp.cq_pgtbl_virt, 0, ep->qp.cq_pgtbl_size); | 1017 | memset(ep->qp.cq_pgtbl_virt, 0, ep->qp.cq_pgtbl_size); |
1018 | num_pages = ep->qp.cq_mem_size / PAGE_SIZE; | 1018 | num_pages = ep->qp.cq_mem_size / CNIC_PAGE_SIZE; |
1019 | page = ep->qp.cq_phys; | 1019 | page = ep->qp.cq_phys; |
1020 | 1020 | ||
1021 | if (cnic_dev_10g) | 1021 | if (cnic_dev_10g) |
@@ -1029,7 +1029,7 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
1029 | ptbl++; | 1029 | ptbl++; |
1030 | *ptbl = (u32) ((u64) page >> 32); | 1030 | *ptbl = (u32) ((u64) page >> 32); |
1031 | ptbl++; | 1031 | ptbl++; |
1032 | page += PAGE_SIZE; | 1032 | page += CNIC_PAGE_SIZE; |
1033 | } else { | 1033 | } else { |
1034 | /* PTE is written in big endian format for | 1034 | /* PTE is written in big endian format for |
1035 | * 5706/5708/5709 devices */ | 1035 | * 5706/5708/5709 devices */ |
@@ -1037,7 +1037,7 @@ static void setup_qp_page_tables(struct bnx2i_endpoint *ep) | |||
1037 | ptbl++; | 1037 | ptbl++; |
1038 | *ptbl = (u32) page; | 1038 | *ptbl = (u32) page; |
1039 | ptbl++; | 1039 | ptbl++; |
1040 | page += PAGE_SIZE; | 1040 | page += CNIC_PAGE_SIZE; |
1041 | } | 1041 | } |
1042 | } | 1042 | } |
1043 | } | 1043 | } |
@@ -1064,11 +1064,11 @@ int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep) | |||
1064 | /* Allocate page table memory for SQ which is page aligned */ | 1064 | /* Allocate page table memory for SQ which is page aligned */ |
1065 | ep->qp.sq_mem_size = hba->max_sqes * BNX2I_SQ_WQE_SIZE; | 1065 | ep->qp.sq_mem_size = hba->max_sqes * BNX2I_SQ_WQE_SIZE; |
1066 | ep->qp.sq_mem_size = | 1066 | ep->qp.sq_mem_size = |
1067 | (ep->qp.sq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1067 | (ep->qp.sq_mem_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1068 | ep->qp.sq_pgtbl_size = | 1068 | ep->qp.sq_pgtbl_size = |
1069 | (ep->qp.sq_mem_size / PAGE_SIZE) * sizeof(void *); | 1069 | (ep->qp.sq_mem_size / CNIC_PAGE_SIZE) * sizeof(void *); |
1070 | ep->qp.sq_pgtbl_size = | 1070 | ep->qp.sq_pgtbl_size = |
1071 | (ep->qp.sq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1071 | (ep->qp.sq_pgtbl_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1072 | 1072 | ||
1073 | ep->qp.sq_pgtbl_virt = | 1073 | ep->qp.sq_pgtbl_virt = |
1074 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.sq_pgtbl_size, | 1074 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.sq_pgtbl_size, |
@@ -1101,11 +1101,11 @@ int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep) | |||
1101 | /* Allocate page table memory for CQ which is page aligned */ | 1101 | /* Allocate page table memory for CQ which is page aligned */ |
1102 | ep->qp.cq_mem_size = hba->max_cqes * BNX2I_CQE_SIZE; | 1102 | ep->qp.cq_mem_size = hba->max_cqes * BNX2I_CQE_SIZE; |
1103 | ep->qp.cq_mem_size = | 1103 | ep->qp.cq_mem_size = |
1104 | (ep->qp.cq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1104 | (ep->qp.cq_mem_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1105 | ep->qp.cq_pgtbl_size = | 1105 | ep->qp.cq_pgtbl_size = |
1106 | (ep->qp.cq_mem_size / PAGE_SIZE) * sizeof(void *); | 1106 | (ep->qp.cq_mem_size / CNIC_PAGE_SIZE) * sizeof(void *); |
1107 | ep->qp.cq_pgtbl_size = | 1107 | ep->qp.cq_pgtbl_size = |
1108 | (ep->qp.cq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1108 | (ep->qp.cq_pgtbl_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1109 | 1109 | ||
1110 | ep->qp.cq_pgtbl_virt = | 1110 | ep->qp.cq_pgtbl_virt = |
1111 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.cq_pgtbl_size, | 1111 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.cq_pgtbl_size, |
@@ -1144,11 +1144,11 @@ int bnx2i_alloc_qp_resc(struct bnx2i_hba *hba, struct bnx2i_endpoint *ep) | |||
1144 | /* Allocate page table memory for RQ which is page aligned */ | 1144 | /* Allocate page table memory for RQ which is page aligned */ |
1145 | ep->qp.rq_mem_size = hba->max_rqes * BNX2I_RQ_WQE_SIZE; | 1145 | ep->qp.rq_mem_size = hba->max_rqes * BNX2I_RQ_WQE_SIZE; |
1146 | ep->qp.rq_mem_size = | 1146 | ep->qp.rq_mem_size = |
1147 | (ep->qp.rq_mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1147 | (ep->qp.rq_mem_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1148 | ep->qp.rq_pgtbl_size = | 1148 | ep->qp.rq_pgtbl_size = |
1149 | (ep->qp.rq_mem_size / PAGE_SIZE) * sizeof(void *); | 1149 | (ep->qp.rq_mem_size / CNIC_PAGE_SIZE) * sizeof(void *); |
1150 | ep->qp.rq_pgtbl_size = | 1150 | ep->qp.rq_pgtbl_size = |
1151 | (ep->qp.rq_pgtbl_size + (PAGE_SIZE - 1)) & PAGE_MASK; | 1151 | (ep->qp.rq_pgtbl_size + (CNIC_PAGE_SIZE - 1)) & CNIC_PAGE_MASK; |
1152 | 1152 | ||
1153 | ep->qp.rq_pgtbl_virt = | 1153 | ep->qp.rq_pgtbl_virt = |
1154 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.rq_pgtbl_size, | 1154 | dma_alloc_coherent(&hba->pcidev->dev, ep->qp.rq_pgtbl_size, |
@@ -1270,7 +1270,7 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) | |||
1270 | bnx2i_adjust_qp_size(hba); | 1270 | bnx2i_adjust_qp_size(hba); |
1271 | 1271 | ||
1272 | iscsi_init.flags = | 1272 | iscsi_init.flags = |
1273 | ISCSI_PAGE_SIZE_4K << ISCSI_KWQE_INIT1_PAGE_SIZE_SHIFT; | 1273 | (CNIC_PAGE_BITS - 8) << ISCSI_KWQE_INIT1_PAGE_SIZE_SHIFT; |
1274 | if (en_tcp_dack) | 1274 | if (en_tcp_dack) |
1275 | iscsi_init.flags |= ISCSI_KWQE_INIT1_DELAYED_ACK_ENABLE; | 1275 | iscsi_init.flags |= ISCSI_KWQE_INIT1_DELAYED_ACK_ENABLE; |
1276 | iscsi_init.reserved0 = 0; | 1276 | iscsi_init.reserved0 = 0; |
@@ -1288,15 +1288,15 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) | |||
1288 | ((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16)); | 1288 | ((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16)); |
1289 | iscsi_init.num_ccells_per_conn = hba->num_ccell; | 1289 | iscsi_init.num_ccells_per_conn = hba->num_ccell; |
1290 | iscsi_init.num_tasks_per_conn = hba->max_sqes; | 1290 | iscsi_init.num_tasks_per_conn = hba->max_sqes; |
1291 | iscsi_init.sq_wqes_per_page = PAGE_SIZE / BNX2I_SQ_WQE_SIZE; | 1291 | iscsi_init.sq_wqes_per_page = CNIC_PAGE_SIZE / BNX2I_SQ_WQE_SIZE; |
1292 | iscsi_init.sq_num_wqes = hba->max_sqes; | 1292 | iscsi_init.sq_num_wqes = hba->max_sqes; |
1293 | iscsi_init.cq_log_wqes_per_page = | 1293 | iscsi_init.cq_log_wqes_per_page = |
1294 | (u8) bnx2i_power_of2(PAGE_SIZE / BNX2I_CQE_SIZE); | 1294 | (u8) bnx2i_power_of2(CNIC_PAGE_SIZE / BNX2I_CQE_SIZE); |
1295 | iscsi_init.cq_num_wqes = hba->max_cqes; | 1295 | iscsi_init.cq_num_wqes = hba->max_cqes; |
1296 | iscsi_init.cq_num_pages = (hba->max_cqes * BNX2I_CQE_SIZE + | 1296 | iscsi_init.cq_num_pages = (hba->max_cqes * BNX2I_CQE_SIZE + |
1297 | (PAGE_SIZE - 1)) / PAGE_SIZE; | 1297 | (CNIC_PAGE_SIZE - 1)) / CNIC_PAGE_SIZE; |
1298 | iscsi_init.sq_num_pages = (hba->max_sqes * BNX2I_SQ_WQE_SIZE + | 1298 | iscsi_init.sq_num_pages = (hba->max_sqes * BNX2I_SQ_WQE_SIZE + |
1299 | (PAGE_SIZE - 1)) / PAGE_SIZE; | 1299 | (CNIC_PAGE_SIZE - 1)) / CNIC_PAGE_SIZE; |
1300 | iscsi_init.rq_buffer_size = BNX2I_RQ_WQE_SIZE; | 1300 | iscsi_init.rq_buffer_size = BNX2I_RQ_WQE_SIZE; |
1301 | iscsi_init.rq_num_wqes = hba->max_rqes; | 1301 | iscsi_init.rq_num_wqes = hba->max_rqes; |
1302 | 1302 | ||
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 854dad7d5b03..c8b0aff5bbd4 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c | |||
@@ -525,7 +525,7 @@ static int bnx2i_setup_mp_bdt(struct bnx2i_hba *hba) | |||
525 | struct iscsi_bd *mp_bdt; | 525 | struct iscsi_bd *mp_bdt; |
526 | u64 addr; | 526 | u64 addr; |
527 | 527 | ||
528 | hba->mp_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 528 | hba->mp_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
529 | &hba->mp_bd_dma, GFP_KERNEL); | 529 | &hba->mp_bd_dma, GFP_KERNEL); |
530 | if (!hba->mp_bd_tbl) { | 530 | if (!hba->mp_bd_tbl) { |
531 | printk(KERN_ERR "unable to allocate Middle Path BDT\n"); | 531 | printk(KERN_ERR "unable to allocate Middle Path BDT\n"); |
@@ -533,11 +533,12 @@ static int bnx2i_setup_mp_bdt(struct bnx2i_hba *hba) | |||
533 | goto out; | 533 | goto out; |
534 | } | 534 | } |
535 | 535 | ||
536 | hba->dummy_buffer = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 536 | hba->dummy_buffer = dma_alloc_coherent(&hba->pcidev->dev, |
537 | CNIC_PAGE_SIZE, | ||
537 | &hba->dummy_buf_dma, GFP_KERNEL); | 538 | &hba->dummy_buf_dma, GFP_KERNEL); |
538 | if (!hba->dummy_buffer) { | 539 | if (!hba->dummy_buffer) { |
539 | printk(KERN_ERR "unable to alloc Middle Path Dummy Buffer\n"); | 540 | printk(KERN_ERR "unable to alloc Middle Path Dummy Buffer\n"); |
540 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 541 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
541 | hba->mp_bd_tbl, hba->mp_bd_dma); | 542 | hba->mp_bd_tbl, hba->mp_bd_dma); |
542 | hba->mp_bd_tbl = NULL; | 543 | hba->mp_bd_tbl = NULL; |
543 | rc = -1; | 544 | rc = -1; |
@@ -548,7 +549,7 @@ static int bnx2i_setup_mp_bdt(struct bnx2i_hba *hba) | |||
548 | addr = (unsigned long) hba->dummy_buf_dma; | 549 | addr = (unsigned long) hba->dummy_buf_dma; |
549 | mp_bdt->buffer_addr_lo = addr & 0xffffffff; | 550 | mp_bdt->buffer_addr_lo = addr & 0xffffffff; |
550 | mp_bdt->buffer_addr_hi = addr >> 32; | 551 | mp_bdt->buffer_addr_hi = addr >> 32; |
551 | mp_bdt->buffer_length = PAGE_SIZE; | 552 | mp_bdt->buffer_length = CNIC_PAGE_SIZE; |
552 | mp_bdt->flags = ISCSI_BD_LAST_IN_BD_CHAIN | | 553 | mp_bdt->flags = ISCSI_BD_LAST_IN_BD_CHAIN | |
553 | ISCSI_BD_FIRST_IN_BD_CHAIN; | 554 | ISCSI_BD_FIRST_IN_BD_CHAIN; |
554 | out: | 555 | out: |
@@ -565,12 +566,12 @@ out: | |||
565 | static void bnx2i_free_mp_bdt(struct bnx2i_hba *hba) | 566 | static void bnx2i_free_mp_bdt(struct bnx2i_hba *hba) |
566 | { | 567 | { |
567 | if (hba->mp_bd_tbl) { | 568 | if (hba->mp_bd_tbl) { |
568 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 569 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
569 | hba->mp_bd_tbl, hba->mp_bd_dma); | 570 | hba->mp_bd_tbl, hba->mp_bd_dma); |
570 | hba->mp_bd_tbl = NULL; | 571 | hba->mp_bd_tbl = NULL; |
571 | } | 572 | } |
572 | if (hba->dummy_buffer) { | 573 | if (hba->dummy_buffer) { |
573 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 574 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
574 | hba->dummy_buffer, hba->dummy_buf_dma); | 575 | hba->dummy_buffer, hba->dummy_buf_dma); |
575 | hba->dummy_buffer = NULL; | 576 | hba->dummy_buffer = NULL; |
576 | } | 577 | } |
@@ -934,14 +935,14 @@ static void bnx2i_conn_free_login_resources(struct bnx2i_hba *hba, | |||
934 | struct bnx2i_conn *bnx2i_conn) | 935 | struct bnx2i_conn *bnx2i_conn) |
935 | { | 936 | { |
936 | if (bnx2i_conn->gen_pdu.resp_bd_tbl) { | 937 | if (bnx2i_conn->gen_pdu.resp_bd_tbl) { |
937 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 938 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
938 | bnx2i_conn->gen_pdu.resp_bd_tbl, | 939 | bnx2i_conn->gen_pdu.resp_bd_tbl, |
939 | bnx2i_conn->gen_pdu.resp_bd_dma); | 940 | bnx2i_conn->gen_pdu.resp_bd_dma); |
940 | bnx2i_conn->gen_pdu.resp_bd_tbl = NULL; | 941 | bnx2i_conn->gen_pdu.resp_bd_tbl = NULL; |
941 | } | 942 | } |
942 | 943 | ||
943 | if (bnx2i_conn->gen_pdu.req_bd_tbl) { | 944 | if (bnx2i_conn->gen_pdu.req_bd_tbl) { |
944 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 945 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
945 | bnx2i_conn->gen_pdu.req_bd_tbl, | 946 | bnx2i_conn->gen_pdu.req_bd_tbl, |
946 | bnx2i_conn->gen_pdu.req_bd_dma); | 947 | bnx2i_conn->gen_pdu.req_bd_dma); |
947 | bnx2i_conn->gen_pdu.req_bd_tbl = NULL; | 948 | bnx2i_conn->gen_pdu.req_bd_tbl = NULL; |
@@ -998,13 +999,13 @@ static int bnx2i_conn_alloc_login_resources(struct bnx2i_hba *hba, | |||
998 | bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf; | 999 | bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf; |
999 | 1000 | ||
1000 | bnx2i_conn->gen_pdu.req_bd_tbl = | 1001 | bnx2i_conn->gen_pdu.req_bd_tbl = |
1001 | dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 1002 | dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
1002 | &bnx2i_conn->gen_pdu.req_bd_dma, GFP_KERNEL); | 1003 | &bnx2i_conn->gen_pdu.req_bd_dma, GFP_KERNEL); |
1003 | if (bnx2i_conn->gen_pdu.req_bd_tbl == NULL) | 1004 | if (bnx2i_conn->gen_pdu.req_bd_tbl == NULL) |
1004 | goto login_req_bd_tbl_failure; | 1005 | goto login_req_bd_tbl_failure; |
1005 | 1006 | ||
1006 | bnx2i_conn->gen_pdu.resp_bd_tbl = | 1007 | bnx2i_conn->gen_pdu.resp_bd_tbl = |
1007 | dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, | 1008 | dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
1008 | &bnx2i_conn->gen_pdu.resp_bd_dma, | 1009 | &bnx2i_conn->gen_pdu.resp_bd_dma, |
1009 | GFP_KERNEL); | 1010 | GFP_KERNEL); |
1010 | if (bnx2i_conn->gen_pdu.resp_bd_tbl == NULL) | 1011 | if (bnx2i_conn->gen_pdu.resp_bd_tbl == NULL) |
@@ -1013,7 +1014,7 @@ static int bnx2i_conn_alloc_login_resources(struct bnx2i_hba *hba, | |||
1013 | return 0; | 1014 | return 0; |
1014 | 1015 | ||
1015 | login_resp_bd_tbl_failure: | 1016 | login_resp_bd_tbl_failure: |
1016 | dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, | 1017 | dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE, |
1017 | bnx2i_conn->gen_pdu.req_bd_tbl, | 1018 | bnx2i_conn->gen_pdu.req_bd_tbl, |
1018 | bnx2i_conn->gen_pdu.req_bd_dma); | 1019 | bnx2i_conn->gen_pdu.req_bd_dma); |
1019 | bnx2i_conn->gen_pdu.req_bd_tbl = NULL; | 1020 | bnx2i_conn->gen_pdu.req_bd_tbl = NULL; |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 4911310a38f5..22a9bb1abae1 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -311,9 +311,8 @@ static inline struct Scsi_Host *to_shost(struct isci_host *ihost) | |||
311 | } | 311 | } |
312 | 312 | ||
313 | #define for_each_isci_host(id, ihost, pdev) \ | 313 | #define for_each_isci_host(id, ihost, pdev) \ |
314 | for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \ | 314 | for (id = 0; id < SCI_MAX_CONTROLLERS && \ |
315 | id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \ | 315 | (ihost = to_pci_info(pdev)->hosts[id]); id++) |
316 | ihost = to_pci_info(pdev)->hosts[++id]) | ||
317 | 316 | ||
318 | static inline void wait_for_start(struct isci_host *ihost) | 317 | static inline void wait_for_start(struct isci_host *ihost) |
319 | { | 318 | { |
diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c index 85c77f6b802b..ac879745ef80 100644 --- a/drivers/scsi/isci/port_config.c +++ b/drivers/scsi/isci/port_config.c | |||
@@ -615,13 +615,6 @@ static void sci_apc_agent_link_up(struct isci_host *ihost, | |||
615 | SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION); | 615 | SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION); |
616 | } else { | 616 | } else { |
617 | /* the phy is already the part of the port */ | 617 | /* the phy is already the part of the port */ |
618 | u32 port_state = iport->sm.current_state_id; | ||
619 | |||
620 | /* if the PORT'S state is resetting then the link up is from | ||
621 | * port hard reset in this case, we need to tell the port | ||
622 | * that link up is recieved | ||
623 | */ | ||
624 | BUG_ON(port_state != SCI_PORT_RESETTING); | ||
625 | port_agent->phy_ready_mask |= 1 << phy_index; | 618 | port_agent->phy_ready_mask |= 1 << phy_index; |
626 | sci_port_link_up(iport, iphy); | 619 | sci_port_link_up(iport, iphy); |
627 | } | 620 | } |
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 0d30ca849e8f..5d6fda72d659 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c | |||
@@ -801,7 +801,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev) | |||
801 | /* XXX: need to cleanup any ireqs targeting this | 801 | /* XXX: need to cleanup any ireqs targeting this |
802 | * domain_device | 802 | * domain_device |
803 | */ | 803 | */ |
804 | ret = TMF_RESP_FUNC_COMPLETE; | 804 | ret = -ENODEV; |
805 | goto out; | 805 | goto out; |
806 | } | 806 | } |
807 | 807 | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index e1fe95ef23e1..266724b6b899 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2996,8 +2996,7 @@ struct qla_hw_data { | |||
2996 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ | 2996 | IS_QLA82XX(ha) || IS_QLA83XX(ha) || \ |
2997 | IS_QLA8044(ha)) | 2997 | IS_QLA8044(ha)) |
2998 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 2998 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) |
2999 | #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ | 2999 | #define IS_NOPOLLING_TYPE(ha) (IS_QLA81XX(ha) && (ha)->flags.msix_enabled) |
3000 | IS_QLA83XX(ha)) && (ha)->flags.msix_enabled) | ||
3001 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 3000 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) |
3002 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) | 3001 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) |
3003 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) | 3002 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 9bc86b9e86b1..0a1dcb43d18b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -2880,6 +2880,7 @@ static int | |||
2880 | qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) | 2880 | qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) |
2881 | { | 2881 | { |
2882 | #define MIN_MSIX_COUNT 2 | 2882 | #define MIN_MSIX_COUNT 2 |
2883 | #define ATIO_VECTOR 2 | ||
2883 | int i, ret; | 2884 | int i, ret; |
2884 | struct msix_entry *entries; | 2885 | struct msix_entry *entries; |
2885 | struct qla_msix_entry *qentry; | 2886 | struct qla_msix_entry *qentry; |
@@ -2936,34 +2937,47 @@ msix_failed: | |||
2936 | } | 2937 | } |
2937 | 2938 | ||
2938 | /* Enable MSI-X vectors for the base queue */ | 2939 | /* Enable MSI-X vectors for the base queue */ |
2939 | for (i = 0; i < ha->msix_count; i++) { | 2940 | for (i = 0; i < 2; i++) { |
2940 | qentry = &ha->msix_entries[i]; | 2941 | qentry = &ha->msix_entries[i]; |
2941 | if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { | 2942 | if (IS_P3P_TYPE(ha)) |
2942 | ret = request_irq(qentry->vector, | ||
2943 | qla83xx_msix_entries[i].handler, | ||
2944 | 0, qla83xx_msix_entries[i].name, rsp); | ||
2945 | } else if (IS_P3P_TYPE(ha)) { | ||
2946 | ret = request_irq(qentry->vector, | 2943 | ret = request_irq(qentry->vector, |
2947 | qla82xx_msix_entries[i].handler, | 2944 | qla82xx_msix_entries[i].handler, |
2948 | 0, qla82xx_msix_entries[i].name, rsp); | 2945 | 0, qla82xx_msix_entries[i].name, rsp); |
2949 | } else { | 2946 | else |
2950 | ret = request_irq(qentry->vector, | 2947 | ret = request_irq(qentry->vector, |
2951 | msix_entries[i].handler, | 2948 | msix_entries[i].handler, |
2952 | 0, msix_entries[i].name, rsp); | 2949 | 0, msix_entries[i].name, rsp); |
2953 | } | 2950 | if (ret) |
2954 | if (ret) { | 2951 | goto msix_register_fail; |
2955 | ql_log(ql_log_fatal, vha, 0x00cb, | ||
2956 | "MSI-X: unable to register handler -- %x/%d.\n", | ||
2957 | qentry->vector, ret); | ||
2958 | qla24xx_disable_msix(ha); | ||
2959 | ha->mqenable = 0; | ||
2960 | goto msix_out; | ||
2961 | } | ||
2962 | qentry->have_irq = 1; | 2952 | qentry->have_irq = 1; |
2963 | qentry->rsp = rsp; | 2953 | qentry->rsp = rsp; |
2964 | rsp->msix = qentry; | 2954 | rsp->msix = qentry; |
2965 | } | 2955 | } |
2966 | 2956 | ||
2957 | /* | ||
2958 | * If target mode is enable, also request the vector for the ATIO | ||
2959 | * queue. | ||
2960 | */ | ||
2961 | if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { | ||
2962 | qentry = &ha->msix_entries[ATIO_VECTOR]; | ||
2963 | ret = request_irq(qentry->vector, | ||
2964 | qla83xx_msix_entries[ATIO_VECTOR].handler, | ||
2965 | 0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp); | ||
2966 | qentry->have_irq = 1; | ||
2967 | qentry->rsp = rsp; | ||
2968 | rsp->msix = qentry; | ||
2969 | } | ||
2970 | |||
2971 | msix_register_fail: | ||
2972 | if (ret) { | ||
2973 | ql_log(ql_log_fatal, vha, 0x00cb, | ||
2974 | "MSI-X: unable to register handler -- %x/%d.\n", | ||
2975 | qentry->vector, ret); | ||
2976 | qla24xx_disable_msix(ha); | ||
2977 | ha->mqenable = 0; | ||
2978 | goto msix_out; | ||
2979 | } | ||
2980 | |||
2967 | /* Enable MSI-X vector for response queue update for queue 0 */ | 2981 | /* Enable MSI-X vector for response queue update for queue 0 */ |
2968 | if (IS_QLA83XX(ha)) { | 2982 | if (IS_QLA83XX(ha)) { |
2969 | if (ha->msixbase && ha->mqiobase && | 2983 | if (ha->msixbase && ha->mqiobase && |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 9e80d61e5a3a..0cb73074c199 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -790,17 +790,32 @@ static inline int test_tgt_sess_count(struct qla_tgt *tgt) | |||
790 | } | 790 | } |
791 | 791 | ||
792 | /* Called by tcm_qla2xxx configfs code */ | 792 | /* Called by tcm_qla2xxx configfs code */ |
793 | void qlt_stop_phase1(struct qla_tgt *tgt) | 793 | int qlt_stop_phase1(struct qla_tgt *tgt) |
794 | { | 794 | { |
795 | struct scsi_qla_host *vha = tgt->vha; | 795 | struct scsi_qla_host *vha = tgt->vha; |
796 | struct qla_hw_data *ha = tgt->ha; | 796 | struct qla_hw_data *ha = tgt->ha; |
797 | unsigned long flags; | 797 | unsigned long flags; |
798 | 798 | ||
799 | mutex_lock(&qla_tgt_mutex); | ||
800 | if (!vha->fc_vport) { | ||
801 | struct Scsi_Host *sh = vha->host; | ||
802 | struct fc_host_attrs *fc_host = shost_to_fc_host(sh); | ||
803 | bool npiv_vports; | ||
804 | |||
805 | spin_lock_irqsave(sh->host_lock, flags); | ||
806 | npiv_vports = (fc_host->npiv_vports_inuse); | ||
807 | spin_unlock_irqrestore(sh->host_lock, flags); | ||
808 | |||
809 | if (npiv_vports) { | ||
810 | mutex_unlock(&qla_tgt_mutex); | ||
811 | return -EPERM; | ||
812 | } | ||
813 | } | ||
799 | if (tgt->tgt_stop || tgt->tgt_stopped) { | 814 | if (tgt->tgt_stop || tgt->tgt_stopped) { |
800 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, | 815 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, |
801 | "Already in tgt->tgt_stop or tgt_stopped state\n"); | 816 | "Already in tgt->tgt_stop or tgt_stopped state\n"); |
802 | dump_stack(); | 817 | mutex_unlock(&qla_tgt_mutex); |
803 | return; | 818 | return -EPERM; |
804 | } | 819 | } |
805 | 820 | ||
806 | ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", | 821 | ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", |
@@ -815,6 +830,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt) | |||
815 | qlt_clear_tgt_db(tgt, true); | 830 | qlt_clear_tgt_db(tgt, true); |
816 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 831 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
817 | mutex_unlock(&vha->vha_tgt.tgt_mutex); | 832 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
833 | mutex_unlock(&qla_tgt_mutex); | ||
818 | 834 | ||
819 | flush_delayed_work(&tgt->sess_del_work); | 835 | flush_delayed_work(&tgt->sess_del_work); |
820 | 836 | ||
@@ -841,6 +857,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt) | |||
841 | 857 | ||
842 | /* Wait for sessions to clear out (just in case) */ | 858 | /* Wait for sessions to clear out (just in case) */ |
843 | wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); | 859 | wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); |
860 | return 0; | ||
844 | } | 861 | } |
845 | EXPORT_SYMBOL(qlt_stop_phase1); | 862 | EXPORT_SYMBOL(qlt_stop_phase1); |
846 | 863 | ||
@@ -2595,8 +2612,6 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, | |||
2595 | return -ENOMEM; | 2612 | return -ENOMEM; |
2596 | } | 2613 | } |
2597 | 2614 | ||
2598 | INIT_LIST_HEAD(&cmd->cmd_list); | ||
2599 | |||
2600 | memcpy(&cmd->atio, atio, sizeof(*atio)); | 2615 | memcpy(&cmd->atio, atio, sizeof(*atio)); |
2601 | cmd->state = QLA_TGT_STATE_NEW; | 2616 | cmd->state = QLA_TGT_STATE_NEW; |
2602 | cmd->tgt = vha->vha_tgt.qla_tgt; | 2617 | cmd->tgt = vha->vha_tgt.qla_tgt; |
@@ -3187,7 +3202,8 @@ restart: | |||
3187 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, | 3202 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, |
3188 | "SRR cmd %p (se_cmd %p, tag %d, op %x), " | 3203 | "SRR cmd %p (se_cmd %p, tag %d, op %x), " |
3189 | "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, | 3204 | "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, |
3190 | se_cmd->t_task_cdb[0], cmd->sg_cnt, cmd->offset); | 3205 | se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, |
3206 | cmd->sg_cnt, cmd->offset); | ||
3191 | 3207 | ||
3192 | qlt_handle_srr(vha, sctio, imm); | 3208 | qlt_handle_srr(vha, sctio, imm); |
3193 | 3209 | ||
@@ -4183,6 +4199,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4183 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; | 4199 | tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; |
4184 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; | 4200 | tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; |
4185 | 4201 | ||
4202 | if (base_vha->fc_vport) | ||
4203 | return 0; | ||
4204 | |||
4186 | mutex_lock(&qla_tgt_mutex); | 4205 | mutex_lock(&qla_tgt_mutex); |
4187 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); | 4206 | list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); |
4188 | mutex_unlock(&qla_tgt_mutex); | 4207 | mutex_unlock(&qla_tgt_mutex); |
@@ -4196,6 +4215,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) | |||
4196 | if (!vha->vha_tgt.qla_tgt) | 4215 | if (!vha->vha_tgt.qla_tgt) |
4197 | return 0; | 4216 | return 0; |
4198 | 4217 | ||
4218 | if (vha->fc_vport) { | ||
4219 | qlt_release(vha->vha_tgt.qla_tgt); | ||
4220 | return 0; | ||
4221 | } | ||
4199 | mutex_lock(&qla_tgt_mutex); | 4222 | mutex_lock(&qla_tgt_mutex); |
4200 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); | 4223 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); |
4201 | mutex_unlock(&qla_tgt_mutex); | 4224 | mutex_unlock(&qla_tgt_mutex); |
@@ -4267,6 +4290,12 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4267 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4290 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4268 | continue; | 4291 | continue; |
4269 | } | 4292 | } |
4293 | if (tgt->tgt_stop) { | ||
4294 | pr_debug("MODE_TARGET in shutdown on qla2xxx(%d)\n", | ||
4295 | host->host_no); | ||
4296 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
4297 | continue; | ||
4298 | } | ||
4270 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4299 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4271 | 4300 | ||
4272 | if (!scsi_host_get(host)) { | 4301 | if (!scsi_host_get(host)) { |
@@ -4281,12 +4310,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | |||
4281 | scsi_host_put(host); | 4310 | scsi_host_put(host); |
4282 | continue; | 4311 | continue; |
4283 | } | 4312 | } |
4284 | mutex_unlock(&qla_tgt_mutex); | ||
4285 | |||
4286 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); | 4313 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); |
4287 | if (rc != 0) | 4314 | if (rc != 0) |
4288 | scsi_host_put(host); | 4315 | scsi_host_put(host); |
4289 | 4316 | ||
4317 | mutex_unlock(&qla_tgt_mutex); | ||
4290 | return rc; | 4318 | return rc; |
4291 | } | 4319 | } |
4292 | mutex_unlock(&qla_tgt_mutex); | 4320 | mutex_unlock(&qla_tgt_mutex); |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 1d10eecad499..ce33d8c26406 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -855,7 +855,6 @@ struct qla_tgt_cmd { | |||
855 | uint16_t loop_id; /* to save extra sess dereferences */ | 855 | uint16_t loop_id; /* to save extra sess dereferences */ |
856 | struct qla_tgt *tgt; /* to save extra sess dereferences */ | 856 | struct qla_tgt *tgt; /* to save extra sess dereferences */ |
857 | struct scsi_qla_host *vha; | 857 | struct scsi_qla_host *vha; |
858 | struct list_head cmd_list; | ||
859 | 858 | ||
860 | struct atio_from_isp atio; | 859 | struct atio_from_isp atio; |
861 | }; | 860 | }; |
@@ -1002,7 +1001,7 @@ extern void qlt_modify_vp_config(struct scsi_qla_host *, | |||
1002 | extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); | 1001 | extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); |
1003 | extern int qlt_mem_alloc(struct qla_hw_data *); | 1002 | extern int qlt_mem_alloc(struct qla_hw_data *); |
1004 | extern void qlt_mem_free(struct qla_hw_data *); | 1003 | extern void qlt_mem_free(struct qla_hw_data *); |
1005 | extern void qlt_stop_phase1(struct qla_tgt *); | 1004 | extern int qlt_stop_phase1(struct qla_tgt *); |
1006 | extern void qlt_stop_phase2(struct qla_tgt *); | 1005 | extern void qlt_stop_phase2(struct qla_tgt *); |
1007 | extern irqreturn_t qla83xx_msix_atio_q(int, void *); | 1006 | extern irqreturn_t qla83xx_msix_atio_q(int, void *); |
1008 | extern void qlt_83xx_iospace_config(struct qla_hw_data *); | 1007 | extern void qlt_83xx_iospace_config(struct qla_hw_data *); |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 75a141bbe74d..788c4fe2b0c9 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -182,20 +182,6 @@ static int tcm_qla2xxx_npiv_parse_wwn( | |||
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
185 | static ssize_t tcm_qla2xxx_npiv_format_wwn(char *buf, size_t len, | ||
186 | u64 wwpn, u64 wwnn) | ||
187 | { | ||
188 | u8 b[8], b2[8]; | ||
189 | |||
190 | put_unaligned_be64(wwpn, b); | ||
191 | put_unaligned_be64(wwnn, b2); | ||
192 | return snprintf(buf, len, | ||
193 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x," | ||
194 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | ||
195 | b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], | ||
196 | b2[0], b2[1], b2[2], b2[3], b2[4], b2[5], b2[6], b2[7]); | ||
197 | } | ||
198 | |||
199 | static char *tcm_qla2xxx_npiv_get_fabric_name(void) | 185 | static char *tcm_qla2xxx_npiv_get_fabric_name(void) |
200 | { | 186 | { |
201 | return "qla2xxx_npiv"; | 187 | return "qla2xxx_npiv"; |
@@ -227,15 +213,6 @@ static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) | |||
227 | return lport->lport_naa_name; | 213 | return lport->lport_naa_name; |
228 | } | 214 | } |
229 | 215 | ||
230 | static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) | ||
231 | { | ||
232 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | ||
233 | struct tcm_qla2xxx_tpg, se_tpg); | ||
234 | struct tcm_qla2xxx_lport *lport = tpg->lport; | ||
235 | |||
236 | return &lport->lport_npiv_name[0]; | ||
237 | } | ||
238 | |||
239 | static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) | 216 | static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) |
240 | { | 217 | { |
241 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | 218 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, |
@@ -941,15 +918,41 @@ static ssize_t tcm_qla2xxx_tpg_show_enable( | |||
941 | atomic_read(&tpg->lport_tpg_enabled)); | 918 | atomic_read(&tpg->lport_tpg_enabled)); |
942 | } | 919 | } |
943 | 920 | ||
921 | static void tcm_qla2xxx_depend_tpg(struct work_struct *work) | ||
922 | { | ||
923 | struct tcm_qla2xxx_tpg *base_tpg = container_of(work, | ||
924 | struct tcm_qla2xxx_tpg, tpg_base_work); | ||
925 | struct se_portal_group *se_tpg = &base_tpg->se_tpg; | ||
926 | struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; | ||
927 | |||
928 | if (!configfs_depend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
929 | &se_tpg->tpg_group.cg_item)) { | ||
930 | atomic_set(&base_tpg->lport_tpg_enabled, 1); | ||
931 | qlt_enable_vha(base_vha); | ||
932 | } | ||
933 | complete(&base_tpg->tpg_base_comp); | ||
934 | } | ||
935 | |||
936 | static void tcm_qla2xxx_undepend_tpg(struct work_struct *work) | ||
937 | { | ||
938 | struct tcm_qla2xxx_tpg *base_tpg = container_of(work, | ||
939 | struct tcm_qla2xxx_tpg, tpg_base_work); | ||
940 | struct se_portal_group *se_tpg = &base_tpg->se_tpg; | ||
941 | struct scsi_qla_host *base_vha = base_tpg->lport->qla_vha; | ||
942 | |||
943 | if (!qlt_stop_phase1(base_vha->vha_tgt.qla_tgt)) { | ||
944 | atomic_set(&base_tpg->lport_tpg_enabled, 0); | ||
945 | configfs_undepend_item(se_tpg->se_tpg_tfo->tf_subsys, | ||
946 | &se_tpg->tpg_group.cg_item); | ||
947 | } | ||
948 | complete(&base_tpg->tpg_base_comp); | ||
949 | } | ||
950 | |||
944 | static ssize_t tcm_qla2xxx_tpg_store_enable( | 951 | static ssize_t tcm_qla2xxx_tpg_store_enable( |
945 | struct se_portal_group *se_tpg, | 952 | struct se_portal_group *se_tpg, |
946 | const char *page, | 953 | const char *page, |
947 | size_t count) | 954 | size_t count) |
948 | { | 955 | { |
949 | struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; | ||
950 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, | ||
951 | struct tcm_qla2xxx_lport, lport_wwn); | ||
952 | struct scsi_qla_host *vha = lport->qla_vha; | ||
953 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | 956 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, |
954 | struct tcm_qla2xxx_tpg, se_tpg); | 957 | struct tcm_qla2xxx_tpg, se_tpg); |
955 | unsigned long op; | 958 | unsigned long op; |
@@ -964,19 +967,28 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( | |||
964 | pr_err("Illegal value for tpg_enable: %lu\n", op); | 967 | pr_err("Illegal value for tpg_enable: %lu\n", op); |
965 | return -EINVAL; | 968 | return -EINVAL; |
966 | } | 969 | } |
967 | |||
968 | if (op) { | 970 | if (op) { |
969 | atomic_set(&tpg->lport_tpg_enabled, 1); | 971 | if (atomic_read(&tpg->lport_tpg_enabled)) |
970 | qlt_enable_vha(vha); | 972 | return -EEXIST; |
973 | |||
974 | INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_depend_tpg); | ||
971 | } else { | 975 | } else { |
972 | if (!vha->vha_tgt.qla_tgt) { | 976 | if (!atomic_read(&tpg->lport_tpg_enabled)) |
973 | pr_err("struct qla_hw_data *vha->vha_tgt.qla_tgt is NULL\n"); | 977 | return count; |
974 | return -ENODEV; | 978 | |
975 | } | 979 | INIT_WORK(&tpg->tpg_base_work, tcm_qla2xxx_undepend_tpg); |
976 | atomic_set(&tpg->lport_tpg_enabled, 0); | ||
977 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); | ||
978 | } | 980 | } |
981 | init_completion(&tpg->tpg_base_comp); | ||
982 | schedule_work(&tpg->tpg_base_work); | ||
983 | wait_for_completion(&tpg->tpg_base_comp); | ||
979 | 984 | ||
985 | if (op) { | ||
986 | if (!atomic_read(&tpg->lport_tpg_enabled)) | ||
987 | return -ENODEV; | ||
988 | } else { | ||
989 | if (atomic_read(&tpg->lport_tpg_enabled)) | ||
990 | return -EPERM; | ||
991 | } | ||
980 | return count; | 992 | return count; |
981 | } | 993 | } |
982 | 994 | ||
@@ -1053,11 +1065,64 @@ static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) | |||
1053 | /* | 1065 | /* |
1054 | * Clear local TPG=1 pointer for non NPIV mode. | 1066 | * Clear local TPG=1 pointer for non NPIV mode. |
1055 | */ | 1067 | */ |
1056 | lport->tpg_1 = NULL; | 1068 | lport->tpg_1 = NULL; |
1057 | |||
1058 | kfree(tpg); | 1069 | kfree(tpg); |
1059 | } | 1070 | } |
1060 | 1071 | ||
1072 | static ssize_t tcm_qla2xxx_npiv_tpg_show_enable( | ||
1073 | struct se_portal_group *se_tpg, | ||
1074 | char *page) | ||
1075 | { | ||
1076 | return tcm_qla2xxx_tpg_show_enable(se_tpg, page); | ||
1077 | } | ||
1078 | |||
1079 | static ssize_t tcm_qla2xxx_npiv_tpg_store_enable( | ||
1080 | struct se_portal_group *se_tpg, | ||
1081 | const char *page, | ||
1082 | size_t count) | ||
1083 | { | ||
1084 | struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; | ||
1085 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, | ||
1086 | struct tcm_qla2xxx_lport, lport_wwn); | ||
1087 | struct scsi_qla_host *vha = lport->qla_vha; | ||
1088 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | ||
1089 | struct tcm_qla2xxx_tpg, se_tpg); | ||
1090 | unsigned long op; | ||
1091 | int rc; | ||
1092 | |||
1093 | rc = kstrtoul(page, 0, &op); | ||
1094 | if (rc < 0) { | ||
1095 | pr_err("kstrtoul() returned %d\n", rc); | ||
1096 | return -EINVAL; | ||
1097 | } | ||
1098 | if ((op != 1) && (op != 0)) { | ||
1099 | pr_err("Illegal value for tpg_enable: %lu\n", op); | ||
1100 | return -EINVAL; | ||
1101 | } | ||
1102 | if (op) { | ||
1103 | if (atomic_read(&tpg->lport_tpg_enabled)) | ||
1104 | return -EEXIST; | ||
1105 | |||
1106 | atomic_set(&tpg->lport_tpg_enabled, 1); | ||
1107 | qlt_enable_vha(vha); | ||
1108 | } else { | ||
1109 | if (!atomic_read(&tpg->lport_tpg_enabled)) | ||
1110 | return count; | ||
1111 | |||
1112 | atomic_set(&tpg->lport_tpg_enabled, 0); | ||
1113 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); | ||
1114 | } | ||
1115 | |||
1116 | return count; | ||
1117 | } | ||
1118 | |||
1119 | TF_TPG_BASE_ATTR(tcm_qla2xxx_npiv, enable, S_IRUGO | S_IWUSR); | ||
1120 | |||
1121 | static struct configfs_attribute *tcm_qla2xxx_npiv_tpg_attrs[] = { | ||
1122 | &tcm_qla2xxx_npiv_tpg_enable.attr, | ||
1123 | NULL, | ||
1124 | }; | ||
1125 | |||
1061 | static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( | 1126 | static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( |
1062 | struct se_wwn *wwn, | 1127 | struct se_wwn *wwn, |
1063 | struct config_group *group, | 1128 | struct config_group *group, |
@@ -1650,6 +1715,9 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1650 | struct scsi_qla_host *npiv_vha; | 1715 | struct scsi_qla_host *npiv_vha; |
1651 | struct tcm_qla2xxx_lport *lport = | 1716 | struct tcm_qla2xxx_lport *lport = |
1652 | (struct tcm_qla2xxx_lport *)target_lport_ptr; | 1717 | (struct tcm_qla2xxx_lport *)target_lport_ptr; |
1718 | struct tcm_qla2xxx_lport *base_lport = | ||
1719 | (struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr; | ||
1720 | struct tcm_qla2xxx_tpg *base_tpg; | ||
1653 | struct fc_vport_identifiers vport_id; | 1721 | struct fc_vport_identifiers vport_id; |
1654 | 1722 | ||
1655 | if (!qla_tgt_mode_enabled(base_vha)) { | 1723 | if (!qla_tgt_mode_enabled(base_vha)) { |
@@ -1657,6 +1725,13 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1657 | return -EPERM; | 1725 | return -EPERM; |
1658 | } | 1726 | } |
1659 | 1727 | ||
1728 | if (!base_lport || !base_lport->tpg_1 || | ||
1729 | !atomic_read(&base_lport->tpg_1->lport_tpg_enabled)) { | ||
1730 | pr_err("qla2xxx base_lport or tpg_1 not available\n"); | ||
1731 | return -EPERM; | ||
1732 | } | ||
1733 | base_tpg = base_lport->tpg_1; | ||
1734 | |||
1660 | memset(&vport_id, 0, sizeof(vport_id)); | 1735 | memset(&vport_id, 0, sizeof(vport_id)); |
1661 | vport_id.port_name = npiv_wwpn; | 1736 | vport_id.port_name = npiv_wwpn; |
1662 | vport_id.node_name = npiv_wwnn; | 1737 | vport_id.node_name = npiv_wwnn; |
@@ -1675,7 +1750,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1675 | npiv_vha = (struct scsi_qla_host *)vport->dd_data; | 1750 | npiv_vha = (struct scsi_qla_host *)vport->dd_data; |
1676 | npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr; | 1751 | npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr; |
1677 | lport->qla_vha = npiv_vha; | 1752 | lport->qla_vha = npiv_vha; |
1678 | |||
1679 | scsi_host_get(npiv_vha->host); | 1753 | scsi_host_get(npiv_vha->host); |
1680 | return 0; | 1754 | return 0; |
1681 | } | 1755 | } |
@@ -1714,8 +1788,6 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | |||
1714 | } | 1788 | } |
1715 | lport->lport_npiv_wwpn = npiv_wwpn; | 1789 | lport->lport_npiv_wwpn = npiv_wwpn; |
1716 | lport->lport_npiv_wwnn = npiv_wwnn; | 1790 | lport->lport_npiv_wwnn = npiv_wwnn; |
1717 | tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], | ||
1718 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); | ||
1719 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); | 1791 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); |
1720 | 1792 | ||
1721 | ret = tcm_qla2xxx_init_lport(lport); | 1793 | ret = tcm_qla2xxx_init_lport(lport); |
@@ -1824,7 +1896,7 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { | |||
1824 | static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | 1896 | static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { |
1825 | .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, | 1897 | .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, |
1826 | .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, | 1898 | .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, |
1827 | .tpg_get_wwn = tcm_qla2xxx_npiv_get_fabric_wwn, | 1899 | .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, |
1828 | .tpg_get_tag = tcm_qla2xxx_get_tag, | 1900 | .tpg_get_tag = tcm_qla2xxx_get_tag, |
1829 | .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, | 1901 | .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, |
1830 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, | 1902 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, |
@@ -1935,7 +2007,7 @@ static int tcm_qla2xxx_register_configfs(void) | |||
1935 | */ | 2007 | */ |
1936 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; | 2008 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; |
1937 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = | 2009 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = |
1938 | tcm_qla2xxx_tpg_attrs; | 2010 | tcm_qla2xxx_npiv_tpg_attrs; |
1939 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | 2011 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; |
1940 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | 2012 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; |
1941 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | 2013 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 275d8b9a7a34..33aaac8c7d59 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h | |||
@@ -4,8 +4,6 @@ | |||
4 | #define TCM_QLA2XXX_VERSION "v0.1" | 4 | #define TCM_QLA2XXX_VERSION "v0.1" |
5 | /* length of ASCII WWPNs including pad */ | 5 | /* length of ASCII WWPNs including pad */ |
6 | #define TCM_QLA2XXX_NAMELEN 32 | 6 | #define TCM_QLA2XXX_NAMELEN 32 |
7 | /* lenth of ASCII NPIV 'WWPN+WWNN' including pad */ | ||
8 | #define TCM_QLA2XXX_NPIV_NAMELEN 66 | ||
9 | 7 | ||
10 | #include "qla_target.h" | 8 | #include "qla_target.h" |
11 | 9 | ||
@@ -43,6 +41,9 @@ struct tcm_qla2xxx_tpg { | |||
43 | struct tcm_qla2xxx_tpg_attrib tpg_attrib; | 41 | struct tcm_qla2xxx_tpg_attrib tpg_attrib; |
44 | /* Returned by tcm_qla2xxx_make_tpg() */ | 42 | /* Returned by tcm_qla2xxx_make_tpg() */ |
45 | struct se_portal_group se_tpg; | 43 | struct se_portal_group se_tpg; |
44 | /* Items for dealing with configfs_depend_item */ | ||
45 | struct completion tpg_base_comp; | ||
46 | struct work_struct tpg_base_work; | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | struct tcm_qla2xxx_fc_loopid { | 49 | struct tcm_qla2xxx_fc_loopid { |
@@ -62,8 +63,6 @@ struct tcm_qla2xxx_lport { | |||
62 | char lport_name[TCM_QLA2XXX_NAMELEN]; | 63 | char lport_name[TCM_QLA2XXX_NAMELEN]; |
63 | /* ASCII formatted naa WWPN for VPD page 83 etc */ | 64 | /* ASCII formatted naa WWPN for VPD page 83 etc */ |
64 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; | 65 | char lport_naa_name[TCM_QLA2XXX_NAMELEN]; |
65 | /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ | ||
66 | char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; | ||
67 | /* map for fc_port pointers in 24-bit FC Port ID space */ | 66 | /* map for fc_port pointers in 24-bit FC Port ID space */ |
68 | struct btree_head32 lport_fcport_map; | 67 | struct btree_head32 lport_fcport_map; |
69 | /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ | 68 | /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7bd7f0d5f050..62ec84b42e31 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1684,7 +1684,7 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) | |||
1684 | 1684 | ||
1685 | host_dev = scsi_get_device(shost); | 1685 | host_dev = scsi_get_device(shost); |
1686 | if (host_dev && host_dev->dma_mask) | 1686 | if (host_dev && host_dev->dma_mask) |
1687 | bounce_limit = dma_max_pfn(host_dev) << PAGE_SHIFT; | 1687 | bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT; |
1688 | 1688 | ||
1689 | return bounce_limit; | 1689 | return bounce_limit; |
1690 | } | 1690 | } |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 17d740427240..9969fa1ef7c4 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
@@ -1419,6 +1419,9 @@ static void storvsc_device_destroy(struct scsi_device *sdevice) | |||
1419 | { | 1419 | { |
1420 | struct stor_mem_pools *memp = sdevice->hostdata; | 1420 | struct stor_mem_pools *memp = sdevice->hostdata; |
1421 | 1421 | ||
1422 | if (!memp) | ||
1423 | return; | ||
1424 | |||
1422 | mempool_destroy(memp->request_mempool); | 1425 | mempool_destroy(memp->request_mempool); |
1423 | kmem_cache_destroy(memp->request_pool); | 1426 | kmem_cache_destroy(memp->request_pool); |
1424 | kfree(memp); | 1427 | kfree(memp); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ba9310bc9acb..581ee2a8856b 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -376,10 +376,10 @@ config SPI_PXA2XX_PCI | |||
376 | def_tristate SPI_PXA2XX && PCI | 376 | def_tristate SPI_PXA2XX && PCI |
377 | 377 | ||
378 | config SPI_RSPI | 378 | config SPI_RSPI |
379 | tristate "Renesas RSPI controller" | 379 | tristate "Renesas RSPI/QSPI controller" |
380 | depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE | 380 | depends on (SUPERH && SH_DMAE_BASE) || ARCH_SHMOBILE |
381 | help | 381 | help |
382 | SPI driver for Renesas RSPI blocks. | 382 | SPI driver for Renesas RSPI and QSPI blocks. |
383 | 383 | ||
384 | config SPI_S3C24XX | 384 | config SPI_S3C24XX |
385 | tristate "Samsung S3C24XX series SPI" | 385 | tristate "Samsung S3C24XX series SPI" |
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 31534b51715a..c3b2fb9b6713 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
@@ -132,9 +132,9 @@ static int ath79_spi_setup_cs(struct spi_device *spi) | |||
132 | 132 | ||
133 | flags = GPIOF_DIR_OUT; | 133 | flags = GPIOF_DIR_OUT; |
134 | if (spi->mode & SPI_CS_HIGH) | 134 | if (spi->mode & SPI_CS_HIGH) |
135 | flags |= GPIOF_INIT_HIGH; | ||
136 | else | ||
137 | flags |= GPIOF_INIT_LOW; | 135 | flags |= GPIOF_INIT_LOW; |
136 | else | ||
137 | flags |= GPIOF_INIT_HIGH; | ||
138 | 138 | ||
139 | status = gpio_request_one(cdata->gpio, flags, | 139 | status = gpio_request_one(cdata->gpio, flags, |
140 | dev_name(&spi->dev)); | 140 | dev_name(&spi->dev)); |
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index b0842f751016..bc879930470b 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/pinctrl/consumer.h> | ||
29 | 30 | ||
30 | /* SPI register offsets */ | 31 | /* SPI register offsets */ |
31 | #define SPI_CR 0x0000 | 32 | #define SPI_CR 0x0000 |
@@ -1087,14 +1088,6 @@ static int atmel_spi_one_transfer(struct spi_master *master, | |||
1087 | } | 1088 | } |
1088 | } | 1089 | } |
1089 | 1090 | ||
1090 | if (xfer->bits_per_word > 8) { | ||
1091 | if (xfer->len % 2) { | ||
1092 | dev_dbg(&spi->dev, | ||
1093 | "buffer len should be 16 bits aligned\n"); | ||
1094 | return -EINVAL; | ||
1095 | } | ||
1096 | } | ||
1097 | |||
1098 | /* | 1091 | /* |
1099 | * DMA map early, for performance (empties dcache ASAP) and | 1092 | * DMA map early, for performance (empties dcache ASAP) and |
1100 | * better fault reporting. | 1093 | * better fault reporting. |
@@ -1221,9 +1214,6 @@ static int atmel_spi_transfer_one_message(struct spi_master *master, | |||
1221 | dev_dbg(&spi->dev, "new message %p submitted for %s\n", | 1214 | dev_dbg(&spi->dev, "new message %p submitted for %s\n", |
1222 | msg, dev_name(&spi->dev)); | 1215 | msg, dev_name(&spi->dev)); |
1223 | 1216 | ||
1224 | if (unlikely(list_empty(&msg->transfers))) | ||
1225 | return -EINVAL; | ||
1226 | |||
1227 | atmel_spi_lock(as); | 1217 | atmel_spi_lock(as); |
1228 | cs_activate(as, spi); | 1218 | cs_activate(as, spi); |
1229 | 1219 | ||
@@ -1244,10 +1234,10 @@ static int atmel_spi_transfer_one_message(struct spi_master *master, | |||
1244 | 1234 | ||
1245 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | 1235 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
1246 | dev_dbg(&spi->dev, | 1236 | dev_dbg(&spi->dev, |
1247 | " xfer %p: len %u tx %p/%08x rx %p/%08x\n", | 1237 | " xfer %p: len %u tx %p/%pad rx %p/%pad\n", |
1248 | xfer, xfer->len, | 1238 | xfer, xfer->len, |
1249 | xfer->tx_buf, xfer->tx_dma, | 1239 | xfer->tx_buf, &xfer->tx_dma, |
1250 | xfer->rx_buf, xfer->rx_dma); | 1240 | xfer->rx_buf, &xfer->rx_dma); |
1251 | } | 1241 | } |
1252 | 1242 | ||
1253 | msg_done: | 1243 | msg_done: |
@@ -1303,6 +1293,9 @@ static int atmel_spi_probe(struct platform_device *pdev) | |||
1303 | struct spi_master *master; | 1293 | struct spi_master *master; |
1304 | struct atmel_spi *as; | 1294 | struct atmel_spi *as; |
1305 | 1295 | ||
1296 | /* Select default pin state */ | ||
1297 | pinctrl_pm_select_default_state(&pdev->dev); | ||
1298 | |||
1306 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1299 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1307 | if (!regs) | 1300 | if (!regs) |
1308 | return -ENXIO; | 1301 | return -ENXIO; |
@@ -1455,8 +1448,19 @@ static int atmel_spi_suspend(struct device *dev) | |||
1455 | { | 1448 | { |
1456 | struct spi_master *master = dev_get_drvdata(dev); | 1449 | struct spi_master *master = dev_get_drvdata(dev); |
1457 | struct atmel_spi *as = spi_master_get_devdata(master); | 1450 | struct atmel_spi *as = spi_master_get_devdata(master); |
1451 | int ret; | ||
1452 | |||
1453 | /* Stop the queue running */ | ||
1454 | ret = spi_master_suspend(master); | ||
1455 | if (ret) { | ||
1456 | dev_warn(dev, "cannot suspend master\n"); | ||
1457 | return ret; | ||
1458 | } | ||
1458 | 1459 | ||
1459 | clk_disable_unprepare(as->clk); | 1460 | clk_disable_unprepare(as->clk); |
1461 | |||
1462 | pinctrl_pm_select_sleep_state(dev); | ||
1463 | |||
1460 | return 0; | 1464 | return 0; |
1461 | } | 1465 | } |
1462 | 1466 | ||
@@ -1464,9 +1468,18 @@ static int atmel_spi_resume(struct device *dev) | |||
1464 | { | 1468 | { |
1465 | struct spi_master *master = dev_get_drvdata(dev); | 1469 | struct spi_master *master = dev_get_drvdata(dev); |
1466 | struct atmel_spi *as = spi_master_get_devdata(master); | 1470 | struct atmel_spi *as = spi_master_get_devdata(master); |
1471 | int ret; | ||
1472 | |||
1473 | pinctrl_pm_select_default_state(dev); | ||
1467 | 1474 | ||
1468 | clk_prepare_enable(as->clk); | 1475 | clk_prepare_enable(as->clk); |
1469 | return 0; | 1476 | |
1477 | /* Start the queue running */ | ||
1478 | ret = spi_master_resume(master); | ||
1479 | if (ret) | ||
1480 | dev_err(dev, "problem starting queue (%d)\n", ret); | ||
1481 | |||
1482 | return ret; | ||
1470 | } | 1483 | } |
1471 | 1484 | ||
1472 | static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume); | 1485 | static SIMPLE_DEV_PM_OPS(atmel_spi_pm_ops, atmel_spi_suspend, atmel_spi_resume); |
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index c4141c92bcff..aafb812d7ea6 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c | |||
@@ -55,8 +55,6 @@ struct au1550_spi { | |||
55 | 55 | ||
56 | volatile psc_spi_t __iomem *regs; | 56 | volatile psc_spi_t __iomem *regs; |
57 | int irq; | 57 | int irq; |
58 | unsigned freq_max; | ||
59 | unsigned freq_min; | ||
60 | 58 | ||
61 | unsigned len; | 59 | unsigned len; |
62 | unsigned tx_count; | 60 | unsigned tx_count; |
@@ -248,11 +246,8 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | |||
248 | hz = t->speed_hz; | 246 | hz = t->speed_hz; |
249 | } | 247 | } |
250 | 248 | ||
251 | if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) { | 249 | if (!hz) |
252 | dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n", | ||
253 | hz); | ||
254 | return -EINVAL; | 250 | return -EINVAL; |
255 | } | ||
256 | 251 | ||
257 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); | 252 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); |
258 | 253 | ||
@@ -287,23 +282,6 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | |||
287 | return 0; | 282 | return 0; |
288 | } | 283 | } |
289 | 284 | ||
290 | static int au1550_spi_setup(struct spi_device *spi) | ||
291 | { | ||
292 | struct au1550_spi *hw = spi_master_get_devdata(spi->master); | ||
293 | |||
294 | if (spi->max_speed_hz == 0) | ||
295 | spi->max_speed_hz = hw->freq_max; | ||
296 | if (spi->max_speed_hz > hw->freq_max | ||
297 | || spi->max_speed_hz < hw->freq_min) | ||
298 | return -EINVAL; | ||
299 | /* | ||
300 | * NOTE: cannot change speed and other hw settings immediately, | ||
301 | * otherwise sharing of spi bus is not possible, | ||
302 | * so do not call setupxfer(spi, NULL) here | ||
303 | */ | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* | 285 | /* |
308 | * for dma spi transfers, we have to setup rx channel, otherwise there is | 286 | * for dma spi transfers, we have to setup rx channel, otherwise there is |
309 | * no reliable way how to recognize that spi transfer is done | 287 | * no reliable way how to recognize that spi transfer is done |
@@ -838,7 +816,6 @@ static int au1550_spi_probe(struct platform_device *pdev) | |||
838 | hw->bitbang.master = hw->master; | 816 | hw->bitbang.master = hw->master; |
839 | hw->bitbang.setup_transfer = au1550_spi_setupxfer; | 817 | hw->bitbang.setup_transfer = au1550_spi_setupxfer; |
840 | hw->bitbang.chipselect = au1550_spi_chipsel; | 818 | hw->bitbang.chipselect = au1550_spi_chipsel; |
841 | hw->bitbang.master->setup = au1550_spi_setup; | ||
842 | hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; | 819 | hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; |
843 | 820 | ||
844 | if (hw->usedma) { | 821 | if (hw->usedma) { |
@@ -909,8 +886,9 @@ static int au1550_spi_probe(struct platform_device *pdev) | |||
909 | { | 886 | { |
910 | int min_div = (2 << 0) * (2 * (4 + 1)); | 887 | int min_div = (2 << 0) * (2 * (4 + 1)); |
911 | int max_div = (2 << 3) * (2 * (63 + 1)); | 888 | int max_div = (2 << 3) * (2 * (63 + 1)); |
912 | hw->freq_max = hw->pdata->mainclk_hz / min_div; | 889 | master->max_speed_hz = hw->pdata->mainclk_hz / min_div; |
913 | hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1; | 890 | master->min_speed_hz = |
891 | hw->pdata->mainclk_hz / (max_div + 1) + 1; | ||
914 | } | 892 | } |
915 | 893 | ||
916 | au1550_spi_setup_psc_as_spi(hw); | 894 | au1550_spi_setup_psc_as_spi(hw); |
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index b528f9fc8bc0..13bbce349ed9 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c | |||
@@ -453,9 +453,8 @@ static int bcm63xx_hsspi_resume(struct device *dev) | |||
453 | } | 453 | } |
454 | #endif | 454 | #endif |
455 | 455 | ||
456 | static const struct dev_pm_ops bcm63xx_hsspi_pm_ops = { | 456 | static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, |
457 | SET_SYSTEM_SLEEP_PM_OPS(bcm63xx_hsspi_suspend, bcm63xx_hsspi_resume) | 457 | bcm63xx_hsspi_resume); |
458 | }; | ||
459 | 458 | ||
460 | static struct platform_driver bcm63xx_hsspi_driver = { | 459 | static struct platform_driver bcm63xx_hsspi_driver = { |
461 | .driver = { | 460 | .driver = { |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 77286aef2adf..b3d719a9667a 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -35,8 +35,6 @@ | |||
35 | 35 | ||
36 | #include <bcm63xx_dev_spi.h> | 36 | #include <bcm63xx_dev_spi.h> |
37 | 37 | ||
38 | #define PFX KBUILD_MODNAME | ||
39 | |||
40 | #define BCM63XX_SPI_MAX_PREPEND 15 | 38 | #define BCM63XX_SPI_MAX_PREPEND 15 |
41 | 39 | ||
42 | struct bcm63xx_spi { | 40 | struct bcm63xx_spi { |
diff --git a/drivers/spi/spi-bfin-v3.c b/drivers/spi/spi-bfin-v3.c index 8f8598834b30..4089d0e0d84e 100644 --- a/drivers/spi/spi-bfin-v3.c +++ b/drivers/spi/spi-bfin-v3.c | |||
@@ -822,7 +822,8 @@ static int bfin_spi_probe(struct platform_device *pdev) | |||
822 | master->cleanup = bfin_spi_cleanup; | 822 | master->cleanup = bfin_spi_cleanup; |
823 | master->setup = bfin_spi_setup; | 823 | master->setup = bfin_spi_setup; |
824 | master->transfer_one_message = bfin_spi_transfer_one_message; | 824 | master->transfer_one_message = bfin_spi_transfer_one_message; |
825 | master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); | 825 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | |
826 | SPI_BPW_MASK(8); | ||
826 | 827 | ||
827 | drv_data = spi_master_get_devdata(master); | 828 | drv_data = spi_master_get_devdata(master); |
828 | drv_data->master = master; | 829 | drv_data->master = master; |
diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index f0f195af75d4..55e57c3eb9bd 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c | |||
@@ -350,7 +350,6 @@ static void *bfin_spi_next_transfer(struct bfin_spi_master_data *drv_data) | |||
350 | static void bfin_spi_giveback(struct bfin_spi_master_data *drv_data) | 350 | static void bfin_spi_giveback(struct bfin_spi_master_data *drv_data) |
351 | { | 351 | { |
352 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; | 352 | struct bfin_spi_slave_data *chip = drv_data->cur_chip; |
353 | struct spi_transfer *last_transfer; | ||
354 | unsigned long flags; | 353 | unsigned long flags; |
355 | struct spi_message *msg; | 354 | struct spi_message *msg; |
356 | 355 | ||
@@ -362,9 +361,6 @@ static void bfin_spi_giveback(struct bfin_spi_master_data *drv_data) | |||
362 | queue_work(drv_data->workqueue, &drv_data->pump_messages); | 361 | queue_work(drv_data->workqueue, &drv_data->pump_messages); |
363 | spin_unlock_irqrestore(&drv_data->lock, flags); | 362 | spin_unlock_irqrestore(&drv_data->lock, flags); |
364 | 363 | ||
365 | last_transfer = list_entry(msg->transfers.prev, | ||
366 | struct spi_transfer, transfer_list); | ||
367 | |||
368 | msg->state = NULL; | 364 | msg->state = NULL; |
369 | 365 | ||
370 | if (!drv_data->cs_change) | 366 | if (!drv_data->cs_change) |
@@ -1030,10 +1026,6 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
1030 | } | 1026 | } |
1031 | 1027 | ||
1032 | /* translate common spi framework into our register */ | 1028 | /* translate common spi framework into our register */ |
1033 | if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { | ||
1034 | dev_err(&spi->dev, "unsupported spi modes detected\n"); | ||
1035 | goto error; | ||
1036 | } | ||
1037 | if (spi->mode & SPI_CPOL) | 1029 | if (spi->mode & SPI_CPOL) |
1038 | chip->ctl_reg |= BIT_CTL_CPOL; | 1030 | chip->ctl_reg |= BIT_CTL_CPOL; |
1039 | if (spi->mode & SPI_CPHA) | 1031 | if (spi->mode & SPI_CPHA) |
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index bd222f6b677d..67aead248753 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
@@ -467,11 +467,9 @@ EXPORT_SYMBOL_GPL(spi_bitbang_start); | |||
467 | /** | 467 | /** |
468 | * spi_bitbang_stop - stops the task providing spi communication | 468 | * spi_bitbang_stop - stops the task providing spi communication |
469 | */ | 469 | */ |
470 | int spi_bitbang_stop(struct spi_bitbang *bitbang) | 470 | void spi_bitbang_stop(struct spi_bitbang *bitbang) |
471 | { | 471 | { |
472 | spi_unregister_master(bitbang->master); | 472 | spi_unregister_master(bitbang->master); |
473 | |||
474 | return 0; | ||
475 | } | 473 | } |
476 | EXPORT_SYMBOL_GPL(spi_bitbang_stop); | 474 | EXPORT_SYMBOL_GPL(spi_bitbang_stop); |
477 | 475 | ||
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 8081f96bd1d5..ee4f91ccd8fd 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c | |||
@@ -309,7 +309,6 @@ done: | |||
309 | static void butterfly_detach(struct parport *p) | 309 | static void butterfly_detach(struct parport *p) |
310 | { | 310 | { |
311 | struct butterfly *pp; | 311 | struct butterfly *pp; |
312 | int status; | ||
313 | 312 | ||
314 | /* FIXME this global is ugly ... but, how to quickly get from | 313 | /* FIXME this global is ugly ... but, how to quickly get from |
315 | * the parport to the "struct butterfly" associated with it? | 314 | * the parport to the "struct butterfly" associated with it? |
@@ -321,7 +320,7 @@ static void butterfly_detach(struct parport *p) | |||
321 | butterfly = NULL; | 320 | butterfly = NULL; |
322 | 321 | ||
323 | /* stop() unregisters child devices too */ | 322 | /* stop() unregisters child devices too */ |
324 | status = spi_bitbang_stop(&pp->bitbang); | 323 | spi_bitbang_stop(&pp->bitbang); |
325 | 324 | ||
326 | /* turn off VCC */ | 325 | /* turn off VCC */ |
327 | parport_write_data(pp->port, 0); | 326 | parport_write_data(pp->port, 0); |
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index cabed8f9119e..28ae470397a9 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
@@ -514,7 +514,8 @@ static int mcfqspi_resume(struct device *dev) | |||
514 | #ifdef CONFIG_PM_RUNTIME | 514 | #ifdef CONFIG_PM_RUNTIME |
515 | static int mcfqspi_runtime_suspend(struct device *dev) | 515 | static int mcfqspi_runtime_suspend(struct device *dev) |
516 | { | 516 | { |
517 | struct mcfqspi *mcfqspi = dev_get_drvdata(dev); | 517 | struct spi_master *master = dev_get_drvdata(dev); |
518 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | ||
518 | 519 | ||
519 | clk_disable(mcfqspi->clk); | 520 | clk_disable(mcfqspi->clk); |
520 | 521 | ||
@@ -523,7 +524,8 @@ static int mcfqspi_runtime_suspend(struct device *dev) | |||
523 | 524 | ||
524 | static int mcfqspi_runtime_resume(struct device *dev) | 525 | static int mcfqspi_runtime_resume(struct device *dev) |
525 | { | 526 | { |
526 | struct mcfqspi *mcfqspi = dev_get_drvdata(dev); | 527 | struct spi_master *master = dev_get_drvdata(dev); |
528 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | ||
527 | 529 | ||
528 | clk_enable(mcfqspi->clk); | 530 | clk_enable(mcfqspi->clk); |
529 | 531 | ||
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index ec79f726672a..a25392065d9b 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
@@ -420,7 +420,6 @@ static int dspi_suspend(struct device *dev) | |||
420 | 420 | ||
421 | static int dspi_resume(struct device *dev) | 421 | static int dspi_resume(struct device *dev) |
422 | { | 422 | { |
423 | |||
424 | struct spi_master *master = dev_get_drvdata(dev); | 423 | struct spi_master *master = dev_get_drvdata(dev); |
425 | struct fsl_dspi *dspi = spi_master_get_devdata(master); | 424 | struct fsl_dspi *dspi = spi_master_get_devdata(master); |
426 | 425 | ||
@@ -504,7 +503,7 @@ static int dspi_probe(struct platform_device *pdev) | |||
504 | clk_prepare_enable(dspi->clk); | 503 | clk_prepare_enable(dspi->clk); |
505 | 504 | ||
506 | init_waitqueue_head(&dspi->waitq); | 505 | init_waitqueue_head(&dspi->waitq); |
507 | platform_set_drvdata(pdev, dspi); | 506 | platform_set_drvdata(pdev, master); |
508 | 507 | ||
509 | ret = spi_bitbang_start(&dspi->bitbang); | 508 | ret = spi_bitbang_start(&dspi->bitbang); |
510 | if (ret != 0) { | 509 | if (ret != 0) { |
@@ -525,7 +524,8 @@ out_master_put: | |||
525 | 524 | ||
526 | static int dspi_remove(struct platform_device *pdev) | 525 | static int dspi_remove(struct platform_device *pdev) |
527 | { | 526 | { |
528 | struct fsl_dspi *dspi = platform_get_drvdata(pdev); | 527 | struct spi_master *master = platform_get_drvdata(pdev); |
528 | struct fsl_dspi *dspi = spi_master_get_devdata(master); | ||
529 | 529 | ||
530 | /* Disconnect from the SPI framework */ | 530 | /* Disconnect from the SPI framework */ |
531 | spi_bitbang_stop(&dspi->bitbang); | 531 | spi_bitbang_stop(&dspi->bitbang); |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 7beeb29472ac..b189b958432b 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -503,13 +503,12 @@ static int spi_gpio_remove(struct platform_device *pdev) | |||
503 | { | 503 | { |
504 | struct spi_gpio *spi_gpio; | 504 | struct spi_gpio *spi_gpio; |
505 | struct spi_gpio_platform_data *pdata; | 505 | struct spi_gpio_platform_data *pdata; |
506 | int status; | ||
507 | 506 | ||
508 | spi_gpio = platform_get_drvdata(pdev); | 507 | spi_gpio = platform_get_drvdata(pdev); |
509 | pdata = dev_get_platdata(&pdev->dev); | 508 | pdata = dev_get_platdata(&pdev->dev); |
510 | 509 | ||
511 | /* stop() unregisters child devices too */ | 510 | /* stop() unregisters child devices too */ |
512 | status = spi_bitbang_stop(&spi_gpio->bitbang); | 511 | spi_bitbang_stop(&spi_gpio->bitbang); |
513 | 512 | ||
514 | if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) | 513 | if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) |
515 | gpio_free(SPI_MISO_GPIO); | 514 | gpio_free(SPI_MISO_GPIO); |
@@ -518,7 +517,7 @@ static int spi_gpio_remove(struct platform_device *pdev) | |||
518 | gpio_free(SPI_SCK_GPIO); | 517 | gpio_free(SPI_SCK_GPIO); |
519 | spi_master_put(spi_gpio->bitbang.master); | 518 | spi_master_put(spi_gpio->bitbang.master); |
520 | 519 | ||
521 | return status; | 520 | return 0; |
522 | } | 521 | } |
523 | 522 | ||
524 | MODULE_ALIAS("platform:" DRIVER_NAME); | 523 | MODULE_ALIAS("platform:" DRIVER_NAME); |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index a5474ef9d2a0..47f15d97e7fa 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -948,8 +948,8 @@ static int spi_imx_remove(struct platform_device *pdev) | |||
948 | spi_bitbang_stop(&spi_imx->bitbang); | 948 | spi_bitbang_stop(&spi_imx->bitbang); |
949 | 949 | ||
950 | writel(0, spi_imx->base + MXC_CSPICTRL); | 950 | writel(0, spi_imx->base + MXC_CSPICTRL); |
951 | clk_disable_unprepare(spi_imx->clk_ipg); | 951 | clk_unprepare(spi_imx->clk_ipg); |
952 | clk_disable_unprepare(spi_imx->clk_per); | 952 | clk_unprepare(spi_imx->clk_per); |
953 | spi_master_put(master); | 953 | spi_master_put(master); |
954 | 954 | ||
955 | return 0; | 955 | return 0; |
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 50406306bc20..bae97ffec4b9 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
@@ -361,6 +361,8 @@ static int nuc900_spi_probe(struct platform_device *pdev) | |||
361 | init_completion(&hw->done); | 361 | init_completion(&hw->done); |
362 | 362 | ||
363 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 363 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
364 | if (hw->pdata->lsb) | ||
365 | master->mode_bits |= SPI_LSB_FIRST; | ||
364 | master->num_chipselect = hw->pdata->num_cs; | 366 | master->num_chipselect = hw->pdata->num_cs; |
365 | master->bus_num = hw->pdata->bus_num; | 367 | master->bus_num = hw->pdata->bus_num; |
366 | hw->bitbang.master = hw->master; | 368 | hw->bitbang.master = hw->master; |
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 9313fd3b413d..a4d7bb557792 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c | |||
@@ -539,14 +539,13 @@ static int uwire_probe(struct platform_device *pdev) | |||
539 | static int uwire_remove(struct platform_device *pdev) | 539 | static int uwire_remove(struct platform_device *pdev) |
540 | { | 540 | { |
541 | struct uwire_spi *uwire = platform_get_drvdata(pdev); | 541 | struct uwire_spi *uwire = platform_get_drvdata(pdev); |
542 | int status; | ||
543 | 542 | ||
544 | // FIXME remove all child devices, somewhere ... | 543 | // FIXME remove all child devices, somewhere ... |
545 | 544 | ||
546 | status = spi_bitbang_stop(&uwire->bitbang); | 545 | spi_bitbang_stop(&uwire->bitbang); |
547 | uwire_off(uwire); | 546 | uwire_off(uwire); |
548 | iounmap(uwire_base); | 547 | iounmap(uwire_base); |
549 | return status; | 548 | return 0; |
550 | } | 549 | } |
551 | 550 | ||
552 | /* work with hotplug and coldplug */ | 551 | /* work with hotplug and coldplug */ |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index ae907dde1371..25c9bd409a87 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -381,7 +381,7 @@ static void s3c64xx_spi_dma_stop(struct s3c64xx_spi_driver_data *sdd, | |||
381 | #else | 381 | #else |
382 | 382 | ||
383 | static void prepare_dma(struct s3c64xx_spi_dma_data *dma, | 383 | static void prepare_dma(struct s3c64xx_spi_dma_data *dma, |
384 | unsigned len, dma_addr_t buf) | 384 | struct sg_table *sgt) |
385 | { | 385 | { |
386 | struct s3c64xx_spi_driver_data *sdd; | 386 | struct s3c64xx_spi_driver_data *sdd; |
387 | struct dma_slave_config config; | 387 | struct dma_slave_config config; |
@@ -407,8 +407,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma, | |||
407 | dmaengine_slave_config(dma->ch, &config); | 407 | dmaengine_slave_config(dma->ch, &config); |
408 | } | 408 | } |
409 | 409 | ||
410 | desc = dmaengine_prep_slave_single(dma->ch, buf, len, | 410 | desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, |
411 | dma->direction, DMA_PREP_INTERRUPT); | 411 | dma->direction, DMA_PREP_INTERRUPT); |
412 | 412 | ||
413 | desc->callback = s3c64xx_spi_dmacb; | 413 | desc->callback = s3c64xx_spi_dmacb; |
414 | desc->callback_param = dma; | 414 | desc->callback_param = dma; |
@@ -515,7 +515,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | |||
515 | chcfg |= S3C64XX_SPI_CH_TXCH_ON; | 515 | chcfg |= S3C64XX_SPI_CH_TXCH_ON; |
516 | if (dma_mode) { | 516 | if (dma_mode) { |
517 | modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; | 517 | modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; |
518 | #ifndef CONFIG_S3C_DMA | ||
519 | prepare_dma(&sdd->tx_dma, &xfer->tx_sg); | ||
520 | #else | ||
518 | prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); | 521 | prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); |
522 | #endif | ||
519 | } else { | 523 | } else { |
520 | switch (sdd->cur_bpw) { | 524 | switch (sdd->cur_bpw) { |
521 | case 32: | 525 | case 32: |
@@ -547,7 +551,11 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | |||
547 | writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) | 551 | writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) |
548 | | S3C64XX_SPI_PACKET_CNT_EN, | 552 | | S3C64XX_SPI_PACKET_CNT_EN, |
549 | regs + S3C64XX_SPI_PACKET_CNT); | 553 | regs + S3C64XX_SPI_PACKET_CNT); |
554 | #ifndef CONFIG_S3C_DMA | ||
555 | prepare_dma(&sdd->rx_dma, &xfer->rx_sg); | ||
556 | #else | ||
550 | prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); | 557 | prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); |
558 | #endif | ||
551 | } | 559 | } |
552 | } | 560 | } |
553 | 561 | ||
@@ -555,23 +563,6 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | |||
555 | writel(chcfg, regs + S3C64XX_SPI_CH_CFG); | 563 | writel(chcfg, regs + S3C64XX_SPI_CH_CFG); |
556 | } | 564 | } |
557 | 565 | ||
558 | static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, | ||
559 | struct spi_device *spi) | ||
560 | { | ||
561 | if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ | ||
562 | if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ | ||
563 | /* Deselect the last toggled device */ | ||
564 | if (spi->cs_gpio >= 0) | ||
565 | gpio_set_value(spi->cs_gpio, | ||
566 | spi->mode & SPI_CS_HIGH ? 0 : 1); | ||
567 | } | ||
568 | sdd->tgl_spi = NULL; | ||
569 | } | ||
570 | |||
571 | if (spi->cs_gpio >= 0) | ||
572 | gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 1 : 0); | ||
573 | } | ||
574 | |||
575 | static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, | 566 | static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, |
576 | int timeout_ms) | 567 | int timeout_ms) |
577 | { | 568 | { |
@@ -593,112 +584,111 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, | |||
593 | return RX_FIFO_LVL(status, sdd); | 584 | return RX_FIFO_LVL(status, sdd); |
594 | } | 585 | } |
595 | 586 | ||
596 | static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, | 587 | static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd, |
597 | struct spi_transfer *xfer, int dma_mode) | 588 | struct spi_transfer *xfer) |
598 | { | 589 | { |
599 | void __iomem *regs = sdd->regs; | 590 | void __iomem *regs = sdd->regs; |
600 | unsigned long val; | 591 | unsigned long val; |
592 | u32 status; | ||
601 | int ms; | 593 | int ms; |
602 | 594 | ||
603 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ | 595 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ |
604 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; | 596 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; |
605 | ms += 10; /* some tolerance */ | 597 | ms += 10; /* some tolerance */ |
606 | 598 | ||
607 | if (dma_mode) { | 599 | val = msecs_to_jiffies(ms) + 10; |
608 | val = msecs_to_jiffies(ms) + 10; | 600 | val = wait_for_completion_timeout(&sdd->xfer_completion, val); |
609 | val = wait_for_completion_timeout(&sdd->xfer_completion, val); | 601 | |
610 | } else { | 602 | /* |
611 | u32 status; | 603 | * If the previous xfer was completed within timeout, then |
612 | val = msecs_to_loops(ms); | 604 | * proceed further else return -EIO. |
613 | do { | 605 | * DmaTx returns after simply writing data in the FIFO, |
606 | * w/o waiting for real transmission on the bus to finish. | ||
607 | * DmaRx returns only after Dma read data from FIFO which | ||
608 | * needs bus transmission to finish, so we don't worry if | ||
609 | * Xfer involved Rx(with or without Tx). | ||
610 | */ | ||
611 | if (val && !xfer->rx_buf) { | ||
612 | val = msecs_to_loops(10); | ||
613 | status = readl(regs + S3C64XX_SPI_STATUS); | ||
614 | while ((TX_FIFO_LVL(status, sdd) | ||
615 | || !S3C64XX_SPI_ST_TX_DONE(status, sdd)) | ||
616 | && --val) { | ||
617 | cpu_relax(); | ||
614 | status = readl(regs + S3C64XX_SPI_STATUS); | 618 | status = readl(regs + S3C64XX_SPI_STATUS); |
615 | } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); | 619 | } |
620 | |||
616 | } | 621 | } |
617 | 622 | ||
618 | if (dma_mode) { | 623 | /* If timed out while checking rx/tx status return error */ |
619 | u32 status; | 624 | if (!val) |
620 | 625 | return -EIO; | |
621 | /* | ||
622 | * If the previous xfer was completed within timeout, then | ||
623 | * proceed further else return -EIO. | ||
624 | * DmaTx returns after simply writing data in the FIFO, | ||
625 | * w/o waiting for real transmission on the bus to finish. | ||
626 | * DmaRx returns only after Dma read data from FIFO which | ||
627 | * needs bus transmission to finish, so we don't worry if | ||
628 | * Xfer involved Rx(with or without Tx). | ||
629 | */ | ||
630 | if (val && !xfer->rx_buf) { | ||
631 | val = msecs_to_loops(10); | ||
632 | status = readl(regs + S3C64XX_SPI_STATUS); | ||
633 | while ((TX_FIFO_LVL(status, sdd) | ||
634 | || !S3C64XX_SPI_ST_TX_DONE(status, sdd)) | ||
635 | && --val) { | ||
636 | cpu_relax(); | ||
637 | status = readl(regs + S3C64XX_SPI_STATUS); | ||
638 | } | ||
639 | 626 | ||
640 | } | 627 | return 0; |
628 | } | ||
641 | 629 | ||
642 | /* If timed out while checking rx/tx status return error */ | 630 | static int wait_for_pio(struct s3c64xx_spi_driver_data *sdd, |
643 | if (!val) | 631 | struct spi_transfer *xfer) |
644 | return -EIO; | 632 | { |
645 | } else { | 633 | void __iomem *regs = sdd->regs; |
646 | int loops; | 634 | unsigned long val; |
647 | u32 cpy_len; | 635 | u32 status; |
648 | u8 *buf; | 636 | int loops; |
649 | 637 | u32 cpy_len; | |
650 | /* If it was only Tx */ | 638 | u8 *buf; |
651 | if (!xfer->rx_buf) { | 639 | int ms; |
652 | sdd->state &= ~TXBUSY; | ||
653 | return 0; | ||
654 | } | ||
655 | 640 | ||
656 | /* | 641 | /* millisecs to xfer 'len' bytes @ 'cur_speed' */ |
657 | * If the receive length is bigger than the controller fifo | 642 | ms = xfer->len * 8 * 1000 / sdd->cur_speed; |
658 | * size, calculate the loops and read the fifo as many times. | 643 | ms += 10; /* some tolerance */ |
659 | * loops = length / max fifo size (calculated by using the | ||
660 | * fifo mask). | ||
661 | * For any size less than the fifo size the below code is | ||
662 | * executed atleast once. | ||
663 | */ | ||
664 | loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); | ||
665 | buf = xfer->rx_buf; | ||
666 | do { | ||
667 | /* wait for data to be received in the fifo */ | ||
668 | cpy_len = s3c64xx_spi_wait_for_timeout(sdd, | ||
669 | (loops ? ms : 0)); | ||
670 | 644 | ||
671 | switch (sdd->cur_bpw) { | 645 | val = msecs_to_loops(ms); |
672 | case 32: | 646 | do { |
673 | ioread32_rep(regs + S3C64XX_SPI_RX_DATA, | 647 | status = readl(regs + S3C64XX_SPI_STATUS); |
674 | buf, cpy_len / 4); | 648 | } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val); |
675 | break; | ||
676 | case 16: | ||
677 | ioread16_rep(regs + S3C64XX_SPI_RX_DATA, | ||
678 | buf, cpy_len / 2); | ||
679 | break; | ||
680 | default: | ||
681 | ioread8_rep(regs + S3C64XX_SPI_RX_DATA, | ||
682 | buf, cpy_len); | ||
683 | break; | ||
684 | } | ||
685 | 649 | ||
686 | buf = buf + cpy_len; | 650 | |
687 | } while (loops--); | 651 | /* If it was only Tx */ |
688 | sdd->state &= ~RXBUSY; | 652 | if (!xfer->rx_buf) { |
653 | sdd->state &= ~TXBUSY; | ||
654 | return 0; | ||
689 | } | 655 | } |
690 | 656 | ||
691 | return 0; | 657 | /* |
692 | } | 658 | * If the receive length is bigger than the controller fifo |
659 | * size, calculate the loops and read the fifo as many times. | ||
660 | * loops = length / max fifo size (calculated by using the | ||
661 | * fifo mask). | ||
662 | * For any size less than the fifo size the below code is | ||
663 | * executed atleast once. | ||
664 | */ | ||
665 | loops = xfer->len / ((FIFO_LVL_MASK(sdd) >> 1) + 1); | ||
666 | buf = xfer->rx_buf; | ||
667 | do { | ||
668 | /* wait for data to be received in the fifo */ | ||
669 | cpy_len = s3c64xx_spi_wait_for_timeout(sdd, | ||
670 | (loops ? ms : 0)); | ||
671 | |||
672 | switch (sdd->cur_bpw) { | ||
673 | case 32: | ||
674 | ioread32_rep(regs + S3C64XX_SPI_RX_DATA, | ||
675 | buf, cpy_len / 4); | ||
676 | break; | ||
677 | case 16: | ||
678 | ioread16_rep(regs + S3C64XX_SPI_RX_DATA, | ||
679 | buf, cpy_len / 2); | ||
680 | break; | ||
681 | default: | ||
682 | ioread8_rep(regs + S3C64XX_SPI_RX_DATA, | ||
683 | buf, cpy_len); | ||
684 | break; | ||
685 | } | ||
693 | 686 | ||
694 | static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, | 687 | buf = buf + cpy_len; |
695 | struct spi_device *spi) | 688 | } while (loops--); |
696 | { | 689 | sdd->state &= ~RXBUSY; |
697 | if (sdd->tgl_spi == spi) | ||
698 | sdd->tgl_spi = NULL; | ||
699 | 690 | ||
700 | if (spi->cs_gpio >= 0) | 691 | return 0; |
701 | gpio_set_value(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); | ||
702 | } | 692 | } |
703 | 693 | ||
704 | static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) | 694 | static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) |
@@ -929,7 +919,10 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, | |||
929 | 919 | ||
930 | spin_unlock_irqrestore(&sdd->lock, flags); | 920 | spin_unlock_irqrestore(&sdd->lock, flags); |
931 | 921 | ||
932 | status = wait_for_xfer(sdd, xfer, use_dma); | 922 | if (use_dma) |
923 | status = wait_for_dma(sdd, xfer); | ||
924 | else | ||
925 | status = wait_for_pio(sdd, xfer); | ||
933 | 926 | ||
934 | if (status) { | 927 | if (status) { |
935 | dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", | 928 | dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", |
@@ -1092,14 +1085,12 @@ static int s3c64xx_spi_setup(struct spi_device *spi) | |||
1092 | 1085 | ||
1093 | pm_runtime_put(&sdd->pdev->dev); | 1086 | pm_runtime_put(&sdd->pdev->dev); |
1094 | writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); | 1087 | writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); |
1095 | disable_cs(sdd, spi); | ||
1096 | return 0; | 1088 | return 0; |
1097 | 1089 | ||
1098 | setup_exit: | 1090 | setup_exit: |
1099 | pm_runtime_put(&sdd->pdev->dev); | 1091 | pm_runtime_put(&sdd->pdev->dev); |
1100 | /* setup() returns with device de-selected */ | 1092 | /* setup() returns with device de-selected */ |
1101 | writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); | 1093 | writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); |
1102 | disable_cs(sdd, spi); | ||
1103 | 1094 | ||
1104 | gpio_free(cs->line); | 1095 | gpio_free(cs->line); |
1105 | spi_set_ctldata(spi, NULL); | 1096 | spi_set_ctldata(spi, NULL); |
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 3d09265b5133..7eb2cef739b6 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c | |||
@@ -435,7 +435,8 @@ static int ti_qspi_probe(struct platform_device *pdev) | |||
435 | master->auto_runtime_pm = true; | 435 | master->auto_runtime_pm = true; |
436 | master->transfer_one_message = ti_qspi_start_transfer_one; | 436 | master->transfer_one_message = ti_qspi_start_transfer_one; |
437 | master->dev.of_node = pdev->dev.of_node; | 437 | master->dev.of_node = pdev->dev.of_node; |
438 | master->bits_per_word_mask = BIT(32 - 1) | BIT(16 - 1) | BIT(8 - 1); | 438 | master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | |
439 | SPI_BPW_MASK(8); | ||
439 | 440 | ||
440 | if (!of_property_read_u32(np, "num-cs", &num_cs)) | 441 | if (!of_property_read_u32(np, "num-cs", &num_cs)) |
441 | master->num_chipselect = num_cs; | 442 | master->num_chipselect = num_cs; |
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 2e7f38c7a961..88eb57e858b3 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c | |||
@@ -915,7 +915,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw) | |||
915 | /* Set Tx DMA */ | 915 | /* Set Tx DMA */ |
916 | param = &dma->param_tx; | 916 | param = &dma->param_tx; |
917 | param->dma_dev = &dma_dev->dev; | 917 | param->dma_dev = &dma_dev->dev; |
918 | param->chan_id = data->master->bus_num * 2; /* Tx = 0, 2 */ | 918 | param->chan_id = data->ch * 2; /* Tx = 0, 2 */; |
919 | param->tx_reg = data->io_base_addr + PCH_SPDWR; | 919 | param->tx_reg = data->io_base_addr + PCH_SPDWR; |
920 | param->width = width; | 920 | param->width = width; |
921 | chan = dma_request_channel(mask, pch_spi_filter, param); | 921 | chan = dma_request_channel(mask, pch_spi_filter, param); |
@@ -930,7 +930,7 @@ static void pch_spi_request_dma(struct pch_spi_data *data, int bpw) | |||
930 | /* Set Rx DMA */ | 930 | /* Set Rx DMA */ |
931 | param = &dma->param_rx; | 931 | param = &dma->param_rx; |
932 | param->dma_dev = &dma_dev->dev; | 932 | param->dma_dev = &dma_dev->dev; |
933 | param->chan_id = data->master->bus_num * 2 + 1; /* Rx = Tx + 1 */ | 933 | param->chan_id = data->ch * 2 + 1; /* Rx = Tx + 1 */; |
934 | param->rx_reg = data->io_base_addr + PCH_SPDRR; | 934 | param->rx_reg = data->io_base_addr + PCH_SPDRR; |
935 | param->width = width; | 935 | param->width = width; |
936 | chan = dma_request_channel(mask, pch_spi_filter, param); | 936 | chan = dma_request_channel(mask, pch_spi_filter, param); |
@@ -1452,6 +1452,11 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev) | |||
1452 | 1452 | ||
1453 | pch_spi_set_master_mode(master); | 1453 | pch_spi_set_master_mode(master); |
1454 | 1454 | ||
1455 | if (use_dma) { | ||
1456 | dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); | ||
1457 | pch_alloc_dma_buf(board_dat, data); | ||
1458 | } | ||
1459 | |||
1455 | ret = spi_register_master(master); | 1460 | ret = spi_register_master(master); |
1456 | if (ret != 0) { | 1461 | if (ret != 0) { |
1457 | dev_err(&plat_dev->dev, | 1462 | dev_err(&plat_dev->dev, |
@@ -1459,14 +1464,10 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev) | |||
1459 | goto err_spi_register_master; | 1464 | goto err_spi_register_master; |
1460 | } | 1465 | } |
1461 | 1466 | ||
1462 | if (use_dma) { | ||
1463 | dev_info(&plat_dev->dev, "Use DMA for data transfers\n"); | ||
1464 | pch_alloc_dma_buf(board_dat, data); | ||
1465 | } | ||
1466 | |||
1467 | return 0; | 1467 | return 0; |
1468 | 1468 | ||
1469 | err_spi_register_master: | 1469 | err_spi_register_master: |
1470 | pch_free_dma_buf(board_dat, data); | ||
1470 | free_irq(board_dat->pdev->irq, data); | 1471 | free_irq(board_dat->pdev->irq, data); |
1471 | err_request_irq: | 1472 | err_request_irq: |
1472 | pch_spi_free_resources(board_dat, data); | 1473 | pch_spi_free_resources(board_dat, data); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 23756b0f9036..32e4603d5fc8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/cache.h> | 26 | #include <linux/cache.h> |
27 | #include <linux/dma-mapping.h> | ||
28 | #include <linux/dmaengine.h> | ||
27 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
28 | #include <linux/of_device.h> | 30 | #include <linux/of_device.h> |
29 | #include <linux/of_irq.h> | 31 | #include <linux/of_irq.h> |
@@ -255,13 +257,12 @@ EXPORT_SYMBOL_GPL(spi_bus_type); | |||
255 | static int spi_drv_probe(struct device *dev) | 257 | static int spi_drv_probe(struct device *dev) |
256 | { | 258 | { |
257 | const struct spi_driver *sdrv = to_spi_driver(dev->driver); | 259 | const struct spi_driver *sdrv = to_spi_driver(dev->driver); |
258 | struct spi_device *spi = to_spi_device(dev); | ||
259 | int ret; | 260 | int ret; |
260 | 261 | ||
261 | acpi_dev_pm_attach(&spi->dev, true); | 262 | acpi_dev_pm_attach(dev, true); |
262 | ret = sdrv->probe(spi); | 263 | ret = sdrv->probe(to_spi_device(dev)); |
263 | if (ret) | 264 | if (ret) |
264 | acpi_dev_pm_detach(&spi->dev, true); | 265 | acpi_dev_pm_detach(dev, true); |
265 | 266 | ||
266 | return ret; | 267 | return ret; |
267 | } | 268 | } |
@@ -269,11 +270,10 @@ static int spi_drv_probe(struct device *dev) | |||
269 | static int spi_drv_remove(struct device *dev) | 270 | static int spi_drv_remove(struct device *dev) |
270 | { | 271 | { |
271 | const struct spi_driver *sdrv = to_spi_driver(dev->driver); | 272 | const struct spi_driver *sdrv = to_spi_driver(dev->driver); |
272 | struct spi_device *spi = to_spi_device(dev); | ||
273 | int ret; | 273 | int ret; |
274 | 274 | ||
275 | ret = sdrv->remove(spi); | 275 | ret = sdrv->remove(to_spi_device(dev)); |
276 | acpi_dev_pm_detach(&spi->dev, true); | 276 | acpi_dev_pm_detach(dev, true); |
277 | 277 | ||
278 | return ret; | 278 | return ret; |
279 | } | 279 | } |
@@ -580,6 +580,169 @@ static void spi_set_cs(struct spi_device *spi, bool enable) | |||
580 | spi->master->set_cs(spi, !enable); | 580 | spi->master->set_cs(spi, !enable); |
581 | } | 581 | } |
582 | 582 | ||
583 | static int spi_map_buf(struct spi_master *master, struct device *dev, | ||
584 | struct sg_table *sgt, void *buf, size_t len, | ||
585 | enum dma_data_direction dir) | ||
586 | { | ||
587 | const bool vmalloced_buf = is_vmalloc_addr(buf); | ||
588 | const int desc_len = vmalloced_buf ? PAGE_SIZE : master->max_dma_len; | ||
589 | const int sgs = DIV_ROUND_UP(len, desc_len); | ||
590 | struct page *vm_page; | ||
591 | void *sg_buf; | ||
592 | size_t min; | ||
593 | int i, ret; | ||
594 | |||
595 | ret = sg_alloc_table(sgt, sgs, GFP_KERNEL); | ||
596 | if (ret != 0) | ||
597 | return ret; | ||
598 | |||
599 | for (i = 0; i < sgs; i++) { | ||
600 | min = min_t(size_t, len, desc_len); | ||
601 | |||
602 | if (vmalloced_buf) { | ||
603 | vm_page = vmalloc_to_page(buf); | ||
604 | if (!vm_page) { | ||
605 | sg_free_table(sgt); | ||
606 | return -ENOMEM; | ||
607 | } | ||
608 | sg_buf = page_address(vm_page) + | ||
609 | ((size_t)buf & ~PAGE_MASK); | ||
610 | } else { | ||
611 | sg_buf = buf; | ||
612 | } | ||
613 | |||
614 | sg_set_buf(&sgt->sgl[i], sg_buf, min); | ||
615 | |||
616 | buf += min; | ||
617 | len -= min; | ||
618 | } | ||
619 | |||
620 | ret = dma_map_sg(dev, sgt->sgl, sgt->nents, dir); | ||
621 | if (ret < 0) { | ||
622 | sg_free_table(sgt); | ||
623 | return ret; | ||
624 | } | ||
625 | |||
626 | sgt->nents = ret; | ||
627 | |||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static void spi_unmap_buf(struct spi_master *master, struct device *dev, | ||
632 | struct sg_table *sgt, enum dma_data_direction dir) | ||
633 | { | ||
634 | if (sgt->orig_nents) { | ||
635 | dma_unmap_sg(dev, sgt->sgl, sgt->orig_nents, dir); | ||
636 | sg_free_table(sgt); | ||
637 | } | ||
638 | } | ||
639 | |||
640 | static int spi_map_msg(struct spi_master *master, struct spi_message *msg) | ||
641 | { | ||
642 | struct device *tx_dev, *rx_dev; | ||
643 | struct spi_transfer *xfer; | ||
644 | void *tmp; | ||
645 | unsigned int max_tx, max_rx; | ||
646 | int ret; | ||
647 | |||
648 | if (master->flags & (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX)) { | ||
649 | max_tx = 0; | ||
650 | max_rx = 0; | ||
651 | |||
652 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
653 | if ((master->flags & SPI_MASTER_MUST_TX) && | ||
654 | !xfer->tx_buf) | ||
655 | max_tx = max(xfer->len, max_tx); | ||
656 | if ((master->flags & SPI_MASTER_MUST_RX) && | ||
657 | !xfer->rx_buf) | ||
658 | max_rx = max(xfer->len, max_rx); | ||
659 | } | ||
660 | |||
661 | if (max_tx) { | ||
662 | tmp = krealloc(master->dummy_tx, max_tx, | ||
663 | GFP_KERNEL | GFP_DMA); | ||
664 | if (!tmp) | ||
665 | return -ENOMEM; | ||
666 | master->dummy_tx = tmp; | ||
667 | memset(tmp, 0, max_tx); | ||
668 | } | ||
669 | |||
670 | if (max_rx) { | ||
671 | tmp = krealloc(master->dummy_rx, max_rx, | ||
672 | GFP_KERNEL | GFP_DMA); | ||
673 | if (!tmp) | ||
674 | return -ENOMEM; | ||
675 | master->dummy_rx = tmp; | ||
676 | } | ||
677 | |||
678 | if (max_tx || max_rx) { | ||
679 | list_for_each_entry(xfer, &msg->transfers, | ||
680 | transfer_list) { | ||
681 | if (!xfer->tx_buf) | ||
682 | xfer->tx_buf = master->dummy_tx; | ||
683 | if (!xfer->rx_buf) | ||
684 | xfer->rx_buf = master->dummy_rx; | ||
685 | } | ||
686 | } | ||
687 | } | ||
688 | |||
689 | if (!master->can_dma) | ||
690 | return 0; | ||
691 | |||
692 | tx_dev = &master->dma_tx->dev->device; | ||
693 | rx_dev = &master->dma_rx->dev->device; | ||
694 | |||
695 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
696 | if (!master->can_dma(master, msg->spi, xfer)) | ||
697 | continue; | ||
698 | |||
699 | if (xfer->tx_buf != NULL) { | ||
700 | ret = spi_map_buf(master, tx_dev, &xfer->tx_sg, | ||
701 | (void *)xfer->tx_buf, xfer->len, | ||
702 | DMA_TO_DEVICE); | ||
703 | if (ret != 0) | ||
704 | return ret; | ||
705 | } | ||
706 | |||
707 | if (xfer->rx_buf != NULL) { | ||
708 | ret = spi_map_buf(master, rx_dev, &xfer->rx_sg, | ||
709 | xfer->rx_buf, xfer->len, | ||
710 | DMA_FROM_DEVICE); | ||
711 | if (ret != 0) { | ||
712 | spi_unmap_buf(master, tx_dev, &xfer->tx_sg, | ||
713 | DMA_TO_DEVICE); | ||
714 | return ret; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | |||
719 | master->cur_msg_mapped = true; | ||
720 | |||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | static int spi_unmap_msg(struct spi_master *master, struct spi_message *msg) | ||
725 | { | ||
726 | struct spi_transfer *xfer; | ||
727 | struct device *tx_dev, *rx_dev; | ||
728 | |||
729 | if (!master->cur_msg_mapped || !master->can_dma) | ||
730 | return 0; | ||
731 | |||
732 | tx_dev = &master->dma_tx->dev->device; | ||
733 | rx_dev = &master->dma_rx->dev->device; | ||
734 | |||
735 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { | ||
736 | if (!master->can_dma(master, msg->spi, xfer)) | ||
737 | continue; | ||
738 | |||
739 | spi_unmap_buf(master, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); | ||
740 | spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); | ||
741 | } | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
583 | /* | 746 | /* |
584 | * spi_transfer_one_message - Default implementation of transfer_one_message() | 747 | * spi_transfer_one_message - Default implementation of transfer_one_message() |
585 | * | 748 | * |
@@ -591,7 +754,6 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
591 | struct spi_message *msg) | 754 | struct spi_message *msg) |
592 | { | 755 | { |
593 | struct spi_transfer *xfer; | 756 | struct spi_transfer *xfer; |
594 | bool cur_cs = true; | ||
595 | bool keep_cs = false; | 757 | bool keep_cs = false; |
596 | int ret = 0; | 758 | int ret = 0; |
597 | 759 | ||
@@ -627,8 +789,9 @@ static int spi_transfer_one_message(struct spi_master *master, | |||
627 | &msg->transfers)) { | 789 | &msg->transfers)) { |
628 | keep_cs = true; | 790 | keep_cs = true; |
629 | } else { | 791 | } else { |
630 | cur_cs = !cur_cs; | 792 | spi_set_cs(msg->spi, false); |
631 | spi_set_cs(msg->spi, cur_cs); | 793 | udelay(10); |
794 | spi_set_cs(msg->spi, true); | ||
632 | } | 795 | } |
633 | } | 796 | } |
634 | 797 | ||
@@ -686,6 +849,10 @@ static void spi_pump_messages(struct kthread_work *work) | |||
686 | } | 849 | } |
687 | master->busy = false; | 850 | master->busy = false; |
688 | spin_unlock_irqrestore(&master->queue_lock, flags); | 851 | spin_unlock_irqrestore(&master->queue_lock, flags); |
852 | kfree(master->dummy_rx); | ||
853 | master->dummy_rx = NULL; | ||
854 | kfree(master->dummy_tx); | ||
855 | master->dummy_tx = NULL; | ||
689 | if (master->unprepare_transfer_hardware && | 856 | if (master->unprepare_transfer_hardware && |
690 | master->unprepare_transfer_hardware(master)) | 857 | master->unprepare_transfer_hardware(master)) |
691 | dev_err(&master->dev, | 858 | dev_err(&master->dev, |
@@ -752,14 +919,19 @@ static void spi_pump_messages(struct kthread_work *work) | |||
752 | master->cur_msg_prepared = true; | 919 | master->cur_msg_prepared = true; |
753 | } | 920 | } |
754 | 921 | ||
755 | ret = master->transfer_one_message(master, master->cur_msg); | 922 | ret = spi_map_msg(master, master->cur_msg); |
756 | if (ret) { | 923 | if (ret) { |
757 | dev_err(&master->dev, | ||
758 | "failed to transfer one message from queue: %d\n", ret); | ||
759 | master->cur_msg->status = ret; | 924 | master->cur_msg->status = ret; |
760 | spi_finalize_current_message(master); | 925 | spi_finalize_current_message(master); |
761 | return; | 926 | return; |
762 | } | 927 | } |
928 | |||
929 | ret = master->transfer_one_message(master, master->cur_msg); | ||
930 | if (ret) { | ||
931 | dev_err(&master->dev, | ||
932 | "failed to transfer one message from queue\n"); | ||
933 | return; | ||
934 | } | ||
763 | } | 935 | } |
764 | 936 | ||
765 | static int spi_init_queue(struct spi_master *master) | 937 | static int spi_init_queue(struct spi_master *master) |
@@ -841,6 +1013,8 @@ void spi_finalize_current_message(struct spi_master *master) | |||
841 | queue_kthread_work(&master->kworker, &master->pump_messages); | 1013 | queue_kthread_work(&master->kworker, &master->pump_messages); |
842 | spin_unlock_irqrestore(&master->queue_lock, flags); | 1014 | spin_unlock_irqrestore(&master->queue_lock, flags); |
843 | 1015 | ||
1016 | spi_unmap_msg(master, mesg); | ||
1017 | |||
844 | if (master->cur_msg_prepared && master->unprepare_message) { | 1018 | if (master->cur_msg_prepared && master->unprepare_message) { |
845 | ret = master->unprepare_message(master, mesg); | 1019 | ret = master->unprepare_message(master, mesg); |
846 | if (ret) { | 1020 | if (ret) { |
@@ -894,7 +1068,7 @@ static int spi_stop_queue(struct spi_master *master) | |||
894 | */ | 1068 | */ |
895 | while ((!list_empty(&master->queue) || master->busy) && limit--) { | 1069 | while ((!list_empty(&master->queue) || master->busy) && limit--) { |
896 | spin_unlock_irqrestore(&master->queue_lock, flags); | 1070 | spin_unlock_irqrestore(&master->queue_lock, flags); |
897 | msleep(10); | 1071 | usleep_range(10000, 11000); |
898 | spin_lock_irqsave(&master->queue_lock, flags); | 1072 | spin_lock_irqsave(&master->queue_lock, flags); |
899 | } | 1073 | } |
900 | 1074 | ||
@@ -1374,6 +1548,8 @@ int spi_register_master(struct spi_master *master) | |||
1374 | mutex_init(&master->bus_lock_mutex); | 1548 | mutex_init(&master->bus_lock_mutex); |
1375 | master->bus_lock_flag = 0; | 1549 | master->bus_lock_flag = 0; |
1376 | init_completion(&master->xfer_completion); | 1550 | init_completion(&master->xfer_completion); |
1551 | if (!master->max_dma_len) | ||
1552 | master->max_dma_len = INT_MAX; | ||
1377 | 1553 | ||
1378 | /* register the device, then userspace will see it. | 1554 | /* register the device, then userspace will see it. |
1379 | * registration fails if the bus ID is in use. | 1555 | * registration fails if the bus ID is in use. |
@@ -1619,11 +1795,10 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
1619 | { | 1795 | { |
1620 | struct spi_master *master = spi->master; | 1796 | struct spi_master *master = spi->master; |
1621 | struct spi_transfer *xfer; | 1797 | struct spi_transfer *xfer; |
1798 | int w_size; | ||
1622 | 1799 | ||
1623 | if (list_empty(&message->transfers)) | 1800 | if (list_empty(&message->transfers)) |
1624 | return -EINVAL; | 1801 | return -EINVAL; |
1625 | if (!message->complete) | ||
1626 | return -EINVAL; | ||
1627 | 1802 | ||
1628 | /* Half-duplex links include original MicroWire, and ones with | 1803 | /* Half-duplex links include original MicroWire, and ones with |
1629 | * only one data pin like SPI_3WIRE (switches direction) or where | 1804 | * only one data pin like SPI_3WIRE (switches direction) or where |
@@ -1654,12 +1829,13 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
1654 | message->frame_length += xfer->len; | 1829 | message->frame_length += xfer->len; |
1655 | if (!xfer->bits_per_word) | 1830 | if (!xfer->bits_per_word) |
1656 | xfer->bits_per_word = spi->bits_per_word; | 1831 | xfer->bits_per_word = spi->bits_per_word; |
1657 | if (!xfer->speed_hz) { | 1832 | |
1833 | if (!xfer->speed_hz) | ||
1658 | xfer->speed_hz = spi->max_speed_hz; | 1834 | xfer->speed_hz = spi->max_speed_hz; |
1659 | if (master->max_speed_hz && | 1835 | |
1660 | xfer->speed_hz > master->max_speed_hz) | 1836 | if (master->max_speed_hz && |
1661 | xfer->speed_hz = master->max_speed_hz; | 1837 | xfer->speed_hz > master->max_speed_hz) |
1662 | } | 1838 | xfer->speed_hz = master->max_speed_hz; |
1663 | 1839 | ||
1664 | if (master->bits_per_word_mask) { | 1840 | if (master->bits_per_word_mask) { |
1665 | /* Only 32 bits fit in the mask */ | 1841 | /* Only 32 bits fit in the mask */ |
@@ -1670,12 +1846,24 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) | |||
1670 | return -EINVAL; | 1846 | return -EINVAL; |
1671 | } | 1847 | } |
1672 | 1848 | ||
1849 | /* | ||
1850 | * SPI transfer length should be multiple of SPI word size | ||
1851 | * where SPI word size should be power-of-two multiple | ||
1852 | */ | ||
1853 | if (xfer->bits_per_word <= 8) | ||
1854 | w_size = 1; | ||
1855 | else if (xfer->bits_per_word <= 16) | ||
1856 | w_size = 2; | ||
1857 | else | ||
1858 | w_size = 4; | ||
1859 | |||
1860 | /* No partial transfers accepted */ | ||
1861 | if (xfer->len % w_size) | ||
1862 | return -EINVAL; | ||
1863 | |||
1673 | if (xfer->speed_hz && master->min_speed_hz && | 1864 | if (xfer->speed_hz && master->min_speed_hz && |
1674 | xfer->speed_hz < master->min_speed_hz) | 1865 | xfer->speed_hz < master->min_speed_hz) |
1675 | return -EINVAL; | 1866 | return -EINVAL; |
1676 | if (xfer->speed_hz && master->max_speed_hz && | ||
1677 | xfer->speed_hz > master->max_speed_hz) | ||
1678 | return -EINVAL; | ||
1679 | 1867 | ||
1680 | if (xfer->tx_buf && !xfer->tx_nbits) | 1868 | if (xfer->tx_buf && !xfer->tx_nbits) |
1681 | xfer->tx_nbits = SPI_NBITS_SINGLE; | 1869 | xfer->tx_nbits = SPI_NBITS_SINGLE; |
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 23948f167012..713a97226787 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c | |||
@@ -295,21 +295,29 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, | |||
295 | 295 | ||
296 | /* If size is not set, or set to 0, always return EOF. */ | 296 | /* If size is not set, or set to 0, always return EOF. */ |
297 | if (asma->size == 0) | 297 | if (asma->size == 0) |
298 | goto out; | 298 | goto out_unlock; |
299 | 299 | ||
300 | if (!asma->file) { | 300 | if (!asma->file) { |
301 | ret = -EBADF; | 301 | ret = -EBADF; |
302 | goto out; | 302 | goto out_unlock; |
303 | } | 303 | } |
304 | 304 | ||
305 | ret = asma->file->f_op->read(asma->file, buf, len, pos); | 305 | mutex_unlock(&ashmem_mutex); |
306 | if (ret < 0) | ||
307 | goto out; | ||
308 | 306 | ||
309 | /** Update backing file pos, since f_ops->read() doesn't */ | 307 | /* |
310 | asma->file->f_pos = *pos; | 308 | * asma and asma->file are used outside the lock here. We assume |
309 | * once asma->file is set it will never be changed, and will not | ||
310 | * be destroyed until all references to the file are dropped and | ||
311 | * ashmem_release is called. | ||
312 | */ | ||
313 | ret = asma->file->f_op->read(asma->file, buf, len, pos); | ||
314 | if (ret >= 0) { | ||
315 | /** Update backing file pos, since f_ops->read() doesn't */ | ||
316 | asma->file->f_pos = *pos; | ||
317 | } | ||
318 | return ret; | ||
311 | 319 | ||
312 | out: | 320 | out_unlock: |
313 | mutex_unlock(&ashmem_mutex); | 321 | mutex_unlock(&ashmem_mutex); |
314 | return ret; | 322 | return ret; |
315 | } | 323 | } |
@@ -498,6 +506,7 @@ out: | |||
498 | 506 | ||
499 | static int set_name(struct ashmem_area *asma, void __user *name) | 507 | static int set_name(struct ashmem_area *asma, void __user *name) |
500 | { | 508 | { |
509 | int len; | ||
501 | int ret = 0; | 510 | int ret = 0; |
502 | char local_name[ASHMEM_NAME_LEN]; | 511 | char local_name[ASHMEM_NAME_LEN]; |
503 | 512 | ||
@@ -510,21 +519,19 @@ static int set_name(struct ashmem_area *asma, void __user *name) | |||
510 | * variable that does not need protection and later copy the local | 519 | * variable that does not need protection and later copy the local |
511 | * variable to the structure member with lock held. | 520 | * variable to the structure member with lock held. |
512 | */ | 521 | */ |
513 | if (copy_from_user(local_name, name, ASHMEM_NAME_LEN)) | 522 | len = strncpy_from_user(local_name, name, ASHMEM_NAME_LEN); |
514 | return -EFAULT; | 523 | if (len < 0) |
515 | 524 | return len; | |
525 | if (len == ASHMEM_NAME_LEN) | ||
526 | local_name[ASHMEM_NAME_LEN - 1] = '\0'; | ||
516 | mutex_lock(&ashmem_mutex); | 527 | mutex_lock(&ashmem_mutex); |
517 | /* cannot change an existing mapping's name */ | 528 | /* cannot change an existing mapping's name */ |
518 | if (unlikely(asma->file)) { | 529 | if (unlikely(asma->file)) |
519 | ret = -EINVAL; | 530 | ret = -EINVAL; |
520 | goto out; | 531 | else |
521 | } | 532 | strcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, local_name); |
522 | memcpy(asma->name + ASHMEM_NAME_PREFIX_LEN, | ||
523 | local_name, ASHMEM_NAME_LEN); | ||
524 | asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0'; | ||
525 | out: | ||
526 | mutex_unlock(&ashmem_mutex); | ||
527 | 533 | ||
534 | mutex_unlock(&ashmem_mutex); | ||
528 | return ret; | 535 | return ret; |
529 | } | 536 | } |
530 | 537 | ||
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index eaec1dab7fe4..1432d956769c 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c | |||
@@ -2904,7 +2904,7 @@ static int binder_node_release(struct binder_node *node, int refs) | |||
2904 | refs++; | 2904 | refs++; |
2905 | 2905 | ||
2906 | if (!ref->death) | 2906 | if (!ref->death) |
2907 | goto out; | 2907 | continue; |
2908 | 2908 | ||
2909 | death++; | 2909 | death++; |
2910 | 2910 | ||
@@ -2917,7 +2917,6 @@ static int binder_node_release(struct binder_node *node, int refs) | |||
2917 | BUG(); | 2917 | BUG(); |
2918 | } | 2918 | } |
2919 | 2919 | ||
2920 | out: | ||
2921 | binder_debug(BINDER_DEBUG_DEAD_BINDER, | 2920 | binder_debug(BINDER_DEBUG_DEAD_BINDER, |
2922 | "node %d now dead, refs %d, death %d\n", | 2921 | "node %d now dead, refs %d, death %d\n", |
2923 | node->debug_id, refs, death); | 2922 | node->debug_id, refs, death); |
diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index af6cd370b30f..ee3a7380e53b 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c | |||
@@ -35,9 +35,14 @@ struct compat_ion_custom_data { | |||
35 | compat_ulong_t arg; | 35 | compat_ulong_t arg; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct compat_ion_handle_data { | ||
39 | compat_int_t handle; | ||
40 | }; | ||
41 | |||
38 | #define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ | 42 | #define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ |
39 | struct compat_ion_allocation_data) | 43 | struct compat_ion_allocation_data) |
40 | #define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) | 44 | #define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \ |
45 | struct compat_ion_handle_data) | ||
41 | #define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ | 46 | #define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ |
42 | struct compat_ion_custom_data) | 47 | struct compat_ion_custom_data) |
43 | 48 | ||
@@ -64,6 +69,19 @@ static int compat_get_ion_allocation_data( | |||
64 | return err; | 69 | return err; |
65 | } | 70 | } |
66 | 71 | ||
72 | static int compat_get_ion_handle_data( | ||
73 | struct compat_ion_handle_data __user *data32, | ||
74 | struct ion_handle_data __user *data) | ||
75 | { | ||
76 | compat_int_t i; | ||
77 | int err; | ||
78 | |||
79 | err = get_user(i, &data32->handle); | ||
80 | err |= put_user(i, &data->handle); | ||
81 | |||
82 | return err; | ||
83 | } | ||
84 | |||
67 | static int compat_put_ion_allocation_data( | 85 | static int compat_put_ion_allocation_data( |
68 | struct compat_ion_allocation_data __user *data32, | 86 | struct compat_ion_allocation_data __user *data32, |
69 | struct ion_allocation_data __user *data) | 87 | struct ion_allocation_data __user *data) |
@@ -132,8 +150,8 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
132 | } | 150 | } |
133 | case COMPAT_ION_IOC_FREE: | 151 | case COMPAT_ION_IOC_FREE: |
134 | { | 152 | { |
135 | struct compat_ion_allocation_data __user *data32; | 153 | struct compat_ion_handle_data __user *data32; |
136 | struct ion_allocation_data __user *data; | 154 | struct ion_handle_data __user *data; |
137 | int err; | 155 | int err; |
138 | 156 | ||
139 | data32 = compat_ptr(arg); | 157 | data32 = compat_ptr(arg); |
@@ -141,7 +159,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
141 | if (data == NULL) | 159 | if (data == NULL) |
142 | return -EFAULT; | 160 | return -EFAULT; |
143 | 161 | ||
144 | err = compat_get_ion_allocation_data(data32, data); | 162 | err = compat_get_ion_handle_data(data32, data); |
145 | if (err) | 163 | if (err) |
146 | return err; | 164 | return err; |
147 | 165 | ||
diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c index 55b2002753f2..01cdc8aee898 100644 --- a/drivers/staging/android/ion/ion_dummy_driver.c +++ b/drivers/staging/android/ion/ion_dummy_driver.c | |||
@@ -17,9 +17,11 @@ | |||
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/init.h> | ||
20 | #include <linux/bootmem.h> | 21 | #include <linux/bootmem.h> |
21 | #include <linux/memblock.h> | 22 | #include <linux/memblock.h> |
22 | #include <linux/sizes.h> | 23 | #include <linux/sizes.h> |
24 | #include <linux/io.h> | ||
23 | #include "ion.h" | 25 | #include "ion.h" |
24 | #include "ion_priv.h" | 26 | #include "ion_priv.h" |
25 | 27 | ||
@@ -57,7 +59,7 @@ struct ion_platform_heap dummy_heaps[] = { | |||
57 | }; | 59 | }; |
58 | 60 | ||
59 | struct ion_platform_data dummy_ion_pdata = { | 61 | struct ion_platform_data dummy_ion_pdata = { |
60 | .nr = 4, | 62 | .nr = ARRAY_SIZE(dummy_heaps), |
61 | .heaps = dummy_heaps, | 63 | .heaps = dummy_heaps, |
62 | }; | 64 | }; |
63 | 65 | ||
@@ -69,7 +71,7 @@ static int __init ion_dummy_init(void) | |||
69 | heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, | 71 | heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, |
70 | GFP_KERNEL); | 72 | GFP_KERNEL); |
71 | if (!heaps) | 73 | if (!heaps) |
72 | return PTR_ERR(heaps); | 74 | return -ENOMEM; |
73 | 75 | ||
74 | 76 | ||
75 | /* Allocate a dummy carveout heap */ | 77 | /* Allocate a dummy carveout heap */ |
@@ -128,6 +130,7 @@ err: | |||
128 | } | 130 | } |
129 | return err; | 131 | return err; |
130 | } | 132 | } |
133 | device_initcall(ion_dummy_init); | ||
131 | 134 | ||
132 | static void __exit ion_dummy_exit(void) | 135 | static void __exit ion_dummy_exit(void) |
133 | { | 136 | { |
@@ -152,7 +155,4 @@ static void __exit ion_dummy_exit(void) | |||
152 | 155 | ||
153 | return; | 156 | return; |
154 | } | 157 | } |
155 | 158 | __exitcall(ion_dummy_exit); | |
156 | module_init(ion_dummy_init); | ||
157 | module_exit(ion_dummy_exit); | ||
158 | |||
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 296c74f98dc0..37e64d51394c 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c | |||
@@ -243,12 +243,12 @@ int ion_heap_init_deferred_free(struct ion_heap *heap) | |||
243 | init_waitqueue_head(&heap->waitqueue); | 243 | init_waitqueue_head(&heap->waitqueue); |
244 | heap->task = kthread_run(ion_heap_deferred_free, heap, | 244 | heap->task = kthread_run(ion_heap_deferred_free, heap, |
245 | "%s", heap->name); | 245 | "%s", heap->name); |
246 | sched_setscheduler(heap->task, SCHED_IDLE, ¶m); | ||
247 | if (IS_ERR(heap->task)) { | 246 | if (IS_ERR(heap->task)) { |
248 | pr_err("%s: creating thread for deferred free failed\n", | 247 | pr_err("%s: creating thread for deferred free failed\n", |
249 | __func__); | 248 | __func__); |
250 | return PTR_RET(heap->task); | 249 | return PTR_RET(heap->task); |
251 | } | 250 | } |
251 | sched_setscheduler(heap->task, SCHED_IDLE, ¶m); | ||
252 | return 0; | 252 | return 0; |
253 | } | 253 | } |
254 | 254 | ||
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index d98673981cc4..fc2e4fccf69d 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #ifndef _ION_PRIV_H | 17 | #ifndef _ION_PRIV_H |
18 | #define _ION_PRIV_H | 18 | #define _ION_PRIV_H |
19 | 19 | ||
20 | #include <linux/device.h> | ||
20 | #include <linux/dma-direction.h> | 21 | #include <linux/dma-direction.h> |
21 | #include <linux/kref.h> | 22 | #include <linux/kref.h> |
22 | #include <linux/mm_types.h> | 23 | #include <linux/mm_types.h> |
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 7f0729130d65..9849f3963e75 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c | |||
@@ -124,6 +124,7 @@ static struct page_info *alloc_largest_available(struct ion_system_heap *heap, | |||
124 | 124 | ||
125 | info->page = page; | 125 | info->page = page; |
126 | info->order = orders[i]; | 126 | info->order = orders[i]; |
127 | INIT_LIST_HEAD(&info->list); | ||
127 | return info; | 128 | return info; |
128 | } | 129 | } |
129 | kfree(info); | 130 | kfree(info); |
@@ -145,12 +146,15 @@ static int ion_system_heap_allocate(struct ion_heap *heap, | |||
145 | struct list_head pages; | 146 | struct list_head pages; |
146 | struct page_info *info, *tmp_info; | 147 | struct page_info *info, *tmp_info; |
147 | int i = 0; | 148 | int i = 0; |
148 | long size_remaining = PAGE_ALIGN(size); | 149 | unsigned long size_remaining = PAGE_ALIGN(size); |
149 | unsigned int max_order = orders[0]; | 150 | unsigned int max_order = orders[0]; |
150 | 151 | ||
151 | if (align > PAGE_SIZE) | 152 | if (align > PAGE_SIZE) |
152 | return -EINVAL; | 153 | return -EINVAL; |
153 | 154 | ||
155 | if (size / PAGE_SIZE > totalram_pages / 2) | ||
156 | return -ENOMEM; | ||
157 | |||
154 | INIT_LIST_HEAD(&pages); | 158 | INIT_LIST_HEAD(&pages); |
155 | while (size_remaining > 0) { | 159 | while (size_remaining > 0) { |
156 | info = alloc_largest_available(sys_heap, buffer, size_remaining, | 160 | info = alloc_largest_available(sys_heap, buffer, size_remaining, |
diff --git a/drivers/staging/android/sw_sync.h b/drivers/staging/android/sw_sync.h index 585040be5f18..5aaf71d6974b 100644 --- a/drivers/staging/android/sw_sync.h +++ b/drivers/staging/android/sw_sync.h | |||
@@ -35,10 +35,27 @@ struct sw_sync_pt { | |||
35 | u32 value; | 35 | u32 value; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | #if IS_ENABLED(CONFIG_SW_SYNC) | ||
38 | struct sw_sync_timeline *sw_sync_timeline_create(const char *name); | 39 | struct sw_sync_timeline *sw_sync_timeline_create(const char *name); |
39 | void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); | 40 | void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc); |
40 | 41 | ||
41 | struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); | 42 | struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value); |
43 | #else | ||
44 | static inline struct sw_sync_timeline *sw_sync_timeline_create(const char *name) | ||
45 | { | ||
46 | return NULL; | ||
47 | } | ||
48 | |||
49 | static inline void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) | ||
50 | { | ||
51 | } | ||
52 | |||
53 | static inline struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, | ||
54 | u32 value) | ||
55 | { | ||
56 | return NULL; | ||
57 | } | ||
58 | #endif /* IS_ENABLED(CONFIG_SW_SYNC) */ | ||
42 | 59 | ||
43 | #endif /* __KERNEL __ */ | 60 | #endif /* __KERNEL __ */ |
44 | 61 | ||
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 38e5d3b5ed9b..3d05f662110b 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c | |||
@@ -79,27 +79,27 @@ static void sync_timeline_free(struct kref *kref) | |||
79 | container_of(kref, struct sync_timeline, kref); | 79 | container_of(kref, struct sync_timeline, kref); |
80 | unsigned long flags; | 80 | unsigned long flags; |
81 | 81 | ||
82 | if (obj->ops->release_obj) | ||
83 | obj->ops->release_obj(obj); | ||
84 | |||
85 | spin_lock_irqsave(&sync_timeline_list_lock, flags); | 82 | spin_lock_irqsave(&sync_timeline_list_lock, flags); |
86 | list_del(&obj->sync_timeline_list); | 83 | list_del(&obj->sync_timeline_list); |
87 | spin_unlock_irqrestore(&sync_timeline_list_lock, flags); | 84 | spin_unlock_irqrestore(&sync_timeline_list_lock, flags); |
88 | 85 | ||
86 | if (obj->ops->release_obj) | ||
87 | obj->ops->release_obj(obj); | ||
88 | |||
89 | kfree(obj); | 89 | kfree(obj); |
90 | } | 90 | } |
91 | 91 | ||
92 | void sync_timeline_destroy(struct sync_timeline *obj) | 92 | void sync_timeline_destroy(struct sync_timeline *obj) |
93 | { | 93 | { |
94 | obj->destroyed = true; | 94 | obj->destroyed = true; |
95 | smp_wmb(); | ||
95 | 96 | ||
96 | /* | 97 | /* |
97 | * If this is not the last reference, signal any children | 98 | * signal any children that their parent is going away. |
98 | * that their parent is going away. | ||
99 | */ | 99 | */ |
100 | sync_timeline_signal(obj); | ||
100 | 101 | ||
101 | if (!kref_put(&obj->kref, sync_timeline_free)) | 102 | kref_put(&obj->kref, sync_timeline_free); |
102 | sync_timeline_signal(obj); | ||
103 | } | 103 | } |
104 | EXPORT_SYMBOL(sync_timeline_destroy); | 104 | EXPORT_SYMBOL(sync_timeline_destroy); |
105 | 105 | ||
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 8dfdd2732bdc..95a2358267ba 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c | |||
@@ -40,7 +40,7 @@ static INT bcm_close(struct net_device *dev) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, | 42 | static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb, |
43 | void *accel_priv) | 43 | void *accel_priv, select_queue_fallback_t fallback) |
44 | { | 44 | { |
45 | return ClassifyPacket(netdev_priv(dev), skb); | 45 | return ClassifyPacket(netdev_priv(dev), skb); |
46 | } | 46 | } |
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 246080316c90..5b15033a94bf 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c | |||
@@ -616,8 +616,6 @@ int comedi_auto_config(struct device *hardware_device, | |||
616 | ret = driver->auto_attach(dev, context); | 616 | ret = driver->auto_attach(dev, context); |
617 | if (ret >= 0) | 617 | if (ret >= 0) |
618 | ret = comedi_device_postconfig(dev); | 618 | ret = comedi_device_postconfig(dev); |
619 | if (ret < 0) | ||
620 | comedi_device_detach(dev); | ||
621 | mutex_unlock(&dev->mutex); | 619 | mutex_unlock(&dev->mutex); |
622 | 620 | ||
623 | if (ret < 0) { | 621 | if (ret < 0) { |
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 593676cf706a..d9ad2c0fdda2 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c | |||
@@ -494,6 +494,7 @@ static int pci171x_insn_write_ao(struct comedi_device *dev, | |||
494 | struct comedi_insn *insn, unsigned int *data) | 494 | struct comedi_insn *insn, unsigned int *data) |
495 | { | 495 | { |
496 | struct pci1710_private *devpriv = dev->private; | 496 | struct pci1710_private *devpriv = dev->private; |
497 | unsigned int val; | ||
497 | int n, chan, range, ofs; | 498 | int n, chan, range, ofs; |
498 | 499 | ||
499 | chan = CR_CHAN(insn->chanspec); | 500 | chan = CR_CHAN(insn->chanspec); |
@@ -509,11 +510,14 @@ static int pci171x_insn_write_ao(struct comedi_device *dev, | |||
509 | outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); | 510 | outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); |
510 | ofs = PCI171x_DA1; | 511 | ofs = PCI171x_DA1; |
511 | } | 512 | } |
513 | val = devpriv->ao_data[chan]; | ||
512 | 514 | ||
513 | for (n = 0; n < insn->n; n++) | 515 | for (n = 0; n < insn->n; n++) { |
514 | outw(data[n], dev->iobase + ofs); | 516 | val = data[n]; |
517 | outw(val, dev->iobase + ofs); | ||
518 | } | ||
515 | 519 | ||
516 | devpriv->ao_data[chan] = data[n]; | 520 | devpriv->ao_data[chan] = val; |
517 | 521 | ||
518 | return n; | 522 | return n; |
519 | 523 | ||
@@ -679,6 +683,7 @@ static int pci1720_insn_write_ao(struct comedi_device *dev, | |||
679 | struct comedi_insn *insn, unsigned int *data) | 683 | struct comedi_insn *insn, unsigned int *data) |
680 | { | 684 | { |
681 | struct pci1710_private *devpriv = dev->private; | 685 | struct pci1710_private *devpriv = dev->private; |
686 | unsigned int val; | ||
682 | int n, rangereg, chan; | 687 | int n, rangereg, chan; |
683 | 688 | ||
684 | chan = CR_CHAN(insn->chanspec); | 689 | chan = CR_CHAN(insn->chanspec); |
@@ -688,13 +693,15 @@ static int pci1720_insn_write_ao(struct comedi_device *dev, | |||
688 | outb(rangereg, dev->iobase + PCI1720_RANGE); | 693 | outb(rangereg, dev->iobase + PCI1720_RANGE); |
689 | devpriv->da_ranges = rangereg; | 694 | devpriv->da_ranges = rangereg; |
690 | } | 695 | } |
696 | val = devpriv->ao_data[chan]; | ||
691 | 697 | ||
692 | for (n = 0; n < insn->n; n++) { | 698 | for (n = 0; n < insn->n; n++) { |
693 | outw(data[n], dev->iobase + PCI1720_DA0 + (chan << 1)); | 699 | val = data[n]; |
700 | outw(val, dev->iobase + PCI1720_DA0 + (chan << 1)); | ||
694 | outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */ | 701 | outb(0, dev->iobase + PCI1720_SYNCOUT); /* update outputs */ |
695 | } | 702 | } |
696 | 703 | ||
697 | devpriv->ao_data[chan] = data[n]; | 704 | devpriv->ao_data[chan] = val; |
698 | 705 | ||
699 | return n; | 706 | return n; |
700 | } | 707 | } |
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 3beeb1254152..88c60b6020c4 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
49 | #include <linux/fcntl.h> | 49 | #include <linux/fcntl.h> |
50 | #include <linux/compiler.h> | 50 | #include <linux/compiler.h> |
51 | #include <asm/unaligned.h> | ||
51 | 52 | ||
52 | #include "comedi_fc.h" | 53 | #include "comedi_fc.h" |
53 | #include "../comedidev.h" | 54 | #include "../comedidev.h" |
@@ -792,7 +793,8 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev, | |||
792 | } | 793 | } |
793 | 794 | ||
794 | /* 32 bits big endian from the A/D converter */ | 795 | /* 32 bits big endian from the A/D converter */ |
795 | val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf) + 1))); | 796 | val = be32_to_cpu(get_unaligned((uint32_t |
797 | *)(devpriv->insn_buf + 1))); | ||
796 | val &= 0x00ffffff; /* strip status byte */ | 798 | val &= 0x00ffffff; /* strip status byte */ |
797 | val ^= 0x00800000; /* convert to unsigned */ | 799 | val ^= 0x00800000; /* convert to unsigned */ |
798 | 800 | ||
@@ -1357,7 +1359,7 @@ static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan) | |||
1357 | return ret; | 1359 | return ret; |
1358 | 1360 | ||
1359 | /* 32 bits big endian from the A/D converter */ | 1361 | /* 32 bits big endian from the A/D converter */ |
1360 | val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf)+1))); | 1362 | val = be32_to_cpu(get_unaligned((uint32_t *)(devpriv->insn_buf + 1))); |
1361 | val &= 0x00ffffff; /* strip status byte */ | 1363 | val &= 0x00ffffff; /* strip status byte */ |
1362 | val ^= 0x00800000; /* convert to unsigned */ | 1364 | val ^= 0x00800000; /* convert to unsigned */ |
1363 | 1365 | ||
diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index 4a08e16e42f7..79206cb3fb94 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c | |||
@@ -866,6 +866,8 @@ c4_ioctl (struct net_device *ndev, struct ifreq *ifr, int cmd) | |||
866 | _IOC_SIZE (iocmd)); | 866 | _IOC_SIZE (iocmd)); |
867 | #endif | 867 | #endif |
868 | iolen = _IOC_SIZE (iocmd); | 868 | iolen = _IOC_SIZE (iocmd); |
869 | if (iolen > sizeof(arg)) | ||
870 | return -EFAULT; | ||
869 | data = ifr->ifr_data + sizeof (iocmd); | 871 | data = ifr->ifr_data + sizeof (iocmd); |
870 | if (copy_from_user (&arg, data, iolen)) | 872 | if (copy_from_user (&arg, data, iolen)) |
871 | return -EFAULT; | 873 | return -EFAULT; |
diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 1f61b89eca44..33ac7fb88cbd 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c | |||
@@ -2232,177 +2232,6 @@ done: | |||
2232 | return rtn; | 2232 | return rtn; |
2233 | } | 2233 | } |
2234 | 2234 | ||
2235 | /* | ||
2236 | * Common Packet Handling code | ||
2237 | */ | ||
2238 | |||
2239 | static void handle_data_in_packet(struct nd_struct *nd, struct ch_struct *ch, | ||
2240 | long dlen, long plen, int n1, u8 *dbuf) | ||
2241 | { | ||
2242 | char *error; | ||
2243 | long n; | ||
2244 | long remain; | ||
2245 | u8 *buf; | ||
2246 | u8 *b; | ||
2247 | |||
2248 | remain = nd->nd_remain; | ||
2249 | nd->nd_tx_work = 1; | ||
2250 | |||
2251 | /* | ||
2252 | * Otherwise data should appear only when we are | ||
2253 | * in the CS_READY state. | ||
2254 | */ | ||
2255 | |||
2256 | if (ch->ch_state < CS_READY) { | ||
2257 | error = "Data received before RWIN established"; | ||
2258 | nd->nd_remain = 0; | ||
2259 | nd->nd_state = NS_SEND_ERROR; | ||
2260 | nd->nd_error = error; | ||
2261 | } | ||
2262 | |||
2263 | /* | ||
2264 | * Assure that the data received is within the | ||
2265 | * allowable window. | ||
2266 | */ | ||
2267 | |||
2268 | n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; | ||
2269 | |||
2270 | if (dlen > n) { | ||
2271 | error = "Receive data overrun"; | ||
2272 | nd->nd_remain = 0; | ||
2273 | nd->nd_state = NS_SEND_ERROR; | ||
2274 | nd->nd_error = error; | ||
2275 | } | ||
2276 | |||
2277 | /* | ||
2278 | * If we received 3 or less characters, | ||
2279 | * assume it is a human typing, and set RTIME | ||
2280 | * to 10 milliseconds. | ||
2281 | * | ||
2282 | * If we receive 10 or more characters, | ||
2283 | * assume its not a human typing, and set RTIME | ||
2284 | * to 100 milliseconds. | ||
2285 | */ | ||
2286 | |||
2287 | if (ch->ch_edelay != DGRP_RTIME) { | ||
2288 | if (ch->ch_rtime != ch->ch_edelay) { | ||
2289 | ch->ch_rtime = ch->ch_edelay; | ||
2290 | ch->ch_flag |= CH_PARAM; | ||
2291 | } | ||
2292 | } else if (dlen <= 3) { | ||
2293 | if (ch->ch_rtime != 10) { | ||
2294 | ch->ch_rtime = 10; | ||
2295 | ch->ch_flag |= CH_PARAM; | ||
2296 | } | ||
2297 | } else { | ||
2298 | if (ch->ch_rtime != DGRP_RTIME) { | ||
2299 | ch->ch_rtime = DGRP_RTIME; | ||
2300 | ch->ch_flag |= CH_PARAM; | ||
2301 | } | ||
2302 | } | ||
2303 | |||
2304 | /* | ||
2305 | * If a portion of the packet is outside the | ||
2306 | * buffer, shorten the effective length of the | ||
2307 | * data packet to be the amount of data received. | ||
2308 | */ | ||
2309 | |||
2310 | if (remain < plen) | ||
2311 | dlen -= plen - remain; | ||
2312 | |||
2313 | /* | ||
2314 | * Detect if receive flush is now complete. | ||
2315 | */ | ||
2316 | |||
2317 | if ((ch->ch_flag & CH_RX_FLUSH) != 0 && | ||
2318 | ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= | ||
2319 | ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { | ||
2320 | ch->ch_flag &= ~CH_RX_FLUSH; | ||
2321 | } | ||
2322 | |||
2323 | /* | ||
2324 | * If we are ready to receive, move the data into | ||
2325 | * the receive buffer. | ||
2326 | */ | ||
2327 | |||
2328 | ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; | ||
2329 | |||
2330 | if (ch->ch_state == CS_READY && | ||
2331 | (ch->ch_tun.un_open_count != 0) && | ||
2332 | (ch->ch_tun.un_flag & UN_CLOSING) == 0 && | ||
2333 | (ch->ch_cflag & CF_CREAD) != 0 && | ||
2334 | (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && | ||
2335 | (ch->ch_send & RR_RX_FLUSH) == 0) { | ||
2336 | |||
2337 | if (ch->ch_rin + dlen >= RBUF_MAX) { | ||
2338 | n = RBUF_MAX - ch->ch_rin; | ||
2339 | |||
2340 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); | ||
2341 | |||
2342 | ch->ch_rin = 0; | ||
2343 | dbuf += n; | ||
2344 | dlen -= n; | ||
2345 | } | ||
2346 | |||
2347 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); | ||
2348 | |||
2349 | ch->ch_rin += dlen; | ||
2350 | |||
2351 | |||
2352 | /* | ||
2353 | * If we are not in fastcook mode, or | ||
2354 | * if there is a fastcook thread | ||
2355 | * waiting for data, send the data to | ||
2356 | * the line discipline. | ||
2357 | */ | ||
2358 | |||
2359 | if ((ch->ch_flag & CH_FAST_READ) == 0 || | ||
2360 | ch->ch_inwait != 0) { | ||
2361 | dgrp_input(ch); | ||
2362 | } | ||
2363 | |||
2364 | /* | ||
2365 | * If there is a read thread waiting | ||
2366 | * in select, and we are in fastcook | ||
2367 | * mode, wake him up. | ||
2368 | */ | ||
2369 | |||
2370 | if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && | ||
2371 | (ch->ch_flag & CH_FAST_READ) != 0) | ||
2372 | wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); | ||
2373 | |||
2374 | /* | ||
2375 | * Wake any thread waiting in the | ||
2376 | * fastcook loop. | ||
2377 | */ | ||
2378 | |||
2379 | if ((ch->ch_flag & CH_INPUT) != 0) { | ||
2380 | ch->ch_flag &= ~CH_INPUT; | ||
2381 | wake_up_interruptible(&ch->ch_flag_wait); | ||
2382 | } | ||
2383 | } | ||
2384 | |||
2385 | /* | ||
2386 | * Fabricate and insert a data packet header to | ||
2387 | * preced the remaining data when it comes in. | ||
2388 | */ | ||
2389 | |||
2390 | if (remain < plen) { | ||
2391 | dlen = plen - remain; | ||
2392 | b = buf; | ||
2393 | |||
2394 | b[0] = 0x90 + n1; | ||
2395 | put_unaligned_be16(dlen, b + 1); | ||
2396 | |||
2397 | remain = 3; | ||
2398 | if (remain > 0 && b != buf) | ||
2399 | memcpy(buf, b, remain); | ||
2400 | |||
2401 | nd->nd_remain = remain; | ||
2402 | return; | ||
2403 | } | ||
2404 | } | ||
2405 | |||
2406 | /** | 2235 | /** |
2407 | * dgrp_receive() -- decode data packets received from the remote PortServer. | 2236 | * dgrp_receive() -- decode data packets received from the remote PortServer. |
2408 | * @nd: pointer to a node structure | 2237 | * @nd: pointer to a node structure |
@@ -2477,8 +2306,7 @@ static void dgrp_receive(struct nd_struct *nd) | |||
2477 | plen = dlen + 1; | 2306 | plen = dlen + 1; |
2478 | 2307 | ||
2479 | dbuf = b + 1; | 2308 | dbuf = b + 1; |
2480 | handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); | 2309 | goto data; |
2481 | break; | ||
2482 | 2310 | ||
2483 | /* | 2311 | /* |
2484 | * Process 2-byte header data packet. | 2312 | * Process 2-byte header data packet. |
@@ -2492,8 +2320,7 @@ static void dgrp_receive(struct nd_struct *nd) | |||
2492 | plen = dlen + 2; | 2320 | plen = dlen + 2; |
2493 | 2321 | ||
2494 | dbuf = b + 2; | 2322 | dbuf = b + 2; |
2495 | handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); | 2323 | goto data; |
2496 | break; | ||
2497 | 2324 | ||
2498 | /* | 2325 | /* |
2499 | * Process 3-byte header data packet. | 2326 | * Process 3-byte header data packet. |
@@ -2508,6 +2335,159 @@ static void dgrp_receive(struct nd_struct *nd) | |||
2508 | 2335 | ||
2509 | dbuf = b + 3; | 2336 | dbuf = b + 3; |
2510 | 2337 | ||
2338 | /* | ||
2339 | * Common packet handling code. | ||
2340 | */ | ||
2341 | |||
2342 | data: | ||
2343 | nd->nd_tx_work = 1; | ||
2344 | |||
2345 | /* | ||
2346 | * Otherwise data should appear only when we are | ||
2347 | * in the CS_READY state. | ||
2348 | */ | ||
2349 | |||
2350 | if (ch->ch_state < CS_READY) { | ||
2351 | error = "Data received before RWIN established"; | ||
2352 | goto prot_error; | ||
2353 | } | ||
2354 | |||
2355 | /* | ||
2356 | * Assure that the data received is within the | ||
2357 | * allowable window. | ||
2358 | */ | ||
2359 | |||
2360 | n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; | ||
2361 | |||
2362 | if (dlen > n) { | ||
2363 | error = "Receive data overrun"; | ||
2364 | goto prot_error; | ||
2365 | } | ||
2366 | |||
2367 | /* | ||
2368 | * If we received 3 or less characters, | ||
2369 | * assume it is a human typing, and set RTIME | ||
2370 | * to 10 milliseconds. | ||
2371 | * | ||
2372 | * If we receive 10 or more characters, | ||
2373 | * assume its not a human typing, and set RTIME | ||
2374 | * to 100 milliseconds. | ||
2375 | */ | ||
2376 | |||
2377 | if (ch->ch_edelay != DGRP_RTIME) { | ||
2378 | if (ch->ch_rtime != ch->ch_edelay) { | ||
2379 | ch->ch_rtime = ch->ch_edelay; | ||
2380 | ch->ch_flag |= CH_PARAM; | ||
2381 | } | ||
2382 | } else if (dlen <= 3) { | ||
2383 | if (ch->ch_rtime != 10) { | ||
2384 | ch->ch_rtime = 10; | ||
2385 | ch->ch_flag |= CH_PARAM; | ||
2386 | } | ||
2387 | } else { | ||
2388 | if (ch->ch_rtime != DGRP_RTIME) { | ||
2389 | ch->ch_rtime = DGRP_RTIME; | ||
2390 | ch->ch_flag |= CH_PARAM; | ||
2391 | } | ||
2392 | } | ||
2393 | |||
2394 | /* | ||
2395 | * If a portion of the packet is outside the | ||
2396 | * buffer, shorten the effective length of the | ||
2397 | * data packet to be the amount of data received. | ||
2398 | */ | ||
2399 | |||
2400 | if (remain < plen) | ||
2401 | dlen -= plen - remain; | ||
2402 | |||
2403 | /* | ||
2404 | * Detect if receive flush is now complete. | ||
2405 | */ | ||
2406 | |||
2407 | if ((ch->ch_flag & CH_RX_FLUSH) != 0 && | ||
2408 | ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= | ||
2409 | ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { | ||
2410 | ch->ch_flag &= ~CH_RX_FLUSH; | ||
2411 | } | ||
2412 | |||
2413 | /* | ||
2414 | * If we are ready to receive, move the data into | ||
2415 | * the receive buffer. | ||
2416 | */ | ||
2417 | |||
2418 | ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; | ||
2419 | |||
2420 | if (ch->ch_state == CS_READY && | ||
2421 | (ch->ch_tun.un_open_count != 0) && | ||
2422 | (ch->ch_tun.un_flag & UN_CLOSING) == 0 && | ||
2423 | (ch->ch_cflag & CF_CREAD) != 0 && | ||
2424 | (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && | ||
2425 | (ch->ch_send & RR_RX_FLUSH) == 0) { | ||
2426 | |||
2427 | if (ch->ch_rin + dlen >= RBUF_MAX) { | ||
2428 | n = RBUF_MAX - ch->ch_rin; | ||
2429 | |||
2430 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); | ||
2431 | |||
2432 | ch->ch_rin = 0; | ||
2433 | dbuf += n; | ||
2434 | dlen -= n; | ||
2435 | } | ||
2436 | |||
2437 | memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); | ||
2438 | |||
2439 | ch->ch_rin += dlen; | ||
2440 | |||
2441 | |||
2442 | /* | ||
2443 | * If we are not in fastcook mode, or | ||
2444 | * if there is a fastcook thread | ||
2445 | * waiting for data, send the data to | ||
2446 | * the line discipline. | ||
2447 | */ | ||
2448 | |||
2449 | if ((ch->ch_flag & CH_FAST_READ) == 0 || | ||
2450 | ch->ch_inwait != 0) { | ||
2451 | dgrp_input(ch); | ||
2452 | } | ||
2453 | |||
2454 | /* | ||
2455 | * If there is a read thread waiting | ||
2456 | * in select, and we are in fastcook | ||
2457 | * mode, wake him up. | ||
2458 | */ | ||
2459 | |||
2460 | if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && | ||
2461 | (ch->ch_flag & CH_FAST_READ) != 0) | ||
2462 | wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); | ||
2463 | |||
2464 | /* | ||
2465 | * Wake any thread waiting in the | ||
2466 | * fastcook loop. | ||
2467 | */ | ||
2468 | |||
2469 | if ((ch->ch_flag & CH_INPUT) != 0) { | ||
2470 | ch->ch_flag &= ~CH_INPUT; | ||
2471 | |||
2472 | wake_up_interruptible(&ch->ch_flag_wait); | ||
2473 | } | ||
2474 | } | ||
2475 | |||
2476 | /* | ||
2477 | * Fabricate and insert a data packet header to | ||
2478 | * preced the remaining data when it comes in. | ||
2479 | */ | ||
2480 | |||
2481 | if (remain < plen) { | ||
2482 | dlen = plen - remain; | ||
2483 | b = buf; | ||
2484 | |||
2485 | b[0] = 0x90 + n1; | ||
2486 | put_unaligned_be16(dlen, b + 1); | ||
2487 | |||
2488 | remain = 3; | ||
2489 | goto done; | ||
2490 | } | ||
2511 | break; | 2491 | break; |
2512 | 2492 | ||
2513 | /* | 2493 | /* |
diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index f8788bf0a7d3..cdeffe75496b 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c | |||
@@ -635,11 +635,14 @@ static int gdm_usb_probe(struct usb_interface *intf, | |||
635 | #endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ | 635 | #endif /* CONFIG_WIMAX_GDM72XX_USB_PM */ |
636 | 636 | ||
637 | ret = register_wimax_device(phy_dev, &intf->dev); | 637 | ret = register_wimax_device(phy_dev, &intf->dev); |
638 | if (ret) | ||
639 | release_usb(udev); | ||
638 | 640 | ||
639 | out: | 641 | out: |
640 | if (ret) { | 642 | if (ret) { |
641 | kfree(phy_dev); | 643 | kfree(phy_dev); |
642 | kfree(udev); | 644 | kfree(udev); |
645 | usb_put_dev(usbdev); | ||
643 | } else { | 646 | } else { |
644 | usb_set_intfdata(intf, phy_dev); | 647 | usb_set_intfdata(intf, phy_dev); |
645 | } | 648 | } |
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h index 35154d60faf6..c9fedb79e3a2 100644 --- a/drivers/staging/iio/Documentation/iio_utils.h +++ b/drivers/staging/iio/Documentation/iio_utils.h | |||
@@ -77,7 +77,6 @@ struct iio_channel_info { | |||
77 | uint64_t mask; | 77 | uint64_t mask; |
78 | unsigned be; | 78 | unsigned be; |
79 | unsigned is_signed; | 79 | unsigned is_signed; |
80 | unsigned enabled; | ||
81 | unsigned location; | 80 | unsigned location; |
82 | }; | 81 | }; |
83 | 82 | ||
@@ -335,6 +334,7 @@ inline int build_channel_array(const char *device_dir, | |||
335 | while (ent = readdir(dp), ent != NULL) { | 334 | while (ent = readdir(dp), ent != NULL) { |
336 | if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), | 335 | if (strcmp(ent->d_name + strlen(ent->d_name) - strlen("_en"), |
337 | "_en") == 0) { | 336 | "_en") == 0) { |
337 | int current_enabled = 0; | ||
338 | current = &(*ci_array)[count++]; | 338 | current = &(*ci_array)[count++]; |
339 | ret = asprintf(&filename, | 339 | ret = asprintf(&filename, |
340 | "%s/%s", scan_el_dir, ent->d_name); | 340 | "%s/%s", scan_el_dir, ent->d_name); |
@@ -350,10 +350,10 @@ inline int build_channel_array(const char *device_dir, | |||
350 | ret = -errno; | 350 | ret = -errno; |
351 | goto error_cleanup_array; | 351 | goto error_cleanup_array; |
352 | } | 352 | } |
353 | fscanf(sysfsfp, "%u", ¤t->enabled); | 353 | fscanf(sysfsfp, "%u", ¤t_enabled); |
354 | fclose(sysfsfp); | 354 | fclose(sysfsfp); |
355 | 355 | ||
356 | if (!current->enabled) { | 356 | if (!current_enabled) { |
357 | free(filename); | 357 | free(filename); |
358 | count--; | 358 | count--; |
359 | continue; | 359 | continue; |
diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 5ea36410f716..5708ffc62aec 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c | |||
@@ -393,7 +393,7 @@ static const struct iio_event_spec ad799x_events[] = { | |||
393 | }, { | 393 | }, { |
394 | .type = IIO_EV_TYPE_THRESH, | 394 | .type = IIO_EV_TYPE_THRESH, |
395 | .dir = IIO_EV_DIR_FALLING, | 395 | .dir = IIO_EV_DIR_FALLING, |
396 | .mask_separate = BIT(IIO_EV_INFO_VALUE), | 396 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
397 | BIT(IIO_EV_INFO_ENABLE), | 397 | BIT(IIO_EV_INFO_ENABLE), |
398 | }, { | 398 | }, { |
399 | .type = IIO_EV_TYPE_THRESH, | 399 | .type = IIO_EV_TYPE_THRESH, |
@@ -409,7 +409,13 @@ static const struct iio_event_spec ad799x_events[] = { | |||
409 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | 409 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
410 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | 410 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
411 | .scan_index = (_index), \ | 411 | .scan_index = (_index), \ |
412 | .scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \ | 412 | .scan_type = { \ |
413 | .sign = 'u', \ | ||
414 | .realbits = (_realbits), \ | ||
415 | .storagebits = 16, \ | ||
416 | .shift = 12 - (_realbits), \ | ||
417 | .endianness = IIO_BE, \ | ||
418 | }, \ | ||
413 | .event_spec = _ev_spec, \ | 419 | .event_spec = _ev_spec, \ |
414 | .num_event_specs = _num_ev_spec, \ | 420 | .num_event_specs = _num_ev_spec, \ |
415 | } | 421 | } |
@@ -588,7 +594,8 @@ static int ad799x_probe(struct i2c_client *client, | |||
588 | return 0; | 594 | return 0; |
589 | 595 | ||
590 | error_free_irq: | 596 | error_free_irq: |
591 | free_irq(client->irq, indio_dev); | 597 | if (client->irq > 0) |
598 | free_irq(client->irq, indio_dev); | ||
592 | error_cleanup_ring: | 599 | error_cleanup_ring: |
593 | ad799x_ring_cleanup(indio_dev); | 600 | ad799x_ring_cleanup(indio_dev); |
594 | error_disable_reg: | 601 | error_disable_reg: |
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index df71669bb60e..514844efac75 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c | |||
@@ -757,6 +757,7 @@ static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid) | |||
757 | } | 757 | } |
758 | 758 | ||
759 | /* if it is released, wait for the next touch via IRQ */ | 759 | /* if it is released, wait for the next touch via IRQ */ |
760 | lradc->cur_plate = LRADC_TOUCH; | ||
760 | mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); | 761 | mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1); |
761 | mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); | 762 | mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1); |
762 | } | 763 | } |
@@ -1035,8 +1036,6 @@ SHOW_SCALE_AVAILABLE_ATTR(4); | |||
1035 | SHOW_SCALE_AVAILABLE_ATTR(5); | 1036 | SHOW_SCALE_AVAILABLE_ATTR(5); |
1036 | SHOW_SCALE_AVAILABLE_ATTR(6); | 1037 | SHOW_SCALE_AVAILABLE_ATTR(6); |
1037 | SHOW_SCALE_AVAILABLE_ATTR(7); | 1038 | SHOW_SCALE_AVAILABLE_ATTR(7); |
1038 | SHOW_SCALE_AVAILABLE_ATTR(8); | ||
1039 | SHOW_SCALE_AVAILABLE_ATTR(9); | ||
1040 | SHOW_SCALE_AVAILABLE_ATTR(10); | 1039 | SHOW_SCALE_AVAILABLE_ATTR(10); |
1041 | SHOW_SCALE_AVAILABLE_ATTR(11); | 1040 | SHOW_SCALE_AVAILABLE_ATTR(11); |
1042 | SHOW_SCALE_AVAILABLE_ATTR(12); | 1041 | SHOW_SCALE_AVAILABLE_ATTR(12); |
@@ -1053,8 +1052,6 @@ static struct attribute *mxs_lradc_attributes[] = { | |||
1053 | &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr, | 1052 | &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr, |
1054 | &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr, | 1053 | &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr, |
1055 | &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr, | 1054 | &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr, |
1056 | &iio_dev_attr_in_voltage8_scale_available.dev_attr.attr, | ||
1057 | &iio_dev_attr_in_voltage9_scale_available.dev_attr.attr, | ||
1058 | &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr, | 1055 | &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr, |
1059 | &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr, | 1056 | &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr, |
1060 | &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr, | 1057 | &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr, |
@@ -1613,7 +1610,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) | |||
1613 | * of the array. | 1610 | * of the array. |
1614 | */ | 1611 | */ |
1615 | scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >> | 1612 | scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >> |
1616 | (iio->channels[i].scan_type.realbits - s); | 1613 | (LRADC_RESOLUTION - s); |
1617 | lradc->scale_avail[i][s].nano = | 1614 | lradc->scale_avail[i][s].nano = |
1618 | do_div(scale_uv, 100000000) * 10; | 1615 | do_div(scale_uv, 100000000) * 10; |
1619 | lradc->scale_avail[i][s].integer = scale_uv; | 1616 | lradc->scale_avail[i][s].integer = scale_uv; |
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 0a4298b744e6..2b96665da8a2 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c | |||
@@ -629,7 +629,7 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) | |||
629 | struct iio_buffer *buffer; | 629 | struct iio_buffer *buffer; |
630 | 630 | ||
631 | buffer = iio_kfifo_allocate(indio_dev); | 631 | buffer = iio_kfifo_allocate(indio_dev); |
632 | if (buffer) | 632 | if (!buffer) |
633 | return -ENOMEM; | 633 | return -ENOMEM; |
634 | 634 | ||
635 | iio_device_attach_buffer(indio_dev, buffer); | 635 | iio_device_attach_buffer(indio_dev, buffer); |
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 09ef5fb8bae6..236ed66f116a 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c | |||
@@ -88,9 +88,9 @@ static int imx_drm_driver_unload(struct drm_device *drm) | |||
88 | 88 | ||
89 | imx_drm_device_put(); | 89 | imx_drm_device_put(); |
90 | 90 | ||
91 | drm_vblank_cleanup(imxdrm->drm); | 91 | drm_vblank_cleanup(drm); |
92 | drm_kms_helper_poll_fini(imxdrm->drm); | 92 | drm_kms_helper_poll_fini(drm); |
93 | drm_mode_config_cleanup(imxdrm->drm); | 93 | drm_mode_config_cleanup(drm); |
94 | 94 | ||
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
@@ -142,19 +142,19 @@ EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format); | |||
142 | 142 | ||
143 | int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) | 143 | int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) |
144 | { | 144 | { |
145 | return drm_vblank_get(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); | 145 | return drm_vblank_get(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); |
146 | } | 146 | } |
147 | EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get); | 147 | EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get); |
148 | 148 | ||
149 | void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc) | 149 | void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc) |
150 | { | 150 | { |
151 | drm_vblank_put(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); | 151 | drm_vblank_put(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); |
152 | } | 152 | } |
153 | EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put); | 153 | EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put); |
154 | 154 | ||
155 | void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) | 155 | void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) |
156 | { | 156 | { |
157 | drm_handle_vblank(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); | 157 | drm_handle_vblank(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); |
158 | } | 158 | } |
159 | EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); | 159 | EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); |
160 | 160 | ||
@@ -370,29 +370,6 @@ static void imx_drm_connector_unregister( | |||
370 | } | 370 | } |
371 | 371 | ||
372 | /* | 372 | /* |
373 | * register a crtc to the drm core | ||
374 | */ | ||
375 | static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc) | ||
376 | { | ||
377 | struct imx_drm_device *imxdrm = __imx_drm_device(); | ||
378 | int ret; | ||
379 | |||
380 | ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); | ||
381 | if (ret) | ||
382 | return ret; | ||
383 | |||
384 | drm_crtc_helper_add(imx_drm_crtc->crtc, | ||
385 | imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); | ||
386 | |||
387 | drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc, | ||
388 | imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); | ||
389 | |||
390 | drm_mode_group_reinit(imxdrm->drm); | ||
391 | |||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * Called by the CRTC driver when all CRTCs are registered. This | 373 | * Called by the CRTC driver when all CRTCs are registered. This |
397 | * puts all the pieces together and initializes the driver. | 374 | * puts all the pieces together and initializes the driver. |
398 | * Once this is called no more CRTCs can be registered since | 375 | * Once this is called no more CRTCs can be registered since |
@@ -424,15 +401,15 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) | |||
424 | 401 | ||
425 | mutex_lock(&imxdrm->mutex); | 402 | mutex_lock(&imxdrm->mutex); |
426 | 403 | ||
427 | drm_kms_helper_poll_init(imxdrm->drm); | 404 | drm_kms_helper_poll_init(drm); |
428 | 405 | ||
429 | /* setup the grouping for the legacy output */ | 406 | /* setup the grouping for the legacy output */ |
430 | ret = drm_mode_group_init_legacy_group(imxdrm->drm, | 407 | ret = drm_mode_group_init_legacy_group(drm, |
431 | &imxdrm->drm->primary->mode_group); | 408 | &drm->primary->mode_group); |
432 | if (ret) | 409 | if (ret) |
433 | goto err_kms; | 410 | goto err_kms; |
434 | 411 | ||
435 | ret = drm_vblank_init(imxdrm->drm, MAX_CRTC); | 412 | ret = drm_vblank_init(drm, MAX_CRTC); |
436 | if (ret) | 413 | if (ret) |
437 | goto err_kms; | 414 | goto err_kms; |
438 | 415 | ||
@@ -441,7 +418,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) | |||
441 | * by drm timer once a current process gives up ownership of | 418 | * by drm timer once a current process gives up ownership of |
442 | * vblank event.(after drm_vblank_put function is called) | 419 | * vblank event.(after drm_vblank_put function is called) |
443 | */ | 420 | */ |
444 | imxdrm->drm->vblank_disable_allowed = true; | 421 | drm->vblank_disable_allowed = true; |
445 | 422 | ||
446 | if (!imx_drm_device_get()) { | 423 | if (!imx_drm_device_get()) { |
447 | ret = -EINVAL; | 424 | ret = -EINVAL; |
@@ -536,10 +513,18 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, | |||
536 | 513 | ||
537 | *new_crtc = imx_drm_crtc; | 514 | *new_crtc = imx_drm_crtc; |
538 | 515 | ||
539 | ret = imx_drm_crtc_register(imx_drm_crtc); | 516 | ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); |
540 | if (ret) | 517 | if (ret) |
541 | goto err_register; | 518 | goto err_register; |
542 | 519 | ||
520 | drm_crtc_helper_add(crtc, | ||
521 | imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); | ||
522 | |||
523 | drm_crtc_init(imxdrm->drm, crtc, | ||
524 | imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); | ||
525 | |||
526 | drm_mode_group_reinit(imxdrm->drm); | ||
527 | |||
543 | imx_drm_update_possible_crtcs(); | 528 | imx_drm_update_possible_crtcs(); |
544 | 529 | ||
545 | mutex_unlock(&imxdrm->mutex); | 530 | mutex_unlock(&imxdrm->mutex); |
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index f3a1f5e2e492..62ce0e86f14b 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/hdmi.h> | ||
19 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
20 | #include <linux/mfd/syscon.h> | 21 | #include <linux/mfd/syscon.h> |
21 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | 22 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> |
@@ -52,11 +53,6 @@ enum hdmi_datamap { | |||
52 | YCbCr422_12B = 0x12, | 53 | YCbCr422_12B = 0x12, |
53 | }; | 54 | }; |
54 | 55 | ||
55 | enum hdmi_colorimetry { | ||
56 | ITU601, | ||
57 | ITU709, | ||
58 | }; | ||
59 | |||
60 | enum imx_hdmi_devtype { | 56 | enum imx_hdmi_devtype { |
61 | IMX6Q_HDMI, | 57 | IMX6Q_HDMI, |
62 | IMX6DL_HDMI, | 58 | IMX6DL_HDMI, |
@@ -489,12 +485,12 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) | |||
489 | 485 | ||
490 | if (is_color_space_conversion(hdmi)) { | 486 | if (is_color_space_conversion(hdmi)) { |
491 | if (hdmi->hdmi_data.enc_out_format == RGB) { | 487 | if (hdmi->hdmi_data.enc_out_format == RGB) { |
492 | if (hdmi->hdmi_data.colorimetry == ITU601) | 488 | if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) |
493 | csc_coeff = &csc_coeff_rgb_out_eitu601; | 489 | csc_coeff = &csc_coeff_rgb_out_eitu601; |
494 | else | 490 | else |
495 | csc_coeff = &csc_coeff_rgb_out_eitu709; | 491 | csc_coeff = &csc_coeff_rgb_out_eitu709; |
496 | } else if (hdmi->hdmi_data.enc_in_format == RGB) { | 492 | } else if (hdmi->hdmi_data.enc_in_format == RGB) { |
497 | if (hdmi->hdmi_data.colorimetry == ITU601) | 493 | if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) |
498 | csc_coeff = &csc_coeff_rgb_in_eitu601; | 494 | csc_coeff = &csc_coeff_rgb_in_eitu601; |
499 | else | 495 | else |
500 | csc_coeff = &csc_coeff_rgb_in_eitu709; | 496 | csc_coeff = &csc_coeff_rgb_in_eitu709; |
@@ -1140,16 +1136,16 @@ static void hdmi_config_AVI(struct imx_hdmi *hdmi) | |||
1140 | /* Set up colorimetry */ | 1136 | /* Set up colorimetry */ |
1141 | if (hdmi->hdmi_data.enc_out_format == XVYCC444) { | 1137 | if (hdmi->hdmi_data.enc_out_format == XVYCC444) { |
1142 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; | 1138 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; |
1143 | if (hdmi->hdmi_data.colorimetry == ITU601) | 1139 | if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) |
1144 | ext_colorimetry = | 1140 | ext_colorimetry = |
1145 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; | 1141 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; |
1146 | else /* hdmi->hdmi_data.colorimetry == ITU709 */ | 1142 | else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ |
1147 | ext_colorimetry = | 1143 | ext_colorimetry = |
1148 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; | 1144 | HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; |
1149 | } else if (hdmi->hdmi_data.enc_out_format != RGB) { | 1145 | } else if (hdmi->hdmi_data.enc_out_format != RGB) { |
1150 | if (hdmi->hdmi_data.colorimetry == ITU601) | 1146 | if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) |
1151 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; | 1147 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; |
1152 | else /* hdmi->hdmi_data.colorimetry == ITU709 */ | 1148 | else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ |
1153 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; | 1149 | colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; |
1154 | ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; | 1150 | ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; |
1155 | } else { /* Carries no data */ | 1151 | } else { /* Carries no data */ |
@@ -1379,9 +1375,9 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) | |||
1379 | (hdmi->vic == 21) || (hdmi->vic == 22) || | 1375 | (hdmi->vic == 21) || (hdmi->vic == 22) || |
1380 | (hdmi->vic == 2) || (hdmi->vic == 3) || | 1376 | (hdmi->vic == 2) || (hdmi->vic == 3) || |
1381 | (hdmi->vic == 17) || (hdmi->vic == 18)) | 1377 | (hdmi->vic == 17) || (hdmi->vic == 18)) |
1382 | hdmi->hdmi_data.colorimetry = ITU601; | 1378 | hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; |
1383 | else | 1379 | else |
1384 | hdmi->hdmi_data.colorimetry = ITU709; | 1380 | hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; |
1385 | 1381 | ||
1386 | if ((hdmi->vic == 10) || (hdmi->vic == 11) || | 1382 | if ((hdmi->vic == 10) || (hdmi->vic == 11) || |
1387 | (hdmi->vic == 12) || (hdmi->vic == 13) || | 1383 | (hdmi->vic == 12) || (hdmi->vic == 13) || |
diff --git a/drivers/staging/lustre/TODO b/drivers/staging/lustre/TODO index 22742d6d62a8..0a2b6cb3775e 100644 --- a/drivers/staging/lustre/TODO +++ b/drivers/staging/lustre/TODO | |||
@@ -9,5 +9,6 @@ | |||
9 | * Other minor misc cleanups... | 9 | * Other minor misc cleanups... |
10 | 10 | ||
11 | Please send any patches to Greg Kroah-Hartman <greg@kroah.com>, Andreas Dilger | 11 | Please send any patches to Greg Kroah-Hartman <greg@kroah.com>, Andreas Dilger |
12 | <andreas.dilger@intel.com> and Peng Tao <tao.peng@emc.com>. CCing | 12 | <andreas.dilger@intel.com>, Oleg Drokin <oleg.drokin@intel.com> and |
13 | hpdd-discuss <hpdd-discuss@lists.01.org> would be great too. | 13 | Peng Tao <tao.peng@emc.com>. CCing hpdd-discuss <hpdd-discuss@lists.01.org> |
14 | would be great too. | ||
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h index 596a15fc8996..037ae8a6d531 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_kernelcomm.h | |||
@@ -61,6 +61,8 @@ struct kuc_hdr { | |||
61 | __u16 kuc_msglen; /* Including header */ | 61 | __u16 kuc_msglen; /* Including header */ |
62 | } __attribute__((aligned(sizeof(__u64)))); | 62 | } __attribute__((aligned(sizeof(__u64)))); |
63 | 63 | ||
64 | #define KUC_CHANGELOG_MSG_MAXSIZE (sizeof(struct kuc_hdr)+CR_MAXSIZE) | ||
65 | |||
64 | #define KUC_MAGIC 0x191C /*Lustre9etLinC */ | 66 | #define KUC_MAGIC 0x191C /*Lustre9etLinC */ |
65 | #define KUC_FL_BLOCK 0x01 /* Wait for send */ | 67 | #define KUC_FL_BLOCK 0x01 /* Wait for send */ |
66 | 68 | ||
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index d0d942ced01a..dddccca120c9 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h | |||
@@ -120,7 +120,7 @@ do { \ | |||
120 | do { \ | 120 | do { \ |
121 | LASSERT(!in_interrupt() || \ | 121 | LASSERT(!in_interrupt() || \ |
122 | ((size) <= LIBCFS_VMALLOC_SIZE && \ | 122 | ((size) <= LIBCFS_VMALLOC_SIZE && \ |
123 | ((mask) & GFP_ATOMIC)) != 0); \ | 123 | ((mask) & __GFP_WAIT) == 0)); \ |
124 | } while (0) | 124 | } while (0) |
125 | 125 | ||
126 | #define LIBCFS_ALLOC_POST(ptr, size) \ | 126 | #define LIBCFS_ALLOC_POST(ptr, size) \ |
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 93648632ba26..6f58ead20393 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c | |||
@@ -529,7 +529,7 @@ kiblnd_kvaddr_to_page (unsigned long vaddr) | |||
529 | { | 529 | { |
530 | struct page *page; | 530 | struct page *page; |
531 | 531 | ||
532 | if (is_vmalloc_addr(vaddr)) { | 532 | if (is_vmalloc_addr((void *)vaddr)) { |
533 | page = vmalloc_to_page ((void *)vaddr); | 533 | page = vmalloc_to_page ((void *)vaddr); |
534 | LASSERT (page != NULL); | 534 | LASSERT (page != NULL); |
535 | return page; | 535 | return page; |
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 68a4f52ec998..b7b53b579c85 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c | |||
@@ -924,7 +924,7 @@ ksocknal_launch_packet (lnet_ni_t *ni, ksock_tx_t *tx, lnet_process_id_t id) | |||
924 | int | 924 | int |
925 | ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) | 925 | ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) |
926 | { | 926 | { |
927 | int mpflag = 0; | 927 | int mpflag = 1; |
928 | int type = lntmsg->msg_type; | 928 | int type = lntmsg->msg_type; |
929 | lnet_process_id_t target = lntmsg->msg_target; | 929 | lnet_process_id_t target = lntmsg->msg_target; |
930 | unsigned int payload_niov = lntmsg->msg_niov; | 930 | unsigned int payload_niov = lntmsg->msg_niov; |
@@ -993,8 +993,9 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg) | |||
993 | 993 | ||
994 | /* The first fragment will be set later in pro_pack */ | 994 | /* The first fragment will be set later in pro_pack */ |
995 | rc = ksocknal_launch_packet(ni, tx, target); | 995 | rc = ksocknal_launch_packet(ni, tx, target); |
996 | if (lntmsg->msg_vmflush) | 996 | if (!mpflag) |
997 | cfs_memory_pressure_restore(mpflag); | 997 | cfs_memory_pressure_restore(mpflag); |
998 | |||
998 | if (rc == 0) | 999 | if (rc == 0) |
999 | return (0); | 1000 | return (0); |
1000 | 1001 | ||
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index 6b6c0240e824..7893d83e131f 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h | |||
@@ -760,7 +760,8 @@ static inline void hsm_set_cl_error(int *flags, int error) | |||
760 | *flags |= (error << CLF_HSM_ERR_L); | 760 | *flags |= (error << CLF_HSM_ERR_L); |
761 | } | 761 | } |
762 | 762 | ||
763 | #define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + sizeof(struct changelog_rec)) | 763 | #define CR_MAXSIZE cfs_size_round(2*NAME_MAX + 1 + \ |
764 | sizeof(struct changelog_ext_rec)) | ||
764 | 765 | ||
765 | struct changelog_rec { | 766 | struct changelog_rec { |
766 | __u16 cr_namelen; | 767 | __u16 cr_namelen; |
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 22d0acc95bc5..52b7731bcc38 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c | |||
@@ -1086,7 +1086,7 @@ static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) | |||
1086 | break; | 1086 | break; |
1087 | case Q_GETQUOTA: | 1087 | case Q_GETQUOTA: |
1088 | if (((type == USRQUOTA && | 1088 | if (((type == USRQUOTA && |
1089 | uid_eq(current_euid(), make_kuid(&init_user_ns, id))) || | 1089 | !uid_eq(current_euid(), make_kuid(&init_user_ns, id))) || |
1090 | (type == GRPQUOTA && | 1090 | (type == GRPQUOTA && |
1091 | !in_egroup_p(make_kgid(&init_user_ns, id)))) && | 1091 | !in_egroup_p(make_kgid(&init_user_ns, id)))) && |
1092 | (!cfs_capable(CFS_CAP_SYS_ADMIN) || | 1092 | (!cfs_capable(CFS_CAP_SYS_ADMIN) || |
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index d1ad91c34ddc..83013927e131 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c | |||
@@ -1430,7 +1430,7 @@ static struct kuc_hdr *changelog_kuc_hdr(char *buf, int len, int flags) | |||
1430 | { | 1430 | { |
1431 | struct kuc_hdr *lh = (struct kuc_hdr *)buf; | 1431 | struct kuc_hdr *lh = (struct kuc_hdr *)buf; |
1432 | 1432 | ||
1433 | LASSERT(len <= CR_MAXSIZE); | 1433 | LASSERT(len <= KUC_CHANGELOG_MSG_MAXSIZE); |
1434 | 1434 | ||
1435 | lh->kuc_magic = KUC_MAGIC; | 1435 | lh->kuc_magic = KUC_MAGIC; |
1436 | lh->kuc_transport = KUC_TRANSPORT_CHANGELOG; | 1436 | lh->kuc_transport = KUC_TRANSPORT_CHANGELOG; |
@@ -1503,7 +1503,7 @@ static int mdc_changelog_send_thread(void *csdata) | |||
1503 | CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n", | 1503 | CDEBUG(D_CHANGELOG, "changelog to fp=%p start "LPU64"\n", |
1504 | cs->cs_fp, cs->cs_startrec); | 1504 | cs->cs_fp, cs->cs_startrec); |
1505 | 1505 | ||
1506 | OBD_ALLOC(cs->cs_buf, CR_MAXSIZE); | 1506 | OBD_ALLOC(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE); |
1507 | if (cs->cs_buf == NULL) | 1507 | if (cs->cs_buf == NULL) |
1508 | GOTO(out, rc = -ENOMEM); | 1508 | GOTO(out, rc = -ENOMEM); |
1509 | 1509 | ||
@@ -1540,7 +1540,7 @@ out: | |||
1540 | if (ctxt) | 1540 | if (ctxt) |
1541 | llog_ctxt_put(ctxt); | 1541 | llog_ctxt_put(ctxt); |
1542 | if (cs->cs_buf) | 1542 | if (cs->cs_buf) |
1543 | OBD_FREE(cs->cs_buf, CR_MAXSIZE); | 1543 | OBD_FREE(cs->cs_buf, KUC_CHANGELOG_MSG_MAXSIZE); |
1544 | OBD_FREE_PTR(cs); | 1544 | OBD_FREE_PTR(cs); |
1545 | return rc; | 1545 | return rc; |
1546 | } | 1546 | } |
diff --git a/drivers/staging/media/go7007/go7007-loader.c b/drivers/staging/media/go7007/go7007-loader.c index 10bb41c2fb6d..eecb1f2a5574 100644 --- a/drivers/staging/media/go7007/go7007-loader.c +++ b/drivers/staging/media/go7007/go7007-loader.c | |||
@@ -59,7 +59,7 @@ static int go7007_loader_probe(struct usb_interface *interface, | |||
59 | 59 | ||
60 | if (usbdev->descriptor.bNumConfigurations != 1) { | 60 | if (usbdev->descriptor.bNumConfigurations != 1) { |
61 | dev_err(&interface->dev, "can't handle multiple config\n"); | 61 | dev_err(&interface->dev, "can't handle multiple config\n"); |
62 | return -ENODEV; | 62 | goto failed2; |
63 | } | 63 | } |
64 | 64 | ||
65 | vendor = le16_to_cpu(usbdev->descriptor.idVendor); | 65 | vendor = le16_to_cpu(usbdev->descriptor.idVendor); |
@@ -108,6 +108,7 @@ static int go7007_loader_probe(struct usb_interface *interface, | |||
108 | return 0; | 108 | return 0; |
109 | 109 | ||
110 | failed2: | 110 | failed2: |
111 | usb_put_dev(usbdev); | ||
111 | dev_err(&interface->dev, "probe failed\n"); | 112 | dev_err(&interface->dev, "probe failed\n"); |
112 | return -ENODEV; | 113 | return -ENODEV; |
113 | } | 114 | } |
@@ -115,6 +116,7 @@ failed2: | |||
115 | static void go7007_loader_disconnect(struct usb_interface *interface) | 116 | static void go7007_loader_disconnect(struct usb_interface *interface) |
116 | { | 117 | { |
117 | dev_info(&interface->dev, "disconnect\n"); | 118 | dev_info(&interface->dev, "disconnect\n"); |
119 | usb_put_dev(interface_to_usbdev(interface)); | ||
118 | usb_set_intfdata(interface, NULL); | 120 | usb_set_intfdata(interface, NULL); |
119 | } | 121 | } |
120 | 122 | ||
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c index eedffed17e39..31b269a5fff7 100644 --- a/drivers/staging/netlogic/xlr_net.c +++ b/drivers/staging/netlogic/xlr_net.c | |||
@@ -307,7 +307,7 @@ static netdev_tx_t xlr_net_start_xmit(struct sk_buff *skb, | |||
307 | } | 307 | } |
308 | 308 | ||
309 | static u16 xlr_net_select_queue(struct net_device *ndev, struct sk_buff *skb, | 309 | static u16 xlr_net_select_queue(struct net_device *ndev, struct sk_buff *skb, |
310 | void *accel_priv) | 310 | void *accel_priv, select_queue_fallback_t fallback) |
311 | { | 311 | { |
312 | return (u16)smp_processor_id(); | 312 | return (u16)smp_processor_id(); |
313 | } | 313 | } |
@@ -892,6 +892,11 @@ static int xlr_setup_mdio(struct xlr_net_priv *priv, | |||
892 | priv->mii_bus->write = xlr_mii_write; | 892 | priv->mii_bus->write = xlr_mii_write; |
893 | priv->mii_bus->parent = &pdev->dev; | 893 | priv->mii_bus->parent = &pdev->dev; |
894 | priv->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 894 | priv->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
895 | if (priv->mii_bus->irq == NULL) { | ||
896 | pr_err("irq alloc failed\n"); | ||
897 | mdiobus_free(priv->mii_bus); | ||
898 | return -ENOMEM; | ||
899 | } | ||
895 | priv->mii_bus->irq[priv->phy_addr] = priv->ndev->irq; | 900 | priv->mii_bus->irq[priv->phy_addr] = priv->ndev->irq; |
896 | 901 | ||
897 | /* Scan only the enabled address */ | 902 | /* Scan only the enabled address */ |
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c index 47e0a91238a1..5a001d9b4252 100644 --- a/drivers/staging/octeon-usb/octeon-hcd.c +++ b/drivers/staging/octeon-usb/octeon-hcd.c | |||
@@ -275,13 +275,6 @@ enum cvmx_usb_pipe_flags { | |||
275 | */ | 275 | */ |
276 | #define MAX_TRANSFER_PACKETS ((1<<10)-1) | 276 | #define MAX_TRANSFER_PACKETS ((1<<10)-1) |
277 | 277 | ||
278 | enum { | ||
279 | USB_CLOCK_TYPE_REF_12, | ||
280 | USB_CLOCK_TYPE_REF_24, | ||
281 | USB_CLOCK_TYPE_REF_48, | ||
282 | USB_CLOCK_TYPE_CRYSTAL_12, | ||
283 | }; | ||
284 | |||
285 | /** | 278 | /** |
286 | * Logical transactions may take numerous low level | 279 | * Logical transactions may take numerous low level |
287 | * transactions, especially when splits are concerned. This | 280 | * transactions, especially when splits are concerned. This |
@@ -471,19 +464,6 @@ struct octeon_hcd { | |||
471 | /* Returns the IO address to push/pop stuff data from the FIFOs */ | 464 | /* Returns the IO address to push/pop stuff data from the FIFOs */ |
472 | #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000) | 465 | #define USB_FIFO_ADDRESS(channel, usb_index) (CVMX_USBCX_GOTGCTL(usb_index) + ((channel)+1)*0x1000) |
473 | 466 | ||
474 | static int octeon_usb_get_clock_type(void) | ||
475 | { | ||
476 | switch (cvmx_sysinfo_get()->board_type) { | ||
477 | case CVMX_BOARD_TYPE_BBGW_REF: | ||
478 | case CVMX_BOARD_TYPE_LANAI2_A: | ||
479 | case CVMX_BOARD_TYPE_LANAI2_U: | ||
480 | case CVMX_BOARD_TYPE_LANAI2_G: | ||
481 | case CVMX_BOARD_TYPE_UBNT_E100: | ||
482 | return USB_CLOCK_TYPE_CRYSTAL_12; | ||
483 | } | ||
484 | return USB_CLOCK_TYPE_REF_48; | ||
485 | } | ||
486 | |||
487 | /** | 467 | /** |
488 | * Read a USB 32bit CSR. It performs the necessary address swizzle | 468 | * Read a USB 32bit CSR. It performs the necessary address swizzle |
489 | * for 32bit CSRs and logs the value in a readable format if | 469 | * for 32bit CSRs and logs the value in a readable format if |
@@ -582,37 +562,6 @@ static inline int __cvmx_usb_get_data_pid(struct cvmx_usb_pipe *pipe) | |||
582 | return 0; /* Data0 */ | 562 | return 0; /* Data0 */ |
583 | } | 563 | } |
584 | 564 | ||
585 | |||
586 | /** | ||
587 | * Return the number of USB ports supported by this Octeon | ||
588 | * chip. If the chip doesn't support USB, or is not supported | ||
589 | * by this API, a zero will be returned. Most Octeon chips | ||
590 | * support one usb port, but some support two ports. | ||
591 | * cvmx_usb_initialize() must be called on independent | ||
592 | * struct cvmx_usb_state. | ||
593 | * | ||
594 | * Returns: Number of port, zero if usb isn't supported | ||
595 | */ | ||
596 | static int cvmx_usb_get_num_ports(void) | ||
597 | { | ||
598 | int arch_ports = 0; | ||
599 | |||
600 | if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
601 | arch_ports = 1; | ||
602 | else if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
603 | arch_ports = 2; | ||
604 | else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) | ||
605 | arch_ports = 1; | ||
606 | else if (OCTEON_IS_MODEL(OCTEON_CN31XX)) | ||
607 | arch_ports = 1; | ||
608 | else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) | ||
609 | arch_ports = 1; | ||
610 | else | ||
611 | arch_ports = 0; | ||
612 | |||
613 | return arch_ports; | ||
614 | } | ||
615 | |||
616 | /** | 565 | /** |
617 | * Initialize a USB port for use. This must be called before any | 566 | * Initialize a USB port for use. This must be called before any |
618 | * other access to the Octeon USB port is made. The port starts | 567 | * other access to the Octeon USB port is made. The port starts |
@@ -628,41 +577,16 @@ static int cvmx_usb_get_num_ports(void) | |||
628 | * Returns: 0 or a negative error code. | 577 | * Returns: 0 or a negative error code. |
629 | */ | 578 | */ |
630 | static int cvmx_usb_initialize(struct cvmx_usb_state *usb, | 579 | static int cvmx_usb_initialize(struct cvmx_usb_state *usb, |
631 | int usb_port_number) | 580 | int usb_port_number, |
581 | enum cvmx_usb_initialize_flags flags) | ||
632 | { | 582 | { |
633 | union cvmx_usbnx_clk_ctl usbn_clk_ctl; | 583 | union cvmx_usbnx_clk_ctl usbn_clk_ctl; |
634 | union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status; | 584 | union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status; |
635 | enum cvmx_usb_initialize_flags flags = 0; | ||
636 | int i; | 585 | int i; |
637 | 586 | ||
638 | /* At first allow 0-1 for the usb port number */ | 587 | /* At first allow 0-1 for the usb port number */ |
639 | if ((usb_port_number < 0) || (usb_port_number > 1)) | 588 | if ((usb_port_number < 0) || (usb_port_number > 1)) |
640 | return -EINVAL; | 589 | return -EINVAL; |
641 | /* For all chips except 52XX there is only one port */ | ||
642 | if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0)) | ||
643 | return -EINVAL; | ||
644 | /* Try to determine clock type automatically */ | ||
645 | if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) { | ||
646 | /* Only 12 MHZ crystals are supported */ | ||
647 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI; | ||
648 | } else { | ||
649 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND; | ||
650 | |||
651 | switch (octeon_usb_get_clock_type()) { | ||
652 | case USB_CLOCK_TYPE_REF_12: | ||
653 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ; | ||
654 | break; | ||
655 | case USB_CLOCK_TYPE_REF_24: | ||
656 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ; | ||
657 | break; | ||
658 | case USB_CLOCK_TYPE_REF_48: | ||
659 | flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ; | ||
660 | break; | ||
661 | default: | ||
662 | return -EINVAL; | ||
663 | break; | ||
664 | } | ||
665 | } | ||
666 | 590 | ||
667 | memset(usb, 0, sizeof(*usb)); | 591 | memset(usb, 0, sizeof(*usb)); |
668 | usb->init_flags = flags; | 592 | usb->init_flags = flags; |
@@ -3431,7 +3355,6 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
3431 | return 0; | 3355 | return 0; |
3432 | } | 3356 | } |
3433 | 3357 | ||
3434 | |||
3435 | static const struct hc_driver octeon_hc_driver = { | 3358 | static const struct hc_driver octeon_hc_driver = { |
3436 | .description = "Octeon USB", | 3359 | .description = "Octeon USB", |
3437 | .product_desc = "Octeon Host Controller", | 3360 | .product_desc = "Octeon Host Controller", |
@@ -3448,15 +3371,74 @@ static const struct hc_driver octeon_hc_driver = { | |||
3448 | .hub_control = octeon_usb_hub_control, | 3371 | .hub_control = octeon_usb_hub_control, |
3449 | }; | 3372 | }; |
3450 | 3373 | ||
3451 | 3374 | static int octeon_usb_probe(struct platform_device *pdev) | |
3452 | static int octeon_usb_driver_probe(struct device *dev) | ||
3453 | { | 3375 | { |
3454 | int status; | 3376 | int status; |
3455 | int usb_num = to_platform_device(dev)->id; | 3377 | int initialize_flags; |
3456 | int irq = platform_get_irq(to_platform_device(dev), 0); | 3378 | int usb_num; |
3379 | struct resource *res_mem; | ||
3380 | struct device_node *usbn_node; | ||
3381 | int irq = platform_get_irq(pdev, 0); | ||
3382 | struct device *dev = &pdev->dev; | ||
3457 | struct octeon_hcd *priv; | 3383 | struct octeon_hcd *priv; |
3458 | struct usb_hcd *hcd; | 3384 | struct usb_hcd *hcd; |
3459 | unsigned long flags; | 3385 | unsigned long flags; |
3386 | u32 clock_rate = 48000000; | ||
3387 | bool is_crystal_clock = false; | ||
3388 | const char *clock_type; | ||
3389 | int i; | ||
3390 | |||
3391 | if (dev->of_node == NULL) { | ||
3392 | dev_err(dev, "Error: empty of_node\n"); | ||
3393 | return -ENXIO; | ||
3394 | } | ||
3395 | usbn_node = dev->of_node->parent; | ||
3396 | |||
3397 | i = of_property_read_u32(usbn_node, | ||
3398 | "refclk-frequency", &clock_rate); | ||
3399 | if (i) { | ||
3400 | dev_err(dev, "No USBN \"refclk-frequency\"\n"); | ||
3401 | return -ENXIO; | ||
3402 | } | ||
3403 | switch (clock_rate) { | ||
3404 | case 12000000: | ||
3405 | initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ; | ||
3406 | break; | ||
3407 | case 24000000: | ||
3408 | initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ; | ||
3409 | break; | ||
3410 | case 48000000: | ||
3411 | initialize_flags = CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ; | ||
3412 | break; | ||
3413 | default: | ||
3414 | dev_err(dev, "Illebal USBN \"refclk-frequency\" %u\n", clock_rate); | ||
3415 | return -ENXIO; | ||
3416 | |||
3417 | } | ||
3418 | |||
3419 | i = of_property_read_string(usbn_node, | ||
3420 | "refclk-type", &clock_type); | ||
3421 | |||
3422 | if (!i && strcmp("crystal", clock_type) == 0) | ||
3423 | is_crystal_clock = true; | ||
3424 | |||
3425 | if (is_crystal_clock) | ||
3426 | initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI; | ||
3427 | else | ||
3428 | initialize_flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND; | ||
3429 | |||
3430 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
3431 | if (res_mem == NULL) { | ||
3432 | dev_err(dev, "found no memory resource\n"); | ||
3433 | return -ENXIO; | ||
3434 | } | ||
3435 | usb_num = (res_mem->start >> 44) & 1; | ||
3436 | |||
3437 | if (irq < 0) { | ||
3438 | /* Defective device tree, but we know how to fix it. */ | ||
3439 | irq_hw_number_t hwirq = usb_num ? (1 << 6) + 17 : 56; | ||
3440 | irq = irq_create_mapping(NULL, hwirq); | ||
3441 | } | ||
3460 | 3442 | ||
3461 | /* | 3443 | /* |
3462 | * Set the DMA mask to 64bits so we get buffers already translated for | 3444 | * Set the DMA mask to 64bits so we get buffers already translated for |
@@ -3465,6 +3447,26 @@ static int octeon_usb_driver_probe(struct device *dev) | |||
3465 | dev->coherent_dma_mask = ~0; | 3447 | dev->coherent_dma_mask = ~0; |
3466 | dev->dma_mask = &dev->coherent_dma_mask; | 3448 | dev->dma_mask = &dev->coherent_dma_mask; |
3467 | 3449 | ||
3450 | /* | ||
3451 | * Only cn52XX and cn56XX have DWC_OTG USB hardware and the | ||
3452 | * IOB priority registers. Under heavy network load USB | ||
3453 | * hardware can be starved by the IOB causing a crash. Give | ||
3454 | * it a priority boost if it has been waiting more than 400 | ||
3455 | * cycles to avoid this situation. | ||
3456 | * | ||
3457 | * Testing indicates that a cnt_val of 8192 is not sufficient, | ||
3458 | * but no failures are seen with 4096. We choose a value of | ||
3459 | * 400 to give a safety factor of 10. | ||
3460 | */ | ||
3461 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) { | ||
3462 | union cvmx_iob_n2c_l2c_pri_cnt pri_cnt; | ||
3463 | |||
3464 | pri_cnt.u64 = 0; | ||
3465 | pri_cnt.s.cnt_enb = 1; | ||
3466 | pri_cnt.s.cnt_val = 400; | ||
3467 | cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64); | ||
3468 | } | ||
3469 | |||
3468 | hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev)); | 3470 | hcd = usb_create_hcd(&octeon_hc_driver, dev, dev_name(dev)); |
3469 | if (!hcd) { | 3471 | if (!hcd) { |
3470 | dev_dbg(dev, "Failed to allocate memory for HCD\n"); | 3472 | dev_dbg(dev, "Failed to allocate memory for HCD\n"); |
@@ -3478,7 +3480,7 @@ static int octeon_usb_driver_probe(struct device *dev) | |||
3478 | tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv); | 3480 | tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv); |
3479 | INIT_LIST_HEAD(&priv->dequeue_list); | 3481 | INIT_LIST_HEAD(&priv->dequeue_list); |
3480 | 3482 | ||
3481 | status = cvmx_usb_initialize(&priv->usb, usb_num); | 3483 | status = cvmx_usb_initialize(&priv->usb, usb_num, initialize_flags); |
3482 | if (status) { | 3484 | if (status) { |
3483 | dev_dbg(dev, "USB initialization failed with %d\n", status); | 3485 | dev_dbg(dev, "USB initialization failed with %d\n", status); |
3484 | kfree(hcd); | 3486 | kfree(hcd); |
@@ -3492,7 +3494,7 @@ static int octeon_usb_driver_probe(struct device *dev) | |||
3492 | cvmx_usb_poll(&priv->usb); | 3494 | cvmx_usb_poll(&priv->usb); |
3493 | spin_unlock_irqrestore(&priv->lock, flags); | 3495 | spin_unlock_irqrestore(&priv->lock, flags); |
3494 | 3496 | ||
3495 | status = usb_add_hcd(hcd, irq, IRQF_SHARED); | 3497 | status = usb_add_hcd(hcd, irq, 0); |
3496 | if (status) { | 3498 | if (status) { |
3497 | dev_dbg(dev, "USB add HCD failed with %d\n", status); | 3499 | dev_dbg(dev, "USB add HCD failed with %d\n", status); |
3498 | kfree(hcd); | 3500 | kfree(hcd); |
@@ -3500,14 +3502,15 @@ static int octeon_usb_driver_probe(struct device *dev) | |||
3500 | } | 3502 | } |
3501 | device_wakeup_enable(hcd->self.controller); | 3503 | device_wakeup_enable(hcd->self.controller); |
3502 | 3504 | ||
3503 | dev_dbg(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq); | 3505 | dev_info(dev, "Registered HCD for port %d on irq %d\n", usb_num, irq); |
3504 | 3506 | ||
3505 | return 0; | 3507 | return 0; |
3506 | } | 3508 | } |
3507 | 3509 | ||
3508 | static int octeon_usb_driver_remove(struct device *dev) | 3510 | static int octeon_usb_remove(struct platform_device *pdev) |
3509 | { | 3511 | { |
3510 | int status; | 3512 | int status; |
3513 | struct device *dev = &pdev->dev; | ||
3511 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 3514 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
3512 | struct octeon_hcd *priv = hcd_to_octeon(hcd); | 3515 | struct octeon_hcd *priv = hcd_to_octeon(hcd); |
3513 | unsigned long flags; | 3516 | unsigned long flags; |
@@ -3525,85 +3528,41 @@ static int octeon_usb_driver_remove(struct device *dev) | |||
3525 | return 0; | 3528 | return 0; |
3526 | } | 3529 | } |
3527 | 3530 | ||
3528 | static struct device_driver octeon_usb_driver = { | 3531 | static struct of_device_id octeon_usb_match[] = { |
3529 | .name = "OcteonUSB", | 3532 | { |
3530 | .bus = &platform_bus_type, | 3533 | .compatible = "cavium,octeon-5750-usbc", |
3531 | .probe = octeon_usb_driver_probe, | 3534 | }, |
3532 | .remove = octeon_usb_driver_remove, | 3535 | {}, |
3533 | }; | 3536 | }; |
3534 | 3537 | ||
3538 | static struct platform_driver octeon_usb_driver = { | ||
3539 | .driver = { | ||
3540 | .name = "OcteonUSB", | ||
3541 | .owner = THIS_MODULE, | ||
3542 | .of_match_table = octeon_usb_match, | ||
3543 | }, | ||
3544 | .probe = octeon_usb_probe, | ||
3545 | .remove = octeon_usb_remove, | ||
3546 | }; | ||
3535 | 3547 | ||
3536 | #define MAX_USB_PORTS 10 | 3548 | static int __init octeon_usb_driver_init(void) |
3537 | static struct platform_device *pdev_glob[MAX_USB_PORTS]; | ||
3538 | static int octeon_usb_registered; | ||
3539 | static int __init octeon_usb_module_init(void) | ||
3540 | { | 3549 | { |
3541 | int num_devices = cvmx_usb_get_num_ports(); | 3550 | if (usb_disabled()) |
3542 | int device; | 3551 | return 0; |
3543 | |||
3544 | if (usb_disabled() || num_devices == 0) | ||
3545 | return -ENODEV; | ||
3546 | |||
3547 | if (driver_register(&octeon_usb_driver)) | ||
3548 | return -ENOMEM; | ||
3549 | |||
3550 | octeon_usb_registered = 1; | ||
3551 | |||
3552 | /* | ||
3553 | * Only cn52XX and cn56XX have DWC_OTG USB hardware and the | ||
3554 | * IOB priority registers. Under heavy network load USB | ||
3555 | * hardware can be starved by the IOB causing a crash. Give | ||
3556 | * it a priority boost if it has been waiting more than 400 | ||
3557 | * cycles to avoid this situation. | ||
3558 | * | ||
3559 | * Testing indicates that a cnt_val of 8192 is not sufficient, | ||
3560 | * but no failures are seen with 4096. We choose a value of | ||
3561 | * 400 to give a safety factor of 10. | ||
3562 | */ | ||
3563 | if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) { | ||
3564 | union cvmx_iob_n2c_l2c_pri_cnt pri_cnt; | ||
3565 | |||
3566 | pri_cnt.u64 = 0; | ||
3567 | pri_cnt.s.cnt_enb = 1; | ||
3568 | pri_cnt.s.cnt_val = 400; | ||
3569 | cvmx_write_csr(CVMX_IOB_N2C_L2C_PRI_CNT, pri_cnt.u64); | ||
3570 | } | ||
3571 | |||
3572 | for (device = 0; device < num_devices; device++) { | ||
3573 | struct resource irq_resource; | ||
3574 | struct platform_device *pdev; | ||
3575 | memset(&irq_resource, 0, sizeof(irq_resource)); | ||
3576 | irq_resource.start = (device == 0) ? OCTEON_IRQ_USB0 : OCTEON_IRQ_USB1; | ||
3577 | irq_resource.end = irq_resource.start; | ||
3578 | irq_resource.flags = IORESOURCE_IRQ; | ||
3579 | pdev = platform_device_register_simple((char *)octeon_usb_driver. name, device, &irq_resource, 1); | ||
3580 | if (IS_ERR(pdev)) { | ||
3581 | driver_unregister(&octeon_usb_driver); | ||
3582 | octeon_usb_registered = 0; | ||
3583 | return PTR_ERR(pdev); | ||
3584 | } | ||
3585 | if (device < MAX_USB_PORTS) | ||
3586 | pdev_glob[device] = pdev; | ||
3587 | 3552 | ||
3588 | } | 3553 | return platform_driver_register(&octeon_usb_driver); |
3589 | return 0; | ||
3590 | } | 3554 | } |
3555 | module_init(octeon_usb_driver_init); | ||
3591 | 3556 | ||
3592 | static void __exit octeon_usb_module_cleanup(void) | 3557 | static void __exit octeon_usb_driver_exit(void) |
3593 | { | 3558 | { |
3594 | int i; | 3559 | if (usb_disabled()) |
3560 | return; | ||
3595 | 3561 | ||
3596 | for (i = 0; i < MAX_USB_PORTS; i++) | 3562 | platform_driver_unregister(&octeon_usb_driver); |
3597 | if (pdev_glob[i]) { | ||
3598 | platform_device_unregister(pdev_glob[i]); | ||
3599 | pdev_glob[i] = NULL; | ||
3600 | } | ||
3601 | if (octeon_usb_registered) | ||
3602 | driver_unregister(&octeon_usb_driver); | ||
3603 | } | 3563 | } |
3564 | module_exit(octeon_usb_driver_exit); | ||
3604 | 3565 | ||
3605 | MODULE_LICENSE("GPL"); | 3566 | MODULE_LICENSE("GPL"); |
3606 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); | 3567 | MODULE_AUTHOR("Cavium, Inc. <support@cavium.com>"); |
3607 | MODULE_DESCRIPTION("Cavium Networks Octeon USB Host driver."); | 3568 | MODULE_DESCRIPTION("Cavium Inc. OCTEON USB Host driver."); |
3608 | module_init(octeon_usb_module_init); | ||
3609 | module_exit(octeon_usb_module_cleanup); | ||
diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index cb060364dfe7..5d965cf06d59 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c | |||
@@ -668,8 +668,8 @@ void oz_binding_add(const char *net_dev) | |||
668 | if (binding) { | 668 | if (binding) { |
669 | binding->ptype.type = __constant_htons(OZ_ETHERTYPE); | 669 | binding->ptype.type = __constant_htons(OZ_ETHERTYPE); |
670 | binding->ptype.func = oz_pkt_recv; | 670 | binding->ptype.func = oz_pkt_recv; |
671 | memcpy(binding->name, net_dev, OZ_MAX_BINDING_LEN); | ||
672 | if (net_dev && *net_dev) { | 671 | if (net_dev && *net_dev) { |
672 | memcpy(binding->name, net_dev, OZ_MAX_BINDING_LEN); | ||
673 | oz_dbg(ON, "Adding binding: %s\n", net_dev); | 673 | oz_dbg(ON, "Adding binding: %s\n", net_dev); |
674 | binding->ptype.dev = | 674 | binding->ptype.dev = |
675 | dev_get_by_name(&init_net, net_dev); | 675 | dev_get_by_name(&init_net, net_dev); |
@@ -680,6 +680,7 @@ void oz_binding_add(const char *net_dev) | |||
680 | } | 680 | } |
681 | } else { | 681 | } else { |
682 | oz_dbg(ON, "Binding to all netcards\n"); | 682 | oz_dbg(ON, "Binding to all netcards\n"); |
683 | memset(binding->name, 0, OZ_MAX_BINDING_LEN); | ||
683 | binding->ptype.dev = NULL; | 684 | binding->ptype.dev = NULL; |
684 | } | 685 | } |
685 | if (binding) { | 686 | if (binding) { |
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c index 153ec61493ab..96df62f95b6b 100644 --- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c | |||
@@ -912,12 +912,12 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) | |||
912 | unsigned char *pbuf; | 912 | unsigned char *pbuf; |
913 | u32 wpa_ielen = 0; | 913 | u32 wpa_ielen = 0; |
914 | u8 *pbssid = GetAddr3Ptr(pframe); | 914 | u8 *pbssid = GetAddr3Ptr(pframe); |
915 | u32 hidden_ssid = 0; | ||
916 | struct HT_info_element *pht_info = NULL; | 915 | struct HT_info_element *pht_info = NULL; |
917 | struct rtw_ieee80211_ht_cap *pht_cap = NULL; | 916 | struct rtw_ieee80211_ht_cap *pht_cap = NULL; |
918 | u32 bcn_channel; | 917 | u32 bcn_channel; |
919 | unsigned short ht_cap_info; | 918 | unsigned short ht_cap_info; |
920 | unsigned char ht_info_infos_0; | 919 | unsigned char ht_info_infos_0; |
920 | int ssid_len; | ||
921 | 921 | ||
922 | if (is_client_associated_to_ap(Adapter) == false) | 922 | if (is_client_associated_to_ap(Adapter) == false) |
923 | return true; | 923 | return true; |
@@ -999,21 +999,15 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) | |||
999 | } | 999 | } |
1000 | 1000 | ||
1001 | /* checking SSID */ | 1001 | /* checking SSID */ |
1002 | ssid_len = 0; | ||
1002 | p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); | 1003 | p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); |
1003 | if (p == NULL) { | 1004 | if (p) { |
1004 | DBG_88E("%s marc: cannot find SSID for survey event\n", __func__); | 1005 | ssid_len = *(p + 1); |
1005 | hidden_ssid = true; | 1006 | if (ssid_len > NDIS_802_11_LENGTH_SSID) |
1006 | } else { | 1007 | ssid_len = 0; |
1007 | hidden_ssid = false; | ||
1008 | } | ||
1009 | |||
1010 | if ((NULL != p) && (false == hidden_ssid && (*(p + 1)))) { | ||
1011 | memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); | ||
1012 | bssid->Ssid.SsidLength = *(p + 1); | ||
1013 | } else { | ||
1014 | bssid->Ssid.SsidLength = 0; | ||
1015 | bssid->Ssid.Ssid[0] = '\0'; | ||
1016 | } | 1008 | } |
1009 | memcpy(bssid->Ssid.Ssid, (p + 2), ssid_len); | ||
1010 | bssid->Ssid.SsidLength = ssid_len; | ||
1017 | 1011 | ||
1018 | RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d " | 1012 | RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s bssid.Ssid.Ssid:%s bssid.Ssid.SsidLength:%d " |
1019 | "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid, | 1013 | "cur_network->network.Ssid.Ssid:%s len:%d\n", __func__, bssid->Ssid.Ssid, |
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index dec992569476..4ad80ae1067f 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | |||
@@ -2500,7 +2500,7 @@ static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info | |||
2500 | ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n", | 2500 | ("rtw_mp_ioctl_hdl: subcode [%d], len[%d], buffer_len[%d]\r\n", |
2501 | poidparam->subcode, poidparam->len, len)); | 2501 | poidparam->subcode, poidparam->len, len)); |
2502 | 2502 | ||
2503 | if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) { | 2503 | if (poidparam->subcode >= ARRAY_SIZE(mp_ioctl_hdl)) { |
2504 | RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n")); | 2504 | RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("no matching drvext subcodes\r\n")); |
2505 | ret = -EINVAL; | 2505 | ret = -EINVAL; |
2506 | goto _rtw_mp_ioctl_hdl_exit; | 2506 | goto _rtw_mp_ioctl_hdl_exit; |
@@ -3164,9 +3164,7 @@ static int rtw_p2p_get_go_device_address(struct net_device *dev, | |||
3164 | u8 *p2pie; | 3164 | u8 *p2pie; |
3165 | uint p2pielen = 0, attr_contentlen = 0; | 3165 | uint p2pielen = 0, attr_contentlen = 0; |
3166 | u8 attr_content[100] = {0x00}; | 3166 | u8 attr_content[100] = {0x00}; |
3167 | 3167 | u8 go_devadd_str[17 + 12] = {}; | |
3168 | u8 go_devadd_str[17 + 10] = {0x00}; | ||
3169 | /* +10 is for the str "go_devadd =", we have to clear it at wrqu->data.pointer */ | ||
3170 | 3168 | ||
3171 | /* Commented by Albert 20121209 */ | 3169 | /* Commented by Albert 20121209 */ |
3172 | /* The input data is the GO's interface address which the application wants to know its device address. */ | 3170 | /* The input data is the GO's interface address which the application wants to know its device address. */ |
@@ -3223,12 +3221,12 @@ static int rtw_p2p_get_go_device_address(struct net_device *dev, | |||
3223 | spin_unlock_bh(&pmlmepriv->scanned_queue.lock); | 3221 | spin_unlock_bh(&pmlmepriv->scanned_queue.lock); |
3224 | 3222 | ||
3225 | if (!blnMatch) | 3223 | if (!blnMatch) |
3226 | sprintf(go_devadd_str, "\n\ndev_add = NULL"); | 3224 | snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add = NULL"); |
3227 | else | 3225 | else |
3228 | sprintf(go_devadd_str, "\n\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", | 3226 | snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", |
3229 | attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); | 3227 | attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); |
3230 | 3228 | ||
3231 | if (copy_to_user(wrqu->data.pointer, go_devadd_str, 10 + 17)) | 3229 | if (copy_to_user(wrqu->data.pointer, go_devadd_str, sizeof(go_devadd_str))) |
3232 | return -EFAULT; | 3230 | return -EFAULT; |
3233 | return ret; | 3231 | return ret; |
3234 | } | 3232 | } |
diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index 68f98fa114d2..7c9ee58f47bb 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c | |||
@@ -653,7 +653,7 @@ static unsigned int rtw_classify8021d(struct sk_buff *skb) | |||
653 | } | 653 | } |
654 | 654 | ||
655 | static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, | 655 | static u16 rtw_select_queue(struct net_device *dev, struct sk_buff *skb, |
656 | void *accel_priv) | 656 | void *accel_priv, select_queue_fallback_t fallback) |
657 | { | 657 | { |
658 | struct adapter *padapter = rtw_netdev_priv(dev); | 658 | struct adapter *padapter = rtw_netdev_priv(dev); |
659 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; | 659 | struct mlme_priv *pmlmepriv = &padapter->mlmepriv; |
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c index 0a341d6ec51f..2f40ff5901d6 100644 --- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c +++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c | |||
@@ -53,8 +53,9 @@ static struct usb_device_id rtw_usb_id_tbl[] = { | |||
53 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ | 53 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */ |
54 | /*=== Customer ID ===*/ | 54 | /*=== Customer ID ===*/ |
55 | /****** 8188EUS ********/ | 55 | /****** 8188EUS ********/ |
56 | {USB_DEVICE(0x8179, 0x07B8)}, /* Abocom - Abocom */ | 56 | {USB_DEVICE(0x07b8, 0x8179)}, /* Abocom - Abocom */ |
57 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ | 57 | {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */ |
58 | {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */ | ||
58 | {} /* Terminating entry */ | 59 | {} /* Terminating entry */ |
59 | }; | 60 | }; |
60 | 61 | ||
diff --git a/drivers/staging/rtl8821ae/Kconfig b/drivers/staging/rtl8821ae/Kconfig index 2aa5dac2f1df..abccc9dabd65 100644 --- a/drivers/staging/rtl8821ae/Kconfig +++ b/drivers/staging/rtl8821ae/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config R8821AE | 1 | config R8821AE |
2 | tristate "RealTek RTL8821AE Wireless LAN NIC driver" | 2 | tristate "RealTek RTL8821AE Wireless LAN NIC driver" |
3 | depends on PCI && WLAN | 3 | depends on PCI && WLAN && MAC80211 |
4 | depends on m | 4 | depends on m |
5 | select WIRELESS_EXT | 5 | select WIRELESS_EXT |
6 | select WEXT_PRIV | 6 | select WEXT_PRIV |
diff --git a/drivers/staging/rtl8821ae/wifi.h b/drivers/staging/rtl8821ae/wifi.h index cfe88a1efd55..76bef93ad70a 100644 --- a/drivers/staging/rtl8821ae/wifi.h +++ b/drivers/staging/rtl8821ae/wifi.h | |||
@@ -1414,7 +1414,7 @@ struct rtl_dm { | |||
1414 | 1414 | ||
1415 | 1415 | ||
1416 | /*88e tx power tracking*/ | 1416 | /*88e tx power tracking*/ |
1417 | u8 bb_swing_idx_ofdm[2]; | 1417 | u8 bb_swing_idx_ofdm[MAX_RF_PATH]; |
1418 | u8 bb_swing_idx_ofdm_current; | 1418 | u8 bb_swing_idx_ofdm_current; |
1419 | u8 bb_swing_idx_ofdm_base[MAX_RF_PATH]; | 1419 | u8 bb_swing_idx_ofdm_base[MAX_RF_PATH]; |
1420 | bool bb_swing_flag_Ofdm; | 1420 | bool bb_swing_flag_Ofdm; |
diff --git a/drivers/staging/usbip/userspace/libsrc/names.c b/drivers/staging/usbip/userspace/libsrc/names.c index 3c8d28b771e0..81ff8522405c 100644 --- a/drivers/staging/usbip/userspace/libsrc/names.c +++ b/drivers/staging/usbip/userspace/libsrc/names.c | |||
@@ -169,14 +169,14 @@ static void *my_malloc(size_t size) | |||
169 | struct pool *p; | 169 | struct pool *p; |
170 | 170 | ||
171 | p = calloc(1, sizeof(struct pool)); | 171 | p = calloc(1, sizeof(struct pool)); |
172 | if (!p) { | 172 | if (!p) |
173 | free(p); | ||
174 | return NULL; | 173 | return NULL; |
175 | } | ||
176 | 174 | ||
177 | p->mem = calloc(1, size); | 175 | p->mem = calloc(1, size); |
178 | if (!p->mem) | 176 | if (!p->mem) { |
177 | free(p); | ||
179 | return NULL; | 178 | return NULL; |
179 | } | ||
180 | 180 | ||
181 | p->next = pool_head; | 181 | p->next = pool_head; |
182 | pool_head = p; | 182 | pool_head = p; |
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 9b51586d11d9..0141bc34d5cc 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c | |||
@@ -149,7 +149,8 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed) | |||
149 | case USB_SPEED_WIRELESS: | 149 | case USB_SPEED_WIRELESS: |
150 | break; | 150 | break; |
151 | default: | 151 | default: |
152 | pr_err("speed %d\n", speed); | 152 | pr_err("Failed attach request for unsupported USB speed: %s\n", |
153 | usb_speed_string(speed)); | ||
153 | return -EINVAL; | 154 | return -EINVAL; |
154 | } | 155 | } |
155 | 156 | ||
diff --git a/drivers/staging/wlags49_h2/wl_wext.c b/drivers/staging/wlags49_h2/wl_wext.c index 4a1ddaf5e00f..187fc060de26 100644 --- a/drivers/staging/wlags49_h2/wl_wext.c +++ b/drivers/staging/wlags49_h2/wl_wext.c | |||
@@ -1061,7 +1061,7 @@ static int wireless_set_essid(struct net_device *dev, struct iw_request_info *in | |||
1061 | goto out; | 1061 | goto out; |
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | if (data->flags != 0 && data->length > HCF_MAX_NAME_LEN + 1) { | 1064 | if (data->flags != 0 && data->length > HCF_MAX_NAME_LEN) { |
1065 | ret = -EINVAL; | 1065 | ret = -EINVAL; |
1066 | goto out; | 1066 | goto out; |
1067 | } | 1067 | } |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 7f1a7ce4b771..b83ec378d04f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -785,7 +785,7 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
785 | spin_unlock_bh(&conn->cmd_lock); | 785 | spin_unlock_bh(&conn->cmd_lock); |
786 | 786 | ||
787 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { | 787 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { |
788 | list_del(&cmd->i_conn_node); | 788 | list_del_init(&cmd->i_conn_node); |
789 | iscsit_free_cmd(cmd, false); | 789 | iscsit_free_cmd(cmd, false); |
790 | } | 790 | } |
791 | } | 791 | } |
@@ -3708,7 +3708,7 @@ iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state | |||
3708 | break; | 3708 | break; |
3709 | case ISTATE_REMOVE: | 3709 | case ISTATE_REMOVE: |
3710 | spin_lock_bh(&conn->cmd_lock); | 3710 | spin_lock_bh(&conn->cmd_lock); |
3711 | list_del(&cmd->i_conn_node); | 3711 | list_del_init(&cmd->i_conn_node); |
3712 | spin_unlock_bh(&conn->cmd_lock); | 3712 | spin_unlock_bh(&conn->cmd_lock); |
3713 | 3713 | ||
3714 | iscsit_free_cmd(cmd, false); | 3714 | iscsit_free_cmd(cmd, false); |
@@ -4151,7 +4151,7 @@ static void iscsit_release_commands_from_conn(struct iscsi_conn *conn) | |||
4151 | spin_lock_bh(&conn->cmd_lock); | 4151 | spin_lock_bh(&conn->cmd_lock); |
4152 | list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { | 4152 | list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) { |
4153 | 4153 | ||
4154 | list_del(&cmd->i_conn_node); | 4154 | list_del_init(&cmd->i_conn_node); |
4155 | spin_unlock_bh(&conn->cmd_lock); | 4155 | spin_unlock_bh(&conn->cmd_lock); |
4156 | 4156 | ||
4157 | iscsit_increment_maxcmdsn(cmd, sess); | 4157 | iscsit_increment_maxcmdsn(cmd, sess); |
@@ -4196,6 +4196,10 @@ int iscsit_close_connection( | |||
4196 | iscsit_stop_timers_for_cmds(conn); | 4196 | iscsit_stop_timers_for_cmds(conn); |
4197 | iscsit_stop_nopin_response_timer(conn); | 4197 | iscsit_stop_nopin_response_timer(conn); |
4198 | iscsit_stop_nopin_timer(conn); | 4198 | iscsit_stop_nopin_timer(conn); |
4199 | |||
4200 | if (conn->conn_transport->iscsit_wait_conn) | ||
4201 | conn->conn_transport->iscsit_wait_conn(conn); | ||
4202 | |||
4199 | iscsit_free_queue_reqs_for_conn(conn); | 4203 | iscsit_free_queue_reqs_for_conn(conn); |
4200 | 4204 | ||
4201 | /* | 4205 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index e048d6439f4a..cda4d80cfaef 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -507,7 +507,9 @@ int iscsit_handle_status_snack( | |||
507 | u32 last_statsn; | 507 | u32 last_statsn; |
508 | int found_cmd; | 508 | int found_cmd; |
509 | 509 | ||
510 | if (conn->exp_statsn > begrun) { | 510 | if (!begrun) { |
511 | begrun = conn->exp_statsn; | ||
512 | } else if (conn->exp_statsn > begrun) { | ||
511 | pr_err("Got Status SNACK Begrun: 0x%08x, RunLength:" | 513 | pr_err("Got Status SNACK Begrun: 0x%08x, RunLength:" |
512 | " 0x%08x but already got ExpStatSN: 0x%08x on CID:" | 514 | " 0x%08x but already got ExpStatSN: 0x%08x on CID:" |
513 | " %hu.\n", begrun, runlength, conn->exp_statsn, | 515 | " %hu.\n", begrun, runlength, conn->exp_statsn, |
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 33be1fb1df32..4ca8fd2a70db 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c | |||
@@ -138,7 +138,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
138 | list_for_each_entry_safe(cmd, cmd_tmp, | 138 | list_for_each_entry_safe(cmd, cmd_tmp, |
139 | &cr->conn_recovery_cmd_list, i_conn_node) { | 139 | &cr->conn_recovery_cmd_list, i_conn_node) { |
140 | 140 | ||
141 | list_del(&cmd->i_conn_node); | 141 | list_del_init(&cmd->i_conn_node); |
142 | cmd->conn = NULL; | 142 | cmd->conn = NULL; |
143 | spin_unlock(&cr->conn_recovery_cmd_lock); | 143 | spin_unlock(&cr->conn_recovery_cmd_lock); |
144 | iscsit_free_cmd(cmd, true); | 144 | iscsit_free_cmd(cmd, true); |
@@ -160,7 +160,7 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess) | |||
160 | list_for_each_entry_safe(cmd, cmd_tmp, | 160 | list_for_each_entry_safe(cmd, cmd_tmp, |
161 | &cr->conn_recovery_cmd_list, i_conn_node) { | 161 | &cr->conn_recovery_cmd_list, i_conn_node) { |
162 | 162 | ||
163 | list_del(&cmd->i_conn_node); | 163 | list_del_init(&cmd->i_conn_node); |
164 | cmd->conn = NULL; | 164 | cmd->conn = NULL; |
165 | spin_unlock(&cr->conn_recovery_cmd_lock); | 165 | spin_unlock(&cr->conn_recovery_cmd_lock); |
166 | iscsit_free_cmd(cmd, true); | 166 | iscsit_free_cmd(cmd, true); |
@@ -216,7 +216,7 @@ int iscsit_remove_cmd_from_connection_recovery( | |||
216 | } | 216 | } |
217 | cr = cmd->cr; | 217 | cr = cmd->cr; |
218 | 218 | ||
219 | list_del(&cmd->i_conn_node); | 219 | list_del_init(&cmd->i_conn_node); |
220 | return --cr->cmd_count; | 220 | return --cr->cmd_count; |
221 | } | 221 | } |
222 | 222 | ||
@@ -297,7 +297,7 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn) | |||
297 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN)) | 297 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN)) |
298 | continue; | 298 | continue; |
299 | 299 | ||
300 | list_del(&cmd->i_conn_node); | 300 | list_del_init(&cmd->i_conn_node); |
301 | 301 | ||
302 | spin_unlock_bh(&conn->cmd_lock); | 302 | spin_unlock_bh(&conn->cmd_lock); |
303 | iscsit_free_cmd(cmd, true); | 303 | iscsit_free_cmd(cmd, true); |
@@ -335,7 +335,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
335 | /* | 335 | /* |
336 | * Only perform connection recovery on ISCSI_OP_SCSI_CMD or | 336 | * Only perform connection recovery on ISCSI_OP_SCSI_CMD or |
337 | * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call | 337 | * ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call |
338 | * list_del(&cmd->i_conn_node); to release the command to the | 338 | * list_del_init(&cmd->i_conn_node); to release the command to the |
339 | * session pool and remove it from the connection's list. | 339 | * session pool and remove it from the connection's list. |
340 | * | 340 | * |
341 | * Also stop the DataOUT timer, which will be restarted after | 341 | * Also stop the DataOUT timer, which will be restarted after |
@@ -351,7 +351,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
351 | " CID: %hu\n", cmd->iscsi_opcode, | 351 | " CID: %hu\n", cmd->iscsi_opcode, |
352 | cmd->init_task_tag, cmd->cmd_sn, conn->cid); | 352 | cmd->init_task_tag, cmd->cmd_sn, conn->cid); |
353 | 353 | ||
354 | list_del(&cmd->i_conn_node); | 354 | list_del_init(&cmd->i_conn_node); |
355 | spin_unlock_bh(&conn->cmd_lock); | 355 | spin_unlock_bh(&conn->cmd_lock); |
356 | iscsit_free_cmd(cmd, true); | 356 | iscsit_free_cmd(cmd, true); |
357 | spin_lock_bh(&conn->cmd_lock); | 357 | spin_lock_bh(&conn->cmd_lock); |
@@ -371,7 +371,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
371 | */ | 371 | */ |
372 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && | 372 | if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd && |
373 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { | 373 | iscsi_sna_gte(cmd->cmd_sn, conn->sess->exp_cmd_sn)) { |
374 | list_del(&cmd->i_conn_node); | 374 | list_del_init(&cmd->i_conn_node); |
375 | spin_unlock_bh(&conn->cmd_lock); | 375 | spin_unlock_bh(&conn->cmd_lock); |
376 | iscsit_free_cmd(cmd, true); | 376 | iscsit_free_cmd(cmd, true); |
377 | spin_lock_bh(&conn->cmd_lock); | 377 | spin_lock_bh(&conn->cmd_lock); |
@@ -393,7 +393,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn) | |||
393 | 393 | ||
394 | cmd->sess = conn->sess; | 394 | cmd->sess = conn->sess; |
395 | 395 | ||
396 | list_del(&cmd->i_conn_node); | 396 | list_del_init(&cmd->i_conn_node); |
397 | spin_unlock_bh(&conn->cmd_lock); | 397 | spin_unlock_bh(&conn->cmd_lock); |
398 | 398 | ||
399 | iscsit_free_all_datain_reqs(cmd); | 399 | iscsit_free_all_datain_reqs(cmd); |
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 39761837608d..44a5471de00f 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
@@ -137,7 +137,7 @@ struct iscsi_portal_group *iscsit_get_tpg_from_np( | |||
137 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { | 137 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { |
138 | 138 | ||
139 | spin_lock(&tpg->tpg_state_lock); | 139 | spin_lock(&tpg->tpg_state_lock); |
140 | if (tpg->tpg_state == TPG_STATE_FREE) { | 140 | if (tpg->tpg_state != TPG_STATE_ACTIVE) { |
141 | spin_unlock(&tpg->tpg_state_lock); | 141 | spin_unlock(&tpg->tpg_state_lock); |
142 | continue; | 142 | continue; |
143 | } | 143 | } |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 12da9b386169..c3d9df6aaf5f 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -500,7 +500,7 @@ static inline int core_alua_state_lba_dependent( | |||
500 | 500 | ||
501 | if (segment_mult) { | 501 | if (segment_mult) { |
502 | u64 tmp = lba; | 502 | u64 tmp = lba; |
503 | start_lba = sector_div(tmp, segment_size * segment_mult); | 503 | start_lba = do_div(tmp, segment_size * segment_mult); |
504 | 504 | ||
505 | last_lba = first_lba + segment_size - 1; | 505 | last_lba = first_lba + segment_size - 1; |
506 | if (start_lba >= first_lba && | 506 | if (start_lba >= first_lba && |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 2f5d77932c80..3013287a2aaa 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -2009,7 +2009,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2009 | struct t10_reservation *pr_tmpl = &dev->t10_pr; | 2009 | struct t10_reservation *pr_tmpl = &dev->t10_pr; |
2010 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; | 2010 | unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; |
2011 | sense_reason_t ret = TCM_NO_SENSE; | 2011 | sense_reason_t ret = TCM_NO_SENSE; |
2012 | int pr_holder = 0; | 2012 | int pr_holder = 0, type; |
2013 | 2013 | ||
2014 | if (!se_sess || !se_lun) { | 2014 | if (!se_sess || !se_lun) { |
2015 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2015 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
@@ -2131,6 +2131,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2131 | ret = TCM_RESERVATION_CONFLICT; | 2131 | ret = TCM_RESERVATION_CONFLICT; |
2132 | goto out; | 2132 | goto out; |
2133 | } | 2133 | } |
2134 | type = pr_reg->pr_res_type; | ||
2134 | 2135 | ||
2135 | spin_lock(&pr_tmpl->registration_lock); | 2136 | spin_lock(&pr_tmpl->registration_lock); |
2136 | /* | 2137 | /* |
@@ -2161,6 +2162,7 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2161 | * Release the calling I_T Nexus registration now.. | 2162 | * Release the calling I_T Nexus registration now.. |
2162 | */ | 2163 | */ |
2163 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1); | 2164 | __core_scsi3_free_registration(cmd->se_dev, pr_reg, NULL, 1); |
2165 | pr_reg = NULL; | ||
2164 | 2166 | ||
2165 | /* | 2167 | /* |
2166 | * From spc4r17, section 5.7.11.3 Unregistering | 2168 | * From spc4r17, section 5.7.11.3 Unregistering |
@@ -2174,8 +2176,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2174 | * RESERVATIONS RELEASED. | 2176 | * RESERVATIONS RELEASED. |
2175 | */ | 2177 | */ |
2176 | if (pr_holder && | 2178 | if (pr_holder && |
2177 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || | 2179 | (type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY || |
2178 | pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { | 2180 | type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY)) { |
2179 | list_for_each_entry(pr_reg_p, | 2181 | list_for_each_entry(pr_reg_p, |
2180 | &pr_tmpl->registration_list, | 2182 | &pr_tmpl->registration_list, |
2181 | pr_reg_list) { | 2183 | pr_reg_list) { |
@@ -2194,7 +2196,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, | |||
2194 | ret = core_scsi3_update_and_write_aptpl(dev, aptpl); | 2196 | ret = core_scsi3_update_and_write_aptpl(dev, aptpl); |
2195 | 2197 | ||
2196 | out: | 2198 | out: |
2197 | core_scsi3_put_pr_reg(pr_reg); | 2199 | if (pr_reg) |
2200 | core_scsi3_put_pr_reg(pr_reg); | ||
2198 | return ret; | 2201 | return ret; |
2199 | } | 2202 | } |
2200 | 2203 | ||
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index fa3cae393e13..77e6531fb0a1 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -1074,23 +1074,36 @@ sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read, | |||
1074 | struct scatterlist *psg; | 1074 | struct scatterlist *psg; |
1075 | void *paddr, *addr; | 1075 | void *paddr, *addr; |
1076 | unsigned int i, len, left; | 1076 | unsigned int i, len, left; |
1077 | unsigned int offset = sg_off; | ||
1077 | 1078 | ||
1078 | left = sectors * dev->prot_length; | 1079 | left = sectors * dev->prot_length; |
1079 | 1080 | ||
1080 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { | 1081 | for_each_sg(cmd->t_prot_sg, psg, cmd->t_prot_nents, i) { |
1082 | unsigned int psg_len, copied = 0; | ||
1081 | 1083 | ||
1082 | len = min(psg->length, left); | ||
1083 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; | 1084 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
1084 | addr = kmap_atomic(sg_page(sg)) + sg_off; | 1085 | psg_len = min(left, psg->length); |
1086 | while (psg_len) { | ||
1087 | len = min(psg_len, sg->length - offset); | ||
1088 | addr = kmap_atomic(sg_page(sg)) + sg->offset + offset; | ||
1085 | 1089 | ||
1086 | if (read) | 1090 | if (read) |
1087 | memcpy(paddr, addr, len); | 1091 | memcpy(paddr + copied, addr, len); |
1088 | else | 1092 | else |
1089 | memcpy(addr, paddr, len); | 1093 | memcpy(addr, paddr + copied, len); |
1090 | 1094 | ||
1091 | left -= len; | 1095 | left -= len; |
1096 | offset += len; | ||
1097 | copied += len; | ||
1098 | psg_len -= len; | ||
1099 | |||
1100 | if (offset >= sg->length) { | ||
1101 | sg = sg_next(sg); | ||
1102 | offset = 0; | ||
1103 | } | ||
1104 | kunmap_atomic(addr); | ||
1105 | } | ||
1092 | kunmap_atomic(paddr); | 1106 | kunmap_atomic(paddr); |
1093 | kunmap_atomic(addr); | ||
1094 | } | 1107 | } |
1095 | } | 1108 | } |
1096 | 1109 | ||
@@ -1155,7 +1168,7 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1155 | { | 1168 | { |
1156 | struct se_device *dev = cmd->se_dev; | 1169 | struct se_device *dev = cmd->se_dev; |
1157 | struct se_dif_v1_tuple *sdt; | 1170 | struct se_dif_v1_tuple *sdt; |
1158 | struct scatterlist *dsg; | 1171 | struct scatterlist *dsg, *psg = sg; |
1159 | sector_t sector = start; | 1172 | sector_t sector = start; |
1160 | void *daddr, *paddr; | 1173 | void *daddr, *paddr; |
1161 | int i, j, offset = sg_off; | 1174 | int i, j, offset = sg_off; |
@@ -1163,14 +1176,14 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1163 | 1176 | ||
1164 | for_each_sg(cmd->t_data_sg, dsg, cmd->t_data_nents, i) { | 1177 | for_each_sg(cmd->t_data_sg, dsg, cmd->t_data_nents, i) { |
1165 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; | 1178 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; |
1166 | paddr = kmap_atomic(sg_page(sg)) + sg->offset; | 1179 | paddr = kmap_atomic(sg_page(psg)) + sg->offset; |
1167 | 1180 | ||
1168 | for (j = 0; j < dsg->length; j += dev->dev_attrib.block_size) { | 1181 | for (j = 0; j < dsg->length; j += dev->dev_attrib.block_size) { |
1169 | 1182 | ||
1170 | if (offset >= sg->length) { | 1183 | if (offset >= psg->length) { |
1171 | kunmap_atomic(paddr); | 1184 | kunmap_atomic(paddr); |
1172 | sg = sg_next(sg); | 1185 | psg = sg_next(psg); |
1173 | paddr = kmap_atomic(sg_page(sg)) + sg->offset; | 1186 | paddr = kmap_atomic(sg_page(psg)) + psg->offset; |
1174 | offset = 0; | 1187 | offset = 0; |
1175 | } | 1188 | } |
1176 | 1189 | ||
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 43c5ca9878bc..3bebc71ea033 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -440,8 +440,8 @@ check_scsi_name: | |||
440 | padding = ((-scsi_target_len) & 3); | 440 | padding = ((-scsi_target_len) & 3); |
441 | if (padding) | 441 | if (padding) |
442 | scsi_target_len += padding; | 442 | scsi_target_len += padding; |
443 | if (scsi_name_len > 256) | 443 | if (scsi_target_len > 256) |
444 | scsi_name_len = 256; | 444 | scsi_target_len = 256; |
445 | 445 | ||
446 | buf[off-1] = scsi_target_len; | 446 | buf[off-1] = scsi_target_len; |
447 | off += scsi_target_len; | 447 | off += scsi_target_len; |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c50fd9f11aab..2956250b7225 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -669,9 +669,6 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
669 | return; | 669 | return; |
670 | } | 670 | } |
671 | 671 | ||
672 | if (!success) | ||
673 | cmd->transport_state |= CMD_T_FAILED; | ||
674 | |||
675 | /* | 672 | /* |
676 | * Check for case where an explicit ABORT_TASK has been received | 673 | * Check for case where an explicit ABORT_TASK has been received |
677 | * and transport_wait_for_tasks() will be waiting for completion.. | 674 | * and transport_wait_for_tasks() will be waiting for completion.. |
@@ -681,7 +678,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
681 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 678 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
682 | complete(&cmd->t_transport_stop_comp); | 679 | complete(&cmd->t_transport_stop_comp); |
683 | return; | 680 | return; |
684 | } else if (cmd->transport_state & CMD_T_FAILED) { | 681 | } else if (!success) { |
685 | INIT_WORK(&cmd->work, target_complete_failure_work); | 682 | INIT_WORK(&cmd->work, target_complete_failure_work); |
686 | } else { | 683 | } else { |
687 | INIT_WORK(&cmd->work, target_complete_ok_work); | 684 | INIT_WORK(&cmd->work, target_complete_ok_work); |
@@ -1604,6 +1601,9 @@ void transport_generic_request_failure(struct se_cmd *cmd, | |||
1604 | case TCM_CHECK_CONDITION_ABORT_CMD: | 1601 | case TCM_CHECK_CONDITION_ABORT_CMD: |
1605 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: | 1602 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1606 | case TCM_CHECK_CONDITION_NOT_READY: | 1603 | case TCM_CHECK_CONDITION_NOT_READY: |
1604 | case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED: | ||
1605 | case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: | ||
1606 | case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: | ||
1607 | break; | 1607 | break; |
1608 | case TCM_OUT_OF_RESOURCES: | 1608 | case TCM_OUT_OF_RESOURCES: |
1609 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1609 | sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 35c066489a19..5f88d767671e 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -136,6 +136,7 @@ config SPEAR_THERMAL | |||
136 | config RCAR_THERMAL | 136 | config RCAR_THERMAL |
137 | tristate "Renesas R-Car thermal driver" | 137 | tristate "Renesas R-Car thermal driver" |
138 | depends on ARCH_SHMOBILE || COMPILE_TEST | 138 | depends on ARCH_SHMOBILE || COMPILE_TEST |
139 | depends on HAS_IOMEM | ||
139 | help | 140 | help |
140 | Enable this to plug the R-Car thermal sensor driver into the Linux | 141 | Enable this to plug the R-Car thermal sensor driver into the Linux |
141 | thermal framework. | 142 | thermal framework. |
@@ -210,8 +211,16 @@ config ACPI_INT3403_THERMAL | |||
210 | tristate "ACPI INT3403 thermal driver" | 211 | tristate "ACPI INT3403 thermal driver" |
211 | depends on X86 && ACPI | 212 | depends on X86 && ACPI |
212 | help | 213 | help |
213 | This driver uses ACPI INT3403 device objects. If present, it will | 214 | Newer laptops and tablets that use ACPI may have thermal sensors |
214 | register each INT3403 thermal sensor as a thermal zone. | 215 | outside the core CPU/SOC for thermal safety reasons. These |
216 | temperature sensors are also exposed for the OS to use via the so | ||
217 | called INT3403 ACPI object. This driver will, on devices that have | ||
218 | such sensors, expose the temperature information from these sensors | ||
219 | to userspace via the normal thermal framework. This means that a wide | ||
220 | range of applications and GUI widgets can show this information to | ||
221 | the user or use this information for making decisions. For example, | ||
222 | the Intel Thermal Daemon can use this information to allow the user | ||
223 | to select his laptop to run without turning on the fans. | ||
215 | 224 | ||
216 | menu "Texas Instruments thermal drivers" | 225 | menu "Texas Instruments thermal drivers" |
217 | source "drivers/thermal/ti-soc-thermal/Kconfig" | 226 | source "drivers/thermal/ti-soc-thermal/Kconfig" |
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 338a88bf6662..71b0ec0c370d 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c | |||
@@ -56,10 +56,15 @@ static LIST_HEAD(thermal_governor_list); | |||
56 | static DEFINE_MUTEX(thermal_list_lock); | 56 | static DEFINE_MUTEX(thermal_list_lock); |
57 | static DEFINE_MUTEX(thermal_governor_lock); | 57 | static DEFINE_MUTEX(thermal_governor_lock); |
58 | 58 | ||
59 | static struct thermal_governor *def_governor; | ||
60 | |||
59 | static struct thermal_governor *__find_governor(const char *name) | 61 | static struct thermal_governor *__find_governor(const char *name) |
60 | { | 62 | { |
61 | struct thermal_governor *pos; | 63 | struct thermal_governor *pos; |
62 | 64 | ||
65 | if (!name || !name[0]) | ||
66 | return def_governor; | ||
67 | |||
63 | list_for_each_entry(pos, &thermal_governor_list, governor_list) | 68 | list_for_each_entry(pos, &thermal_governor_list, governor_list) |
64 | if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) | 69 | if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH)) |
65 | return pos; | 70 | return pos; |
@@ -82,17 +87,23 @@ int thermal_register_governor(struct thermal_governor *governor) | |||
82 | if (__find_governor(governor->name) == NULL) { | 87 | if (__find_governor(governor->name) == NULL) { |
83 | err = 0; | 88 | err = 0; |
84 | list_add(&governor->governor_list, &thermal_governor_list); | 89 | list_add(&governor->governor_list, &thermal_governor_list); |
90 | if (!def_governor && !strncmp(governor->name, | ||
91 | DEFAULT_THERMAL_GOVERNOR, THERMAL_NAME_LENGTH)) | ||
92 | def_governor = governor; | ||
85 | } | 93 | } |
86 | 94 | ||
87 | mutex_lock(&thermal_list_lock); | 95 | mutex_lock(&thermal_list_lock); |
88 | 96 | ||
89 | list_for_each_entry(pos, &thermal_tz_list, node) { | 97 | list_for_each_entry(pos, &thermal_tz_list, node) { |
98 | /* | ||
99 | * only thermal zones with specified tz->tzp->governor_name | ||
100 | * may run with tz->govenor unset | ||
101 | */ | ||
90 | if (pos->governor) | 102 | if (pos->governor) |
91 | continue; | 103 | continue; |
92 | if (pos->tzp) | 104 | |
93 | name = pos->tzp->governor_name; | 105 | name = pos->tzp->governor_name; |
94 | else | 106 | |
95 | name = DEFAULT_THERMAL_GOVERNOR; | ||
96 | if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) | 107 | if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH)) |
97 | pos->governor = governor; | 108 | pos->governor = governor; |
98 | } | 109 | } |
@@ -342,8 +353,8 @@ static void monitor_thermal_zone(struct thermal_zone_device *tz) | |||
342 | static void handle_non_critical_trips(struct thermal_zone_device *tz, | 353 | static void handle_non_critical_trips(struct thermal_zone_device *tz, |
343 | int trip, enum thermal_trip_type trip_type) | 354 | int trip, enum thermal_trip_type trip_type) |
344 | { | 355 | { |
345 | if (tz->governor) | 356 | tz->governor ? tz->governor->throttle(tz, trip) : |
346 | tz->governor->throttle(tz, trip); | 357 | def_governor->throttle(tz, trip); |
347 | } | 358 | } |
348 | 359 | ||
349 | static void handle_critical_trips(struct thermal_zone_device *tz, | 360 | static void handle_critical_trips(struct thermal_zone_device *tz, |
@@ -1107,7 +1118,7 @@ __thermal_cooling_device_register(struct device_node *np, | |||
1107 | INIT_LIST_HEAD(&cdev->thermal_instances); | 1118 | INIT_LIST_HEAD(&cdev->thermal_instances); |
1108 | cdev->np = np; | 1119 | cdev->np = np; |
1109 | cdev->ops = ops; | 1120 | cdev->ops = ops; |
1110 | cdev->updated = true; | 1121 | cdev->updated = false; |
1111 | cdev->device.class = &thermal_class; | 1122 | cdev->device.class = &thermal_class; |
1112 | cdev->devdata = devdata; | 1123 | cdev->devdata = devdata; |
1113 | dev_set_name(&cdev->device, "cooling_device%d", cdev->id); | 1124 | dev_set_name(&cdev->device, "cooling_device%d", cdev->id); |
@@ -1533,7 +1544,7 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, | |||
1533 | if (tz->tzp) | 1544 | if (tz->tzp) |
1534 | tz->governor = __find_governor(tz->tzp->governor_name); | 1545 | tz->governor = __find_governor(tz->tzp->governor_name); |
1535 | else | 1546 | else |
1536 | tz->governor = __find_governor(DEFAULT_THERMAL_GOVERNOR); | 1547 | tz->governor = def_governor; |
1537 | 1548 | ||
1538 | mutex_unlock(&thermal_governor_lock); | 1549 | mutex_unlock(&thermal_governor_lock); |
1539 | 1550 | ||
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c index 972e1c73722a..081fd7e6a9f0 100644 --- a/drivers/thermal/x86_pkg_temp_thermal.c +++ b/drivers/thermal/x86_pkg_temp_thermal.c | |||
@@ -68,6 +68,10 @@ struct phy_dev_entry { | |||
68 | struct thermal_zone_device *tzone; | 68 | struct thermal_zone_device *tzone; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static const struct thermal_zone_params pkg_temp_tz_params = { | ||
72 | .no_hwmon = true, | ||
73 | }; | ||
74 | |||
71 | /* List maintaining number of package instances */ | 75 | /* List maintaining number of package instances */ |
72 | static LIST_HEAD(phy_dev_list); | 76 | static LIST_HEAD(phy_dev_list); |
73 | static DEFINE_MUTEX(phy_dev_list_mutex); | 77 | static DEFINE_MUTEX(phy_dev_list_mutex); |
@@ -394,7 +398,6 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) | |||
394 | int err; | 398 | int err; |
395 | u32 tj_max; | 399 | u32 tj_max; |
396 | struct phy_dev_entry *phy_dev_entry; | 400 | struct phy_dev_entry *phy_dev_entry; |
397 | char buffer[30]; | ||
398 | int thres_count; | 401 | int thres_count; |
399 | u32 eax, ebx, ecx, edx; | 402 | u32 eax, ebx, ecx, edx; |
400 | u8 *temp; | 403 | u8 *temp; |
@@ -440,13 +443,11 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) | |||
440 | phy_dev_entry->first_cpu = cpu; | 443 | phy_dev_entry->first_cpu = cpu; |
441 | phy_dev_entry->tj_max = tj_max; | 444 | phy_dev_entry->tj_max = tj_max; |
442 | phy_dev_entry->ref_cnt = 1; | 445 | phy_dev_entry->ref_cnt = 1; |
443 | snprintf(buffer, sizeof(buffer), "pkg-temp-%d\n", | 446 | phy_dev_entry->tzone = thermal_zone_device_register("x86_pkg_temp", |
444 | phy_dev_entry->phys_proc_id); | ||
445 | phy_dev_entry->tzone = thermal_zone_device_register(buffer, | ||
446 | thres_count, | 447 | thres_count, |
447 | (thres_count == MAX_NUMBER_OF_TRIPS) ? | 448 | (thres_count == MAX_NUMBER_OF_TRIPS) ? |
448 | 0x03 : 0x01, | 449 | 0x03 : 0x01, |
449 | phy_dev_entry, &tzone_ops, NULL, 0, 0); | 450 | phy_dev_entry, &tzone_ops, &pkg_temp_tz_params, 0, 0); |
450 | if (IS_ERR(phy_dev_entry->tzone)) { | 451 | if (IS_ERR(phy_dev_entry->tzone)) { |
451 | err = PTR_ERR(phy_dev_entry->tzone); | 452 | err = PTR_ERR(phy_dev_entry->tzone); |
452 | goto err_ret_free; | 453 | goto err_ret_free; |
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 6496872e2e47..b01659bd4f7c 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c | |||
@@ -255,13 +255,7 @@ static int __init hvc_opal_init(void) | |||
255 | /* Register as a vio device to receive callbacks */ | 255 | /* Register as a vio device to receive callbacks */ |
256 | return platform_driver_register(&hvc_opal_driver); | 256 | return platform_driver_register(&hvc_opal_driver); |
257 | } | 257 | } |
258 | module_init(hvc_opal_init); | 258 | device_initcall(hvc_opal_init); |
259 | |||
260 | static void __exit hvc_opal_exit(void) | ||
261 | { | ||
262 | platform_driver_unregister(&hvc_opal_driver); | ||
263 | } | ||
264 | module_exit(hvc_opal_exit); | ||
265 | 259 | ||
266 | static void udbg_opal_putc(char c) | 260 | static void udbg_opal_putc(char c) |
267 | { | 261 | { |
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index 0069bb86ba49..08c87920b74a 100644 --- a/drivers/tty/hvc/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c | |||
@@ -102,17 +102,7 @@ static int __init hvc_rtas_init(void) | |||
102 | 102 | ||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | module_init(hvc_rtas_init); | 105 | device_initcall(hvc_rtas_init); |
106 | |||
107 | /* This will tear down the tty portion of the driver */ | ||
108 | static void __exit hvc_rtas_exit(void) | ||
109 | { | ||
110 | /* Really the fun isn't over until the worker thread breaks down and | ||
111 | * the tty cleans up */ | ||
112 | if (hvc_rtas_dev) | ||
113 | hvc_remove(hvc_rtas_dev); | ||
114 | } | ||
115 | module_exit(hvc_rtas_exit); | ||
116 | 106 | ||
117 | /* This will happen prior to module init. There is no tty at this time? */ | 107 | /* This will happen prior to module init. There is no tty at this time? */ |
118 | static int __init hvc_rtas_console_init(void) | 108 | static int __init hvc_rtas_console_init(void) |
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c index 72228276fe31..9cf573d06a29 100644 --- a/drivers/tty/hvc/hvc_udbg.c +++ b/drivers/tty/hvc/hvc_udbg.c | |||
@@ -80,14 +80,7 @@ static int __init hvc_udbg_init(void) | |||
80 | 80 | ||
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | module_init(hvc_udbg_init); | 83 | device_initcall(hvc_udbg_init); |
84 | |||
85 | static void __exit hvc_udbg_exit(void) | ||
86 | { | ||
87 | if (hvc_udbg_dev) | ||
88 | hvc_remove(hvc_udbg_dev); | ||
89 | } | ||
90 | module_exit(hvc_udbg_exit); | ||
91 | 84 | ||
92 | static int __init hvc_udbg_console_init(void) | 85 | static int __init hvc_udbg_console_init(void) |
93 | { | 86 | { |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 636c9baad7a5..2dc2831840ca 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -561,18 +561,7 @@ static int __init xen_hvc_init(void) | |||
561 | #endif | 561 | #endif |
562 | return r; | 562 | return r; |
563 | } | 563 | } |
564 | 564 | device_initcall(xen_hvc_init); | |
565 | static void __exit xen_hvc_fini(void) | ||
566 | { | ||
567 | struct xencons_info *entry, *next; | ||
568 | |||
569 | if (list_empty(&xenconsoles)) | ||
570 | return; | ||
571 | |||
572 | list_for_each_entry_safe(entry, next, &xenconsoles, list) { | ||
573 | xen_console_remove(entry); | ||
574 | } | ||
575 | } | ||
576 | 565 | ||
577 | static int xen_cons_init(void) | 566 | static int xen_cons_init(void) |
578 | { | 567 | { |
@@ -598,10 +587,6 @@ static int xen_cons_init(void) | |||
598 | hvc_instantiate(HVC_COOKIE, 0, ops); | 587 | hvc_instantiate(HVC_COOKIE, 0, ops); |
599 | return 0; | 588 | return 0; |
600 | } | 589 | } |
601 | |||
602 | |||
603 | module_init(xen_hvc_init); | ||
604 | module_exit(xen_hvc_fini); | ||
605 | console_initcall(xen_cons_init); | 590 | console_initcall(xen_cons_init); |
606 | 591 | ||
607 | #ifdef CONFIG_EARLY_PRINTK | 592 | #ifdef CONFIG_EARLY_PRINTK |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index f34461c5f14e..2ebe47b78a3e 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1090,6 +1090,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) | |||
1090 | { | 1090 | { |
1091 | unsigned int addr = 0; | 1091 | unsigned int addr = 0; |
1092 | unsigned int modem = 0; | 1092 | unsigned int modem = 0; |
1093 | unsigned int brk = 0; | ||
1093 | struct gsm_dlci *dlci; | 1094 | struct gsm_dlci *dlci; |
1094 | int len = clen; | 1095 | int len = clen; |
1095 | u8 *dp = data; | 1096 | u8 *dp = data; |
@@ -1116,6 +1117,16 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) | |||
1116 | if (len == 0) | 1117 | if (len == 0) |
1117 | return; | 1118 | return; |
1118 | } | 1119 | } |
1120 | len--; | ||
1121 | if (len > 0) { | ||
1122 | while (gsm_read_ea(&brk, *dp++) == 0) { | ||
1123 | len--; | ||
1124 | if (len == 0) | ||
1125 | return; | ||
1126 | } | ||
1127 | modem <<= 7; | ||
1128 | modem |= (brk & 0x7f); | ||
1129 | } | ||
1119 | tty = tty_port_tty_get(&dlci->port); | 1130 | tty = tty_port_tty_get(&dlci->port); |
1120 | gsm_process_modem(tty, dlci, modem, clen); | 1131 | gsm_process_modem(tty, dlci, modem, clen); |
1121 | if (tty) { | 1132 | if (tty) { |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index cb8017aa4434..d15624c1b751 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -817,8 +817,7 @@ static void process_echoes(struct tty_struct *tty) | |||
817 | struct n_tty_data *ldata = tty->disc_data; | 817 | struct n_tty_data *ldata = tty->disc_data; |
818 | size_t echoed; | 818 | size_t echoed; |
819 | 819 | ||
820 | if ((!L_ECHO(tty) && !L_ECHONL(tty)) || | 820 | if (ldata->echo_mark == ldata->echo_tail) |
821 | ldata->echo_mark == ldata->echo_tail) | ||
822 | return; | 821 | return; |
823 | 822 | ||
824 | mutex_lock(&ldata->output_lock); | 823 | mutex_lock(&ldata->output_lock); |
@@ -1244,7 +1243,8 @@ n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c) | |||
1244 | if (L_ECHO(tty)) { | 1243 | if (L_ECHO(tty)) { |
1245 | echo_char(c, tty); | 1244 | echo_char(c, tty); |
1246 | commit_echoes(tty); | 1245 | commit_echoes(tty); |
1247 | } | 1246 | } else |
1247 | process_echoes(tty); | ||
1248 | isig(signal, tty); | 1248 | isig(signal, tty); |
1249 | return; | 1249 | return; |
1250 | } | 1250 | } |
@@ -1274,7 +1274,7 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c) | |||
1274 | if (I_IXON(tty)) { | 1274 | if (I_IXON(tty)) { |
1275 | if (c == START_CHAR(tty)) { | 1275 | if (c == START_CHAR(tty)) { |
1276 | start_tty(tty); | 1276 | start_tty(tty); |
1277 | commit_echoes(tty); | 1277 | process_echoes(tty); |
1278 | return 0; | 1278 | return 0; |
1279 | } | 1279 | } |
1280 | if (c == STOP_CHAR(tty)) { | 1280 | if (c == STOP_CHAR(tty)) { |
@@ -1820,8 +1820,10 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1820 | * Fix tty hang when I_IXON(tty) is cleared, but the tty | 1820 | * Fix tty hang when I_IXON(tty) is cleared, but the tty |
1821 | * been stopped by STOP_CHAR(tty) before it. | 1821 | * been stopped by STOP_CHAR(tty) before it. |
1822 | */ | 1822 | */ |
1823 | if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) | 1823 | if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { |
1824 | start_tty(tty); | 1824 | start_tty(tty); |
1825 | process_echoes(tty); | ||
1826 | } | ||
1825 | 1827 | ||
1826 | /* The termios change make the tty ready for I/O */ | 1828 | /* The termios change make the tty ready for I/O */ |
1827 | if (waitqueue_active(&tty->write_wait)) | 1829 | if (waitqueue_active(&tty->write_wait)) |
@@ -1896,7 +1898,7 @@ err: | |||
1896 | static inline int input_available_p(struct tty_struct *tty, int poll) | 1898 | static inline int input_available_p(struct tty_struct *tty, int poll) |
1897 | { | 1899 | { |
1898 | struct n_tty_data *ldata = tty->disc_data; | 1900 | struct n_tty_data *ldata = tty->disc_data; |
1899 | int amt = poll && !TIME_CHAR(tty) ? MIN_CHAR(tty) : 1; | 1901 | int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1; |
1900 | 1902 | ||
1901 | if (ldata->icanon && !L_EXTPROC(tty)) { | 1903 | if (ldata->icanon && !L_EXTPROC(tty)) { |
1902 | if (ldata->canon_head != ldata->read_tail) | 1904 | if (ldata->canon_head != ldata->read_tail) |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 61ecd709a722..69932b7556cf 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -2433,6 +2433,24 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2433 | serial_dl_write(up, quot); | 2433 | serial_dl_write(up, quot); |
2434 | 2434 | ||
2435 | /* | 2435 | /* |
2436 | * XR17V35x UARTs have an extra fractional divisor register (DLD) | ||
2437 | * | ||
2438 | * We need to recalculate all of the registers, because DLM and DLL | ||
2439 | * are already rounded to a whole integer. | ||
2440 | * | ||
2441 | * When recalculating we use a 32x clock instead of a 16x clock to | ||
2442 | * allow 1-bit for rounding in the fractional part. | ||
2443 | */ | ||
2444 | if (up->port.type == PORT_XR17V35X) { | ||
2445 | unsigned int baud_x32 = (port->uartclk * 2) / baud; | ||
2446 | u16 quot = baud_x32 / 32; | ||
2447 | u8 quot_frac = DIV_ROUND_CLOSEST(baud_x32 % 32, 2); | ||
2448 | |||
2449 | serial_dl_write(up, quot); | ||
2450 | serial_port_out(port, 0x2, quot_frac & 0xf); | ||
2451 | } | ||
2452 | |||
2453 | /* | ||
2436 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR | 2454 | * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR |
2437 | * is written without DLAB set, this mode will be disabled. | 2455 | * is written without DLAB set, this mode will be disabled. |
2438 | */ | 2456 | */ |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index faa64e646100..ed3113576740 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -391,7 +391,7 @@ static int dw8250_remove(struct platform_device *pdev) | |||
391 | return 0; | 391 | return 0; |
392 | } | 392 | } |
393 | 393 | ||
394 | #ifdef CONFIG_PM | 394 | #ifdef CONFIG_PM_SLEEP |
395 | static int dw8250_suspend(struct device *dev) | 395 | static int dw8250_suspend(struct device *dev) |
396 | { | 396 | { |
397 | struct dw8250_data *data = dev_get_drvdata(dev); | 397 | struct dw8250_data *data = dev_get_drvdata(dev); |
@@ -409,7 +409,7 @@ static int dw8250_resume(struct device *dev) | |||
409 | 409 | ||
410 | return 0; | 410 | return 0; |
411 | } | 411 | } |
412 | #endif /* CONFIG_PM */ | 412 | #endif /* CONFIG_PM_SLEEP */ |
413 | 413 | ||
414 | #ifdef CONFIG_PM_RUNTIME | 414 | #ifdef CONFIG_PM_RUNTIME |
415 | static int dw8250_runtime_suspend(struct device *dev) | 415 | static int dw8250_runtime_suspend(struct device *dev) |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 50228eed3b6f..0ff3e3624d4c 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -783,7 +783,8 @@ static int pci_netmos_9900_setup(struct serial_private *priv, | |||
783 | { | 783 | { |
784 | unsigned int bar; | 784 | unsigned int bar; |
785 | 785 | ||
786 | if ((priv->dev->subsystem_device & 0xff00) == 0x3000) { | 786 | if ((priv->dev->device != PCI_DEVICE_ID_NETMOS_9865) && |
787 | (priv->dev->subsystem_device & 0xff00) == 0x3000) { | ||
787 | /* netmos apparently orders BARs by datasheet layout, so serial | 788 | /* netmos apparently orders BARs by datasheet layout, so serial |
788 | * ports get BARs 0 and 3 (or 1 and 4 for memmapped) | 789 | * ports get BARs 0 and 3 (or 1 and 4 for memmapped) |
789 | */ | 790 | */ |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fa511ebab67c..77f035158d6c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -738,9 +738,6 @@ static int serial_omap_startup(struct uart_port *port) | |||
738 | return retval; | 738 | return retval; |
739 | } | 739 | } |
740 | disable_irq(up->wakeirq); | 740 | disable_irq(up->wakeirq); |
741 | } else { | ||
742 | dev_info(up->port.dev, "no wakeirq for uart%d\n", | ||
743 | up->port.line); | ||
744 | } | 741 | } |
745 | 742 | ||
746 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); | 743 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); |
@@ -1604,8 +1601,11 @@ static int serial_omap_probe_rs485(struct uart_omap_port *up, | |||
1604 | flags & SER_RS485_RTS_AFTER_SEND); | 1601 | flags & SER_RS485_RTS_AFTER_SEND); |
1605 | if (ret < 0) | 1602 | if (ret < 0) |
1606 | return ret; | 1603 | return ret; |
1607 | } else | 1604 | } else if (up->rts_gpio == -EPROBE_DEFER) { |
1605 | return -EPROBE_DEFER; | ||
1606 | } else { | ||
1608 | up->rts_gpio = -EINVAL; | 1607 | up->rts_gpio = -EINVAL; |
1608 | } | ||
1609 | 1609 | ||
1610 | if (of_property_read_u32_array(np, "rs485-rts-delay", | 1610 | if (of_property_read_u32_array(np, "rs485-rts-delay", |
1611 | rs485_delay, 2) == 0) { | 1611 | rs485_delay, 2) == 0) { |
@@ -1687,6 +1687,9 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1687 | up->port.iotype = UPIO_MEM; | 1687 | up->port.iotype = UPIO_MEM; |
1688 | up->port.irq = uartirq; | 1688 | up->port.irq = uartirq; |
1689 | up->wakeirq = wakeirq; | 1689 | up->wakeirq = wakeirq; |
1690 | if (!up->wakeirq) | ||
1691 | dev_info(up->port.dev, "no wakeirq for uart%d\n", | ||
1692 | up->port.line); | ||
1690 | 1693 | ||
1691 | up->port.regshift = 2; | 1694 | up->port.regshift = 2; |
1692 | up->port.fifosize = 64; | 1695 | up->port.fifosize = 64; |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 49a2ffd101a7..b7bfe24d4ebc 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -542,8 +542,10 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param) | |||
542 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | 542 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, |
543 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | | 543 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | |
544 | SIRFUART_IO_MODE); | 544 | SIRFUART_IO_MODE); |
545 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); | ||
546 | spin_unlock_irqrestore(&sirfport->rx_lock, flags); | 545 | spin_unlock_irqrestore(&sirfport->rx_lock, flags); |
546 | spin_lock(&port->lock); | ||
547 | sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count); | ||
548 | spin_unlock(&port->lock); | ||
547 | if (sirfport->rx_io_count == 4) { | 549 | if (sirfport->rx_io_count == 4) { |
548 | spin_lock_irqsave(&sirfport->rx_lock, flags); | 550 | spin_lock_irqsave(&sirfport->rx_lock, flags); |
549 | sirfport->rx_io_count = 0; | 551 | sirfport->rx_io_count = 0; |
diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index cf86e729532b..dc697cee248a 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c | |||
@@ -433,13 +433,10 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign | |||
433 | unsigned long flags; | 433 | unsigned long flags; |
434 | int locked = 1; | 434 | int locked = 1; |
435 | 435 | ||
436 | local_irq_save(flags); | 436 | if (port->sysrq || oops_in_progress) |
437 | if (port->sysrq) { | 437 | locked = spin_trylock_irqsave(&port->lock, flags); |
438 | locked = 0; | 438 | else |
439 | } else if (oops_in_progress) { | 439 | spin_lock_irqsave(&port->lock, flags); |
440 | locked = spin_trylock(&port->lock); | ||
441 | } else | ||
442 | spin_lock(&port->lock); | ||
443 | 440 | ||
444 | while (n > 0) { | 441 | while (n > 0) { |
445 | unsigned long ra = __pa(con_write_page); | 442 | unsigned long ra = __pa(con_write_page); |
@@ -470,8 +467,7 @@ static void sunhv_console_write_paged(struct console *con, const char *s, unsign | |||
470 | } | 467 | } |
471 | 468 | ||
472 | if (locked) | 469 | if (locked) |
473 | spin_unlock(&port->lock); | 470 | spin_unlock_irqrestore(&port->lock, flags); |
474 | local_irq_restore(flags); | ||
475 | } | 471 | } |
476 | 472 | ||
477 | static inline void sunhv_console_putchar(struct uart_port *port, char c) | 473 | static inline void sunhv_console_putchar(struct uart_port *port, char c) |
@@ -492,7 +488,10 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig | |||
492 | unsigned long flags; | 488 | unsigned long flags; |
493 | int i, locked = 1; | 489 | int i, locked = 1; |
494 | 490 | ||
495 | local_irq_save(flags); | 491 | if (port->sysrq || oops_in_progress) |
492 | locked = spin_trylock_irqsave(&port->lock, flags); | ||
493 | else | ||
494 | spin_lock_irqsave(&port->lock, flags); | ||
496 | if (port->sysrq) { | 495 | if (port->sysrq) { |
497 | locked = 0; | 496 | locked = 0; |
498 | } else if (oops_in_progress) { | 497 | } else if (oops_in_progress) { |
@@ -507,8 +506,7 @@ static void sunhv_console_write_bychar(struct console *con, const char *s, unsig | |||
507 | } | 506 | } |
508 | 507 | ||
509 | if (locked) | 508 | if (locked) |
510 | spin_unlock(&port->lock); | 509 | spin_unlock_irqrestore(&port->lock, flags); |
511 | local_irq_restore(flags); | ||
512 | } | 510 | } |
513 | 511 | ||
514 | static struct console sunhv_console = { | 512 | static struct console sunhv_console = { |
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 380fb5355cb2..5faa8e905e98 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c | |||
@@ -844,20 +844,16 @@ static void sunsab_console_write(struct console *con, const char *s, unsigned n) | |||
844 | unsigned long flags; | 844 | unsigned long flags; |
845 | int locked = 1; | 845 | int locked = 1; |
846 | 846 | ||
847 | local_irq_save(flags); | 847 | if (up->port.sysrq || oops_in_progress) |
848 | if (up->port.sysrq) { | 848 | locked = spin_trylock_irqsave(&up->port.lock, flags); |
849 | locked = 0; | 849 | else |
850 | } else if (oops_in_progress) { | 850 | spin_lock_irqsave(&up->port.lock, flags); |
851 | locked = spin_trylock(&up->port.lock); | ||
852 | } else | ||
853 | spin_lock(&up->port.lock); | ||
854 | 851 | ||
855 | uart_console_write(&up->port, s, n, sunsab_console_putchar); | 852 | uart_console_write(&up->port, s, n, sunsab_console_putchar); |
856 | sunsab_tec_wait(up); | 853 | sunsab_tec_wait(up); |
857 | 854 | ||
858 | if (locked) | 855 | if (locked) |
859 | spin_unlock(&up->port.lock); | 856 | spin_unlock_irqrestore(&up->port.lock, flags); |
860 | local_irq_restore(flags); | ||
861 | } | 857 | } |
862 | 858 | ||
863 | static int sunsab_console_setup(struct console *con, char *options) | 859 | static int sunsab_console_setup(struct console *con, char *options) |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index db79b76f5c8e..9a0f24f83720 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -1295,13 +1295,10 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1295 | unsigned int ier; | 1295 | unsigned int ier; |
1296 | int locked = 1; | 1296 | int locked = 1; |
1297 | 1297 | ||
1298 | local_irq_save(flags); | 1298 | if (up->port.sysrq || oops_in_progress) |
1299 | if (up->port.sysrq) { | 1299 | locked = spin_trylock_irqsave(&up->port.lock, flags); |
1300 | locked = 0; | 1300 | else |
1301 | } else if (oops_in_progress) { | 1301 | spin_lock_irqsave(&up->port.lock, flags); |
1302 | locked = spin_trylock(&up->port.lock); | ||
1303 | } else | ||
1304 | spin_lock(&up->port.lock); | ||
1305 | 1302 | ||
1306 | /* | 1303 | /* |
1307 | * First save the UER then disable the interrupts | 1304 | * First save the UER then disable the interrupts |
@@ -1319,8 +1316,7 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1319 | serial_out(up, UART_IER, ier); | 1316 | serial_out(up, UART_IER, ier); |
1320 | 1317 | ||
1321 | if (locked) | 1318 | if (locked) |
1322 | spin_unlock(&up->port.lock); | 1319 | spin_unlock_irqrestore(&up->port.lock, flags); |
1323 | local_irq_restore(flags); | ||
1324 | } | 1320 | } |
1325 | 1321 | ||
1326 | /* | 1322 | /* |
diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 45a8c6aa5837..a2c40ed287d2 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c | |||
@@ -1195,20 +1195,16 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count) | |||
1195 | unsigned long flags; | 1195 | unsigned long flags; |
1196 | int locked = 1; | 1196 | int locked = 1; |
1197 | 1197 | ||
1198 | local_irq_save(flags); | 1198 | if (up->port.sysrq || oops_in_progress) |
1199 | if (up->port.sysrq) { | 1199 | locked = spin_trylock_irqsave(&up->port.lock, flags); |
1200 | locked = 0; | 1200 | else |
1201 | } else if (oops_in_progress) { | 1201 | spin_lock_irqsave(&up->port.lock, flags); |
1202 | locked = spin_trylock(&up->port.lock); | ||
1203 | } else | ||
1204 | spin_lock(&up->port.lock); | ||
1205 | 1202 | ||
1206 | uart_console_write(&up->port, s, count, sunzilog_putchar); | 1203 | uart_console_write(&up->port, s, count, sunzilog_putchar); |
1207 | udelay(2); | 1204 | udelay(2); |
1208 | 1205 | ||
1209 | if (locked) | 1206 | if (locked) |
1210 | spin_unlock(&up->port.lock); | 1207 | spin_unlock_irqrestore(&up->port.lock, flags); |
1211 | local_irq_restore(flags); | ||
1212 | } | 1208 | } |
1213 | 1209 | ||
1214 | static int __init sunzilog_console_setup(struct console *con, char *options) | 1210 | static int __init sunzilog_console_setup(struct console *con, char *options) |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 61b1137d7e56..23b5d32954bf 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -1164,6 +1164,8 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1164 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | 1164 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, |
1165 | vc->vc_screenbuf_size >> 1); | 1165 | vc->vc_screenbuf_size >> 1); |
1166 | set_origin(vc); | 1166 | set_origin(vc); |
1167 | if (CON_IS_VISIBLE(vc)) | ||
1168 | update_screen(vc); | ||
1167 | /* fall through */ | 1169 | /* fall through */ |
1168 | case 2: /* erase whole display */ | 1170 | case 2: /* erase whole display */ |
1169 | count = vc->vc_cols * vc->vc_rows; | 1171 | count = vc->vc_cols * vc->vc_rows; |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 80de2f88ed2c..4ab2cb62dfce 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -105,7 +105,7 @@ static int hw_ep_flush(struct ci_hdrc *ci, int num, int dir) | |||
105 | 105 | ||
106 | do { | 106 | do { |
107 | /* flush any pending transfer */ | 107 | /* flush any pending transfer */ |
108 | hw_write(ci, OP_ENDPTFLUSH, BIT(n), BIT(n)); | 108 | hw_write(ci, OP_ENDPTFLUSH, ~0, BIT(n)); |
109 | while (hw_read(ci, OP_ENDPTFLUSH, BIT(n))) | 109 | while (hw_read(ci, OP_ENDPTFLUSH, BIT(n))) |
110 | cpu_relax(); | 110 | cpu_relax(); |
111 | } while (hw_read(ci, OP_ENDPTSTAT, BIT(n))); | 111 | } while (hw_read(ci, OP_ENDPTSTAT, BIT(n))); |
@@ -205,7 +205,7 @@ static int hw_ep_prime(struct ci_hdrc *ci, int num, int dir, int is_ctrl) | |||
205 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) | 205 | if (is_ctrl && dir == RX && hw_read(ci, OP_ENDPTSETUPSTAT, BIT(num))) |
206 | return -EAGAIN; | 206 | return -EAGAIN; |
207 | 207 | ||
208 | hw_write(ci, OP_ENDPTPRIME, BIT(n), BIT(n)); | 208 | hw_write(ci, OP_ENDPTPRIME, ~0, BIT(n)); |
209 | 209 | ||
210 | while (hw_read(ci, OP_ENDPTPRIME, BIT(n))) | 210 | while (hw_read(ci, OP_ENDPTPRIME, BIT(n))) |
211 | cpu_relax(); | 211 | cpu_relax(); |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 8d72f0c65937..062967c90b2a 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -717,6 +717,10 @@ int usb_get_configuration(struct usb_device *dev) | |||
717 | result = -ENOMEM; | 717 | result = -ENOMEM; |
718 | goto err; | 718 | goto err; |
719 | } | 719 | } |
720 | |||
721 | if (dev->quirks & USB_QUIRK_DELAY_INIT) | ||
722 | msleep(100); | ||
723 | |||
720 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, | 724 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, |
721 | bigbuffer, length); | 725 | bigbuffer, length); |
722 | if (result < 0) { | 726 | if (result < 0) { |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 5d01558cef66..ab90a0156828 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -63,8 +63,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, | |||
63 | dynid->id.idProduct = idProduct; | 63 | dynid->id.idProduct = idProduct; |
64 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 64 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
65 | if (fields > 2 && bInterfaceClass) { | 65 | if (fields > 2 && bInterfaceClass) { |
66 | if (bInterfaceClass > 255) | 66 | if (bInterfaceClass > 255) { |
67 | return -EINVAL; | 67 | retval = -EINVAL; |
68 | goto fail; | ||
69 | } | ||
68 | 70 | ||
69 | dynid->id.bInterfaceClass = (u8)bInterfaceClass; | 71 | dynid->id.bInterfaceClass = (u8)bInterfaceClass; |
70 | dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; | 72 | dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; |
@@ -73,17 +75,21 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, | |||
73 | if (fields > 4) { | 75 | if (fields > 4) { |
74 | const struct usb_device_id *id = id_table; | 76 | const struct usb_device_id *id = id_table; |
75 | 77 | ||
76 | if (!id) | 78 | if (!id) { |
77 | return -ENODEV; | 79 | retval = -ENODEV; |
80 | goto fail; | ||
81 | } | ||
78 | 82 | ||
79 | for (; id->match_flags; id++) | 83 | for (; id->match_flags; id++) |
80 | if (id->idVendor == refVendor && id->idProduct == refProduct) | 84 | if (id->idVendor == refVendor && id->idProduct == refProduct) |
81 | break; | 85 | break; |
82 | 86 | ||
83 | if (id->match_flags) | 87 | if (id->match_flags) { |
84 | dynid->id.driver_info = id->driver_info; | 88 | dynid->id.driver_info = id->driver_info; |
85 | else | 89 | } else { |
86 | return -ENODEV; | 90 | retval = -ENODEV; |
91 | goto fail; | ||
92 | } | ||
87 | } | 93 | } |
88 | 94 | ||
89 | spin_lock(&dynids->lock); | 95 | spin_lock(&dynids->lock); |
@@ -95,6 +101,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, | |||
95 | if (retval) | 101 | if (retval) |
96 | return retval; | 102 | return retval; |
97 | return count; | 103 | return count; |
104 | |||
105 | fail: | ||
106 | kfree(dynid); | ||
107 | return retval; | ||
98 | } | 108 | } |
99 | EXPORT_SYMBOL_GPL(usb_store_new_id); | 109 | EXPORT_SYMBOL_GPL(usb_store_new_id); |
100 | 110 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 199aaea6bfe0..2518c3250750 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1032,7 +1032,6 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
1032 | dev_name(&usb_dev->dev), retval); | 1032 | dev_name(&usb_dev->dev), retval); |
1033 | return retval; | 1033 | return retval; |
1034 | } | 1034 | } |
1035 | usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev); | ||
1036 | } | 1035 | } |
1037 | 1036 | ||
1038 | retval = usb_new_device (usb_dev); | 1037 | retval = usb_new_device (usb_dev); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index babba885978d..64ea21971be2 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -128,7 +128,7 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev) | |||
128 | return usb_get_intfdata(hdev->actconfig->interface[0]); | 128 | return usb_get_intfdata(hdev->actconfig->interface[0]); |
129 | } | 129 | } |
130 | 130 | ||
131 | int usb_device_supports_lpm(struct usb_device *udev) | 131 | static int usb_device_supports_lpm(struct usb_device *udev) |
132 | { | 132 | { |
133 | /* USB 2.1 (and greater) devices indicate LPM support through | 133 | /* USB 2.1 (and greater) devices indicate LPM support through |
134 | * their USB 2.0 Extended Capabilities BOS descriptor. | 134 | * their USB 2.0 Extended Capabilities BOS descriptor. |
@@ -149,11 +149,6 @@ int usb_device_supports_lpm(struct usb_device *udev) | |||
149 | "Power management will be impacted.\n"); | 149 | "Power management will be impacted.\n"); |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | |||
153 | /* udev is root hub */ | ||
154 | if (!udev->parent) | ||
155 | return 1; | ||
156 | |||
157 | if (udev->parent->lpm_capable) | 152 | if (udev->parent->lpm_capable) |
158 | return 1; | 153 | return 1; |
159 | 154 | ||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 8f37063c0a49..739ee8e8bdfd 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -47,6 +47,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
47 | /* Microsoft LifeCam-VX700 v2.0 */ | 47 | /* Microsoft LifeCam-VX700 v2.0 */ |
48 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, | 48 | { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, |
49 | 49 | ||
50 | /* Logitech HD Pro Webcams C920 and C930e */ | ||
51 | { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
52 | { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, | ||
53 | |||
50 | /* Logitech Quickcam Fusion */ | 54 | /* Logitech Quickcam Fusion */ |
51 | { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, | 55 | { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, |
52 | 56 | ||
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index c49383669cd8..823857767a16 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -35,7 +35,6 @@ extern int usb_get_device_descriptor(struct usb_device *dev, | |||
35 | unsigned int size); | 35 | unsigned int size); |
36 | extern int usb_get_bos_descriptor(struct usb_device *dev); | 36 | extern int usb_get_bos_descriptor(struct usb_device *dev); |
37 | extern void usb_release_bos_descriptor(struct usb_device *dev); | 37 | extern void usb_release_bos_descriptor(struct usb_device *dev); |
38 | extern int usb_device_supports_lpm(struct usb_device *udev); | ||
39 | extern char *usb_cache_string(struct usb_device *udev, int index); | 38 | extern char *usb_cache_string(struct usb_device *udev, int index); |
40 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 39 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
41 | extern int usb_choose_configuration(struct usb_device *udev); | 40 | extern int usb_choose_configuration(struct usb_device *udev); |
diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 8565d87f94b4..1d129884cc39 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c | |||
@@ -216,7 +216,7 @@ static int dwc2_hs_phy_init(struct dwc2_hsotg *hsotg, bool select_phy) | |||
216 | int retval = 0; | 216 | int retval = 0; |
217 | 217 | ||
218 | if (!select_phy) | 218 | if (!select_phy) |
219 | return -ENODEV; | 219 | return 0; |
220 | 220 | ||
221 | usbcfg = readl(hsotg->regs + GUSBCFG); | 221 | usbcfg = readl(hsotg->regs + GUSBCFG); |
222 | 222 | ||
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index f59484d43b35..4d918ed8d343 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c | |||
@@ -2565,25 +2565,14 @@ static void _dwc2_hcd_endpoint_reset(struct usb_hcd *hcd, | |||
2565 | struct usb_host_endpoint *ep) | 2565 | struct usb_host_endpoint *ep) |
2566 | { | 2566 | { |
2567 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); | 2567 | struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd); |
2568 | int is_control = usb_endpoint_xfer_control(&ep->desc); | ||
2569 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
2570 | int epnum = usb_endpoint_num(&ep->desc); | ||
2571 | struct usb_device *udev; | ||
2572 | unsigned long flags; | 2568 | unsigned long flags; |
2573 | 2569 | ||
2574 | dev_dbg(hsotg->dev, | 2570 | dev_dbg(hsotg->dev, |
2575 | "DWC OTG HCD EP RESET: bEndpointAddress=0x%02x\n", | 2571 | "DWC OTG HCD EP RESET: bEndpointAddress=0x%02x\n", |
2576 | ep->desc.bEndpointAddress); | 2572 | ep->desc.bEndpointAddress); |
2577 | 2573 | ||
2578 | udev = to_usb_device(hsotg->dev); | ||
2579 | |||
2580 | spin_lock_irqsave(&hsotg->lock, flags); | 2574 | spin_lock_irqsave(&hsotg->lock, flags); |
2581 | |||
2582 | usb_settoggle(udev, epnum, is_out, 0); | ||
2583 | if (is_control) | ||
2584 | usb_settoggle(udev, epnum, !is_out, 0); | ||
2585 | dwc2_hcd_endpoint_reset(hsotg, ep); | 2575 | dwc2_hcd_endpoint_reset(hsotg, ep); |
2586 | |||
2587 | spin_unlock_irqrestore(&hsotg->lock, flags); | 2576 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2588 | } | 2577 | } |
2589 | 2578 | ||
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index d01d0d3f2cf0..eaba547ce26b 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c | |||
@@ -124,6 +124,9 @@ static int dwc2_driver_probe(struct platform_device *dev) | |||
124 | int retval; | 124 | int retval; |
125 | int irq; | 125 | int irq; |
126 | 126 | ||
127 | if (usb_disabled()) | ||
128 | return -ENODEV; | ||
129 | |||
127 | match = of_match_device(dwc2_of_match_table, &dev->dev); | 130 | match = of_match_device(dwc2_of_match_table, &dev->dev); |
128 | if (match && match->data) { | 131 | if (match && match->data) { |
129 | params = match->data; | 132 | params = match->data; |
diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 888fbb43b338..e969eb809a85 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c | |||
@@ -360,24 +360,30 @@ static inline void usb_dma_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | |||
360 | bcm_writel(val, udc->iudma_regs + off); | 360 | bcm_writel(val, udc->iudma_regs + off); |
361 | } | 361 | } |
362 | 362 | ||
363 | static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off) | 363 | static inline u32 usb_dmac_readl(struct bcm63xx_udc *udc, u32 off, int chan) |
364 | { | 364 | { |
365 | return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off); | 365 | return bcm_readl(udc->iudma_regs + IUDMA_DMAC_OFFSET + off + |
366 | (ENETDMA_CHAN_WIDTH * chan)); | ||
366 | } | 367 | } |
367 | 368 | ||
368 | static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | 369 | static inline void usb_dmac_writel(struct bcm63xx_udc *udc, u32 val, u32 off, |
370 | int chan) | ||
369 | { | 371 | { |
370 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off); | 372 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAC_OFFSET + off + |
373 | (ENETDMA_CHAN_WIDTH * chan)); | ||
371 | } | 374 | } |
372 | 375 | ||
373 | static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off) | 376 | static inline u32 usb_dmas_readl(struct bcm63xx_udc *udc, u32 off, int chan) |
374 | { | 377 | { |
375 | return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off); | 378 | return bcm_readl(udc->iudma_regs + IUDMA_DMAS_OFFSET + off + |
379 | (ENETDMA_CHAN_WIDTH * chan)); | ||
376 | } | 380 | } |
377 | 381 | ||
378 | static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off) | 382 | static inline void usb_dmas_writel(struct bcm63xx_udc *udc, u32 val, u32 off, |
383 | int chan) | ||
379 | { | 384 | { |
380 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off); | 385 | bcm_writel(val, udc->iudma_regs + IUDMA_DMAS_OFFSET + off + |
386 | (ENETDMA_CHAN_WIDTH * chan)); | ||
381 | } | 387 | } |
382 | 388 | ||
383 | static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) | 389 | static inline void set_clocks(struct bcm63xx_udc *udc, bool is_enabled) |
@@ -638,7 +644,7 @@ static void iudma_write(struct bcm63xx_udc *udc, struct iudma_ch *iudma, | |||
638 | } while (!last_bd); | 644 | } while (!last_bd); |
639 | 645 | ||
640 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, | 646 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_EN_MASK, |
641 | ENETDMAC_CHANCFG_REG(iudma->ch_idx)); | 647 | ENETDMAC_CHANCFG_REG, iudma->ch_idx); |
642 | } | 648 | } |
643 | 649 | ||
644 | /** | 650 | /** |
@@ -694,9 +700,9 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
694 | bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); | 700 | bcm63xx_fifo_reset_ep(udc, max(0, iudma->ep_num)); |
695 | 701 | ||
696 | /* stop DMA, then wait for the hardware to wrap up */ | 702 | /* stop DMA, then wait for the hardware to wrap up */ |
697 | usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG(ch_idx)); | 703 | usb_dmac_writel(udc, 0, ENETDMAC_CHANCFG_REG, ch_idx); |
698 | 704 | ||
699 | while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)) & | 705 | while (usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx) & |
700 | ENETDMAC_CHANCFG_EN_MASK) { | 706 | ENETDMAC_CHANCFG_EN_MASK) { |
701 | udelay(1); | 707 | udelay(1); |
702 | 708 | ||
@@ -713,10 +719,10 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
713 | dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", | 719 | dev_warn(udc->dev, "forcibly halting IUDMA channel %d\n", |
714 | ch_idx); | 720 | ch_idx); |
715 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, | 721 | usb_dmac_writel(udc, ENETDMAC_CHANCFG_BUFHALT_MASK, |
716 | ENETDMAC_CHANCFG_REG(ch_idx)); | 722 | ENETDMAC_CHANCFG_REG, ch_idx); |
717 | } | 723 | } |
718 | } | 724 | } |
719 | usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG(ch_idx)); | 725 | usb_dmac_writel(udc, ~0, ENETDMAC_IR_REG, ch_idx); |
720 | 726 | ||
721 | /* don't leave "live" HW-owned entries for the next guy to step on */ | 727 | /* don't leave "live" HW-owned entries for the next guy to step on */ |
722 | for (d = iudma->bd_ring; d <= iudma->end_bd; d++) | 728 | for (d = iudma->bd_ring; d <= iudma->end_bd; d++) |
@@ -728,11 +734,11 @@ static void iudma_reset_channel(struct bcm63xx_udc *udc, struct iudma_ch *iudma) | |||
728 | 734 | ||
729 | /* set up IRQs, UBUS burst size, and BD base for this channel */ | 735 | /* set up IRQs, UBUS burst size, and BD base for this channel */ |
730 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, | 736 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, |
731 | ENETDMAC_IRMASK_REG(ch_idx)); | 737 | ENETDMAC_IRMASK_REG, ch_idx); |
732 | usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG(ch_idx)); | 738 | usb_dmac_writel(udc, 8, ENETDMAC_MAXBURST_REG, ch_idx); |
733 | 739 | ||
734 | usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG(ch_idx)); | 740 | usb_dmas_writel(udc, iudma->bd_ring_dma, ENETDMAS_RSTART_REG, ch_idx); |
735 | usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG(ch_idx)); | 741 | usb_dmas_writel(udc, 0, ENETDMAS_SRAM2_REG, ch_idx); |
736 | } | 742 | } |
737 | 743 | ||
738 | /** | 744 | /** |
@@ -2035,7 +2041,7 @@ static irqreturn_t bcm63xx_udc_data_isr(int irq, void *dev_id) | |||
2035 | spin_lock(&udc->lock); | 2041 | spin_lock(&udc->lock); |
2036 | 2042 | ||
2037 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, | 2043 | usb_dmac_writel(udc, ENETDMAC_IR_BUFDONE_MASK, |
2038 | ENETDMAC_IR_REG(iudma->ch_idx)); | 2044 | ENETDMAC_IR_REG, iudma->ch_idx); |
2039 | bep = iudma->bep; | 2045 | bep = iudma->bep; |
2040 | rc = iudma_read(udc, iudma); | 2046 | rc = iudma_read(udc, iudma); |
2041 | 2047 | ||
@@ -2175,18 +2181,18 @@ static int bcm63xx_iudma_dbg_show(struct seq_file *s, void *p) | |||
2175 | seq_printf(s, " [ep%d]:\n", | 2181 | seq_printf(s, " [ep%d]:\n", |
2176 | max_t(int, iudma_defaults[ch_idx].ep_num, 0)); | 2182 | max_t(int, iudma_defaults[ch_idx].ep_num, 0)); |
2177 | seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n", | 2183 | seq_printf(s, " cfg: %08x; irqstat: %08x; irqmask: %08x; maxburst: %08x\n", |
2178 | usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG(ch_idx)), | 2184 | usb_dmac_readl(udc, ENETDMAC_CHANCFG_REG, ch_idx), |
2179 | usb_dmac_readl(udc, ENETDMAC_IR_REG(ch_idx)), | 2185 | usb_dmac_readl(udc, ENETDMAC_IR_REG, ch_idx), |
2180 | usb_dmac_readl(udc, ENETDMAC_IRMASK_REG(ch_idx)), | 2186 | usb_dmac_readl(udc, ENETDMAC_IRMASK_REG, ch_idx), |
2181 | usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG(ch_idx))); | 2187 | usb_dmac_readl(udc, ENETDMAC_MAXBURST_REG, ch_idx)); |
2182 | 2188 | ||
2183 | sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG(ch_idx)); | 2189 | sram2 = usb_dmas_readl(udc, ENETDMAS_SRAM2_REG, ch_idx); |
2184 | sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG(ch_idx)); | 2190 | sram3 = usb_dmas_readl(udc, ENETDMAS_SRAM3_REG, ch_idx); |
2185 | seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n", | 2191 | seq_printf(s, " base: %08x; index: %04x_%04x; desc: %04x_%04x %08x\n", |
2186 | usb_dmas_readl(udc, ENETDMAS_RSTART_REG(ch_idx)), | 2192 | usb_dmas_readl(udc, ENETDMAS_RSTART_REG, ch_idx), |
2187 | sram2 >> 16, sram2 & 0xffff, | 2193 | sram2 >> 16, sram2 & 0xffff, |
2188 | sram3 >> 16, sram3 & 0xffff, | 2194 | sram3 >> 16, sram3 & 0xffff, |
2189 | usb_dmas_readl(udc, ENETDMAS_SRAM4_REG(ch_idx))); | 2195 | usb_dmas_readl(udc, ENETDMAS_SRAM4_REG, ch_idx)); |
2190 | seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, | 2196 | seq_printf(s, " desc: %d/%d used", iudma->n_bds_used, |
2191 | iudma->n_bds); | 2197 | iudma->n_bds); |
2192 | 2198 | ||
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 306a2b52125c..2b4334394076 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -585,7 +585,6 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
585 | char __user *buf, size_t len, int read) | 585 | char __user *buf, size_t len, int read) |
586 | { | 586 | { |
587 | struct ffs_epfile *epfile = file->private_data; | 587 | struct ffs_epfile *epfile = file->private_data; |
588 | struct usb_gadget *gadget = epfile->ffs->gadget; | ||
589 | struct ffs_ep *ep; | 588 | struct ffs_ep *ep; |
590 | char *data = NULL; | 589 | char *data = NULL; |
591 | ssize_t ret, data_len; | 590 | ssize_t ret, data_len; |
@@ -622,6 +621,12 @@ static ssize_t ffs_epfile_io(struct file *file, | |||
622 | /* Allocate & copy */ | 621 | /* Allocate & copy */ |
623 | if (!halt) { | 622 | if (!halt) { |
624 | /* | 623 | /* |
624 | * if we _do_ wait above, the epfile->ffs->gadget might be NULL | ||
625 | * before the waiting completes, so do not assign to 'gadget' earlier | ||
626 | */ | ||
627 | struct usb_gadget *gadget = epfile->ffs->gadget; | ||
628 | |||
629 | /* | ||
625 | * Controller may require buffer size to be aligned to | 630 | * Controller may require buffer size to be aligned to |
626 | * maxpacketsize of an out endpoint. | 631 | * maxpacketsize of an out endpoint. |
627 | */ | 632 | */ |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index bf7a56b6d48a..69b76efd11e9 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -1157,7 +1157,7 @@ static int __init printer_bind_config(struct usb_configuration *c) | |||
1157 | 1157 | ||
1158 | usb_gadget_set_selfpowered(gadget); | 1158 | usb_gadget_set_selfpowered(gadget); |
1159 | 1159 | ||
1160 | if (gadget->is_otg) { | 1160 | if (gadget_is_otg(gadget)) { |
1161 | otg_descriptor.bmAttributes |= USB_OTG_HNP; | 1161 | otg_descriptor.bmAttributes |= USB_OTG_HNP; |
1162 | printer_cfg_driver.descriptors = otg_desc; | 1162 | printer_cfg_driver.descriptors = otg_desc; |
1163 | printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1163 | printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index f04b2c3154de..dd9678f85c58 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1629,7 +1629,7 @@ static void s3c2410_udc_reinit(struct s3c2410_udc *dev) | |||
1629 | ep->ep.desc = NULL; | 1629 | ep->ep.desc = NULL; |
1630 | ep->halted = 0; | 1630 | ep->halted = 0; |
1631 | INIT_LIST_HEAD(&ep->queue); | 1631 | INIT_LIST_HEAD(&ep->queue); |
1632 | usb_ep_set_maxpacket_limit(&ep->ep, &ep->ep.maxpacket); | 1632 | usb_ep_set_maxpacket_limit(&ep->ep, ep->ep.maxpacket); |
1633 | } | 1633 | } |
1634 | } | 1634 | } |
1635 | 1635 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 471142725ffe..81cda09b47e3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -685,8 +685,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
685 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 685 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
686 | u32 status, masked_status, pcd_status = 0, cmd; | 686 | u32 status, masked_status, pcd_status = 0, cmd; |
687 | int bh; | 687 | int bh; |
688 | unsigned long flags; | ||
688 | 689 | ||
689 | spin_lock (&ehci->lock); | 690 | /* |
691 | * For threadirqs option we use spin_lock_irqsave() variant to prevent | ||
692 | * deadlock with ehci hrtimer callback, because hrtimer callbacks run | ||
693 | * in interrupt context even when threadirqs is specified. We can go | ||
694 | * back to spin_lock() variant when hrtimer callbacks become threaded. | ||
695 | */ | ||
696 | spin_lock_irqsave(&ehci->lock, flags); | ||
690 | 697 | ||
691 | status = ehci_readl(ehci, &ehci->regs->status); | 698 | status = ehci_readl(ehci, &ehci->regs->status); |
692 | 699 | ||
@@ -704,7 +711,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
704 | 711 | ||
705 | /* Shared IRQ? */ | 712 | /* Shared IRQ? */ |
706 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { | 713 | if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { |
707 | spin_unlock(&ehci->lock); | 714 | spin_unlock_irqrestore(&ehci->lock, flags); |
708 | return IRQ_NONE; | 715 | return IRQ_NONE; |
709 | } | 716 | } |
710 | 717 | ||
@@ -815,7 +822,7 @@ dead: | |||
815 | 822 | ||
816 | if (bh) | 823 | if (bh) |
817 | ehci_work (ehci); | 824 | ehci_work (ehci); |
818 | spin_unlock (&ehci->lock); | 825 | spin_unlock_irqrestore(&ehci->lock, flags); |
819 | if (pcd_status) | 826 | if (pcd_status) |
820 | usb_hcd_poll_rh_status(hcd); | 827 | usb_hcd_poll_rh_status(hcd); |
821 | return IRQ_HANDLED; | 828 | return IRQ_HANDLED; |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 47b858fc50b2..7ae0c4d51741 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -238,6 +238,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
238 | int port; | 238 | int port; |
239 | int mask; | 239 | int mask; |
240 | int changed; | 240 | int changed; |
241 | bool fs_idle_delay; | ||
241 | 242 | ||
242 | ehci_dbg(ehci, "suspend root hub\n"); | 243 | ehci_dbg(ehci, "suspend root hub\n"); |
243 | 244 | ||
@@ -272,6 +273,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
272 | ehci->bus_suspended = 0; | 273 | ehci->bus_suspended = 0; |
273 | ehci->owned_ports = 0; | 274 | ehci->owned_ports = 0; |
274 | changed = 0; | 275 | changed = 0; |
276 | fs_idle_delay = false; | ||
275 | port = HCS_N_PORTS(ehci->hcs_params); | 277 | port = HCS_N_PORTS(ehci->hcs_params); |
276 | while (port--) { | 278 | while (port--) { |
277 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 279 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
@@ -300,16 +302,32 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
300 | } | 302 | } |
301 | 303 | ||
302 | if (t1 != t2) { | 304 | if (t1 != t2) { |
305 | /* | ||
306 | * On some controllers, Wake-On-Disconnect will | ||
307 | * generate false wakeup signals until the bus | ||
308 | * switches over to full-speed idle. For their | ||
309 | * sake, add a delay if we need one. | ||
310 | */ | ||
311 | if ((t2 & PORT_WKDISC_E) && | ||
312 | ehci_port_speed(ehci, t2) == | ||
313 | USB_PORT_STAT_HIGH_SPEED) | ||
314 | fs_idle_delay = true; | ||
303 | ehci_writel(ehci, t2, reg); | 315 | ehci_writel(ehci, t2, reg); |
304 | changed = 1; | 316 | changed = 1; |
305 | } | 317 | } |
306 | } | 318 | } |
319 | spin_unlock_irq(&ehci->lock); | ||
320 | |||
321 | if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) { | ||
322 | /* | ||
323 | * Wait for HCD to enter low-power mode or for the bus | ||
324 | * to switch to full-speed idle. | ||
325 | */ | ||
326 | usleep_range(5000, 5500); | ||
327 | } | ||
307 | 328 | ||
308 | if (changed && ehci->has_tdi_phy_lpm) { | 329 | if (changed && ehci->has_tdi_phy_lpm) { |
309 | spin_unlock_irq(&ehci->lock); | ||
310 | msleep(5); /* 5 ms for HCD to enter low-power mode */ | ||
311 | spin_lock_irq(&ehci->lock); | 330 | spin_lock_irq(&ehci->lock); |
312 | |||
313 | port = HCS_N_PORTS(ehci->hcs_params); | 331 | port = HCS_N_PORTS(ehci->hcs_params); |
314 | while (port--) { | 332 | while (port--) { |
315 | u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; | 333 | u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; |
@@ -322,8 +340,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
322 | port, (t3 & HOSTPC_PHCD) ? | 340 | port, (t3 & HOSTPC_PHCD) ? |
323 | "succeeded" : "failed"); | 341 | "succeeded" : "failed"); |
324 | } | 342 | } |
343 | spin_unlock_irq(&ehci->lock); | ||
325 | } | 344 | } |
326 | spin_unlock_irq(&ehci->lock); | ||
327 | 345 | ||
328 | /* Apparently some devices need a >= 1-uframe delay here */ | 346 | /* Apparently some devices need a >= 1-uframe delay here */ |
329 | if (ehci->bus_suspended) | 347 | if (ehci->bus_suspended) |
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index b016d38199f2..eb009a457fb5 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -203,12 +203,12 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num) | |||
203 | addr, (unsigned int)temp); | 203 | addr, (unsigned int)temp); |
204 | 204 | ||
205 | addr = &ir_set->erst_base; | 205 | addr = &ir_set->erst_base; |
206 | temp_64 = readq(addr); | 206 | temp_64 = xhci_read_64(xhci, addr); |
207 | xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n", | 207 | xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n", |
208 | addr, temp_64); | 208 | addr, temp_64); |
209 | 209 | ||
210 | addr = &ir_set->erst_dequeue; | 210 | addr = &ir_set->erst_dequeue; |
211 | temp_64 = readq(addr); | 211 | temp_64 = xhci_read_64(xhci, addr); |
212 | xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n", | 212 | xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n", |
213 | addr, temp_64); | 213 | addr, temp_64); |
214 | } | 214 | } |
@@ -412,7 +412,7 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci) | |||
412 | { | 412 | { |
413 | u64 val; | 413 | u64 val; |
414 | 414 | ||
415 | val = readq(&xhci->op_regs->cmd_ring); | 415 | val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
416 | xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n", | 416 | xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n", |
417 | lower_32_bits(val)); | 417 | lower_32_bits(val)); |
418 | xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n", | 418 | xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n", |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 873c272b3ef5..bce4391a0e7d 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1958,7 +1958,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | |||
1958 | xhci_warn(xhci, "WARN something wrong with SW event ring " | 1958 | xhci_warn(xhci, "WARN something wrong with SW event ring " |
1959 | "dequeue ptr.\n"); | 1959 | "dequeue ptr.\n"); |
1960 | /* Update HC event ring dequeue pointer */ | 1960 | /* Update HC event ring dequeue pointer */ |
1961 | temp = readq(&xhci->ir_set->erst_dequeue); | 1961 | temp = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
1962 | temp &= ERST_PTR_MASK; | 1962 | temp &= ERST_PTR_MASK; |
1963 | /* Don't clear the EHB bit (which is RW1C) because | 1963 | /* Don't clear the EHB bit (which is RW1C) because |
1964 | * there might be more events to service. | 1964 | * there might be more events to service. |
@@ -1967,7 +1967,7 @@ static void xhci_set_hc_event_deq(struct xhci_hcd *xhci) | |||
1967 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 1967 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
1968 | "// Write event ring dequeue pointer, " | 1968 | "// Write event ring dequeue pointer, " |
1969 | "preserving EHB bit"); | 1969 | "preserving EHB bit"); |
1970 | writeq(((u64) deq & (u64) ~ERST_PTR_MASK) | temp, | 1970 | xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp, |
1971 | &xhci->ir_set->erst_dequeue); | 1971 | &xhci->ir_set->erst_dequeue); |
1972 | } | 1972 | } |
1973 | 1973 | ||
@@ -2269,7 +2269,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2269 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 2269 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
2270 | "// Device context base array address = 0x%llx (DMA), %p (virt)", | 2270 | "// Device context base array address = 0x%llx (DMA), %p (virt)", |
2271 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); | 2271 | (unsigned long long)xhci->dcbaa->dma, xhci->dcbaa); |
2272 | writeq(dma, &xhci->op_regs->dcbaa_ptr); | 2272 | xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr); |
2273 | 2273 | ||
2274 | /* | 2274 | /* |
2275 | * Initialize the ring segment pool. The ring must be a contiguous | 2275 | * Initialize the ring segment pool. The ring must be a contiguous |
@@ -2312,13 +2312,13 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2312 | (unsigned long long)xhci->cmd_ring->first_seg->dma); | 2312 | (unsigned long long)xhci->cmd_ring->first_seg->dma); |
2313 | 2313 | ||
2314 | /* Set the address in the Command Ring Control register */ | 2314 | /* Set the address in the Command Ring Control register */ |
2315 | val_64 = readq(&xhci->op_regs->cmd_ring); | 2315 | val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
2316 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | | 2316 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | |
2317 | (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) | | 2317 | (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) | |
2318 | xhci->cmd_ring->cycle_state; | 2318 | xhci->cmd_ring->cycle_state; |
2319 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 2319 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
2320 | "// Setting command ring address to 0x%x", val); | 2320 | "// Setting command ring address to 0x%x", val); |
2321 | writeq(val_64, &xhci->op_regs->cmd_ring); | 2321 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); |
2322 | xhci_dbg_cmd_ptrs(xhci); | 2322 | xhci_dbg_cmd_ptrs(xhci); |
2323 | 2323 | ||
2324 | xhci->lpm_command = xhci_alloc_command(xhci, true, true, flags); | 2324 | xhci->lpm_command = xhci_alloc_command(xhci, true, true, flags); |
@@ -2396,10 +2396,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2396 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 2396 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
2397 | "// Set ERST base address for ir_set 0 = 0x%llx", | 2397 | "// Set ERST base address for ir_set 0 = 0x%llx", |
2398 | (unsigned long long)xhci->erst.erst_dma_addr); | 2398 | (unsigned long long)xhci->erst.erst_dma_addr); |
2399 | val_64 = readq(&xhci->ir_set->erst_base); | 2399 | val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base); |
2400 | val_64 &= ERST_PTR_MASK; | 2400 | val_64 &= ERST_PTR_MASK; |
2401 | val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); | 2401 | val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK); |
2402 | writeq(val_64, &xhci->ir_set->erst_base); | 2402 | xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base); |
2403 | 2403 | ||
2404 | /* Set the event ring dequeue address */ | 2404 | /* Set the event ring dequeue address */ |
2405 | xhci_set_hc_event_deq(xhci); | 2405 | xhci_set_hc_event_deq(xhci); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 3c898c12a06b..04f986d9234f 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -142,6 +142,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
142 | "QUIRK: Resetting on resume"); | 142 | "QUIRK: Resetting on resume"); |
143 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | 143 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; |
144 | } | 144 | } |
145 | if (pdev->vendor == PCI_VENDOR_ID_RENESAS && | ||
146 | pdev->device == 0x0015 && | ||
147 | pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && | ||
148 | pdev->subsystem_device == 0xc0cd) | ||
149 | xhci->quirks |= XHCI_RESET_ON_RESUME; | ||
145 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 150 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
146 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 151 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
147 | } | 152 | } |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index a0b248c34526..0ed64eb68e48 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -307,13 +307,14 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) | |||
307 | return 0; | 307 | return 0; |
308 | } | 308 | } |
309 | 309 | ||
310 | temp_64 = readq(&xhci->op_regs->cmd_ring); | 310 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
311 | if (!(temp_64 & CMD_RING_RUNNING)) { | 311 | if (!(temp_64 & CMD_RING_RUNNING)) { |
312 | xhci_dbg(xhci, "Command ring had been stopped\n"); | 312 | xhci_dbg(xhci, "Command ring had been stopped\n"); |
313 | return 0; | 313 | return 0; |
314 | } | 314 | } |
315 | xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; | 315 | xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; |
316 | writeq(temp_64 | CMD_RING_ABORT, &xhci->op_regs->cmd_ring); | 316 | xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, |
317 | &xhci->op_regs->cmd_ring); | ||
317 | 318 | ||
318 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should | 319 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should |
319 | * time the completion od all xHCI commands, including | 320 | * time the completion od all xHCI commands, including |
@@ -2864,8 +2865,9 @@ hw_died: | |||
2864 | /* Clear the event handler busy flag (RW1C); | 2865 | /* Clear the event handler busy flag (RW1C); |
2865 | * the event ring should be empty. | 2866 | * the event ring should be empty. |
2866 | */ | 2867 | */ |
2867 | temp_64 = readq(&xhci->ir_set->erst_dequeue); | 2868 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
2868 | writeq(temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue); | 2869 | xhci_write_64(xhci, temp_64 | ERST_EHB, |
2870 | &xhci->ir_set->erst_dequeue); | ||
2869 | spin_unlock(&xhci->lock); | 2871 | spin_unlock(&xhci->lock); |
2870 | 2872 | ||
2871 | return IRQ_HANDLED; | 2873 | return IRQ_HANDLED; |
@@ -2877,7 +2879,7 @@ hw_died: | |||
2877 | */ | 2879 | */ |
2878 | while (xhci_handle_event(xhci) > 0) {} | 2880 | while (xhci_handle_event(xhci) > 0) {} |
2879 | 2881 | ||
2880 | temp_64 = readq(&xhci->ir_set->erst_dequeue); | 2882 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
2881 | /* If necessary, update the HW's version of the event ring deq ptr. */ | 2883 | /* If necessary, update the HW's version of the event ring deq ptr. */ |
2882 | if (event_ring_deq != xhci->event_ring->dequeue) { | 2884 | if (event_ring_deq != xhci->event_ring->dequeue) { |
2883 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, | 2885 | deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, |
@@ -2892,7 +2894,7 @@ hw_died: | |||
2892 | 2894 | ||
2893 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ | 2895 | /* Clear the event handler busy flag (RW1C); event ring is empty. */ |
2894 | temp_64 |= ERST_EHB; | 2896 | temp_64 |= ERST_EHB; |
2895 | writeq(temp_64, &xhci->ir_set->erst_dequeue); | 2897 | xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue); |
2896 | 2898 | ||
2897 | spin_unlock(&xhci->lock); | 2899 | spin_unlock(&xhci->lock); |
2898 | 2900 | ||
@@ -2965,58 +2967,8 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, | |||
2965 | } | 2967 | } |
2966 | 2968 | ||
2967 | while (1) { | 2969 | while (1) { |
2968 | if (room_on_ring(xhci, ep_ring, num_trbs)) { | 2970 | if (room_on_ring(xhci, ep_ring, num_trbs)) |
2969 | union xhci_trb *trb = ep_ring->enqueue; | 2971 | break; |
2970 | unsigned int usable = ep_ring->enq_seg->trbs + | ||
2971 | TRBS_PER_SEGMENT - 1 - trb; | ||
2972 | u32 nop_cmd; | ||
2973 | |||
2974 | /* | ||
2975 | * Section 4.11.7.1 TD Fragments states that a link | ||
2976 | * TRB must only occur at the boundary between | ||
2977 | * data bursts (eg 512 bytes for 480M). | ||
2978 | * While it is possible to split a large fragment | ||
2979 | * we don't know the size yet. | ||
2980 | * Simplest solution is to fill the trb before the | ||
2981 | * LINK with nop commands. | ||
2982 | */ | ||
2983 | if (num_trbs == 1 || num_trbs <= usable || usable == 0) | ||
2984 | break; | ||
2985 | |||
2986 | if (ep_ring->type != TYPE_BULK) | ||
2987 | /* | ||
2988 | * While isoc transfers might have a buffer that | ||
2989 | * crosses a 64k boundary it is unlikely. | ||
2990 | * Since we can't add NOPs without generating | ||
2991 | * gaps in the traffic just hope it never | ||
2992 | * happens at the end of the ring. | ||
2993 | * This could be fixed by writing a LINK TRB | ||
2994 | * instead of the first NOP - however the | ||
2995 | * TRB_TYPE_LINK_LE32() calls would all need | ||
2996 | * changing to check the ring length. | ||
2997 | */ | ||
2998 | break; | ||
2999 | |||
3000 | if (num_trbs >= TRBS_PER_SEGMENT) { | ||
3001 | xhci_err(xhci, "Too many fragments %d, max %d\n", | ||
3002 | num_trbs, TRBS_PER_SEGMENT - 1); | ||
3003 | return -EINVAL; | ||
3004 | } | ||
3005 | |||
3006 | nop_cmd = cpu_to_le32(TRB_TYPE(TRB_TR_NOOP) | | ||
3007 | ep_ring->cycle_state); | ||
3008 | ep_ring->num_trbs_free -= usable; | ||
3009 | do { | ||
3010 | trb->generic.field[0] = 0; | ||
3011 | trb->generic.field[1] = 0; | ||
3012 | trb->generic.field[2] = 0; | ||
3013 | trb->generic.field[3] = nop_cmd; | ||
3014 | trb++; | ||
3015 | } while (--usable); | ||
3016 | ep_ring->enqueue = trb; | ||
3017 | if (room_on_ring(xhci, ep_ring, num_trbs)) | ||
3018 | break; | ||
3019 | } | ||
3020 | 2972 | ||
3021 | if (ep_ring == xhci->cmd_ring) { | 2973 | if (ep_ring == xhci->cmd_ring) { |
3022 | xhci_err(xhci, "Do not support expand command ring\n"); | 2974 | xhci_err(xhci, "Do not support expand command ring\n"); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ad364394885a..924a6ccdb622 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -611,7 +611,7 @@ int xhci_run(struct usb_hcd *hcd) | |||
611 | xhci_dbg(xhci, "Event ring:\n"); | 611 | xhci_dbg(xhci, "Event ring:\n"); |
612 | xhci_debug_ring(xhci, xhci->event_ring); | 612 | xhci_debug_ring(xhci, xhci->event_ring); |
613 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); | 613 | xhci_dbg_ring_ptrs(xhci, xhci->event_ring); |
614 | temp_64 = readq(&xhci->ir_set->erst_dequeue); | 614 | temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
615 | temp_64 &= ~ERST_PTR_MASK; | 615 | temp_64 &= ~ERST_PTR_MASK; |
616 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 616 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
617 | "ERST deq = 64'h%0lx", (long unsigned int) temp_64); | 617 | "ERST deq = 64'h%0lx", (long unsigned int) temp_64); |
@@ -756,11 +756,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci) | |||
756 | { | 756 | { |
757 | xhci->s3.command = readl(&xhci->op_regs->command); | 757 | xhci->s3.command = readl(&xhci->op_regs->command); |
758 | xhci->s3.dev_nt = readl(&xhci->op_regs->dev_notification); | 758 | xhci->s3.dev_nt = readl(&xhci->op_regs->dev_notification); |
759 | xhci->s3.dcbaa_ptr = readq(&xhci->op_regs->dcbaa_ptr); | 759 | xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); |
760 | xhci->s3.config_reg = readl(&xhci->op_regs->config_reg); | 760 | xhci->s3.config_reg = readl(&xhci->op_regs->config_reg); |
761 | xhci->s3.erst_size = readl(&xhci->ir_set->erst_size); | 761 | xhci->s3.erst_size = readl(&xhci->ir_set->erst_size); |
762 | xhci->s3.erst_base = readq(&xhci->ir_set->erst_base); | 762 | xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); |
763 | xhci->s3.erst_dequeue = readq(&xhci->ir_set->erst_dequeue); | 763 | xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); |
764 | xhci->s3.irq_pending = readl(&xhci->ir_set->irq_pending); | 764 | xhci->s3.irq_pending = readl(&xhci->ir_set->irq_pending); |
765 | xhci->s3.irq_control = readl(&xhci->ir_set->irq_control); | 765 | xhci->s3.irq_control = readl(&xhci->ir_set->irq_control); |
766 | } | 766 | } |
@@ -769,11 +769,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) | |||
769 | { | 769 | { |
770 | writel(xhci->s3.command, &xhci->op_regs->command); | 770 | writel(xhci->s3.command, &xhci->op_regs->command); |
771 | writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification); | 771 | writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification); |
772 | writeq(xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); | 772 | xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); |
773 | writel(xhci->s3.config_reg, &xhci->op_regs->config_reg); | 773 | writel(xhci->s3.config_reg, &xhci->op_regs->config_reg); |
774 | writel(xhci->s3.erst_size, &xhci->ir_set->erst_size); | 774 | writel(xhci->s3.erst_size, &xhci->ir_set->erst_size); |
775 | writeq(xhci->s3.erst_base, &xhci->ir_set->erst_base); | 775 | xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); |
776 | writeq(xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); | 776 | xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); |
777 | writel(xhci->s3.irq_pending, &xhci->ir_set->irq_pending); | 777 | writel(xhci->s3.irq_pending, &xhci->ir_set->irq_pending); |
778 | writel(xhci->s3.irq_control, &xhci->ir_set->irq_control); | 778 | writel(xhci->s3.irq_control, &xhci->ir_set->irq_control); |
779 | } | 779 | } |
@@ -783,7 +783,7 @@ static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) | |||
783 | u64 val_64; | 783 | u64 val_64; |
784 | 784 | ||
785 | /* step 2: initialize command ring buffer */ | 785 | /* step 2: initialize command ring buffer */ |
786 | val_64 = readq(&xhci->op_regs->cmd_ring); | 786 | val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); |
787 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | | 787 | val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | |
788 | (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | 788 | (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
789 | xhci->cmd_ring->dequeue) & | 789 | xhci->cmd_ring->dequeue) & |
@@ -792,7 +792,7 @@ static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) | |||
792 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, | 792 | xhci_dbg_trace(xhci, trace_xhci_dbg_init, |
793 | "// Setting command ring address to 0x%llx", | 793 | "// Setting command ring address to 0x%llx", |
794 | (long unsigned long) val_64); | 794 | (long unsigned long) val_64); |
795 | writeq(val_64, &xhci->op_regs->cmd_ring); | 795 | xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); |
796 | } | 796 | } |
797 | 797 | ||
798 | /* | 798 | /* |
@@ -3842,7 +3842,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3842 | if (ret) { | 3842 | if (ret) { |
3843 | return ret; | 3843 | return ret; |
3844 | } | 3844 | } |
3845 | temp_64 = readq(&xhci->op_regs->dcbaa_ptr); | 3845 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); |
3846 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3846 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
3847 | "Op regs DCBAA ptr = %#016llx", temp_64); | 3847 | "Op regs DCBAA ptr = %#016llx", temp_64); |
3848 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, | 3848 | xhci_dbg_trace(xhci, trace_xhci_dbg_address, |
@@ -4730,8 +4730,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4730 | struct device *dev = hcd->self.controller; | 4730 | struct device *dev = hcd->self.controller; |
4731 | int retval; | 4731 | int retval; |
4732 | 4732 | ||
4733 | /* Limit the block layer scatter-gather lists to half a segment. */ | 4733 | /* Accept arbitrarily long scatter-gather lists */ |
4734 | hcd->self.sg_tablesize = TRBS_PER_SEGMENT / 2; | 4734 | hcd->self.sg_tablesize = ~0; |
4735 | 4735 | ||
4736 | /* support to build packet from discontinuous buffers */ | 4736 | /* support to build packet from discontinuous buffers */ |
4737 | hcd->self.no_sg_constraint = 1; | 4737 | hcd->self.no_sg_constraint = 1; |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f8416639bf31..58ed9d088e63 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -28,17 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/usb/hcd.h> | 29 | #include <linux/usb/hcd.h> |
30 | 30 | ||
31 | /* | ||
32 | * Registers should always be accessed with double word or quad word accesses. | ||
33 | * | ||
34 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
35 | * with 64-bit address pointers should be written to with dword accesses by | ||
36 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
37 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
38 | * the high dword, and write order is irrelevant. | ||
39 | */ | ||
40 | #include <asm-generic/io-64-nonatomic-lo-hi.h> | ||
41 | |||
42 | /* Code sharing between pci-quirks and xhci hcd */ | 31 | /* Code sharing between pci-quirks and xhci hcd */ |
43 | #include "xhci-ext-caps.h" | 32 | #include "xhci-ext-caps.h" |
44 | #include "pci-quirks.h" | 33 | #include "pci-quirks.h" |
@@ -1279,7 +1268,7 @@ union xhci_trb { | |||
1279 | * since the command ring is 64-byte aligned. | 1268 | * since the command ring is 64-byte aligned. |
1280 | * It must also be greater than 16. | 1269 | * It must also be greater than 16. |
1281 | */ | 1270 | */ |
1282 | #define TRBS_PER_SEGMENT 256 | 1271 | #define TRBS_PER_SEGMENT 64 |
1283 | /* Allow two commands + a link TRB, along with any reserved command TRBs */ | 1272 | /* Allow two commands + a link TRB, along with any reserved command TRBs */ |
1284 | #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) | 1273 | #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) |
1285 | #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) | 1274 | #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) |
@@ -1614,6 +1603,34 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
1614 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | 1603 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ |
1615 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1604 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1616 | 1605 | ||
1606 | /* | ||
1607 | * Registers should always be accessed with double word or quad word accesses. | ||
1608 | * | ||
1609 | * Some xHCI implementations may support 64-bit address pointers. Registers | ||
1610 | * with 64-bit address pointers should be written to with dword accesses by | ||
1611 | * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. | ||
1612 | * xHCI implementations that do not support 64-bit address pointers will ignore | ||
1613 | * the high dword, and write order is irrelevant. | ||
1614 | */ | ||
1615 | static inline u64 xhci_read_64(const struct xhci_hcd *xhci, | ||
1616 | __le64 __iomem *regs) | ||
1617 | { | ||
1618 | __u32 __iomem *ptr = (__u32 __iomem *) regs; | ||
1619 | u64 val_lo = readl(ptr); | ||
1620 | u64 val_hi = readl(ptr + 1); | ||
1621 | return val_lo + (val_hi << 32); | ||
1622 | } | ||
1623 | static inline void xhci_write_64(struct xhci_hcd *xhci, | ||
1624 | const u64 val, __le64 __iomem *regs) | ||
1625 | { | ||
1626 | __u32 __iomem *ptr = (__u32 __iomem *) regs; | ||
1627 | u32 val_lo = lower_32_bits(val); | ||
1628 | u32 val_hi = upper_32_bits(val); | ||
1629 | |||
1630 | writel(val_lo, ptr); | ||
1631 | writel(val_hi, ptr + 1); | ||
1632 | } | ||
1633 | |||
1617 | static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) | 1634 | static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci) |
1618 | { | 1635 | { |
1619 | return xhci->quirks & XHCI_LINK_TRB_QUIRK; | 1636 | return xhci->quirks & XHCI_LINK_TRB_QUIRK; |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fc192ad9cc6a..239ad0b1ceb6 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -477,8 +477,11 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
477 | musb->port1_status |= | 477 | musb->port1_status |= |
478 | (USB_PORT_STAT_C_SUSPEND << 16) | 478 | (USB_PORT_STAT_C_SUSPEND << 16) |
479 | | MUSB_PORT_STAT_RESUME; | 479 | | MUSB_PORT_STAT_RESUME; |
480 | musb->rh_timer = jiffies | ||
481 | + msecs_to_jiffies(20); | ||
480 | schedule_delayed_work( | 482 | schedule_delayed_work( |
481 | &musb->finish_resume_work, 20); | 483 | &musb->finish_resume_work, |
484 | msecs_to_jiffies(20)); | ||
482 | 485 | ||
483 | musb->xceiv->state = OTG_STATE_A_HOST; | 486 | musb->xceiv->state = OTG_STATE_A_HOST; |
484 | musb->is_active = 1; | 487 | musb->is_active = 1; |
@@ -2157,11 +2160,19 @@ static void musb_restore_context(struct musb *musb) | |||
2157 | void __iomem *musb_base = musb->mregs; | 2160 | void __iomem *musb_base = musb->mregs; |
2158 | void __iomem *ep_target_regs; | 2161 | void __iomem *ep_target_regs; |
2159 | void __iomem *epio; | 2162 | void __iomem *epio; |
2163 | u8 power; | ||
2160 | 2164 | ||
2161 | musb_writew(musb_base, MUSB_FRAME, musb->context.frame); | 2165 | musb_writew(musb_base, MUSB_FRAME, musb->context.frame); |
2162 | musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); | 2166 | musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); |
2163 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); | 2167 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); |
2164 | musb_writeb(musb_base, MUSB_POWER, musb->context.power); | 2168 | |
2169 | /* Don't affect SUSPENDM/RESUME bits in POWER reg */ | ||
2170 | power = musb_readb(musb_base, MUSB_POWER); | ||
2171 | power &= MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME; | ||
2172 | musb->context.power &= ~(MUSB_POWER_SUSPENDM | MUSB_POWER_RESUME); | ||
2173 | power |= musb->context.power; | ||
2174 | musb_writeb(musb_base, MUSB_POWER, power); | ||
2175 | |||
2165 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); | 2176 | musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); |
2166 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); | 2177 | musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); |
2167 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); | 2178 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ed455724017b..abb38c3833ef 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -1183,6 +1183,9 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1183 | csr = MUSB_CSR0_H_STATUSPKT | 1183 | csr = MUSB_CSR0_H_STATUSPKT |
1184 | | MUSB_CSR0_TXPKTRDY; | 1184 | | MUSB_CSR0_TXPKTRDY; |
1185 | 1185 | ||
1186 | /* disable ping token in status phase */ | ||
1187 | csr |= MUSB_CSR0_H_DIS_PING; | ||
1188 | |||
1186 | /* flag status stage */ | 1189 | /* flag status stage */ |
1187 | musb->ep0_stage = MUSB_EP0_STATUS; | 1190 | musb->ep0_stage = MUSB_EP0_STATUS; |
1188 | 1191 | ||
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index eb634433ef09..e2d2d8c9891b 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
@@ -135,7 +135,8 @@ void musb_port_suspend(struct musb *musb, bool do_suspend) | |||
135 | 135 | ||
136 | /* later, GetPortStatus will stop RESUME signaling */ | 136 | /* later, GetPortStatus will stop RESUME signaling */ |
137 | musb->port1_status |= MUSB_PORT_STAT_RESUME; | 137 | musb->port1_status |= MUSB_PORT_STAT_RESUME; |
138 | schedule_delayed_work(&musb->finish_resume_work, 20); | 138 | schedule_delayed_work(&musb->finish_resume_work, |
139 | msecs_to_jiffies(20)); | ||
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
@@ -158,7 +159,6 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
158 | */ | 159 | */ |
159 | power = musb_readb(mbase, MUSB_POWER); | 160 | power = musb_readb(mbase, MUSB_POWER); |
160 | if (do_reset) { | 161 | if (do_reset) { |
161 | |||
162 | /* | 162 | /* |
163 | * If RESUME is set, we must make sure it stays minimum 20 ms. | 163 | * If RESUME is set, we must make sure it stays minimum 20 ms. |
164 | * Then we must clear RESUME and wait a bit to let musb start | 164 | * Then we must clear RESUME and wait a bit to let musb start |
@@ -167,11 +167,22 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
167 | * detected". | 167 | * detected". |
168 | */ | 168 | */ |
169 | if (power & MUSB_POWER_RESUME) { | 169 | if (power & MUSB_POWER_RESUME) { |
170 | while (time_before(jiffies, musb->rh_timer)) | 170 | long remain = (unsigned long) musb->rh_timer - jiffies; |
171 | msleep(1); | 171 | |
172 | if (musb->rh_timer > 0 && remain > 0) { | ||
173 | /* take into account the minimum delay after resume */ | ||
174 | schedule_delayed_work( | ||
175 | &musb->deassert_reset_work, remain); | ||
176 | return; | ||
177 | } | ||
178 | |||
172 | musb_writeb(mbase, MUSB_POWER, | 179 | musb_writeb(mbase, MUSB_POWER, |
173 | power & ~MUSB_POWER_RESUME); | 180 | power & ~MUSB_POWER_RESUME); |
174 | msleep(1); | 181 | |
182 | /* Give the core 1 ms to clear MUSB_POWER_RESUME */ | ||
183 | schedule_delayed_work(&musb->deassert_reset_work, | ||
184 | msecs_to_jiffies(1)); | ||
185 | return; | ||
175 | } | 186 | } |
176 | 187 | ||
177 | power &= 0xf0; | 188 | power &= 0xf0; |
@@ -180,7 +191,8 @@ void musb_port_reset(struct musb *musb, bool do_reset) | |||
180 | 191 | ||
181 | musb->port1_status |= USB_PORT_STAT_RESET; | 192 | musb->port1_status |= USB_PORT_STAT_RESET; |
182 | musb->port1_status &= ~USB_PORT_STAT_ENABLE; | 193 | musb->port1_status &= ~USB_PORT_STAT_ENABLE; |
183 | schedule_delayed_work(&musb->deassert_reset_work, 50); | 194 | schedule_delayed_work(&musb->deassert_reset_work, |
195 | msecs_to_jiffies(50)); | ||
184 | } else { | 196 | } else { |
185 | dev_dbg(musb->controller, "root port reset stopped\n"); | 197 | dev_dbg(musb->controller, "root port reset stopped\n"); |
186 | musb_writeb(mbase, MUSB_POWER, | 198 | musb_writeb(mbase, MUSB_POWER, |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2a408cdaf7b2..8aa59a2c5eb2 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -659,7 +659,6 @@ static int omap2430_runtime_suspend(struct device *dev) | |||
659 | OTG_INTERFSEL); | 659 | OTG_INTERFSEL); |
660 | 660 | ||
661 | omap2430_low_level_exit(musb); | 661 | omap2430_low_level_exit(musb); |
662 | phy_power_off(musb->phy); | ||
663 | } | 662 | } |
664 | 663 | ||
665 | return 0; | 664 | return 0; |
@@ -674,7 +673,6 @@ static int omap2430_runtime_resume(struct device *dev) | |||
674 | omap2430_low_level_init(musb); | 673 | omap2430_low_level_init(musb); |
675 | musb_writel(musb->mregs, OTG_INTERFSEL, | 674 | musb_writel(musb->mregs, OTG_INTERFSEL, |
676 | musb->context.otg_interfsel); | 675 | musb->context.otg_interfsel); |
677 | phy_power_on(musb->phy); | ||
678 | } | 676 | } |
679 | 677 | ||
680 | return 0; | 678 | return 0; |
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 8546c8dccd51..d204f745ed05 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c | |||
@@ -159,32 +159,6 @@ put_3p3: | |||
159 | return rc; | 159 | return rc; |
160 | } | 160 | } |
161 | 161 | ||
162 | #ifdef CONFIG_PM_SLEEP | ||
163 | #define USB_PHY_SUSP_DIG_VOL 500000 | ||
164 | static int msm_hsusb_config_vddcx(int high) | ||
165 | { | ||
166 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | ||
167 | int min_vol; | ||
168 | int ret; | ||
169 | |||
170 | if (high) | ||
171 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | ||
172 | else | ||
173 | min_vol = USB_PHY_SUSP_DIG_VOL; | ||
174 | |||
175 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | ||
176 | if (ret) { | ||
177 | pr_err("%s: unable to set the voltage for regulator " | ||
178 | "HSUSB_VDDCX\n", __func__); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); | ||
183 | |||
184 | return ret; | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | static int msm_hsusb_ldo_set_mode(int on) | 162 | static int msm_hsusb_ldo_set_mode(int on) |
189 | { | 163 | { |
190 | int ret = 0; | 164 | int ret = 0; |
@@ -440,7 +414,32 @@ static int msm_otg_reset(struct usb_phy *phy) | |||
440 | #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) | 414 | #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) |
441 | #define PHY_RESUME_TIMEOUT_USEC (100 * 1000) | 415 | #define PHY_RESUME_TIMEOUT_USEC (100 * 1000) |
442 | 416 | ||
443 | #ifdef CONFIG_PM_SLEEP | 417 | #ifdef CONFIG_PM |
418 | |||
419 | #define USB_PHY_SUSP_DIG_VOL 500000 | ||
420 | static int msm_hsusb_config_vddcx(int high) | ||
421 | { | ||
422 | int max_vol = USB_PHY_VDD_DIG_VOL_MAX; | ||
423 | int min_vol; | ||
424 | int ret; | ||
425 | |||
426 | if (high) | ||
427 | min_vol = USB_PHY_VDD_DIG_VOL_MIN; | ||
428 | else | ||
429 | min_vol = USB_PHY_SUSP_DIG_VOL; | ||
430 | |||
431 | ret = regulator_set_voltage(hsusb_vddcx, min_vol, max_vol); | ||
432 | if (ret) { | ||
433 | pr_err("%s: unable to set the voltage for regulator " | ||
434 | "HSUSB_VDDCX\n", __func__); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
438 | pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol); | ||
439 | |||
440 | return ret; | ||
441 | } | ||
442 | |||
444 | static int msm_otg_suspend(struct msm_otg *motg) | 443 | static int msm_otg_suspend(struct msm_otg *motg) |
445 | { | 444 | { |
446 | struct usb_phy *phy = &motg->phy; | 445 | struct usb_phy *phy = &motg->phy; |
@@ -1733,22 +1732,18 @@ static int msm_otg_pm_resume(struct device *dev) | |||
1733 | } | 1732 | } |
1734 | #endif | 1733 | #endif |
1735 | 1734 | ||
1736 | #ifdef CONFIG_PM | ||
1737 | static const struct dev_pm_ops msm_otg_dev_pm_ops = { | 1735 | static const struct dev_pm_ops msm_otg_dev_pm_ops = { |
1738 | SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) | 1736 | SET_SYSTEM_SLEEP_PM_OPS(msm_otg_pm_suspend, msm_otg_pm_resume) |
1739 | SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, | 1737 | SET_RUNTIME_PM_OPS(msm_otg_runtime_suspend, msm_otg_runtime_resume, |
1740 | msm_otg_runtime_idle) | 1738 | msm_otg_runtime_idle) |
1741 | }; | 1739 | }; |
1742 | #endif | ||
1743 | 1740 | ||
1744 | static struct platform_driver msm_otg_driver = { | 1741 | static struct platform_driver msm_otg_driver = { |
1745 | .remove = msm_otg_remove, | 1742 | .remove = msm_otg_remove, |
1746 | .driver = { | 1743 | .driver = { |
1747 | .name = DRIVER_NAME, | 1744 | .name = DRIVER_NAME, |
1748 | .owner = THIS_MODULE, | 1745 | .owner = THIS_MODULE, |
1749 | #ifdef CONFIG_PM | ||
1750 | .pm = &msm_otg_dev_pm_ops, | 1746 | .pm = &msm_otg_dev_pm_ops, |
1751 | #endif | ||
1752 | }, | 1747 | }, |
1753 | }; | 1748 | }; |
1754 | 1749 | ||
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index e6f61e4361df..8afa813d690b 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
@@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) | |||
130 | 130 | ||
131 | phy = __usb_find_phy(&phy_list, type); | 131 | phy = __usb_find_phy(&phy_list, type); |
132 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | 132 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { |
133 | pr_err("unable to find transceiver of type %s\n", | 133 | pr_debug("PHY: unable to find transceiver of type %s\n", |
134 | usb_phy_type_string(type)); | 134 | usb_phy_type_string(type)); |
135 | goto err0; | 135 | goto err0; |
136 | } | 136 | } |
@@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) | |||
228 | 228 | ||
229 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); | 229 | phy = __usb_find_phy_dev(dev, &phy_bind_list, index); |
230 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | 230 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { |
231 | pr_err("unable to find transceiver\n"); | 231 | dev_dbg(dev, "unable to find transceiver\n"); |
232 | goto err0; | 232 | goto err0; |
233 | } | 233 | } |
234 | 234 | ||
@@ -424,10 +424,8 @@ int usb_bind_phy(const char *dev_name, u8 index, | |||
424 | unsigned long flags; | 424 | unsigned long flags; |
425 | 425 | ||
426 | phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); | 426 | phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL); |
427 | if (!phy_bind) { | 427 | if (!phy_bind) |
428 | pr_err("phy_bind(): No memory for phy_bind"); | ||
429 | return -ENOMEM; | 428 | return -ENOMEM; |
430 | } | ||
431 | 429 | ||
432 | phy_bind->dev_name = dev_name; | 430 | phy_bind->dev_name = dev_name; |
433 | phy_bind->phy_dev_name = phy_dev_name; | 431 | phy_bind->phy_dev_name = phy_dev_name; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ce0d7b0db012..44ab12986805 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -152,6 +152,7 @@ static const struct usb_device_id id_table_combined[] = { | |||
152 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 152 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
153 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 153 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
154 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, | 154 | { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) }, |
155 | { USB_DEVICE(FTDI_VID, FTDI_EV3CON_PID) }, | ||
155 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, | 156 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, |
156 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, | 157 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, |
157 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, | 158 | { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, |
@@ -191,6 +192,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
191 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 192 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
192 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 193 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
193 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, | 194 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, |
195 | { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_LP101_PID) }, | ||
196 | { USB_DEVICE(FTDI_VID, FTDI_TAGSYS_P200X_PID) }, | ||
194 | { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, | 197 | { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, |
195 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, | 198 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, |
196 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, | 199 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, |
@@ -904,6 +907,8 @@ static const struct usb_device_id id_table_combined[] = { | |||
904 | /* Crucible Devices */ | 907 | /* Crucible Devices */ |
905 | { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, | 908 | { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) }, |
906 | { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, | 909 | { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, |
910 | /* Cressi Devices */ | ||
911 | { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, | ||
907 | { } /* Terminating entry */ | 912 | { } /* Terminating entry */ |
908 | }; | 913 | }; |
909 | 914 | ||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index a7019d1e3058..e599fbfcde5f 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -50,6 +50,7 @@ | |||
50 | #define TI_XDS100V2_PID 0xa6d0 | 50 | #define TI_XDS100V2_PID 0xa6d0 |
51 | 51 | ||
52 | #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ | 52 | #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ |
53 | #define FTDI_EV3CON_PID 0xABB9 /* Mindstorms EV3 Console Adapter */ | ||
53 | 54 | ||
54 | /* US Interface Navigator (http://www.usinterface.com/) */ | 55 | /* US Interface Navigator (http://www.usinterface.com/) */ |
55 | #define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */ | 56 | #define FTDI_USINT_CAT_PID 0xb810 /* Navigator CAT and 2nd PTT lines */ |
@@ -363,6 +364,12 @@ | |||
363 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ | 364 | /* Sprog II (Andrew Crosland's SprogII DCC interface) */ |
364 | #define FTDI_SPROG_II 0xF0C8 | 365 | #define FTDI_SPROG_II 0xF0C8 |
365 | 366 | ||
367 | /* | ||
368 | * Two of the Tagsys RFID Readers | ||
369 | */ | ||
370 | #define FTDI_TAGSYS_LP101_PID 0xF0E9 /* Tagsys L-P101 RFID*/ | ||
371 | #define FTDI_TAGSYS_P200X_PID 0xF0EE /* Tagsys Medio P200x RFID*/ | ||
372 | |||
366 | /* an infrared receiver for user access control with IR tags */ | 373 | /* an infrared receiver for user access control with IR tags */ |
367 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ | 374 | #define FTDI_PIEGROUP_PID 0xF208 /* Product Id */ |
368 | 375 | ||
@@ -1313,3 +1320,9 @@ | |||
1313 | * Manufacturer: Smart GSM Team | 1320 | * Manufacturer: Smart GSM Team |
1314 | */ | 1321 | */ |
1315 | #define FTDI_Z3X_PID 0x0011 | 1322 | #define FTDI_Z3X_PID 0x0011 |
1323 | |||
1324 | /* | ||
1325 | * Product: Cressi PC Interface | ||
1326 | * Manufacturer: Cressi | ||
1327 | */ | ||
1328 | #define FTDI_CRESSI_PID 0x87d0 | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5c86f57e4afa..68fc9fe65936 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -1362,7 +1362,8 @@ static const struct usb_device_id option_ids[] = { | |||
1362 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, | 1362 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) }, |
1363 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, | 1363 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, |
1364 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, | 1364 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, |
1365 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) }, | 1365 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff), |
1366 | .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, | ||
1366 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, | 1367 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, |
1367 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, | 1368 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, |
1368 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, | 1369 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, |
@@ -1525,7 +1526,8 @@ static const struct usb_device_id option_ids[] = { | |||
1525 | /* Cinterion */ | 1526 | /* Cinterion */ |
1526 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, | 1527 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, |
1527 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, | 1528 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, |
1528 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, | 1529 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), |
1530 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | ||
1529 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, | 1531 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, |
1530 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), | 1532 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), |
1531 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 1533 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index c65437cfd4a2..968a40201e5f 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -139,6 +139,9 @@ static const struct usb_device_id id_table[] = { | |||
139 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 0)}, /* Sierra Wireless EM7700 Device Management */ | 139 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 0)}, /* Sierra Wireless EM7700 Device Management */ |
140 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 2)}, /* Sierra Wireless EM7700 NMEA */ | 140 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 2)}, /* Sierra Wireless EM7700 NMEA */ |
141 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 3)}, /* Sierra Wireless EM7700 Modem */ | 141 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 3)}, /* Sierra Wireless EM7700 Modem */ |
142 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */ | ||
143 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */ | ||
144 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */ | ||
142 | 145 | ||
143 | { } /* Terminating entry */ | 146 | { } /* Terminating entry */ |
144 | }; | 147 | }; |
diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index f112b079ddfc..fb79775447b0 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c | |||
@@ -71,7 +71,8 @@ DEVICE(hp4x, HP4X_IDS); | |||
71 | 71 | ||
72 | /* Suunto ANT+ USB Driver */ | 72 | /* Suunto ANT+ USB Driver */ |
73 | #define SUUNTO_IDS() \ | 73 | #define SUUNTO_IDS() \ |
74 | { USB_DEVICE(0x0fcf, 0x1008) } | 74 | { USB_DEVICE(0x0fcf, 0x1008) }, \ |
75 | { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */ | ||
75 | DEVICE(suunto, SUUNTO_IDS); | 76 | DEVICE(suunto, SUUNTO_IDS); |
76 | 77 | ||
77 | /* Siemens USB/MPI adapter */ | 78 | /* Siemens USB/MPI adapter */ |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 8470e1b114f2..1dd0604d1911 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
@@ -18,7 +18,9 @@ config USB_STORAGE | |||
18 | 18 | ||
19 | This option depends on 'SCSI' support being enabled, but you | 19 | This option depends on 'SCSI' support being enabled, but you |
20 | probably also need 'SCSI device support: SCSI disk support' | 20 | probably also need 'SCSI device support: SCSI disk support' |
21 | (BLK_DEV_SD) for most USB storage devices. | 21 | (BLK_DEV_SD) for most USB storage devices. Some devices also |
22 | will require 'Probe all LUNs on each SCSI device' | ||
23 | (SCSI_MULTI_LUN). | ||
22 | 24 | ||
23 | To compile this driver as a module, choose M here: the | 25 | To compile this driver as a module, choose M here: the |
24 | module will be called usb-storage. | 26 | module will be called usb-storage. |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 18509e6c21ab..9d38ddc8da49 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -78,6 +78,8 @@ static const char* host_info(struct Scsi_Host *host) | |||
78 | 78 | ||
79 | static int slave_alloc (struct scsi_device *sdev) | 79 | static int slave_alloc (struct scsi_device *sdev) |
80 | { | 80 | { |
81 | struct us_data *us = host_to_us(sdev->host); | ||
82 | |||
81 | /* | 83 | /* |
82 | * Set the INQUIRY transfer length to 36. We don't use any of | 84 | * Set the INQUIRY transfer length to 36. We don't use any of |
83 | * the extra data and many devices choke if asked for more or | 85 | * the extra data and many devices choke if asked for more or |
@@ -102,6 +104,10 @@ static int slave_alloc (struct scsi_device *sdev) | |||
102 | */ | 104 | */ |
103 | blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); | 105 | blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); |
104 | 106 | ||
107 | /* Tell the SCSI layer if we know there is more than one LUN */ | ||
108 | if (us->protocol == USB_PR_BULK && us->max_lun > 0) | ||
109 | sdev->sdev_bflags |= BLIST_FORCELUN; | ||
110 | |||
105 | return 0; | 111 | return 0; |
106 | } | 112 | } |
107 | 113 | ||
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h index 65a6a75066a8..82e8ed0324e3 100644 --- a/drivers/usb/storage/unusual_cypress.h +++ b/drivers/usb/storage/unusual_cypress.h | |||
@@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | |||
31 | "Cypress ISD-300LP", | 31 | "Cypress ISD-300LP", |
32 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), | 32 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), |
33 | 33 | ||
34 | UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219, | 34 | UNUSUAL_DEV( 0x14cd, 0x6116, 0x0160, 0x0160, |
35 | "Super Top", | 35 | "Super Top", |
36 | "USB 2.0 SATA BRIDGE", | 36 | "USB 2.0 SATA BRIDGE", |
37 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), | 37 | USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ad06255c2ade..adbeb255616a 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1455,6 +1455,13 @@ UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100, | |||
1455 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1455 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1456 | US_FL_FIX_CAPACITY ), | 1456 | US_FL_FIX_CAPACITY ), |
1457 | 1457 | ||
1458 | /* Reported by Moritz Moeller-Herrmann <moritz-kernel@moeller-herrmann.de> */ | ||
1459 | UNUSUAL_DEV( 0x0fca, 0x8004, 0x0201, 0x0201, | ||
1460 | "Research In Motion", | ||
1461 | "BlackBerry Bold 9000", | ||
1462 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
1463 | US_FL_MAX_SECTORS_64 ), | ||
1464 | |||
1458 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1465 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
1459 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1466 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
1460 | "Sony Ericsson", | 1467 | "Sony Ericsson", |
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 4fb7a8f83c8a..54af4e933695 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c | |||
@@ -186,12 +186,12 @@ static bool is_invalid_reserved_pfn(unsigned long pfn) | |||
186 | if (pfn_valid(pfn)) { | 186 | if (pfn_valid(pfn)) { |
187 | bool reserved; | 187 | bool reserved; |
188 | struct page *tail = pfn_to_page(pfn); | 188 | struct page *tail = pfn_to_page(pfn); |
189 | struct page *head = compound_trans_head(tail); | 189 | struct page *head = compound_head(tail); |
190 | reserved = !!(PageReserved(head)); | 190 | reserved = !!(PageReserved(head)); |
191 | if (head != tail) { | 191 | if (head != tail) { |
192 | /* | 192 | /* |
193 | * "head" is not a dangling pointer | 193 | * "head" is not a dangling pointer |
194 | * (compound_trans_head takes care of that) | 194 | * (compound_head takes care of that) |
195 | * but the hugepage may have been split | 195 | * but the hugepage may have been split |
196 | * from under us (and we may not hold a | 196 | * from under us (and we may not hold a |
197 | * reference count on the head page so it can | 197 | * reference count on the head page so it can |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 9a68409580d5..a0fa5de210cf 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -70,7 +70,12 @@ enum { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct vhost_net_ubuf_ref { | 72 | struct vhost_net_ubuf_ref { |
73 | struct kref kref; | 73 | /* refcount follows semantics similar to kref: |
74 | * 0: object is released | ||
75 | * 1: no outstanding ubufs | ||
76 | * >1: outstanding ubufs | ||
77 | */ | ||
78 | atomic_t refcount; | ||
74 | wait_queue_head_t wait; | 79 | wait_queue_head_t wait; |
75 | struct vhost_virtqueue *vq; | 80 | struct vhost_virtqueue *vq; |
76 | }; | 81 | }; |
@@ -116,14 +121,6 @@ static void vhost_net_enable_zcopy(int vq) | |||
116 | vhost_net_zcopy_mask |= 0x1 << vq; | 121 | vhost_net_zcopy_mask |= 0x1 << vq; |
117 | } | 122 | } |
118 | 123 | ||
119 | static void vhost_net_zerocopy_done_signal(struct kref *kref) | ||
120 | { | ||
121 | struct vhost_net_ubuf_ref *ubufs; | ||
122 | |||
123 | ubufs = container_of(kref, struct vhost_net_ubuf_ref, kref); | ||
124 | wake_up(&ubufs->wait); | ||
125 | } | ||
126 | |||
127 | static struct vhost_net_ubuf_ref * | 124 | static struct vhost_net_ubuf_ref * |
128 | vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) | 125 | vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) |
129 | { | 126 | { |
@@ -134,21 +131,24 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) | |||
134 | ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL); | 131 | ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL); |
135 | if (!ubufs) | 132 | if (!ubufs) |
136 | return ERR_PTR(-ENOMEM); | 133 | return ERR_PTR(-ENOMEM); |
137 | kref_init(&ubufs->kref); | 134 | atomic_set(&ubufs->refcount, 1); |
138 | init_waitqueue_head(&ubufs->wait); | 135 | init_waitqueue_head(&ubufs->wait); |
139 | ubufs->vq = vq; | 136 | ubufs->vq = vq; |
140 | return ubufs; | 137 | return ubufs; |
141 | } | 138 | } |
142 | 139 | ||
143 | static void vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) | 140 | static int vhost_net_ubuf_put(struct vhost_net_ubuf_ref *ubufs) |
144 | { | 141 | { |
145 | kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal); | 142 | int r = atomic_sub_return(1, &ubufs->refcount); |
143 | if (unlikely(!r)) | ||
144 | wake_up(&ubufs->wait); | ||
145 | return r; | ||
146 | } | 146 | } |
147 | 147 | ||
148 | static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) | 148 | static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs) |
149 | { | 149 | { |
150 | kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal); | 150 | vhost_net_ubuf_put(ubufs); |
151 | wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount)); | 151 | wait_event(ubufs->wait, !atomic_read(&ubufs->refcount)); |
152 | } | 152 | } |
153 | 153 | ||
154 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) | 154 | static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs) |
@@ -306,23 +306,26 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | |||
306 | { | 306 | { |
307 | struct vhost_net_ubuf_ref *ubufs = ubuf->ctx; | 307 | struct vhost_net_ubuf_ref *ubufs = ubuf->ctx; |
308 | struct vhost_virtqueue *vq = ubufs->vq; | 308 | struct vhost_virtqueue *vq = ubufs->vq; |
309 | int cnt = atomic_read(&ubufs->kref.refcount); | 309 | int cnt; |
310 | |||
311 | rcu_read_lock_bh(); | ||
310 | 312 | ||
311 | /* set len to mark this desc buffers done DMA */ | 313 | /* set len to mark this desc buffers done DMA */ |
312 | vq->heads[ubuf->desc].len = success ? | 314 | vq->heads[ubuf->desc].len = success ? |
313 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; | 315 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; |
314 | vhost_net_ubuf_put(ubufs); | 316 | cnt = vhost_net_ubuf_put(ubufs); |
315 | 317 | ||
316 | /* | 318 | /* |
317 | * Trigger polling thread if guest stopped submitting new buffers: | 319 | * Trigger polling thread if guest stopped submitting new buffers: |
318 | * in this case, the refcount after decrement will eventually reach 1 | 320 | * in this case, the refcount after decrement will eventually reach 1. |
319 | * so here it is 2. | ||
320 | * We also trigger polling periodically after each 16 packets | 321 | * We also trigger polling periodically after each 16 packets |
321 | * (the value 16 here is more or less arbitrary, it's tuned to trigger | 322 | * (the value 16 here is more or less arbitrary, it's tuned to trigger |
322 | * less than 10% of times). | 323 | * less than 10% of times). |
323 | */ | 324 | */ |
324 | if (cnt <= 2 || !(cnt % 16)) | 325 | if (cnt <= 1 || !(cnt % 16)) |
325 | vhost_poll_queue(&vq->poll); | 326 | vhost_poll_queue(&vq->poll); |
327 | |||
328 | rcu_read_unlock_bh(); | ||
326 | } | 329 | } |
327 | 330 | ||
328 | /* Expects to be always run from workqueue - which acts as | 331 | /* Expects to be always run from workqueue - which acts as |
@@ -420,7 +423,7 @@ static void handle_tx(struct vhost_net *net) | |||
420 | msg.msg_control = ubuf; | 423 | msg.msg_control = ubuf; |
421 | msg.msg_controllen = sizeof(ubuf); | 424 | msg.msg_controllen = sizeof(ubuf); |
422 | ubufs = nvq->ubufs; | 425 | ubufs = nvq->ubufs; |
423 | kref_get(&ubufs->kref); | 426 | atomic_inc(&ubufs->refcount); |
424 | nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; | 427 | nvq->upend_idx = (nvq->upend_idx + 1) % UIO_MAXIOV; |
425 | } else { | 428 | } else { |
426 | msg.msg_control = NULL; | 429 | msg.msg_control = NULL; |
@@ -780,7 +783,7 @@ static void vhost_net_flush(struct vhost_net *n) | |||
780 | vhost_net_ubuf_put_and_wait(n->vqs[VHOST_NET_VQ_TX].ubufs); | 783 | vhost_net_ubuf_put_and_wait(n->vqs[VHOST_NET_VQ_TX].ubufs); |
781 | mutex_lock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); | 784 | mutex_lock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); |
782 | n->tx_flush = false; | 785 | n->tx_flush = false; |
783 | kref_init(&n->vqs[VHOST_NET_VQ_TX].ubufs->kref); | 786 | atomic_set(&n->vqs[VHOST_NET_VQ_TX].ubufs->refcount, 1); |
784 | mutex_unlock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); | 787 | mutex_unlock(&n->vqs[VHOST_NET_VQ_TX].vq.mutex); |
785 | } | 788 | } |
786 | } | 789 | } |
@@ -800,6 +803,8 @@ static int vhost_net_release(struct inode *inode, struct file *f) | |||
800 | fput(tx_sock->file); | 803 | fput(tx_sock->file); |
801 | if (rx_sock) | 804 | if (rx_sock) |
802 | fput(rx_sock->file); | 805 | fput(rx_sock->file); |
806 | /* Make sure no callbacks are outstanding */ | ||
807 | synchronize_rcu_bh(); | ||
803 | /* We do an extra flush before freeing memory, | 808 | /* We do an extra flush before freeing memory, |
804 | * since jobs can re-queue themselves. */ | 809 | * since jobs can re-queue themselves. */ |
805 | vhost_net_flush(n); | 810 | vhost_net_flush(n); |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 0a025b8e2a12..e48d4a672580 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -1001,6 +1001,12 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) | |||
1001 | break; | 1001 | break; |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | /* virtio-scsi spec requires byte 0 of the lun to be 1 */ | ||
1005 | if (unlikely(v_req.lun[0] != 1)) { | ||
1006 | vhost_scsi_send_bad_target(vs, vq, head, out); | ||
1007 | continue; | ||
1008 | } | ||
1009 | |||
1004 | /* Extract the tpgt */ | 1010 | /* Extract the tpgt */ |
1005 | target = v_req.lun[1]; | 1011 | target = v_req.lun[1]; |
1006 | tpg = ACCESS_ONCE(vs_tpg[target]); | 1012 | tpg = ACCESS_ONCE(vs_tpg[target]); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 22262a3a0e2d..dade5b7699bc 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -364,7 +364,7 @@ config FB_SA1100 | |||
364 | 364 | ||
365 | config FB_IMX | 365 | config FB_IMX |
366 | tristate "Freescale i.MX1/21/25/27 LCD support" | 366 | tristate "Freescale i.MX1/21/25/27 LCD support" |
367 | depends on FB && IMX_HAVE_PLATFORM_IMX_FB | 367 | depends on FB && ARCH_MXC |
368 | select FB_CFB_FILLRECT | 368 | select FB_CFB_FILLRECT |
369 | select FB_CFB_COPYAREA | 369 | select FB_CFB_COPYAREA |
370 | select FB_CFB_IMAGEBLIT | 370 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig index 1129d0e9e640..75c8a8e7efc0 100644 --- a/drivers/video/exynos/Kconfig +++ b/drivers/video/exynos/Kconfig | |||
@@ -22,7 +22,8 @@ config EXYNOS_MIPI_DSI | |||
22 | 22 | ||
23 | config EXYNOS_LCD_S6E8AX0 | 23 | config EXYNOS_LCD_S6E8AX0 |
24 | bool "S6E8AX0 MIPI AMOLED LCD Driver" | 24 | bool "S6E8AX0 MIPI AMOLED LCD Driver" |
25 | depends on (EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE) | 25 | depends on EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE |
26 | depends on (LCD_CLASS_DEVICE = y) | ||
26 | default n | 27 | default n |
27 | help | 28 | help |
28 | If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its | 29 | If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index bbeb8dd7f108..77d6221618f4 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -2160,8 +2160,8 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk, | |||
2160 | *five_taps = false; | 2160 | *five_taps = false; |
2161 | 2161 | ||
2162 | do { | 2162 | do { |
2163 | in_height = DIV_ROUND_UP(height, *decim_y); | 2163 | in_height = height / *decim_y; |
2164 | in_width = DIV_ROUND_UP(width, *decim_x); | 2164 | in_width = width / *decim_x; |
2165 | *core_clk = dispc.feat->calc_core_clk(pclk, in_width, | 2165 | *core_clk = dispc.feat->calc_core_clk(pclk, in_width, |
2166 | in_height, out_width, out_height, mem_to_mem); | 2166 | in_height, out_width, out_height, mem_to_mem); |
2167 | error = (in_width > maxsinglelinewidth || !*core_clk || | 2167 | error = (in_width > maxsinglelinewidth || !*core_clk || |
@@ -2199,8 +2199,8 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk, | |||
2199 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2199 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
2200 | 2200 | ||
2201 | do { | 2201 | do { |
2202 | in_height = DIV_ROUND_UP(height, *decim_y); | 2202 | in_height = height / *decim_y; |
2203 | in_width = DIV_ROUND_UP(width, *decim_x); | 2203 | in_width = width / *decim_x; |
2204 | *five_taps = in_height > out_height; | 2204 | *five_taps = in_height > out_height; |
2205 | 2205 | ||
2206 | if (in_width > maxsinglelinewidth) | 2206 | if (in_width > maxsinglelinewidth) |
@@ -2268,7 +2268,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk, | |||
2268 | { | 2268 | { |
2269 | u16 in_width, in_width_max; | 2269 | u16 in_width, in_width_max; |
2270 | int decim_x_min = *decim_x; | 2270 | int decim_x_min = *decim_x; |
2271 | u16 in_height = DIV_ROUND_UP(height, *decim_y); | 2271 | u16 in_height = height / *decim_y; |
2272 | const int maxsinglelinewidth = | 2272 | const int maxsinglelinewidth = |
2273 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); | 2273 | dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); |
2274 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); | 2274 | const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); |
@@ -2287,7 +2287,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk, | |||
2287 | return -EINVAL; | 2287 | return -EINVAL; |
2288 | 2288 | ||
2289 | do { | 2289 | do { |
2290 | in_width = DIV_ROUND_UP(width, *decim_x); | 2290 | in_width = width / *decim_x; |
2291 | } while (*decim_x <= *x_predecim && | 2291 | } while (*decim_x <= *x_predecim && |
2292 | in_width > maxsinglelinewidth && ++*decim_x); | 2292 | in_width > maxsinglelinewidth && ++*decim_x); |
2293 | 2293 | ||
@@ -2466,8 +2466,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane, | |||
2466 | if (r) | 2466 | if (r) |
2467 | return r; | 2467 | return r; |
2468 | 2468 | ||
2469 | in_width = DIV_ROUND_UP(in_width, x_predecim); | 2469 | in_width = in_width / x_predecim; |
2470 | in_height = DIV_ROUND_UP(in_height, y_predecim); | 2470 | in_height = in_height / y_predecim; |
2471 | 2471 | ||
2472 | if (color_mode == OMAP_DSS_COLOR_YUV2 || | 2472 | if (color_mode == OMAP_DSS_COLOR_YUV2 || |
2473 | color_mode == OMAP_DSS_COLOR_UYVY || | 2473 | color_mode == OMAP_DSS_COLOR_UYVY || |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 7411f2674e16..23ef21ffc2c4 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -117,7 +117,7 @@ struct dpi_clk_calc_ctx { | |||
117 | /* outputs */ | 117 | /* outputs */ |
118 | 118 | ||
119 | struct dsi_clock_info dsi_cinfo; | 119 | struct dsi_clock_info dsi_cinfo; |
120 | unsigned long long fck; | 120 | unsigned long fck; |
121 | struct dispc_clock_info dispc_cinfo; | 121 | struct dispc_clock_info dispc_cinfo; |
122 | }; | 122 | }; |
123 | 123 | ||
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index efb9ee9e3c96..ba806c9e7f54 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -46,7 +46,7 @@ static struct { | |||
46 | struct sdi_clk_calc_ctx { | 46 | struct sdi_clk_calc_ctx { |
47 | unsigned long pck_min, pck_max; | 47 | unsigned long pck_min, pck_max; |
48 | 48 | ||
49 | unsigned long long fck; | 49 | unsigned long fck; |
50 | struct dispc_clock_info dispc_cinfo; | 50 | struct dispc_clock_info dispc_cinfo; |
51 | }; | 51 | }; |
52 | 52 | ||
diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c index a06edbfa95ca..1b5d48c578e1 100644 --- a/drivers/vme/bridges/vme_ca91cx42.c +++ b/drivers/vme/bridges/vme_ca91cx42.c | |||
@@ -884,7 +884,7 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image, | |||
884 | if (done == count) | 884 | if (done == count) |
885 | goto out; | 885 | goto out; |
886 | } | 886 | } |
887 | if ((uintptr_t)addr & 0x2) { | 887 | if ((uintptr_t)(addr + done) & 0x2) { |
888 | if ((count - done) < 2) { | 888 | if ((count - done) < 2) { |
889 | *(u8 *)(buf + done) = ioread8(addr + done); | 889 | *(u8 *)(buf + done) = ioread8(addr + done); |
890 | done += 1; | 890 | done += 1; |
@@ -938,7 +938,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image, | |||
938 | if (done == count) | 938 | if (done == count) |
939 | goto out; | 939 | goto out; |
940 | } | 940 | } |
941 | if ((uintptr_t)addr & 0x2) { | 941 | if ((uintptr_t)(addr + done) & 0x2) { |
942 | if ((count - done) < 2) { | 942 | if ((count - done) < 2) { |
943 | iowrite8(*(u8 *)(buf + done), addr + done); | 943 | iowrite8(*(u8 *)(buf + done), addr + done); |
944 | done += 1; | 944 | done += 1; |
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 16830d8b777c..9911cd5fddb5 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c | |||
@@ -1289,7 +1289,7 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, | |||
1289 | if (done == count) | 1289 | if (done == count) |
1290 | goto out; | 1290 | goto out; |
1291 | } | 1291 | } |
1292 | if ((uintptr_t)addr & 0x2) { | 1292 | if ((uintptr_t)(addr + done) & 0x2) { |
1293 | if ((count - done) < 2) { | 1293 | if ((count - done) < 2) { |
1294 | *(u8 *)(buf + done) = ioread8(addr + done); | 1294 | *(u8 *)(buf + done) = ioread8(addr + done); |
1295 | done += 1; | 1295 | done += 1; |
@@ -1371,7 +1371,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, | |||
1371 | if (done == count) | 1371 | if (done == count) |
1372 | goto out; | 1372 | goto out; |
1373 | } | 1373 | } |
1374 | if ((uintptr_t)addr & 0x2) { | 1374 | if ((uintptr_t)(addr + done) & 0x2) { |
1375 | if ((count - done) < 2) { | 1375 | if ((count - done) < 2) { |
1376 | iowrite8(*(u8 *)(buf + done), addr + done); | 1376 | iowrite8(*(u8 *)(buf + done), addr + done); |
1377 | done += 1; | 1377 | done += 1; |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4c4c566c52a3..79d25894343a 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -223,6 +223,7 @@ config SA1100_WATCHDOG | |||
223 | 223 | ||
224 | config DW_WATCHDOG | 224 | config DW_WATCHDOG |
225 | tristate "Synopsys DesignWare watchdog" | 225 | tristate "Synopsys DesignWare watchdog" |
226 | depends on HAS_IOMEM | ||
226 | help | 227 | help |
227 | Say Y here if to include support for the Synopsys DesignWare | 228 | Say Y here if to include support for the Synopsys DesignWare |
228 | watchdog timer found in many chips. | 229 | watchdog timer found in many chips. |
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c index aaf2995d37f4..68b45fc9ba6a 100644 --- a/drivers/watchdog/w83697hf_wdt.c +++ b/drivers/watchdog/w83697hf_wdt.c | |||
@@ -402,7 +402,7 @@ static int __init wdt_init(void) | |||
402 | 402 | ||
403 | if (!found) { | 403 | if (!found) { |
404 | pr_err("No W83697HF/HG could be found\n"); | 404 | pr_err("No W83697HF/HG could be found\n"); |
405 | ret = -EIO; | 405 | ret = -ENODEV; |
406 | goto out; | 406 | goto out; |
407 | } | 407 | } |
408 | 408 | ||
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index d75c811bfa56..45e00afa7f2d 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile | |||
@@ -16,7 +16,6 @@ xen-pad-$(CONFIG_X86) += xen-acpi-pad.o | |||
16 | dom0-$(CONFIG_X86) += pcpu.o | 16 | dom0-$(CONFIG_X86) += pcpu.o |
17 | obj-$(CONFIG_XEN_DOM0) += $(dom0-y) | 17 | obj-$(CONFIG_XEN_DOM0) += $(dom0-y) |
18 | obj-$(CONFIG_BLOCK) += biomerge.o | 18 | obj-$(CONFIG_BLOCK) += biomerge.o |
19 | obj-$(CONFIG_XEN_XENCOMM) += xencomm.o | ||
20 | obj-$(CONFIG_XEN_BALLOON) += xen-balloon.o | 19 | obj-$(CONFIG_XEN_BALLOON) += xen-balloon.o |
21 | obj-$(CONFIG_XEN_SELFBALLOONING) += xen-selfballoon.o | 20 | obj-$(CONFIG_XEN_SELFBALLOONING) += xen-selfballoon.o |
22 | obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o | 21 | obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o |
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 4672e003c0ad..f4a9e3311297 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c | |||
@@ -862,6 +862,8 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
862 | irq = ret; | 862 | irq = ret; |
863 | goto out; | 863 | goto out; |
864 | } | 864 | } |
865 | /* New interdomain events are bound to VCPU 0. */ | ||
866 | bind_evtchn_to_cpu(evtchn, 0); | ||
865 | } else { | 867 | } else { |
866 | struct irq_info *info = info_for_irq(irq); | 868 | struct irq_info *info = info_for_irq(irq); |
867 | WARN_ON(info == NULL || info->type != IRQT_EVTCHN); | 869 | WARN_ON(info == NULL || info->type != IRQT_EVTCHN); |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 34a2704fbc88..073b4a19a8b0 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -284,10 +284,8 @@ static int map_grant_pages(struct grant_map *map) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | pr_debug("map %d+%d\n", map->index, map->count); | 286 | pr_debug("map %d+%d\n", map->index, map->count); |
287 | err = gnttab_map_refs_userspace(map->map_ops, | 287 | err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL, |
288 | use_ptemod ? map->kmap_ops : NULL, | 288 | map->pages, map->count); |
289 | map->pages, | ||
290 | map->count); | ||
291 | if (err) | 289 | if (err) |
292 | return err; | 290 | return err; |
293 | 291 | ||
@@ -317,10 +315,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
317 | } | 315 | } |
318 | } | 316 | } |
319 | 317 | ||
320 | err = gnttab_unmap_refs_userspace(map->unmap_ops + offset, | 318 | err = gnttab_unmap_refs(map->unmap_ops + offset, |
321 | use_ptemod ? map->kmap_ops + offset : NULL, | 319 | use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, |
322 | map->pages + offset, | 320 | pages); |
323 | pages); | ||
324 | if (err) | 321 | if (err) |
325 | return err; | 322 | return err; |
326 | 323 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 8ee13e2e45e2..b84e3ab839aa 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -928,17 +928,15 @@ void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count) | |||
928 | } | 928 | } |
929 | EXPORT_SYMBOL_GPL(gnttab_batch_copy); | 929 | EXPORT_SYMBOL_GPL(gnttab_batch_copy); |
930 | 930 | ||
931 | int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | 931 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, |
932 | struct gnttab_map_grant_ref *kmap_ops, | 932 | struct gnttab_map_grant_ref *kmap_ops, |
933 | struct page **pages, unsigned int count, | 933 | struct page **pages, unsigned int count) |
934 | bool m2p_override) | ||
935 | { | 934 | { |
936 | int i, ret; | 935 | int i, ret; |
937 | bool lazy = false; | 936 | bool lazy = false; |
938 | pte_t *pte; | 937 | pte_t *pte; |
939 | unsigned long mfn, pfn; | 938 | unsigned long mfn; |
940 | 939 | ||
941 | BUG_ON(kmap_ops && !m2p_override); | ||
942 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); | 940 | ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map_ops, count); |
943 | if (ret) | 941 | if (ret) |
944 | return ret; | 942 | return ret; |
@@ -957,12 +955,10 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
957 | set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, | 955 | set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT, |
958 | map_ops[i].dev_bus_addr >> PAGE_SHIFT); | 956 | map_ops[i].dev_bus_addr >> PAGE_SHIFT); |
959 | } | 957 | } |
960 | return 0; | 958 | return ret; |
961 | } | 959 | } |
962 | 960 | ||
963 | if (m2p_override && | 961 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { |
964 | !in_interrupt() && | ||
965 | paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
966 | arch_enter_lazy_mmu_mode(); | 962 | arch_enter_lazy_mmu_mode(); |
967 | lazy = true; | 963 | lazy = true; |
968 | } | 964 | } |
@@ -979,20 +975,8 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
979 | } else { | 975 | } else { |
980 | mfn = PFN_DOWN(map_ops[i].dev_bus_addr); | 976 | mfn = PFN_DOWN(map_ops[i].dev_bus_addr); |
981 | } | 977 | } |
982 | pfn = page_to_pfn(pages[i]); | 978 | ret = m2p_add_override(mfn, pages[i], kmap_ops ? |
983 | 979 | &kmap_ops[i] : NULL); | |
984 | WARN_ON(PagePrivate(pages[i])); | ||
985 | SetPagePrivate(pages[i]); | ||
986 | set_page_private(pages[i], mfn); | ||
987 | |||
988 | pages[i]->index = pfn_to_mfn(pfn); | ||
989 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) { | ||
990 | ret = -ENOMEM; | ||
991 | goto out; | ||
992 | } | ||
993 | if (m2p_override) | ||
994 | ret = m2p_add_override(mfn, pages[i], kmap_ops ? | ||
995 | &kmap_ops[i] : NULL); | ||
996 | if (ret) | 980 | if (ret) |
997 | goto out; | 981 | goto out; |
998 | } | 982 | } |
@@ -1003,32 +987,15 @@ int __gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
1003 | 987 | ||
1004 | return ret; | 988 | return ret; |
1005 | } | 989 | } |
1006 | |||
1007 | int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | ||
1008 | struct page **pages, unsigned int count) | ||
1009 | { | ||
1010 | return __gnttab_map_refs(map_ops, NULL, pages, count, false); | ||
1011 | } | ||
1012 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 990 | EXPORT_SYMBOL_GPL(gnttab_map_refs); |
1013 | 991 | ||
1014 | int gnttab_map_refs_userspace(struct gnttab_map_grant_ref *map_ops, | 992 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, |
1015 | struct gnttab_map_grant_ref *kmap_ops, | ||
1016 | struct page **pages, unsigned int count) | ||
1017 | { | ||
1018 | return __gnttab_map_refs(map_ops, kmap_ops, pages, count, true); | ||
1019 | } | ||
1020 | EXPORT_SYMBOL_GPL(gnttab_map_refs_userspace); | ||
1021 | |||
1022 | int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | ||
1023 | struct gnttab_map_grant_ref *kmap_ops, | 993 | struct gnttab_map_grant_ref *kmap_ops, |
1024 | struct page **pages, unsigned int count, | 994 | struct page **pages, unsigned int count) |
1025 | bool m2p_override) | ||
1026 | { | 995 | { |
1027 | int i, ret; | 996 | int i, ret; |
1028 | bool lazy = false; | 997 | bool lazy = false; |
1029 | unsigned long pfn, mfn; | ||
1030 | 998 | ||
1031 | BUG_ON(kmap_ops && !m2p_override); | ||
1032 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); | 999 | ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap_ops, count); |
1033 | if (ret) | 1000 | if (ret) |
1034 | return ret; | 1001 | return ret; |
@@ -1039,33 +1006,17 @@ int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
1039 | set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT, | 1006 | set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT, |
1040 | INVALID_P2M_ENTRY); | 1007 | INVALID_P2M_ENTRY); |
1041 | } | 1008 | } |
1042 | return 0; | 1009 | return ret; |
1043 | } | 1010 | } |
1044 | 1011 | ||
1045 | if (m2p_override && | 1012 | if (!in_interrupt() && paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { |
1046 | !in_interrupt() && | ||
1047 | paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE) { | ||
1048 | arch_enter_lazy_mmu_mode(); | 1013 | arch_enter_lazy_mmu_mode(); |
1049 | lazy = true; | 1014 | lazy = true; |
1050 | } | 1015 | } |
1051 | 1016 | ||
1052 | for (i = 0; i < count; i++) { | 1017 | for (i = 0; i < count; i++) { |
1053 | pfn = page_to_pfn(pages[i]); | 1018 | ret = m2p_remove_override(pages[i], kmap_ops ? |
1054 | mfn = get_phys_to_machine(pfn); | 1019 | &kmap_ops[i] : NULL); |
1055 | if (mfn == INVALID_P2M_ENTRY || !(mfn & FOREIGN_FRAME_BIT)) { | ||
1056 | ret = -EINVAL; | ||
1057 | goto out; | ||
1058 | } | ||
1059 | |||
1060 | set_page_private(pages[i], INVALID_P2M_ENTRY); | ||
1061 | WARN_ON(!PagePrivate(pages[i])); | ||
1062 | ClearPagePrivate(pages[i]); | ||
1063 | set_phys_to_machine(pfn, pages[i]->index); | ||
1064 | if (m2p_override) | ||
1065 | ret = m2p_remove_override(pages[i], | ||
1066 | kmap_ops ? | ||
1067 | &kmap_ops[i] : NULL, | ||
1068 | mfn); | ||
1069 | if (ret) | 1020 | if (ret) |
1070 | goto out; | 1021 | goto out; |
1071 | } | 1022 | } |
@@ -1076,22 +1027,8 @@ int __gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
1076 | 1027 | ||
1077 | return ret; | 1028 | return ret; |
1078 | } | 1029 | } |
1079 | |||
1080 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *map_ops, | ||
1081 | struct page **pages, unsigned int count) | ||
1082 | { | ||
1083 | return __gnttab_unmap_refs(map_ops, NULL, pages, count, false); | ||
1084 | } | ||
1085 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); | 1030 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs); |
1086 | 1031 | ||
1087 | int gnttab_unmap_refs_userspace(struct gnttab_unmap_grant_ref *map_ops, | ||
1088 | struct gnttab_map_grant_ref *kmap_ops, | ||
1089 | struct page **pages, unsigned int count) | ||
1090 | { | ||
1091 | return __gnttab_unmap_refs(map_ops, kmap_ops, pages, count, true); | ||
1092 | } | ||
1093 | EXPORT_SYMBOL_GPL(gnttab_unmap_refs_userspace); | ||
1094 | |||
1095 | static unsigned nr_status_frames(unsigned nr_grant_frames) | 1032 | static unsigned nr_status_frames(unsigned nr_grant_frames) |
1096 | { | 1033 | { |
1097 | BUG_ON(grefs_per_grant_frame == 0); | 1034 | BUG_ON(grefs_per_grant_frame == 0); |
diff --git a/drivers/xen/xencomm.c b/drivers/xen/xencomm.c deleted file mode 100644 index 4793fc594549..000000000000 --- a/drivers/xen/xencomm.c +++ /dev/null | |||
@@ -1,219 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2 of the License, or | ||
5 | * (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
15 | * | ||
16 | * Copyright (C) IBM Corp. 2006 | ||
17 | * | ||
18 | * Authors: Hollis Blanchard <hollisb@us.ibm.com> | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
23 | #include <linux/mm.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <asm/page.h> | ||
26 | #include <xen/xencomm.h> | ||
27 | #include <xen/interface/xen.h> | ||
28 | #include <asm/xen/xencomm.h> /* for xencomm_is_phys_contiguous() */ | ||
29 | |||
30 | static int xencomm_init(struct xencomm_desc *desc, | ||
31 | void *buffer, unsigned long bytes) | ||
32 | { | ||
33 | unsigned long recorded = 0; | ||
34 | int i = 0; | ||
35 | |||
36 | while ((recorded < bytes) && (i < desc->nr_addrs)) { | ||
37 | unsigned long vaddr = (unsigned long)buffer + recorded; | ||
38 | unsigned long paddr; | ||
39 | int offset; | ||
40 | int chunksz; | ||
41 | |||
42 | offset = vaddr % PAGE_SIZE; /* handle partial pages */ | ||
43 | chunksz = min(PAGE_SIZE - offset, bytes - recorded); | ||
44 | |||
45 | paddr = xencomm_vtop(vaddr); | ||
46 | if (paddr == ~0UL) { | ||
47 | printk(KERN_DEBUG "%s: couldn't translate vaddr %lx\n", | ||
48 | __func__, vaddr); | ||
49 | return -EINVAL; | ||
50 | } | ||
51 | |||
52 | desc->address[i++] = paddr; | ||
53 | recorded += chunksz; | ||
54 | } | ||
55 | |||
56 | if (recorded < bytes) { | ||
57 | printk(KERN_DEBUG | ||
58 | "%s: could only translate %ld of %ld bytes\n", | ||
59 | __func__, recorded, bytes); | ||
60 | return -ENOSPC; | ||
61 | } | ||
62 | |||
63 | /* mark remaining addresses invalid (just for safety) */ | ||
64 | while (i < desc->nr_addrs) | ||
65 | desc->address[i++] = XENCOMM_INVALID; | ||
66 | |||
67 | desc->magic = XENCOMM_MAGIC; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static struct xencomm_desc *xencomm_alloc(gfp_t gfp_mask, | ||
73 | void *buffer, unsigned long bytes) | ||
74 | { | ||
75 | struct xencomm_desc *desc; | ||
76 | unsigned long buffer_ulong = (unsigned long)buffer; | ||
77 | unsigned long start = buffer_ulong & PAGE_MASK; | ||
78 | unsigned long end = (buffer_ulong + bytes) | ~PAGE_MASK; | ||
79 | unsigned long nr_addrs = (end - start + 1) >> PAGE_SHIFT; | ||
80 | unsigned long size = sizeof(*desc) + | ||
81 | sizeof(desc->address[0]) * nr_addrs; | ||
82 | |||
83 | /* | ||
84 | * slab allocator returns at least sizeof(void*) aligned pointer. | ||
85 | * When sizeof(*desc) > sizeof(void*), struct xencomm_desc might | ||
86 | * cross page boundary. | ||
87 | */ | ||
88 | if (sizeof(*desc) > sizeof(void *)) { | ||
89 | unsigned long order = get_order(size); | ||
90 | desc = (struct xencomm_desc *)__get_free_pages(gfp_mask, | ||
91 | order); | ||
92 | if (desc == NULL) | ||
93 | return NULL; | ||
94 | |||
95 | desc->nr_addrs = | ||
96 | ((PAGE_SIZE << order) - sizeof(struct xencomm_desc)) / | ||
97 | sizeof(*desc->address); | ||
98 | } else { | ||
99 | desc = kmalloc(size, gfp_mask); | ||
100 | if (desc == NULL) | ||
101 | return NULL; | ||
102 | |||
103 | desc->nr_addrs = nr_addrs; | ||
104 | } | ||
105 | return desc; | ||
106 | } | ||
107 | |||
108 | void xencomm_free(struct xencomm_handle *desc) | ||
109 | { | ||
110 | if (desc && !((ulong)desc & XENCOMM_INLINE_FLAG)) { | ||
111 | struct xencomm_desc *desc__ = (struct xencomm_desc *)desc; | ||
112 | if (sizeof(*desc__) > sizeof(void *)) { | ||
113 | unsigned long size = sizeof(*desc__) + | ||
114 | sizeof(desc__->address[0]) * desc__->nr_addrs; | ||
115 | unsigned long order = get_order(size); | ||
116 | free_pages((unsigned long)__va(desc), order); | ||
117 | } else | ||
118 | kfree(__va(desc)); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | static int xencomm_create(void *buffer, unsigned long bytes, | ||
123 | struct xencomm_desc **ret, gfp_t gfp_mask) | ||
124 | { | ||
125 | struct xencomm_desc *desc; | ||
126 | int rc; | ||
127 | |||
128 | pr_debug("%s: %p[%ld]\n", __func__, buffer, bytes); | ||
129 | |||
130 | if (bytes == 0) { | ||
131 | /* don't create a descriptor; Xen recognizes NULL. */ | ||
132 | BUG_ON(buffer != NULL); | ||
133 | *ret = NULL; | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | BUG_ON(buffer == NULL); /* 'bytes' is non-zero */ | ||
138 | |||
139 | desc = xencomm_alloc(gfp_mask, buffer, bytes); | ||
140 | if (!desc) { | ||
141 | printk(KERN_DEBUG "%s failure\n", "xencomm_alloc"); | ||
142 | return -ENOMEM; | ||
143 | } | ||
144 | |||
145 | rc = xencomm_init(desc, buffer, bytes); | ||
146 | if (rc) { | ||
147 | printk(KERN_DEBUG "%s failure: %d\n", "xencomm_init", rc); | ||
148 | xencomm_free((struct xencomm_handle *)__pa(desc)); | ||
149 | return rc; | ||
150 | } | ||
151 | |||
152 | *ret = desc; | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static struct xencomm_handle *xencomm_create_inline(void *ptr) | ||
157 | { | ||
158 | unsigned long paddr; | ||
159 | |||
160 | BUG_ON(!xencomm_is_phys_contiguous((unsigned long)ptr)); | ||
161 | |||
162 | paddr = (unsigned long)xencomm_pa(ptr); | ||
163 | BUG_ON(paddr & XENCOMM_INLINE_FLAG); | ||
164 | return (struct xencomm_handle *)(paddr | XENCOMM_INLINE_FLAG); | ||
165 | } | ||
166 | |||
167 | /* "mini" routine, for stack-based communications: */ | ||
168 | static int xencomm_create_mini(void *buffer, | ||
169 | unsigned long bytes, struct xencomm_mini *xc_desc, | ||
170 | struct xencomm_desc **ret) | ||
171 | { | ||
172 | int rc = 0; | ||
173 | struct xencomm_desc *desc; | ||
174 | BUG_ON(((unsigned long)xc_desc) % sizeof(*xc_desc) != 0); | ||
175 | |||
176 | desc = (void *)xc_desc; | ||
177 | |||
178 | desc->nr_addrs = XENCOMM_MINI_ADDRS; | ||
179 | |||
180 | rc = xencomm_init(desc, buffer, bytes); | ||
181 | if (!rc) | ||
182 | *ret = desc; | ||
183 | |||
184 | return rc; | ||
185 | } | ||
186 | |||
187 | struct xencomm_handle *xencomm_map(void *ptr, unsigned long bytes) | ||
188 | { | ||
189 | int rc; | ||
190 | struct xencomm_desc *desc; | ||
191 | |||
192 | if (xencomm_is_phys_contiguous((unsigned long)ptr)) | ||
193 | return xencomm_create_inline(ptr); | ||
194 | |||
195 | rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL); | ||
196 | |||
197 | if (rc || desc == NULL) | ||
198 | return NULL; | ||
199 | |||
200 | return xencomm_pa(desc); | ||
201 | } | ||
202 | |||
203 | struct xencomm_handle *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, | ||
204 | struct xencomm_mini *xc_desc) | ||
205 | { | ||
206 | int rc; | ||
207 | struct xencomm_desc *desc = NULL; | ||
208 | |||
209 | if (xencomm_is_phys_contiguous((unsigned long)ptr)) | ||
210 | return xencomm_create_inline(ptr); | ||
211 | |||
212 | rc = xencomm_create_mini(ptr, bytes, xc_desc, | ||
213 | &desc); | ||
214 | |||
215 | if (rc) | ||
216 | return NULL; | ||
217 | |||
218 | return xencomm_pa(desc); | ||
219 | } | ||