diff options
Diffstat (limited to 'drivers')
489 files changed, 6982 insertions, 5717 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index 694d5a70d6ce..c70d6e45dc10 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -134,8 +134,6 @@ source "drivers/staging/Kconfig" | |||
134 | 134 | ||
135 | source "drivers/platform/Kconfig" | 135 | source "drivers/platform/Kconfig" |
136 | 136 | ||
137 | source "drivers/soc/Kconfig" | ||
138 | |||
139 | source "drivers/clk/Kconfig" | 137 | source "drivers/clk/Kconfig" |
140 | 138 | ||
141 | source "drivers/hwspinlock/Kconfig" | 139 | source "drivers/hwspinlock/Kconfig" |
diff --git a/drivers/Makefile b/drivers/Makefile index 67d2334dc41e..527a6da8d539 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/ | |||
50 | obj-y += tty/ | 50 | obj-y += tty/ |
51 | obj-y += char/ | 51 | obj-y += char/ |
52 | 52 | ||
53 | # gpu/ comes after char for AGP vs DRM startup | 53 | # iommu/ comes before gpu as gpu are using iommu controllers |
54 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | ||
55 | |||
56 | # gpu/ comes after char for AGP vs DRM startup and after iommu | ||
54 | obj-y += gpu/ | 57 | obj-y += gpu/ |
55 | 58 | ||
56 | obj-$(CONFIG_CONNECTOR) += connector/ | 59 | obj-$(CONFIG_CONNECTOR) += connector/ |
@@ -141,7 +144,6 @@ obj-y += clk/ | |||
141 | 144 | ||
142 | obj-$(CONFIG_MAILBOX) += mailbox/ | 145 | obj-$(CONFIG_MAILBOX) += mailbox/ |
143 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ | 146 | obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ |
144 | obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ | ||
145 | obj-$(CONFIG_REMOTEPROC) += remoteproc/ | 147 | obj-$(CONFIG_REMOTEPROC) += remoteproc/ |
146 | obj-$(CONFIG_RPMSG) += rpmsg/ | 148 | obj-$(CONFIG_RPMSG) += rpmsg/ |
147 | 149 | ||
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 1fdf5e07a1c7..1020b1b53a17 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -170,7 +170,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
170 | acpi_status status; | 170 | acpi_status status; |
171 | int ret; | 171 | int ret; |
172 | 172 | ||
173 | if (pr->apic_id == -1) | 173 | if (pr->phys_id == -1) |
174 | return -ENODEV; | 174 | return -ENODEV; |
175 | 175 | ||
176 | status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); | 176 | status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); |
@@ -180,13 +180,13 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
180 | cpu_maps_update_begin(); | 180 | cpu_maps_update_begin(); |
181 | cpu_hotplug_begin(); | 181 | cpu_hotplug_begin(); |
182 | 182 | ||
183 | ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id); | 183 | ret = acpi_map_cpu(pr->handle, pr->phys_id, &pr->id); |
184 | if (ret) | 184 | if (ret) |
185 | goto out; | 185 | goto out; |
186 | 186 | ||
187 | ret = arch_register_cpu(pr->id); | 187 | ret = arch_register_cpu(pr->id); |
188 | if (ret) { | 188 | if (ret) { |
189 | acpi_unmap_lsapic(pr->id); | 189 | acpi_unmap_cpu(pr->id); |
190 | goto out; | 190 | goto out; |
191 | } | 191 | } |
192 | 192 | ||
@@ -215,7 +215,7 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
215 | union acpi_object object = { 0 }; | 215 | union acpi_object object = { 0 }; |
216 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 216 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
217 | struct acpi_processor *pr = acpi_driver_data(device); | 217 | struct acpi_processor *pr = acpi_driver_data(device); |
218 | int apic_id, cpu_index, device_declaration = 0; | 218 | int phys_id, cpu_index, device_declaration = 0; |
219 | acpi_status status = AE_OK; | 219 | acpi_status status = AE_OK; |
220 | static int cpu0_initialized; | 220 | static int cpu0_initialized; |
221 | unsigned long long value; | 221 | unsigned long long value; |
@@ -262,15 +262,18 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
262 | pr->acpi_id = value; | 262 | pr->acpi_id = value; |
263 | } | 263 | } |
264 | 264 | ||
265 | apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); | 265 | phys_id = acpi_get_phys_id(pr->handle, device_declaration, pr->acpi_id); |
266 | if (apic_id < 0) | 266 | if (phys_id < 0) |
267 | acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); | 267 | acpi_handle_debug(pr->handle, "failed to get CPU physical ID.\n"); |
268 | pr->apic_id = apic_id; | 268 | pr->phys_id = phys_id; |
269 | 269 | ||
270 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | 270 | cpu_index = acpi_map_cpuid(pr->phys_id, pr->acpi_id); |
271 | if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { | 271 | if (!cpu0_initialized && !acpi_has_cpu_in_madt()) { |
272 | cpu0_initialized = 1; | 272 | cpu0_initialized = 1; |
273 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 273 | /* |
274 | * Handle UP system running SMP kernel, with no CPU | ||
275 | * entry in MADT | ||
276 | */ | ||
274 | if ((cpu_index == -1) && (num_online_cpus() == 1)) | 277 | if ((cpu_index == -1) && (num_online_cpus() == 1)) |
275 | cpu_index = 0; | 278 | cpu_index = 0; |
276 | } | 279 | } |
@@ -458,7 +461,7 @@ static void acpi_processor_remove(struct acpi_device *device) | |||
458 | 461 | ||
459 | /* Remove the CPU. */ | 462 | /* Remove the CPU. */ |
460 | arch_unregister_cpu(pr->id); | 463 | arch_unregister_cpu(pr->id); |
461 | acpi_unmap_lsapic(pr->id); | 464 | acpi_unmap_cpu(pr->id); |
462 | 465 | ||
463 | cpu_hotplug_done(); | 466 | cpu_hotplug_done(); |
464 | cpu_maps_update_done(); | 467 | cpu_maps_update_done(); |
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c2daa85fc9f7..c0d44d394ca3 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -257,7 +257,7 @@ int acpi_bus_init_power(struct acpi_device *device) | |||
257 | 257 | ||
258 | device->power.state = ACPI_STATE_UNKNOWN; | 258 | device->power.state = ACPI_STATE_UNKNOWN; |
259 | if (!acpi_device_is_present(device)) | 259 | if (!acpi_device_is_present(device)) |
260 | return 0; | 260 | return -ENXIO; |
261 | 261 | ||
262 | result = acpi_device_get_power(device, &state); | 262 | result = acpi_device_get_power(device, &state); |
263 | if (result) | 263 | if (result) |
diff --git a/drivers/acpi/int340x_thermal.c b/drivers/acpi/int340x_thermal.c index a27d31d1ba24..9dcf83682e36 100644 --- a/drivers/acpi/int340x_thermal.c +++ b/drivers/acpi/int340x_thermal.c | |||
@@ -14,10 +14,10 @@ | |||
14 | 14 | ||
15 | #include "internal.h" | 15 | #include "internal.h" |
16 | 16 | ||
17 | #define DO_ENUMERATION 0x01 | 17 | #define INT3401_DEVICE 0X01 |
18 | static const struct acpi_device_id int340x_thermal_device_ids[] = { | 18 | static const struct acpi_device_id int340x_thermal_device_ids[] = { |
19 | {"INT3400", DO_ENUMERATION }, | 19 | {"INT3400"}, |
20 | {"INT3401"}, | 20 | {"INT3401", INT3401_DEVICE}, |
21 | {"INT3402"}, | 21 | {"INT3402"}, |
22 | {"INT3403"}, | 22 | {"INT3403"}, |
23 | {"INT3404"}, | 23 | {"INT3404"}, |
@@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev, | |||
34 | const struct acpi_device_id *id) | 34 | const struct acpi_device_id *id) |
35 | { | 35 | { |
36 | #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) | 36 | #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) |
37 | if (id->driver_data == DO_ENUMERATION) | 37 | acpi_create_platform_device(adev); |
38 | #elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE) | ||
39 | /* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */ | ||
40 | if (id->driver_data == INT3401_DEVICE) | ||
38 | acpi_create_platform_device(adev); | 41 | acpi_create_platform_device(adev); |
39 | #endif | 42 | #endif |
40 | return 1; | 43 | return 1; |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 5277a0ee5704..b1def411c0b8 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
512 | dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); | 512 | dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); |
513 | if (gsi >= 0) { | 513 | if (gsi >= 0) { |
514 | acpi_unregister_gsi(gsi); | 514 | acpi_unregister_gsi(gsi); |
515 | dev->irq = 0; | ||
516 | dev->irq_managed = 0; | 515 | dev->irq_managed = 0; |
517 | } | 516 | } |
518 | } | 517 | } |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 342942f90a10..02e48394276c 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -69,7 +69,7 @@ static int map_madt_entry(int type, u32 acpi_id) | |||
69 | unsigned long madt_end, entry; | 69 | unsigned long madt_end, entry; |
70 | static struct acpi_table_madt *madt; | 70 | static struct acpi_table_madt *madt; |
71 | static int read_madt; | 71 | static int read_madt; |
72 | int apic_id = -1; | 72 | int phys_id = -1; /* CPU hardware ID */ |
73 | 73 | ||
74 | if (!read_madt) { | 74 | if (!read_madt) { |
75 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, | 75 | if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, |
@@ -79,7 +79,7 @@ static int map_madt_entry(int type, u32 acpi_id) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | if (!madt) | 81 | if (!madt) |
82 | return apic_id; | 82 | return phys_id; |
83 | 83 | ||
84 | entry = (unsigned long)madt; | 84 | entry = (unsigned long)madt; |
85 | madt_end = entry + madt->header.length; | 85 | madt_end = entry + madt->header.length; |
@@ -91,18 +91,18 @@ static int map_madt_entry(int type, u32 acpi_id) | |||
91 | struct acpi_subtable_header *header = | 91 | struct acpi_subtable_header *header = |
92 | (struct acpi_subtable_header *)entry; | 92 | (struct acpi_subtable_header *)entry; |
93 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | 93 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
94 | if (!map_lapic_id(header, acpi_id, &apic_id)) | 94 | if (!map_lapic_id(header, acpi_id, &phys_id)) |
95 | break; | 95 | break; |
96 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { | 96 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { |
97 | if (!map_x2apic_id(header, type, acpi_id, &apic_id)) | 97 | if (!map_x2apic_id(header, type, acpi_id, &phys_id)) |
98 | break; | 98 | break; |
99 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 99 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
100 | if (!map_lsapic_id(header, type, acpi_id, &apic_id)) | 100 | if (!map_lsapic_id(header, type, acpi_id, &phys_id)) |
101 | break; | 101 | break; |
102 | } | 102 | } |
103 | entry += header->length; | 103 | entry += header->length; |
104 | } | 104 | } |
105 | return apic_id; | 105 | return phys_id; |
106 | } | 106 | } |
107 | 107 | ||
108 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) | 108 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
@@ -110,7 +110,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) | |||
110 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 110 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
111 | union acpi_object *obj; | 111 | union acpi_object *obj; |
112 | struct acpi_subtable_header *header; | 112 | struct acpi_subtable_header *header; |
113 | int apic_id = -1; | 113 | int phys_id = -1; |
114 | 114 | ||
115 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) | 115 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) |
116 | goto exit; | 116 | goto exit; |
@@ -126,38 +126,38 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) | |||
126 | 126 | ||
127 | header = (struct acpi_subtable_header *)obj->buffer.pointer; | 127 | header = (struct acpi_subtable_header *)obj->buffer.pointer; |
128 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) | 128 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) |
129 | map_lapic_id(header, acpi_id, &apic_id); | 129 | map_lapic_id(header, acpi_id, &phys_id); |
130 | else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) | 130 | else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) |
131 | map_lsapic_id(header, type, acpi_id, &apic_id); | 131 | map_lsapic_id(header, type, acpi_id, &phys_id); |
132 | else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) | 132 | else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) |
133 | map_x2apic_id(header, type, acpi_id, &apic_id); | 133 | map_x2apic_id(header, type, acpi_id, &phys_id); |
134 | 134 | ||
135 | exit: | 135 | exit: |
136 | kfree(buffer.pointer); | 136 | kfree(buffer.pointer); |
137 | return apic_id; | 137 | return phys_id; |
138 | } | 138 | } |
139 | 139 | ||
140 | int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) | 140 | int acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id) |
141 | { | 141 | { |
142 | int apic_id; | 142 | int phys_id; |
143 | 143 | ||
144 | apic_id = map_mat_entry(handle, type, acpi_id); | 144 | phys_id = map_mat_entry(handle, type, acpi_id); |
145 | if (apic_id == -1) | 145 | if (phys_id == -1) |
146 | apic_id = map_madt_entry(type, acpi_id); | 146 | phys_id = map_madt_entry(type, acpi_id); |
147 | 147 | ||
148 | return apic_id; | 148 | return phys_id; |
149 | } | 149 | } |
150 | 150 | ||
151 | int acpi_map_cpuid(int apic_id, u32 acpi_id) | 151 | int acpi_map_cpuid(int phys_id, u32 acpi_id) |
152 | { | 152 | { |
153 | #ifdef CONFIG_SMP | 153 | #ifdef CONFIG_SMP |
154 | int i; | 154 | int i; |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | if (apic_id == -1) { | 157 | if (phys_id == -1) { |
158 | /* | 158 | /* |
159 | * On UP processor, there is no _MAT or MADT table. | 159 | * On UP processor, there is no _MAT or MADT table. |
160 | * So above apic_id is always set to -1. | 160 | * So above phys_id is always set to -1. |
161 | * | 161 | * |
162 | * BIOS may define multiple CPU handles even for UP processor. | 162 | * BIOS may define multiple CPU handles even for UP processor. |
163 | * For example, | 163 | * For example, |
@@ -170,7 +170,7 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) | |||
170 | * Processor (CPU3, 0x03, 0x00000410, 0x06) {} | 170 | * Processor (CPU3, 0x03, 0x00000410, 0x06) {} |
171 | * } | 171 | * } |
172 | * | 172 | * |
173 | * Ignores apic_id and always returns 0 for the processor | 173 | * Ignores phys_id and always returns 0 for the processor |
174 | * handle with acpi id 0 if nr_cpu_ids is 1. | 174 | * handle with acpi id 0 if nr_cpu_ids is 1. |
175 | * This should be the case if SMP tables are not found. | 175 | * This should be the case if SMP tables are not found. |
176 | * Return -1 for other CPU's handle. | 176 | * Return -1 for other CPU's handle. |
@@ -178,28 +178,28 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) | |||
178 | if (nr_cpu_ids <= 1 && acpi_id == 0) | 178 | if (nr_cpu_ids <= 1 && acpi_id == 0) |
179 | return acpi_id; | 179 | return acpi_id; |
180 | else | 180 | else |
181 | return apic_id; | 181 | return phys_id; |
182 | } | 182 | } |
183 | 183 | ||
184 | #ifdef CONFIG_SMP | 184 | #ifdef CONFIG_SMP |
185 | for_each_possible_cpu(i) { | 185 | for_each_possible_cpu(i) { |
186 | if (cpu_physical_id(i) == apic_id) | 186 | if (cpu_physical_id(i) == phys_id) |
187 | return i; | 187 | return i; |
188 | } | 188 | } |
189 | #else | 189 | #else |
190 | /* In UP kernel, only processor 0 is valid */ | 190 | /* In UP kernel, only processor 0 is valid */ |
191 | if (apic_id == 0) | 191 | if (phys_id == 0) |
192 | return apic_id; | 192 | return phys_id; |
193 | #endif | 193 | #endif |
194 | return -1; | 194 | return -1; |
195 | } | 195 | } |
196 | 196 | ||
197 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | 197 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) |
198 | { | 198 | { |
199 | int apic_id; | 199 | int phys_id; |
200 | 200 | ||
201 | apic_id = acpi_get_apicid(handle, type, acpi_id); | 201 | phys_id = acpi_get_phys_id(handle, type, acpi_id); |
202 | 202 | ||
203 | return acpi_map_cpuid(apic_id, acpi_id); | 203 | return acpi_map_cpuid(phys_id, acpi_id); |
204 | } | 204 | } |
205 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 205 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 499536504698..87b704e41877 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) | |||
985 | state->flags = 0; | 985 | state->flags = 0; |
986 | switch (cx->type) { | 986 | switch (cx->type) { |
987 | case ACPI_STATE_C1: | 987 | case ACPI_STATE_C1: |
988 | if (cx->entry_method != ACPI_CSTATE_FFH) | ||
989 | state->flags |= CPUIDLE_FLAG_TIME_INVALID; | ||
990 | 988 | ||
991 | state->enter = acpi_idle_enter_c1; | 989 | state->enter = acpi_idle_enter_c1; |
992 | state->enter_dead = acpi_idle_play_dead; | 990 | state->enter_dead = acpi_idle_play_dead; |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 16914cc30882..dc4d8960684a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1001,7 +1001,7 @@ static void acpi_free_power_resources_lists(struct acpi_device *device) | |||
1001 | if (device->wakeup.flags.valid) | 1001 | if (device->wakeup.flags.valid) |
1002 | acpi_power_resources_list_free(&device->wakeup.resources); | 1002 | acpi_power_resources_list_free(&device->wakeup.resources); |
1003 | 1003 | ||
1004 | if (!device->flags.power_manageable) | 1004 | if (!device->power.flags.power_resources) |
1005 | return; | 1005 | return; |
1006 | 1006 | ||
1007 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { | 1007 | for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { |
@@ -1744,10 +1744,8 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) | |||
1744 | device->power.flags.power_resources) | 1744 | device->power.flags.power_resources) |
1745 | device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; | 1745 | device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; |
1746 | 1746 | ||
1747 | if (acpi_bus_init_power(device)) { | 1747 | if (acpi_bus_init_power(device)) |
1748 | acpi_free_power_resources_lists(device); | ||
1749 | device->flags.power_manageable = 0; | 1748 | device->flags.power_manageable = 0; |
1750 | } | ||
1751 | } | 1749 | } |
1752 | 1750 | ||
1753 | static void acpi_bus_get_flags(struct acpi_device *device) | 1751 | static void acpi_bus_get_flags(struct acpi_device *device) |
@@ -2371,13 +2369,18 @@ static void acpi_bus_attach(struct acpi_device *device) | |||
2371 | /* Skip devices that are not present. */ | 2369 | /* Skip devices that are not present. */ |
2372 | if (!acpi_device_is_present(device)) { | 2370 | if (!acpi_device_is_present(device)) { |
2373 | device->flags.visited = false; | 2371 | device->flags.visited = false; |
2372 | device->flags.power_manageable = 0; | ||
2374 | return; | 2373 | return; |
2375 | } | 2374 | } |
2376 | if (device->handler) | 2375 | if (device->handler) |
2377 | goto ok; | 2376 | goto ok; |
2378 | 2377 | ||
2379 | if (!device->flags.initialized) { | 2378 | if (!device->flags.initialized) { |
2380 | acpi_bus_update_power(device, NULL); | 2379 | device->flags.power_manageable = |
2380 | device->power.states[ACPI_STATE_D0].flags.valid; | ||
2381 | if (acpi_bus_init_power(device)) | ||
2382 | device->flags.power_manageable = 0; | ||
2383 | |||
2381 | device->flags.initialized = true; | 2384 | device->flags.initialized = true; |
2382 | } | 2385 | } |
2383 | device->flags.visited = false; | 2386 | device->flags.visited = false; |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 1eaadff2e198..032db459370f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -505,6 +505,33 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
505 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), | 505 | DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), |
506 | }, | 506 | }, |
507 | }, | 507 | }, |
508 | |||
509 | { | ||
510 | .callback = video_disable_native_backlight, | ||
511 | .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", | ||
512 | .matches = { | ||
513 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
514 | DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), | ||
515 | }, | ||
516 | }, | ||
517 | { | ||
518 | .callback = video_disable_native_backlight, | ||
519 | .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", | ||
520 | .matches = { | ||
521 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
522 | DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"), | ||
523 | }, | ||
524 | }, | ||
525 | |||
526 | { | ||
527 | /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ | ||
528 | .callback = video_disable_native_backlight, | ||
529 | .ident = "Dell XPS15 L521X", | ||
530 | .matches = { | ||
531 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
532 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), | ||
533 | }, | ||
534 | }, | ||
508 | {} | 535 | {} |
509 | }; | 536 | }; |
510 | 537 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index a3a13605a9c4..5f601553b9b0 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -835,6 +835,7 @@ config PATA_AT32 | |||
835 | config PATA_AT91 | 835 | config PATA_AT91 |
836 | tristate "PATA support for AT91SAM9260" | 836 | tristate "PATA support for AT91SAM9260" |
837 | depends on ARM && SOC_AT91SAM9 | 837 | depends on ARM && SOC_AT91SAM9 |
838 | depends on !ARCH_MULTIPLATFORM | ||
838 | help | 839 | help |
839 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. | 840 | This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. |
840 | 841 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 49f1e6890587..33bb06e006c9 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -325,7 +325,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
325 | { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ | 325 | { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ |
326 | { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ | 326 | { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ |
327 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ | 327 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ |
328 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ | ||
329 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ | 328 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ |
330 | { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ | 329 | { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ |
331 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ | 330 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ |
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index feeb8f1e2fe8..cbcd20810355 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c | |||
@@ -125,10 +125,11 @@ static int xgene_ahci_restart_engine(struct ata_port *ap) | |||
125 | * xgene_ahci_qc_issue - Issue commands to the device | 125 | * xgene_ahci_qc_issue - Issue commands to the device |
126 | * @qc: Command to issue | 126 | * @qc: Command to issue |
127 | * | 127 | * |
128 | * Due to Hardware errata for IDENTIFY DEVICE command, the controller cannot | 128 | * Due to Hardware errata for IDENTIFY DEVICE command and PACKET |
129 | * clear the BSY bit after receiving the PIO setup FIS. This results in the dma | 129 | * command of ATAPI protocol set, the controller cannot clear the BSY bit |
130 | * state machine goes into the CMFatalErrorUpdate state and locks up. By | 130 | * after receiving the PIO setup FIS. This results in the DMA state machine |
131 | * restarting the dma engine, it removes the controller out of lock up state. | 131 | * going into the CMFatalErrorUpdate state and locks up. By restarting the |
132 | * DMA engine, it removes the controller out of lock up state. | ||
132 | */ | 133 | */ |
133 | static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) | 134 | static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) |
134 | { | 135 | { |
@@ -137,7 +138,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) | |||
137 | struct xgene_ahci_context *ctx = hpriv->plat_data; | 138 | struct xgene_ahci_context *ctx = hpriv->plat_data; |
138 | int rc = 0; | 139 | int rc = 0; |
139 | 140 | ||
140 | if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) | 141 | if (unlikely((ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA) || |
142 | (ctx->last_cmd[ap->port_no] == ATA_CMD_PACKET))) | ||
141 | xgene_ahci_restart_engine(ap); | 143 | xgene_ahci_restart_engine(ap); |
142 | 144 | ||
143 | rc = ahci_qc_issue(qc); | 145 | rc = ahci_qc_issue(qc); |
@@ -188,7 +190,7 @@ static unsigned int xgene_ahci_read_id(struct ata_device *dev, | |||
188 | * | 190 | * |
189 | * Clear reserved bit 8 (DEVSLP bit) as we don't support DEVSLP | 191 | * Clear reserved bit 8 (DEVSLP bit) as we don't support DEVSLP |
190 | */ | 192 | */ |
191 | id[ATA_ID_FEATURE_SUPP] &= ~(1 << 8); | 193 | id[ATA_ID_FEATURE_SUPP] &= cpu_to_le16(~(1 << 8)); |
192 | 194 | ||
193 | return 0; | 195 | return 0; |
194 | } | 196 | } |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 97683e45ab04..61a9c07e0dff 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -2003,7 +2003,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep) | |||
2003 | 2003 | ||
2004 | devslp = readl(port_mmio + PORT_DEVSLP); | 2004 | devslp = readl(port_mmio + PORT_DEVSLP); |
2005 | if (!(devslp & PORT_DEVSLP_DSP)) { | 2005 | if (!(devslp & PORT_DEVSLP_DSP)) { |
2006 | dev_err(ap->host->dev, "port does not support device sleep\n"); | 2006 | dev_info(ap->host->dev, "port does not support device sleep\n"); |
2007 | return; | 2007 | return; |
2008 | } | 2008 | } |
2009 | 2009 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5c84fb5c3372..d1a05f9bb91f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4233,10 +4233,33 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4233 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, | 4233 | { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, |
4234 | 4234 | ||
4235 | /* devices that don't properly handle queued TRIM commands */ | 4235 | /* devices that don't properly handle queued TRIM commands */ |
4236 | { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4236 | { "Micron_M[56]*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | |
4237 | { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4237 | ATA_HORKAGE_ZERO_AFTER_TRIM, }, |
4238 | { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4238 | { "Crucial_CT*SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, |
4239 | { "Crucial_CT*M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, | 4239 | |
4240 | /* | ||
4241 | * As defined, the DRAT (Deterministic Read After Trim) and RZAT | ||
4242 | * (Return Zero After Trim) flags in the ATA Command Set are | ||
4243 | * unreliable in the sense that they only define what happens if | ||
4244 | * the device successfully executed the DSM TRIM command. TRIM | ||
4245 | * is only advisory, however, and the device is free to silently | ||
4246 | * ignore all or parts of the request. | ||
4247 | * | ||
4248 | * Whitelist drives that are known to reliably return zeroes | ||
4249 | * after TRIM. | ||
4250 | */ | ||
4251 | |||
4252 | /* | ||
4253 | * The intel 510 drive has buggy DRAT/RZAT. Explicitly exclude | ||
4254 | * that model before whitelisting all other intel SSDs. | ||
4255 | */ | ||
4256 | { "INTEL*SSDSC2MH*", NULL, 0, }, | ||
4257 | |||
4258 | { "INTEL*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
4259 | { "SSD*INTEL*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
4260 | { "Samsung*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
4261 | { "SAMSUNG*SSD*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
4262 | { "ST[1248][0248]0[FH]*", NULL, ATA_HORKAGE_ZERO_AFTER_TRIM, }, | ||
4240 | 4263 | ||
4241 | /* | 4264 | /* |
4242 | * Some WD SATA-I drives spin up and down erratically when the link | 4265 | * Some WD SATA-I drives spin up and down erratically when the link |
@@ -4748,7 +4771,10 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | |||
4748 | return NULL; | 4771 | return NULL; |
4749 | 4772 | ||
4750 | for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) { | 4773 | for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) { |
4751 | tag = tag < max_queue ? tag : 0; | 4774 | if (ap->flags & ATA_FLAG_LOWTAG) |
4775 | tag = i; | ||
4776 | else | ||
4777 | tag = tag < max_queue ? tag : 0; | ||
4752 | 4778 | ||
4753 | /* the last tag is reserved for internal command. */ | 4779 | /* the last tag is reserved for internal command. */ |
4754 | if (tag == ATA_TAG_INTERNAL) | 4780 | if (tag == ATA_TAG_INTERNAL) |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 3dbec8954c86..8d00c2638bed 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2389,6 +2389,7 @@ const char *ata_get_cmd_descript(u8 command) | |||
2389 | 2389 | ||
2390 | return NULL; | 2390 | return NULL; |
2391 | } | 2391 | } |
2392 | EXPORT_SYMBOL_GPL(ata_get_cmd_descript); | ||
2392 | 2393 | ||
2393 | /** | 2394 | /** |
2394 | * ata_eh_link_report - report error handling to user | 2395 | * ata_eh_link_report - report error handling to user |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e364e86e84d7..6abd17a85b13 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2532,13 +2532,15 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) | |||
2532 | rbuf[15] = lowest_aligned; | 2532 | rbuf[15] = lowest_aligned; |
2533 | 2533 | ||
2534 | if (ata_id_has_trim(args->id)) { | 2534 | if (ata_id_has_trim(args->id)) { |
2535 | rbuf[14] |= 0x80; /* TPE */ | 2535 | rbuf[14] |= 0x80; /* LBPME */ |
2536 | 2536 | ||
2537 | if (ata_id_has_zero_after_trim(args->id)) | 2537 | if (ata_id_has_zero_after_trim(args->id) && |
2538 | rbuf[14] |= 0x40; /* TPRZ */ | 2538 | dev->horkage & ATA_HORKAGE_ZERO_AFTER_TRIM) { |
2539 | ata_dev_info(dev, "Enabling discard_zeroes_data\n"); | ||
2540 | rbuf[14] |= 0x40; /* LBPRZ */ | ||
2541 | } | ||
2539 | } | 2542 | } |
2540 | } | 2543 | } |
2541 | |||
2542 | return 0; | 2544 | return 0; |
2543 | } | 2545 | } |
2544 | 2546 | ||
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index db90aa35cb71..2e86e3b85266 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1333,7 +1333,19 @@ void ata_sff_flush_pio_task(struct ata_port *ap) | |||
1333 | DPRINTK("ENTER\n"); | 1333 | DPRINTK("ENTER\n"); |
1334 | 1334 | ||
1335 | cancel_delayed_work_sync(&ap->sff_pio_task); | 1335 | cancel_delayed_work_sync(&ap->sff_pio_task); |
1336 | |||
1337 | /* | ||
1338 | * We wanna reset the HSM state to IDLE. If we do so without | ||
1339 | * grabbing the port lock, critical sections protected by it which | ||
1340 | * expect the HSM state to stay stable may get surprised. For | ||
1341 | * example, we may set IDLE in between the time | ||
1342 | * __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls | ||
1343 | * ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG(). | ||
1344 | */ | ||
1345 | spin_lock_irq(ap->lock); | ||
1336 | ap->hsm_task_state = HSM_ST_IDLE; | 1346 | ap->hsm_task_state = HSM_ST_IDLE; |
1347 | spin_unlock_irq(ap->lock); | ||
1348 | |||
1337 | ap->sff_pio_task_link = NULL; | 1349 | ap->sff_pio_task_link = NULL; |
1338 | 1350 | ||
1339 | if (ata_msg_ctl(ap)) | 1351 | if (ata_msg_ctl(ap)) |
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index c7ddef89e7b0..8e8248179d20 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c | |||
@@ -797,7 +797,7 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) | |||
797 | if (err) { | 797 | if (err) { |
798 | dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns" | 798 | dev_err(host_pvt.dwc_dev, "%s: dma_request_interrupts returns" |
799 | " %d\n", __func__, err); | 799 | " %d\n", __func__, err); |
800 | goto error_out; | 800 | return err; |
801 | } | 801 | } |
802 | 802 | ||
803 | /* Enabe DMA */ | 803 | /* Enabe DMA */ |
@@ -808,11 +808,6 @@ static int dma_dwc_init(struct sata_dwc_device *hsdev, int irq) | |||
808 | sata_dma_regs); | 808 | sata_dma_regs); |
809 | 809 | ||
810 | return 0; | 810 | return 0; |
811 | |||
812 | error_out: | ||
813 | dma_dwc_exit(hsdev); | ||
814 | |||
815 | return err; | ||
816 | } | 811 | } |
817 | 812 | ||
818 | static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val) | 813 | static int sata_dwc_scr_read(struct ata_link *link, unsigned int scr, u32 *val) |
@@ -1662,7 +1657,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) | |||
1662 | char *ver = (char *)&versionr; | 1657 | char *ver = (char *)&versionr; |
1663 | u8 *base = NULL; | 1658 | u8 *base = NULL; |
1664 | int err = 0; | 1659 | int err = 0; |
1665 | int irq, rc; | 1660 | int irq; |
1666 | struct ata_host *host; | 1661 | struct ata_host *host; |
1667 | struct ata_port_info pi = sata_dwc_port_info[0]; | 1662 | struct ata_port_info pi = sata_dwc_port_info[0]; |
1668 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 1663 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
@@ -1725,7 +1720,7 @@ static int sata_dwc_probe(struct platform_device *ofdev) | |||
1725 | if (irq == NO_IRQ) { | 1720 | if (irq == NO_IRQ) { |
1726 | dev_err(&ofdev->dev, "no SATA DMA irq\n"); | 1721 | dev_err(&ofdev->dev, "no SATA DMA irq\n"); |
1727 | err = -ENODEV; | 1722 | err = -ENODEV; |
1728 | goto error_out; | 1723 | goto error_iomap; |
1729 | } | 1724 | } |
1730 | 1725 | ||
1731 | /* Get physical SATA DMA register base address */ | 1726 | /* Get physical SATA DMA register base address */ |
@@ -1734,14 +1729,16 @@ static int sata_dwc_probe(struct platform_device *ofdev) | |||
1734 | dev_err(&ofdev->dev, "ioremap failed for AHBDMA register" | 1729 | dev_err(&ofdev->dev, "ioremap failed for AHBDMA register" |
1735 | " address\n"); | 1730 | " address\n"); |
1736 | err = -ENODEV; | 1731 | err = -ENODEV; |
1737 | goto error_out; | 1732 | goto error_iomap; |
1738 | } | 1733 | } |
1739 | 1734 | ||
1740 | /* Save dev for later use in dev_xxx() routines */ | 1735 | /* Save dev for later use in dev_xxx() routines */ |
1741 | host_pvt.dwc_dev = &ofdev->dev; | 1736 | host_pvt.dwc_dev = &ofdev->dev; |
1742 | 1737 | ||
1743 | /* Initialize AHB DMAC */ | 1738 | /* Initialize AHB DMAC */ |
1744 | dma_dwc_init(hsdev, irq); | 1739 | err = dma_dwc_init(hsdev, irq); |
1740 | if (err) | ||
1741 | goto error_dma_iomap; | ||
1745 | 1742 | ||
1746 | /* Enable SATA Interrupts */ | 1743 | /* Enable SATA Interrupts */ |
1747 | sata_dwc_enable_interrupts(hsdev); | 1744 | sata_dwc_enable_interrupts(hsdev); |
@@ -1759,9 +1756,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) | |||
1759 | * device discovery process, invoking our port_start() handler & | 1756 | * device discovery process, invoking our port_start() handler & |
1760 | * error_handler() to execute a dummy Softreset EH session | 1757 | * error_handler() to execute a dummy Softreset EH session |
1761 | */ | 1758 | */ |
1762 | rc = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); | 1759 | err = ata_host_activate(host, irq, sata_dwc_isr, 0, &sata_dwc_sht); |
1763 | 1760 | if (err) | |
1764 | if (rc != 0) | ||
1765 | dev_err(&ofdev->dev, "failed to activate host"); | 1761 | dev_err(&ofdev->dev, "failed to activate host"); |
1766 | 1762 | ||
1767 | dev_set_drvdata(&ofdev->dev, host); | 1763 | dev_set_drvdata(&ofdev->dev, host); |
@@ -1770,7 +1766,8 @@ static int sata_dwc_probe(struct platform_device *ofdev) | |||
1770 | error_out: | 1766 | error_out: |
1771 | /* Free SATA DMA resources */ | 1767 | /* Free SATA DMA resources */ |
1772 | dma_dwc_exit(hsdev); | 1768 | dma_dwc_exit(hsdev); |
1773 | 1769 | error_dma_iomap: | |
1770 | iounmap((void __iomem *)host_pvt.sata_dma_regs); | ||
1774 | error_iomap: | 1771 | error_iomap: |
1775 | iounmap(base); | 1772 | iounmap(base); |
1776 | error_kmalloc: | 1773 | error_kmalloc: |
@@ -1791,6 +1788,7 @@ static int sata_dwc_remove(struct platform_device *ofdev) | |||
1791 | /* Free SATA DMA resources */ | 1788 | /* Free SATA DMA resources */ |
1792 | dma_dwc_exit(hsdev); | 1789 | dma_dwc_exit(hsdev); |
1793 | 1790 | ||
1791 | iounmap((void __iomem *)host_pvt.sata_dma_regs); | ||
1794 | iounmap(hsdev->reg_base); | 1792 | iounmap(hsdev->reg_base); |
1795 | kfree(hsdev); | 1793 | kfree(hsdev); |
1796 | kfree(host); | 1794 | kfree(host); |
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index d81b20ddb527..ea655949023f 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c | |||
@@ -246,7 +246,7 @@ enum { | |||
246 | /* host flags */ | 246 | /* host flags */ |
247 | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | | 247 | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA | |
248 | ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | | 248 | ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA | |
249 | ATA_FLAG_AN | ATA_FLAG_PMP, | 249 | ATA_FLAG_AN | ATA_FLAG_PMP | ATA_FLAG_LOWTAG, |
250 | SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ | 250 | SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ |
251 | 251 | ||
252 | IRQ_STAT_4PORTS = 0xf, | 252 | IRQ_STAT_4PORTS = 0xf, |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6a103a35ea9b..0d8780c04a5e 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -2088,7 +2088,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider); | |||
2088 | * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR() | 2088 | * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR() |
2089 | * on failure. | 2089 | * on failure. |
2090 | */ | 2090 | */ |
2091 | static struct generic_pm_domain *of_genpd_get_from_provider( | 2091 | struct generic_pm_domain *of_genpd_get_from_provider( |
2092 | struct of_phandle_args *genpdspec) | 2092 | struct of_phandle_args *genpdspec) |
2093 | { | 2093 | { |
2094 | struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); | 2094 | struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); |
@@ -2108,6 +2108,7 @@ static struct generic_pm_domain *of_genpd_get_from_provider( | |||
2108 | 2108 | ||
2109 | return genpd; | 2109 | return genpd; |
2110 | } | 2110 | } |
2111 | EXPORT_SYMBOL_GPL(of_genpd_get_from_provider); | ||
2111 | 2112 | ||
2112 | /** | 2113 | /** |
2113 | * genpd_dev_pm_detach - Detach a device from its PM domain. | 2114 | * genpd_dev_pm_detach - Detach a device from its PM domain. |
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index d24dd614a0bd..106c69359306 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c | |||
@@ -108,6 +108,14 @@ static LIST_HEAD(dev_opp_list); | |||
108 | /* Lock to allow exclusive modification to the device and opp lists */ | 108 | /* Lock to allow exclusive modification to the device and opp lists */ |
109 | static DEFINE_MUTEX(dev_opp_list_lock); | 109 | static DEFINE_MUTEX(dev_opp_list_lock); |
110 | 110 | ||
111 | #define opp_rcu_lockdep_assert() \ | ||
112 | do { \ | ||
113 | rcu_lockdep_assert(rcu_read_lock_held() || \ | ||
114 | lockdep_is_held(&dev_opp_list_lock), \ | ||
115 | "Missing rcu_read_lock() or " \ | ||
116 | "dev_opp_list_lock protection"); \ | ||
117 | } while (0) | ||
118 | |||
111 | /** | 119 | /** |
112 | * find_device_opp() - find device_opp struct using device pointer | 120 | * find_device_opp() - find device_opp struct using device pointer |
113 | * @dev: device pointer used to lookup device OPPs | 121 | * @dev: device pointer used to lookup device OPPs |
@@ -208,9 +216,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); | |||
208 | * This function returns the number of available opps if there are any, | 216 | * This function returns the number of available opps if there are any, |
209 | * else returns 0 if none or the corresponding error value. | 217 | * else returns 0 if none or the corresponding error value. |
210 | * | 218 | * |
211 | * Locking: This function must be called under rcu_read_lock(). This function | 219 | * Locking: This function takes rcu_read_lock(). |
212 | * internally references two RCU protected structures: device_opp and opp which | ||
213 | * are safe as long as we are under a common RCU locked section. | ||
214 | */ | 220 | */ |
215 | int dev_pm_opp_get_opp_count(struct device *dev) | 221 | int dev_pm_opp_get_opp_count(struct device *dev) |
216 | { | 222 | { |
@@ -218,11 +224,14 @@ int dev_pm_opp_get_opp_count(struct device *dev) | |||
218 | struct dev_pm_opp *temp_opp; | 224 | struct dev_pm_opp *temp_opp; |
219 | int count = 0; | 225 | int count = 0; |
220 | 226 | ||
227 | rcu_read_lock(); | ||
228 | |||
221 | dev_opp = find_device_opp(dev); | 229 | dev_opp = find_device_opp(dev); |
222 | if (IS_ERR(dev_opp)) { | 230 | if (IS_ERR(dev_opp)) { |
223 | int r = PTR_ERR(dev_opp); | 231 | count = PTR_ERR(dev_opp); |
224 | dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r); | 232 | dev_err(dev, "%s: device OPP not found (%d)\n", |
225 | return r; | 233 | __func__, count); |
234 | goto out_unlock; | ||
226 | } | 235 | } |
227 | 236 | ||
228 | list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { | 237 | list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { |
@@ -230,6 +239,8 @@ int dev_pm_opp_get_opp_count(struct device *dev) | |||
230 | count++; | 239 | count++; |
231 | } | 240 | } |
232 | 241 | ||
242 | out_unlock: | ||
243 | rcu_read_unlock(); | ||
233 | return count; | 244 | return count; |
234 | } | 245 | } |
235 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); | 246 | EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); |
@@ -267,6 +278,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, | |||
267 | struct device_opp *dev_opp; | 278 | struct device_opp *dev_opp; |
268 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | 279 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); |
269 | 280 | ||
281 | opp_rcu_lockdep_assert(); | ||
282 | |||
270 | dev_opp = find_device_opp(dev); | 283 | dev_opp = find_device_opp(dev); |
271 | if (IS_ERR(dev_opp)) { | 284 | if (IS_ERR(dev_opp)) { |
272 | int r = PTR_ERR(dev_opp); | 285 | int r = PTR_ERR(dev_opp); |
@@ -313,6 +326,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, | |||
313 | struct device_opp *dev_opp; | 326 | struct device_opp *dev_opp; |
314 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | 327 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); |
315 | 328 | ||
329 | opp_rcu_lockdep_assert(); | ||
330 | |||
316 | if (!dev || !freq) { | 331 | if (!dev || !freq) { |
317 | dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); | 332 | dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); |
318 | return ERR_PTR(-EINVAL); | 333 | return ERR_PTR(-EINVAL); |
@@ -361,6 +376,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, | |||
361 | struct device_opp *dev_opp; | 376 | struct device_opp *dev_opp; |
362 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); | 377 | struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE); |
363 | 378 | ||
379 | opp_rcu_lockdep_assert(); | ||
380 | |||
364 | if (!dev || !freq) { | 381 | if (!dev || !freq) { |
365 | dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); | 382 | dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); |
366 | return ERR_PTR(-EINVAL); | 383 | return ERR_PTR(-EINVAL); |
@@ -783,9 +800,15 @@ void of_free_opp_table(struct device *dev) | |||
783 | 800 | ||
784 | /* Check for existing list for 'dev' */ | 801 | /* Check for existing list for 'dev' */ |
785 | dev_opp = find_device_opp(dev); | 802 | dev_opp = find_device_opp(dev); |
786 | if (WARN(IS_ERR(dev_opp), "%s: dev_opp: %ld\n", dev_name(dev), | 803 | if (IS_ERR(dev_opp)) { |
787 | PTR_ERR(dev_opp))) | 804 | int error = PTR_ERR(dev_opp); |
805 | if (error != -ENODEV) | ||
806 | WARN(1, "%s: dev_opp: %d\n", | ||
807 | IS_ERR_OR_NULL(dev) ? | ||
808 | "Invalid device" : dev_name(dev), | ||
809 | error); | ||
788 | return; | 810 | return; |
811 | } | ||
789 | 812 | ||
790 | /* Hold our list modification lock here */ | 813 | /* Hold our list modification lock here */ |
791 | mutex_lock(&dev_opp_list_lock); | 814 | mutex_lock(&dev_opp_list_lock); |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ae9f615382f6..aa2224aa7caa 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
@@ -530,7 +530,7 @@ static int null_add_dev(void) | |||
530 | goto out_cleanup_queues; | 530 | goto out_cleanup_queues; |
531 | 531 | ||
532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); | 532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); |
533 | if (!nullb->q) { | 533 | if (IS_ERR(nullb->q)) { |
534 | rv = -ENOMEM; | 534 | rv = -ENOMEM; |
535 | goto out_cleanup_tags; | 535 | goto out_cleanup_tags; |
536 | } | 536 | } |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b1d5d8797315..d826bf3e62c8 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
@@ -106,7 +106,7 @@ struct nvme_queue { | |||
106 | dma_addr_t cq_dma_addr; | 106 | dma_addr_t cq_dma_addr; |
107 | u32 __iomem *q_db; | 107 | u32 __iomem *q_db; |
108 | u16 q_depth; | 108 | u16 q_depth; |
109 | u16 cq_vector; | 109 | s16 cq_vector; |
110 | u16 sq_head; | 110 | u16 sq_head; |
111 | u16 sq_tail; | 111 | u16 sq_tail; |
112 | u16 cq_head; | 112 | u16 cq_head; |
@@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx, | |||
215 | cmd->fn = handler; | 215 | cmd->fn = handler; |
216 | cmd->ctx = ctx; | 216 | cmd->ctx = ctx; |
217 | cmd->aborted = 0; | 217 | cmd->aborted = 0; |
218 | blk_mq_start_request(blk_mq_rq_from_pdu(cmd)); | ||
218 | } | 219 | } |
219 | 220 | ||
220 | /* Special values must be less than 0x1000 */ | 221 | /* Special values must be less than 0x1000 */ |
@@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx, | |||
431 | if (unlikely(status)) { | 432 | if (unlikely(status)) { |
432 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) | 433 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) |
433 | && (jiffies - req->start_time) < req->timeout) { | 434 | && (jiffies - req->start_time) < req->timeout) { |
435 | unsigned long flags; | ||
436 | |||
434 | blk_mq_requeue_request(req); | 437 | blk_mq_requeue_request(req); |
435 | blk_mq_kick_requeue_list(req->q); | 438 | spin_lock_irqsave(req->q->queue_lock, flags); |
439 | if (!blk_queue_stopped(req->q)) | ||
440 | blk_mq_kick_requeue_list(req->q); | ||
441 | spin_unlock_irqrestore(req->q->queue_lock, flags); | ||
436 | return; | 442 | return; |
437 | } | 443 | } |
438 | req->errors = nvme_error_status(status); | 444 | req->errors = nvme_error_status(status); |
@@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
664 | } | 670 | } |
665 | } | 671 | } |
666 | 672 | ||
667 | blk_mq_start_request(req); | ||
668 | |||
669 | nvme_set_info(cmd, iod, req_completion); | 673 | nvme_set_info(cmd, iod, req_completion); |
670 | spin_lock_irq(&nvmeq->q_lock); | 674 | spin_lock_irq(&nvmeq->q_lock); |
671 | if (req->cmd_flags & REQ_DISCARD) | 675 | if (req->cmd_flags & REQ_DISCARD) |
@@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) | |||
835 | if (IS_ERR(req)) | 839 | if (IS_ERR(req)) |
836 | return PTR_ERR(req); | 840 | return PTR_ERR(req); |
837 | 841 | ||
842 | req->cmd_flags |= REQ_NO_TIMEOUT; | ||
838 | cmd_info = blk_mq_rq_to_pdu(req); | 843 | cmd_info = blk_mq_rq_to_pdu(req); |
839 | nvme_set_info(cmd_info, req, async_req_completion); | 844 | nvme_set_info(cmd_info, req, async_req_completion); |
840 | 845 | ||
@@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req) | |||
1016 | struct nvme_command cmd; | 1021 | struct nvme_command cmd; |
1017 | 1022 | ||
1018 | if (!nvmeq->qid || cmd_rq->aborted) { | 1023 | if (!nvmeq->qid || cmd_rq->aborted) { |
1024 | unsigned long flags; | ||
1025 | |||
1026 | spin_lock_irqsave(&dev_list_lock, flags); | ||
1019 | if (work_busy(&dev->reset_work)) | 1027 | if (work_busy(&dev->reset_work)) |
1020 | return; | 1028 | goto out; |
1021 | list_del_init(&dev->node); | 1029 | list_del_init(&dev->node); |
1022 | dev_warn(&dev->pci_dev->dev, | 1030 | dev_warn(&dev->pci_dev->dev, |
1023 | "I/O %d QID %d timeout, reset controller\n", | 1031 | "I/O %d QID %d timeout, reset controller\n", |
1024 | req->tag, nvmeq->qid); | 1032 | req->tag, nvmeq->qid); |
1025 | dev->reset_workfn = nvme_reset_failed_dev; | 1033 | dev->reset_workfn = nvme_reset_failed_dev; |
1026 | queue_work(nvme_workq, &dev->reset_work); | 1034 | queue_work(nvme_workq, &dev->reset_work); |
1035 | out: | ||
1036 | spin_unlock_irqrestore(&dev_list_lock, flags); | ||
1027 | return; | 1037 | return; |
1028 | } | 1038 | } |
1029 | 1039 | ||
@@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx, | |||
1064 | void *ctx; | 1074 | void *ctx; |
1065 | nvme_completion_fn fn; | 1075 | nvme_completion_fn fn; |
1066 | struct nvme_cmd_info *cmd; | 1076 | struct nvme_cmd_info *cmd; |
1067 | static struct nvme_completion cqe = { | 1077 | struct nvme_completion cqe; |
1068 | .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), | 1078 | |
1069 | }; | 1079 | if (!blk_mq_request_started(req)) |
1080 | return; | ||
1070 | 1081 | ||
1071 | cmd = blk_mq_rq_to_pdu(req); | 1082 | cmd = blk_mq_rq_to_pdu(req); |
1072 | 1083 | ||
1073 | if (cmd->ctx == CMD_CTX_CANCELLED) | 1084 | if (cmd->ctx == CMD_CTX_CANCELLED) |
1074 | return; | 1085 | return; |
1075 | 1086 | ||
1087 | if (blk_queue_dying(req->q)) | ||
1088 | cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); | ||
1089 | else | ||
1090 | cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); | ||
1091 | |||
1092 | |||
1076 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", | 1093 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", |
1077 | req->tag, nvmeq->qid); | 1094 | req->tag, nvmeq->qid); |
1078 | ctx = cancel_cmd_info(cmd, &fn); | 1095 | ctx = cancel_cmd_info(cmd, &fn); |
@@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
1084 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); | 1101 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); |
1085 | struct nvme_queue *nvmeq = cmd->nvmeq; | 1102 | struct nvme_queue *nvmeq = cmd->nvmeq; |
1086 | 1103 | ||
1087 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
1088 | nvmeq->qid); | ||
1089 | if (nvmeq->dev->initialized) | ||
1090 | nvme_abort_req(req); | ||
1091 | |||
1092 | /* | 1104 | /* |
1093 | * The aborted req will be completed on receiving the abort req. | 1105 | * The aborted req will be completed on receiving the abort req. |
1094 | * We enable the timer again. If hit twice, it'll cause a device reset, | 1106 | * We enable the timer again. If hit twice, it'll cause a device reset, |
1095 | * as the device then is in a faulty state. | 1107 | * as the device then is in a faulty state. |
1096 | */ | 1108 | */ |
1097 | return BLK_EH_RESET_TIMER; | 1109 | int ret = BLK_EH_RESET_TIMER; |
1110 | |||
1111 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
1112 | nvmeq->qid); | ||
1113 | |||
1114 | spin_lock_irq(&nvmeq->q_lock); | ||
1115 | if (!nvmeq->dev->initialized) { | ||
1116 | /* | ||
1117 | * Force cancelled command frees the request, which requires we | ||
1118 | * return BLK_EH_NOT_HANDLED. | ||
1119 | */ | ||
1120 | nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved); | ||
1121 | ret = BLK_EH_NOT_HANDLED; | ||
1122 | } else | ||
1123 | nvme_abort_req(req); | ||
1124 | spin_unlock_irq(&nvmeq->q_lock); | ||
1125 | |||
1126 | return ret; | ||
1098 | } | 1127 | } |
1099 | 1128 | ||
1100 | static void nvme_free_queue(struct nvme_queue *nvmeq) | 1129 | static void nvme_free_queue(struct nvme_queue *nvmeq) |
@@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) | |||
1131 | */ | 1160 | */ |
1132 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) | 1161 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) |
1133 | { | 1162 | { |
1134 | int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | 1163 | int vector; |
1135 | 1164 | ||
1136 | spin_lock_irq(&nvmeq->q_lock); | 1165 | spin_lock_irq(&nvmeq->q_lock); |
1166 | if (nvmeq->cq_vector == -1) { | ||
1167 | spin_unlock_irq(&nvmeq->q_lock); | ||
1168 | return 1; | ||
1169 | } | ||
1170 | vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | ||
1137 | nvmeq->dev->online_queues--; | 1171 | nvmeq->dev->online_queues--; |
1172 | nvmeq->cq_vector = -1; | ||
1138 | spin_unlock_irq(&nvmeq->q_lock); | 1173 | spin_unlock_irq(&nvmeq->q_lock); |
1139 | 1174 | ||
1140 | irq_set_affinity_hint(vector, NULL); | 1175 | irq_set_affinity_hint(vector, NULL); |
@@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) | |||
1169 | adapter_delete_sq(dev, qid); | 1204 | adapter_delete_sq(dev, qid); |
1170 | adapter_delete_cq(dev, qid); | 1205 | adapter_delete_cq(dev, qid); |
1171 | } | 1206 | } |
1207 | if (!qid && dev->admin_q) | ||
1208 | blk_mq_freeze_queue_start(dev->admin_q); | ||
1172 | nvme_clear_queue(nvmeq); | 1209 | nvme_clear_queue(nvmeq); |
1173 | } | 1210 | } |
1174 | 1211 | ||
1175 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 1212 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
1176 | int depth, int vector) | 1213 | int depth) |
1177 | { | 1214 | { |
1178 | struct device *dmadev = &dev->pci_dev->dev; | 1215 | struct device *dmadev = &dev->pci_dev->dev; |
1179 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); | 1216 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); |
@@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | |||
1199 | nvmeq->cq_phase = 1; | 1236 | nvmeq->cq_phase = 1; |
1200 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; | 1237 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
1201 | nvmeq->q_depth = depth; | 1238 | nvmeq->q_depth = depth; |
1202 | nvmeq->cq_vector = vector; | ||
1203 | nvmeq->qid = qid; | 1239 | nvmeq->qid = qid; |
1204 | dev->queue_count++; | 1240 | dev->queue_count++; |
1205 | dev->queues[qid] = nvmeq; | 1241 | dev->queues[qid] = nvmeq; |
@@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
1244 | struct nvme_dev *dev = nvmeq->dev; | 1280 | struct nvme_dev *dev = nvmeq->dev; |
1245 | int result; | 1281 | int result; |
1246 | 1282 | ||
1283 | nvmeq->cq_vector = qid - 1; | ||
1247 | result = adapter_alloc_cq(dev, qid, nvmeq); | 1284 | result = adapter_alloc_cq(dev, qid, nvmeq); |
1248 | if (result < 0) | 1285 | if (result < 0) |
1249 | return result; | 1286 | return result; |
@@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = { | |||
1355 | .timeout = nvme_timeout, | 1392 | .timeout = nvme_timeout, |
1356 | }; | 1393 | }; |
1357 | 1394 | ||
1395 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
1396 | { | ||
1397 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) { | ||
1398 | blk_cleanup_queue(dev->admin_q); | ||
1399 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1358 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) | 1403 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) |
1359 | { | 1404 | { |
1360 | if (!dev->admin_q) { | 1405 | if (!dev->admin_q) { |
@@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) | |||
1370 | return -ENOMEM; | 1415 | return -ENOMEM; |
1371 | 1416 | ||
1372 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); | 1417 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); |
1373 | if (!dev->admin_q) { | 1418 | if (IS_ERR(dev->admin_q)) { |
1374 | blk_mq_free_tag_set(&dev->admin_tagset); | 1419 | blk_mq_free_tag_set(&dev->admin_tagset); |
1375 | return -ENOMEM; | 1420 | return -ENOMEM; |
1376 | } | 1421 | } |
1377 | } | 1422 | if (!blk_get_queue(dev->admin_q)) { |
1423 | nvme_dev_remove_admin(dev); | ||
1424 | return -ENODEV; | ||
1425 | } | ||
1426 | } else | ||
1427 | blk_mq_unfreeze_queue(dev->admin_q); | ||
1378 | 1428 | ||
1379 | return 0; | 1429 | return 0; |
1380 | } | 1430 | } |
1381 | 1431 | ||
1382 | static void nvme_free_admin_tags(struct nvme_dev *dev) | ||
1383 | { | ||
1384 | if (dev->admin_q) | ||
1385 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
1386 | } | ||
1387 | |||
1388 | static int nvme_configure_admin_queue(struct nvme_dev *dev) | 1432 | static int nvme_configure_admin_queue(struct nvme_dev *dev) |
1389 | { | 1433 | { |
1390 | int result; | 1434 | int result; |
@@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
1416 | 1460 | ||
1417 | nvmeq = dev->queues[0]; | 1461 | nvmeq = dev->queues[0]; |
1418 | if (!nvmeq) { | 1462 | if (!nvmeq) { |
1419 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); | 1463 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH); |
1420 | if (!nvmeq) | 1464 | if (!nvmeq) |
1421 | return -ENOMEM; | 1465 | return -ENOMEM; |
1422 | } | 1466 | } |
@@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
1439 | if (result) | 1483 | if (result) |
1440 | goto free_nvmeq; | 1484 | goto free_nvmeq; |
1441 | 1485 | ||
1442 | result = nvme_alloc_admin_tags(dev); | 1486 | nvmeq->cq_vector = 0; |
1443 | if (result) | ||
1444 | goto free_nvmeq; | ||
1445 | |||
1446 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); | 1487 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
1447 | if (result) | 1488 | if (result) |
1448 | goto free_tags; | 1489 | goto free_nvmeq; |
1449 | 1490 | ||
1450 | return result; | 1491 | return result; |
1451 | 1492 | ||
1452 | free_tags: | ||
1453 | nvme_free_admin_tags(dev); | ||
1454 | free_nvmeq: | 1493 | free_nvmeq: |
1455 | nvme_free_queues(dev, 0); | 1494 | nvme_free_queues(dev, 0); |
1456 | return result; | 1495 | return result; |
@@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev) | |||
1944 | unsigned i; | 1983 | unsigned i; |
1945 | 1984 | ||
1946 | for (i = dev->queue_count; i <= dev->max_qid; i++) | 1985 | for (i = dev->queue_count; i <= dev->max_qid; i++) |
1947 | if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) | 1986 | if (!nvme_alloc_queue(dev, i, dev->q_depth)) |
1948 | break; | 1987 | break; |
1949 | 1988 | ||
1950 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) | 1989 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) |
@@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) | |||
2235 | break; | 2274 | break; |
2236 | if (!schedule_timeout(ADMIN_TIMEOUT) || | 2275 | if (!schedule_timeout(ADMIN_TIMEOUT) || |
2237 | fatal_signal_pending(current)) { | 2276 | fatal_signal_pending(current)) { |
2277 | /* | ||
2278 | * Disable the controller first since we can't trust it | ||
2279 | * at this point, but leave the admin queue enabled | ||
2280 | * until all queue deletion requests are flushed. | ||
2281 | * FIXME: This may take a while if there are more h/w | ||
2282 | * queues than admin tags. | ||
2283 | */ | ||
2238 | set_current_state(TASK_RUNNING); | 2284 | set_current_state(TASK_RUNNING); |
2239 | |||
2240 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); | 2285 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); |
2241 | nvme_disable_queue(dev, 0); | 2286 | nvme_clear_queue(dev->queues[0]); |
2242 | |||
2243 | send_sig(SIGKILL, dq->worker->task, 1); | ||
2244 | flush_kthread_worker(dq->worker); | 2287 | flush_kthread_worker(dq->worker); |
2288 | nvme_disable_queue(dev, 0); | ||
2245 | return; | 2289 | return; |
2246 | } | 2290 | } |
2247 | } | 2291 | } |
@@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work) | |||
2318 | { | 2362 | { |
2319 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | 2363 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, |
2320 | cmdinfo.work); | 2364 | cmdinfo.work); |
2321 | allow_signal(SIGKILL); | ||
2322 | if (nvme_delete_sq(nvmeq)) | 2365 | if (nvme_delete_sq(nvmeq)) |
2323 | nvme_del_queue_end(nvmeq); | 2366 | nvme_del_queue_end(nvmeq); |
2324 | } | 2367 | } |
@@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev) | |||
2376 | kthread_stop(tmp); | 2419 | kthread_stop(tmp); |
2377 | } | 2420 | } |
2378 | 2421 | ||
2422 | static void nvme_freeze_queues(struct nvme_dev *dev) | ||
2423 | { | ||
2424 | struct nvme_ns *ns; | ||
2425 | |||
2426 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
2427 | blk_mq_freeze_queue_start(ns->queue); | ||
2428 | |||
2429 | spin_lock(ns->queue->queue_lock); | ||
2430 | queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue); | ||
2431 | spin_unlock(ns->queue->queue_lock); | ||
2432 | |||
2433 | blk_mq_cancel_requeue_work(ns->queue); | ||
2434 | blk_mq_stop_hw_queues(ns->queue); | ||
2435 | } | ||
2436 | } | ||
2437 | |||
2438 | static void nvme_unfreeze_queues(struct nvme_dev *dev) | ||
2439 | { | ||
2440 | struct nvme_ns *ns; | ||
2441 | |||
2442 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
2443 | queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue); | ||
2444 | blk_mq_unfreeze_queue(ns->queue); | ||
2445 | blk_mq_start_stopped_hw_queues(ns->queue, true); | ||
2446 | blk_mq_kick_requeue_list(ns->queue); | ||
2447 | } | ||
2448 | } | ||
2449 | |||
2379 | static void nvme_dev_shutdown(struct nvme_dev *dev) | 2450 | static void nvme_dev_shutdown(struct nvme_dev *dev) |
2380 | { | 2451 | { |
2381 | int i; | 2452 | int i; |
@@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
2384 | dev->initialized = 0; | 2455 | dev->initialized = 0; |
2385 | nvme_dev_list_remove(dev); | 2456 | nvme_dev_list_remove(dev); |
2386 | 2457 | ||
2387 | if (dev->bar) | 2458 | if (dev->bar) { |
2459 | nvme_freeze_queues(dev); | ||
2388 | csts = readl(&dev->bar->csts); | 2460 | csts = readl(&dev->bar->csts); |
2461 | } | ||
2389 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { | 2462 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { |
2390 | for (i = dev->queue_count - 1; i >= 0; i--) { | 2463 | for (i = dev->queue_count - 1; i >= 0; i--) { |
2391 | struct nvme_queue *nvmeq = dev->queues[i]; | 2464 | struct nvme_queue *nvmeq = dev->queues[i]; |
@@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
2400 | nvme_dev_unmap(dev); | 2473 | nvme_dev_unmap(dev); |
2401 | } | 2474 | } |
2402 | 2475 | ||
2403 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
2404 | { | ||
2405 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) | ||
2406 | blk_cleanup_queue(dev->admin_q); | ||
2407 | } | ||
2408 | |||
2409 | static void nvme_dev_remove(struct nvme_dev *dev) | 2476 | static void nvme_dev_remove(struct nvme_dev *dev) |
2410 | { | 2477 | { |
2411 | struct nvme_ns *ns; | 2478 | struct nvme_ns *ns; |
@@ -2413,8 +2480,10 @@ static void nvme_dev_remove(struct nvme_dev *dev) | |||
2413 | list_for_each_entry(ns, &dev->namespaces, list) { | 2480 | list_for_each_entry(ns, &dev->namespaces, list) { |
2414 | if (ns->disk->flags & GENHD_FL_UP) | 2481 | if (ns->disk->flags & GENHD_FL_UP) |
2415 | del_gendisk(ns->disk); | 2482 | del_gendisk(ns->disk); |
2416 | if (!blk_queue_dying(ns->queue)) | 2483 | if (!blk_queue_dying(ns->queue)) { |
2484 | blk_mq_abort_requeue_list(ns->queue); | ||
2417 | blk_cleanup_queue(ns->queue); | 2485 | blk_cleanup_queue(ns->queue); |
2486 | } | ||
2418 | } | 2487 | } |
2419 | } | 2488 | } |
2420 | 2489 | ||
@@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref) | |||
2495 | nvme_free_namespaces(dev); | 2564 | nvme_free_namespaces(dev); |
2496 | nvme_release_instance(dev); | 2565 | nvme_release_instance(dev); |
2497 | blk_mq_free_tag_set(&dev->tagset); | 2566 | blk_mq_free_tag_set(&dev->tagset); |
2567 | blk_put_queue(dev->admin_q); | ||
2498 | kfree(dev->queues); | 2568 | kfree(dev->queues); |
2499 | kfree(dev->entry); | 2569 | kfree(dev->entry); |
2500 | kfree(dev); | 2570 | kfree(dev); |
@@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
2591 | } | 2661 | } |
2592 | 2662 | ||
2593 | nvme_init_queue(dev->queues[0], 0); | 2663 | nvme_init_queue(dev->queues[0], 0); |
2664 | result = nvme_alloc_admin_tags(dev); | ||
2665 | if (result) | ||
2666 | goto disable; | ||
2594 | 2667 | ||
2595 | result = nvme_setup_io_queues(dev); | 2668 | result = nvme_setup_io_queues(dev); |
2596 | if (result) | 2669 | if (result) |
2597 | goto disable; | 2670 | goto free_tags; |
2598 | 2671 | ||
2599 | nvme_set_irq_hints(dev); | 2672 | nvme_set_irq_hints(dev); |
2600 | 2673 | ||
2601 | return result; | 2674 | return result; |
2602 | 2675 | ||
2676 | free_tags: | ||
2677 | nvme_dev_remove_admin(dev); | ||
2603 | disable: | 2678 | disable: |
2604 | nvme_disable_queue(dev, 0); | 2679 | nvme_disable_queue(dev, 0); |
2605 | nvme_dev_list_remove(dev); | 2680 | nvme_dev_list_remove(dev); |
@@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev) | |||
2639 | dev->reset_workfn = nvme_remove_disks; | 2714 | dev->reset_workfn = nvme_remove_disks; |
2640 | queue_work(nvme_workq, &dev->reset_work); | 2715 | queue_work(nvme_workq, &dev->reset_work); |
2641 | spin_unlock(&dev_list_lock); | 2716 | spin_unlock(&dev_list_lock); |
2717 | } else { | ||
2718 | nvme_unfreeze_queues(dev); | ||
2719 | nvme_set_irq_hints(dev); | ||
2642 | } | 2720 | } |
2643 | dev->initialized = 1; | 2721 | dev->initialized = 1; |
2644 | return 0; | 2722 | return 0; |
@@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev) | |||
2776 | pci_set_drvdata(pdev, NULL); | 2854 | pci_set_drvdata(pdev, NULL); |
2777 | flush_work(&dev->reset_work); | 2855 | flush_work(&dev->reset_work); |
2778 | misc_deregister(&dev->miscdev); | 2856 | misc_deregister(&dev->miscdev); |
2779 | nvme_dev_remove(dev); | ||
2780 | nvme_dev_shutdown(dev); | 2857 | nvme_dev_shutdown(dev); |
2858 | nvme_dev_remove(dev); | ||
2781 | nvme_dev_remove_admin(dev); | 2859 | nvme_dev_remove_admin(dev); |
2782 | nvme_free_queues(dev, 0); | 2860 | nvme_free_queues(dev, 0); |
2783 | nvme_free_admin_tags(dev); | ||
2784 | nvme_release_prp_pools(dev); | 2861 | nvme_release_prp_pools(dev); |
2785 | kref_put(&dev->kref, nvme_free_dev); | 2862 | kref_put(&dev->kref, nvme_free_dev); |
2786 | } | 2863 | } |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 3ec85dfce124..8a86b62466f7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -2098,32 +2098,26 @@ static void rbd_dev_parent_put(struct rbd_device *rbd_dev) | |||
2098 | * If an image has a non-zero parent overlap, get a reference to its | 2098 | * If an image has a non-zero parent overlap, get a reference to its |
2099 | * parent. | 2099 | * parent. |
2100 | * | 2100 | * |
2101 | * We must get the reference before checking for the overlap to | ||
2102 | * coordinate properly with zeroing the parent overlap in | ||
2103 | * rbd_dev_v2_parent_info() when an image gets flattened. We | ||
2104 | * drop it again if there is no overlap. | ||
2105 | * | ||
2106 | * Returns true if the rbd device has a parent with a non-zero | 2101 | * Returns true if the rbd device has a parent with a non-zero |
2107 | * overlap and a reference for it was successfully taken, or | 2102 | * overlap and a reference for it was successfully taken, or |
2108 | * false otherwise. | 2103 | * false otherwise. |
2109 | */ | 2104 | */ |
2110 | static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) | 2105 | static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) |
2111 | { | 2106 | { |
2112 | int counter; | 2107 | int counter = 0; |
2113 | 2108 | ||
2114 | if (!rbd_dev->parent_spec) | 2109 | if (!rbd_dev->parent_spec) |
2115 | return false; | 2110 | return false; |
2116 | 2111 | ||
2117 | counter = atomic_inc_return_safe(&rbd_dev->parent_ref); | 2112 | down_read(&rbd_dev->header_rwsem); |
2118 | if (counter > 0 && rbd_dev->parent_overlap) | 2113 | if (rbd_dev->parent_overlap) |
2119 | return true; | 2114 | counter = atomic_inc_return_safe(&rbd_dev->parent_ref); |
2120 | 2115 | up_read(&rbd_dev->header_rwsem); | |
2121 | /* Image was flattened, but parent is not yet torn down */ | ||
2122 | 2116 | ||
2123 | if (counter < 0) | 2117 | if (counter < 0) |
2124 | rbd_warn(rbd_dev, "parent reference overflow"); | 2118 | rbd_warn(rbd_dev, "parent reference overflow"); |
2125 | 2119 | ||
2126 | return false; | 2120 | return counter > 0; |
2127 | } | 2121 | } |
2128 | 2122 | ||
2129 | /* | 2123 | /* |
@@ -4239,7 +4233,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | |||
4239 | */ | 4233 | */ |
4240 | if (rbd_dev->parent_overlap) { | 4234 | if (rbd_dev->parent_overlap) { |
4241 | rbd_dev->parent_overlap = 0; | 4235 | rbd_dev->parent_overlap = 0; |
4242 | smp_mb(); | ||
4243 | rbd_dev_parent_put(rbd_dev); | 4236 | rbd_dev_parent_put(rbd_dev); |
4244 | pr_info("%s: clone image has been flattened\n", | 4237 | pr_info("%s: clone image has been flattened\n", |
4245 | rbd_dev->disk->disk_name); | 4238 | rbd_dev->disk->disk_name); |
@@ -4285,7 +4278,6 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) | |||
4285 | * treat it specially. | 4278 | * treat it specially. |
4286 | */ | 4279 | */ |
4287 | rbd_dev->parent_overlap = overlap; | 4280 | rbd_dev->parent_overlap = overlap; |
4288 | smp_mb(); | ||
4289 | if (!overlap) { | 4281 | if (!overlap) { |
4290 | 4282 | ||
4291 | /* A null parent_spec indicates it's the initial probe */ | 4283 | /* A null parent_spec indicates it's the initial probe */ |
@@ -5114,10 +5106,7 @@ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) | |||
5114 | { | 5106 | { |
5115 | struct rbd_image_header *header; | 5107 | struct rbd_image_header *header; |
5116 | 5108 | ||
5117 | /* Drop parent reference unless it's already been done (or none) */ | 5109 | rbd_dev_parent_put(rbd_dev); |
5118 | |||
5119 | if (rbd_dev->parent_overlap) | ||
5120 | rbd_dev_parent_put(rbd_dev); | ||
5121 | 5110 | ||
5122 | /* Free dynamic fields from the header, then zero it out */ | 5111 | /* Free dynamic fields from the header, then zero it out */ |
5123 | 5112 | ||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ef7c098708f..cdfbd21e3597 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
638 | goto out_put_disk; | 638 | goto out_put_disk; |
639 | 639 | ||
640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); | 640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); |
641 | if (!q) { | 641 | if (IS_ERR(q)) { |
642 | err = -ENOMEM; | 642 | err = -ENOMEM; |
643 | goto out_free_tags; | 643 | goto out_free_tags; |
644 | } | 644 | } |
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 860da40b78ef..0ce5e2d65a06 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c | |||
@@ -1312,6 +1312,9 @@ static int cci_probe(void) | |||
1312 | if (!np) | 1312 | if (!np) |
1313 | return -ENODEV; | 1313 | return -ENODEV; |
1314 | 1314 | ||
1315 | if (!of_device_is_available(np)) | ||
1316 | return -ENODEV; | ||
1317 | |||
1315 | cci_config = of_match_node(arm_cci_matches, np)->data; | 1318 | cci_config = of_match_node(arm_cci_matches, np)->data; |
1316 | if (!cci_config) | 1319 | if (!cci_config) |
1317 | return -ENODEV; | 1320 | return -ENODEV; |
diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index eb7682dc123b..81bf297f1034 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c | |||
@@ -210,12 +210,25 @@ static void mvebu_mbus_disable_window(struct mvebu_mbus_state *mbus, | |||
210 | } | 210 | } |
211 | 211 | ||
212 | /* Checks whether the given window number is available */ | 212 | /* Checks whether the given window number is available */ |
213 | |||
214 | /* On Armada XP, 375 and 38x the MBus window 13 has the remap | ||
215 | * capability, like windows 0 to 7. However, the mvebu-mbus driver | ||
216 | * isn't currently taking into account this special case, which means | ||
217 | * that when window 13 is actually used, the remap registers are left | ||
218 | * to 0, making the device using this MBus window unavailable. The | ||
219 | * quick fix for stable is to not use window 13. A follow up patch | ||
220 | * will correctly handle this window. | ||
221 | */ | ||
213 | static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, | 222 | static int mvebu_mbus_window_is_free(struct mvebu_mbus_state *mbus, |
214 | const int win) | 223 | const int win) |
215 | { | 224 | { |
216 | void __iomem *addr = mbus->mbuswins_base + | 225 | void __iomem *addr = mbus->mbuswins_base + |
217 | mbus->soc->win_cfg_offset(win); | 226 | mbus->soc->win_cfg_offset(win); |
218 | u32 ctrl = readl(addr + WIN_CTRL_OFF); | 227 | u32 ctrl = readl(addr + WIN_CTRL_OFF); |
228 | |||
229 | if (win == 13) | ||
230 | return false; | ||
231 | |||
219 | return !(ctrl & WIN_CTRL_ENABLE); | 232 | return !(ctrl & WIN_CTRL_ENABLE); |
220 | } | 233 | } |
221 | 234 | ||
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 19db03667650..dcbbb4ea3cc1 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void) | |||
417 | module_init(agp_ali_init); | 417 | module_init(agp_ali_init); |
418 | module_exit(agp_ali_cleanup); | 418 | module_exit(agp_ali_cleanup); |
419 | 419 | ||
420 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 420 | MODULE_AUTHOR("Dave Jones"); |
421 | MODULE_LICENSE("GPL and additional rights"); | 421 | MODULE_LICENSE("GPL and additional rights"); |
422 | 422 | ||
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 3b47ed0310e1..0ef350010766 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -813,6 +813,6 @@ static void __exit agp_amd64_cleanup(void) | |||
813 | module_init(agp_amd64_mod_init); | 813 | module_init(agp_amd64_mod_init); |
814 | module_exit(agp_amd64_cleanup); | 814 | module_exit(agp_amd64_cleanup); |
815 | 815 | ||
816 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); | 816 | MODULE_AUTHOR("Dave Jones, Andi Kleen"); |
817 | module_param(agp_try_unsupported, bool, 0); | 817 | module_param(agp_try_unsupported, bool, 0); |
818 | MODULE_LICENSE("GPL"); | 818 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 18a7a6baa304..75a9786a77e6 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -579,6 +579,6 @@ static void __exit agp_ati_cleanup(void) | |||
579 | module_init(agp_ati_init); | 579 | module_init(agp_ati_init); |
580 | module_exit(agp_ati_cleanup); | 580 | module_exit(agp_ati_cleanup); |
581 | 581 | ||
582 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 582 | MODULE_AUTHOR("Dave Jones"); |
583 | MODULE_LICENSE("GPL and additional rights"); | 583 | MODULE_LICENSE("GPL and additional rights"); |
584 | 584 | ||
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 317c28ce8328..38ffb281df97 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -356,7 +356,7 @@ static __init int agp_setup(char *s) | |||
356 | __setup("agp=", agp_setup); | 356 | __setup("agp=", agp_setup); |
357 | #endif | 357 | #endif |
358 | 358 | ||
359 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 359 | MODULE_AUTHOR("Dave Jones, Jeff Hartmann"); |
360 | MODULE_DESCRIPTION("AGP GART driver"); | 360 | MODULE_DESCRIPTION("AGP GART driver"); |
361 | MODULE_LICENSE("GPL and additional rights"); | 361 | MODULE_LICENSE("GPL and additional rights"); |
362 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); | 362 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index f9b9ca5d31b7..0a21daed5b62 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -920,5 +920,5 @@ static void __exit agp_intel_cleanup(void) | |||
920 | module_init(agp_intel_init); | 920 | module_init(agp_intel_init); |
921 | module_exit(agp_intel_cleanup); | 921 | module_exit(agp_intel_cleanup); |
922 | 922 | ||
923 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 923 | MODULE_AUTHOR("Dave Jones, Various @Intel"); |
924 | MODULE_LICENSE("GPL and additional rights"); | 924 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index f3334829e55a..92aa43fa8d70 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -1438,5 +1438,5 @@ void intel_gmch_remove(void) | |||
1438 | } | 1438 | } |
1439 | EXPORT_SYMBOL(intel_gmch_remove); | 1439 | EXPORT_SYMBOL(intel_gmch_remove); |
1440 | 1440 | ||
1441 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 1441 | MODULE_AUTHOR("Dave Jones, Various @Intel"); |
1442 | MODULE_LICENSE("GPL and additional rights"); | 1442 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index a1861b75eb31..6c8d39cb566e 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Nvidia AGPGART routines. | 2 | * Nvidia AGPGART routines. |
3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up | 3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up |
4 | * to work in 2.5 by Dave Jones <davej@redhat.com> | 4 | * to work in 2.5 by Dave Jones. |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 228f20cddc05..a4961d35e940 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -595,4 +595,4 @@ module_init(agp_via_init); | |||
595 | module_exit(agp_via_cleanup); | 595 | module_exit(agp_via_cleanup); |
596 | 596 | ||
597 | MODULE_LICENSE("GPL"); | 597 | MODULE_LICENSE("GPL"); |
598 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | 598 | MODULE_AUTHOR("Dave Jones"); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 5fa83f751378..6b65fa4e0c55 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -199,18 +199,6 @@ struct bmc_device { | |||
199 | int guid_set; | 199 | int guid_set; |
200 | char name[16]; | 200 | char name[16]; |
201 | struct kref usecount; | 201 | struct kref usecount; |
202 | |||
203 | /* bmc device attributes */ | ||
204 | struct device_attribute device_id_attr; | ||
205 | struct device_attribute provides_dev_sdrs_attr; | ||
206 | struct device_attribute revision_attr; | ||
207 | struct device_attribute firmware_rev_attr; | ||
208 | struct device_attribute version_attr; | ||
209 | struct device_attribute add_dev_support_attr; | ||
210 | struct device_attribute manufacturer_id_attr; | ||
211 | struct device_attribute product_id_attr; | ||
212 | struct device_attribute guid_attr; | ||
213 | struct device_attribute aux_firmware_rev_attr; | ||
214 | }; | 202 | }; |
215 | #define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) | 203 | #define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev) |
216 | 204 | ||
@@ -2252,7 +2240,7 @@ static ssize_t device_id_show(struct device *dev, | |||
2252 | 2240 | ||
2253 | return snprintf(buf, 10, "%u\n", bmc->id.device_id); | 2241 | return snprintf(buf, 10, "%u\n", bmc->id.device_id); |
2254 | } | 2242 | } |
2255 | DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL); | 2243 | static DEVICE_ATTR(device_id, S_IRUGO, device_id_show, NULL); |
2256 | 2244 | ||
2257 | static ssize_t provides_device_sdrs_show(struct device *dev, | 2245 | static ssize_t provides_device_sdrs_show(struct device *dev, |
2258 | struct device_attribute *attr, | 2246 | struct device_attribute *attr, |
@@ -2263,7 +2251,8 @@ static ssize_t provides_device_sdrs_show(struct device *dev, | |||
2263 | return snprintf(buf, 10, "%u\n", | 2251 | return snprintf(buf, 10, "%u\n", |
2264 | (bmc->id.device_revision & 0x80) >> 7); | 2252 | (bmc->id.device_revision & 0x80) >> 7); |
2265 | } | 2253 | } |
2266 | DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, NULL); | 2254 | static DEVICE_ATTR(provides_device_sdrs, S_IRUGO, provides_device_sdrs_show, |
2255 | NULL); | ||
2267 | 2256 | ||
2268 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | 2257 | static ssize_t revision_show(struct device *dev, struct device_attribute *attr, |
2269 | char *buf) | 2258 | char *buf) |
@@ -2273,7 +2262,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr, | |||
2273 | return snprintf(buf, 20, "%u\n", | 2262 | return snprintf(buf, 20, "%u\n", |
2274 | bmc->id.device_revision & 0x0F); | 2263 | bmc->id.device_revision & 0x0F); |
2275 | } | 2264 | } |
2276 | DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL); | 2265 | static DEVICE_ATTR(revision, S_IRUGO, revision_show, NULL); |
2277 | 2266 | ||
2278 | static ssize_t firmware_revision_show(struct device *dev, | 2267 | static ssize_t firmware_revision_show(struct device *dev, |
2279 | struct device_attribute *attr, | 2268 | struct device_attribute *attr, |
@@ -2284,7 +2273,7 @@ static ssize_t firmware_revision_show(struct device *dev, | |||
2284 | return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1, | 2273 | return snprintf(buf, 20, "%u.%x\n", bmc->id.firmware_revision_1, |
2285 | bmc->id.firmware_revision_2); | 2274 | bmc->id.firmware_revision_2); |
2286 | } | 2275 | } |
2287 | DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL); | 2276 | static DEVICE_ATTR(firmware_revision, S_IRUGO, firmware_revision_show, NULL); |
2288 | 2277 | ||
2289 | static ssize_t ipmi_version_show(struct device *dev, | 2278 | static ssize_t ipmi_version_show(struct device *dev, |
2290 | struct device_attribute *attr, | 2279 | struct device_attribute *attr, |
@@ -2296,7 +2285,7 @@ static ssize_t ipmi_version_show(struct device *dev, | |||
2296 | ipmi_version_major(&bmc->id), | 2285 | ipmi_version_major(&bmc->id), |
2297 | ipmi_version_minor(&bmc->id)); | 2286 | ipmi_version_minor(&bmc->id)); |
2298 | } | 2287 | } |
2299 | DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL); | 2288 | static DEVICE_ATTR(ipmi_version, S_IRUGO, ipmi_version_show, NULL); |
2300 | 2289 | ||
2301 | static ssize_t add_dev_support_show(struct device *dev, | 2290 | static ssize_t add_dev_support_show(struct device *dev, |
2302 | struct device_attribute *attr, | 2291 | struct device_attribute *attr, |
@@ -2307,7 +2296,8 @@ static ssize_t add_dev_support_show(struct device *dev, | |||
2307 | return snprintf(buf, 10, "0x%02x\n", | 2296 | return snprintf(buf, 10, "0x%02x\n", |
2308 | bmc->id.additional_device_support); | 2297 | bmc->id.additional_device_support); |
2309 | } | 2298 | } |
2310 | DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, NULL); | 2299 | static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show, |
2300 | NULL); | ||
2311 | 2301 | ||
2312 | static ssize_t manufacturer_id_show(struct device *dev, | 2302 | static ssize_t manufacturer_id_show(struct device *dev, |
2313 | struct device_attribute *attr, | 2303 | struct device_attribute *attr, |
@@ -2317,7 +2307,7 @@ static ssize_t manufacturer_id_show(struct device *dev, | |||
2317 | 2307 | ||
2318 | return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id); | 2308 | return snprintf(buf, 20, "0x%6.6x\n", bmc->id.manufacturer_id); |
2319 | } | 2309 | } |
2320 | DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL); | 2310 | static DEVICE_ATTR(manufacturer_id, S_IRUGO, manufacturer_id_show, NULL); |
2321 | 2311 | ||
2322 | static ssize_t product_id_show(struct device *dev, | 2312 | static ssize_t product_id_show(struct device *dev, |
2323 | struct device_attribute *attr, | 2313 | struct device_attribute *attr, |
@@ -2327,7 +2317,7 @@ static ssize_t product_id_show(struct device *dev, | |||
2327 | 2317 | ||
2328 | return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id); | 2318 | return snprintf(buf, 10, "0x%4.4x\n", bmc->id.product_id); |
2329 | } | 2319 | } |
2330 | DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL); | 2320 | static DEVICE_ATTR(product_id, S_IRUGO, product_id_show, NULL); |
2331 | 2321 | ||
2332 | static ssize_t aux_firmware_rev_show(struct device *dev, | 2322 | static ssize_t aux_firmware_rev_show(struct device *dev, |
2333 | struct device_attribute *attr, | 2323 | struct device_attribute *attr, |
@@ -2341,7 +2331,7 @@ static ssize_t aux_firmware_rev_show(struct device *dev, | |||
2341 | bmc->id.aux_firmware_revision[1], | 2331 | bmc->id.aux_firmware_revision[1], |
2342 | bmc->id.aux_firmware_revision[0]); | 2332 | bmc->id.aux_firmware_revision[0]); |
2343 | } | 2333 | } |
2344 | DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL); | 2334 | static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL); |
2345 | 2335 | ||
2346 | static ssize_t guid_show(struct device *dev, struct device_attribute *attr, | 2336 | static ssize_t guid_show(struct device *dev, struct device_attribute *attr, |
2347 | char *buf) | 2337 | char *buf) |
@@ -2352,7 +2342,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, | |||
2352 | (long long) bmc->guid[0], | 2342 | (long long) bmc->guid[0], |
2353 | (long long) bmc->guid[8]); | 2343 | (long long) bmc->guid[8]); |
2354 | } | 2344 | } |
2355 | DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL); | 2345 | static DEVICE_ATTR(guid, S_IRUGO, guid_show, NULL); |
2356 | 2346 | ||
2357 | static struct attribute *bmc_dev_attrs[] = { | 2347 | static struct attribute *bmc_dev_attrs[] = { |
2358 | &dev_attr_device_id.attr, | 2348 | &dev_attr_device_id.attr, |
@@ -2392,10 +2382,10 @@ cleanup_bmc_device(struct kref *ref) | |||
2392 | 2382 | ||
2393 | if (bmc->id.aux_firmware_revision_set) | 2383 | if (bmc->id.aux_firmware_revision_set) |
2394 | device_remove_file(&bmc->pdev.dev, | 2384 | device_remove_file(&bmc->pdev.dev, |
2395 | &bmc->aux_firmware_rev_attr); | 2385 | &dev_attr_aux_firmware_revision); |
2396 | if (bmc->guid_set) | 2386 | if (bmc->guid_set) |
2397 | device_remove_file(&bmc->pdev.dev, | 2387 | device_remove_file(&bmc->pdev.dev, |
2398 | &bmc->guid_attr); | 2388 | &dev_attr_guid); |
2399 | 2389 | ||
2400 | platform_device_unregister(&bmc->pdev); | 2390 | platform_device_unregister(&bmc->pdev); |
2401 | } | 2391 | } |
@@ -2422,16 +2412,14 @@ static int create_bmc_files(struct bmc_device *bmc) | |||
2422 | int err; | 2412 | int err; |
2423 | 2413 | ||
2424 | if (bmc->id.aux_firmware_revision_set) { | 2414 | if (bmc->id.aux_firmware_revision_set) { |
2425 | bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; | ||
2426 | err = device_create_file(&bmc->pdev.dev, | 2415 | err = device_create_file(&bmc->pdev.dev, |
2427 | &bmc->aux_firmware_rev_attr); | 2416 | &dev_attr_aux_firmware_revision); |
2428 | if (err) | 2417 | if (err) |
2429 | goto out; | 2418 | goto out; |
2430 | } | 2419 | } |
2431 | if (bmc->guid_set) { | 2420 | if (bmc->guid_set) { |
2432 | bmc->guid_attr.attr.name = "guid"; | ||
2433 | err = device_create_file(&bmc->pdev.dev, | 2421 | err = device_create_file(&bmc->pdev.dev, |
2434 | &bmc->guid_attr); | 2422 | &dev_attr_guid); |
2435 | if (err) | 2423 | if (err) |
2436 | goto out_aux_firm; | 2424 | goto out_aux_firm; |
2437 | } | 2425 | } |
@@ -2441,7 +2429,7 @@ static int create_bmc_files(struct bmc_device *bmc) | |||
2441 | out_aux_firm: | 2429 | out_aux_firm: |
2442 | if (bmc->id.aux_firmware_revision_set) | 2430 | if (bmc->id.aux_firmware_revision_set) |
2443 | device_remove_file(&bmc->pdev.dev, | 2431 | device_remove_file(&bmc->pdev.dev, |
2444 | &bmc->aux_firmware_rev_attr); | 2432 | &dev_attr_aux_firmware_revision); |
2445 | out: | 2433 | out: |
2446 | return err; | 2434 | return err; |
2447 | } | 2435 | } |
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index e178ac27e73c..982b96323f82 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/dmi.h> | 52 | #include <linux/dmi.h> |
53 | #include <linux/kthread.h> | 53 | #include <linux/kthread.h> |
54 | #include <linux/acpi.h> | 54 | #include <linux/acpi.h> |
55 | #include <linux/ctype.h> | ||
55 | 56 | ||
56 | #define PFX "ipmi_ssif: " | 57 | #define PFX "ipmi_ssif: " |
57 | #define DEVICE_NAME "ipmi_ssif" | 58 | #define DEVICE_NAME "ipmi_ssif" |
@@ -968,7 +969,8 @@ static void sender(void *send_info, | |||
968 | 969 | ||
969 | do_gettimeofday(&t); | 970 | do_gettimeofday(&t); |
970 | pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", | 971 | pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", |
971 | msg->data[0], msg->data[1], t.tv_sec, t.tv_usec); | 972 | msg->data[0], msg->data[1], |
973 | (long) t.tv_sec, (long) t.tv_usec); | ||
972 | } | 974 | } |
973 | } | 975 | } |
974 | 976 | ||
diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 32f7c1b36204..2f13bd5246b5 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c | |||
@@ -70,6 +70,7 @@ struct clk_sam9x5_slow { | |||
70 | 70 | ||
71 | #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) | 71 | #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) |
72 | 72 | ||
73 | static struct clk *slow_clk; | ||
73 | 74 | ||
74 | static int clk_slow_osc_prepare(struct clk_hw *hw) | 75 | static int clk_slow_osc_prepare(struct clk_hw *hw) |
75 | { | 76 | { |
@@ -357,6 +358,8 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, | |||
357 | clk = clk_register(NULL, &slowck->hw); | 358 | clk = clk_register(NULL, &slowck->hw); |
358 | if (IS_ERR(clk)) | 359 | if (IS_ERR(clk)) |
359 | kfree(slowck); | 360 | kfree(slowck); |
361 | else | ||
362 | slow_clk = clk; | ||
360 | 363 | ||
361 | return clk; | 364 | return clk; |
362 | } | 365 | } |
@@ -433,6 +436,8 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, | |||
433 | clk = clk_register(NULL, &slowck->hw); | 436 | clk = clk_register(NULL, &slowck->hw); |
434 | if (IS_ERR(clk)) | 437 | if (IS_ERR(clk)) |
435 | kfree(slowck); | 438 | kfree(slowck); |
439 | else | ||
440 | slow_clk = clk; | ||
436 | 441 | ||
437 | return clk; | 442 | return clk; |
438 | } | 443 | } |
@@ -465,3 +470,25 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np, | |||
465 | 470 | ||
466 | of_clk_add_provider(np, of_clk_src_simple_get, clk); | 471 | of_clk_add_provider(np, of_clk_src_simple_get, clk); |
467 | } | 472 | } |
473 | |||
474 | /* | ||
475 | * FIXME: All slow clk users are not properly claiming it (get + prepare + | ||
476 | * enable) before using it. | ||
477 | * If all users properly claiming this clock decide that they don't need it | ||
478 | * anymore (or are removed), it is disabled while faulty users are still | ||
479 | * requiring it, and the system hangs. | ||
480 | * Prevent this clock from being disabled until all users are properly | ||
481 | * requesting it. | ||
482 | * Once this is done we should remove this function and the slow_clk variable. | ||
483 | */ | ||
484 | static int __init of_at91_clk_slow_retain(void) | ||
485 | { | ||
486 | if (!slow_clk) | ||
487 | return 0; | ||
488 | |||
489 | __clk_get(slow_clk); | ||
490 | clk_prepare_enable(slow_clk); | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | arch_initcall(of_at91_clk_slow_retain); | ||
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index 21784e4eb3f0..440ef81ab15c 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c | |||
@@ -285,7 +285,6 @@ static const struct berlin2_gate_data bg2q_gates[] __initconst = { | |||
285 | { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, | 285 | { "pbridge", "perif", 15, CLK_IGNORE_UNUSED }, |
286 | { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, | 286 | { "sdio", "perif", 16, CLK_IGNORE_UNUSED }, |
287 | { "nfc", "perif", 18 }, | 287 | { "nfc", "perif", 18 }, |
288 | { "smemc", "perif", 19 }, | ||
289 | { "pcie", "perif", 22 }, | 288 | { "pcie", "perif", 22 }, |
290 | }; | 289 | }; |
291 | 290 | ||
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index b6e6c85507a5..0a47d6f49cd6 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c | |||
@@ -291,7 +291,7 @@ static const struct of_device_id ppc_clk_ids[] __initconst = { | |||
291 | {} | 291 | {} |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static struct platform_driver ppc_corenet_clk_driver __initdata = { | 294 | static struct platform_driver ppc_corenet_clk_driver = { |
295 | .driver = { | 295 | .driver = { |
296 | .name = "ppc_corenet_clock", | 296 | .name = "ppc_corenet_clock", |
297 | .of_match_table = ppc_clk_ids, | 297 | .of_match_table = ppc_clk_ids, |
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f4963b7d4e17..d48ac71c6c8b 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -1366,7 +1366,7 @@ static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate) | |||
1366 | new_rate = clk->ops->determine_rate(clk->hw, rate, | 1366 | new_rate = clk->ops->determine_rate(clk->hw, rate, |
1367 | &best_parent_rate, | 1367 | &best_parent_rate, |
1368 | &parent_hw); | 1368 | &parent_hw); |
1369 | parent = parent_hw->clk; | 1369 | parent = parent_hw ? parent_hw->clk : NULL; |
1370 | } else if (clk->ops->round_rate) { | 1370 | } else if (clk->ops->round_rate) { |
1371 | new_rate = clk->ops->round_rate(clk->hw, rate, | 1371 | new_rate = clk->ops->round_rate(clk->hw, rate, |
1372 | &best_parent_rate); | 1372 | &best_parent_rate); |
diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 75c8c45ef728..8539c4fd34cc 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c | |||
@@ -124,10 +124,11 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, | |||
124 | { | 124 | { |
125 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; | 125 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; |
126 | unsigned long alt_prate, alt_div; | 126 | unsigned long alt_prate, alt_div; |
127 | unsigned long flags; | ||
127 | 128 | ||
128 | alt_prate = clk_get_rate(cpuclk->alt_parent); | 129 | alt_prate = clk_get_rate(cpuclk->alt_parent); |
129 | 130 | ||
130 | spin_lock(cpuclk->lock); | 131 | spin_lock_irqsave(cpuclk->lock, flags); |
131 | 132 | ||
132 | /* | 133 | /* |
133 | * If the old parent clock speed is less than the clock speed | 134 | * If the old parent clock speed is less than the clock speed |
@@ -164,7 +165,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, | |||
164 | cpuclk->reg_base + reg_data->core_reg); | 165 | cpuclk->reg_base + reg_data->core_reg); |
165 | } | 166 | } |
166 | 167 | ||
167 | spin_unlock(cpuclk->lock); | 168 | spin_unlock_irqrestore(cpuclk->lock, flags); |
168 | return 0; | 169 | return 0; |
169 | } | 170 | } |
170 | 171 | ||
@@ -173,6 +174,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, | |||
173 | { | 174 | { |
174 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; | 175 | const struct rockchip_cpuclk_reg_data *reg_data = cpuclk->reg_data; |
175 | const struct rockchip_cpuclk_rate_table *rate; | 176 | const struct rockchip_cpuclk_rate_table *rate; |
177 | unsigned long flags; | ||
176 | 178 | ||
177 | rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); | 179 | rate = rockchip_get_cpuclk_settings(cpuclk, ndata->new_rate); |
178 | if (!rate) { | 180 | if (!rate) { |
@@ -181,7 +183,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, | |||
181 | return -EINVAL; | 183 | return -EINVAL; |
182 | } | 184 | } |
183 | 185 | ||
184 | spin_lock(cpuclk->lock); | 186 | spin_lock_irqsave(cpuclk->lock, flags); |
185 | 187 | ||
186 | if (ndata->old_rate < ndata->new_rate) | 188 | if (ndata->old_rate < ndata->new_rate) |
187 | rockchip_cpuclk_set_dividers(cpuclk, rate); | 189 | rockchip_cpuclk_set_dividers(cpuclk, rate); |
@@ -201,7 +203,7 @@ static int rockchip_cpuclk_post_rate_change(struct rockchip_cpuclk *cpuclk, | |||
201 | if (ndata->old_rate > ndata->new_rate) | 203 | if (ndata->old_rate > ndata->new_rate) |
202 | rockchip_cpuclk_set_dividers(cpuclk, rate); | 204 | rockchip_cpuclk_set_dividers(cpuclk, rate); |
203 | 205 | ||
204 | spin_unlock(cpuclk->lock); | 206 | spin_unlock_irqrestore(cpuclk->lock, flags); |
205 | return 0; | 207 | return 0; |
206 | } | 208 | } |
207 | 209 | ||
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index c54078960847..7eb684c50d42 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c | |||
@@ -210,6 +210,17 @@ PNAME(mux_sclk_hsadc_p) = { "hsadc_src", "hsadc_frac", "ext_hsadc" }; | |||
210 | PNAME(mux_mac_p) = { "gpll", "dpll" }; | 210 | PNAME(mux_mac_p) = { "gpll", "dpll" }; |
211 | PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; | 211 | PNAME(mux_sclk_macref_p) = { "mac_src", "ext_rmii" }; |
212 | 212 | ||
213 | static struct rockchip_pll_clock rk3066_pll_clks[] __initdata = { | ||
214 | [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), | ||
215 | RK2928_MODE_CON, 0, 5, 0, rk3188_pll_rates), | ||
216 | [dpll] = PLL(pll_rk3066, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4), | ||
217 | RK2928_MODE_CON, 4, 4, 0, NULL), | ||
218 | [cpll] = PLL(pll_rk3066, PLL_CPLL, "cpll", mux_pll_p, 0, RK2928_PLL_CON(8), | ||
219 | RK2928_MODE_CON, 8, 6, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), | ||
220 | [gpll] = PLL(pll_rk3066, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12), | ||
221 | RK2928_MODE_CON, 12, 7, ROCKCHIP_PLL_SYNC_RATE, rk3188_pll_rates), | ||
222 | }; | ||
223 | |||
213 | static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { | 224 | static struct rockchip_pll_clock rk3188_pll_clks[] __initdata = { |
214 | [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), | 225 | [apll] = PLL(pll_rk3066, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0), |
215 | RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), | 226 | RK2928_MODE_CON, 0, 6, 0, rk3188_pll_rates), |
@@ -427,11 +438,11 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { | |||
427 | /* hclk_peri gates */ | 438 | /* hclk_peri gates */ |
428 | GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), | 439 | GATE(0, "hclk_peri_axi_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), |
429 | GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), | 440 | GATE(0, "hclk_peri_ahb_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 6, GFLAGS), |
430 | GATE(0, "hclk_emem_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 7, GFLAGS), | 441 | GATE(0, "hclk_emem_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 7, GFLAGS), |
431 | GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), | 442 | GATE(HCLK_EMAC, "hclk_emac", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS), |
432 | GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), | 443 | GATE(HCLK_NANDC0, "hclk_nandc0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS), |
433 | GATE(0, "hclk_usb_peri", "hclk_peri", 0, RK2928_CLKGATE_CON(4), 5, GFLAGS), | 444 | GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 5, GFLAGS), |
434 | GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), | 445 | GATE(HCLK_OTG0, "hclk_usbotg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), |
435 | GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), | 446 | GATE(HCLK_HSADC, "hclk_hsadc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 5, GFLAGS), |
436 | GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), | 447 | GATE(HCLK_PIDF, "hclk_pidfilter", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 6, GFLAGS), |
437 | GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), | 448 | GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), |
@@ -592,7 +603,8 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { | |||
592 | GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), | 603 | GATE(0, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), |
593 | GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), | 604 | GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), |
594 | 605 | ||
595 | GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), | 606 | GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, |
607 | RK2928_CLKGATE_CON(5), 14, GFLAGS), | ||
596 | 608 | ||
597 | GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), | 609 | GATE(0, "aclk_cif1", "aclk_vio1", 0, RK2928_CLKGATE_CON(6), 7, GFLAGS), |
598 | 610 | ||
@@ -680,7 +692,8 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { | |||
680 | GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), | 692 | GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), |
681 | GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), | 693 | GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), |
682 | 694 | ||
683 | GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), | 695 | GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, |
696 | RK2928_CLKGATE_CON(7), 3, GFLAGS), | ||
684 | GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), | 697 | GATE(HCLK_HSIC, "hclk_hsic", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), |
685 | 698 | ||
686 | GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), | 699 | GATE(PCLK_TIMER3, "pclk_timer3", "pclk_cpu", 0, RK2928_CLKGATE_CON(7), 9, GFLAGS), |
@@ -735,8 +748,8 @@ static void __init rk3188_common_clk_init(struct device_node *np) | |||
735 | static void __init rk3066a_clk_init(struct device_node *np) | 748 | static void __init rk3066a_clk_init(struct device_node *np) |
736 | { | 749 | { |
737 | rk3188_common_clk_init(np); | 750 | rk3188_common_clk_init(np); |
738 | rockchip_clk_register_plls(rk3188_pll_clks, | 751 | rockchip_clk_register_plls(rk3066_pll_clks, |
739 | ARRAY_SIZE(rk3188_pll_clks), | 752 | ARRAY_SIZE(rk3066_pll_clks), |
740 | RK3066_GRF_SOC_STATUS); | 753 | RK3066_GRF_SOC_STATUS); |
741 | rockchip_clk_register_branches(rk3066a_clk_branches, | 754 | rockchip_clk_register_branches(rk3066a_clk_branches, |
742 | ARRAY_SIZE(rk3066a_clk_branches)); | 755 | ARRAY_SIZE(rk3066a_clk_branches)); |
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index ac6be7c0132d..11194b8329fe 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c | |||
@@ -145,20 +145,20 @@ struct rockchip_pll_rate_table rk3288_pll_rates[] = { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { | 147 | static struct rockchip_cpuclk_rate_table rk3288_cpuclk_rates[] __initdata = { |
148 | RK3288_CPUCLK_RATE(1800000000, 2, 4, 2, 4, 4), | 148 | RK3288_CPUCLK_RATE(1800000000, 1, 3, 1, 3, 3), |
149 | RK3288_CPUCLK_RATE(1704000000, 2, 4, 2, 4, 4), | 149 | RK3288_CPUCLK_RATE(1704000000, 1, 3, 1, 3, 3), |
150 | RK3288_CPUCLK_RATE(1608000000, 2, 4, 2, 4, 4), | 150 | RK3288_CPUCLK_RATE(1608000000, 1, 3, 1, 3, 3), |
151 | RK3288_CPUCLK_RATE(1512000000, 2, 4, 2, 4, 4), | 151 | RK3288_CPUCLK_RATE(1512000000, 1, 3, 1, 3, 3), |
152 | RK3288_CPUCLK_RATE(1416000000, 2, 4, 2, 4, 4), | 152 | RK3288_CPUCLK_RATE(1416000000, 1, 3, 1, 3, 3), |
153 | RK3288_CPUCLK_RATE(1200000000, 2, 4, 2, 4, 4), | 153 | RK3288_CPUCLK_RATE(1200000000, 1, 3, 1, 3, 3), |
154 | RK3288_CPUCLK_RATE(1008000000, 2, 4, 2, 4, 4), | 154 | RK3288_CPUCLK_RATE(1008000000, 1, 3, 1, 3, 3), |
155 | RK3288_CPUCLK_RATE( 816000000, 2, 4, 2, 4, 4), | 155 | RK3288_CPUCLK_RATE( 816000000, 1, 3, 1, 3, 3), |
156 | RK3288_CPUCLK_RATE( 696000000, 2, 4, 2, 4, 4), | 156 | RK3288_CPUCLK_RATE( 696000000, 1, 3, 1, 3, 3), |
157 | RK3288_CPUCLK_RATE( 600000000, 2, 4, 2, 4, 4), | 157 | RK3288_CPUCLK_RATE( 600000000, 1, 3, 1, 3, 3), |
158 | RK3288_CPUCLK_RATE( 408000000, 2, 4, 2, 4, 4), | 158 | RK3288_CPUCLK_RATE( 408000000, 1, 3, 1, 3, 3), |
159 | RK3288_CPUCLK_RATE( 312000000, 2, 4, 2, 4, 4), | 159 | RK3288_CPUCLK_RATE( 312000000, 1, 3, 1, 3, 3), |
160 | RK3288_CPUCLK_RATE( 216000000, 2, 4, 2, 4, 4), | 160 | RK3288_CPUCLK_RATE( 216000000, 1, 3, 1, 3, 3), |
161 | RK3288_CPUCLK_RATE( 126000000, 2, 4, 2, 4, 4), | 161 | RK3288_CPUCLK_RATE( 126000000, 1, 3, 1, 3, 3), |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { | 164 | static const struct rockchip_cpuclk_reg_data rk3288_cpuclk_data = { |
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 6a79fc4f900c..095c1774592c 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -462,7 +462,7 @@ static void __init arch_counter_register(unsigned type) | |||
462 | 462 | ||
463 | /* Register the CP15 based counter if we have one */ | 463 | /* Register the CP15 based counter if we have one */ |
464 | if (type & ARCH_CP15_TIMER) { | 464 | if (type & ARCH_CP15_TIMER) { |
465 | if (arch_timer_use_virtual) | 465 | if (IS_ENABLED(CONFIG_ARM64) || arch_timer_use_virtual) |
466 | arch_timer_read_counter = arch_counter_get_cntvct; | 466 | arch_timer_read_counter = arch_counter_get_cntvct; |
467 | else | 467 | else |
468 | arch_timer_read_counter = arch_counter_get_cntpct; | 468 | arch_timer_read_counter = arch_counter_get_cntpct; |
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index 0595dc6c453e..f1e33d08dd83 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c | |||
@@ -68,9 +68,8 @@ static void kona_timer_disable_and_clear(void __iomem *base) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | static void | 70 | static void |
71 | kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) | 71 | kona_timer_get_counter(void __iomem *timer_base, uint32_t *msw, uint32_t *lsw) |
72 | { | 72 | { |
73 | void __iomem *base = IOMEM(timer_base); | ||
74 | int loop_limit = 4; | 73 | int loop_limit = 4; |
75 | 74 | ||
76 | /* | 75 | /* |
@@ -86,9 +85,9 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) | |||
86 | */ | 85 | */ |
87 | 86 | ||
88 | while (--loop_limit) { | 87 | while (--loop_limit) { |
89 | *msw = readl(base + KONA_GPTIMER_STCHI_OFFSET); | 88 | *msw = readl(timer_base + KONA_GPTIMER_STCHI_OFFSET); |
90 | *lsw = readl(base + KONA_GPTIMER_STCLO_OFFSET); | 89 | *lsw = readl(timer_base + KONA_GPTIMER_STCLO_OFFSET); |
91 | if (*msw == readl(base + KONA_GPTIMER_STCHI_OFFSET)) | 90 | if (*msw == readl(timer_base + KONA_GPTIMER_STCHI_OFFSET)) |
92 | break; | 91 | break; |
93 | } | 92 | } |
94 | if (!loop_limit) { | 93 | if (!loop_limit) { |
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index 9403061a2acc..83564c9cfdbe 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
@@ -97,8 +97,8 @@ static void exynos4_mct_write(unsigned int value, unsigned long offset) | |||
97 | writel_relaxed(value, reg_base + offset); | 97 | writel_relaxed(value, reg_base + offset); |
98 | 98 | ||
99 | if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { | 99 | if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) { |
100 | stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; | 100 | stat_addr = (offset & EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET; |
101 | switch (offset & EXYNOS4_MCT_L_MASK) { | 101 | switch (offset & ~EXYNOS4_MCT_L_MASK) { |
102 | case MCT_L_TCON_OFFSET: | 102 | case MCT_L_TCON_OFFSET: |
103 | mask = 1 << 3; /* L_TCON write status */ | 103 | mask = 1 << 3; /* L_TCON write status */ |
104 | break; | 104 | break; |
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 0f665b8f2461..f150ca82bfaf 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c | |||
@@ -428,7 +428,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch, | |||
428 | ced->features = CLOCK_EVT_FEAT_PERIODIC; | 428 | ced->features = CLOCK_EVT_FEAT_PERIODIC; |
429 | ced->features |= CLOCK_EVT_FEAT_ONESHOT; | 429 | ced->features |= CLOCK_EVT_FEAT_ONESHOT; |
430 | ced->rating = 200; | 430 | ced->rating = 200; |
431 | ced->cpumask = cpumask_of(0); | 431 | ced->cpumask = cpu_possible_mask; |
432 | ced->set_next_event = sh_tmu_clock_event_next; | 432 | ced->set_next_event = sh_tmu_clock_event_next; |
433 | ced->set_mode = sh_tmu_clock_event_mode; | 433 | ced->set_mode = sh_tmu_clock_event_mode; |
434 | ced->suspend = sh_tmu_clock_event_suspend; | 434 | ced->suspend = sh_tmu_clock_event_suspend; |
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f56147a1daed..fde97d6e31d6 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c | |||
@@ -211,6 +211,17 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
211 | /* OPPs might be populated at runtime, don't check for error here */ | 211 | /* OPPs might be populated at runtime, don't check for error here */ |
212 | of_init_opp_table(cpu_dev); | 212 | of_init_opp_table(cpu_dev); |
213 | 213 | ||
214 | /* | ||
215 | * But we need OPP table to function so if it is not there let's | ||
216 | * give platform code chance to provide it for us. | ||
217 | */ | ||
218 | ret = dev_pm_opp_get_opp_count(cpu_dev); | ||
219 | if (ret <= 0) { | ||
220 | pr_debug("OPP table is not ready, deferring probe\n"); | ||
221 | ret = -EPROBE_DEFER; | ||
222 | goto out_free_opp; | ||
223 | } | ||
224 | |||
214 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 225 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
215 | if (!priv) { | 226 | if (!priv) { |
216 | ret = -ENOMEM; | 227 | ret = -ENOMEM; |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a09a29c312a9..46bed4f81cde 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -2028,6 +2028,12 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, | |||
2028 | /* Don't start any governor operations if we are entering suspend */ | 2028 | /* Don't start any governor operations if we are entering suspend */ |
2029 | if (cpufreq_suspended) | 2029 | if (cpufreq_suspended) |
2030 | return 0; | 2030 | return 0; |
2031 | /* | ||
2032 | * Governor might not be initiated here if ACPI _PPC changed | ||
2033 | * notification happened, so check it. | ||
2034 | */ | ||
2035 | if (!policy->governor) | ||
2036 | return -EINVAL; | ||
2031 | 2037 | ||
2032 | if (policy->governor->max_transition_latency && | 2038 | if (policy->governor->max_transition_latency && |
2033 | policy->cpuinfo.transition_latency > | 2039 | policy->cpuinfo.transition_latency > |
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c index 37263d9a1051..401c0106ed34 100644 --- a/drivers/cpuidle/governors/ladder.c +++ b/drivers/cpuidle/governors/ladder.c | |||
@@ -79,12 +79,7 @@ static int ladder_select_state(struct cpuidle_driver *drv, | |||
79 | 79 | ||
80 | last_state = &ldev->states[last_idx]; | 80 | last_state = &ldev->states[last_idx]; |
81 | 81 | ||
82 | if (!(drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_INVALID)) { | 82 | last_residency = cpuidle_get_last_residency(dev) - drv->states[last_idx].exit_latency; |
83 | last_residency = cpuidle_get_last_residency(dev) - \ | ||
84 | drv->states[last_idx].exit_latency; | ||
85 | } | ||
86 | else | ||
87 | last_residency = last_state->threshold.promotion_time + 1; | ||
88 | 83 | ||
89 | /* consider promotion */ | 84 | /* consider promotion */ |
90 | if (last_idx < drv->state_count - 1 && | 85 | if (last_idx < drv->state_count - 1 && |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 659d7b0c9ebf..40580794e23d 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -396,8 +396,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
396 | * power state and occurrence of the wakeup event. | 396 | * power state and occurrence of the wakeup event. |
397 | * | 397 | * |
398 | * If the entered idle state didn't support residency measurements, | 398 | * If the entered idle state didn't support residency measurements, |
399 | * we are basically lost in the dark how much time passed. | 399 | * we use them anyway if they are short, and if long, |
400 | * As a compromise, assume we slept for the whole expected time. | 400 | * truncate to the whole expected time. |
401 | * | 401 | * |
402 | * Any measured amount of time will include the exit latency. | 402 | * Any measured amount of time will include the exit latency. |
403 | * Since we are interested in when the wakeup begun, not when it | 403 | * Since we are interested in when the wakeup begun, not when it |
@@ -405,22 +405,17 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
405 | * the measured amount of time is less than the exit latency, | 405 | * the measured amount of time is less than the exit latency, |
406 | * assume the state was never reached and the exit latency is 0. | 406 | * assume the state was never reached and the exit latency is 0. |
407 | */ | 407 | */ |
408 | if (unlikely(target->flags & CPUIDLE_FLAG_TIME_INVALID)) { | ||
409 | /* Use timer value as is */ | ||
410 | measured_us = data->next_timer_us; | ||
411 | 408 | ||
412 | } else { | 409 | /* measured value */ |
413 | /* Use measured value */ | 410 | measured_us = cpuidle_get_last_residency(dev); |
414 | measured_us = cpuidle_get_last_residency(dev); | ||
415 | 411 | ||
416 | /* Deduct exit latency */ | 412 | /* Deduct exit latency */ |
417 | if (measured_us > target->exit_latency) | 413 | if (measured_us > target->exit_latency) |
418 | measured_us -= target->exit_latency; | 414 | measured_us -= target->exit_latency; |
419 | 415 | ||
420 | /* Make sure our coefficients do not exceed unity */ | 416 | /* Make sure our coefficients do not exceed unity */ |
421 | if (measured_us > data->next_timer_us) | 417 | if (measured_us > data->next_timer_us) |
422 | measured_us = data->next_timer_us; | 418 | measured_us = data->next_timer_us; |
423 | } | ||
424 | 419 | ||
425 | /* Update our correction ratio */ | 420 | /* Update our correction ratio */ |
426 | new_factor = data->correction_factor[data->bucket]; | 421 | new_factor = data->correction_factor[data->bucket]; |
diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 380478562b7d..5c062548957c 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c | |||
@@ -1505,7 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) | |||
1505 | dw->regs = chip->regs; | 1505 | dw->regs = chip->regs; |
1506 | chip->dw = dw; | 1506 | chip->dw = dw; |
1507 | 1507 | ||
1508 | pm_runtime_enable(chip->dev); | ||
1509 | pm_runtime_get_sync(chip->dev); | 1508 | pm_runtime_get_sync(chip->dev); |
1510 | 1509 | ||
1511 | dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); | 1510 | dw_params = dma_read_byaddr(chip->regs, DW_PARAMS); |
@@ -1703,7 +1702,6 @@ int dw_dma_remove(struct dw_dma_chip *chip) | |||
1703 | } | 1702 | } |
1704 | 1703 | ||
1705 | pm_runtime_put_sync_suspend(chip->dev); | 1704 | pm_runtime_put_sync_suspend(chip->dev); |
1706 | pm_runtime_disable(chip->dev); | ||
1707 | return 0; | 1705 | return 0; |
1708 | } | 1706 | } |
1709 | EXPORT_SYMBOL_GPL(dw_dma_remove); | 1707 | EXPORT_SYMBOL_GPL(dw_dma_remove); |
diff --git a/drivers/dma/dw/platform.c b/drivers/dma/dw/platform.c index a630161473a4..32ea1aca7a0e 100644 --- a/drivers/dma/dw/platform.c +++ b/drivers/dma/dw/platform.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/pm_runtime.h> | ||
18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
19 | #include <linux/dmaengine.h> | 20 | #include <linux/dmaengine.h> |
20 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
@@ -185,6 +186,8 @@ static int dw_probe(struct platform_device *pdev) | |||
185 | if (err) | 186 | if (err) |
186 | return err; | 187 | return err; |
187 | 188 | ||
189 | pm_runtime_enable(&pdev->dev); | ||
190 | |||
188 | err = dw_dma_probe(chip, pdata); | 191 | err = dw_dma_probe(chip, pdata); |
189 | if (err) | 192 | if (err) |
190 | goto err_dw_dma_probe; | 193 | goto err_dw_dma_probe; |
@@ -205,6 +208,7 @@ static int dw_probe(struct platform_device *pdev) | |||
205 | return 0; | 208 | return 0; |
206 | 209 | ||
207 | err_dw_dma_probe: | 210 | err_dw_dma_probe: |
211 | pm_runtime_disable(&pdev->dev); | ||
208 | clk_disable_unprepare(chip->clk); | 212 | clk_disable_unprepare(chip->clk); |
209 | return err; | 213 | return err; |
210 | } | 214 | } |
@@ -217,6 +221,7 @@ static int dw_remove(struct platform_device *pdev) | |||
217 | of_dma_controller_free(pdev->dev.of_node); | 221 | of_dma_controller_free(pdev->dev.of_node); |
218 | 222 | ||
219 | dw_dma_remove(chip); | 223 | dw_dma_remove(chip); |
224 | pm_runtime_disable(&pdev->dev); | ||
220 | clk_disable_unprepare(chip->clk); | 225 | clk_disable_unprepare(chip->clk); |
221 | 226 | ||
222 | return 0; | 227 | return 0; |
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 55d4803d71b0..3d9e08f7e823 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c | |||
@@ -272,7 +272,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) | |||
272 | for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { | 272 | for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { |
273 | if (pending & BIT(gpio)) { | 273 | if (pending & BIT(gpio)) { |
274 | virq = irq_find_mapping(cg->chip.irqdomain, gpio); | 274 | virq = irq_find_mapping(cg->chip.irqdomain, gpio); |
275 | generic_handle_irq(virq); | 275 | handle_nested_irq(virq); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 978b51eae2ec..ce3c1558cb0a 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c | |||
@@ -47,13 +47,6 @@ | |||
47 | 47 | ||
48 | #define DLN2_GPIO_MAX_PINS 32 | 48 | #define DLN2_GPIO_MAX_PINS 32 |
49 | 49 | ||
50 | struct dln2_irq_work { | ||
51 | struct work_struct work; | ||
52 | struct dln2_gpio *dln2; | ||
53 | int pin; | ||
54 | int type; | ||
55 | }; | ||
56 | |||
57 | struct dln2_gpio { | 50 | struct dln2_gpio { |
58 | struct platform_device *pdev; | 51 | struct platform_device *pdev; |
59 | struct gpio_chip gpio; | 52 | struct gpio_chip gpio; |
@@ -64,10 +57,12 @@ struct dln2_gpio { | |||
64 | */ | 57 | */ |
65 | DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); | 58 | DECLARE_BITMAP(output_enabled, DLN2_GPIO_MAX_PINS); |
66 | 59 | ||
67 | DECLARE_BITMAP(irqs_masked, DLN2_GPIO_MAX_PINS); | 60 | /* active IRQs - not synced to hardware */ |
68 | DECLARE_BITMAP(irqs_enabled, DLN2_GPIO_MAX_PINS); | 61 | DECLARE_BITMAP(unmasked_irqs, DLN2_GPIO_MAX_PINS); |
69 | DECLARE_BITMAP(irqs_pending, DLN2_GPIO_MAX_PINS); | 62 | /* active IRQS - synced to hardware */ |
70 | struct dln2_irq_work *irq_work; | 63 | DECLARE_BITMAP(enabled_irqs, DLN2_GPIO_MAX_PINS); |
64 | int irq_type[DLN2_GPIO_MAX_PINS]; | ||
65 | struct mutex irq_lock; | ||
71 | }; | 66 | }; |
72 | 67 | ||
73 | struct dln2_gpio_pin { | 68 | struct dln2_gpio_pin { |
@@ -141,16 +136,16 @@ static int dln2_gpio_pin_get_out_val(struct dln2_gpio *dln2, unsigned int pin) | |||
141 | return !!ret; | 136 | return !!ret; |
142 | } | 137 | } |
143 | 138 | ||
144 | static void dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, | 139 | static int dln2_gpio_pin_set_out_val(struct dln2_gpio *dln2, |
145 | unsigned int pin, int value) | 140 | unsigned int pin, int value) |
146 | { | 141 | { |
147 | struct dln2_gpio_pin_val req = { | 142 | struct dln2_gpio_pin_val req = { |
148 | .pin = cpu_to_le16(pin), | 143 | .pin = cpu_to_le16(pin), |
149 | .value = value, | 144 | .value = value, |
150 | }; | 145 | }; |
151 | 146 | ||
152 | dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, | 147 | return dln2_transfer_tx(dln2->pdev, DLN2_GPIO_PIN_SET_OUT_VAL, &req, |
153 | sizeof(req)); | 148 | sizeof(req)); |
154 | } | 149 | } |
155 | 150 | ||
156 | #define DLN2_GPIO_DIRECTION_IN 0 | 151 | #define DLN2_GPIO_DIRECTION_IN 0 |
@@ -267,6 +262,13 @@ static int dln2_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
267 | static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | 262 | static int dln2_gpio_direction_output(struct gpio_chip *chip, unsigned offset, |
268 | int value) | 263 | int value) |
269 | { | 264 | { |
265 | struct dln2_gpio *dln2 = container_of(chip, struct dln2_gpio, gpio); | ||
266 | int ret; | ||
267 | |||
268 | ret = dln2_gpio_pin_set_out_val(dln2, offset, value); | ||
269 | if (ret < 0) | ||
270 | return ret; | ||
271 | |||
270 | return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT); | 272 | return dln2_gpio_set_direction(chip, offset, DLN2_GPIO_DIRECTION_OUT); |
271 | } | 273 | } |
272 | 274 | ||
@@ -297,36 +299,13 @@ static int dln2_gpio_set_event_cfg(struct dln2_gpio *dln2, unsigned pin, | |||
297 | &req, sizeof(req)); | 299 | &req, sizeof(req)); |
298 | } | 300 | } |
299 | 301 | ||
300 | static void dln2_irq_work(struct work_struct *w) | 302 | static void dln2_irq_unmask(struct irq_data *irqd) |
301 | { | ||
302 | struct dln2_irq_work *iw = container_of(w, struct dln2_irq_work, work); | ||
303 | struct dln2_gpio *dln2 = iw->dln2; | ||
304 | u8 type = iw->type & DLN2_GPIO_EVENT_MASK; | ||
305 | |||
306 | if (test_bit(iw->pin, dln2->irqs_enabled)) | ||
307 | dln2_gpio_set_event_cfg(dln2, iw->pin, type, 0); | ||
308 | else | ||
309 | dln2_gpio_set_event_cfg(dln2, iw->pin, DLN2_GPIO_EVENT_NONE, 0); | ||
310 | } | ||
311 | |||
312 | static void dln2_irq_enable(struct irq_data *irqd) | ||
313 | { | ||
314 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
315 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
316 | int pin = irqd_to_hwirq(irqd); | ||
317 | |||
318 | set_bit(pin, dln2->irqs_enabled); | ||
319 | schedule_work(&dln2->irq_work[pin].work); | ||
320 | } | ||
321 | |||
322 | static void dln2_irq_disable(struct irq_data *irqd) | ||
323 | { | 303 | { |
324 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | 304 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); |
325 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | 305 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); |
326 | int pin = irqd_to_hwirq(irqd); | 306 | int pin = irqd_to_hwirq(irqd); |
327 | 307 | ||
328 | clear_bit(pin, dln2->irqs_enabled); | 308 | set_bit(pin, dln2->unmasked_irqs); |
329 | schedule_work(&dln2->irq_work[pin].work); | ||
330 | } | 309 | } |
331 | 310 | ||
332 | static void dln2_irq_mask(struct irq_data *irqd) | 311 | static void dln2_irq_mask(struct irq_data *irqd) |
@@ -335,27 +314,7 @@ static void dln2_irq_mask(struct irq_data *irqd) | |||
335 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | 314 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); |
336 | int pin = irqd_to_hwirq(irqd); | 315 | int pin = irqd_to_hwirq(irqd); |
337 | 316 | ||
338 | set_bit(pin, dln2->irqs_masked); | 317 | clear_bit(pin, dln2->unmasked_irqs); |
339 | } | ||
340 | |||
341 | static void dln2_irq_unmask(struct irq_data *irqd) | ||
342 | { | ||
343 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
344 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
345 | struct device *dev = dln2->gpio.dev; | ||
346 | int pin = irqd_to_hwirq(irqd); | ||
347 | |||
348 | if (test_and_clear_bit(pin, dln2->irqs_pending)) { | ||
349 | int irq; | ||
350 | |||
351 | irq = irq_find_mapping(dln2->gpio.irqdomain, pin); | ||
352 | if (!irq) { | ||
353 | dev_err(dev, "pin %d not mapped to IRQ\n", pin); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | generic_handle_irq(irq); | ||
358 | } | ||
359 | } | 318 | } |
360 | 319 | ||
361 | static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) | 320 | static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) |
@@ -366,19 +325,19 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) | |||
366 | 325 | ||
367 | switch (type) { | 326 | switch (type) { |
368 | case IRQ_TYPE_LEVEL_HIGH: | 327 | case IRQ_TYPE_LEVEL_HIGH: |
369 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_HIGH; | 328 | dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_HIGH; |
370 | break; | 329 | break; |
371 | case IRQ_TYPE_LEVEL_LOW: | 330 | case IRQ_TYPE_LEVEL_LOW: |
372 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_LVL_LOW; | 331 | dln2->irq_type[pin] = DLN2_GPIO_EVENT_LVL_LOW; |
373 | break; | 332 | break; |
374 | case IRQ_TYPE_EDGE_BOTH: | 333 | case IRQ_TYPE_EDGE_BOTH: |
375 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE; | 334 | dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE; |
376 | break; | 335 | break; |
377 | case IRQ_TYPE_EDGE_RISING: | 336 | case IRQ_TYPE_EDGE_RISING: |
378 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_RISING; | 337 | dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_RISING; |
379 | break; | 338 | break; |
380 | case IRQ_TYPE_EDGE_FALLING: | 339 | case IRQ_TYPE_EDGE_FALLING: |
381 | dln2->irq_work[pin].type = DLN2_GPIO_EVENT_CHANGE_FALLING; | 340 | dln2->irq_type[pin] = DLN2_GPIO_EVENT_CHANGE_FALLING; |
382 | break; | 341 | break; |
383 | default: | 342 | default: |
384 | return -EINVAL; | 343 | return -EINVAL; |
@@ -387,13 +346,50 @@ static int dln2_irq_set_type(struct irq_data *irqd, unsigned type) | |||
387 | return 0; | 346 | return 0; |
388 | } | 347 | } |
389 | 348 | ||
349 | static void dln2_irq_bus_lock(struct irq_data *irqd) | ||
350 | { | ||
351 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
352 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
353 | |||
354 | mutex_lock(&dln2->irq_lock); | ||
355 | } | ||
356 | |||
357 | static void dln2_irq_bus_unlock(struct irq_data *irqd) | ||
358 | { | ||
359 | struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd); | ||
360 | struct dln2_gpio *dln2 = container_of(gc, struct dln2_gpio, gpio); | ||
361 | int pin = irqd_to_hwirq(irqd); | ||
362 | int enabled, unmasked; | ||
363 | unsigned type; | ||
364 | int ret; | ||
365 | |||
366 | enabled = test_bit(pin, dln2->enabled_irqs); | ||
367 | unmasked = test_bit(pin, dln2->unmasked_irqs); | ||
368 | |||
369 | if (enabled != unmasked) { | ||
370 | if (unmasked) { | ||
371 | type = dln2->irq_type[pin] & DLN2_GPIO_EVENT_MASK; | ||
372 | set_bit(pin, dln2->enabled_irqs); | ||
373 | } else { | ||
374 | type = DLN2_GPIO_EVENT_NONE; | ||
375 | clear_bit(pin, dln2->enabled_irqs); | ||
376 | } | ||
377 | |||
378 | ret = dln2_gpio_set_event_cfg(dln2, pin, type, 0); | ||
379 | if (ret) | ||
380 | dev_err(dln2->gpio.dev, "failed to set event\n"); | ||
381 | } | ||
382 | |||
383 | mutex_unlock(&dln2->irq_lock); | ||
384 | } | ||
385 | |||
390 | static struct irq_chip dln2_gpio_irqchip = { | 386 | static struct irq_chip dln2_gpio_irqchip = { |
391 | .name = "dln2-irq", | 387 | .name = "dln2-irq", |
392 | .irq_enable = dln2_irq_enable, | ||
393 | .irq_disable = dln2_irq_disable, | ||
394 | .irq_mask = dln2_irq_mask, | 388 | .irq_mask = dln2_irq_mask, |
395 | .irq_unmask = dln2_irq_unmask, | 389 | .irq_unmask = dln2_irq_unmask, |
396 | .irq_set_type = dln2_irq_set_type, | 390 | .irq_set_type = dln2_irq_set_type, |
391 | .irq_bus_lock = dln2_irq_bus_lock, | ||
392 | .irq_bus_sync_unlock = dln2_irq_bus_unlock, | ||
397 | }; | 393 | }; |
398 | 394 | ||
399 | static void dln2_gpio_event(struct platform_device *pdev, u16 echo, | 395 | static void dln2_gpio_event(struct platform_device *pdev, u16 echo, |
@@ -425,14 +421,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, | |||
425 | return; | 421 | return; |
426 | } | 422 | } |
427 | 423 | ||
428 | if (!test_bit(pin, dln2->irqs_enabled)) | 424 | switch (dln2->irq_type[pin]) { |
429 | return; | ||
430 | if (test_bit(pin, dln2->irqs_masked)) { | ||
431 | set_bit(pin, dln2->irqs_pending); | ||
432 | return; | ||
433 | } | ||
434 | |||
435 | switch (dln2->irq_work[pin].type) { | ||
436 | case DLN2_GPIO_EVENT_CHANGE_RISING: | 425 | case DLN2_GPIO_EVENT_CHANGE_RISING: |
437 | if (event->value) | 426 | if (event->value) |
438 | generic_handle_irq(irq); | 427 | generic_handle_irq(irq); |
@@ -451,7 +440,7 @@ static int dln2_gpio_probe(struct platform_device *pdev) | |||
451 | struct dln2_gpio *dln2; | 440 | struct dln2_gpio *dln2; |
452 | struct device *dev = &pdev->dev; | 441 | struct device *dev = &pdev->dev; |
453 | int pins; | 442 | int pins; |
454 | int i, ret; | 443 | int ret; |
455 | 444 | ||
456 | pins = dln2_gpio_get_pin_count(pdev); | 445 | pins = dln2_gpio_get_pin_count(pdev); |
457 | if (pins < 0) { | 446 | if (pins < 0) { |
@@ -467,15 +456,7 @@ static int dln2_gpio_probe(struct platform_device *pdev) | |||
467 | if (!dln2) | 456 | if (!dln2) |
468 | return -ENOMEM; | 457 | return -ENOMEM; |
469 | 458 | ||
470 | dln2->irq_work = devm_kcalloc(&pdev->dev, pins, | 459 | mutex_init(&dln2->irq_lock); |
471 | sizeof(struct dln2_irq_work), GFP_KERNEL); | ||
472 | if (!dln2->irq_work) | ||
473 | return -ENOMEM; | ||
474 | for (i = 0; i < pins; i++) { | ||
475 | INIT_WORK(&dln2->irq_work[i].work, dln2_irq_work); | ||
476 | dln2->irq_work[i].pin = i; | ||
477 | dln2->irq_work[i].dln2 = dln2; | ||
478 | } | ||
479 | 460 | ||
480 | dln2->pdev = pdev; | 461 | dln2->pdev = pdev; |
481 | 462 | ||
@@ -529,11 +510,8 @@ out: | |||
529 | static int dln2_gpio_remove(struct platform_device *pdev) | 510 | static int dln2_gpio_remove(struct platform_device *pdev) |
530 | { | 511 | { |
531 | struct dln2_gpio *dln2 = platform_get_drvdata(pdev); | 512 | struct dln2_gpio *dln2 = platform_get_drvdata(pdev); |
532 | int i; | ||
533 | 513 | ||
534 | dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); | 514 | dln2_unregister_event_cb(pdev, DLN2_GPIO_CONDITION_MET_EV); |
535 | for (i = 0; i < dln2->gpio.ngpio; i++) | ||
536 | flush_work(&dln2->irq_work[i].work); | ||
537 | gpiochip_remove(&dln2->gpio); | 515 | gpiochip_remove(&dln2->gpio); |
538 | 516 | ||
539 | return 0; | 517 | return 0; |
diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 09daaf2aeb56..3a5a71050559 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c | |||
@@ -441,7 +441,8 @@ static int grgpio_probe(struct platform_device *ofdev) | |||
441 | err = gpiochip_add(gc); | 441 | err = gpiochip_add(gc); |
442 | if (err) { | 442 | if (err) { |
443 | dev_err(&ofdev->dev, "Could not add gpiochip\n"); | 443 | dev_err(&ofdev->dev, "Could not add gpiochip\n"); |
444 | irq_domain_remove(priv->domain); | 444 | if (priv->domain) |
445 | irq_domain_remove(priv->domain); | ||
445 | return err; | 446 | return err; |
446 | } | 447 | } |
447 | 448 | ||
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 604dbe60bdee..08261f2b3a82 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -45,8 +45,14 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) | |||
45 | return false; | 45 | return false; |
46 | 46 | ||
47 | ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); | 47 | ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); |
48 | if (ret < 0) | 48 | if (ret < 0) { |
49 | return false; | 49 | /* We've found the gpio chip, but the translation failed. |
50 | * Return true to stop looking and return the translation | ||
51 | * error via out_gpio | ||
52 | */ | ||
53 | gg_data->out_gpio = ERR_PTR(ret); | ||
54 | return true; | ||
55 | } | ||
50 | 56 | ||
51 | gg_data->out_gpio = gpiochip_get_desc(gc, ret); | 57 | gg_data->out_gpio = gpiochip_get_desc(gc, ret); |
52 | return true; | 58 | return true; |
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 2ac1800b58bb..f62aa115d79a 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c | |||
@@ -128,7 +128,7 @@ static ssize_t gpio_value_store(struct device *dev, | |||
128 | return status; | 128 | return status; |
129 | } | 129 | } |
130 | 130 | ||
131 | static const DEVICE_ATTR(value, 0644, | 131 | static DEVICE_ATTR(value, 0644, |
132 | gpio_value_show, gpio_value_store); | 132 | gpio_value_show, gpio_value_store); |
133 | 133 | ||
134 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | 134 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) |
@@ -353,17 +353,46 @@ static ssize_t gpio_active_low_store(struct device *dev, | |||
353 | return status ? : size; | 353 | return status ? : size; |
354 | } | 354 | } |
355 | 355 | ||
356 | static const DEVICE_ATTR(active_low, 0644, | 356 | static DEVICE_ATTR(active_low, 0644, |
357 | gpio_active_low_show, gpio_active_low_store); | 357 | gpio_active_low_show, gpio_active_low_store); |
358 | 358 | ||
359 | static const struct attribute *gpio_attrs[] = { | 359 | static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, |
360 | int n) | ||
361 | { | ||
362 | struct device *dev = container_of(kobj, struct device, kobj); | ||
363 | struct gpio_desc *desc = dev_get_drvdata(dev); | ||
364 | umode_t mode = attr->mode; | ||
365 | bool show_direction = test_bit(FLAG_SYSFS_DIR, &desc->flags); | ||
366 | |||
367 | if (attr == &dev_attr_direction.attr) { | ||
368 | if (!show_direction) | ||
369 | mode = 0; | ||
370 | } else if (attr == &dev_attr_edge.attr) { | ||
371 | if (gpiod_to_irq(desc) < 0) | ||
372 | mode = 0; | ||
373 | if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) | ||
374 | mode = 0; | ||
375 | } | ||
376 | |||
377 | return mode; | ||
378 | } | ||
379 | |||
380 | static struct attribute *gpio_attrs[] = { | ||
381 | &dev_attr_direction.attr, | ||
382 | &dev_attr_edge.attr, | ||
360 | &dev_attr_value.attr, | 383 | &dev_attr_value.attr, |
361 | &dev_attr_active_low.attr, | 384 | &dev_attr_active_low.attr, |
362 | NULL, | 385 | NULL, |
363 | }; | 386 | }; |
364 | 387 | ||
365 | static const struct attribute_group gpio_attr_group = { | 388 | static const struct attribute_group gpio_group = { |
366 | .attrs = (struct attribute **) gpio_attrs, | 389 | .attrs = gpio_attrs, |
390 | .is_visible = gpio_is_visible, | ||
391 | }; | ||
392 | |||
393 | static const struct attribute_group *gpio_groups[] = { | ||
394 | &gpio_group, | ||
395 | NULL | ||
367 | }; | 396 | }; |
368 | 397 | ||
369 | /* | 398 | /* |
@@ -400,16 +429,13 @@ static ssize_t chip_ngpio_show(struct device *dev, | |||
400 | } | 429 | } |
401 | static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); | 430 | static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); |
402 | 431 | ||
403 | static const struct attribute *gpiochip_attrs[] = { | 432 | static struct attribute *gpiochip_attrs[] = { |
404 | &dev_attr_base.attr, | 433 | &dev_attr_base.attr, |
405 | &dev_attr_label.attr, | 434 | &dev_attr_label.attr, |
406 | &dev_attr_ngpio.attr, | 435 | &dev_attr_ngpio.attr, |
407 | NULL, | 436 | NULL, |
408 | }; | 437 | }; |
409 | 438 | ATTRIBUTE_GROUPS(gpiochip); | |
410 | static const struct attribute_group gpiochip_attr_group = { | ||
411 | .attrs = (struct attribute **) gpiochip_attrs, | ||
412 | }; | ||
413 | 439 | ||
414 | /* | 440 | /* |
415 | * /sys/class/gpio/export ... write-only | 441 | * /sys/class/gpio/export ... write-only |
@@ -556,45 +582,30 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) | |||
556 | goto fail_unlock; | 582 | goto fail_unlock; |
557 | } | 583 | } |
558 | 584 | ||
559 | if (!desc->chip->direction_input || !desc->chip->direction_output) | 585 | if (desc->chip->direction_input && desc->chip->direction_output && |
560 | direction_may_change = false; | 586 | direction_may_change) { |
587 | set_bit(FLAG_SYSFS_DIR, &desc->flags); | ||
588 | } | ||
589 | |||
561 | spin_unlock_irqrestore(&gpio_lock, flags); | 590 | spin_unlock_irqrestore(&gpio_lock, flags); |
562 | 591 | ||
563 | offset = gpio_chip_hwgpio(desc); | 592 | offset = gpio_chip_hwgpio(desc); |
564 | if (desc->chip->names && desc->chip->names[offset]) | 593 | if (desc->chip->names && desc->chip->names[offset]) |
565 | ioname = desc->chip->names[offset]; | 594 | ioname = desc->chip->names[offset]; |
566 | 595 | ||
567 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 596 | dev = device_create_with_groups(&gpio_class, desc->chip->dev, |
568 | desc, ioname ? ioname : "gpio%u", | 597 | MKDEV(0, 0), desc, gpio_groups, |
569 | desc_to_gpio(desc)); | 598 | ioname ? ioname : "gpio%u", |
599 | desc_to_gpio(desc)); | ||
570 | if (IS_ERR(dev)) { | 600 | if (IS_ERR(dev)) { |
571 | status = PTR_ERR(dev); | 601 | status = PTR_ERR(dev); |
572 | goto fail_unlock; | 602 | goto fail_unlock; |
573 | } | 603 | } |
574 | 604 | ||
575 | status = sysfs_create_group(&dev->kobj, &gpio_attr_group); | ||
576 | if (status) | ||
577 | goto fail_unregister_device; | ||
578 | |||
579 | if (direction_may_change) { | ||
580 | status = device_create_file(dev, &dev_attr_direction); | ||
581 | if (status) | ||
582 | goto fail_unregister_device; | ||
583 | } | ||
584 | |||
585 | if (gpiod_to_irq(desc) >= 0 && (direction_may_change || | ||
586 | !test_bit(FLAG_IS_OUT, &desc->flags))) { | ||
587 | status = device_create_file(dev, &dev_attr_edge); | ||
588 | if (status) | ||
589 | goto fail_unregister_device; | ||
590 | } | ||
591 | |||
592 | set_bit(FLAG_EXPORT, &desc->flags); | 605 | set_bit(FLAG_EXPORT, &desc->flags); |
593 | mutex_unlock(&sysfs_lock); | 606 | mutex_unlock(&sysfs_lock); |
594 | return 0; | 607 | return 0; |
595 | 608 | ||
596 | fail_unregister_device: | ||
597 | device_unregister(dev); | ||
598 | fail_unlock: | 609 | fail_unlock: |
599 | mutex_unlock(&sysfs_lock); | 610 | mutex_unlock(&sysfs_lock); |
600 | gpiod_dbg(desc, "%s: status %d\n", __func__, status); | 611 | gpiod_dbg(desc, "%s: status %d\n", __func__, status); |
@@ -718,6 +729,7 @@ void gpiod_unexport(struct gpio_desc *desc) | |||
718 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | 729 | dev = class_find_device(&gpio_class, NULL, desc, match_export); |
719 | if (dev) { | 730 | if (dev) { |
720 | gpio_setup_irq(desc, dev, 0); | 731 | gpio_setup_irq(desc, dev, 0); |
732 | clear_bit(FLAG_SYSFS_DIR, &desc->flags); | ||
721 | clear_bit(FLAG_EXPORT, &desc->flags); | 733 | clear_bit(FLAG_EXPORT, &desc->flags); |
722 | } else | 734 | } else |
723 | status = -ENODEV; | 735 | status = -ENODEV; |
@@ -750,13 +762,13 @@ int gpiochip_export(struct gpio_chip *chip) | |||
750 | 762 | ||
751 | /* use chip->base for the ID; it's already known to be unique */ | 763 | /* use chip->base for the ID; it's already known to be unique */ |
752 | mutex_lock(&sysfs_lock); | 764 | mutex_lock(&sysfs_lock); |
753 | dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, | 765 | dev = device_create_with_groups(&gpio_class, chip->dev, MKDEV(0, 0), |
754 | "gpiochip%d", chip->base); | 766 | chip, gpiochip_groups, |
755 | if (!IS_ERR(dev)) { | 767 | "gpiochip%d", chip->base); |
756 | status = sysfs_create_group(&dev->kobj, | 768 | if (IS_ERR(dev)) |
757 | &gpiochip_attr_group); | ||
758 | } else | ||
759 | status = PTR_ERR(dev); | 769 | status = PTR_ERR(dev); |
770 | else | ||
771 | status = 0; | ||
760 | chip->exported = (status == 0); | 772 | chip->exported = (status == 0); |
761 | mutex_unlock(&sysfs_lock); | 773 | mutex_unlock(&sysfs_lock); |
762 | 774 | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 487afe6f22fc..568aa2b6bdb0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -248,29 +248,30 @@ int gpiochip_add(struct gpio_chip *chip) | |||
248 | base = gpiochip_find_base(chip->ngpio); | 248 | base = gpiochip_find_base(chip->ngpio); |
249 | if (base < 0) { | 249 | if (base < 0) { |
250 | status = base; | 250 | status = base; |
251 | goto unlock; | 251 | spin_unlock_irqrestore(&gpio_lock, flags); |
252 | goto err_free_descs; | ||
252 | } | 253 | } |
253 | chip->base = base; | 254 | chip->base = base; |
254 | } | 255 | } |
255 | 256 | ||
256 | status = gpiochip_add_to_list(chip); | 257 | status = gpiochip_add_to_list(chip); |
258 | if (status) { | ||
259 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
260 | goto err_free_descs; | ||
261 | } | ||
257 | 262 | ||
258 | if (status == 0) { | 263 | for (id = 0; id < chip->ngpio; id++) { |
259 | for (id = 0; id < chip->ngpio; id++) { | 264 | struct gpio_desc *desc = &descs[id]; |
260 | struct gpio_desc *desc = &descs[id]; | 265 | |
261 | desc->chip = chip; | 266 | desc->chip = chip; |
262 | 267 | ||
263 | /* REVISIT: most hardware initializes GPIOs as | 268 | /* REVISIT: most hardware initializes GPIOs as inputs (often |
264 | * inputs (often with pullups enabled) so power | 269 | * with pullups enabled) so power usage is minimized. Linux |
265 | * usage is minimized. Linux code should set the | 270 | * code should set the gpio direction first thing; but until |
266 | * gpio direction first thing; but until it does, | 271 | * it does, and in case chip->get_direction is not set, we may |
267 | * and in case chip->get_direction is not set, | 272 | * expose the wrong direction in sysfs. |
268 | * we may expose the wrong direction in sysfs. | 273 | */ |
269 | */ | 274 | desc->flags = !chip->direction_input ? (1 << FLAG_IS_OUT) : 0; |
270 | desc->flags = !chip->direction_input | ||
271 | ? (1 << FLAG_IS_OUT) | ||
272 | : 0; | ||
273 | } | ||
274 | } | 275 | } |
275 | 276 | ||
276 | chip->desc = descs; | 277 | chip->desc = descs; |
@@ -284,12 +285,9 @@ int gpiochip_add(struct gpio_chip *chip) | |||
284 | of_gpiochip_add(chip); | 285 | of_gpiochip_add(chip); |
285 | acpi_gpiochip_add(chip); | 286 | acpi_gpiochip_add(chip); |
286 | 287 | ||
287 | if (status) | ||
288 | goto fail; | ||
289 | |||
290 | status = gpiochip_export(chip); | 288 | status = gpiochip_export(chip); |
291 | if (status) | 289 | if (status) |
292 | goto fail; | 290 | goto err_remove_chip; |
293 | 291 | ||
294 | pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, | 292 | pr_debug("%s: registered GPIOs %d to %d on device: %s\n", __func__, |
295 | chip->base, chip->base + chip->ngpio - 1, | 293 | chip->base, chip->base + chip->ngpio - 1, |
@@ -297,11 +295,15 @@ int gpiochip_add(struct gpio_chip *chip) | |||
297 | 295 | ||
298 | return 0; | 296 | return 0; |
299 | 297 | ||
300 | unlock: | 298 | err_remove_chip: |
299 | acpi_gpiochip_remove(chip); | ||
300 | of_gpiochip_remove(chip); | ||
301 | spin_lock_irqsave(&gpio_lock, flags); | ||
302 | list_del(&chip->list); | ||
301 | spin_unlock_irqrestore(&gpio_lock, flags); | 303 | spin_unlock_irqrestore(&gpio_lock, flags); |
302 | fail: | ||
303 | kfree(descs); | ||
304 | chip->desc = NULL; | 304 | chip->desc = NULL; |
305 | err_free_descs: | ||
306 | kfree(descs); | ||
305 | 307 | ||
306 | /* failures here can mean systems won't boot... */ | 308 | /* failures here can mean systems won't boot... */ |
307 | pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, | 309 | pr_err("%s: GPIOs %d..%d (%s) failed to register\n", __func__, |
@@ -325,14 +327,15 @@ void gpiochip_remove(struct gpio_chip *chip) | |||
325 | unsigned long flags; | 327 | unsigned long flags; |
326 | unsigned id; | 328 | unsigned id; |
327 | 329 | ||
328 | acpi_gpiochip_remove(chip); | 330 | gpiochip_unexport(chip); |
329 | |||
330 | spin_lock_irqsave(&gpio_lock, flags); | ||
331 | 331 | ||
332 | gpiochip_irqchip_remove(chip); | 332 | gpiochip_irqchip_remove(chip); |
333 | |||
334 | acpi_gpiochip_remove(chip); | ||
333 | gpiochip_remove_pin_ranges(chip); | 335 | gpiochip_remove_pin_ranges(chip); |
334 | of_gpiochip_remove(chip); | 336 | of_gpiochip_remove(chip); |
335 | 337 | ||
338 | spin_lock_irqsave(&gpio_lock, flags); | ||
336 | for (id = 0; id < chip->ngpio; id++) { | 339 | for (id = 0; id < chip->ngpio; id++) { |
337 | if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) | 340 | if (test_bit(FLAG_REQUESTED, &chip->desc[id].flags)) |
338 | dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); | 341 | dev_crit(chip->dev, "REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED\n"); |
@@ -342,7 +345,6 @@ void gpiochip_remove(struct gpio_chip *chip) | |||
342 | 345 | ||
343 | list_del(&chip->list); | 346 | list_del(&chip->list); |
344 | spin_unlock_irqrestore(&gpio_lock, flags); | 347 | spin_unlock_irqrestore(&gpio_lock, flags); |
345 | gpiochip_unexport(chip); | ||
346 | 348 | ||
347 | kfree(chip->desc); | 349 | kfree(chip->desc); |
348 | chip->desc = NULL; | 350 | chip->desc = NULL; |
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index e3a52113a541..550a5eafbd38 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h | |||
@@ -77,6 +77,7 @@ struct gpio_desc { | |||
77 | #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ | 77 | #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ |
78 | #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ | 78 | #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ |
79 | #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ | 79 | #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ |
80 | #define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ | ||
80 | 81 | ||
81 | #define ID_SHIFT 16 /* add new flags before this one */ | 82 | #define ID_SHIFT 16 /* add new flags before this one */ |
82 | 83 | ||
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 66e40398b3d3..e620807418ea 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o | |||
37 | obj-$(CONFIG_DRM_TTM) += ttm/ | 37 | obj-$(CONFIG_DRM_TTM) += ttm/ |
38 | obj-$(CONFIG_DRM_TDFX) += tdfx/ | 38 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
39 | obj-$(CONFIG_DRM_R128) += r128/ | 39 | obj-$(CONFIG_DRM_R128) += r128/ |
40 | obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | ||
40 | obj-$(CONFIG_DRM_RADEON)+= radeon/ | 41 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
41 | obj-$(CONFIG_DRM_MGA) += mga/ | 42 | obj-$(CONFIG_DRM_MGA) += mga/ |
42 | obj-$(CONFIG_DRM_I810) += i810/ | 43 | obj-$(CONFIG_DRM_I810) += i810/ |
@@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/ | |||
67 | obj-y += i2c/ | 68 | obj-y += i2c/ |
68 | obj-y += panel/ | 69 | obj-y += panel/ |
69 | obj-y += bridge/ | 70 | obj-y += bridge/ |
70 | obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index be6246de5091..307a309110e6 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile | |||
@@ -8,7 +8,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ | |||
8 | kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ | 8 | kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \ |
9 | kfd_process.o kfd_queue.o kfd_mqd_manager.o \ | 9 | kfd_process.o kfd_queue.o kfd_mqd_manager.o \ |
10 | kfd_kernel_queue.o kfd_packet_manager.o \ | 10 | kfd_kernel_queue.o kfd_packet_manager.o \ |
11 | kfd_process_queue_manager.o kfd_device_queue_manager.o \ | 11 | kfd_process_queue_manager.o kfd_device_queue_manager.o |
12 | kfd_interrupt.o | ||
13 | 12 | ||
14 | obj-$(CONFIG_HSA_AMD) += amdkfd.o | 13 | obj-$(CONFIG_HSA_AMD) += amdkfd.o |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 4f7b275f2f7b..fcfdf23e1913 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <uapi/linux/kfd_ioctl.h> | 31 | #include <uapi/linux/kfd_ioctl.h> |
32 | #include <linux/time.h> | 32 | #include <linux/time.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/uaccess.h> | ||
35 | #include <uapi/asm-generic/mman-common.h> | 34 | #include <uapi/asm-generic/mman-common.h> |
36 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
37 | #include "kfd_priv.h" | 36 | #include "kfd_priv.h" |
@@ -121,27 +120,20 @@ static int kfd_open(struct inode *inode, struct file *filep) | |||
121 | if (IS_ERR(process)) | 120 | if (IS_ERR(process)) |
122 | return PTR_ERR(process); | 121 | return PTR_ERR(process); |
123 | 122 | ||
124 | process->is_32bit_user_mode = is_32bit_user_mode; | ||
125 | |||
126 | dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n", | 123 | dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n", |
127 | process->pasid, process->is_32bit_user_mode); | 124 | process->pasid, process->is_32bit_user_mode); |
128 | 125 | ||
129 | kfd_init_apertures(process); | ||
130 | |||
131 | return 0; | 126 | return 0; |
132 | } | 127 | } |
133 | 128 | ||
134 | static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, | 129 | static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, |
135 | void __user *arg) | 130 | void *data) |
136 | { | 131 | { |
137 | struct kfd_ioctl_get_version_args args; | 132 | struct kfd_ioctl_get_version_args *args = data; |
138 | int err = 0; | 133 | int err = 0; |
139 | 134 | ||
140 | args.major_version = KFD_IOCTL_MAJOR_VERSION; | 135 | args->major_version = KFD_IOCTL_MAJOR_VERSION; |
141 | args.minor_version = KFD_IOCTL_MINOR_VERSION; | 136 | args->minor_version = KFD_IOCTL_MINOR_VERSION; |
142 | |||
143 | if (copy_to_user(arg, &args, sizeof(args))) | ||
144 | err = -EFAULT; | ||
145 | 137 | ||
146 | return err; | 138 | return err; |
147 | } | 139 | } |
@@ -225,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, | |||
225 | return 0; | 217 | return 0; |
226 | } | 218 | } |
227 | 219 | ||
228 | static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | 220 | static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, |
229 | void __user *arg) | 221 | void *data) |
230 | { | 222 | { |
231 | struct kfd_ioctl_create_queue_args args; | 223 | struct kfd_ioctl_create_queue_args *args = data; |
232 | struct kfd_dev *dev; | 224 | struct kfd_dev *dev; |
233 | int err = 0; | 225 | int err = 0; |
234 | unsigned int queue_id; | 226 | unsigned int queue_id; |
@@ -237,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
237 | 229 | ||
238 | memset(&q_properties, 0, sizeof(struct queue_properties)); | 230 | memset(&q_properties, 0, sizeof(struct queue_properties)); |
239 | 231 | ||
240 | if (copy_from_user(&args, arg, sizeof(args))) | ||
241 | return -EFAULT; | ||
242 | |||
243 | pr_debug("kfd: creating queue ioctl\n"); | 232 | pr_debug("kfd: creating queue ioctl\n"); |
244 | 233 | ||
245 | err = set_queue_properties_from_user(&q_properties, &args); | 234 | err = set_queue_properties_from_user(&q_properties, args); |
246 | if (err) | 235 | if (err) |
247 | return err; | 236 | return err; |
248 | 237 | ||
249 | dev = kfd_device_by_id(args.gpu_id); | 238 | dev = kfd_device_by_id(args->gpu_id); |
250 | if (dev == NULL) | 239 | if (dev == NULL) |
251 | return -EINVAL; | 240 | return -EINVAL; |
252 | 241 | ||
@@ -254,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
254 | 243 | ||
255 | pdd = kfd_bind_process_to_device(dev, p); | 244 | pdd = kfd_bind_process_to_device(dev, p); |
256 | if (IS_ERR(pdd)) { | 245 | if (IS_ERR(pdd)) { |
257 | err = PTR_ERR(pdd); | 246 | err = -ESRCH; |
258 | goto err_bind_process; | 247 | goto err_bind_process; |
259 | } | 248 | } |
260 | 249 | ||
@@ -267,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
267 | if (err != 0) | 256 | if (err != 0) |
268 | goto err_create_queue; | 257 | goto err_create_queue; |
269 | 258 | ||
270 | args.queue_id = queue_id; | 259 | args->queue_id = queue_id; |
271 | 260 | ||
272 | /* Return gpu_id as doorbell offset for mmap usage */ | 261 | /* Return gpu_id as doorbell offset for mmap usage */ |
273 | args.doorbell_offset = args.gpu_id << PAGE_SHIFT; | 262 | args->doorbell_offset = args->gpu_id << PAGE_SHIFT; |
274 | |||
275 | if (copy_to_user(arg, &args, sizeof(args))) { | ||
276 | err = -EFAULT; | ||
277 | goto err_copy_args_out; | ||
278 | } | ||
279 | 263 | ||
280 | mutex_unlock(&p->mutex); | 264 | mutex_unlock(&p->mutex); |
281 | 265 | ||
282 | pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); | 266 | pr_debug("kfd: queue id %d was created successfully\n", args->queue_id); |
283 | 267 | ||
284 | pr_debug("ring buffer address == 0x%016llX\n", | 268 | pr_debug("ring buffer address == 0x%016llX\n", |
285 | args.ring_base_address); | 269 | args->ring_base_address); |
286 | 270 | ||
287 | pr_debug("read ptr address == 0x%016llX\n", | 271 | pr_debug("read ptr address == 0x%016llX\n", |
288 | args.read_pointer_address); | 272 | args->read_pointer_address); |
289 | 273 | ||
290 | pr_debug("write ptr address == 0x%016llX\n", | 274 | pr_debug("write ptr address == 0x%016llX\n", |
291 | args.write_pointer_address); | 275 | args->write_pointer_address); |
292 | 276 | ||
293 | return 0; | 277 | return 0; |
294 | 278 | ||
295 | err_copy_args_out: | ||
296 | pqm_destroy_queue(&p->pqm, queue_id); | ||
297 | err_create_queue: | 279 | err_create_queue: |
298 | err_bind_process: | 280 | err_bind_process: |
299 | mutex_unlock(&p->mutex); | 281 | mutex_unlock(&p->mutex); |
@@ -301,99 +283,90 @@ err_bind_process: | |||
301 | } | 283 | } |
302 | 284 | ||
303 | static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, | 285 | static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, |
304 | void __user *arg) | 286 | void *data) |
305 | { | 287 | { |
306 | int retval; | 288 | int retval; |
307 | struct kfd_ioctl_destroy_queue_args args; | 289 | struct kfd_ioctl_destroy_queue_args *args = data; |
308 | |||
309 | if (copy_from_user(&args, arg, sizeof(args))) | ||
310 | return -EFAULT; | ||
311 | 290 | ||
312 | pr_debug("kfd: destroying queue id %d for PASID %d\n", | 291 | pr_debug("kfd: destroying queue id %d for PASID %d\n", |
313 | args.queue_id, | 292 | args->queue_id, |
314 | p->pasid); | 293 | p->pasid); |
315 | 294 | ||
316 | mutex_lock(&p->mutex); | 295 | mutex_lock(&p->mutex); |
317 | 296 | ||
318 | retval = pqm_destroy_queue(&p->pqm, args.queue_id); | 297 | retval = pqm_destroy_queue(&p->pqm, args->queue_id); |
319 | 298 | ||
320 | mutex_unlock(&p->mutex); | 299 | mutex_unlock(&p->mutex); |
321 | return retval; | 300 | return retval; |
322 | } | 301 | } |
323 | 302 | ||
324 | static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, | 303 | static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, |
325 | void __user *arg) | 304 | void *data) |
326 | { | 305 | { |
327 | int retval; | 306 | int retval; |
328 | struct kfd_ioctl_update_queue_args args; | 307 | struct kfd_ioctl_update_queue_args *args = data; |
329 | struct queue_properties properties; | 308 | struct queue_properties properties; |
330 | 309 | ||
331 | if (copy_from_user(&args, arg, sizeof(args))) | 310 | if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { |
332 | return -EFAULT; | ||
333 | |||
334 | if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { | ||
335 | pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); | 311 | pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); |
336 | return -EINVAL; | 312 | return -EINVAL; |
337 | } | 313 | } |
338 | 314 | ||
339 | if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { | 315 | if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) { |
340 | pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); | 316 | pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); |
341 | return -EINVAL; | 317 | return -EINVAL; |
342 | } | 318 | } |
343 | 319 | ||
344 | if ((args.ring_base_address) && | 320 | if ((args->ring_base_address) && |
345 | (!access_ok(VERIFY_WRITE, | 321 | (!access_ok(VERIFY_WRITE, |
346 | (const void __user *) args.ring_base_address, | 322 | (const void __user *) args->ring_base_address, |
347 | sizeof(uint64_t)))) { | 323 | sizeof(uint64_t)))) { |
348 | pr_err("kfd: can't access ring base address\n"); | 324 | pr_err("kfd: can't access ring base address\n"); |
349 | return -EFAULT; | 325 | return -EFAULT; |
350 | } | 326 | } |
351 | 327 | ||
352 | if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { | 328 | if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) { |
353 | pr_err("kfd: ring size must be a power of 2 or 0\n"); | 329 | pr_err("kfd: ring size must be a power of 2 or 0\n"); |
354 | return -EINVAL; | 330 | return -EINVAL; |
355 | } | 331 | } |
356 | 332 | ||
357 | properties.queue_address = args.ring_base_address; | 333 | properties.queue_address = args->ring_base_address; |
358 | properties.queue_size = args.ring_size; | 334 | properties.queue_size = args->ring_size; |
359 | properties.queue_percent = args.queue_percentage; | 335 | properties.queue_percent = args->queue_percentage; |
360 | properties.priority = args.queue_priority; | 336 | properties.priority = args->queue_priority; |
361 | 337 | ||
362 | pr_debug("kfd: updating queue id %d for PASID %d\n", | 338 | pr_debug("kfd: updating queue id %d for PASID %d\n", |
363 | args.queue_id, p->pasid); | 339 | args->queue_id, p->pasid); |
364 | 340 | ||
365 | mutex_lock(&p->mutex); | 341 | mutex_lock(&p->mutex); |
366 | 342 | ||
367 | retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); | 343 | retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); |
368 | 344 | ||
369 | mutex_unlock(&p->mutex); | 345 | mutex_unlock(&p->mutex); |
370 | 346 | ||
371 | return retval; | 347 | return retval; |
372 | } | 348 | } |
373 | 349 | ||
374 | static long kfd_ioctl_set_memory_policy(struct file *filep, | 350 | static int kfd_ioctl_set_memory_policy(struct file *filep, |
375 | struct kfd_process *p, void __user *arg) | 351 | struct kfd_process *p, void *data) |
376 | { | 352 | { |
377 | struct kfd_ioctl_set_memory_policy_args args; | 353 | struct kfd_ioctl_set_memory_policy_args *args = data; |
378 | struct kfd_dev *dev; | 354 | struct kfd_dev *dev; |
379 | int err = 0; | 355 | int err = 0; |
380 | struct kfd_process_device *pdd; | 356 | struct kfd_process_device *pdd; |
381 | enum cache_policy default_policy, alternate_policy; | 357 | enum cache_policy default_policy, alternate_policy; |
382 | 358 | ||
383 | if (copy_from_user(&args, arg, sizeof(args))) | 359 | if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT |
384 | return -EFAULT; | 360 | && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { |
385 | |||
386 | if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT | ||
387 | && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | ||
388 | return -EINVAL; | 361 | return -EINVAL; |
389 | } | 362 | } |
390 | 363 | ||
391 | if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT | 364 | if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT |
392 | && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | 365 | && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { |
393 | return -EINVAL; | 366 | return -EINVAL; |
394 | } | 367 | } |
395 | 368 | ||
396 | dev = kfd_device_by_id(args.gpu_id); | 369 | dev = kfd_device_by_id(args->gpu_id); |
397 | if (dev == NULL) | 370 | if (dev == NULL) |
398 | return -EINVAL; | 371 | return -EINVAL; |
399 | 372 | ||
@@ -401,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, | |||
401 | 374 | ||
402 | pdd = kfd_bind_process_to_device(dev, p); | 375 | pdd = kfd_bind_process_to_device(dev, p); |
403 | if (IS_ERR(pdd)) { | 376 | if (IS_ERR(pdd)) { |
404 | err = PTR_ERR(pdd); | 377 | err = -ESRCH; |
405 | goto out; | 378 | goto out; |
406 | } | 379 | } |
407 | 380 | ||
408 | default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) | 381 | default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT) |
409 | ? cache_policy_coherent : cache_policy_noncoherent; | 382 | ? cache_policy_coherent : cache_policy_noncoherent; |
410 | 383 | ||
411 | alternate_policy = | 384 | alternate_policy = |
412 | (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) | 385 | (args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) |
413 | ? cache_policy_coherent : cache_policy_noncoherent; | 386 | ? cache_policy_coherent : cache_policy_noncoherent; |
414 | 387 | ||
415 | if (!dev->dqm->set_cache_memory_policy(dev->dqm, | 388 | if (!dev->dqm->set_cache_memory_policy(dev->dqm, |
416 | &pdd->qpd, | 389 | &pdd->qpd, |
417 | default_policy, | 390 | default_policy, |
418 | alternate_policy, | 391 | alternate_policy, |
419 | (void __user *)args.alternate_aperture_base, | 392 | (void __user *)args->alternate_aperture_base, |
420 | args.alternate_aperture_size)) | 393 | args->alternate_aperture_size)) |
421 | err = -EINVAL; | 394 | err = -EINVAL; |
422 | 395 | ||
423 | out: | 396 | out: |
@@ -426,53 +399,44 @@ out: | |||
426 | return err; | 399 | return err; |
427 | } | 400 | } |
428 | 401 | ||
429 | static long kfd_ioctl_get_clock_counters(struct file *filep, | 402 | static int kfd_ioctl_get_clock_counters(struct file *filep, |
430 | struct kfd_process *p, void __user *arg) | 403 | struct kfd_process *p, void *data) |
431 | { | 404 | { |
432 | struct kfd_ioctl_get_clock_counters_args args; | 405 | struct kfd_ioctl_get_clock_counters_args *args = data; |
433 | struct kfd_dev *dev; | 406 | struct kfd_dev *dev; |
434 | struct timespec time; | 407 | struct timespec time; |
435 | 408 | ||
436 | if (copy_from_user(&args, arg, sizeof(args))) | 409 | dev = kfd_device_by_id(args->gpu_id); |
437 | return -EFAULT; | ||
438 | |||
439 | dev = kfd_device_by_id(args.gpu_id); | ||
440 | if (dev == NULL) | 410 | if (dev == NULL) |
441 | return -EINVAL; | 411 | return -EINVAL; |
442 | 412 | ||
443 | /* Reading GPU clock counter from KGD */ | 413 | /* Reading GPU clock counter from KGD */ |
444 | args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); | 414 | args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); |
445 | 415 | ||
446 | /* No access to rdtsc. Using raw monotonic time */ | 416 | /* No access to rdtsc. Using raw monotonic time */ |
447 | getrawmonotonic(&time); | 417 | getrawmonotonic(&time); |
448 | args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); | 418 | args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time); |
449 | 419 | ||
450 | get_monotonic_boottime(&time); | 420 | get_monotonic_boottime(&time); |
451 | args.system_clock_counter = (uint64_t)timespec_to_ns(&time); | 421 | args->system_clock_counter = (uint64_t)timespec_to_ns(&time); |
452 | 422 | ||
453 | /* Since the counter is in nano-seconds we use 1GHz frequency */ | 423 | /* Since the counter is in nano-seconds we use 1GHz frequency */ |
454 | args.system_clock_freq = 1000000000; | 424 | args->system_clock_freq = 1000000000; |
455 | |||
456 | if (copy_to_user(arg, &args, sizeof(args))) | ||
457 | return -EFAULT; | ||
458 | 425 | ||
459 | return 0; | 426 | return 0; |
460 | } | 427 | } |
461 | 428 | ||
462 | 429 | ||
463 | static int kfd_ioctl_get_process_apertures(struct file *filp, | 430 | static int kfd_ioctl_get_process_apertures(struct file *filp, |
464 | struct kfd_process *p, void __user *arg) | 431 | struct kfd_process *p, void *data) |
465 | { | 432 | { |
466 | struct kfd_ioctl_get_process_apertures_args args; | 433 | struct kfd_ioctl_get_process_apertures_args *args = data; |
467 | struct kfd_process_device_apertures *pAperture; | 434 | struct kfd_process_device_apertures *pAperture; |
468 | struct kfd_process_device *pdd; | 435 | struct kfd_process_device *pdd; |
469 | 436 | ||
470 | dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); | 437 | dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); |
471 | 438 | ||
472 | if (copy_from_user(&args, arg, sizeof(args))) | 439 | args->num_of_nodes = 0; |
473 | return -EFAULT; | ||
474 | |||
475 | args.num_of_nodes = 0; | ||
476 | 440 | ||
477 | mutex_lock(&p->mutex); | 441 | mutex_lock(&p->mutex); |
478 | 442 | ||
@@ -481,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
481 | /* Run over all pdd of the process */ | 445 | /* Run over all pdd of the process */ |
482 | pdd = kfd_get_first_process_device_data(p); | 446 | pdd = kfd_get_first_process_device_data(p); |
483 | do { | 447 | do { |
484 | pAperture = &args.process_apertures[args.num_of_nodes]; | 448 | pAperture = |
449 | &args->process_apertures[args->num_of_nodes]; | ||
485 | pAperture->gpu_id = pdd->dev->id; | 450 | pAperture->gpu_id = pdd->dev->id; |
486 | pAperture->lds_base = pdd->lds_base; | 451 | pAperture->lds_base = pdd->lds_base; |
487 | pAperture->lds_limit = pdd->lds_limit; | 452 | pAperture->lds_limit = pdd->lds_limit; |
@@ -491,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
491 | pAperture->scratch_limit = pdd->scratch_limit; | 456 | pAperture->scratch_limit = pdd->scratch_limit; |
492 | 457 | ||
493 | dev_dbg(kfd_device, | 458 | dev_dbg(kfd_device, |
494 | "node id %u\n", args.num_of_nodes); | 459 | "node id %u\n", args->num_of_nodes); |
495 | dev_dbg(kfd_device, | 460 | dev_dbg(kfd_device, |
496 | "gpu id %u\n", pdd->dev->id); | 461 | "gpu id %u\n", pdd->dev->id); |
497 | dev_dbg(kfd_device, | 462 | dev_dbg(kfd_device, |
@@ -507,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
507 | dev_dbg(kfd_device, | 472 | dev_dbg(kfd_device, |
508 | "scratch_limit %llX\n", pdd->scratch_limit); | 473 | "scratch_limit %llX\n", pdd->scratch_limit); |
509 | 474 | ||
510 | args.num_of_nodes++; | 475 | args->num_of_nodes++; |
511 | } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && | 476 | } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && |
512 | (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); | 477 | (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS)); |
513 | } | 478 | } |
514 | 479 | ||
515 | mutex_unlock(&p->mutex); | 480 | mutex_unlock(&p->mutex); |
516 | 481 | ||
517 | if (copy_to_user(arg, &args, sizeof(args))) | ||
518 | return -EFAULT; | ||
519 | |||
520 | return 0; | 482 | return 0; |
521 | } | 483 | } |
522 | 484 | ||
485 | #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ | ||
486 | [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | ||
487 | |||
488 | /** Ioctl table */ | ||
489 | static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { | ||
490 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, | ||
491 | kfd_ioctl_get_version, 0), | ||
492 | |||
493 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, | ||
494 | kfd_ioctl_create_queue, 0), | ||
495 | |||
496 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, | ||
497 | kfd_ioctl_destroy_queue, 0), | ||
498 | |||
499 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, | ||
500 | kfd_ioctl_set_memory_policy, 0), | ||
501 | |||
502 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, | ||
503 | kfd_ioctl_get_clock_counters, 0), | ||
504 | |||
505 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, | ||
506 | kfd_ioctl_get_process_apertures, 0), | ||
507 | |||
508 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, | ||
509 | kfd_ioctl_update_queue, 0), | ||
510 | }; | ||
511 | |||
512 | #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) | ||
513 | |||
523 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 514 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
524 | { | 515 | { |
525 | struct kfd_process *process; | 516 | struct kfd_process *process; |
526 | long err = -EINVAL; | 517 | amdkfd_ioctl_t *func; |
518 | const struct amdkfd_ioctl_desc *ioctl = NULL; | ||
519 | unsigned int nr = _IOC_NR(cmd); | ||
520 | char stack_kdata[128]; | ||
521 | char *kdata = NULL; | ||
522 | unsigned int usize, asize; | ||
523 | int retcode = -EINVAL; | ||
524 | |||
525 | if (nr >= AMDKFD_CORE_IOCTL_COUNT) | ||
526 | goto err_i1; | ||
527 | |||
528 | if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { | ||
529 | u32 amdkfd_size; | ||
530 | |||
531 | ioctl = &amdkfd_ioctls[nr]; | ||
527 | 532 | ||
528 | dev_dbg(kfd_device, | 533 | amdkfd_size = _IOC_SIZE(ioctl->cmd); |
529 | "ioctl cmd 0x%x (#%d), arg 0x%lx\n", | 534 | usize = asize = _IOC_SIZE(cmd); |
530 | cmd, _IOC_NR(cmd), arg); | 535 | if (amdkfd_size > asize) |
536 | asize = amdkfd_size; | ||
537 | |||
538 | cmd = ioctl->cmd; | ||
539 | } else | ||
540 | goto err_i1; | ||
541 | |||
542 | dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg); | ||
531 | 543 | ||
532 | process = kfd_get_process(current); | 544 | process = kfd_get_process(current); |
533 | if (IS_ERR(process)) | 545 | if (IS_ERR(process)) { |
534 | return PTR_ERR(process); | 546 | dev_dbg(kfd_device, "no process\n"); |
547 | goto err_i1; | ||
548 | } | ||
535 | 549 | ||
536 | switch (cmd) { | 550 | /* Do not trust userspace, use our own definition */ |
537 | case KFD_IOC_GET_VERSION: | 551 | func = ioctl->func; |
538 | err = kfd_ioctl_get_version(filep, process, (void __user *)arg); | 552 | |
539 | break; | 553 | if (unlikely(!func)) { |
540 | case KFD_IOC_CREATE_QUEUE: | 554 | dev_dbg(kfd_device, "no function\n"); |
541 | err = kfd_ioctl_create_queue(filep, process, | 555 | retcode = -EINVAL; |
542 | (void __user *)arg); | 556 | goto err_i1; |
543 | break; | ||
544 | |||
545 | case KFD_IOC_DESTROY_QUEUE: | ||
546 | err = kfd_ioctl_destroy_queue(filep, process, | ||
547 | (void __user *)arg); | ||
548 | break; | ||
549 | |||
550 | case KFD_IOC_SET_MEMORY_POLICY: | ||
551 | err = kfd_ioctl_set_memory_policy(filep, process, | ||
552 | (void __user *)arg); | ||
553 | break; | ||
554 | |||
555 | case KFD_IOC_GET_CLOCK_COUNTERS: | ||
556 | err = kfd_ioctl_get_clock_counters(filep, process, | ||
557 | (void __user *)arg); | ||
558 | break; | ||
559 | |||
560 | case KFD_IOC_GET_PROCESS_APERTURES: | ||
561 | err = kfd_ioctl_get_process_apertures(filep, process, | ||
562 | (void __user *)arg); | ||
563 | break; | ||
564 | |||
565 | case KFD_IOC_UPDATE_QUEUE: | ||
566 | err = kfd_ioctl_update_queue(filep, process, | ||
567 | (void __user *)arg); | ||
568 | break; | ||
569 | |||
570 | default: | ||
571 | dev_err(kfd_device, | ||
572 | "unknown ioctl cmd 0x%x, arg 0x%lx)\n", | ||
573 | cmd, arg); | ||
574 | err = -EINVAL; | ||
575 | break; | ||
576 | } | 557 | } |
577 | 558 | ||
578 | if (err < 0) | 559 | if (cmd & (IOC_IN | IOC_OUT)) { |
579 | dev_err(kfd_device, | 560 | if (asize <= sizeof(stack_kdata)) { |
580 | "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", | 561 | kdata = stack_kdata; |
581 | err, cmd, _IOC_NR(cmd)); | 562 | } else { |
563 | kdata = kmalloc(asize, GFP_KERNEL); | ||
564 | if (!kdata) { | ||
565 | retcode = -ENOMEM; | ||
566 | goto err_i1; | ||
567 | } | ||
568 | } | ||
569 | if (asize > usize) | ||
570 | memset(kdata + usize, 0, asize - usize); | ||
571 | } | ||
582 | 572 | ||
583 | return err; | 573 | if (cmd & IOC_IN) { |
574 | if (copy_from_user(kdata, (void __user *)arg, usize) != 0) { | ||
575 | retcode = -EFAULT; | ||
576 | goto err_i1; | ||
577 | } | ||
578 | } else if (cmd & IOC_OUT) { | ||
579 | memset(kdata, 0, usize); | ||
580 | } | ||
581 | |||
582 | retcode = func(filep, process, kdata); | ||
583 | |||
584 | if (cmd & IOC_OUT) | ||
585 | if (copy_to_user((void __user *)arg, kdata, usize) != 0) | ||
586 | retcode = -EFAULT; | ||
587 | |||
588 | err_i1: | ||
589 | if (!ioctl) | ||
590 | dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", | ||
591 | task_pid_nr(current), cmd, nr); | ||
592 | |||
593 | if (kdata != stack_kdata) | ||
594 | kfree(kdata); | ||
595 | |||
596 | if (retcode) | ||
597 | dev_dbg(kfd_device, "ret = %d\n", retcode); | ||
598 | |||
599 | return retcode; | ||
584 | } | 600 | } |
585 | 601 | ||
586 | static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) | 602 | static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 43884ebd4303..25bc47f3c1cf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include "kfd_priv.h" | 27 | #include "kfd_priv.h" |
28 | #include "kfd_device_queue_manager.h" | 28 | #include "kfd_device_queue_manager.h" |
29 | #include "kfd_pm4_headers.h" | ||
29 | 30 | ||
30 | #define MQD_SIZE_ALIGNED 768 | 31 | #define MQD_SIZE_ALIGNED 768 |
31 | 32 | ||
@@ -169,9 +170,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, | |||
169 | kfd->shared_resources = *gpu_resources; | 170 | kfd->shared_resources = *gpu_resources; |
170 | 171 | ||
171 | /* calculate max size of mqds needed for queues */ | 172 | /* calculate max size of mqds needed for queues */ |
172 | size = max_num_of_processes * | 173 | size = max_num_of_queues_per_device * |
173 | max_num_of_queues_per_process * | 174 | kfd->device_info->mqd_size_aligned; |
174 | kfd->device_info->mqd_size_aligned; | ||
175 | 175 | ||
176 | /* add another 512KB for all other allocations on gart */ | 176 | /* add another 512KB for all other allocations on gart */ |
177 | size += 512 * 1024; | 177 | size += 512 * 1024; |
@@ -192,13 +192,6 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, | |||
192 | goto kfd_topology_add_device_error; | 192 | goto kfd_topology_add_device_error; |
193 | } | 193 | } |
194 | 194 | ||
195 | if (kfd_interrupt_init(kfd)) { | ||
196 | dev_err(kfd_device, | ||
197 | "Error initializing interrupts for device (%x:%x)\n", | ||
198 | kfd->pdev->vendor, kfd->pdev->device); | ||
199 | goto kfd_interrupt_error; | ||
200 | } | ||
201 | |||
202 | if (!device_iommu_pasid_init(kfd)) { | 195 | if (!device_iommu_pasid_init(kfd)) { |
203 | dev_err(kfd_device, | 196 | dev_err(kfd_device, |
204 | "Error initializing iommuv2 for device (%x:%x)\n", | 197 | "Error initializing iommuv2 for device (%x:%x)\n", |
@@ -237,8 +230,6 @@ dqm_start_error: | |||
237 | device_queue_manager_error: | 230 | device_queue_manager_error: |
238 | amd_iommu_free_device(kfd->pdev); | 231 | amd_iommu_free_device(kfd->pdev); |
239 | device_iommu_pasid_error: | 232 | device_iommu_pasid_error: |
240 | kfd_interrupt_exit(kfd); | ||
241 | kfd_interrupt_error: | ||
242 | kfd_topology_remove_device(kfd); | 233 | kfd_topology_remove_device(kfd); |
243 | kfd_topology_add_device_error: | 234 | kfd_topology_add_device_error: |
244 | kfd2kgd->fini_sa_manager(kfd->kgd); | 235 | kfd2kgd->fini_sa_manager(kfd->kgd); |
@@ -254,7 +245,6 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd) | |||
254 | if (kfd->init_complete) { | 245 | if (kfd->init_complete) { |
255 | device_queue_manager_uninit(kfd->dqm); | 246 | device_queue_manager_uninit(kfd->dqm); |
256 | amd_iommu_free_device(kfd->pdev); | 247 | amd_iommu_free_device(kfd->pdev); |
257 | kfd_interrupt_exit(kfd); | ||
258 | kfd_topology_remove_device(kfd); | 248 | kfd_topology_remove_device(kfd); |
259 | } | 249 | } |
260 | 250 | ||
@@ -296,13 +286,5 @@ int kgd2kfd_resume(struct kfd_dev *kfd) | |||
296 | /* This is called directly from KGD at ISR. */ | 286 | /* This is called directly from KGD at ISR. */ |
297 | void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) | 287 | void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry) |
298 | { | 288 | { |
299 | if (kfd->init_complete) { | 289 | /* Process interrupts / schedule work as necessary */ |
300 | spin_lock(&kfd->interrupt_lock); | ||
301 | |||
302 | if (kfd->interrupts_active | ||
303 | && enqueue_ih_ring_entry(kfd, ih_ring_entry)) | ||
304 | schedule_work(&kfd->interrupt_work); | ||
305 | |||
306 | spin_unlock(&kfd->interrupt_lock); | ||
307 | } | ||
308 | } | 290 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 924e90c072e5..0d8694f015c1 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm, | |||
161 | { | 161 | { |
162 | int bit = qpd->vmid - KFD_VMID_START_OFFSET; | 162 | int bit = qpd->vmid - KFD_VMID_START_OFFSET; |
163 | 163 | ||
164 | /* Release the vmid mapping */ | ||
165 | set_pasid_vmid_mapping(dqm, 0, qpd->vmid); | ||
166 | |||
164 | set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); | 167 | set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); |
165 | qpd->vmid = 0; | 168 | qpd->vmid = 0; |
166 | q->properties.vmid = 0; | 169 | q->properties.vmid = 0; |
@@ -180,6 +183,13 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, | |||
180 | 183 | ||
181 | mutex_lock(&dqm->lock); | 184 | mutex_lock(&dqm->lock); |
182 | 185 | ||
186 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
187 | pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | ||
188 | dqm->total_queue_count); | ||
189 | mutex_unlock(&dqm->lock); | ||
190 | return -EPERM; | ||
191 | } | ||
192 | |||
183 | if (list_empty(&qpd->queues_list)) { | 193 | if (list_empty(&qpd->queues_list)) { |
184 | retval = allocate_vmid(dqm, qpd, q); | 194 | retval = allocate_vmid(dqm, qpd, q); |
185 | if (retval != 0) { | 195 | if (retval != 0) { |
@@ -204,6 +214,14 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, | |||
204 | list_add(&q->list, &qpd->queues_list); | 214 | list_add(&q->list, &qpd->queues_list); |
205 | dqm->queue_count++; | 215 | dqm->queue_count++; |
206 | 216 | ||
217 | /* | ||
218 | * Unconditionally increment this counter, regardless of the queue's | ||
219 | * type or whether the queue is active. | ||
220 | */ | ||
221 | dqm->total_queue_count++; | ||
222 | pr_debug("Total of %d queues are accountable so far\n", | ||
223 | dqm->total_queue_count); | ||
224 | |||
207 | mutex_unlock(&dqm->lock); | 225 | mutex_unlock(&dqm->lock); |
208 | return 0; | 226 | return 0; |
209 | } | 227 | } |
@@ -272,6 +290,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, | |||
272 | return retval; | 290 | return retval; |
273 | } | 291 | } |
274 | 292 | ||
293 | pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n", | ||
294 | q->pipe, | ||
295 | q->queue); | ||
296 | |||
297 | retval = mqd->load_mqd(mqd, q->mqd, q->pipe, | ||
298 | q->queue, (uint32_t __user *) q->properties.write_ptr); | ||
299 | if (retval != 0) { | ||
300 | deallocate_hqd(dqm, q); | ||
301 | mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); | ||
302 | return retval; | ||
303 | } | ||
304 | |||
275 | return 0; | 305 | return 0; |
276 | } | 306 | } |
277 | 307 | ||
@@ -311,6 +341,15 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, | |||
311 | if (list_empty(&qpd->queues_list)) | 341 | if (list_empty(&qpd->queues_list)) |
312 | deallocate_vmid(dqm, qpd, q); | 342 | deallocate_vmid(dqm, qpd, q); |
313 | dqm->queue_count--; | 343 | dqm->queue_count--; |
344 | |||
345 | /* | ||
346 | * Unconditionally decrement this counter, regardless of the queue's | ||
347 | * type | ||
348 | */ | ||
349 | dqm->total_queue_count--; | ||
350 | pr_debug("Total of %d queues are accountable so far\n", | ||
351 | dqm->total_queue_count); | ||
352 | |||
314 | out: | 353 | out: |
315 | mutex_unlock(&dqm->lock); | 354 | mutex_unlock(&dqm->lock); |
316 | return retval; | 355 | return retval; |
@@ -320,6 +359,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) | |||
320 | { | 359 | { |
321 | int retval; | 360 | int retval; |
322 | struct mqd_manager *mqd; | 361 | struct mqd_manager *mqd; |
362 | bool prev_active = false; | ||
323 | 363 | ||
324 | BUG_ON(!dqm || !q || !q->mqd); | 364 | BUG_ON(!dqm || !q || !q->mqd); |
325 | 365 | ||
@@ -330,10 +370,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) | |||
330 | return -ENOMEM; | 370 | return -ENOMEM; |
331 | } | 371 | } |
332 | 372 | ||
333 | retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | ||
334 | if (q->properties.is_active == true) | 373 | if (q->properties.is_active == true) |
374 | prev_active = true; | ||
375 | |||
376 | /* | ||
377 | * | ||
378 | * check active state vs. the previous state | ||
379 | * and modify counter accordingly | ||
380 | */ | ||
381 | retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | ||
382 | if ((q->properties.is_active == true) && (prev_active == false)) | ||
335 | dqm->queue_count++; | 383 | dqm->queue_count++; |
336 | else | 384 | else if ((q->properties.is_active == false) && (prev_active == true)) |
337 | dqm->queue_count--; | 385 | dqm->queue_count--; |
338 | 386 | ||
339 | if (sched_policy != KFD_SCHED_POLICY_NO_HWS) | 387 | if (sched_policy != KFD_SCHED_POLICY_NO_HWS) |
@@ -517,10 +565,14 @@ static int init_pipelines(struct device_queue_manager *dqm, | |||
517 | 565 | ||
518 | for (i = 0; i < pipes_num; i++) { | 566 | for (i = 0; i < pipes_num; i++) { |
519 | inx = i + first_pipe; | 567 | inx = i + first_pipe; |
568 | /* | ||
569 | * HPD buffer on GTT is allocated by amdkfd, no need to waste | ||
570 | * space in GTT for pipelines we don't initialize | ||
571 | */ | ||
520 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; | 572 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; |
521 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); | 573 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); |
522 | /* = log2(bytes/4)-1 */ | 574 | /* = log2(bytes/4)-1 */ |
523 | kfd2kgd->init_pipeline(dqm->dev->kgd, i, | 575 | kfd2kgd->init_pipeline(dqm->dev->kgd, inx, |
524 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); | 576 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); |
525 | } | 577 | } |
526 | 578 | ||
@@ -536,7 +588,7 @@ static int init_scheduler(struct device_queue_manager *dqm) | |||
536 | 588 | ||
537 | pr_debug("kfd: In %s\n", __func__); | 589 | pr_debug("kfd: In %s\n", __func__); |
538 | 590 | ||
539 | retval = init_pipelines(dqm, get_pipes_num(dqm), KFD_DQM_FIRST_PIPE); | 591 | retval = init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm)); |
540 | if (retval != 0) | 592 | if (retval != 0) |
541 | return retval; | 593 | return retval; |
542 | 594 | ||
@@ -728,6 +780,21 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, | |||
728 | pr_debug("kfd: In func %s\n", __func__); | 780 | pr_debug("kfd: In func %s\n", __func__); |
729 | 781 | ||
730 | mutex_lock(&dqm->lock); | 782 | mutex_lock(&dqm->lock); |
783 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
784 | pr_warn("amdkfd: Can't create new kernel queue because %d queues were already created\n", | ||
785 | dqm->total_queue_count); | ||
786 | mutex_unlock(&dqm->lock); | ||
787 | return -EPERM; | ||
788 | } | ||
789 | |||
790 | /* | ||
791 | * Unconditionally increment this counter, regardless of the queue's | ||
792 | * type or whether the queue is active. | ||
793 | */ | ||
794 | dqm->total_queue_count++; | ||
795 | pr_debug("Total of %d queues are accountable so far\n", | ||
796 | dqm->total_queue_count); | ||
797 | |||
731 | list_add(&kq->list, &qpd->priv_queue_list); | 798 | list_add(&kq->list, &qpd->priv_queue_list); |
732 | dqm->queue_count++; | 799 | dqm->queue_count++; |
733 | qpd->is_debug = true; | 800 | qpd->is_debug = true; |
@@ -751,6 +818,13 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, | |||
751 | dqm->queue_count--; | 818 | dqm->queue_count--; |
752 | qpd->is_debug = false; | 819 | qpd->is_debug = false; |
753 | execute_queues_cpsch(dqm, false); | 820 | execute_queues_cpsch(dqm, false); |
821 | /* | ||
822 | * Unconditionally decrement this counter, regardless of the queue's | ||
823 | * type. | ||
824 | */ | ||
825 | dqm->total_queue_count++; | ||
826 | pr_debug("Total of %d queues are accountable so far\n", | ||
827 | dqm->total_queue_count); | ||
754 | mutex_unlock(&dqm->lock); | 828 | mutex_unlock(&dqm->lock); |
755 | } | 829 | } |
756 | 830 | ||
@@ -769,6 +843,13 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, | |||
769 | 843 | ||
770 | mutex_lock(&dqm->lock); | 844 | mutex_lock(&dqm->lock); |
771 | 845 | ||
846 | if (dqm->total_queue_count >= max_num_of_queues_per_device) { | ||
847 | pr_warn("amdkfd: Can't create new usermode queue because %d queues were already created\n", | ||
848 | dqm->total_queue_count); | ||
849 | retval = -EPERM; | ||
850 | goto out; | ||
851 | } | ||
852 | |||
772 | mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); | 853 | mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP); |
773 | if (mqd == NULL) { | 854 | if (mqd == NULL) { |
774 | mutex_unlock(&dqm->lock); | 855 | mutex_unlock(&dqm->lock); |
@@ -786,6 +867,15 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, | |||
786 | retval = execute_queues_cpsch(dqm, false); | 867 | retval = execute_queues_cpsch(dqm, false); |
787 | } | 868 | } |
788 | 869 | ||
870 | /* | ||
871 | * Unconditionally increment this counter, regardless of the queue's | ||
872 | * type or whether the queue is active. | ||
873 | */ | ||
874 | dqm->total_queue_count++; | ||
875 | |||
876 | pr_debug("Total of %d queues are accountable so far\n", | ||
877 | dqm->total_queue_count); | ||
878 | |||
789 | out: | 879 | out: |
790 | mutex_unlock(&dqm->lock); | 880 | mutex_unlock(&dqm->lock); |
791 | return retval; | 881 | return retval; |
@@ -906,6 +996,14 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, | |||
906 | 996 | ||
907 | mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); | 997 | mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); |
908 | 998 | ||
999 | /* | ||
1000 | * Unconditionally decrement this counter, regardless of the queue's | ||
1001 | * type | ||
1002 | */ | ||
1003 | dqm->total_queue_count--; | ||
1004 | pr_debug("Total of %d queues are accountable so far\n", | ||
1005 | dqm->total_queue_count); | ||
1006 | |||
909 | mutex_unlock(&dqm->lock); | 1007 | mutex_unlock(&dqm->lock); |
910 | 1008 | ||
911 | return 0; | 1009 | return 0; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index c3f189e8ae35..52035bf0c1cb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | |||
@@ -130,6 +130,7 @@ struct device_queue_manager { | |||
130 | struct list_head queues; | 130 | struct list_head queues; |
131 | unsigned int processes_count; | 131 | unsigned int processes_count; |
132 | unsigned int queue_count; | 132 | unsigned int queue_count; |
133 | unsigned int total_queue_count; | ||
133 | unsigned int next_pipe_to_allocate; | 134 | unsigned int next_pipe_to_allocate; |
134 | unsigned int *allocated_queues; | 135 | unsigned int *allocated_queues; |
135 | unsigned int vmid_bitmap; | 136 | unsigned int vmid_bitmap; |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c index 66df4da01c29..e64aa99e5e41 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c | |||
@@ -299,13 +299,13 @@ int kfd_init_apertures(struct kfd_process *process) | |||
299 | struct kfd_dev *dev; | 299 | struct kfd_dev *dev; |
300 | struct kfd_process_device *pdd; | 300 | struct kfd_process_device *pdd; |
301 | 301 | ||
302 | mutex_lock(&process->mutex); | ||
303 | |||
304 | /*Iterating over all devices*/ | 302 | /*Iterating over all devices*/ |
305 | while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL && | 303 | while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL && |
306 | id < NUM_OF_SUPPORTED_GPUS) { | 304 | id < NUM_OF_SUPPORTED_GPUS) { |
307 | 305 | ||
308 | pdd = kfd_get_process_device_data(dev, process, 1); | 306 | pdd = kfd_get_process_device_data(dev, process, 1); |
307 | if (!pdd) | ||
308 | return -1; | ||
309 | 309 | ||
310 | /* | 310 | /* |
311 | * For 64 bit process aperture will be statically reserved in | 311 | * For 64 bit process aperture will be statically reserved in |
@@ -348,8 +348,6 @@ int kfd_init_apertures(struct kfd_process *process) | |||
348 | id++; | 348 | id++; |
349 | } | 349 | } |
350 | 350 | ||
351 | mutex_unlock(&process->mutex); | ||
352 | |||
353 | return 0; | 351 | return 0; |
354 | } | 352 | } |
355 | 353 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c b/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c deleted file mode 100644 index 5b999095a1f7..000000000000 --- a/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ /dev/null | |||
@@ -1,176 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
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 | |||
23 | /* | ||
24 | * KFD Interrupts. | ||
25 | * | ||
26 | * AMD GPUs deliver interrupts by pushing an interrupt description onto the | ||
27 | * interrupt ring and then sending an interrupt. KGD receives the interrupt | ||
28 | * in ISR and sends us a pointer to each new entry on the interrupt ring. | ||
29 | * | ||
30 | * We generally can't process interrupt-signaled events from ISR, so we call | ||
31 | * out to each interrupt client module (currently only the scheduler) to ask if | ||
32 | * each interrupt is interesting. If they return true, then it requires further | ||
33 | * processing so we copy it to an internal interrupt ring and call each | ||
34 | * interrupt client again from a work-queue. | ||
35 | * | ||
36 | * There's no acknowledgment for the interrupts we use. The hardware simply | ||
37 | * queues a new interrupt each time without waiting. | ||
38 | * | ||
39 | * The fixed-size internal queue means that it's possible for us to lose | ||
40 | * interrupts because we have no back-pressure to the hardware. | ||
41 | */ | ||
42 | |||
43 | #include <linux/slab.h> | ||
44 | #include <linux/device.h> | ||
45 | #include "kfd_priv.h" | ||
46 | |||
47 | #define KFD_INTERRUPT_RING_SIZE 256 | ||
48 | |||
49 | static void interrupt_wq(struct work_struct *); | ||
50 | |||
51 | int kfd_interrupt_init(struct kfd_dev *kfd) | ||
52 | { | ||
53 | void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE, | ||
54 | kfd->device_info->ih_ring_entry_size, | ||
55 | GFP_KERNEL); | ||
56 | if (!interrupt_ring) | ||
57 | return -ENOMEM; | ||
58 | |||
59 | kfd->interrupt_ring = interrupt_ring; | ||
60 | kfd->interrupt_ring_size = | ||
61 | KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size; | ||
62 | atomic_set(&kfd->interrupt_ring_wptr, 0); | ||
63 | atomic_set(&kfd->interrupt_ring_rptr, 0); | ||
64 | |||
65 | spin_lock_init(&kfd->interrupt_lock); | ||
66 | |||
67 | INIT_WORK(&kfd->interrupt_work, interrupt_wq); | ||
68 | |||
69 | kfd->interrupts_active = true; | ||
70 | |||
71 | /* | ||
72 | * After this function returns, the interrupt will be enabled. This | ||
73 | * barrier ensures that the interrupt running on a different processor | ||
74 | * sees all the above writes. | ||
75 | */ | ||
76 | smp_wmb(); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | void kfd_interrupt_exit(struct kfd_dev *kfd) | ||
82 | { | ||
83 | /* | ||
84 | * Stop the interrupt handler from writing to the ring and scheduling | ||
85 | * workqueue items. The spinlock ensures that any interrupt running | ||
86 | * after we have unlocked sees interrupts_active = false. | ||
87 | */ | ||
88 | unsigned long flags; | ||
89 | |||
90 | spin_lock_irqsave(&kfd->interrupt_lock, flags); | ||
91 | kfd->interrupts_active = false; | ||
92 | spin_unlock_irqrestore(&kfd->interrupt_lock, flags); | ||
93 | |||
94 | /* | ||
95 | * Flush_scheduled_work ensures that there are no outstanding | ||
96 | * work-queue items that will access interrupt_ring. New work items | ||
97 | * can't be created because we stopped interrupt handling above. | ||
98 | */ | ||
99 | flush_scheduled_work(); | ||
100 | |||
101 | kfree(kfd->interrupt_ring); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * This assumes that it can't be called concurrently with itself | ||
106 | * but only with dequeue_ih_ring_entry. | ||
107 | */ | ||
108 | bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry) | ||
109 | { | ||
110 | unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); | ||
111 | unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); | ||
112 | |||
113 | if ((rptr - wptr) % kfd->interrupt_ring_size == | ||
114 | kfd->device_info->ih_ring_entry_size) { | ||
115 | /* This is very bad, the system is likely to hang. */ | ||
116 | dev_err_ratelimited(kfd_chardev(), | ||
117 | "Interrupt ring overflow, dropping interrupt.\n"); | ||
118 | return false; | ||
119 | } | ||
120 | |||
121 | memcpy(kfd->interrupt_ring + wptr, ih_ring_entry, | ||
122 | kfd->device_info->ih_ring_entry_size); | ||
123 | |||
124 | wptr = (wptr + kfd->device_info->ih_ring_entry_size) % | ||
125 | kfd->interrupt_ring_size; | ||
126 | smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */ | ||
127 | atomic_set(&kfd->interrupt_ring_wptr, wptr); | ||
128 | |||
129 | return true; | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * This assumes that it can't be called concurrently with itself | ||
134 | * but only with enqueue_ih_ring_entry. | ||
135 | */ | ||
136 | static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry) | ||
137 | { | ||
138 | /* | ||
139 | * Assume that wait queues have an implicit barrier, i.e. anything that | ||
140 | * happened in the ISR before it queued work is visible. | ||
141 | */ | ||
142 | |||
143 | unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr); | ||
144 | unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr); | ||
145 | |||
146 | if (rptr == wptr) | ||
147 | return false; | ||
148 | |||
149 | memcpy(ih_ring_entry, kfd->interrupt_ring + rptr, | ||
150 | kfd->device_info->ih_ring_entry_size); | ||
151 | |||
152 | rptr = (rptr + kfd->device_info->ih_ring_entry_size) % | ||
153 | kfd->interrupt_ring_size; | ||
154 | |||
155 | /* | ||
156 | * Ensure the rptr write update is not visible until | ||
157 | * memcpy has finished reading. | ||
158 | */ | ||
159 | smp_mb(); | ||
160 | atomic_set(&kfd->interrupt_ring_rptr, rptr); | ||
161 | |||
162 | return true; | ||
163 | } | ||
164 | |||
165 | static void interrupt_wq(struct work_struct *work) | ||
166 | { | ||
167 | struct kfd_dev *dev = container_of(work, struct kfd_dev, | ||
168 | interrupt_work); | ||
169 | |||
170 | uint32_t ih_ring_entry[DIV_ROUND_UP( | ||
171 | dev->device_info->ih_ring_entry_size, | ||
172 | sizeof(uint32_t))]; | ||
173 | |||
174 | while (dequeue_ih_ring_entry(dev, ih_ring_entry)) | ||
175 | ; | ||
176 | } | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index 95d5af138e6e..a8be6df85347 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c | |||
@@ -50,15 +50,10 @@ module_param(sched_policy, int, 0444); | |||
50 | MODULE_PARM_DESC(sched_policy, | 50 | MODULE_PARM_DESC(sched_policy, |
51 | "Kernel cmdline parameter that defines the amdkfd scheduling policy"); | 51 | "Kernel cmdline parameter that defines the amdkfd scheduling policy"); |
52 | 52 | ||
53 | int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT; | 53 | int max_num_of_queues_per_device = KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT; |
54 | module_param(max_num_of_processes, int, 0444); | 54 | module_param(max_num_of_queues_per_device, int, 0444); |
55 | MODULE_PARM_DESC(max_num_of_processes, | 55 | MODULE_PARM_DESC(max_num_of_queues_per_device, |
56 | "Kernel cmdline parameter that defines the amdkfd maximum number of supported processes"); | 56 | "Maximum number of supported queues per device (1 = Minimum, 4096 = default)"); |
57 | |||
58 | int max_num_of_queues_per_process = KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT; | ||
59 | module_param(max_num_of_queues_per_process, int, 0444); | ||
60 | MODULE_PARM_DESC(max_num_of_queues_per_process, | ||
61 | "Kernel cmdline parameter that defines the amdkfd maximum number of supported queues per process"); | ||
62 | 57 | ||
63 | bool kgd2kfd_init(unsigned interface_version, | 58 | bool kgd2kfd_init(unsigned interface_version, |
64 | const struct kfd2kgd_calls *f2g, | 59 | const struct kfd2kgd_calls *f2g, |
@@ -100,16 +95,10 @@ static int __init kfd_module_init(void) | |||
100 | } | 95 | } |
101 | 96 | ||
102 | /* Verify module parameters */ | 97 | /* Verify module parameters */ |
103 | if ((max_num_of_processes < 0) || | 98 | if ((max_num_of_queues_per_device < 0) || |
104 | (max_num_of_processes > KFD_MAX_NUM_OF_PROCESSES)) { | 99 | (max_num_of_queues_per_device > |
105 | pr_err("kfd: max_num_of_processes must be between 0 to KFD_MAX_NUM_OF_PROCESSES\n"); | 100 | KFD_MAX_NUM_OF_QUEUES_PER_DEVICE)) { |
106 | return -1; | 101 | pr_err("kfd: max_num_of_queues_per_device must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_DEVICE\n"); |
107 | } | ||
108 | |||
109 | if ((max_num_of_queues_per_process < 0) || | ||
110 | (max_num_of_queues_per_process > | ||
111 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)) { | ||
112 | pr_err("kfd: max_num_of_queues_per_process must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_PROCESS\n"); | ||
113 | return -1; | 102 | return -1; |
114 | } | 103 | } |
115 | 104 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index adc31474e786..4c3828cf45bf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | |||
@@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, | |||
184 | uint32_t queue_id) | 184 | uint32_t queue_id) |
185 | { | 185 | { |
186 | 186 | ||
187 | return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, | 187 | return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, |
188 | pipe_id, queue_id); | 188 | pipe_id, queue_id); |
189 | 189 | ||
190 | } | 190 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 71699ad97d74..6cfe7f1f18cf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | |||
@@ -30,9 +30,9 @@ static DEFINE_MUTEX(pasid_mutex); | |||
30 | 30 | ||
31 | int kfd_pasid_init(void) | 31 | int kfd_pasid_init(void) |
32 | { | 32 | { |
33 | pasid_limit = max_num_of_processes; | 33 | pasid_limit = KFD_MAX_NUM_OF_PROCESSES; |
34 | 34 | ||
35 | pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); | 35 | pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL); |
36 | if (!pasid_bitmap) | 36 | if (!pasid_bitmap) |
37 | return -ENOMEM; | 37 | return -ENOMEM; |
38 | 38 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f9fb81e3bb09..96dc10e8904a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -52,20 +52,19 @@ | |||
52 | #define kfd_alloc_struct(ptr_to_struct) \ | 52 | #define kfd_alloc_struct(ptr_to_struct) \ |
53 | ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) | 53 | ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) |
54 | 54 | ||
55 | /* Kernel module parameter to specify maximum number of supported processes */ | ||
56 | extern int max_num_of_processes; | ||
57 | |||
58 | #define KFD_MAX_NUM_OF_PROCESSES_DEFAULT 32 | ||
59 | #define KFD_MAX_NUM_OF_PROCESSES 512 | 55 | #define KFD_MAX_NUM_OF_PROCESSES 512 |
56 | #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 | ||
60 | 57 | ||
61 | /* | 58 | /* |
62 | * Kernel module parameter to specify maximum number of supported queues | 59 | * Kernel module parameter to specify maximum number of supported queues per |
63 | * per process | 60 | * device |
64 | */ | 61 | */ |
65 | extern int max_num_of_queues_per_process; | 62 | extern int max_num_of_queues_per_device; |
66 | 63 | ||
67 | #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128 | 64 | #define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT 4096 |
68 | #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 | 65 | #define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ |
66 | (KFD_MAX_NUM_OF_PROCESSES * \ | ||
67 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) | ||
69 | 68 | ||
70 | #define KFD_KERNEL_QUEUE_SIZE 2048 | 69 | #define KFD_KERNEL_QUEUE_SIZE 2048 |
71 | 70 | ||
@@ -135,22 +134,10 @@ struct kfd_dev { | |||
135 | 134 | ||
136 | struct kgd2kfd_shared_resources shared_resources; | 135 | struct kgd2kfd_shared_resources shared_resources; |
137 | 136 | ||
138 | void *interrupt_ring; | ||
139 | size_t interrupt_ring_size; | ||
140 | atomic_t interrupt_ring_rptr; | ||
141 | atomic_t interrupt_ring_wptr; | ||
142 | struct work_struct interrupt_work; | ||
143 | spinlock_t interrupt_lock; | ||
144 | |||
145 | /* QCM Device instance */ | 137 | /* QCM Device instance */ |
146 | struct device_queue_manager *dqm; | 138 | struct device_queue_manager *dqm; |
147 | 139 | ||
148 | bool init_complete; | 140 | bool init_complete; |
149 | /* | ||
150 | * Interrupts of interest to KFD are copied | ||
151 | * from the HW ring into a SW ring. | ||
152 | */ | ||
153 | bool interrupts_active; | ||
154 | }; | 141 | }; |
155 | 142 | ||
156 | /* KGD2KFD callbacks */ | 143 | /* KGD2KFD callbacks */ |
@@ -463,6 +450,24 @@ struct kfd_process { | |||
463 | bool is_32bit_user_mode; | 450 | bool is_32bit_user_mode; |
464 | }; | 451 | }; |
465 | 452 | ||
453 | /** | ||
454 | * Ioctl function type. | ||
455 | * | ||
456 | * \param filep pointer to file structure. | ||
457 | * \param p amdkfd process pointer. | ||
458 | * \param data pointer to arg that was copied from user. | ||
459 | */ | ||
460 | typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, | ||
461 | void *data); | ||
462 | |||
463 | struct amdkfd_ioctl_desc { | ||
464 | unsigned int cmd; | ||
465 | int flags; | ||
466 | amdkfd_ioctl_t *func; | ||
467 | unsigned int cmd_drv; | ||
468 | const char *name; | ||
469 | }; | ||
470 | |||
466 | void kfd_process_create_wq(void); | 471 | void kfd_process_create_wq(void); |
467 | void kfd_process_destroy_wq(void); | 472 | void kfd_process_destroy_wq(void); |
468 | struct kfd_process *kfd_create_process(const struct task_struct *); | 473 | struct kfd_process *kfd_create_process(const struct task_struct *); |
@@ -513,10 +518,7 @@ struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev); | |||
513 | struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); | 518 | struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx); |
514 | 519 | ||
515 | /* Interrupts */ | 520 | /* Interrupts */ |
516 | int kfd_interrupt_init(struct kfd_dev *dev); | ||
517 | void kfd_interrupt_exit(struct kfd_dev *dev); | ||
518 | void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); | 521 | void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry); |
519 | bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry); | ||
520 | 522 | ||
521 | /* Power Management */ | 523 | /* Power Management */ |
522 | void kgd2kfd_suspend(struct kfd_dev *kfd); | 524 | void kgd2kfd_suspend(struct kfd_dev *kfd); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index b85eb0b830b4..3c76ef05cbcf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/amd-iommu.h> | 27 | #include <linux/amd-iommu.h> |
28 | #include <linux/notifier.h> | 28 | #include <linux/notifier.h> |
29 | #include <linux/compat.h> | ||
30 | |||
29 | struct mm_struct; | 31 | struct mm_struct; |
30 | 32 | ||
31 | #include "kfd_priv.h" | 33 | #include "kfd_priv.h" |
@@ -285,8 +287,15 @@ static struct kfd_process *create_process(const struct task_struct *thread) | |||
285 | if (err != 0) | 287 | if (err != 0) |
286 | goto err_process_pqm_init; | 288 | goto err_process_pqm_init; |
287 | 289 | ||
290 | /* init process apertures*/ | ||
291 | process->is_32bit_user_mode = is_compat_task(); | ||
292 | if (kfd_init_apertures(process) != 0) | ||
293 | goto err_init_apretures; | ||
294 | |||
288 | return process; | 295 | return process; |
289 | 296 | ||
297 | err_init_apretures: | ||
298 | pqm_uninit(&process->pqm); | ||
290 | err_process_pqm_init: | 299 | err_process_pqm_init: |
291 | hash_del_rcu(&process->kfd_processes); | 300 | hash_del_rcu(&process->kfd_processes); |
292 | synchronize_rcu(); | 301 | synchronize_rcu(); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 47526780d736..f37cf5efe642 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | |||
@@ -54,11 +54,11 @@ static int find_available_queue_slot(struct process_queue_manager *pqm, | |||
54 | pr_debug("kfd: in %s\n", __func__); | 54 | pr_debug("kfd: in %s\n", __func__); |
55 | 55 | ||
56 | found = find_first_zero_bit(pqm->queue_slot_bitmap, | 56 | found = find_first_zero_bit(pqm->queue_slot_bitmap, |
57 | max_num_of_queues_per_process); | 57 | KFD_MAX_NUM_OF_QUEUES_PER_PROCESS); |
58 | 58 | ||
59 | pr_debug("kfd: the new slot id %lu\n", found); | 59 | pr_debug("kfd: the new slot id %lu\n", found); |
60 | 60 | ||
61 | if (found >= max_num_of_queues_per_process) { | 61 | if (found >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS) { |
62 | pr_info("amdkfd: Can not open more queues for process with pasid %d\n", | 62 | pr_info("amdkfd: Can not open more queues for process with pasid %d\n", |
63 | pqm->process->pasid); | 63 | pqm->process->pasid); |
64 | return -ENOMEM; | 64 | return -ENOMEM; |
@@ -76,7 +76,7 @@ int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) | |||
76 | 76 | ||
77 | INIT_LIST_HEAD(&pqm->queues); | 77 | INIT_LIST_HEAD(&pqm->queues); |
78 | pqm->queue_slot_bitmap = | 78 | pqm->queue_slot_bitmap = |
79 | kzalloc(DIV_ROUND_UP(max_num_of_queues_per_process, | 79 | kzalloc(DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, |
80 | BITS_PER_BYTE), GFP_KERNEL); | 80 | BITS_PER_BYTE), GFP_KERNEL); |
81 | if (pqm->queue_slot_bitmap == NULL) | 81 | if (pqm->queue_slot_bitmap == NULL) |
82 | return -ENOMEM; | 82 | return -ENOMEM; |
@@ -203,6 +203,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, | |||
203 | pqn->kq = NULL; | 203 | pqn->kq = NULL; |
204 | retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd, | 204 | retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd, |
205 | &q->properties.vmid); | 205 | &q->properties.vmid); |
206 | pr_debug("DQM returned %d for create_queue\n", retval); | ||
206 | print_queue(q); | 207 | print_queue(q); |
207 | break; | 208 | break; |
208 | case KFD_QUEUE_TYPE_DIQ: | 209 | case KFD_QUEUE_TYPE_DIQ: |
@@ -222,7 +223,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, | |||
222 | } | 223 | } |
223 | 224 | ||
224 | if (retval != 0) { | 225 | if (retval != 0) { |
225 | pr_err("kfd: error dqm create queue\n"); | 226 | pr_debug("Error dqm create queue\n"); |
226 | goto err_create_queue; | 227 | goto err_create_queue; |
227 | } | 228 | } |
228 | 229 | ||
@@ -241,7 +242,10 @@ int pqm_create_queue(struct process_queue_manager *pqm, | |||
241 | err_create_queue: | 242 | err_create_queue: |
242 | kfree(pqn); | 243 | kfree(pqn); |
243 | err_allocate_pqn: | 244 | err_allocate_pqn: |
245 | /* check if queues list is empty unregister process from device */ | ||
244 | clear_bit(*qid, pqm->queue_slot_bitmap); | 246 | clear_bit(*qid, pqm->queue_slot_bitmap); |
247 | if (list_empty(&pqm->queues)) | ||
248 | dev->dqm->unregister_process(dev->dqm, &pdd->qpd); | ||
245 | return retval; | 249 | return retval; |
246 | } | 250 | } |
247 | 251 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 5733e2859e8a..cca1708fd811 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -700,8 +700,6 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
700 | dev->node_props.simd_per_cu); | 700 | dev->node_props.simd_per_cu); |
701 | sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu", | 701 | sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu", |
702 | dev->node_props.max_slots_scratch_cu); | 702 | dev->node_props.max_slots_scratch_cu); |
703 | sysfs_show_32bit_prop(buffer, "engine_id", | ||
704 | dev->node_props.engine_id); | ||
705 | sysfs_show_32bit_prop(buffer, "vendor_id", | 703 | sysfs_show_32bit_prop(buffer, "vendor_id", |
706 | dev->node_props.vendor_id); | 704 | dev->node_props.vendor_id); |
707 | sysfs_show_32bit_prop(buffer, "device_id", | 705 | sysfs_show_32bit_prop(buffer, "device_id", |
@@ -715,6 +713,12 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, | |||
715 | dev->gpu->kgd)); | 713 | dev->gpu->kgd)); |
716 | sysfs_show_64bit_prop(buffer, "local_mem_size", | 714 | sysfs_show_64bit_prop(buffer, "local_mem_size", |
717 | kfd2kgd->get_vmem_size(dev->gpu->kgd)); | 715 | kfd2kgd->get_vmem_size(dev->gpu->kgd)); |
716 | |||
717 | sysfs_show_32bit_prop(buffer, "fw_version", | ||
718 | kfd2kgd->get_fw_version( | ||
719 | dev->gpu->kgd, | ||
720 | KGD_ENGINE_MEC1)); | ||
721 | |||
718 | } | 722 | } |
719 | 723 | ||
720 | ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", | 724 | ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute", |
@@ -917,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void) | |||
917 | uint32_t i = 0; | 921 | uint32_t i = 0; |
918 | 922 | ||
919 | list_for_each_entry(dev, &topology_device_list, list) { | 923 | list_for_each_entry(dev, &topology_device_list, list) { |
920 | ret = kfd_build_sysfs_node_entry(dev, 0); | 924 | ret = kfd_build_sysfs_node_entry(dev, i); |
921 | if (ret < 0) | 925 | if (ret < 0) |
922 | return ret; | 926 | return ret; |
923 | i++; | 927 | i++; |
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 9c729dd8dd50..96a512208fad 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h | |||
@@ -45,6 +45,17 @@ enum kgd_memory_pool { | |||
45 | KGD_POOL_FRAMEBUFFER = 3, | 45 | KGD_POOL_FRAMEBUFFER = 3, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | enum kgd_engine_type { | ||
49 | KGD_ENGINE_PFP = 1, | ||
50 | KGD_ENGINE_ME, | ||
51 | KGD_ENGINE_CE, | ||
52 | KGD_ENGINE_MEC1, | ||
53 | KGD_ENGINE_MEC2, | ||
54 | KGD_ENGINE_RLC, | ||
55 | KGD_ENGINE_SDMA, | ||
56 | KGD_ENGINE_MAX | ||
57 | }; | ||
58 | |||
48 | struct kgd2kfd_shared_resources { | 59 | struct kgd2kfd_shared_resources { |
49 | /* Bit n == 1 means VMID n is available for KFD. */ | 60 | /* Bit n == 1 means VMID n is available for KFD. */ |
50 | unsigned int compute_vmid_bitmap; | 61 | unsigned int compute_vmid_bitmap; |
@@ -137,6 +148,8 @@ struct kgd2kfd_calls { | |||
137 | * | 148 | * |
138 | * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot. | 149 | * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot. |
139 | * | 150 | * |
151 | * @get_fw_version: Returns FW versions from the header | ||
152 | * | ||
140 | * This structure contains function pointers to services that the kgd driver | 153 | * This structure contains function pointers to services that the kgd driver |
141 | * provides to amdkfd driver. | 154 | * provides to amdkfd driver. |
142 | * | 155 | * |
@@ -170,12 +183,14 @@ struct kfd2kgd_calls { | |||
170 | int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | 183 | int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
171 | uint32_t queue_id, uint32_t __user *wptr); | 184 | uint32_t queue_id, uint32_t __user *wptr); |
172 | 185 | ||
173 | bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, | 186 | bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address, |
174 | uint32_t pipe_id, uint32_t queue_id); | 187 | uint32_t pipe_id, uint32_t queue_id); |
175 | 188 | ||
176 | int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, | 189 | int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, |
177 | unsigned int timeout, uint32_t pipe_id, | 190 | unsigned int timeout, uint32_t pipe_id, |
178 | uint32_t queue_id); | 191 | uint32_t queue_id); |
192 | uint16_t (*get_fw_version)(struct kgd_dev *kgd, | ||
193 | enum kgd_engine_type type); | ||
179 | }; | 194 | }; |
180 | 195 | ||
181 | bool kgd2kfd_init(unsigned interface_version, | 196 | bool kgd2kfd_init(unsigned interface_version, |
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 4a78a773151c..bbdbe4721573 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
@@ -61,7 +61,7 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state, | |||
61 | struct drm_crtc_state *crtc_state; | 61 | struct drm_crtc_state *crtc_state; |
62 | 62 | ||
63 | if (plane->state->crtc) { | 63 | if (plane->state->crtc) { |
64 | crtc_state = state->crtc_states[drm_crtc_index(plane->crtc)]; | 64 | crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)]; |
65 | 65 | ||
66 | if (WARN_ON(!crtc_state)) | 66 | if (WARN_ON(!crtc_state)) |
67 | return; | 67 | return; |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 52ce26d6b4fb..dc386ebe5193 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -145,6 +145,31 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ | |||
145 | } | 145 | } |
146 | EXPORT_SYMBOL(drm_fb_helper_add_one_connector); | 146 | EXPORT_SYMBOL(drm_fb_helper_add_one_connector); |
147 | 147 | ||
148 | static void remove_from_modeset(struct drm_mode_set *set, | ||
149 | struct drm_connector *connector) | ||
150 | { | ||
151 | int i, j; | ||
152 | |||
153 | for (i = 0; i < set->num_connectors; i++) { | ||
154 | if (set->connectors[i] == connector) | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (i == set->num_connectors) | ||
159 | return; | ||
160 | |||
161 | for (j = i + 1; j < set->num_connectors; j++) { | ||
162 | set->connectors[j - 1] = set->connectors[j]; | ||
163 | } | ||
164 | set->num_connectors--; | ||
165 | |||
166 | /* because i915 is pissy about this.. | ||
167 | * TODO maybe need to makes sure we set it back to !=NULL somewhere? | ||
168 | */ | ||
169 | if (set->num_connectors == 0) | ||
170 | set->fb = NULL; | ||
171 | } | ||
172 | |||
148 | int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, | 173 | int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, |
149 | struct drm_connector *connector) | 174 | struct drm_connector *connector) |
150 | { | 175 | { |
@@ -167,6 +192,11 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, | |||
167 | } | 192 | } |
168 | fb_helper->connector_count--; | 193 | fb_helper->connector_count--; |
169 | kfree(fb_helper_connector); | 194 | kfree(fb_helper_connector); |
195 | |||
196 | /* also cleanup dangling references to the connector: */ | ||
197 | for (i = 0; i < fb_helper->crtc_count; i++) | ||
198 | remove_from_modeset(&fb_helper->crtc_info[i].mode_set, connector); | ||
199 | |||
170 | return 0; | 200 | return 0; |
171 | } | 201 | } |
172 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); | 202 | EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); |
@@ -741,7 +771,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) | |||
741 | int i, j, rc = 0; | 771 | int i, j, rc = 0; |
742 | int start; | 772 | int start; |
743 | 773 | ||
744 | drm_modeset_lock_all(dev); | 774 | if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { |
775 | return -EBUSY; | ||
776 | } | ||
745 | if (!drm_fb_helper_is_bound(fb_helper)) { | 777 | if (!drm_fb_helper_is_bound(fb_helper)) { |
746 | drm_modeset_unlock_all(dev); | 778 | drm_modeset_unlock_all(dev); |
747 | return -EBUSY; | 779 | return -EBUSY; |
@@ -915,7 +947,9 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, | |||
915 | int ret = 0; | 947 | int ret = 0; |
916 | int i; | 948 | int i; |
917 | 949 | ||
918 | drm_modeset_lock_all(dev); | 950 | if (__drm_modeset_lock_all(dev, !!oops_in_progress)) { |
951 | return -EBUSY; | ||
952 | } | ||
919 | if (!drm_fb_helper_is_bound(fb_helper)) { | 953 | if (!drm_fb_helper_is_bound(fb_helper)) { |
920 | drm_modeset_unlock_all(dev); | 954 | drm_modeset_unlock_all(dev); |
921 | return -EBUSY; | 955 | return -EBUSY; |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index f5a5f18efa5b..4d79dad9d44f 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -830,6 +830,8 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, | |||
830 | * vblank events since the system was booted, including lost events due to | 830 | * vblank events since the system was booted, including lost events due to |
831 | * modesetting activity. | 831 | * modesetting activity. |
832 | * | 832 | * |
833 | * This is the legacy version of drm_crtc_vblank_count(). | ||
834 | * | ||
833 | * Returns: | 835 | * Returns: |
834 | * The software vblank counter. | 836 | * The software vblank counter. |
835 | */ | 837 | */ |
@@ -844,6 +846,25 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc) | |||
844 | EXPORT_SYMBOL(drm_vblank_count); | 846 | EXPORT_SYMBOL(drm_vblank_count); |
845 | 847 | ||
846 | /** | 848 | /** |
849 | * drm_crtc_vblank_count - retrieve "cooked" vblank counter value | ||
850 | * @crtc: which counter to retrieve | ||
851 | * | ||
852 | * Fetches the "cooked" vblank count value that represents the number of | ||
853 | * vblank events since the system was booted, including lost events due to | ||
854 | * modesetting activity. | ||
855 | * | ||
856 | * This is the native KMS version of drm_vblank_count(). | ||
857 | * | ||
858 | * Returns: | ||
859 | * The software vblank counter. | ||
860 | */ | ||
861 | u32 drm_crtc_vblank_count(struct drm_crtc *crtc) | ||
862 | { | ||
863 | return drm_vblank_count(crtc->dev, drm_crtc_index(crtc)); | ||
864 | } | ||
865 | EXPORT_SYMBOL(drm_crtc_vblank_count); | ||
866 | |||
867 | /** | ||
847 | * drm_vblank_count_and_time - retrieve "cooked" vblank counter value | 868 | * drm_vblank_count_and_time - retrieve "cooked" vblank counter value |
848 | * and the system timestamp corresponding to that vblank counter value. | 869 | * and the system timestamp corresponding to that vblank counter value. |
849 | * | 870 | * |
@@ -904,6 +925,8 @@ static void send_vblank_event(struct drm_device *dev, | |||
904 | * | 925 | * |
905 | * Updates sequence # and timestamp on event, and sends it to userspace. | 926 | * Updates sequence # and timestamp on event, and sends it to userspace. |
906 | * Caller must hold event lock. | 927 | * Caller must hold event lock. |
928 | * | ||
929 | * This is the legacy version of drm_crtc_send_vblank_event(). | ||
907 | */ | 930 | */ |
908 | void drm_send_vblank_event(struct drm_device *dev, int crtc, | 931 | void drm_send_vblank_event(struct drm_device *dev, int crtc, |
909 | struct drm_pending_vblank_event *e) | 932 | struct drm_pending_vblank_event *e) |
@@ -923,6 +946,23 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, | |||
923 | EXPORT_SYMBOL(drm_send_vblank_event); | 946 | EXPORT_SYMBOL(drm_send_vblank_event); |
924 | 947 | ||
925 | /** | 948 | /** |
949 | * drm_crtc_send_vblank_event - helper to send vblank event after pageflip | ||
950 | * @crtc: the source CRTC of the vblank event | ||
951 | * @e: the event to send | ||
952 | * | ||
953 | * Updates sequence # and timestamp on event, and sends it to userspace. | ||
954 | * Caller must hold event lock. | ||
955 | * | ||
956 | * This is the native KMS version of drm_send_vblank_event(). | ||
957 | */ | ||
958 | void drm_crtc_send_vblank_event(struct drm_crtc *crtc, | ||
959 | struct drm_pending_vblank_event *e) | ||
960 | { | ||
961 | drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e); | ||
962 | } | ||
963 | EXPORT_SYMBOL(drm_crtc_send_vblank_event); | ||
964 | |||
965 | /** | ||
926 | * drm_vblank_enable - enable the vblank interrupt on a CRTC | 966 | * drm_vblank_enable - enable the vblank interrupt on a CRTC |
927 | * @dev: DRM device | 967 | * @dev: DRM device |
928 | * @crtc: CRTC in question | 968 | * @crtc: CRTC in question |
@@ -1594,6 +1634,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) | |||
1594 | * | 1634 | * |
1595 | * Drivers should call this routine in their vblank interrupt handlers to | 1635 | * Drivers should call this routine in their vblank interrupt handlers to |
1596 | * update the vblank counter and send any signals that may be pending. | 1636 | * update the vblank counter and send any signals that may be pending. |
1637 | * | ||
1638 | * This is the legacy version of drm_crtc_handle_vblank(). | ||
1597 | */ | 1639 | */ |
1598 | bool drm_handle_vblank(struct drm_device *dev, int crtc) | 1640 | bool drm_handle_vblank(struct drm_device *dev, int crtc) |
1599 | { | 1641 | { |
@@ -1670,3 +1712,21 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) | |||
1670 | return true; | 1712 | return true; |
1671 | } | 1713 | } |
1672 | EXPORT_SYMBOL(drm_handle_vblank); | 1714 | EXPORT_SYMBOL(drm_handle_vblank); |
1715 | |||
1716 | /** | ||
1717 | * drm_crtc_handle_vblank - handle a vblank event | ||
1718 | * @crtc: where this event occurred | ||
1719 | * | ||
1720 | * Drivers should call this routine in their vblank interrupt handlers to | ||
1721 | * update the vblank counter and send any signals that may be pending. | ||
1722 | * | ||
1723 | * This is the native KMS version of drm_handle_vblank(). | ||
1724 | * | ||
1725 | * Returns: | ||
1726 | * True if the event was successfully handled, false on failure. | ||
1727 | */ | ||
1728 | bool drm_crtc_handle_vblank(struct drm_crtc *crtc) | ||
1729 | { | ||
1730 | return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc)); | ||
1731 | } | ||
1732 | EXPORT_SYMBOL(drm_crtc_handle_vblank); | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 121470a83d1a..1bcbe07cecfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -645,18 +645,6 @@ static int exynos_drm_init(void) | |||
645 | if (!is_exynos) | 645 | if (!is_exynos) |
646 | return -ENODEV; | 646 | return -ENODEV; |
647 | 647 | ||
648 | /* | ||
649 | * Register device object only in case of Exynos SoC. | ||
650 | * | ||
651 | * Below codes resolves temporarily infinite loop issue incurred | ||
652 | * by Exynos drm driver when using multi-platform kernel. | ||
653 | * So these codes will be replaced with more generic way later. | ||
654 | */ | ||
655 | if (!of_machine_is_compatible("samsung,exynos3") && | ||
656 | !of_machine_is_compatible("samsung,exynos4") && | ||
657 | !of_machine_is_compatible("samsung,exynos5")) | ||
658 | return -ENODEV; | ||
659 | |||
660 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, | 648 | exynos_drm_pdev = platform_device_register_simple("exynos-drm", -1, |
661 | NULL, 0); | 649 | NULL, 0); |
662 | if (IS_ERR(exynos_drm_pdev)) | 650 | if (IS_ERR(exynos_drm_pdev)) |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 5765a161abdd..98051e8e855a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -1669,7 +1669,6 @@ static void hdmi_mode_apply(struct hdmi_context *hdata) | |||
1669 | 1669 | ||
1670 | static void hdmiphy_conf_reset(struct hdmi_context *hdata) | 1670 | static void hdmiphy_conf_reset(struct hdmi_context *hdata) |
1671 | { | 1671 | { |
1672 | u8 buffer[2]; | ||
1673 | u32 reg; | 1672 | u32 reg; |
1674 | 1673 | ||
1675 | clk_disable_unprepare(hdata->res.sclk_hdmi); | 1674 | clk_disable_unprepare(hdata->res.sclk_hdmi); |
@@ -1677,11 +1676,8 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata) | |||
1677 | clk_prepare_enable(hdata->res.sclk_hdmi); | 1676 | clk_prepare_enable(hdata->res.sclk_hdmi); |
1678 | 1677 | ||
1679 | /* operation mode */ | 1678 | /* operation mode */ |
1680 | buffer[0] = 0x1f; | 1679 | hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE, |
1681 | buffer[1] = 0x00; | 1680 | HDMI_PHY_ENABLE_MODE_SET); |
1682 | |||
1683 | if (hdata->hdmiphy_port) | ||
1684 | i2c_master_send(hdata->hdmiphy_port, buffer, 2); | ||
1685 | 1681 | ||
1686 | if (hdata->type == HDMI_TYPE13) | 1682 | if (hdata->type == HDMI_TYPE13) |
1687 | reg = HDMI_V13_PHY_RSTOUT; | 1683 | reg = HDMI_V13_PHY_RSTOUT; |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 820b76234ef4..064ed6597def 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -1026,6 +1026,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) | |||
1026 | static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) | 1026 | static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) |
1027 | { | 1027 | { |
1028 | struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); | 1028 | struct mixer_context *mixer_ctx = mgr_to_mixer(mgr); |
1029 | int err; | ||
1029 | 1030 | ||
1030 | mutex_lock(&mixer_ctx->mixer_mutex); | 1031 | mutex_lock(&mixer_ctx->mixer_mutex); |
1031 | if (!mixer_ctx->powered) { | 1032 | if (!mixer_ctx->powered) { |
@@ -1034,7 +1035,11 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) | |||
1034 | } | 1035 | } |
1035 | mutex_unlock(&mixer_ctx->mixer_mutex); | 1036 | mutex_unlock(&mixer_ctx->mixer_mutex); |
1036 | 1037 | ||
1037 | drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); | 1038 | err = drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe); |
1039 | if (err < 0) { | ||
1040 | DRM_DEBUG_KMS("failed to acquire vblank counter\n"); | ||
1041 | return; | ||
1042 | } | ||
1038 | 1043 | ||
1039 | atomic_set(&mixer_ctx->wait_vsync_event, 1); | 1044 | atomic_set(&mixer_ctx->wait_vsync_event, 1); |
1040 | 1045 | ||
@@ -1262,8 +1267,6 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) | |||
1262 | return ret; | 1267 | return ret; |
1263 | } | 1268 | } |
1264 | 1269 | ||
1265 | pm_runtime_enable(dev); | ||
1266 | |||
1267 | return 0; | 1270 | return 0; |
1268 | } | 1271 | } |
1269 | 1272 | ||
@@ -1272,8 +1275,6 @@ static void mixer_unbind(struct device *dev, struct device *master, void *data) | |||
1272 | struct mixer_context *ctx = dev_get_drvdata(dev); | 1275 | struct mixer_context *ctx = dev_get_drvdata(dev); |
1273 | 1276 | ||
1274 | mixer_mgr_remove(&ctx->manager); | 1277 | mixer_mgr_remove(&ctx->manager); |
1275 | |||
1276 | pm_runtime_disable(dev); | ||
1277 | } | 1278 | } |
1278 | 1279 | ||
1279 | static const struct component_ops mixer_component_ops = { | 1280 | static const struct component_ops mixer_component_ops = { |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index d4762799351d..a9041d1a8ff0 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -32,6 +32,8 @@ | |||
32 | struct tda998x_priv { | 32 | struct tda998x_priv { |
33 | struct i2c_client *cec; | 33 | struct i2c_client *cec; |
34 | struct i2c_client *hdmi; | 34 | struct i2c_client *hdmi; |
35 | struct mutex mutex; | ||
36 | struct delayed_work dwork; | ||
35 | uint16_t rev; | 37 | uint16_t rev; |
36 | uint8_t current_page; | 38 | uint8_t current_page; |
37 | int dpms; | 39 | int dpms; |
@@ -402,9 +404,10 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
402 | uint8_t addr = REG2ADDR(reg); | 404 | uint8_t addr = REG2ADDR(reg); |
403 | int ret; | 405 | int ret; |
404 | 406 | ||
407 | mutex_lock(&priv->mutex); | ||
405 | ret = set_page(priv, reg); | 408 | ret = set_page(priv, reg); |
406 | if (ret < 0) | 409 | if (ret < 0) |
407 | return ret; | 410 | goto out; |
408 | 411 | ||
409 | ret = i2c_master_send(client, &addr, sizeof(addr)); | 412 | ret = i2c_master_send(client, &addr, sizeof(addr)); |
410 | if (ret < 0) | 413 | if (ret < 0) |
@@ -414,10 +417,12 @@ reg_read_range(struct tda998x_priv *priv, uint16_t reg, char *buf, int cnt) | |||
414 | if (ret < 0) | 417 | if (ret < 0) |
415 | goto fail; | 418 | goto fail; |
416 | 419 | ||
417 | return ret; | 420 | goto out; |
418 | 421 | ||
419 | fail: | 422 | fail: |
420 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); | 423 | dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); |
424 | out: | ||
425 | mutex_unlock(&priv->mutex); | ||
421 | return ret; | 426 | return ret; |
422 | } | 427 | } |
423 | 428 | ||
@@ -431,13 +436,16 @@ reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) | |||
431 | buf[0] = REG2ADDR(reg); | 436 | buf[0] = REG2ADDR(reg); |
432 | memcpy(&buf[1], p, cnt); | 437 | memcpy(&buf[1], p, cnt); |
433 | 438 | ||
439 | mutex_lock(&priv->mutex); | ||
434 | ret = set_page(priv, reg); | 440 | ret = set_page(priv, reg); |
435 | if (ret < 0) | 441 | if (ret < 0) |
436 | return; | 442 | goto out; |
437 | 443 | ||
438 | ret = i2c_master_send(client, buf, cnt + 1); | 444 | ret = i2c_master_send(client, buf, cnt + 1); |
439 | if (ret < 0) | 445 | if (ret < 0) |
440 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 446 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
447 | out: | ||
448 | mutex_unlock(&priv->mutex); | ||
441 | } | 449 | } |
442 | 450 | ||
443 | static int | 451 | static int |
@@ -459,13 +467,16 @@ reg_write(struct tda998x_priv *priv, uint16_t reg, uint8_t val) | |||
459 | uint8_t buf[] = {REG2ADDR(reg), val}; | 467 | uint8_t buf[] = {REG2ADDR(reg), val}; |
460 | int ret; | 468 | int ret; |
461 | 469 | ||
470 | mutex_lock(&priv->mutex); | ||
462 | ret = set_page(priv, reg); | 471 | ret = set_page(priv, reg); |
463 | if (ret < 0) | 472 | if (ret < 0) |
464 | return; | 473 | goto out; |
465 | 474 | ||
466 | ret = i2c_master_send(client, buf, sizeof(buf)); | 475 | ret = i2c_master_send(client, buf, sizeof(buf)); |
467 | if (ret < 0) | 476 | if (ret < 0) |
468 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 477 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
478 | out: | ||
479 | mutex_unlock(&priv->mutex); | ||
469 | } | 480 | } |
470 | 481 | ||
471 | static void | 482 | static void |
@@ -475,13 +486,16 @@ reg_write16(struct tda998x_priv *priv, uint16_t reg, uint16_t val) | |||
475 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; | 486 | uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; |
476 | int ret; | 487 | int ret; |
477 | 488 | ||
489 | mutex_lock(&priv->mutex); | ||
478 | ret = set_page(priv, reg); | 490 | ret = set_page(priv, reg); |
479 | if (ret < 0) | 491 | if (ret < 0) |
480 | return; | 492 | goto out; |
481 | 493 | ||
482 | ret = i2c_master_send(client, buf, sizeof(buf)); | 494 | ret = i2c_master_send(client, buf, sizeof(buf)); |
483 | if (ret < 0) | 495 | if (ret < 0) |
484 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); | 496 | dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); |
497 | out: | ||
498 | mutex_unlock(&priv->mutex); | ||
485 | } | 499 | } |
486 | 500 | ||
487 | static void | 501 | static void |
@@ -536,6 +550,17 @@ tda998x_reset(struct tda998x_priv *priv) | |||
536 | reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); | 550 | reg_write(priv, REG_MUX_VP_VIP_OUT, 0x24); |
537 | } | 551 | } |
538 | 552 | ||
553 | /* handle HDMI connect/disconnect */ | ||
554 | static void tda998x_hpd(struct work_struct *work) | ||
555 | { | ||
556 | struct delayed_work *dwork = to_delayed_work(work); | ||
557 | struct tda998x_priv *priv = | ||
558 | container_of(dwork, struct tda998x_priv, dwork); | ||
559 | |||
560 | if (priv->encoder && priv->encoder->dev) | ||
561 | drm_kms_helper_hotplug_event(priv->encoder->dev); | ||
562 | } | ||
563 | |||
539 | /* | 564 | /* |
540 | * only 2 interrupts may occur: screen plug/unplug and EDID read | 565 | * only 2 interrupts may occur: screen plug/unplug and EDID read |
541 | */ | 566 | */ |
@@ -559,8 +584,7 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data) | |||
559 | priv->wq_edid_wait = 0; | 584 | priv->wq_edid_wait = 0; |
560 | wake_up(&priv->wq_edid); | 585 | wake_up(&priv->wq_edid); |
561 | } else if (cec != 0) { /* HPD change */ | 586 | } else if (cec != 0) { /* HPD change */ |
562 | if (priv->encoder && priv->encoder->dev) | 587 | schedule_delayed_work(&priv->dwork, HZ/10); |
563 | drm_helper_hpd_irq_event(priv->encoder->dev); | ||
564 | } | 588 | } |
565 | return IRQ_HANDLED; | 589 | return IRQ_HANDLED; |
566 | } | 590 | } |
@@ -1170,8 +1194,10 @@ static void tda998x_destroy(struct tda998x_priv *priv) | |||
1170 | /* disable all IRQs and free the IRQ handler */ | 1194 | /* disable all IRQs and free the IRQ handler */ |
1171 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); | 1195 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); |
1172 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); | 1196 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); |
1173 | if (priv->hdmi->irq) | 1197 | if (priv->hdmi->irq) { |
1174 | free_irq(priv->hdmi->irq, priv); | 1198 | free_irq(priv->hdmi->irq, priv); |
1199 | cancel_delayed_work_sync(&priv->dwork); | ||
1200 | } | ||
1175 | 1201 | ||
1176 | i2c_unregister_device(priv->cec); | 1202 | i2c_unregister_device(priv->cec); |
1177 | } | 1203 | } |
@@ -1255,6 +1281,7 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
1255 | struct device_node *np = client->dev.of_node; | 1281 | struct device_node *np = client->dev.of_node; |
1256 | u32 video; | 1282 | u32 video; |
1257 | int rev_lo, rev_hi, ret; | 1283 | int rev_lo, rev_hi, ret; |
1284 | unsigned short cec_addr; | ||
1258 | 1285 | ||
1259 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); | 1286 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); |
1260 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); | 1287 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
@@ -1262,12 +1289,16 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
1262 | 1289 | ||
1263 | priv->current_page = 0xff; | 1290 | priv->current_page = 0xff; |
1264 | priv->hdmi = client; | 1291 | priv->hdmi = client; |
1265 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1292 | /* CEC I2C address bound to TDA998x I2C addr by configuration pins */ |
1293 | cec_addr = 0x34 + (client->addr & 0x03); | ||
1294 | priv->cec = i2c_new_dummy(client->adapter, cec_addr); | ||
1266 | if (!priv->cec) | 1295 | if (!priv->cec) |
1267 | return -ENODEV; | 1296 | return -ENODEV; |
1268 | 1297 | ||
1269 | priv->dpms = DRM_MODE_DPMS_OFF; | 1298 | priv->dpms = DRM_MODE_DPMS_OFF; |
1270 | 1299 | ||
1300 | mutex_init(&priv->mutex); /* protect the page access */ | ||
1301 | |||
1271 | /* wake up the device: */ | 1302 | /* wake up the device: */ |
1272 | cec_write(priv, REG_CEC_ENAMODS, | 1303 | cec_write(priv, REG_CEC_ENAMODS, |
1273 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); | 1304 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); |
@@ -1323,8 +1354,9 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | |||
1323 | if (client->irq) { | 1354 | if (client->irq) { |
1324 | int irqf_trigger; | 1355 | int irqf_trigger; |
1325 | 1356 | ||
1326 | /* init read EDID waitqueue */ | 1357 | /* init read EDID waitqueue and HDP work */ |
1327 | init_waitqueue_head(&priv->wq_edid); | 1358 | init_waitqueue_head(&priv->wq_edid); |
1359 | INIT_DELAYED_WORK(&priv->dwork, tda998x_hpd); | ||
1328 | 1360 | ||
1329 | /* clear pending interrupts */ | 1361 | /* clear pending interrupts */ |
1330 | reg_read(priv, REG_INT_FLAGS_0); | 1362 | reg_read(priv, REG_INT_FLAGS_0); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f990ab4c3efb..7643300828c3 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -462,19 +462,13 @@ void intel_detect_pch(struct drm_device *dev) | |||
462 | } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { | 462 | } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) { |
463 | dev_priv->pch_type = PCH_LPT; | 463 | dev_priv->pch_type = PCH_LPT; |
464 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); | 464 | DRM_DEBUG_KMS("Found LynxPoint PCH\n"); |
465 | WARN_ON(!IS_HASWELL(dev)); | 465 | WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); |
466 | WARN_ON(IS_HSW_ULT(dev)); | 466 | WARN_ON(IS_HSW_ULT(dev) || IS_BDW_ULT(dev)); |
467 | } else if (IS_BROADWELL(dev)) { | ||
468 | dev_priv->pch_type = PCH_LPT; | ||
469 | dev_priv->pch_id = | ||
470 | INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; | ||
471 | DRM_DEBUG_KMS("This is Broadwell, assuming " | ||
472 | "LynxPoint LP PCH\n"); | ||
473 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { | 467 | } else if (id == INTEL_PCH_LPT_LP_DEVICE_ID_TYPE) { |
474 | dev_priv->pch_type = PCH_LPT; | 468 | dev_priv->pch_type = PCH_LPT; |
475 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); | 469 | DRM_DEBUG_KMS("Found LynxPoint LP PCH\n"); |
476 | WARN_ON(!IS_HASWELL(dev)); | 470 | WARN_ON(!IS_HASWELL(dev) && !IS_BROADWELL(dev)); |
477 | WARN_ON(!IS_HSW_ULT(dev)); | 471 | WARN_ON(!IS_HSW_ULT(dev) && !IS_BDW_ULT(dev)); |
478 | } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { | 472 | } else if (id == INTEL_PCH_SPT_DEVICE_ID_TYPE) { |
479 | dev_priv->pch_type = PCH_SPT; | 473 | dev_priv->pch_type = PCH_SPT; |
480 | DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); | 474 | DRM_DEBUG_KMS("Found SunrisePoint PCH\n"); |
@@ -811,6 +805,8 @@ int i915_reset(struct drm_device *dev) | |||
811 | if (!i915.reset) | 805 | if (!i915.reset) |
812 | return 0; | 806 | return 0; |
813 | 807 | ||
808 | intel_reset_gt_powersave(dev); | ||
809 | |||
814 | mutex_lock(&dev->struct_mutex); | 810 | mutex_lock(&dev->struct_mutex); |
815 | 811 | ||
816 | i915_gem_reset(dev); | 812 | i915_gem_reset(dev); |
@@ -880,7 +876,7 @@ int i915_reset(struct drm_device *dev) | |||
880 | * of re-init after reset. | 876 | * of re-init after reset. |
881 | */ | 877 | */ |
882 | if (INTEL_INFO(dev)->gen > 5) | 878 | if (INTEL_INFO(dev)->gen > 5) |
883 | intel_reset_gt_powersave(dev); | 879 | intel_enable_gt_powersave(dev); |
884 | } else { | 880 | } else { |
885 | mutex_unlock(&dev->struct_mutex); | 881 | mutex_unlock(&dev->struct_mutex); |
886 | } | 882 | } |
@@ -1584,7 +1580,7 @@ static struct drm_driver driver = { | |||
1584 | .gem_prime_import = i915_gem_prime_import, | 1580 | .gem_prime_import = i915_gem_prime_import, |
1585 | 1581 | ||
1586 | .dumb_create = i915_gem_dumb_create, | 1582 | .dumb_create = i915_gem_dumb_create, |
1587 | .dumb_map_offset = i915_gem_dumb_map_offset, | 1583 | .dumb_map_offset = i915_gem_mmap_gtt, |
1588 | .dumb_destroy = drm_gem_dumb_destroy, | 1584 | .dumb_destroy = drm_gem_dumb_destroy, |
1589 | .ioctls = i915_ioctls, | 1585 | .ioctls = i915_ioctls, |
1590 | .fops = &i915_driver_fops, | 1586 | .fops = &i915_driver_fops, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 63bcda5541ec..9d7a7155bf02 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1756,8 +1756,6 @@ struct drm_i915_private { | |||
1756 | */ | 1756 | */ |
1757 | struct workqueue_struct *dp_wq; | 1757 | struct workqueue_struct *dp_wq; |
1758 | 1758 | ||
1759 | uint32_t bios_vgacntr; | ||
1760 | |||
1761 | /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ | 1759 | /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ |
1762 | struct { | 1760 | struct { |
1763 | int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, | 1761 | int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, |
@@ -2161,8 +2159,7 @@ struct drm_i915_cmd_table { | |||
2161 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ | 2159 | #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ |
2162 | (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) | 2160 | (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) |
2163 | #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ | 2161 | #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ |
2164 | ((INTEL_DEVID(dev) & 0xf) == 0x2 || \ | 2162 | ((INTEL_DEVID(dev) & 0xf) == 0x6 || \ |
2165 | (INTEL_DEVID(dev) & 0xf) == 0x6 || \ | ||
2166 | (INTEL_DEVID(dev) & 0xf) == 0xe)) | 2163 | (INTEL_DEVID(dev) & 0xf) == 0xe)) |
2167 | #define IS_BDW_GT3(dev) (IS_BROADWELL(dev) && \ | 2164 | #define IS_BDW_GT3(dev) (IS_BROADWELL(dev) && \ |
2168 | (INTEL_DEVID(dev) & 0x00F0) == 0x0020) | 2165 | (INTEL_DEVID(dev) & 0x00F0) == 0x0020) |
@@ -2501,9 +2498,8 @@ void i915_vma_move_to_active(struct i915_vma *vma, | |||
2501 | int i915_gem_dumb_create(struct drm_file *file_priv, | 2498 | int i915_gem_dumb_create(struct drm_file *file_priv, |
2502 | struct drm_device *dev, | 2499 | struct drm_device *dev, |
2503 | struct drm_mode_create_dumb *args); | 2500 | struct drm_mode_create_dumb *args); |
2504 | int i915_gem_dumb_map_offset(struct drm_file *file_priv, | 2501 | int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, |
2505 | struct drm_device *dev, uint32_t handle, | 2502 | uint32_t handle, uint64_t *offset); |
2506 | uint64_t *offset); | ||
2507 | /** | 2503 | /** |
2508 | * Returns true if seq1 is later than seq2. | 2504 | * Returns true if seq1 is later than seq2. |
2509 | */ | 2505 | */ |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4a9faea626db..5f614828d365 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -401,7 +401,6 @@ static int | |||
401 | i915_gem_create(struct drm_file *file, | 401 | i915_gem_create(struct drm_file *file, |
402 | struct drm_device *dev, | 402 | struct drm_device *dev, |
403 | uint64_t size, | 403 | uint64_t size, |
404 | bool dumb, | ||
405 | uint32_t *handle_p) | 404 | uint32_t *handle_p) |
406 | { | 405 | { |
407 | struct drm_i915_gem_object *obj; | 406 | struct drm_i915_gem_object *obj; |
@@ -417,7 +416,6 @@ i915_gem_create(struct drm_file *file, | |||
417 | if (obj == NULL) | 416 | if (obj == NULL) |
418 | return -ENOMEM; | 417 | return -ENOMEM; |
419 | 418 | ||
420 | obj->base.dumb = dumb; | ||
421 | ret = drm_gem_handle_create(file, &obj->base, &handle); | 419 | ret = drm_gem_handle_create(file, &obj->base, &handle); |
422 | /* drop reference from allocate - handle holds it now */ | 420 | /* drop reference from allocate - handle holds it now */ |
423 | drm_gem_object_unreference_unlocked(&obj->base); | 421 | drm_gem_object_unreference_unlocked(&obj->base); |
@@ -437,7 +435,7 @@ i915_gem_dumb_create(struct drm_file *file, | |||
437 | args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); | 435 | args->pitch = ALIGN(args->width * DIV_ROUND_UP(args->bpp, 8), 64); |
438 | args->size = args->pitch * args->height; | 436 | args->size = args->pitch * args->height; |
439 | return i915_gem_create(file, dev, | 437 | return i915_gem_create(file, dev, |
440 | args->size, true, &args->handle); | 438 | args->size, &args->handle); |
441 | } | 439 | } |
442 | 440 | ||
443 | /** | 441 | /** |
@@ -450,7 +448,7 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, | |||
450 | struct drm_i915_gem_create *args = data; | 448 | struct drm_i915_gem_create *args = data; |
451 | 449 | ||
452 | return i915_gem_create(file, dev, | 450 | return i915_gem_create(file, dev, |
453 | args->size, false, &args->handle); | 451 | args->size, &args->handle); |
454 | } | 452 | } |
455 | 453 | ||
456 | static inline int | 454 | static inline int |
@@ -1050,6 +1048,7 @@ int | |||
1050 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | 1048 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, |
1051 | struct drm_file *file) | 1049 | struct drm_file *file) |
1052 | { | 1050 | { |
1051 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1053 | struct drm_i915_gem_pwrite *args = data; | 1052 | struct drm_i915_gem_pwrite *args = data; |
1054 | struct drm_i915_gem_object *obj; | 1053 | struct drm_i915_gem_object *obj; |
1055 | int ret; | 1054 | int ret; |
@@ -1069,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1069 | return -EFAULT; | 1068 | return -EFAULT; |
1070 | } | 1069 | } |
1071 | 1070 | ||
1071 | intel_runtime_pm_get(dev_priv); | ||
1072 | |||
1072 | ret = i915_mutex_lock_interruptible(dev); | 1073 | ret = i915_mutex_lock_interruptible(dev); |
1073 | if (ret) | 1074 | if (ret) |
1074 | return ret; | 1075 | goto put_rpm; |
1075 | 1076 | ||
1076 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | 1077 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1077 | if (&obj->base == NULL) { | 1078 | if (&obj->base == NULL) { |
@@ -1123,6 +1124,9 @@ out: | |||
1123 | drm_gem_object_unreference(&obj->base); | 1124 | drm_gem_object_unreference(&obj->base); |
1124 | unlock: | 1125 | unlock: |
1125 | mutex_unlock(&dev->struct_mutex); | 1126 | mutex_unlock(&dev->struct_mutex); |
1127 | put_rpm: | ||
1128 | intel_runtime_pm_put(dev_priv); | ||
1129 | |||
1126 | return ret; | 1130 | return ret; |
1127 | } | 1131 | } |
1128 | 1132 | ||
@@ -1840,10 +1844,10 @@ static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) | |||
1840 | drm_gem_free_mmap_offset(&obj->base); | 1844 | drm_gem_free_mmap_offset(&obj->base); |
1841 | } | 1845 | } |
1842 | 1846 | ||
1843 | static int | 1847 | int |
1844 | i915_gem_mmap_gtt(struct drm_file *file, | 1848 | i915_gem_mmap_gtt(struct drm_file *file, |
1845 | struct drm_device *dev, | 1849 | struct drm_device *dev, |
1846 | uint32_t handle, bool dumb, | 1850 | uint32_t handle, |
1847 | uint64_t *offset) | 1851 | uint64_t *offset) |
1848 | { | 1852 | { |
1849 | struct drm_i915_private *dev_priv = dev->dev_private; | 1853 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1860,13 +1864,6 @@ i915_gem_mmap_gtt(struct drm_file *file, | |||
1860 | goto unlock; | 1864 | goto unlock; |
1861 | } | 1865 | } |
1862 | 1866 | ||
1863 | /* | ||
1864 | * We don't allow dumb mmaps on objects created using another | ||
1865 | * interface. | ||
1866 | */ | ||
1867 | WARN_ONCE(dumb && !(obj->base.dumb || obj->base.import_attach), | ||
1868 | "Illegal dumb map of accelerated buffer.\n"); | ||
1869 | |||
1870 | if (obj->base.size > dev_priv->gtt.mappable_end) { | 1867 | if (obj->base.size > dev_priv->gtt.mappable_end) { |
1871 | ret = -E2BIG; | 1868 | ret = -E2BIG; |
1872 | goto out; | 1869 | goto out; |
@@ -1891,15 +1888,6 @@ unlock: | |||
1891 | return ret; | 1888 | return ret; |
1892 | } | 1889 | } |
1893 | 1890 | ||
1894 | int | ||
1895 | i915_gem_dumb_map_offset(struct drm_file *file, | ||
1896 | struct drm_device *dev, | ||
1897 | uint32_t handle, | ||
1898 | uint64_t *offset) | ||
1899 | { | ||
1900 | return i915_gem_mmap_gtt(file, dev, handle, true, offset); | ||
1901 | } | ||
1902 | |||
1903 | /** | 1891 | /** |
1904 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing | 1892 | * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing |
1905 | * @dev: DRM device | 1893 | * @dev: DRM device |
@@ -1921,7 +1909,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1921 | { | 1909 | { |
1922 | struct drm_i915_gem_mmap_gtt *args = data; | 1910 | struct drm_i915_gem_mmap_gtt *args = data; |
1923 | 1911 | ||
1924 | return i915_gem_mmap_gtt(file, dev, args->handle, false, &args->offset); | 1912 | return i915_gem_mmap_gtt(file, dev, args->handle, &args->offset); |
1925 | } | 1913 | } |
1926 | 1914 | ||
1927 | static inline int | 1915 | static inline int |
@@ -3160,6 +3148,13 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg, | |||
3160 | u32 size = i915_gem_obj_ggtt_size(obj); | 3148 | u32 size = i915_gem_obj_ggtt_size(obj); |
3161 | uint64_t val; | 3149 | uint64_t val; |
3162 | 3150 | ||
3151 | /* Adjust fence size to match tiled area */ | ||
3152 | if (obj->tiling_mode != I915_TILING_NONE) { | ||
3153 | uint32_t row_size = obj->stride * | ||
3154 | (obj->tiling_mode == I915_TILING_Y ? 32 : 8); | ||
3155 | size = (size / row_size) * row_size; | ||
3156 | } | ||
3157 | |||
3163 | val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & | 3158 | val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) & |
3164 | 0xfffff000) << 32; | 3159 | 0xfffff000) << 32; |
3165 | val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; | 3160 | val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000; |
@@ -4896,25 +4891,18 @@ i915_gem_init_hw(struct drm_device *dev) | |||
4896 | for (i = 0; i < NUM_L3_SLICES(dev); i++) | 4891 | for (i = 0; i < NUM_L3_SLICES(dev); i++) |
4897 | i915_gem_l3_remap(&dev_priv->ring[RCS], i); | 4892 | i915_gem_l3_remap(&dev_priv->ring[RCS], i); |
4898 | 4893 | ||
4899 | /* | 4894 | ret = i915_ppgtt_init_hw(dev); |
4900 | * XXX: Contexts should only be initialized once. Doing a switch to the | ||
4901 | * default context switch however is something we'd like to do after | ||
4902 | * reset or thaw (the latter may not actually be necessary for HW, but | ||
4903 | * goes with our code better). Context switching requires rings (for | ||
4904 | * the do_switch), but before enabling PPGTT. So don't move this. | ||
4905 | */ | ||
4906 | ret = i915_gem_context_enable(dev_priv); | ||
4907 | if (ret && ret != -EIO) { | 4895 | if (ret && ret != -EIO) { |
4908 | DRM_ERROR("Context enable failed %d\n", ret); | 4896 | DRM_ERROR("PPGTT enable failed %d\n", ret); |
4909 | i915_gem_cleanup_ringbuffer(dev); | 4897 | i915_gem_cleanup_ringbuffer(dev); |
4910 | |||
4911 | return ret; | ||
4912 | } | 4898 | } |
4913 | 4899 | ||
4914 | ret = i915_ppgtt_init_hw(dev); | 4900 | ret = i915_gem_context_enable(dev_priv); |
4915 | if (ret && ret != -EIO) { | 4901 | if (ret && ret != -EIO) { |
4916 | DRM_ERROR("PPGTT enable failed %d\n", ret); | 4902 | DRM_ERROR("Context enable failed %d\n", ret); |
4917 | i915_gem_cleanup_ringbuffer(dev); | 4903 | i915_gem_cleanup_ringbuffer(dev); |
4904 | |||
4905 | return ret; | ||
4918 | } | 4906 | } |
4919 | 4907 | ||
4920 | return ret; | 4908 | return ret; |
@@ -5167,7 +5155,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task) | |||
5167 | if (!mutex_is_locked(mutex)) | 5155 | if (!mutex_is_locked(mutex)) |
5168 | return false; | 5156 | return false; |
5169 | 5157 | ||
5170 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES) | 5158 | #if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) |
5171 | return mutex->owner == task; | 5159 | return mutex->owner == task; |
5172 | #else | 5160 | #else |
5173 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ | 5161 | /* Since UP may be pre-empted, we cannot assume that we own the lock */ |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index d17ff435f276..d011ec82ef1e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -473,7 +473,12 @@ mi_set_context(struct intel_engine_cs *ring, | |||
473 | u32 hw_flags) | 473 | u32 hw_flags) |
474 | { | 474 | { |
475 | u32 flags = hw_flags | MI_MM_SPACE_GTT; | 475 | u32 flags = hw_flags | MI_MM_SPACE_GTT; |
476 | int ret; | 476 | const int num_rings = |
477 | /* Use an extended w/a on ivb+ if signalling from other rings */ | ||
478 | i915_semaphore_is_enabled(ring->dev) ? | ||
479 | hweight32(INTEL_INFO(ring->dev)->ring_mask) - 1 : | ||
480 | 0; | ||
481 | int len, i, ret; | ||
477 | 482 | ||
478 | /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB | 483 | /* w/a: If Flush TLB Invalidation Mode is enabled, driver must do a TLB |
479 | * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value | 484 | * invalidation prior to MI_SET_CONTEXT. On GEN6 we don't set the value |
@@ -490,15 +495,31 @@ mi_set_context(struct intel_engine_cs *ring, | |||
490 | if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8) | 495 | if (!IS_HASWELL(ring->dev) && INTEL_INFO(ring->dev)->gen < 8) |
491 | flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); | 496 | flags |= (MI_SAVE_EXT_STATE_EN | MI_RESTORE_EXT_STATE_EN); |
492 | 497 | ||
493 | ret = intel_ring_begin(ring, 6); | 498 | |
499 | len = 4; | ||
500 | if (INTEL_INFO(ring->dev)->gen >= 7) | ||
501 | len += 2 + (num_rings ? 4*num_rings + 2 : 0); | ||
502 | |||
503 | ret = intel_ring_begin(ring, len); | ||
494 | if (ret) | 504 | if (ret) |
495 | return ret; | 505 | return ret; |
496 | 506 | ||
497 | /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ | 507 | /* WaProgramMiArbOnOffAroundMiSetContext:ivb,vlv,hsw,bdw,chv */ |
498 | if (INTEL_INFO(ring->dev)->gen >= 7) | 508 | if (INTEL_INFO(ring->dev)->gen >= 7) { |
499 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); | 509 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_DISABLE); |
500 | else | 510 | if (num_rings) { |
501 | intel_ring_emit(ring, MI_NOOP); | 511 | struct intel_engine_cs *signaller; |
512 | |||
513 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); | ||
514 | for_each_ring(signaller, to_i915(ring->dev), i) { | ||
515 | if (signaller == ring) | ||
516 | continue; | ||
517 | |||
518 | intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); | ||
519 | intel_ring_emit(ring, _MASKED_BIT_ENABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); | ||
520 | } | ||
521 | } | ||
522 | } | ||
502 | 523 | ||
503 | intel_ring_emit(ring, MI_NOOP); | 524 | intel_ring_emit(ring, MI_NOOP); |
504 | intel_ring_emit(ring, MI_SET_CONTEXT); | 525 | intel_ring_emit(ring, MI_SET_CONTEXT); |
@@ -510,10 +531,21 @@ mi_set_context(struct intel_engine_cs *ring, | |||
510 | */ | 531 | */ |
511 | intel_ring_emit(ring, MI_NOOP); | 532 | intel_ring_emit(ring, MI_NOOP); |
512 | 533 | ||
513 | if (INTEL_INFO(ring->dev)->gen >= 7) | 534 | if (INTEL_INFO(ring->dev)->gen >= 7) { |
535 | if (num_rings) { | ||
536 | struct intel_engine_cs *signaller; | ||
537 | |||
538 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(num_rings)); | ||
539 | for_each_ring(signaller, to_i915(ring->dev), i) { | ||
540 | if (signaller == ring) | ||
541 | continue; | ||
542 | |||
543 | intel_ring_emit(ring, RING_PSMI_CTL(signaller->mmio_base)); | ||
544 | intel_ring_emit(ring, _MASKED_BIT_DISABLE(GEN6_PSMI_SLEEP_MSG_DISABLE)); | ||
545 | } | ||
546 | } | ||
514 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); | 547 | intel_ring_emit(ring, MI_ARB_ON_OFF | MI_ARB_ENABLE); |
515 | else | 548 | } |
516 | intel_ring_emit(ring, MI_NOOP); | ||
517 | 549 | ||
518 | intel_ring_advance(ring); | 550 | intel_ring_advance(ring); |
519 | 551 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f06027ba3ee5..11738316394a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -121,9 +121,6 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
121 | goto err; | 121 | goto err; |
122 | } | 122 | } |
123 | 123 | ||
124 | WARN_ONCE(obj->base.dumb, | ||
125 | "GPU use of dumb buffer is illegal.\n"); | ||
126 | |||
127 | drm_gem_object_reference(&obj->base); | 124 | drm_gem_object_reference(&obj->base); |
128 | list_add_tail(&obj->obj_exec_link, &objects); | 125 | list_add_tail(&obj->obj_exec_link, &objects); |
129 | } | 126 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 981834b0f9b6..b051a238baf9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -281,13 +281,34 @@ void gen6_enable_rps_interrupts(struct drm_device *dev) | |||
281 | struct drm_i915_private *dev_priv = dev->dev_private; | 281 | struct drm_i915_private *dev_priv = dev->dev_private; |
282 | 282 | ||
283 | spin_lock_irq(&dev_priv->irq_lock); | 283 | spin_lock_irq(&dev_priv->irq_lock); |
284 | |||
284 | WARN_ON(dev_priv->rps.pm_iir); | 285 | WARN_ON(dev_priv->rps.pm_iir); |
285 | WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); | 286 | WARN_ON(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); |
286 | dev_priv->rps.interrupts_enabled = true; | 287 | dev_priv->rps.interrupts_enabled = true; |
288 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) | | ||
289 | dev_priv->pm_rps_events); | ||
287 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 290 | gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
291 | |||
288 | spin_unlock_irq(&dev_priv->irq_lock); | 292 | spin_unlock_irq(&dev_priv->irq_lock); |
289 | } | 293 | } |
290 | 294 | ||
295 | u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask) | ||
296 | { | ||
297 | /* | ||
298 | * SNB,IVB can while VLV,CHV may hard hang on looping batchbuffer | ||
299 | * if GEN6_PM_UP_EI_EXPIRED is masked. | ||
300 | * | ||
301 | * TODO: verify if this can be reproduced on VLV,CHV. | ||
302 | */ | ||
303 | if (INTEL_INFO(dev_priv)->gen <= 7 && !IS_HASWELL(dev_priv)) | ||
304 | mask &= ~GEN6_PM_RP_UP_EI_EXPIRED; | ||
305 | |||
306 | if (INTEL_INFO(dev_priv)->gen >= 8) | ||
307 | mask &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP; | ||
308 | |||
309 | return mask; | ||
310 | } | ||
311 | |||
291 | void gen6_disable_rps_interrupts(struct drm_device *dev) | 312 | void gen6_disable_rps_interrupts(struct drm_device *dev) |
292 | { | 313 | { |
293 | struct drm_i915_private *dev_priv = dev->dev_private; | 314 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -300,8 +321,7 @@ void gen6_disable_rps_interrupts(struct drm_device *dev) | |||
300 | 321 | ||
301 | spin_lock_irq(&dev_priv->irq_lock); | 322 | spin_lock_irq(&dev_priv->irq_lock); |
302 | 323 | ||
303 | I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ? | 324 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); |
304 | ~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0); | ||
305 | 325 | ||
306 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 326 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
307 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & | 327 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & |
@@ -3307,8 +3327,10 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev) | |||
3307 | GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); | 3327 | GEN5_IRQ_INIT(GT, dev_priv->gt_irq_mask, gt_irqs); |
3308 | 3328 | ||
3309 | if (INTEL_INFO(dev)->gen >= 6) { | 3329 | if (INTEL_INFO(dev)->gen >= 6) { |
3310 | pm_irqs |= dev_priv->pm_rps_events; | 3330 | /* |
3311 | 3331 | * RPS interrupts will get enabled/disabled on demand when RPS | |
3332 | * itself is enabled/disabled. | ||
3333 | */ | ||
3312 | if (HAS_VEBOX(dev)) | 3334 | if (HAS_VEBOX(dev)) |
3313 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; | 3335 | pm_irqs |= PM_VEBOX_USER_INTERRUPT; |
3314 | 3336 | ||
@@ -3520,7 +3542,11 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) | |||
3520 | dev_priv->pm_irq_mask = 0xffffffff; | 3542 | dev_priv->pm_irq_mask = 0xffffffff; |
3521 | GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); | 3543 | GEN8_IRQ_INIT_NDX(GT, 0, ~gt_interrupts[0], gt_interrupts[0]); |
3522 | GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); | 3544 | GEN8_IRQ_INIT_NDX(GT, 1, ~gt_interrupts[1], gt_interrupts[1]); |
3523 | GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, dev_priv->pm_rps_events); | 3545 | /* |
3546 | * RPS interrupts will get enabled/disabled on demand when RPS itself | ||
3547 | * is enabled/disabled. | ||
3548 | */ | ||
3549 | GEN8_IRQ_INIT_NDX(GT, 2, dev_priv->pm_irq_mask, 0); | ||
3524 | GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); | 3550 | GEN8_IRQ_INIT_NDX(GT, 3, ~gt_interrupts[3], gt_interrupts[3]); |
3525 | } | 3551 | } |
3526 | 3552 | ||
@@ -3609,7 +3635,7 @@ static void vlv_display_irq_uninstall(struct drm_i915_private *dev_priv) | |||
3609 | 3635 | ||
3610 | vlv_display_irq_reset(dev_priv); | 3636 | vlv_display_irq_reset(dev_priv); |
3611 | 3637 | ||
3612 | dev_priv->irq_mask = 0; | 3638 | dev_priv->irq_mask = ~0; |
3613 | } | 3639 | } |
3614 | 3640 | ||
3615 | static void valleyview_irq_uninstall(struct drm_device *dev) | 3641 | static void valleyview_irq_uninstall(struct drm_device *dev) |
@@ -3715,8 +3741,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev, | |||
3715 | if ((iir & flip_pending) == 0) | 3741 | if ((iir & flip_pending) == 0) |
3716 | goto check_page_flip; | 3742 | goto check_page_flip; |
3717 | 3743 | ||
3718 | intel_prepare_page_flip(dev, plane); | ||
3719 | |||
3720 | /* We detect FlipDone by looking for the change in PendingFlip from '1' | 3744 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
3721 | * to '0' on the following vblank, i.e. IIR has the Pendingflip | 3745 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
3722 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence | 3746 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
@@ -3726,6 +3750,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, | |||
3726 | if (I915_READ16(ISR) & flip_pending) | 3750 | if (I915_READ16(ISR) & flip_pending) |
3727 | goto check_page_flip; | 3751 | goto check_page_flip; |
3728 | 3752 | ||
3753 | intel_prepare_page_flip(dev, plane); | ||
3729 | intel_finish_page_flip(dev, pipe); | 3754 | intel_finish_page_flip(dev, pipe); |
3730 | return true; | 3755 | return true; |
3731 | 3756 | ||
@@ -3897,8 +3922,6 @@ static bool i915_handle_vblank(struct drm_device *dev, | |||
3897 | if ((iir & flip_pending) == 0) | 3922 | if ((iir & flip_pending) == 0) |
3898 | goto check_page_flip; | 3923 | goto check_page_flip; |
3899 | 3924 | ||
3900 | intel_prepare_page_flip(dev, plane); | ||
3901 | |||
3902 | /* We detect FlipDone by looking for the change in PendingFlip from '1' | 3925 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
3903 | * to '0' on the following vblank, i.e. IIR has the Pendingflip | 3926 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
3904 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence | 3927 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
@@ -3908,6 +3931,7 @@ static bool i915_handle_vblank(struct drm_device *dev, | |||
3908 | if (I915_READ(ISR) & flip_pending) | 3931 | if (I915_READ(ISR) & flip_pending) |
3909 | goto check_page_flip; | 3932 | goto check_page_flip; |
3910 | 3933 | ||
3934 | intel_prepare_page_flip(dev, plane); | ||
3911 | intel_finish_page_flip(dev, pipe); | 3935 | intel_finish_page_flip(dev, pipe); |
3912 | return true; | 3936 | return true; |
3913 | 3937 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index eefdc238f70b..172de3b3433b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -395,6 +395,7 @@ | |||
395 | #define PIPE_CONTROL_STORE_DATA_INDEX (1<<21) | 395 | #define PIPE_CONTROL_STORE_DATA_INDEX (1<<21) |
396 | #define PIPE_CONTROL_CS_STALL (1<<20) | 396 | #define PIPE_CONTROL_CS_STALL (1<<20) |
397 | #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) | 397 | #define PIPE_CONTROL_TLB_INVALIDATE (1<<18) |
398 | #define PIPE_CONTROL_MEDIA_STATE_CLEAR (1<<16) | ||
398 | #define PIPE_CONTROL_QW_WRITE (1<<14) | 399 | #define PIPE_CONTROL_QW_WRITE (1<<14) |
399 | #define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) | 400 | #define PIPE_CONTROL_POST_SYNC_OP_MASK (3<<14) |
400 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) | 401 | #define PIPE_CONTROL_DEPTH_STALL (1<<13) |
@@ -1128,6 +1129,7 @@ enum punit_power_well { | |||
1128 | #define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) | 1129 | #define GEN6_VERSYNC (RING_SYNC_1(VEBOX_RING_BASE)) |
1129 | #define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) | 1130 | #define GEN6_VEVSYNC (RING_SYNC_2(VEBOX_RING_BASE)) |
1130 | #define GEN6_NOSYNC 0 | 1131 | #define GEN6_NOSYNC 0 |
1132 | #define RING_PSMI_CTL(base) ((base)+0x50) | ||
1131 | #define RING_MAX_IDLE(base) ((base)+0x54) | 1133 | #define RING_MAX_IDLE(base) ((base)+0x54) |
1132 | #define RING_HWS_PGA(base) ((base)+0x80) | 1134 | #define RING_HWS_PGA(base) ((base)+0x80) |
1133 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) | 1135 | #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) |
@@ -1458,6 +1460,7 @@ enum punit_power_well { | |||
1458 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) | 1460 | #define GEN6_BLITTER_FBC_NOTIFY (1<<3) |
1459 | 1461 | ||
1460 | #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 | 1462 | #define GEN6_RC_SLEEP_PSMI_CONTROL 0x2050 |
1463 | #define GEN6_PSMI_SLEEP_MSG_DISABLE (1 << 0) | ||
1461 | #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) | 1464 | #define GEN8_RC_SEMA_IDLE_MSG_DISABLE (1 << 12) |
1462 | #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) | 1465 | #define GEN8_FF_DOP_CLOCK_GATE_DISABLE (1<<10) |
1463 | 1466 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fb3e3d429191..e7a16f119a29 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -9815,7 +9815,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
9815 | if (obj->tiling_mode != work->old_fb_obj->tiling_mode) | 9815 | if (obj->tiling_mode != work->old_fb_obj->tiling_mode) |
9816 | /* vlv: DISPLAY_FLIP fails to change tiling */ | 9816 | /* vlv: DISPLAY_FLIP fails to change tiling */ |
9817 | ring = NULL; | 9817 | ring = NULL; |
9818 | } else if (IS_IVYBRIDGE(dev)) { | 9818 | } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
9819 | ring = &dev_priv->ring[BCS]; | 9819 | ring = &dev_priv->ring[BCS]; |
9820 | } else if (INTEL_INFO(dev)->gen >= 7) { | 9820 | } else if (INTEL_INFO(dev)->gen >= 7) { |
9821 | ring = obj->ring; | 9821 | ring = obj->ring; |
@@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev) | |||
13057 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | 13057 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
13058 | udelay(300); | 13058 | udelay(300); |
13059 | 13059 | ||
13060 | /* | 13060 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
13061 | * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming | ||
13062 | * from S3 without preserving (some of?) the other bits. | ||
13063 | */ | ||
13064 | I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE); | ||
13065 | POSTING_READ(vga_reg); | 13061 | POSTING_READ(vga_reg); |
13066 | } | 13062 | } |
13067 | 13063 | ||
@@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev) | |||
13146 | 13142 | ||
13147 | intel_shared_dpll_init(dev); | 13143 | intel_shared_dpll_init(dev); |
13148 | 13144 | ||
13149 | /* save the BIOS value before clobbering it */ | ||
13150 | dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev)); | ||
13151 | /* Just disable it once at startup */ | 13145 | /* Just disable it once at startup */ |
13152 | i915_disable_vga(dev); | 13146 | i915_disable_vga(dev); |
13153 | intel_setup_outputs(dev); | 13147 | intel_setup_outputs(dev); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 25fdbb16d4e0..3b40a17b8852 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -794,6 +794,7 @@ void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask); | |||
794 | void gen6_reset_rps_interrupts(struct drm_device *dev); | 794 | void gen6_reset_rps_interrupts(struct drm_device *dev); |
795 | void gen6_enable_rps_interrupts(struct drm_device *dev); | 795 | void gen6_enable_rps_interrupts(struct drm_device *dev); |
796 | void gen6_disable_rps_interrupts(struct drm_device *dev); | 796 | void gen6_disable_rps_interrupts(struct drm_device *dev); |
797 | u32 gen6_sanitize_rps_pm_mask(struct drm_i915_private *dev_priv, u32 mask); | ||
797 | void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); | 798 | void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); |
798 | void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); | 799 | void intel_runtime_pm_enable_interrupts(struct drm_i915_private *dev_priv); |
799 | static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) | 800 | static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 4d63839bd9b4..dfb783a8f2c3 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -962,7 +962,7 @@ void intel_panel_enable_backlight(struct intel_connector *connector) | |||
962 | 962 | ||
963 | WARN_ON(panel->backlight.max == 0); | 963 | WARN_ON(panel->backlight.max == 0); |
964 | 964 | ||
965 | if (panel->backlight.level == 0) { | 965 | if (panel->backlight.level <= panel->backlight.min) { |
966 | panel->backlight.level = panel->backlight.max; | 966 | panel->backlight.level = panel->backlight.max; |
967 | if (panel->backlight.device) | 967 | if (panel->backlight.device) |
968 | panel->backlight.device->props.brightness = | 968 | panel->backlight.device->props.brightness = |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1f4b56e273c8..bf814a64582a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -4363,16 +4363,7 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) | |||
4363 | mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); | 4363 | mask |= dev_priv->pm_rps_events & (GEN6_PM_RP_DOWN_EI_EXPIRED | GEN6_PM_RP_UP_EI_EXPIRED); |
4364 | mask &= dev_priv->pm_rps_events; | 4364 | mask &= dev_priv->pm_rps_events; |
4365 | 4365 | ||
4366 | /* IVB and SNB hard hangs on looping batchbuffer | 4366 | return gen6_sanitize_rps_pm_mask(dev_priv, ~mask); |
4367 | * if GEN6_PM_UP_EI_EXPIRED is masked. | ||
4368 | */ | ||
4369 | if (INTEL_INFO(dev_priv->dev)->gen <= 7 && !IS_HASWELL(dev_priv->dev)) | ||
4370 | mask |= GEN6_PM_RP_UP_EI_EXPIRED; | ||
4371 | |||
4372 | if (IS_GEN8(dev_priv->dev)) | ||
4373 | mask |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; | ||
4374 | |||
4375 | return ~mask; | ||
4376 | } | 4367 | } |
4377 | 4368 | ||
4378 | /* gen6_set_rps is called to update the frequency request, but should also be | 4369 | /* gen6_set_rps is called to update the frequency request, but should also be |
@@ -4441,7 +4432,8 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) | |||
4441 | return; | 4432 | return; |
4442 | 4433 | ||
4443 | /* Mask turbo interrupt so that they will not come in between */ | 4434 | /* Mask turbo interrupt so that they will not come in between */ |
4444 | I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); | 4435 | I915_WRITE(GEN6_PMINTRMSK, |
4436 | gen6_sanitize_rps_pm_mask(dev_priv, ~0)); | ||
4445 | 4437 | ||
4446 | vlv_force_gfx_clock(dev_priv, true); | 4438 | vlv_force_gfx_clock(dev_priv, true); |
4447 | 4439 | ||
@@ -6191,6 +6183,20 @@ void intel_cleanup_gt_powersave(struct drm_device *dev) | |||
6191 | valleyview_cleanup_gt_powersave(dev); | 6183 | valleyview_cleanup_gt_powersave(dev); |
6192 | } | 6184 | } |
6193 | 6185 | ||
6186 | static void gen6_suspend_rps(struct drm_device *dev) | ||
6187 | { | ||
6188 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
6189 | |||
6190 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | ||
6191 | |||
6192 | /* | ||
6193 | * TODO: disable RPS interrupts on GEN9+ too once RPS support | ||
6194 | * is added for it. | ||
6195 | */ | ||
6196 | if (INTEL_INFO(dev)->gen < 9) | ||
6197 | gen6_disable_rps_interrupts(dev); | ||
6198 | } | ||
6199 | |||
6194 | /** | 6200 | /** |
6195 | * intel_suspend_gt_powersave - suspend PM work and helper threads | 6201 | * intel_suspend_gt_powersave - suspend PM work and helper threads |
6196 | * @dev: drm device | 6202 | * @dev: drm device |
@@ -6206,14 +6212,7 @@ void intel_suspend_gt_powersave(struct drm_device *dev) | |||
6206 | if (INTEL_INFO(dev)->gen < 6) | 6212 | if (INTEL_INFO(dev)->gen < 6) |
6207 | return; | 6213 | return; |
6208 | 6214 | ||
6209 | flush_delayed_work(&dev_priv->rps.delayed_resume_work); | 6215 | gen6_suspend_rps(dev); |
6210 | |||
6211 | /* | ||
6212 | * TODO: disable RPS interrupts on GEN9+ too once RPS support | ||
6213 | * is added for it. | ||
6214 | */ | ||
6215 | if (INTEL_INFO(dev)->gen < 9) | ||
6216 | gen6_disable_rps_interrupts(dev); | ||
6217 | 6216 | ||
6218 | /* Force GPU to min freq during suspend */ | 6217 | /* Force GPU to min freq during suspend */ |
6219 | gen6_rps_idle(dev_priv); | 6218 | gen6_rps_idle(dev_priv); |
@@ -6316,8 +6315,11 @@ void intel_reset_gt_powersave(struct drm_device *dev) | |||
6316 | { | 6315 | { |
6317 | struct drm_i915_private *dev_priv = dev->dev_private; | 6316 | struct drm_i915_private *dev_priv = dev->dev_private; |
6318 | 6317 | ||
6318 | if (INTEL_INFO(dev)->gen < 6) | ||
6319 | return; | ||
6320 | |||
6321 | gen6_suspend_rps(dev); | ||
6319 | dev_priv->rps.enabled = false; | 6322 | dev_priv->rps.enabled = false; |
6320 | intel_enable_gt_powersave(dev); | ||
6321 | } | 6323 | } |
6322 | 6324 | ||
6323 | static void ibx_init_clock_gating(struct drm_device *dev) | 6325 | static void ibx_init_clock_gating(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9f445e9a75d1..c7bc93d28d84 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -362,12 +362,15 @@ gen7_render_ring_flush(struct intel_engine_cs *ring, | |||
362 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 362 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; |
363 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 363 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; |
364 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | 364 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; |
365 | flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR; | ||
365 | /* | 366 | /* |
366 | * TLB invalidate requires a post-sync write. | 367 | * TLB invalidate requires a post-sync write. |
367 | */ | 368 | */ |
368 | flags |= PIPE_CONTROL_QW_WRITE; | 369 | flags |= PIPE_CONTROL_QW_WRITE; |
369 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; | 370 | flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; |
370 | 371 | ||
372 | flags |= PIPE_CONTROL_STALL_AT_SCOREBOARD; | ||
373 | |||
371 | /* Workaround: we must issue a pipe_control with CS-stall bit | 374 | /* Workaround: we must issue a pipe_control with CS-stall bit |
372 | * set before a pipe_control command that has the state cache | 375 | * set before a pipe_control command that has the state cache |
373 | * invalidate bit set. */ | 376 | * invalidate bit set. */ |
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f5a78d53e297..ac6da7102fbb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, | |||
615 | vlv_power_sequencer_reset(dev_priv); | 615 | vlv_power_sequencer_reset(dev_priv); |
616 | } | 616 | } |
617 | 617 | ||
618 | static void check_power_well_state(struct drm_i915_private *dev_priv, | ||
619 | struct i915_power_well *power_well) | ||
620 | { | ||
621 | bool enabled = power_well->ops->is_enabled(dev_priv, power_well); | ||
622 | |||
623 | if (power_well->always_on || !i915.disable_power_well) { | ||
624 | if (!enabled) | ||
625 | goto mismatch; | ||
626 | |||
627 | return; | ||
628 | } | ||
629 | |||
630 | if (enabled != (power_well->count > 0)) | ||
631 | goto mismatch; | ||
632 | |||
633 | return; | ||
634 | |||
635 | mismatch: | ||
636 | WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", | ||
637 | power_well->name, power_well->always_on, enabled, | ||
638 | power_well->count, i915.disable_power_well); | ||
639 | } | ||
640 | |||
641 | /** | 618 | /** |
642 | * intel_display_power_get - grab a power domain reference | 619 | * intel_display_power_get - grab a power domain reference |
643 | * @dev_priv: i915 device instance | 620 | * @dev_priv: i915 device instance |
@@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
669 | power_well->ops->enable(dev_priv, power_well); | 646 | power_well->ops->enable(dev_priv, power_well); |
670 | power_well->hw_enabled = true; | 647 | power_well->hw_enabled = true; |
671 | } | 648 | } |
672 | |||
673 | check_power_well_state(dev_priv, power_well); | ||
674 | } | 649 | } |
675 | 650 | ||
676 | power_domains->domain_use_count[domain]++; | 651 | power_domains->domain_use_count[domain]++; |
@@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
709 | power_well->hw_enabled = false; | 684 | power_well->hw_enabled = false; |
710 | power_well->ops->disable(dev_priv, power_well); | 685 | power_well->ops->disable(dev_priv, power_well); |
711 | } | 686 | } |
712 | |||
713 | check_power_well_state(dev_priv, power_well); | ||
714 | } | 687 | } |
715 | 688 | ||
716 | mutex_unlock(&power_domains->lock); | 689 | mutex_unlock(&power_domains->lock); |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index aa873048308b..94a5bee69fe7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c | |||
@@ -386,9 +386,7 @@ void adreno_gpu_cleanup(struct adreno_gpu *gpu) | |||
386 | msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); | 386 | msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id); |
387 | drm_gem_object_unreference(gpu->memptrs_bo); | 387 | drm_gem_object_unreference(gpu->memptrs_bo); |
388 | } | 388 | } |
389 | if (gpu->pm4) | 389 | release_firmware(gpu->pm4); |
390 | release_firmware(gpu->pm4); | 390 | release_firmware(gpu->pfp); |
391 | if (gpu->pfp) | ||
392 | release_firmware(gpu->pfp); | ||
393 | msm_gpu_cleanup(&gpu->base); | 391 | msm_gpu_cleanup(&gpu->base); |
394 | } | 392 | } |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index fbebb0405d76..b4e70e0e3cfa 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c | |||
@@ -141,6 +141,15 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) | |||
141 | uint32_t hpd_ctrl; | 141 | uint32_t hpd_ctrl; |
142 | int i, ret; | 142 | int i, ret; |
143 | 143 | ||
144 | for (i = 0; i < config->hpd_reg_cnt; i++) { | ||
145 | ret = regulator_enable(hdmi->hpd_regs[i]); | ||
146 | if (ret) { | ||
147 | dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n", | ||
148 | config->hpd_reg_names[i], ret); | ||
149 | goto fail; | ||
150 | } | ||
151 | } | ||
152 | |||
144 | ret = gpio_config(hdmi, true); | 153 | ret = gpio_config(hdmi, true); |
145 | if (ret) { | 154 | if (ret) { |
146 | dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret); | 155 | dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret); |
@@ -164,15 +173,6 @@ static int hpd_enable(struct hdmi_connector *hdmi_connector) | |||
164 | } | 173 | } |
165 | } | 174 | } |
166 | 175 | ||
167 | for (i = 0; i < config->hpd_reg_cnt; i++) { | ||
168 | ret = regulator_enable(hdmi->hpd_regs[i]); | ||
169 | if (ret) { | ||
170 | dev_err(dev->dev, "failed to enable hpd regulator: %s (%d)\n", | ||
171 | config->hpd_reg_names[i], ret); | ||
172 | goto fail; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | hdmi_set_mode(hdmi, false); | 176 | hdmi_set_mode(hdmi, false); |
177 | phy->funcs->reset(phy); | 177 | phy->funcs->reset(phy); |
178 | hdmi_set_mode(hdmi, true); | 178 | hdmi_set_mode(hdmi, true); |
@@ -200,7 +200,7 @@ fail: | |||
200 | return ret; | 200 | return ret; |
201 | } | 201 | } |
202 | 202 | ||
203 | static int hdp_disable(struct hdmi_connector *hdmi_connector) | 203 | static void hdp_disable(struct hdmi_connector *hdmi_connector) |
204 | { | 204 | { |
205 | struct hdmi *hdmi = hdmi_connector->hdmi; | 205 | struct hdmi *hdmi = hdmi_connector->hdmi; |
206 | const struct hdmi_platform_config *config = hdmi->config; | 206 | const struct hdmi_platform_config *config = hdmi->config; |
@@ -212,28 +212,19 @@ static int hdp_disable(struct hdmi_connector *hdmi_connector) | |||
212 | 212 | ||
213 | hdmi_set_mode(hdmi, false); | 213 | hdmi_set_mode(hdmi, false); |
214 | 214 | ||
215 | for (i = 0; i < config->hpd_reg_cnt; i++) { | ||
216 | ret = regulator_disable(hdmi->hpd_regs[i]); | ||
217 | if (ret) { | ||
218 | dev_err(dev->dev, "failed to disable hpd regulator: %s (%d)\n", | ||
219 | config->hpd_reg_names[i], ret); | ||
220 | goto fail; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | for (i = 0; i < config->hpd_clk_cnt; i++) | 215 | for (i = 0; i < config->hpd_clk_cnt; i++) |
225 | clk_disable_unprepare(hdmi->hpd_clks[i]); | 216 | clk_disable_unprepare(hdmi->hpd_clks[i]); |
226 | 217 | ||
227 | ret = gpio_config(hdmi, false); | 218 | ret = gpio_config(hdmi, false); |
228 | if (ret) { | 219 | if (ret) |
229 | dev_err(dev->dev, "failed to unconfigure GPIOs: %d\n", ret); | 220 | dev_warn(dev->dev, "failed to unconfigure GPIOs: %d\n", ret); |
230 | goto fail; | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | 221 | ||
235 | fail: | 222 | for (i = 0; i < config->hpd_reg_cnt; i++) { |
236 | return ret; | 223 | ret = regulator_disable(hdmi->hpd_regs[i]); |
224 | if (ret) | ||
225 | dev_warn(dev->dev, "failed to disable hpd regulator: %s (%d)\n", | ||
226 | config->hpd_reg_names[i], ret); | ||
227 | } | ||
237 | } | 228 | } |
238 | 229 | ||
239 | static void | 230 | static void |
@@ -260,11 +251,11 @@ void hdmi_connector_irq(struct drm_connector *connector) | |||
260 | (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) { | 251 | (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) { |
261 | bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED); | 252 | bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED); |
262 | 253 | ||
263 | DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); | 254 | /* ack & disable (temporarily) HPD events: */ |
264 | |||
265 | /* ack the irq: */ | ||
266 | hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, | 255 | hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, |
267 | hpd_int_ctrl | HDMI_HPD_INT_CTRL_INT_ACK); | 256 | HDMI_HPD_INT_CTRL_INT_ACK); |
257 | |||
258 | DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); | ||
268 | 259 | ||
269 | /* detect disconnect if we are connected or visa versa: */ | 260 | /* detect disconnect if we are connected or visa versa: */ |
270 | hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN; | 261 | hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index a7672e100d8b..3449213f1e76 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
@@ -331,17 +331,8 @@ static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, | |||
331 | struct drm_crtc_state *state) | 331 | struct drm_crtc_state *state) |
332 | { | 332 | { |
333 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 333 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
334 | struct drm_device *dev = crtc->dev; | ||
335 | |||
336 | DBG("%s: check", mdp4_crtc->name); | 334 | DBG("%s: check", mdp4_crtc->name); |
337 | |||
338 | if (mdp4_crtc->event) { | ||
339 | dev_err(dev->dev, "already pending flip!\n"); | ||
340 | return -EBUSY; | ||
341 | } | ||
342 | |||
343 | // TODO anything else to check? | 335 | // TODO anything else to check? |
344 | |||
345 | return 0; | 336 | return 0; |
346 | } | 337 | } |
347 | 338 | ||
@@ -357,7 +348,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc) | |||
357 | struct drm_device *dev = crtc->dev; | 348 | struct drm_device *dev = crtc->dev; |
358 | unsigned long flags; | 349 | unsigned long flags; |
359 | 350 | ||
360 | DBG("%s: flush", mdp4_crtc->name); | 351 | DBG("%s: event: %p", mdp4_crtc->name, crtc->state->event); |
361 | 352 | ||
362 | WARN_ON(mdp4_crtc->event); | 353 | WARN_ON(mdp4_crtc->event); |
363 | 354 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 0e9a2e3a82d7..f021f960a8a2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
@@ -303,11 +303,6 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc, | |||
303 | 303 | ||
304 | DBG("%s: check", mdp5_crtc->name); | 304 | DBG("%s: check", mdp5_crtc->name); |
305 | 305 | ||
306 | if (mdp5_crtc->event) { | ||
307 | dev_err(dev->dev, "already pending flip!\n"); | ||
308 | return -EBUSY; | ||
309 | } | ||
310 | |||
311 | /* request a free CTL, if none is already allocated for this CRTC */ | 306 | /* request a free CTL, if none is already allocated for this CRTC */ |
312 | if (state->enable && !mdp5_crtc->ctl) { | 307 | if (state->enable && !mdp5_crtc->ctl) { |
313 | mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); | 308 | mdp5_crtc->ctl = mdp5_ctlm_request(mdp5_kms->ctlm, crtc); |
@@ -364,7 +359,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc) | |||
364 | struct drm_device *dev = crtc->dev; | 359 | struct drm_device *dev = crtc->dev; |
365 | unsigned long flags; | 360 | unsigned long flags; |
366 | 361 | ||
367 | DBG("%s: flush", mdp5_crtc->name); | 362 | DBG("%s: event: %p", mdp5_crtc->name, crtc->state->event); |
368 | 363 | ||
369 | WARN_ON(mdp5_crtc->event); | 364 | WARN_ON(mdp5_crtc->event); |
370 | 365 | ||
@@ -460,10 +455,7 @@ void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, | |||
460 | /* now that we know what irq's we want: */ | 455 | /* now that we know what irq's we want: */ |
461 | mdp5_crtc->err.irqmask = intf2err(intf); | 456 | mdp5_crtc->err.irqmask = intf2err(intf); |
462 | mdp5_crtc->vblank.irqmask = intf2vblank(intf); | 457 | mdp5_crtc->vblank.irqmask = intf2vblank(intf); |
463 | 458 | mdp_irq_update(&mdp5_kms->base); | |
464 | /* when called from modeset_init(), skip the rest until later: */ | ||
465 | if (!mdp5_kms) | ||
466 | return; | ||
467 | 459 | ||
468 | spin_lock_irqsave(&mdp5_kms->resource_lock, flags); | 460 | spin_lock_irqsave(&mdp5_kms->resource_lock, flags); |
469 | intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL); | 461 | intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index a11f1b80c488..9f01a4f21af2 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
@@ -216,17 +216,7 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) | |||
216 | goto fail; | 216 | goto fail; |
217 | } | 217 | } |
218 | 218 | ||
219 | /* NOTE: the vsync and error irq's are actually associated with | 219 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; |
220 | * the INTF/encoder.. the easiest way to deal with this (ie. what | ||
221 | * we do now) is assume a fixed relationship between crtc's and | ||
222 | * encoders. I'm not sure if there is ever a need to more freely | ||
223 | * assign crtcs to encoders, but if there is then we need to take | ||
224 | * care of error and vblank irq's that the crtc has registered, | ||
225 | * and also update user-requested vblank_mask. | ||
226 | */ | ||
227 | encoder->possible_crtcs = BIT(0); | ||
228 | mdp5_crtc_set_intf(priv->crtcs[0], 3, INTF_HDMI); | ||
229 | |||
230 | priv->encoders[priv->num_encoders++] = encoder; | 220 | priv->encoders[priv->num_encoders++] = encoder; |
231 | 221 | ||
232 | /* Construct bridge/connector for HDMI: */ | 222 | /* Construct bridge/connector for HDMI: */ |
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.c b/drivers/gpu/drm/msm/mdp/mdp_kms.c index 03455b64a245..2a731722d840 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.c | |||
@@ -42,7 +42,10 @@ static void update_irq(struct mdp_kms *mdp_kms) | |||
42 | mdp_kms->funcs->set_irqmask(mdp_kms, irqmask); | 42 | mdp_kms->funcs->set_irqmask(mdp_kms, irqmask); |
43 | } | 43 | } |
44 | 44 | ||
45 | static void update_irq_unlocked(struct mdp_kms *mdp_kms) | 45 | /* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder |
46 | * link changes, this must be called to figure out the new global irqmask | ||
47 | */ | ||
48 | void mdp_irq_update(struct mdp_kms *mdp_kms) | ||
46 | { | 49 | { |
47 | unsigned long flags; | 50 | unsigned long flags; |
48 | spin_lock_irqsave(&list_lock, flags); | 51 | spin_lock_irqsave(&list_lock, flags); |
@@ -122,7 +125,7 @@ void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq) | |||
122 | spin_unlock_irqrestore(&list_lock, flags); | 125 | spin_unlock_irqrestore(&list_lock, flags); |
123 | 126 | ||
124 | if (needs_update) | 127 | if (needs_update) |
125 | update_irq_unlocked(mdp_kms); | 128 | mdp_irq_update(mdp_kms); |
126 | } | 129 | } |
127 | 130 | ||
128 | void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq) | 131 | void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq) |
@@ -141,5 +144,5 @@ void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq) | |||
141 | spin_unlock_irqrestore(&list_lock, flags); | 144 | spin_unlock_irqrestore(&list_lock, flags); |
142 | 145 | ||
143 | if (needs_update) | 146 | if (needs_update) |
144 | update_irq_unlocked(mdp_kms); | 147 | mdp_irq_update(mdp_kms); |
145 | } | 148 | } |
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.h b/drivers/gpu/drm/msm/mdp/mdp_kms.h index 99557b5ad4fd..b268ce95d394 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.h | |||
@@ -75,7 +75,7 @@ void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable) | |||
75 | void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask); | 75 | void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask); |
76 | void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq); | 76 | void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq); |
77 | void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq); | 77 | void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq); |
78 | 78 | void mdp_irq_update(struct mdp_kms *mdp_kms); | |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * pixel format helpers: | 81 | * pixel format helpers: |
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index f0de412e13dc..191968256c58 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
@@ -23,10 +23,41 @@ struct msm_commit { | |||
23 | struct drm_atomic_state *state; | 23 | struct drm_atomic_state *state; |
24 | uint32_t fence; | 24 | uint32_t fence; |
25 | struct msm_fence_cb fence_cb; | 25 | struct msm_fence_cb fence_cb; |
26 | uint32_t crtc_mask; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | static void fence_cb(struct msm_fence_cb *cb); | 29 | static void fence_cb(struct msm_fence_cb *cb); |
29 | 30 | ||
31 | /* block until specified crtcs are no longer pending update, and | ||
32 | * atomically mark them as pending update | ||
33 | */ | ||
34 | static int start_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) | ||
35 | { | ||
36 | int ret; | ||
37 | |||
38 | spin_lock(&priv->pending_crtcs_event.lock); | ||
39 | ret = wait_event_interruptible_locked(priv->pending_crtcs_event, | ||
40 | !(priv->pending_crtcs & crtc_mask)); | ||
41 | if (ret == 0) { | ||
42 | DBG("start: %08x", crtc_mask); | ||
43 | priv->pending_crtcs |= crtc_mask; | ||
44 | } | ||
45 | spin_unlock(&priv->pending_crtcs_event.lock); | ||
46 | |||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | /* clear specified crtcs (no longer pending update) | ||
51 | */ | ||
52 | static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) | ||
53 | { | ||
54 | spin_lock(&priv->pending_crtcs_event.lock); | ||
55 | DBG("end: %08x", crtc_mask); | ||
56 | priv->pending_crtcs &= ~crtc_mask; | ||
57 | wake_up_all_locked(&priv->pending_crtcs_event); | ||
58 | spin_unlock(&priv->pending_crtcs_event.lock); | ||
59 | } | ||
60 | |||
30 | static struct msm_commit *new_commit(struct drm_atomic_state *state) | 61 | static struct msm_commit *new_commit(struct drm_atomic_state *state) |
31 | { | 62 | { |
32 | struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); | 63 | struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); |
@@ -58,12 +89,27 @@ static void complete_commit(struct msm_commit *c) | |||
58 | 89 | ||
59 | drm_atomic_helper_commit_post_planes(dev, state); | 90 | drm_atomic_helper_commit_post_planes(dev, state); |
60 | 91 | ||
92 | /* NOTE: _wait_for_vblanks() only waits for vblank on | ||
93 | * enabled CRTCs. So we end up faulting when disabling | ||
94 | * due to (potentially) unref'ing the outgoing fb's | ||
95 | * before the vblank when the disable has latched. | ||
96 | * | ||
97 | * But if it did wait on disabled (or newly disabled) | ||
98 | * CRTCs, that would be racy (ie. we could have missed | ||
99 | * the irq. We need some way to poll for pipe shut | ||
100 | * down. Or just live with occasionally hitting the | ||
101 | * timeout in the CRTC disable path (which really should | ||
102 | * not be critical path) | ||
103 | */ | ||
104 | |||
61 | drm_atomic_helper_wait_for_vblanks(dev, state); | 105 | drm_atomic_helper_wait_for_vblanks(dev, state); |
62 | 106 | ||
63 | drm_atomic_helper_cleanup_planes(dev, state); | 107 | drm_atomic_helper_cleanup_planes(dev, state); |
64 | 108 | ||
65 | drm_atomic_state_free(state); | 109 | drm_atomic_state_free(state); |
66 | 110 | ||
111 | end_atomic(dev->dev_private, c->crtc_mask); | ||
112 | |||
67 | kfree(c); | 113 | kfree(c); |
68 | } | 114 | } |
69 | 115 | ||
@@ -97,8 +143,9 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb) | |||
97 | int msm_atomic_commit(struct drm_device *dev, | 143 | int msm_atomic_commit(struct drm_device *dev, |
98 | struct drm_atomic_state *state, bool async) | 144 | struct drm_atomic_state *state, bool async) |
99 | { | 145 | { |
100 | struct msm_commit *c; | ||
101 | int nplanes = dev->mode_config.num_total_plane; | 146 | int nplanes = dev->mode_config.num_total_plane; |
147 | int ncrtcs = dev->mode_config.num_crtc; | ||
148 | struct msm_commit *c; | ||
102 | int i, ret; | 149 | int i, ret; |
103 | 150 | ||
104 | ret = drm_atomic_helper_prepare_planes(dev, state); | 151 | ret = drm_atomic_helper_prepare_planes(dev, state); |
@@ -106,6 +153,18 @@ int msm_atomic_commit(struct drm_device *dev, | |||
106 | return ret; | 153 | return ret; |
107 | 154 | ||
108 | c = new_commit(state); | 155 | c = new_commit(state); |
156 | if (!c) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | /* | ||
160 | * Figure out what crtcs we have: | ||
161 | */ | ||
162 | for (i = 0; i < ncrtcs; i++) { | ||
163 | struct drm_crtc *crtc = state->crtcs[i]; | ||
164 | if (!crtc) | ||
165 | continue; | ||
166 | c->crtc_mask |= (1 << drm_crtc_index(crtc)); | ||
167 | } | ||
109 | 168 | ||
110 | /* | 169 | /* |
111 | * Figure out what fence to wait for: | 170 | * Figure out what fence to wait for: |
@@ -122,6 +181,14 @@ int msm_atomic_commit(struct drm_device *dev, | |||
122 | } | 181 | } |
123 | 182 | ||
124 | /* | 183 | /* |
184 | * Wait for pending updates on any of the same crtc's and then | ||
185 | * mark our set of crtc's as busy: | ||
186 | */ | ||
187 | ret = start_atomic(dev->dev_private, c->crtc_mask); | ||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | /* | ||
125 | * This is the point of no return - everything below never fails except | 192 | * This is the point of no return - everything below never fails except |
126 | * when the hw goes bonghits. Which means we can commit the new state on | 193 | * when the hw goes bonghits. Which means we can commit the new state on |
127 | * the software side now. | 194 | * the software side now. |
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c795217e1bfc..9a61546a0b05 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -193,6 +193,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags) | |||
193 | 193 | ||
194 | priv->wq = alloc_ordered_workqueue("msm", 0); | 194 | priv->wq = alloc_ordered_workqueue("msm", 0); |
195 | init_waitqueue_head(&priv->fence_event); | 195 | init_waitqueue_head(&priv->fence_event); |
196 | init_waitqueue_head(&priv->pending_crtcs_event); | ||
196 | 197 | ||
197 | INIT_LIST_HEAD(&priv->inactive_list); | 198 | INIT_LIST_HEAD(&priv->inactive_list); |
198 | INIT_LIST_HEAD(&priv->fence_cbs); | 199 | INIT_LIST_HEAD(&priv->fence_cbs); |
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 136303818436..b69ef2d5a26c 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h | |||
@@ -96,6 +96,10 @@ struct msm_drm_private { | |||
96 | /* callbacks deferred until bo is inactive: */ | 96 | /* callbacks deferred until bo is inactive: */ |
97 | struct list_head fence_cbs; | 97 | struct list_head fence_cbs; |
98 | 98 | ||
99 | /* crtcs pending async atomic updates: */ | ||
100 | uint32_t pending_crtcs; | ||
101 | wait_queue_head_t pending_crtcs_event; | ||
102 | |||
99 | /* registered MMUs: */ | 103 | /* registered MMUs: */ |
100 | unsigned int num_mmus; | 104 | unsigned int num_mmus; |
101 | struct msm_mmu *mmus[NUM_DOMAINS]; | 105 | struct msm_mmu *mmus[NUM_DOMAINS]; |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 94d55e526b4e..1f3af13ccede 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
@@ -190,8 +190,7 @@ fail_unlock: | |||
190 | fail: | 190 | fail: |
191 | 191 | ||
192 | if (ret) { | 192 | if (ret) { |
193 | if (fbi) | 193 | framebuffer_release(fbi); |
194 | framebuffer_release(fbi); | ||
195 | if (fb) { | 194 | if (fb) { |
196 | drm_framebuffer_unregister_private(fb); | 195 | drm_framebuffer_unregister_private(fb); |
197 | drm_framebuffer_remove(fb); | 196 | drm_framebuffer_remove(fb); |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 4a6f0e49d5b5..49dea4fb55ac 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
@@ -535,8 +535,7 @@ void msm_gem_free_object(struct drm_gem_object *obj) | |||
535 | drm_free_large(msm_obj->pages); | 535 | drm_free_large(msm_obj->pages); |
536 | 536 | ||
537 | } else { | 537 | } else { |
538 | if (msm_obj->vaddr) | 538 | vunmap(msm_obj->vaddr); |
539 | vunmap(msm_obj->vaddr); | ||
540 | put_pages(obj); | 539 | put_pages(obj); |
541 | } | 540 | } |
542 | 541 | ||
diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index ff2b434b3db4..760947e380c9 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c | |||
@@ -26,7 +26,7 @@ | |||
26 | void | 26 | void |
27 | nvkm_event_put(struct nvkm_event *event, u32 types, int index) | 27 | nvkm_event_put(struct nvkm_event *event, u32 types, int index) |
28 | { | 28 | { |
29 | BUG_ON(!spin_is_locked(&event->refs_lock)); | 29 | assert_spin_locked(&event->refs_lock); |
30 | while (types) { | 30 | while (types) { |
31 | int type = __ffs(types); types &= ~(1 << type); | 31 | int type = __ffs(types); types &= ~(1 << type); |
32 | if (--event->refs[index * event->types_nr + type] == 0) { | 32 | if (--event->refs[index * event->types_nr + type] == 0) { |
@@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index) | |||
39 | void | 39 | void |
40 | nvkm_event_get(struct nvkm_event *event, u32 types, int index) | 40 | nvkm_event_get(struct nvkm_event *event, u32 types, int index) |
41 | { | 41 | { |
42 | BUG_ON(!spin_is_locked(&event->refs_lock)); | 42 | assert_spin_locked(&event->refs_lock); |
43 | while (types) { | 43 | while (types) { |
44 | int type = __ffs(types); types &= ~(1 << type); | 44 | int type = __ffs(types); types &= ~(1 << type); |
45 | if (++event->refs[index * event->types_nr + type] == 1) { | 45 | if (++event->refs[index * event->types_nr + type] == 1) { |
diff --git a/drivers/gpu/drm/nouveau/core/core/notify.c b/drivers/gpu/drm/nouveau/core/core/notify.c index d1bcde55e9d7..839a32577680 100644 --- a/drivers/gpu/drm/nouveau/core/core/notify.c +++ b/drivers/gpu/drm/nouveau/core/core/notify.c | |||
@@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size) | |||
98 | struct nvkm_event *event = notify->event; | 98 | struct nvkm_event *event = notify->event; |
99 | unsigned long flags; | 99 | unsigned long flags; |
100 | 100 | ||
101 | BUG_ON(!spin_is_locked(&event->list_lock)); | 101 | assert_spin_locked(&event->list_lock); |
102 | BUG_ON(size != notify->size); | 102 | BUG_ON(size != notify->size); |
103 | 103 | ||
104 | spin_lock_irqsave(&event->refs_lock, flags); | 104 | spin_lock_irqsave(&event->refs_lock, flags); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 674da1f095b2..732922690653 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c | |||
@@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device) | |||
249 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 249 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
250 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; | 250 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; |
251 | break; | 251 | break; |
252 | case 0x106: | ||
253 | device->cname = "GK208B"; | ||
254 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | ||
255 | device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; | ||
256 | device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; | ||
257 | device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass; | ||
258 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; | ||
259 | device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; | ||
260 | device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | ||
261 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass; | ||
262 | device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; | ||
263 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | ||
264 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | ||
265 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | ||
266 | device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; | ||
267 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | ||
268 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | ||
269 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | ||
270 | device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; | ||
271 | device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; | ||
272 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | ||
273 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; | ||
274 | device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; | ||
275 | device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; | ||
276 | device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; | ||
277 | device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass; | ||
278 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; | ||
279 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; | ||
280 | device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; | ||
281 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | ||
282 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | ||
283 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | ||
284 | break; | ||
252 | case 0x108: | 285 | case 0x108: |
253 | device->cname = "GK208"; | 286 | device->cname = "GK208"; |
254 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | 287 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c index 5e58bba0dd5c..a7a890fad1e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c | |||
@@ -44,8 +44,10 @@ static void | |||
44 | pramin_fini(void *data) | 44 | pramin_fini(void *data) |
45 | { | 45 | { |
46 | struct priv *priv = data; | 46 | struct priv *priv = data; |
47 | nv_wr32(priv->bios, 0x001700, priv->bar0); | 47 | if (priv) { |
48 | kfree(priv); | 48 | nv_wr32(priv->bios, 0x001700, priv->bar0); |
49 | kfree(priv); | ||
50 | } | ||
49 | } | 51 | } |
50 | 52 | ||
51 | static void * | 53 | static void * |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c index 00f2ca7e44a5..033a8e999497 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c | |||
@@ -24,34 +24,71 @@ | |||
24 | 24 | ||
25 | #include "nv50.h" | 25 | #include "nv50.h" |
26 | 26 | ||
27 | struct nvaa_ram_priv { | ||
28 | struct nouveau_ram base; | ||
29 | u64 poller_base; | ||
30 | }; | ||
31 | |||
27 | static int | 32 | static int |
28 | nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 33 | nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
29 | struct nouveau_oclass *oclass, void *data, u32 datasize, | 34 | struct nouveau_oclass *oclass, void *data, u32 datasize, |
30 | struct nouveau_object **pobject) | 35 | struct nouveau_object **pobject) |
31 | { | 36 | { |
32 | const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ | 37 | u32 rsvd_head = ( 256 * 1024); /* vga memory */ |
33 | const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ | 38 | u32 rsvd_tail = (1024 * 1024); /* vbios etc */ |
34 | struct nouveau_fb *pfb = nouveau_fb(parent); | 39 | struct nouveau_fb *pfb = nouveau_fb(parent); |
35 | struct nouveau_ram *ram; | 40 | struct nvaa_ram_priv *priv; |
36 | int ret; | 41 | int ret; |
37 | 42 | ||
38 | ret = nouveau_ram_create(parent, engine, oclass, &ram); | 43 | ret = nouveau_ram_create(parent, engine, oclass, &priv); |
39 | *pobject = nv_object(ram); | 44 | *pobject = nv_object(priv); |
40 | if (ret) | 45 | if (ret) |
41 | return ret; | 46 | return ret; |
42 | 47 | ||
43 | ram->size = nv_rd32(pfb, 0x10020c); | 48 | priv->base.type = NV_MEM_TYPE_STOLEN; |
44 | ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); | 49 | priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; |
50 | priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12; | ||
45 | 51 | ||
46 | ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - | 52 | rsvd_tail += 0x1000; |
47 | (rsvd_head + rsvd_tail), 1); | 53 | priv->poller_base = priv->base.size - rsvd_tail; |
54 | |||
55 | ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12, | ||
56 | (priv->base.size - (rsvd_head + rsvd_tail)) >> 12, | ||
57 | 1); | ||
48 | if (ret) | 58 | if (ret) |
49 | return ret; | 59 | return ret; |
50 | 60 | ||
51 | ram->type = NV_MEM_TYPE_STOLEN; | 61 | priv->base.get = nv50_ram_get; |
52 | ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; | 62 | priv->base.put = nv50_ram_put; |
53 | ram->get = nv50_ram_get; | 63 | return 0; |
54 | ram->put = nv50_ram_put; | 64 | } |
65 | |||
66 | static int | ||
67 | nvaa_ram_init(struct nouveau_object *object) | ||
68 | { | ||
69 | struct nouveau_fb *pfb = nouveau_fb(object); | ||
70 | struct nvaa_ram_priv *priv = (void *)object; | ||
71 | int ret; | ||
72 | u64 dniso, hostnb, flush; | ||
73 | |||
74 | ret = nouveau_ram_init(&priv->base); | ||
75 | if (ret) | ||
76 | return ret; | ||
77 | |||
78 | dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1; | ||
79 | hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1; | ||
80 | flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1; | ||
81 | |||
82 | /* Enable NISO poller for various clients and set their associated | ||
83 | * read address, only for MCP77/78 and MCP79/7A. (fd#25701) | ||
84 | */ | ||
85 | nv_wr32(pfb, 0x100c18, dniso); | ||
86 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001); | ||
87 | nv_wr32(pfb, 0x100c1c, hostnb); | ||
88 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002); | ||
89 | nv_wr32(pfb, 0x100c24, flush); | ||
90 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000); | ||
91 | |||
55 | return 0; | 92 | return 0; |
56 | } | 93 | } |
57 | 94 | ||
@@ -60,7 +97,7 @@ nvaa_ram_oclass = { | |||
60 | .ofuncs = &(struct nouveau_ofuncs) { | 97 | .ofuncs = &(struct nouveau_ofuncs) { |
61 | .ctor = nvaa_ram_ctor, | 98 | .ctor = nvaa_ram_ctor, |
62 | .dtor = _nouveau_ram_dtor, | 99 | .dtor = _nouveau_ram_dtor, |
63 | .init = _nouveau_ram_init, | 100 | .init = nvaa_ram_init, |
64 | .fini = _nouveau_ram_fini, | 101 | .fini = _nouveau_ram_fini, |
65 | }, | 102 | }, |
66 | }; | 103 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c index a75c35ccf25c..165401c4045c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c | |||
@@ -24,13 +24,6 @@ | |||
24 | 24 | ||
25 | #include "nv04.h" | 25 | #include "nv04.h" |
26 | 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 * | 27 | struct nouveau_oclass * |
35 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | 28 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { |
36 | .base.handle = NV_SUBDEV(MC, 0x4c), | 29 | .base.handle = NV_SUBDEV(MC, 0x4c), |
@@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | |||
41 | .fini = _nouveau_mc_fini, | 34 | .fini = _nouveau_mc_fini, |
42 | }, | 35 | }, |
43 | .intr = nv04_mc_intr, | 36 | .intr = nv04_mc_intr, |
44 | .msi_rearm = nv4c_mc_msi_rearm, | ||
45 | }.base; | 37 | }.base; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 21ec561edc99..bba2960d3dfb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1572 | * so use the DMA API for them. | 1572 | * so use the DMA API for them. |
1573 | */ | 1573 | */ |
1574 | if (!nv_device_is_cpu_coherent(device) && | 1574 | if (!nv_device_is_cpu_coherent(device) && |
1575 | ttm->caching_state == tt_uncached) | 1575 | ttm->caching_state == tt_uncached) { |
1576 | ttm_dma_unpopulate(ttm_dma, dev->dev); | 1576 | ttm_dma_unpopulate(ttm_dma, dev->dev); |
1577 | return; | ||
1578 | } | ||
1577 | 1579 | ||
1578 | #if __OS_HAS_AGP | 1580 | #if __OS_HAS_AGP |
1579 | if (drm->agp.stat == ENABLED) { | 1581 | if (drm->agp.stat == ENABLED) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 5d93902a91ab..f8042433752b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -876,7 +876,6 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, | |||
876 | if (ret) | 876 | if (ret) |
877 | return ret; | 877 | return ret; |
878 | 878 | ||
879 | bo->gem.dumb = true; | ||
880 | ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); | 879 | ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); |
881 | drm_gem_object_unreference_unlocked(&bo->gem); | 880 | drm_gem_object_unreference_unlocked(&bo->gem); |
882 | return ret; | 881 | return ret; |
@@ -892,14 +891,6 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, | |||
892 | gem = drm_gem_object_lookup(dev, file_priv, handle); | 891 | gem = drm_gem_object_lookup(dev, file_priv, handle); |
893 | if (gem) { | 892 | if (gem) { |
894 | struct nouveau_bo *bo = nouveau_gem_object(gem); | 893 | struct nouveau_bo *bo = nouveau_gem_object(gem); |
895 | |||
896 | /* | ||
897 | * We don't allow dumb mmaps on objects created using another | ||
898 | * interface. | ||
899 | */ | ||
900 | WARN_ONCE(!(gem->dumb || gem->import_attach), | ||
901 | "Illegal dumb map of accelerated buffer.\n"); | ||
902 | |||
903 | *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); | 894 | *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); |
904 | drm_gem_object_unreference_unlocked(gem); | 895 | drm_gem_object_unreference_unlocked(gem); |
905 | return 0; | 896 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 28d51a22a4bf..bf0f9e21d714 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -36,7 +36,14 @@ void | |||
36 | nouveau_gem_object_del(struct drm_gem_object *gem) | 36 | nouveau_gem_object_del(struct drm_gem_object *gem) |
37 | { | 37 | { |
38 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 38 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
39 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
39 | struct ttm_buffer_object *bo = &nvbo->bo; | 40 | struct ttm_buffer_object *bo = &nvbo->bo; |
41 | struct device *dev = drm->dev->dev; | ||
42 | int ret; | ||
43 | |||
44 | ret = pm_runtime_get_sync(dev); | ||
45 | if (WARN_ON(ret < 0 && ret != -EACCES)) | ||
46 | return; | ||
40 | 47 | ||
41 | if (gem->import_attach) | 48 | if (gem->import_attach) |
42 | drm_prime_gem_destroy(gem, nvbo->bo.sg); | 49 | drm_prime_gem_destroy(gem, nvbo->bo.sg); |
@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem) | |||
46 | /* reset filp so nouveau_bo_del_ttm() can test for it */ | 53 | /* reset filp so nouveau_bo_del_ttm() can test for it */ |
47 | gem->filp = NULL; | 54 | gem->filp = NULL; |
48 | ttm_bo_unref(&bo); | 55 | ttm_bo_unref(&bo); |
56 | |||
57 | pm_runtime_mark_last_busy(dev); | ||
58 | pm_runtime_put_autosuspend(dev); | ||
49 | } | 59 | } |
50 | 60 | ||
51 | int | 61 | int |
@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
53 | { | 63 | { |
54 | struct nouveau_cli *cli = nouveau_cli(file_priv); | 64 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
55 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 65 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
66 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
56 | struct nouveau_vma *vma; | 67 | struct nouveau_vma *vma; |
68 | struct device *dev = drm->dev->dev; | ||
57 | int ret; | 69 | int ret; |
58 | 70 | ||
59 | if (!cli->vm) | 71 | if (!cli->vm) |
@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
71 | goto out; | 83 | goto out; |
72 | } | 84 | } |
73 | 85 | ||
86 | ret = pm_runtime_get_sync(dev); | ||
87 | if (ret < 0 && ret != -EACCES) | ||
88 | goto out; | ||
89 | |||
74 | ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); | 90 | ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); |
75 | if (ret) { | 91 | if (ret) |
76 | kfree(vma); | 92 | kfree(vma); |
77 | goto out; | 93 | |
78 | } | 94 | pm_runtime_mark_last_busy(dev); |
95 | pm_runtime_put_autosuspend(dev); | ||
79 | } else { | 96 | } else { |
80 | vma->refcount++; | 97 | vma->refcount++; |
81 | } | 98 | } |
@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
129 | { | 146 | { |
130 | struct nouveau_cli *cli = nouveau_cli(file_priv); | 147 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
131 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 148 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
149 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
150 | struct device *dev = drm->dev->dev; | ||
132 | struct nouveau_vma *vma; | 151 | struct nouveau_vma *vma; |
133 | int ret; | 152 | int ret; |
134 | 153 | ||
@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
141 | 160 | ||
142 | vma = nouveau_bo_vma_find(nvbo, cli->vm); | 161 | vma = nouveau_bo_vma_find(nvbo, cli->vm); |
143 | if (vma) { | 162 | if (vma) { |
144 | if (--vma->refcount == 0) | 163 | if (--vma->refcount == 0) { |
145 | nouveau_gem_object_unmap(nvbo, vma); | 164 | ret = pm_runtime_get_sync(dev); |
165 | if (!WARN_ON(ret < 0 && ret != -EACCES)) { | ||
166 | nouveau_gem_object_unmap(nvbo, vma); | ||
167 | pm_runtime_mark_last_busy(dev); | ||
168 | pm_runtime_put_autosuspend(dev); | ||
169 | } | ||
170 | } | ||
146 | } | 171 | } |
147 | ttm_bo_unreserve(&nvbo->bo); | 172 | ttm_bo_unreserve(&nvbo->bo); |
148 | } | 173 | } |
@@ -444,9 +469,6 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, | |||
444 | list_for_each_entry(nvbo, list, entry) { | 469 | list_for_each_entry(nvbo, list, entry) { |
445 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 470 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
446 | 471 | ||
447 | WARN_ONCE(nvbo->gem.dumb, | ||
448 | "GPU use of dumb buffer is illegal.\n"); | ||
449 | |||
450 | ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, | 472 | ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, |
451 | b->write_domains, | 473 | b->write_domains, |
452 | b->valid_domains); | 474 | b->valid_domains); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 753a6def61e7..3d1cfcb96b6b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "nouveau_ttm.h" | 28 | #include "nouveau_ttm.h" |
29 | #include "nouveau_gem.h" | 29 | #include "nouveau_gem.h" |
30 | 30 | ||
31 | #include "drm_legacy.h" | ||
31 | static int | 32 | static int |
32 | nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) | 33 | nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) |
33 | { | 34 | { |
@@ -281,7 +282,7 @@ nouveau_ttm_mmap(struct file *filp, struct vm_area_struct *vma) | |||
281 | struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev); | 282 | struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev); |
282 | 283 | ||
283 | if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) | 284 | if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET)) |
284 | return -EINVAL; | 285 | return drm_legacy_mmap(filp, vma); |
285 | 286 | ||
286 | return ttm_bo_mmap(filp, vma, &drm->ttm.bdev); | 287 | return ttm_bo_mmap(filp, vma, &drm->ttm.bdev); |
287 | } | 288 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d59ec491dbb9..ed644a4f6f57 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1851 | return pll; | 1851 | return pll; |
1852 | } | 1852 | } |
1853 | /* otherwise, pick one of the plls */ | 1853 | /* otherwise, pick one of the plls */ |
1854 | if ((rdev->family == CHIP_KAVERI) || | 1854 | if ((rdev->family == CHIP_KABINI) || |
1855 | (rdev->family == CHIP_KABINI) || | ||
1856 | (rdev->family == CHIP_MULLINS)) { | 1855 | (rdev->family == CHIP_MULLINS)) { |
1857 | /* KB/KV/ML has PPLL1 and PPLL2 */ | 1856 | /* KB/ML has PPLL1 and PPLL2 */ |
1858 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1857 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1859 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | 1858 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1860 | return ATOM_PPLL2; | 1859 | return ATOM_PPLL2; |
@@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1863 | DRM_ERROR("unable to allocate a PPLL\n"); | 1862 | DRM_ERROR("unable to allocate a PPLL\n"); |
1864 | return ATOM_PPLL_INVALID; | 1863 | return ATOM_PPLL_INVALID; |
1865 | } else { | 1864 | } else { |
1866 | /* CI has PPLL0, PPLL1, and PPLL2 */ | 1865 | /* CI/KV has PPLL0, PPLL1, and PPLL2 */ |
1867 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1866 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1868 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | 1867 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1869 | return ATOM_PPLL2; | 1868 | return ATOM_PPLL2; |
@@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
2155 | case ATOM_PPLL0: | 2154 | case ATOM_PPLL0: |
2156 | /* disable the ppll */ | 2155 | /* disable the ppll */ |
2157 | if ((rdev->family == CHIP_ARUBA) || | 2156 | if ((rdev->family == CHIP_ARUBA) || |
2157 | (rdev->family == CHIP_KAVERI) || | ||
2158 | (rdev->family == CHIP_BONAIRE) || | 2158 | (rdev->family == CHIP_BONAIRE) || |
2159 | (rdev->family == CHIP_HAWAII)) | 2159 | (rdev->family == CHIP_HAWAII)) |
2160 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 2160 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 11ba9d21b89b..db42a670f995 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, | |||
492 | struct radeon_connector_atom_dig *dig_connector; | 492 | struct radeon_connector_atom_dig *dig_connector; |
493 | int dp_clock; | 493 | int dp_clock; |
494 | 494 | ||
495 | if ((mode->clock > 340000) && | ||
496 | (!radeon_connector_is_dp12_capable(connector))) | ||
497 | return MODE_CLOCK_HIGH; | ||
498 | |||
495 | if (!radeon_connector->con_priv) | 499 | if (!radeon_connector->con_priv) |
496 | return MODE_CLOCK_HIGH; | 500 | return MODE_CLOCK_HIGH; |
497 | dig_connector = radeon_connector->con_priv; | 501 | dig_connector = radeon_connector->con_priv; |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 6dcde3798b45..64fdae558d36 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -6033,6 +6033,17 @@ void cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
6033 | radeon_ring_write(ring, 0); | 6033 | radeon_ring_write(ring, 0); |
6034 | radeon_ring_write(ring, 1 << vm_id); | 6034 | radeon_ring_write(ring, 1 << vm_id); |
6035 | 6035 | ||
6036 | /* wait for the invalidate to complete */ | ||
6037 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
6038 | radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ | ||
6039 | WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
6040 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
6041 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
6042 | radeon_ring_write(ring, 0); | ||
6043 | radeon_ring_write(ring, 0); /* ref */ | ||
6044 | radeon_ring_write(ring, 0); /* mask */ | ||
6045 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
6046 | |||
6036 | /* compute doesn't have PFP */ | 6047 | /* compute doesn't have PFP */ |
6037 | if (usepfp) { | 6048 | if (usepfp) { |
6038 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 6049 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index dde5c7e29eb2..42cd0cffe210 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -816,7 +816,6 @@ void cik_sdma_vm_write_pages(struct radeon_device *rdev, | |||
816 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 816 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
817 | if (flags & R600_PTE_SYSTEM) { | 817 | if (flags & R600_PTE_SYSTEM) { |
818 | value = radeon_vm_map_gart(rdev, addr); | 818 | value = radeon_vm_map_gart(rdev, addr); |
819 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
820 | } else if (flags & R600_PTE_VALID) { | 819 | } else if (flags & R600_PTE_VALID) { |
821 | value = addr; | 820 | value = addr; |
822 | } else { | 821 | } else { |
@@ -903,6 +902,9 @@ void cik_sdma_vm_pad_ib(struct radeon_ib *ib) | |||
903 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | 902 | void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, |
904 | unsigned vm_id, uint64_t pd_addr) | 903 | unsigned vm_id, uint64_t pd_addr) |
905 | { | 904 | { |
905 | u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) | | ||
906 | SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */ | ||
907 | |||
906 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 908 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
907 | if (vm_id < 8) { | 909 | if (vm_id < 8) { |
908 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); | 910 | radeon_ring_write(ring, (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); |
@@ -943,5 +945,12 @@ void cik_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
943 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); | 945 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); |
944 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | 946 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
945 | radeon_ring_write(ring, 1 << vm_id); | 947 | radeon_ring_write(ring, 1 << vm_id); |
948 | |||
949 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits)); | ||
950 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
951 | radeon_ring_write(ring, 0); | ||
952 | radeon_ring_write(ring, 0); /* reference */ | ||
953 | radeon_ring_write(ring, 0); /* mask */ | ||
954 | radeon_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ | ||
946 | } | 955 | } |
947 | 956 | ||
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index ba85986febea..03003f8a6de6 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -2156,4 +2156,6 @@ | |||
2156 | #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu | 2156 | #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu |
2157 | #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u | 2157 | #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u |
2158 | 2158 | ||
2159 | #define IH_VMID_0_LUT 0x3D40u | ||
2160 | |||
2159 | #endif | 2161 | #endif |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 2fe8cfc966d9..bafdf92a5732 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); | 105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
106 | if (sad_count < 0) { | 106 | if (sad_count <= 0) { |
107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | 107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
108 | return; | 108 | return; |
109 | } | 109 | } |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 9b42001295ba..e3e9c10cfba9 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2745 | pi->enable_auto_thermal_throttling = true; | 2745 | pi->enable_auto_thermal_throttling = true; |
2746 | pi->disable_nb_ps3_in_battery = false; | 2746 | pi->disable_nb_ps3_in_battery = false; |
2747 | if (radeon_bapm == -1) { | 2747 | if (radeon_bapm == -1) { |
2748 | /* There are stability issues reported on with | 2748 | /* only enable bapm on KB, ML by default */ |
2749 | * bapm enabled on an asrock system. | 2749 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
2750 | */ | ||
2751 | if (rdev->pdev->subsystem_vendor == 0x1849) | ||
2752 | pi->bapm_enable = false; | ||
2753 | else | ||
2754 | pi->bapm_enable = true; | 2750 | pi->bapm_enable = true; |
2751 | else | ||
2752 | pi->bapm_enable = false; | ||
2755 | } else if (radeon_bapm == 0) { | 2753 | } else if (radeon_bapm == 0) { |
2756 | pi->bapm_enable = false; | 2754 | pi->bapm_enable = false; |
2757 | } else { | 2755 | } else { |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 360de9f1f491..aea48c89b241 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -2516,6 +2516,16 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
2516 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); | 2516 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
2517 | radeon_ring_write(ring, 1 << vm_id); | 2517 | radeon_ring_write(ring, 1 << vm_id); |
2518 | 2518 | ||
2519 | /* wait for the invalidate to complete */ | ||
2520 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
2521 | radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
2522 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
2523 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
2524 | radeon_ring_write(ring, 0); | ||
2525 | radeon_ring_write(ring, 0); /* ref */ | ||
2526 | radeon_ring_write(ring, 0); /* mask */ | ||
2527 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
2528 | |||
2519 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 2529 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
2520 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 2530 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
2521 | radeon_ring_write(ring, 0x0); | 2531 | radeon_ring_write(ring, 0x0); |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 50f88611ff60..ce787a9f12c0 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c | |||
@@ -372,7 +372,6 @@ void cayman_dma_vm_write_pages(struct radeon_device *rdev, | |||
372 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 372 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
373 | if (flags & R600_PTE_SYSTEM) { | 373 | if (flags & R600_PTE_SYSTEM) { |
374 | value = radeon_vm_map_gart(rdev, addr); | 374 | value = radeon_vm_map_gart(rdev, addr); |
375 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
376 | } else if (flags & R600_PTE_VALID) { | 375 | } else if (flags & R600_PTE_VALID) { |
377 | value = addr; | 376 | value = addr; |
378 | } else { | 377 | } else { |
@@ -463,5 +462,11 @@ void cayman_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
463 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 462 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
464 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 463 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
465 | radeon_ring_write(ring, 1 << vm_id); | 464 | radeon_ring_write(ring, 1 << vm_id); |
465 | |||
466 | /* wait for invalidate to complete */ | ||
467 | radeon_ring_write(ring, DMA_SRBM_READ_PACKET); | ||
468 | radeon_ring_write(ring, (0xff << 20) | (VM_INVALIDATE_REQUEST >> 2)); | ||
469 | radeon_ring_write(ring, 0); /* mask */ | ||
470 | radeon_ring_write(ring, 0); /* value */ | ||
466 | } | 471 | } |
467 | 472 | ||
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 2e12e4d69253..ad7125486894 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -1133,6 +1133,23 @@ | |||
1133 | #define PACKET3_MEM_SEMAPHORE 0x39 | 1133 | #define PACKET3_MEM_SEMAPHORE 0x39 |
1134 | #define PACKET3_MPEG_INDEX 0x3A | 1134 | #define PACKET3_MPEG_INDEX 0x3A |
1135 | #define PACKET3_WAIT_REG_MEM 0x3C | 1135 | #define PACKET3_WAIT_REG_MEM 0x3C |
1136 | #define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) | ||
1137 | /* 0 - always | ||
1138 | * 1 - < | ||
1139 | * 2 - <= | ||
1140 | * 3 - == | ||
1141 | * 4 - != | ||
1142 | * 5 - >= | ||
1143 | * 6 - > | ||
1144 | */ | ||
1145 | #define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) | ||
1146 | /* 0 - reg | ||
1147 | * 1 - mem | ||
1148 | */ | ||
1149 | #define WAIT_REG_MEM_ENGINE(x) ((x) << 8) | ||
1150 | /* 0 - me | ||
1151 | * 1 - pfp | ||
1152 | */ | ||
1136 | #define PACKET3_MEM_WRITE 0x3D | 1153 | #define PACKET3_MEM_WRITE 0x3D |
1137 | #define PACKET3_PFP_SYNC_ME 0x42 | 1154 | #define PACKET3_PFP_SYNC_ME 0x42 |
1138 | #define PACKET3_SURFACE_SYNC 0x43 | 1155 | #define PACKET3_SURFACE_SYNC 0x43 |
@@ -1272,6 +1289,13 @@ | |||
1272 | (1 << 21) | \ | 1289 | (1 << 21) | \ |
1273 | (((n) & 0xFFFFF) << 0)) | 1290 | (((n) & 0xFFFFF) << 0)) |
1274 | 1291 | ||
1292 | #define DMA_SRBM_POLL_PACKET ((9 << 28) | \ | ||
1293 | (1 << 27) | \ | ||
1294 | (1 << 26)) | ||
1295 | |||
1296 | #define DMA_SRBM_READ_PACKET ((9 << 28) | \ | ||
1297 | (1 << 27)) | ||
1298 | |||
1275 | /* async DMA Packet types */ | 1299 | /* async DMA Packet types */ |
1276 | #define DMA_PACKET_WRITE 0x2 | 1300 | #define DMA_PACKET_WRITE 0x2 |
1277 | #define DMA_PACKET_COPY 0x3 | 1301 | #define DMA_PACKET_COPY 0x3 |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 74f06d540591..279801ca5110 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -644,6 +644,7 @@ int r100_pci_gart_init(struct radeon_device *rdev) | |||
644 | return r; | 644 | return r; |
645 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; | 645 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
646 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; | 646 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
647 | rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; | ||
647 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; | 648 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
648 | return radeon_gart_table_ram_alloc(rdev); | 649 | return radeon_gart_table_ram_alloc(rdev); |
649 | } | 650 | } |
@@ -681,11 +682,16 @@ void r100_pci_gart_disable(struct radeon_device *rdev) | |||
681 | WREG32(RADEON_AIC_HI_ADDR, 0); | 682 | WREG32(RADEON_AIC_HI_ADDR, 0); |
682 | } | 683 | } |
683 | 684 | ||
685 | uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags) | ||
686 | { | ||
687 | return addr; | ||
688 | } | ||
689 | |||
684 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, | 690 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
685 | uint64_t addr, uint32_t flags) | 691 | uint64_t entry) |
686 | { | 692 | { |
687 | u32 *gtt = rdev->gart.ptr; | 693 | u32 *gtt = rdev->gart.ptr; |
688 | gtt[i] = cpu_to_le32(lower_32_bits(addr)); | 694 | gtt[i] = cpu_to_le32(lower_32_bits(entry)); |
689 | } | 695 | } |
690 | 696 | ||
691 | void r100_pci_gart_fini(struct radeon_device *rdev) | 697 | void r100_pci_gart_fini(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 064ad5569cca..08d68f3e13e9 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -73,11 +73,8 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
73 | #define R300_PTE_WRITEABLE (1 << 2) | 73 | #define R300_PTE_WRITEABLE (1 << 2) |
74 | #define R300_PTE_READABLE (1 << 3) | 74 | #define R300_PTE_READABLE (1 << 3) |
75 | 75 | ||
76 | void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | 76 | uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags) |
77 | uint64_t addr, uint32_t flags) | ||
78 | { | 77 | { |
79 | void __iomem *ptr = rdev->gart.ptr; | ||
80 | |||
81 | addr = (lower_32_bits(addr) >> 8) | | 78 | addr = (lower_32_bits(addr) >> 8) | |
82 | ((upper_32_bits(addr) & 0xff) << 24); | 79 | ((upper_32_bits(addr) & 0xff) << 24); |
83 | if (flags & RADEON_GART_PAGE_READ) | 80 | if (flags & RADEON_GART_PAGE_READ) |
@@ -86,10 +83,18 @@ void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | |||
86 | addr |= R300_PTE_WRITEABLE; | 83 | addr |= R300_PTE_WRITEABLE; |
87 | if (!(flags & RADEON_GART_PAGE_SNOOP)) | 84 | if (!(flags & RADEON_GART_PAGE_SNOOP)) |
88 | addr |= R300_PTE_UNSNOOPED; | 85 | addr |= R300_PTE_UNSNOOPED; |
86 | return addr; | ||
87 | } | ||
88 | |||
89 | void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | ||
90 | uint64_t entry) | ||
91 | { | ||
92 | void __iomem *ptr = rdev->gart.ptr; | ||
93 | |||
89 | /* on x86 we want this to be CPU endian, on powerpc | 94 | /* on x86 we want this to be CPU endian, on powerpc |
90 | * on powerpc without HW swappers, it'll get swapped on way | 95 | * on powerpc without HW swappers, it'll get swapped on way |
91 | * into VRAM - so no need for cpu_to_le32 on VRAM tables */ | 96 | * into VRAM - so no need for cpu_to_le32 on VRAM tables */ |
92 | writel(addr, ((void __iomem *)ptr) + (i * 4)); | 97 | writel(entry, ((void __iomem *)ptr) + (i * 4)); |
93 | } | 98 | } |
94 | 99 | ||
95 | int rv370_pcie_gart_init(struct radeon_device *rdev) | 100 | int rv370_pcie_gart_init(struct radeon_device *rdev) |
@@ -109,6 +114,7 @@ int rv370_pcie_gart_init(struct radeon_device *rdev) | |||
109 | DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); | 114 | DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); |
110 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; | 115 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
111 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; | 116 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
117 | rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; | ||
112 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; | 118 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
113 | return radeon_gart_table_vram_alloc(rdev); | 119 | return radeon_gart_table_vram_alloc(rdev); |
114 | } | 120 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 54529b837afa..3f2a8d3febca 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -242,6 +242,7 @@ bool radeon_get_bios(struct radeon_device *rdev); | |||
242 | * Dummy page | 242 | * Dummy page |
243 | */ | 243 | */ |
244 | struct radeon_dummy_page { | 244 | struct radeon_dummy_page { |
245 | uint64_t entry; | ||
245 | struct page *page; | 246 | struct page *page; |
246 | dma_addr_t addr; | 247 | dma_addr_t addr; |
247 | }; | 248 | }; |
@@ -645,7 +646,7 @@ struct radeon_gart { | |||
645 | unsigned num_cpu_pages; | 646 | unsigned num_cpu_pages; |
646 | unsigned table_size; | 647 | unsigned table_size; |
647 | struct page **pages; | 648 | struct page **pages; |
648 | dma_addr_t *pages_addr; | 649 | uint64_t *pages_entry; |
649 | bool ready; | 650 | bool ready; |
650 | }; | 651 | }; |
651 | 652 | ||
@@ -1847,8 +1848,9 @@ struct radeon_asic { | |||
1847 | /* gart */ | 1848 | /* gart */ |
1848 | struct { | 1849 | struct { |
1849 | void (*tlb_flush)(struct radeon_device *rdev); | 1850 | void (*tlb_flush)(struct radeon_device *rdev); |
1851 | uint64_t (*get_page_entry)(uint64_t addr, uint32_t flags); | ||
1850 | void (*set_page)(struct radeon_device *rdev, unsigned i, | 1852 | void (*set_page)(struct radeon_device *rdev, unsigned i, |
1851 | uint64_t addr, uint32_t flags); | 1853 | uint64_t entry); |
1852 | } gart; | 1854 | } gart; |
1853 | struct { | 1855 | struct { |
1854 | int (*init)(struct radeon_device *rdev); | 1856 | int (*init)(struct radeon_device *rdev); |
@@ -2852,7 +2854,8 @@ static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) | |||
2852 | #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) | 2854 | #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) |
2853 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) | 2855 | #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) |
2854 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) | 2856 | #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) |
2855 | #define radeon_gart_set_page(rdev, i, p, f) (rdev)->asic->gart.set_page((rdev), (i), (p), (f)) | 2857 | #define radeon_gart_get_page_entry(a, f) (rdev)->asic->gart.get_page_entry((a), (f)) |
2858 | #define radeon_gart_set_page(rdev, i, e) (rdev)->asic->gart.set_page((rdev), (i), (e)) | ||
2856 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) | 2859 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) |
2857 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) | 2860 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) |
2858 | #define radeon_asic_vm_copy_pages(rdev, ib, pe, src, count) ((rdev)->asic->vm.copy_pages((rdev), (ib), (pe), (src), (count))) | 2861 | #define radeon_asic_vm_copy_pages(rdev, ib, pe, src, count) ((rdev)->asic->vm.copy_pages((rdev), (ib), (pe), (src), (count))) |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 850de57069be..ed0e10eee2dc 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -159,11 +159,13 @@ void radeon_agp_disable(struct radeon_device *rdev) | |||
159 | DRM_INFO("Forcing AGP to PCIE mode\n"); | 159 | DRM_INFO("Forcing AGP to PCIE mode\n"); |
160 | rdev->flags |= RADEON_IS_PCIE; | 160 | rdev->flags |= RADEON_IS_PCIE; |
161 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; | 161 | rdev->asic->gart.tlb_flush = &rv370_pcie_gart_tlb_flush; |
162 | rdev->asic->gart.get_page_entry = &rv370_pcie_gart_get_page_entry; | ||
162 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; | 163 | rdev->asic->gart.set_page = &rv370_pcie_gart_set_page; |
163 | } else { | 164 | } else { |
164 | DRM_INFO("Forcing AGP to PCI mode\n"); | 165 | DRM_INFO("Forcing AGP to PCI mode\n"); |
165 | rdev->flags |= RADEON_IS_PCI; | 166 | rdev->flags |= RADEON_IS_PCI; |
166 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; | 167 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
168 | rdev->asic->gart.get_page_entry = &r100_pci_gart_get_page_entry; | ||
167 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; | 169 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
168 | } | 170 | } |
169 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | 171 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
@@ -199,6 +201,7 @@ static struct radeon_asic r100_asic = { | |||
199 | .mc_wait_for_idle = &r100_mc_wait_for_idle, | 201 | .mc_wait_for_idle = &r100_mc_wait_for_idle, |
200 | .gart = { | 202 | .gart = { |
201 | .tlb_flush = &r100_pci_gart_tlb_flush, | 203 | .tlb_flush = &r100_pci_gart_tlb_flush, |
204 | .get_page_entry = &r100_pci_gart_get_page_entry, | ||
202 | .set_page = &r100_pci_gart_set_page, | 205 | .set_page = &r100_pci_gart_set_page, |
203 | }, | 206 | }, |
204 | .ring = { | 207 | .ring = { |
@@ -265,6 +268,7 @@ static struct radeon_asic r200_asic = { | |||
265 | .mc_wait_for_idle = &r100_mc_wait_for_idle, | 268 | .mc_wait_for_idle = &r100_mc_wait_for_idle, |
266 | .gart = { | 269 | .gart = { |
267 | .tlb_flush = &r100_pci_gart_tlb_flush, | 270 | .tlb_flush = &r100_pci_gart_tlb_flush, |
271 | .get_page_entry = &r100_pci_gart_get_page_entry, | ||
268 | .set_page = &r100_pci_gart_set_page, | 272 | .set_page = &r100_pci_gart_set_page, |
269 | }, | 273 | }, |
270 | .ring = { | 274 | .ring = { |
@@ -333,6 +337,20 @@ static struct radeon_asic_ring r300_gfx_ring = { | |||
333 | .set_wptr = &r100_gfx_set_wptr, | 337 | .set_wptr = &r100_gfx_set_wptr, |
334 | }; | 338 | }; |
335 | 339 | ||
340 | static struct radeon_asic_ring rv515_gfx_ring = { | ||
341 | .ib_execute = &r100_ring_ib_execute, | ||
342 | .emit_fence = &r300_fence_ring_emit, | ||
343 | .emit_semaphore = &r100_semaphore_ring_emit, | ||
344 | .cs_parse = &r300_cs_parse, | ||
345 | .ring_start = &rv515_ring_start, | ||
346 | .ring_test = &r100_ring_test, | ||
347 | .ib_test = &r100_ib_test, | ||
348 | .is_lockup = &r100_gpu_is_lockup, | ||
349 | .get_rptr = &r100_gfx_get_rptr, | ||
350 | .get_wptr = &r100_gfx_get_wptr, | ||
351 | .set_wptr = &r100_gfx_set_wptr, | ||
352 | }; | ||
353 | |||
336 | static struct radeon_asic r300_asic = { | 354 | static struct radeon_asic r300_asic = { |
337 | .init = &r300_init, | 355 | .init = &r300_init, |
338 | .fini = &r300_fini, | 356 | .fini = &r300_fini, |
@@ -345,6 +363,7 @@ static struct radeon_asic r300_asic = { | |||
345 | .mc_wait_for_idle = &r300_mc_wait_for_idle, | 363 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
346 | .gart = { | 364 | .gart = { |
347 | .tlb_flush = &r100_pci_gart_tlb_flush, | 365 | .tlb_flush = &r100_pci_gart_tlb_flush, |
366 | .get_page_entry = &r100_pci_gart_get_page_entry, | ||
348 | .set_page = &r100_pci_gart_set_page, | 367 | .set_page = &r100_pci_gart_set_page, |
349 | }, | 368 | }, |
350 | .ring = { | 369 | .ring = { |
@@ -411,6 +430,7 @@ static struct radeon_asic r300_asic_pcie = { | |||
411 | .mc_wait_for_idle = &r300_mc_wait_for_idle, | 430 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
412 | .gart = { | 431 | .gart = { |
413 | .tlb_flush = &rv370_pcie_gart_tlb_flush, | 432 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
433 | .get_page_entry = &rv370_pcie_gart_get_page_entry, | ||
414 | .set_page = &rv370_pcie_gart_set_page, | 434 | .set_page = &rv370_pcie_gart_set_page, |
415 | }, | 435 | }, |
416 | .ring = { | 436 | .ring = { |
@@ -477,6 +497,7 @@ static struct radeon_asic r420_asic = { | |||
477 | .mc_wait_for_idle = &r300_mc_wait_for_idle, | 497 | .mc_wait_for_idle = &r300_mc_wait_for_idle, |
478 | .gart = { | 498 | .gart = { |
479 | .tlb_flush = &rv370_pcie_gart_tlb_flush, | 499 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
500 | .get_page_entry = &rv370_pcie_gart_get_page_entry, | ||
480 | .set_page = &rv370_pcie_gart_set_page, | 501 | .set_page = &rv370_pcie_gart_set_page, |
481 | }, | 502 | }, |
482 | .ring = { | 503 | .ring = { |
@@ -543,6 +564,7 @@ static struct radeon_asic rs400_asic = { | |||
543 | .mc_wait_for_idle = &rs400_mc_wait_for_idle, | 564 | .mc_wait_for_idle = &rs400_mc_wait_for_idle, |
544 | .gart = { | 565 | .gart = { |
545 | .tlb_flush = &rs400_gart_tlb_flush, | 566 | .tlb_flush = &rs400_gart_tlb_flush, |
567 | .get_page_entry = &rs400_gart_get_page_entry, | ||
546 | .set_page = &rs400_gart_set_page, | 568 | .set_page = &rs400_gart_set_page, |
547 | }, | 569 | }, |
548 | .ring = { | 570 | .ring = { |
@@ -609,6 +631,7 @@ static struct radeon_asic rs600_asic = { | |||
609 | .mc_wait_for_idle = &rs600_mc_wait_for_idle, | 631 | .mc_wait_for_idle = &rs600_mc_wait_for_idle, |
610 | .gart = { | 632 | .gart = { |
611 | .tlb_flush = &rs600_gart_tlb_flush, | 633 | .tlb_flush = &rs600_gart_tlb_flush, |
634 | .get_page_entry = &rs600_gart_get_page_entry, | ||
612 | .set_page = &rs600_gart_set_page, | 635 | .set_page = &rs600_gart_set_page, |
613 | }, | 636 | }, |
614 | .ring = { | 637 | .ring = { |
@@ -677,6 +700,7 @@ static struct radeon_asic rs690_asic = { | |||
677 | .mc_wait_for_idle = &rs690_mc_wait_for_idle, | 700 | .mc_wait_for_idle = &rs690_mc_wait_for_idle, |
678 | .gart = { | 701 | .gart = { |
679 | .tlb_flush = &rs400_gart_tlb_flush, | 702 | .tlb_flush = &rs400_gart_tlb_flush, |
703 | .get_page_entry = &rs400_gart_get_page_entry, | ||
680 | .set_page = &rs400_gart_set_page, | 704 | .set_page = &rs400_gart_set_page, |
681 | }, | 705 | }, |
682 | .ring = { | 706 | .ring = { |
@@ -745,10 +769,11 @@ static struct radeon_asic rv515_asic = { | |||
745 | .mc_wait_for_idle = &rv515_mc_wait_for_idle, | 769 | .mc_wait_for_idle = &rv515_mc_wait_for_idle, |
746 | .gart = { | 770 | .gart = { |
747 | .tlb_flush = &rv370_pcie_gart_tlb_flush, | 771 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
772 | .get_page_entry = &rv370_pcie_gart_get_page_entry, | ||
748 | .set_page = &rv370_pcie_gart_set_page, | 773 | .set_page = &rv370_pcie_gart_set_page, |
749 | }, | 774 | }, |
750 | .ring = { | 775 | .ring = { |
751 | [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring | 776 | [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring |
752 | }, | 777 | }, |
753 | .irq = { | 778 | .irq = { |
754 | .set = &rs600_irq_set, | 779 | .set = &rs600_irq_set, |
@@ -811,10 +836,11 @@ static struct radeon_asic r520_asic = { | |||
811 | .mc_wait_for_idle = &r520_mc_wait_for_idle, | 836 | .mc_wait_for_idle = &r520_mc_wait_for_idle, |
812 | .gart = { | 837 | .gart = { |
813 | .tlb_flush = &rv370_pcie_gart_tlb_flush, | 838 | .tlb_flush = &rv370_pcie_gart_tlb_flush, |
839 | .get_page_entry = &rv370_pcie_gart_get_page_entry, | ||
814 | .set_page = &rv370_pcie_gart_set_page, | 840 | .set_page = &rv370_pcie_gart_set_page, |
815 | }, | 841 | }, |
816 | .ring = { | 842 | .ring = { |
817 | [RADEON_RING_TYPE_GFX_INDEX] = &r300_gfx_ring | 843 | [RADEON_RING_TYPE_GFX_INDEX] = &rv515_gfx_ring |
818 | }, | 844 | }, |
819 | .irq = { | 845 | .irq = { |
820 | .set = &rs600_irq_set, | 846 | .set = &rs600_irq_set, |
@@ -905,6 +931,7 @@ static struct radeon_asic r600_asic = { | |||
905 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 931 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
906 | .gart = { | 932 | .gart = { |
907 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 933 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
934 | .get_page_entry = &rs600_gart_get_page_entry, | ||
908 | .set_page = &rs600_gart_set_page, | 935 | .set_page = &rs600_gart_set_page, |
909 | }, | 936 | }, |
910 | .ring = { | 937 | .ring = { |
@@ -990,6 +1017,7 @@ static struct radeon_asic rv6xx_asic = { | |||
990 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1017 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
991 | .gart = { | 1018 | .gart = { |
992 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 1019 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
1020 | .get_page_entry = &rs600_gart_get_page_entry, | ||
993 | .set_page = &rs600_gart_set_page, | 1021 | .set_page = &rs600_gart_set_page, |
994 | }, | 1022 | }, |
995 | .ring = { | 1023 | .ring = { |
@@ -1081,6 +1109,7 @@ static struct radeon_asic rs780_asic = { | |||
1081 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1109 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1082 | .gart = { | 1110 | .gart = { |
1083 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 1111 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
1112 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1084 | .set_page = &rs600_gart_set_page, | 1113 | .set_page = &rs600_gart_set_page, |
1085 | }, | 1114 | }, |
1086 | .ring = { | 1115 | .ring = { |
@@ -1185,6 +1214,7 @@ static struct radeon_asic rv770_asic = { | |||
1185 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1214 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1186 | .gart = { | 1215 | .gart = { |
1187 | .tlb_flush = &r600_pcie_gart_tlb_flush, | 1216 | .tlb_flush = &r600_pcie_gart_tlb_flush, |
1217 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1188 | .set_page = &rs600_gart_set_page, | 1218 | .set_page = &rs600_gart_set_page, |
1189 | }, | 1219 | }, |
1190 | .ring = { | 1220 | .ring = { |
@@ -1303,6 +1333,7 @@ static struct radeon_asic evergreen_asic = { | |||
1303 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1333 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1304 | .gart = { | 1334 | .gart = { |
1305 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1335 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1336 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1306 | .set_page = &rs600_gart_set_page, | 1337 | .set_page = &rs600_gart_set_page, |
1307 | }, | 1338 | }, |
1308 | .ring = { | 1339 | .ring = { |
@@ -1395,6 +1426,7 @@ static struct radeon_asic sumo_asic = { | |||
1395 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1426 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1396 | .gart = { | 1427 | .gart = { |
1397 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1428 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1429 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1398 | .set_page = &rs600_gart_set_page, | 1430 | .set_page = &rs600_gart_set_page, |
1399 | }, | 1431 | }, |
1400 | .ring = { | 1432 | .ring = { |
@@ -1486,6 +1518,7 @@ static struct radeon_asic btc_asic = { | |||
1486 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1518 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1487 | .gart = { | 1519 | .gart = { |
1488 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, | 1520 | .tlb_flush = &evergreen_pcie_gart_tlb_flush, |
1521 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1489 | .set_page = &rs600_gart_set_page, | 1522 | .set_page = &rs600_gart_set_page, |
1490 | }, | 1523 | }, |
1491 | .ring = { | 1524 | .ring = { |
@@ -1621,6 +1654,7 @@ static struct radeon_asic cayman_asic = { | |||
1621 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1654 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1622 | .gart = { | 1655 | .gart = { |
1623 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1656 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1657 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1624 | .set_page = &rs600_gart_set_page, | 1658 | .set_page = &rs600_gart_set_page, |
1625 | }, | 1659 | }, |
1626 | .vm = { | 1660 | .vm = { |
@@ -1724,6 +1758,7 @@ static struct radeon_asic trinity_asic = { | |||
1724 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, | 1758 | .get_gpu_clock_counter = &r600_get_gpu_clock_counter, |
1725 | .gart = { | 1759 | .gart = { |
1726 | .tlb_flush = &cayman_pcie_gart_tlb_flush, | 1760 | .tlb_flush = &cayman_pcie_gart_tlb_flush, |
1761 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1727 | .set_page = &rs600_gart_set_page, | 1762 | .set_page = &rs600_gart_set_page, |
1728 | }, | 1763 | }, |
1729 | .vm = { | 1764 | .vm = { |
@@ -1857,6 +1892,7 @@ static struct radeon_asic si_asic = { | |||
1857 | .get_gpu_clock_counter = &si_get_gpu_clock_counter, | 1892 | .get_gpu_clock_counter = &si_get_gpu_clock_counter, |
1858 | .gart = { | 1893 | .gart = { |
1859 | .tlb_flush = &si_pcie_gart_tlb_flush, | 1894 | .tlb_flush = &si_pcie_gart_tlb_flush, |
1895 | .get_page_entry = &rs600_gart_get_page_entry, | ||
1860 | .set_page = &rs600_gart_set_page, | 1896 | .set_page = &rs600_gart_set_page, |
1861 | }, | 1897 | }, |
1862 | .vm = { | 1898 | .vm = { |
@@ -2018,6 +2054,7 @@ static struct radeon_asic ci_asic = { | |||
2018 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, | 2054 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
2019 | .gart = { | 2055 | .gart = { |
2020 | .tlb_flush = &cik_pcie_gart_tlb_flush, | 2056 | .tlb_flush = &cik_pcie_gart_tlb_flush, |
2057 | .get_page_entry = &rs600_gart_get_page_entry, | ||
2021 | .set_page = &rs600_gart_set_page, | 2058 | .set_page = &rs600_gart_set_page, |
2022 | }, | 2059 | }, |
2023 | .vm = { | 2060 | .vm = { |
@@ -2125,6 +2162,7 @@ static struct radeon_asic kv_asic = { | |||
2125 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, | 2162 | .get_gpu_clock_counter = &cik_get_gpu_clock_counter, |
2126 | .gart = { | 2163 | .gart = { |
2127 | .tlb_flush = &cik_pcie_gart_tlb_flush, | 2164 | .tlb_flush = &cik_pcie_gart_tlb_flush, |
2165 | .get_page_entry = &rs600_gart_get_page_entry, | ||
2128 | .set_page = &rs600_gart_set_page, | 2166 | .set_page = &rs600_gart_set_page, |
2129 | }, | 2167 | }, |
2130 | .vm = { | 2168 | .vm = { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 2a45d548d5ec..8d787d115653 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -67,8 +67,9 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); | |||
67 | int r100_asic_reset(struct radeon_device *rdev); | 67 | int r100_asic_reset(struct radeon_device *rdev); |
68 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); | 68 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); |
69 | void r100_pci_gart_tlb_flush(struct radeon_device *rdev); | 69 | void r100_pci_gart_tlb_flush(struct radeon_device *rdev); |
70 | uint64_t r100_pci_gart_get_page_entry(uint64_t addr, uint32_t flags); | ||
70 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, | 71 | void r100_pci_gart_set_page(struct radeon_device *rdev, unsigned i, |
71 | uint64_t addr, uint32_t flags); | 72 | uint64_t entry); |
72 | void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); | 73 | void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); |
73 | int r100_irq_set(struct radeon_device *rdev); | 74 | int r100_irq_set(struct radeon_device *rdev); |
74 | int r100_irq_process(struct radeon_device *rdev); | 75 | int r100_irq_process(struct radeon_device *rdev); |
@@ -172,8 +173,9 @@ extern void r300_fence_ring_emit(struct radeon_device *rdev, | |||
172 | struct radeon_fence *fence); | 173 | struct radeon_fence *fence); |
173 | extern int r300_cs_parse(struct radeon_cs_parser *p); | 174 | extern int r300_cs_parse(struct radeon_cs_parser *p); |
174 | extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); | 175 | extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); |
176 | extern uint64_t rv370_pcie_gart_get_page_entry(uint64_t addr, uint32_t flags); | ||
175 | extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, | 177 | extern void rv370_pcie_gart_set_page(struct radeon_device *rdev, unsigned i, |
176 | uint64_t addr, uint32_t flags); | 178 | uint64_t entry); |
177 | extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); | 179 | extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); |
178 | extern int rv370_get_pcie_lanes(struct radeon_device *rdev); | 180 | extern int rv370_get_pcie_lanes(struct radeon_device *rdev); |
179 | extern void r300_set_reg_safe(struct radeon_device *rdev); | 181 | extern void r300_set_reg_safe(struct radeon_device *rdev); |
@@ -208,8 +210,9 @@ extern void rs400_fini(struct radeon_device *rdev); | |||
208 | extern int rs400_suspend(struct radeon_device *rdev); | 210 | extern int rs400_suspend(struct radeon_device *rdev); |
209 | extern int rs400_resume(struct radeon_device *rdev); | 211 | extern int rs400_resume(struct radeon_device *rdev); |
210 | void rs400_gart_tlb_flush(struct radeon_device *rdev); | 212 | void rs400_gart_tlb_flush(struct radeon_device *rdev); |
213 | uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags); | ||
211 | void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | 214 | void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, |
212 | uint64_t addr, uint32_t flags); | 215 | uint64_t entry); |
213 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 216 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
214 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 217 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
215 | int rs400_gart_init(struct radeon_device *rdev); | 218 | int rs400_gart_init(struct radeon_device *rdev); |
@@ -232,8 +235,9 @@ int rs600_irq_process(struct radeon_device *rdev); | |||
232 | void rs600_irq_disable(struct radeon_device *rdev); | 235 | void rs600_irq_disable(struct radeon_device *rdev); |
233 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); | 236 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); |
234 | void rs600_gart_tlb_flush(struct radeon_device *rdev); | 237 | void rs600_gart_tlb_flush(struct radeon_device *rdev); |
238 | uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags); | ||
235 | void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | 239 | void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, |
236 | uint64_t addr, uint32_t flags); | 240 | uint64_t entry); |
237 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 241 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
238 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 242 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
239 | void rs600_bandwidth_update(struct radeon_device *rdev); | 243 | void rs600_bandwidth_update(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0ec65168f331..bd7519fdd3f4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -774,6 +774,8 @@ int radeon_dummy_page_init(struct radeon_device *rdev) | |||
774 | rdev->dummy_page.page = NULL; | 774 | rdev->dummy_page.page = NULL; |
775 | return -ENOMEM; | 775 | return -ENOMEM; |
776 | } | 776 | } |
777 | rdev->dummy_page.entry = radeon_gart_get_page_entry(rdev->dummy_page.addr, | ||
778 | RADEON_GART_PAGE_DUMMY); | ||
777 | return 0; | 779 | return 0; |
778 | } | 780 | } |
779 | 781 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 84146d5901aa..5450fa95a47e 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -165,6 +165,19 @@ int radeon_gart_table_vram_pin(struct radeon_device *rdev) | |||
165 | radeon_bo_unpin(rdev->gart.robj); | 165 | radeon_bo_unpin(rdev->gart.robj); |
166 | radeon_bo_unreserve(rdev->gart.robj); | 166 | radeon_bo_unreserve(rdev->gart.robj); |
167 | rdev->gart.table_addr = gpu_addr; | 167 | rdev->gart.table_addr = gpu_addr; |
168 | |||
169 | if (!r) { | ||
170 | int i; | ||
171 | |||
172 | /* We might have dropped some GART table updates while it wasn't | ||
173 | * mapped, restore all entries | ||
174 | */ | ||
175 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) | ||
176 | radeon_gart_set_page(rdev, i, rdev->gart.pages_entry[i]); | ||
177 | mb(); | ||
178 | radeon_gart_tlb_flush(rdev); | ||
179 | } | ||
180 | |||
168 | return r; | 181 | return r; |
169 | } | 182 | } |
170 | 183 | ||
@@ -228,7 +241,6 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
228 | unsigned t; | 241 | unsigned t; |
229 | unsigned p; | 242 | unsigned p; |
230 | int i, j; | 243 | int i, j; |
231 | u64 page_base; | ||
232 | 244 | ||
233 | if (!rdev->gart.ready) { | 245 | if (!rdev->gart.ready) { |
234 | WARN(1, "trying to unbind memory from uninitialized GART !\n"); | 246 | WARN(1, "trying to unbind memory from uninitialized GART !\n"); |
@@ -239,14 +251,12 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset, | |||
239 | for (i = 0; i < pages; i++, p++) { | 251 | for (i = 0; i < pages; i++, p++) { |
240 | if (rdev->gart.pages[p]) { | 252 | if (rdev->gart.pages[p]) { |
241 | rdev->gart.pages[p] = NULL; | 253 | rdev->gart.pages[p] = NULL; |
242 | rdev->gart.pages_addr[p] = rdev->dummy_page.addr; | ||
243 | page_base = rdev->gart.pages_addr[p]; | ||
244 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 254 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
255 | rdev->gart.pages_entry[t] = rdev->dummy_page.entry; | ||
245 | if (rdev->gart.ptr) { | 256 | if (rdev->gart.ptr) { |
246 | radeon_gart_set_page(rdev, t, page_base, | 257 | radeon_gart_set_page(rdev, t, |
247 | RADEON_GART_PAGE_DUMMY); | 258 | rdev->dummy_page.entry); |
248 | } | 259 | } |
249 | page_base += RADEON_GPU_PAGE_SIZE; | ||
250 | } | 260 | } |
251 | } | 261 | } |
252 | } | 262 | } |
@@ -274,7 +284,7 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
274 | { | 284 | { |
275 | unsigned t; | 285 | unsigned t; |
276 | unsigned p; | 286 | unsigned p; |
277 | uint64_t page_base; | 287 | uint64_t page_base, page_entry; |
278 | int i, j; | 288 | int i, j; |
279 | 289 | ||
280 | if (!rdev->gart.ready) { | 290 | if (!rdev->gart.ready) { |
@@ -285,14 +295,15 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, | |||
285 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); | 295 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
286 | 296 | ||
287 | for (i = 0; i < pages; i++, p++) { | 297 | for (i = 0; i < pages; i++, p++) { |
288 | rdev->gart.pages_addr[p] = dma_addr[i]; | ||
289 | rdev->gart.pages[p] = pagelist[i]; | 298 | rdev->gart.pages[p] = pagelist[i]; |
290 | if (rdev->gart.ptr) { | 299 | page_base = dma_addr[i]; |
291 | page_base = rdev->gart.pages_addr[p]; | 300 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { |
292 | for (j = 0; j < (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); j++, t++) { | 301 | page_entry = radeon_gart_get_page_entry(page_base, flags); |
293 | radeon_gart_set_page(rdev, t, page_base, flags); | 302 | rdev->gart.pages_entry[t] = page_entry; |
294 | page_base += RADEON_GPU_PAGE_SIZE; | 303 | if (rdev->gart.ptr) { |
304 | radeon_gart_set_page(rdev, t, page_entry); | ||
295 | } | 305 | } |
306 | page_base += RADEON_GPU_PAGE_SIZE; | ||
296 | } | 307 | } |
297 | } | 308 | } |
298 | mb(); | 309 | mb(); |
@@ -334,16 +345,15 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
334 | radeon_gart_fini(rdev); | 345 | radeon_gart_fini(rdev); |
335 | return -ENOMEM; | 346 | return -ENOMEM; |
336 | } | 347 | } |
337 | rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * | 348 | rdev->gart.pages_entry = vmalloc(sizeof(uint64_t) * |
338 | rdev->gart.num_cpu_pages); | 349 | rdev->gart.num_gpu_pages); |
339 | if (rdev->gart.pages_addr == NULL) { | 350 | if (rdev->gart.pages_entry == NULL) { |
340 | radeon_gart_fini(rdev); | 351 | radeon_gart_fini(rdev); |
341 | return -ENOMEM; | 352 | return -ENOMEM; |
342 | } | 353 | } |
343 | /* set GART entry to point to the dummy page by default */ | 354 | /* set GART entry to point to the dummy page by default */ |
344 | for (i = 0; i < rdev->gart.num_cpu_pages; i++) { | 355 | for (i = 0; i < rdev->gart.num_gpu_pages; i++) |
345 | rdev->gart.pages_addr[i] = rdev->dummy_page.addr; | 356 | rdev->gart.pages_entry[i] = rdev->dummy_page.entry; |
346 | } | ||
347 | return 0; | 357 | return 0; |
348 | } | 358 | } |
349 | 359 | ||
@@ -356,15 +366,15 @@ int radeon_gart_init(struct radeon_device *rdev) | |||
356 | */ | 366 | */ |
357 | void radeon_gart_fini(struct radeon_device *rdev) | 367 | void radeon_gart_fini(struct radeon_device *rdev) |
358 | { | 368 | { |
359 | if (rdev->gart.pages && rdev->gart.pages_addr && rdev->gart.ready) { | 369 | if (rdev->gart.ready) { |
360 | /* unbind pages */ | 370 | /* unbind pages */ |
361 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); | 371 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
362 | } | 372 | } |
363 | rdev->gart.ready = false; | 373 | rdev->gart.ready = false; |
364 | vfree(rdev->gart.pages); | 374 | vfree(rdev->gart.pages); |
365 | vfree(rdev->gart.pages_addr); | 375 | vfree(rdev->gart.pages_entry); |
366 | rdev->gart.pages = NULL; | 376 | rdev->gart.pages = NULL; |
367 | rdev->gart.pages_addr = NULL; | 377 | rdev->gart.pages_entry = NULL; |
368 | 378 | ||
369 | radeon_dummy_page_fini(rdev); | 379 | radeon_dummy_page_fini(rdev); |
370 | } | 380 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index fe48f229043e..d0b4f7d1140d 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -394,10 +394,9 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
394 | return r; | 394 | return r; |
395 | } | 395 | } |
396 | 396 | ||
397 | static int radeon_mode_mmap(struct drm_file *filp, | 397 | int radeon_mode_dumb_mmap(struct drm_file *filp, |
398 | struct drm_device *dev, | 398 | struct drm_device *dev, |
399 | uint32_t handle, bool dumb, | 399 | uint32_t handle, uint64_t *offset_p) |
400 | uint64_t *offset_p) | ||
401 | { | 400 | { |
402 | struct drm_gem_object *gobj; | 401 | struct drm_gem_object *gobj; |
403 | struct radeon_bo *robj; | 402 | struct radeon_bo *robj; |
@@ -406,14 +405,6 @@ static int radeon_mode_mmap(struct drm_file *filp, | |||
406 | if (gobj == NULL) { | 405 | if (gobj == NULL) { |
407 | return -ENOENT; | 406 | return -ENOENT; |
408 | } | 407 | } |
409 | |||
410 | /* | ||
411 | * We don't allow dumb mmaps on objects created using another | ||
412 | * interface. | ||
413 | */ | ||
414 | WARN_ONCE(dumb && !(gobj->dumb || gobj->import_attach), | ||
415 | "Illegal dumb map of GPU buffer.\n"); | ||
416 | |||
417 | robj = gem_to_radeon_bo(gobj); | 408 | robj = gem_to_radeon_bo(gobj); |
418 | if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { | 409 | if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { |
419 | drm_gem_object_unreference_unlocked(gobj); | 410 | drm_gem_object_unreference_unlocked(gobj); |
@@ -424,20 +415,12 @@ static int radeon_mode_mmap(struct drm_file *filp, | |||
424 | return 0; | 415 | return 0; |
425 | } | 416 | } |
426 | 417 | ||
427 | int radeon_mode_dumb_mmap(struct drm_file *filp, | ||
428 | struct drm_device *dev, | ||
429 | uint32_t handle, uint64_t *offset_p) | ||
430 | { | ||
431 | return radeon_mode_mmap(filp, dev, handle, true, offset_p); | ||
432 | } | ||
433 | |||
434 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, | 418 | int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, |
435 | struct drm_file *filp) | 419 | struct drm_file *filp) |
436 | { | 420 | { |
437 | struct drm_radeon_gem_mmap *args = data; | 421 | struct drm_radeon_gem_mmap *args = data; |
438 | 422 | ||
439 | return radeon_mode_mmap(filp, dev, args->handle, false, | 423 | return radeon_mode_dumb_mmap(filp, dev, args->handle, &args->addr_ptr); |
440 | &args->addr_ptr); | ||
441 | } | 424 | } |
442 | 425 | ||
443 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, | 426 | int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, |
@@ -593,7 +576,7 @@ error_unreserve: | |||
593 | error_free: | 576 | error_free: |
594 | drm_free_large(vm_bos); | 577 | drm_free_large(vm_bos); |
595 | 578 | ||
596 | if (r) | 579 | if (r && r != -ERESTARTSYS) |
597 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); | 580 | DRM_ERROR("Couldn't update BO_VA (%d)\n", r); |
598 | } | 581 | } |
599 | 582 | ||
@@ -763,7 +746,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, | |||
763 | return -ENOMEM; | 746 | return -ENOMEM; |
764 | 747 | ||
765 | r = drm_gem_handle_create(file_priv, gobj, &handle); | 748 | r = drm_gem_handle_create(file_priv, gobj, &handle); |
766 | gobj->dumb = true; | ||
767 | /* drop reference from allocate - handle holds it now */ | 749 | /* drop reference from allocate - handle holds it now */ |
768 | drm_gem_object_unreference_unlocked(gobj); | 750 | drm_gem_object_unreference_unlocked(gobj); |
769 | if (r) { | 751 | if (r) { |
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 065d02068ec3..bef9a0953284 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "cikd.h" | 28 | #include "cikd.h" |
29 | #include "cik_reg.h" | 29 | #include "cik_reg.h" |
30 | #include "radeon_kfd.h" | 30 | #include "radeon_kfd.h" |
31 | #include "radeon_ucode.h" | ||
32 | #include <linux/firmware.h> | ||
31 | 33 | ||
32 | #define CIK_PIPE_PER_MEC (4) | 34 | #define CIK_PIPE_PER_MEC (4) |
33 | 35 | ||
@@ -49,6 +51,7 @@ static uint64_t get_vmem_size(struct kgd_dev *kgd); | |||
49 | static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); | 51 | static uint64_t get_gpu_clock_counter(struct kgd_dev *kgd); |
50 | 52 | ||
51 | static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); | 53 | static uint32_t get_max_engine_clock_in_mhz(struct kgd_dev *kgd); |
54 | static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type); | ||
52 | 55 | ||
53 | /* | 56 | /* |
54 | * Register access functions | 57 | * Register access functions |
@@ -69,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, | |||
69 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | 72 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
70 | uint32_t queue_id, uint32_t __user *wptr); | 73 | uint32_t queue_id, uint32_t __user *wptr); |
71 | 74 | ||
72 | static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | 75 | static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, |
73 | uint32_t pipe_id, uint32_t queue_id); | 76 | uint32_t pipe_id, uint32_t queue_id); |
74 | 77 | ||
75 | static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, | 78 | static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, |
@@ -89,14 +92,16 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
89 | .init_memory = kgd_init_memory, | 92 | .init_memory = kgd_init_memory, |
90 | .init_pipeline = kgd_init_pipeline, | 93 | .init_pipeline = kgd_init_pipeline, |
91 | .hqd_load = kgd_hqd_load, | 94 | .hqd_load = kgd_hqd_load, |
92 | .hqd_is_occupies = kgd_hqd_is_occupies, | 95 | .hqd_is_occupied = kgd_hqd_is_occupied, |
93 | .hqd_destroy = kgd_hqd_destroy, | 96 | .hqd_destroy = kgd_hqd_destroy, |
97 | .get_fw_version = get_fw_version | ||
94 | }; | 98 | }; |
95 | 99 | ||
96 | static const struct kgd2kfd_calls *kgd2kfd; | 100 | static const struct kgd2kfd_calls *kgd2kfd; |
97 | 101 | ||
98 | bool radeon_kfd_init(void) | 102 | bool radeon_kfd_init(void) |
99 | { | 103 | { |
104 | #if defined(CONFIG_HSA_AMD_MODULE) | ||
100 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, | 105 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, |
101 | const struct kgd2kfd_calls**); | 106 | const struct kgd2kfd_calls**); |
102 | 107 | ||
@@ -113,6 +118,17 @@ bool radeon_kfd_init(void) | |||
113 | } | 118 | } |
114 | 119 | ||
115 | return true; | 120 | return true; |
121 | #elif defined(CONFIG_HSA_AMD) | ||
122 | if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { | ||
123 | kgd2kfd = NULL; | ||
124 | |||
125 | return false; | ||
126 | } | ||
127 | |||
128 | return true; | ||
129 | #else | ||
130 | return false; | ||
131 | #endif | ||
116 | } | 132 | } |
117 | 133 | ||
118 | void radeon_kfd_fini(void) | 134 | void radeon_kfd_fini(void) |
@@ -374,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, | |||
374 | cpu_relax(); | 390 | cpu_relax(); |
375 | write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); | 391 | write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); |
376 | 392 | ||
393 | /* Mapping vmid to pasid also for IH block */ | ||
394 | write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), | ||
395 | pasid_mapping); | ||
396 | |||
377 | return 0; | 397 | return 0; |
378 | } | 398 | } |
379 | 399 | ||
@@ -416,7 +436,7 @@ static int kgd_init_memory(struct kgd_dev *kgd) | |||
416 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, | 436 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, |
417 | uint32_t hpd_size, uint64_t hpd_gpu_addr) | 437 | uint32_t hpd_size, uint64_t hpd_gpu_addr) |
418 | { | 438 | { |
419 | uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; | 439 | uint32_t mec = (pipe_id / CIK_PIPE_PER_MEC) + 1; |
420 | uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); | 440 | uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); |
421 | 441 | ||
422 | lock_srbm(kgd, mec, pipe, 0, 0); | 442 | lock_srbm(kgd, mec, pipe, 0, 0); |
@@ -513,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
513 | return 0; | 533 | return 0; |
514 | } | 534 | } |
515 | 535 | ||
516 | static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | 536 | static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, |
517 | uint32_t pipe_id, uint32_t queue_id) | 537 | uint32_t pipe_id, uint32_t queue_id) |
518 | { | 538 | { |
519 | uint32_t act; | 539 | uint32_t act; |
@@ -552,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, | |||
552 | if (timeout == 0) { | 572 | if (timeout == 0) { |
553 | pr_err("kfd: cp queue preemption time out (%dms)\n", | 573 | pr_err("kfd: cp queue preemption time out (%dms)\n", |
554 | temp); | 574 | temp); |
575 | release_queue(kgd); | ||
555 | return -ETIME; | 576 | return -ETIME; |
556 | } | 577 | } |
557 | msleep(20); | 578 | msleep(20); |
@@ -561,3 +582,52 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, | |||
561 | release_queue(kgd); | 582 | release_queue(kgd); |
562 | return 0; | 583 | return 0; |
563 | } | 584 | } |
585 | |||
586 | static uint16_t get_fw_version(struct kgd_dev *kgd, enum kgd_engine_type type) | ||
587 | { | ||
588 | struct radeon_device *rdev = (struct radeon_device *) kgd; | ||
589 | const union radeon_firmware_header *hdr; | ||
590 | |||
591 | BUG_ON(kgd == NULL || rdev->mec_fw == NULL); | ||
592 | |||
593 | switch (type) { | ||
594 | case KGD_ENGINE_PFP: | ||
595 | hdr = (const union radeon_firmware_header *) rdev->pfp_fw->data; | ||
596 | break; | ||
597 | |||
598 | case KGD_ENGINE_ME: | ||
599 | hdr = (const union radeon_firmware_header *) rdev->me_fw->data; | ||
600 | break; | ||
601 | |||
602 | case KGD_ENGINE_CE: | ||
603 | hdr = (const union radeon_firmware_header *) rdev->ce_fw->data; | ||
604 | break; | ||
605 | |||
606 | case KGD_ENGINE_MEC1: | ||
607 | hdr = (const union radeon_firmware_header *) rdev->mec_fw->data; | ||
608 | break; | ||
609 | |||
610 | case KGD_ENGINE_MEC2: | ||
611 | hdr = (const union radeon_firmware_header *) | ||
612 | rdev->mec2_fw->data; | ||
613 | break; | ||
614 | |||
615 | case KGD_ENGINE_RLC: | ||
616 | hdr = (const union radeon_firmware_header *) rdev->rlc_fw->data; | ||
617 | break; | ||
618 | |||
619 | case KGD_ENGINE_SDMA: | ||
620 | hdr = (const union radeon_firmware_header *) | ||
621 | rdev->sdma_fw->data; | ||
622 | break; | ||
623 | |||
624 | default: | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | if (hdr == NULL) | ||
629 | return 0; | ||
630 | |||
631 | /* Only 12 bit in use*/ | ||
632 | return hdr->common.ucode_version; | ||
633 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 7d68223eb469..86fc56434b28 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -529,9 +529,6 @@ int radeon_bo_list_validate(struct radeon_device *rdev, | |||
529 | u32 current_domain = | 529 | u32 current_domain = |
530 | radeon_mem_type_to_domain(bo->tbo.mem.mem_type); | 530 | radeon_mem_type_to_domain(bo->tbo.mem.mem_type); |
531 | 531 | ||
532 | WARN_ONCE(bo->gem_base.dumb, | ||
533 | "GPU use of dumb buffer is illegal.\n"); | ||
534 | |||
535 | /* Check if this buffer will be moved and don't move it | 532 | /* Check if this buffer will be moved and don't move it |
536 | * if we have moved too many buffers for this IB already. | 533 | * if we have moved too many buffers for this IB already. |
537 | * | 534 | * |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 32522cc940a1..f7da8fe96a66 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -1287,8 +1287,39 @@ dpm_failed: | |||
1287 | return ret; | 1287 | return ret; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | struct radeon_dpm_quirk { | ||
1291 | u32 chip_vendor; | ||
1292 | u32 chip_device; | ||
1293 | u32 subsys_vendor; | ||
1294 | u32 subsys_device; | ||
1295 | }; | ||
1296 | |||
1297 | /* cards with dpm stability problems */ | ||
1298 | static struct radeon_dpm_quirk radeon_dpm_quirk_list[] = { | ||
1299 | /* TURKS - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1386534 */ | ||
1300 | { PCI_VENDOR_ID_ATI, 0x6759, 0x1682, 0x3195 }, | ||
1301 | /* TURKS - https://bugzilla.kernel.org/show_bug.cgi?id=83731 */ | ||
1302 | { PCI_VENDOR_ID_ATI, 0x6840, 0x1179, 0xfb81 }, | ||
1303 | { 0, 0, 0, 0 }, | ||
1304 | }; | ||
1305 | |||
1290 | int radeon_pm_init(struct radeon_device *rdev) | 1306 | int radeon_pm_init(struct radeon_device *rdev) |
1291 | { | 1307 | { |
1308 | struct radeon_dpm_quirk *p = radeon_dpm_quirk_list; | ||
1309 | bool disable_dpm = false; | ||
1310 | |||
1311 | /* Apply dpm quirks */ | ||
1312 | while (p && p->chip_device != 0) { | ||
1313 | if (rdev->pdev->vendor == p->chip_vendor && | ||
1314 | rdev->pdev->device == p->chip_device && | ||
1315 | rdev->pdev->subsystem_vendor == p->subsys_vendor && | ||
1316 | rdev->pdev->subsystem_device == p->subsys_device) { | ||
1317 | disable_dpm = true; | ||
1318 | break; | ||
1319 | } | ||
1320 | ++p; | ||
1321 | } | ||
1322 | |||
1292 | /* enable dpm on rv6xx+ */ | 1323 | /* enable dpm on rv6xx+ */ |
1293 | switch (rdev->family) { | 1324 | switch (rdev->family) { |
1294 | case CHIP_RV610: | 1325 | case CHIP_RV610: |
@@ -1344,6 +1375,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1344 | (!(rdev->flags & RADEON_IS_IGP)) && | 1375 | (!(rdev->flags & RADEON_IS_IGP)) && |
1345 | (!rdev->smc_fw)) | 1376 | (!rdev->smc_fw)) |
1346 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1377 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1378 | else if (disable_dpm && (radeon_dpm == -1)) | ||
1379 | rdev->pm.pm_method = PM_METHOD_PROFILE; | ||
1347 | else if (radeon_dpm == 0) | 1380 | else if (radeon_dpm == 0) |
1348 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1381 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
1349 | else | 1382 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 535403e0c8a2..15aee723db77 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, | |||
1703 | u32 format; | 1703 | u32 format; |
1704 | u32 *buffer; | 1704 | u32 *buffer; |
1705 | const u8 __user *data; | 1705 | const u8 __user *data; |
1706 | int size, dwords, tex_width, blit_width, spitch; | 1706 | unsigned int size, dwords, tex_width, blit_width, spitch; |
1707 | u32 height; | 1707 | u32 height; |
1708 | int i; | 1708 | int i; |
1709 | u32 texpitch, microtile; | 1709 | u32 texpitch, microtile; |
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index cde48c42b30a..06d2246d07f1 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -587,10 +587,8 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) | |||
587 | uint64_t result; | 587 | uint64_t result; |
588 | 588 | ||
589 | /* page table offset */ | 589 | /* page table offset */ |
590 | result = rdev->gart.pages_addr[addr >> PAGE_SHIFT]; | 590 | result = rdev->gart.pages_entry[addr >> RADEON_GPU_PAGE_SHIFT]; |
591 | 591 | result &= ~RADEON_GPU_PAGE_MASK; | |
592 | /* in case cpu page size != gpu page size*/ | ||
593 | result |= addr & (~PAGE_MASK); | ||
594 | 592 | ||
595 | return result; | 593 | return result; |
596 | } | 594 | } |
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index c5799f16aa4b..34e3235f41d2 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -212,11 +212,9 @@ void rs400_gart_fini(struct radeon_device *rdev) | |||
212 | #define RS400_PTE_WRITEABLE (1 << 2) | 212 | #define RS400_PTE_WRITEABLE (1 << 2) |
213 | #define RS400_PTE_READABLE (1 << 3) | 213 | #define RS400_PTE_READABLE (1 << 3) |
214 | 214 | ||
215 | void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | 215 | uint64_t rs400_gart_get_page_entry(uint64_t addr, uint32_t flags) |
216 | uint64_t addr, uint32_t flags) | ||
217 | { | 216 | { |
218 | uint32_t entry; | 217 | uint32_t entry; |
219 | u32 *gtt = rdev->gart.ptr; | ||
220 | 218 | ||
221 | entry = (lower_32_bits(addr) & PAGE_MASK) | | 219 | entry = (lower_32_bits(addr) & PAGE_MASK) | |
222 | ((upper_32_bits(addr) & 0xff) << 4); | 220 | ((upper_32_bits(addr) & 0xff) << 4); |
@@ -226,8 +224,14 @@ void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | |||
226 | entry |= RS400_PTE_WRITEABLE; | 224 | entry |= RS400_PTE_WRITEABLE; |
227 | if (!(flags & RADEON_GART_PAGE_SNOOP)) | 225 | if (!(flags & RADEON_GART_PAGE_SNOOP)) |
228 | entry |= RS400_PTE_UNSNOOPED; | 226 | entry |= RS400_PTE_UNSNOOPED; |
229 | entry = cpu_to_le32(entry); | 227 | return entry; |
230 | gtt[i] = entry; | 228 | } |
229 | |||
230 | void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | ||
231 | uint64_t entry) | ||
232 | { | ||
233 | u32 *gtt = rdev->gart.ptr; | ||
234 | gtt[i] = cpu_to_le32(lower_32_bits(entry)); | ||
231 | } | 235 | } |
232 | 236 | ||
233 | int rs400_mc_wait_for_idle(struct radeon_device *rdev) | 237 | int rs400_mc_wait_for_idle(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 9acb1c3c005b..74bce91aecc1 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -625,11 +625,8 @@ static void rs600_gart_fini(struct radeon_device *rdev) | |||
625 | radeon_gart_table_vram_free(rdev); | 625 | radeon_gart_table_vram_free(rdev); |
626 | } | 626 | } |
627 | 627 | ||
628 | void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | 628 | uint64_t rs600_gart_get_page_entry(uint64_t addr, uint32_t flags) |
629 | uint64_t addr, uint32_t flags) | ||
630 | { | 629 | { |
631 | void __iomem *ptr = (void *)rdev->gart.ptr; | ||
632 | |||
633 | addr = addr & 0xFFFFFFFFFFFFF000ULL; | 630 | addr = addr & 0xFFFFFFFFFFFFF000ULL; |
634 | addr |= R600_PTE_SYSTEM; | 631 | addr |= R600_PTE_SYSTEM; |
635 | if (flags & RADEON_GART_PAGE_VALID) | 632 | if (flags & RADEON_GART_PAGE_VALID) |
@@ -640,7 +637,14 @@ void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | |||
640 | addr |= R600_PTE_WRITEABLE; | 637 | addr |= R600_PTE_WRITEABLE; |
641 | if (flags & RADEON_GART_PAGE_SNOOP) | 638 | if (flags & RADEON_GART_PAGE_SNOOP) |
642 | addr |= R600_PTE_SNOOPED; | 639 | addr |= R600_PTE_SNOOPED; |
643 | writeq(addr, ptr + (i * 8)); | 640 | return addr; |
641 | } | ||
642 | |||
643 | void rs600_gart_set_page(struct radeon_device *rdev, unsigned i, | ||
644 | uint64_t entry) | ||
645 | { | ||
646 | void __iomem *ptr = (void *)rdev->gart.ptr; | ||
647 | writeq(entry, ptr + (i * 8)); | ||
644 | } | 648 | } |
645 | 649 | ||
646 | int rs600_irq_set(struct radeon_device *rdev) | 650 | int rs600_irq_set(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 60df444bd075..5d89b874a1a2 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -5057,6 +5057,16 @@ void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
5057 | radeon_ring_write(ring, 0); | 5057 | radeon_ring_write(ring, 0); |
5058 | radeon_ring_write(ring, 1 << vm_id); | 5058 | radeon_ring_write(ring, 1 << vm_id); |
5059 | 5059 | ||
5060 | /* wait for the invalidate to complete */ | ||
5061 | radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); | ||
5062 | radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ | ||
5063 | WAIT_REG_MEM_ENGINE(0))); /* me */ | ||
5064 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); | ||
5065 | radeon_ring_write(ring, 0); | ||
5066 | radeon_ring_write(ring, 0); /* ref */ | ||
5067 | radeon_ring_write(ring, 0); /* mask */ | ||
5068 | radeon_ring_write(ring, 0x20); /* poll interval */ | ||
5069 | |||
5060 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ | 5070 | /* sync PFP to ME, otherwise we might get invalid PFP reads */ |
5061 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | 5071 | radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); |
5062 | radeon_ring_write(ring, 0x0); | 5072 | radeon_ring_write(ring, 0x0); |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index f5cc777e1c5f..83207929fc62 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
@@ -123,7 +123,6 @@ void si_dma_vm_write_pages(struct radeon_device *rdev, | |||
123 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { | 123 | for (; ndw > 0; ndw -= 2, --count, pe += 8) { |
124 | if (flags & R600_PTE_SYSTEM) { | 124 | if (flags & R600_PTE_SYSTEM) { |
125 | value = radeon_vm_map_gart(rdev, addr); | 125 | value = radeon_vm_map_gart(rdev, addr); |
126 | value &= 0xFFFFFFFFFFFFF000ULL; | ||
127 | } else if (flags & R600_PTE_VALID) { | 126 | } else if (flags & R600_PTE_VALID) { |
128 | value = addr; | 127 | value = addr; |
129 | } else { | 128 | } else { |
@@ -206,6 +205,14 @@ void si_dma_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, | |||
206 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | 205 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); |
207 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | 206 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); |
208 | radeon_ring_write(ring, 1 << vm_id); | 207 | radeon_ring_write(ring, 1 << vm_id); |
208 | |||
209 | /* wait for invalidate to complete */ | ||
210 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0)); | ||
211 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST); | ||
212 | radeon_ring_write(ring, 0xff << 16); /* retry */ | ||
213 | radeon_ring_write(ring, 1 << vm_id); /* mask */ | ||
214 | radeon_ring_write(ring, 0); /* value */ | ||
215 | radeon_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */ | ||
209 | } | 216 | } |
210 | 217 | ||
211 | /** | 218 | /** |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 32e354b8b0ab..eff8a6444956 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev) | |||
2908 | return ret; | 2908 | return ret; |
2909 | } | 2909 | } |
2910 | 2910 | ||
2911 | struct si_dpm_quirk { | ||
2912 | u32 chip_vendor; | ||
2913 | u32 chip_device; | ||
2914 | u32 subsys_vendor; | ||
2915 | u32 subsys_device; | ||
2916 | u32 max_sclk; | ||
2917 | u32 max_mclk; | ||
2918 | }; | ||
2919 | |||
2920 | /* cards with dpm stability problems */ | ||
2921 | static struct si_dpm_quirk si_dpm_quirk_list[] = { | ||
2922 | /* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */ | ||
2923 | { PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 }, | ||
2924 | { 0, 0, 0, 0 }, | ||
2925 | }; | ||
2926 | |||
2911 | static void si_apply_state_adjust_rules(struct radeon_device *rdev, | 2927 | static void si_apply_state_adjust_rules(struct radeon_device *rdev, |
2912 | struct radeon_ps *rps) | 2928 | struct radeon_ps *rps) |
2913 | { | 2929 | { |
@@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2918 | u32 mclk, sclk; | 2934 | u32 mclk, sclk; |
2919 | u16 vddc, vddci; | 2935 | u16 vddc, vddci; |
2920 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | 2936 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; |
2937 | u32 max_sclk = 0, max_mclk = 0; | ||
2921 | int i; | 2938 | int i; |
2939 | struct si_dpm_quirk *p = si_dpm_quirk_list; | ||
2940 | |||
2941 | /* Apply dpm quirks */ | ||
2942 | while (p && p->chip_device != 0) { | ||
2943 | if (rdev->pdev->vendor == p->chip_vendor && | ||
2944 | rdev->pdev->device == p->chip_device && | ||
2945 | rdev->pdev->subsystem_vendor == p->subsys_vendor && | ||
2946 | rdev->pdev->subsystem_device == p->subsys_device) { | ||
2947 | max_sclk = p->max_sclk; | ||
2948 | max_mclk = p->max_mclk; | ||
2949 | break; | ||
2950 | } | ||
2951 | ++p; | ||
2952 | } | ||
2922 | 2953 | ||
2923 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2954 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
2924 | ni_dpm_vblank_too_short(rdev)) | 2955 | ni_dpm_vblank_too_short(rdev)) |
@@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2972 | if (ps->performance_levels[i].mclk > max_mclk_vddc) | 3003 | if (ps->performance_levels[i].mclk > max_mclk_vddc) |
2973 | ps->performance_levels[i].mclk = max_mclk_vddc; | 3004 | ps->performance_levels[i].mclk = max_mclk_vddc; |
2974 | } | 3005 | } |
3006 | if (max_mclk) { | ||
3007 | if (ps->performance_levels[i].mclk > max_mclk) | ||
3008 | ps->performance_levels[i].mclk = max_mclk; | ||
3009 | } | ||
3010 | if (max_sclk) { | ||
3011 | if (ps->performance_levels[i].sclk > max_sclk) | ||
3012 | ps->performance_levels[i].sclk = max_sclk; | ||
3013 | } | ||
2975 | } | 3014 | } |
2976 | 3015 | ||
2977 | /* XXX validate the min clocks required for display */ | 3016 | /* XXX validate the min clocks required for display */ |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 4069be89e585..84999242c747 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -1632,6 +1632,23 @@ | |||
1632 | #define PACKET3_MPEG_INDEX 0x3A | 1632 | #define PACKET3_MPEG_INDEX 0x3A |
1633 | #define PACKET3_COPY_DW 0x3B | 1633 | #define PACKET3_COPY_DW 0x3B |
1634 | #define PACKET3_WAIT_REG_MEM 0x3C | 1634 | #define PACKET3_WAIT_REG_MEM 0x3C |
1635 | #define WAIT_REG_MEM_FUNCTION(x) ((x) << 0) | ||
1636 | /* 0 - always | ||
1637 | * 1 - < | ||
1638 | * 2 - <= | ||
1639 | * 3 - == | ||
1640 | * 4 - != | ||
1641 | * 5 - >= | ||
1642 | * 6 - > | ||
1643 | */ | ||
1644 | #define WAIT_REG_MEM_MEM_SPACE(x) ((x) << 4) | ||
1645 | /* 0 - reg | ||
1646 | * 1 - mem | ||
1647 | */ | ||
1648 | #define WAIT_REG_MEM_ENGINE(x) ((x) << 8) | ||
1649 | /* 0 - me | ||
1650 | * 1 - pfp | ||
1651 | */ | ||
1635 | #define PACKET3_MEM_WRITE 0x3D | 1652 | #define PACKET3_MEM_WRITE 0x3D |
1636 | #define PACKET3_COPY_DATA 0x40 | 1653 | #define PACKET3_COPY_DATA 0x40 |
1637 | #define PACKET3_CP_DMA 0x41 | 1654 | #define PACKET3_CP_DMA 0x41 |
@@ -1835,6 +1852,7 @@ | |||
1835 | #define DMA_PACKET_TRAP 0x7 | 1852 | #define DMA_PACKET_TRAP 0x7 |
1836 | #define DMA_PACKET_SRBM_WRITE 0x9 | 1853 | #define DMA_PACKET_SRBM_WRITE 0x9 |
1837 | #define DMA_PACKET_CONSTANT_FILL 0xd | 1854 | #define DMA_PACKET_CONSTANT_FILL 0xd |
1855 | #define DMA_PACKET_POLL_REG_MEM 0xe | ||
1838 | #define DMA_PACKET_NOP 0xf | 1856 | #define DMA_PACKET_NOP 0xf |
1839 | 1857 | ||
1840 | #define VCE_STATUS 0x20004 | 1858 | #define VCE_STATUS 0x20004 |
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 3367960286a6..978993fa3a36 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -168,7 +168,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, | |||
168 | const struct tegra_dc_window *window) | 168 | const struct tegra_dc_window *window) |
169 | { | 169 | { |
170 | unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; | 170 | unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; |
171 | unsigned long value; | 171 | unsigned long value, flags; |
172 | bool yuv, planar; | 172 | bool yuv, planar; |
173 | 173 | ||
174 | /* | 174 | /* |
@@ -181,6 +181,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, | |||
181 | else | 181 | else |
182 | bpp = planar ? 1 : 2; | 182 | bpp = planar ? 1 : 2; |
183 | 183 | ||
184 | spin_lock_irqsave(&dc->lock, flags); | ||
185 | |||
184 | value = WINDOW_A_SELECT << index; | 186 | value = WINDOW_A_SELECT << index; |
185 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); | 187 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); |
186 | 188 | ||
@@ -273,6 +275,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, | |||
273 | 275 | ||
274 | case TEGRA_BO_TILING_MODE_BLOCK: | 276 | case TEGRA_BO_TILING_MODE_BLOCK: |
275 | DRM_ERROR("hardware doesn't support block linear mode\n"); | 277 | DRM_ERROR("hardware doesn't support block linear mode\n"); |
278 | spin_unlock_irqrestore(&dc->lock, flags); | ||
276 | return -EINVAL; | 279 | return -EINVAL; |
277 | } | 280 | } |
278 | 281 | ||
@@ -331,6 +334,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index, | |||
331 | 334 | ||
332 | tegra_dc_window_commit(dc, index); | 335 | tegra_dc_window_commit(dc, index); |
333 | 336 | ||
337 | spin_unlock_irqrestore(&dc->lock, flags); | ||
338 | |||
334 | return 0; | 339 | return 0; |
335 | } | 340 | } |
336 | 341 | ||
@@ -338,11 +343,14 @@ static int tegra_window_plane_disable(struct drm_plane *plane) | |||
338 | { | 343 | { |
339 | struct tegra_dc *dc = to_tegra_dc(plane->crtc); | 344 | struct tegra_dc *dc = to_tegra_dc(plane->crtc); |
340 | struct tegra_plane *p = to_tegra_plane(plane); | 345 | struct tegra_plane *p = to_tegra_plane(plane); |
346 | unsigned long flags; | ||
341 | u32 value; | 347 | u32 value; |
342 | 348 | ||
343 | if (!plane->crtc) | 349 | if (!plane->crtc) |
344 | return 0; | 350 | return 0; |
345 | 351 | ||
352 | spin_lock_irqsave(&dc->lock, flags); | ||
353 | |||
346 | value = WINDOW_A_SELECT << p->index; | 354 | value = WINDOW_A_SELECT << p->index; |
347 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); | 355 | tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); |
348 | 356 | ||
@@ -352,6 +360,8 @@ static int tegra_window_plane_disable(struct drm_plane *plane) | |||
352 | 360 | ||
353 | tegra_dc_window_commit(dc, p->index); | 361 | tegra_dc_window_commit(dc, p->index); |
354 | 362 | ||
363 | spin_unlock_irqrestore(&dc->lock, flags); | ||
364 | |||
355 | return 0; | 365 | return 0; |
356 | } | 366 | } |
357 | 367 | ||
@@ -699,14 +709,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, | |||
699 | struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); | 709 | struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); |
700 | unsigned int h_offset = 0, v_offset = 0; | 710 | unsigned int h_offset = 0, v_offset = 0; |
701 | struct tegra_bo_tiling tiling; | 711 | struct tegra_bo_tiling tiling; |
712 | unsigned long value, flags; | ||
702 | unsigned int format, swap; | 713 | unsigned int format, swap; |
703 | unsigned long value; | ||
704 | int err; | 714 | int err; |
705 | 715 | ||
706 | err = tegra_fb_get_tiling(fb, &tiling); | 716 | err = tegra_fb_get_tiling(fb, &tiling); |
707 | if (err < 0) | 717 | if (err < 0) |
708 | return err; | 718 | return err; |
709 | 719 | ||
720 | spin_lock_irqsave(&dc->lock, flags); | ||
721 | |||
710 | tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); | 722 | tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); |
711 | 723 | ||
712 | value = fb->offsets[0] + y * fb->pitches[0] + | 724 | value = fb->offsets[0] + y * fb->pitches[0] + |
@@ -752,6 +764,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, | |||
752 | 764 | ||
753 | case TEGRA_BO_TILING_MODE_BLOCK: | 765 | case TEGRA_BO_TILING_MODE_BLOCK: |
754 | DRM_ERROR("hardware doesn't support block linear mode\n"); | 766 | DRM_ERROR("hardware doesn't support block linear mode\n"); |
767 | spin_unlock_irqrestore(&dc->lock, flags); | ||
755 | return -EINVAL; | 768 | return -EINVAL; |
756 | } | 769 | } |
757 | 770 | ||
@@ -778,6 +791,8 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y, | |||
778 | tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); | 791 | tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); |
779 | tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); | 792 | tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); |
780 | 793 | ||
794 | spin_unlock_irqrestore(&dc->lock, flags); | ||
795 | |||
781 | return 0; | 796 | return 0; |
782 | } | 797 | } |
783 | 798 | ||
@@ -814,23 +829,32 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc) | |||
814 | unsigned long flags, base; | 829 | unsigned long flags, base; |
815 | struct tegra_bo *bo; | 830 | struct tegra_bo *bo; |
816 | 831 | ||
817 | if (!dc->event) | 832 | spin_lock_irqsave(&drm->event_lock, flags); |
833 | |||
834 | if (!dc->event) { | ||
835 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
818 | return; | 836 | return; |
837 | } | ||
819 | 838 | ||
820 | bo = tegra_fb_get_plane(crtc->primary->fb, 0); | 839 | bo = tegra_fb_get_plane(crtc->primary->fb, 0); |
821 | 840 | ||
841 | spin_lock_irqsave(&dc->lock, flags); | ||
842 | |||
822 | /* check if new start address has been latched */ | 843 | /* check if new start address has been latched */ |
844 | tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); | ||
823 | tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); | 845 | tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); |
824 | base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); | 846 | base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); |
825 | tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); | 847 | tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); |
826 | 848 | ||
849 | spin_unlock_irqrestore(&dc->lock, flags); | ||
850 | |||
827 | if (base == bo->paddr + crtc->primary->fb->offsets[0]) { | 851 | if (base == bo->paddr + crtc->primary->fb->offsets[0]) { |
828 | spin_lock_irqsave(&drm->event_lock, flags); | 852 | drm_crtc_send_vblank_event(crtc, dc->event); |
829 | drm_send_vblank_event(drm, dc->pipe, dc->event); | 853 | drm_crtc_vblank_put(crtc); |
830 | drm_vblank_put(drm, dc->pipe); | ||
831 | dc->event = NULL; | 854 | dc->event = NULL; |
832 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
833 | } | 855 | } |
856 | |||
857 | spin_unlock_irqrestore(&drm->event_lock, flags); | ||
834 | } | 858 | } |
835 | 859 | ||
836 | void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) | 860 | void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) |
@@ -843,7 +867,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
843 | 867 | ||
844 | if (dc->event && dc->event->base.file_priv == file) { | 868 | if (dc->event && dc->event->base.file_priv == file) { |
845 | dc->event->base.destroy(&dc->event->base); | 869 | dc->event->base.destroy(&dc->event->base); |
846 | drm_vblank_put(drm, dc->pipe); | 870 | drm_crtc_vblank_put(crtc); |
847 | dc->event = NULL; | 871 | dc->event = NULL; |
848 | } | 872 | } |
849 | 873 | ||
@@ -853,16 +877,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
853 | static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 877 | static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
854 | struct drm_pending_vblank_event *event, uint32_t page_flip_flags) | 878 | struct drm_pending_vblank_event *event, uint32_t page_flip_flags) |
855 | { | 879 | { |
880 | unsigned int pipe = drm_crtc_index(crtc); | ||
856 | struct tegra_dc *dc = to_tegra_dc(crtc); | 881 | struct tegra_dc *dc = to_tegra_dc(crtc); |
857 | struct drm_device *drm = crtc->dev; | ||
858 | 882 | ||
859 | if (dc->event) | 883 | if (dc->event) |
860 | return -EBUSY; | 884 | return -EBUSY; |
861 | 885 | ||
862 | if (event) { | 886 | if (event) { |
863 | event->pipe = dc->pipe; | 887 | event->pipe = pipe; |
864 | dc->event = event; | 888 | dc->event = event; |
865 | drm_vblank_get(drm, dc->pipe); | 889 | drm_crtc_vblank_get(crtc); |
866 | } | 890 | } |
867 | 891 | ||
868 | tegra_dc_set_base(dc, 0, 0, fb); | 892 | tegra_dc_set_base(dc, 0, 0, fb); |
@@ -1127,7 +1151,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data) | |||
1127 | /* | 1151 | /* |
1128 | dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); | 1152 | dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); |
1129 | */ | 1153 | */ |
1130 | drm_handle_vblank(dc->base.dev, dc->pipe); | 1154 | drm_crtc_handle_vblank(&dc->base); |
1131 | tegra_dc_finish_page_flip(dc); | 1155 | tegra_dc_finish_page_flip(dc); |
1132 | } | 1156 | } |
1133 | 1157 | ||
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index e549afeece1f..d4f827593dfa 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c | |||
@@ -694,24 +694,28 @@ static const struct file_operations tegra_drm_fops = { | |||
694 | .llseek = noop_llseek, | 694 | .llseek = noop_llseek, |
695 | }; | 695 | }; |
696 | 696 | ||
697 | static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe) | 697 | static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, |
698 | unsigned int pipe) | ||
698 | { | 699 | { |
699 | struct drm_crtc *crtc; | 700 | struct drm_crtc *crtc; |
700 | 701 | ||
701 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { | 702 | list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { |
702 | struct tegra_dc *dc = to_tegra_dc(crtc); | 703 | if (pipe == drm_crtc_index(crtc)) |
703 | |||
704 | if (dc->pipe == pipe) | ||
705 | return crtc; | 704 | return crtc; |
706 | } | 705 | } |
707 | 706 | ||
708 | return NULL; | 707 | return NULL; |
709 | } | 708 | } |
710 | 709 | ||
711 | static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc) | 710 | static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) |
712 | { | 711 | { |
712 | struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); | ||
713 | |||
714 | if (!crtc) | ||
715 | return 0; | ||
716 | |||
713 | /* TODO: implement real hardware counter using syncpoints */ | 717 | /* TODO: implement real hardware counter using syncpoints */ |
714 | return drm_vblank_count(dev, crtc); | 718 | return drm_crtc_vblank_count(crtc); |
715 | } | 719 | } |
716 | 720 | ||
717 | static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) | 721 | static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) |
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index da32086cbeaf..8777b7f75791 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c | |||
@@ -216,32 +216,58 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo) | |||
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
219 | static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo, | 219 | static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo) |
220 | size_t size) | ||
221 | { | 220 | { |
221 | struct scatterlist *s; | ||
222 | struct sg_table *sgt; | ||
223 | unsigned int i; | ||
224 | |||
222 | bo->pages = drm_gem_get_pages(&bo->gem); | 225 | bo->pages = drm_gem_get_pages(&bo->gem); |
223 | if (IS_ERR(bo->pages)) | 226 | if (IS_ERR(bo->pages)) |
224 | return PTR_ERR(bo->pages); | 227 | return PTR_ERR(bo->pages); |
225 | 228 | ||
226 | bo->num_pages = size >> PAGE_SHIFT; | 229 | bo->num_pages = bo->gem.size >> PAGE_SHIFT; |
227 | 230 | ||
228 | bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); | 231 | sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); |
229 | if (IS_ERR(bo->sgt)) { | 232 | if (IS_ERR(sgt)) |
230 | drm_gem_put_pages(&bo->gem, bo->pages, false, false); | 233 | goto put_pages; |
231 | return PTR_ERR(bo->sgt); | 234 | |
235 | /* | ||
236 | * Fake up the SG table so that dma_map_sg() can be used to flush the | ||
237 | * pages associated with it. Note that this relies on the fact that | ||
238 | * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is | ||
239 | * only cache maintenance. | ||
240 | * | ||
241 | * TODO: Replace this by drm_clflash_sg() once it can be implemented | ||
242 | * without relying on symbols that are not exported. | ||
243 | */ | ||
244 | for_each_sg(sgt->sgl, s, sgt->nents, i) | ||
245 | sg_dma_address(s) = sg_phys(s); | ||
246 | |||
247 | if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) { | ||
248 | sgt = ERR_PTR(-ENOMEM); | ||
249 | goto release_sgt; | ||
232 | } | 250 | } |
233 | 251 | ||
252 | bo->sgt = sgt; | ||
253 | |||
234 | return 0; | 254 | return 0; |
255 | |||
256 | release_sgt: | ||
257 | sg_free_table(sgt); | ||
258 | kfree(sgt); | ||
259 | put_pages: | ||
260 | drm_gem_put_pages(&bo->gem, bo->pages, false, false); | ||
261 | return PTR_ERR(sgt); | ||
235 | } | 262 | } |
236 | 263 | ||
237 | static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, | 264 | static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo) |
238 | size_t size) | ||
239 | { | 265 | { |
240 | struct tegra_drm *tegra = drm->dev_private; | 266 | struct tegra_drm *tegra = drm->dev_private; |
241 | int err; | 267 | int err; |
242 | 268 | ||
243 | if (tegra->domain) { | 269 | if (tegra->domain) { |
244 | err = tegra_bo_get_pages(drm, bo, size); | 270 | err = tegra_bo_get_pages(drm, bo); |
245 | if (err < 0) | 271 | if (err < 0) |
246 | return err; | 272 | return err; |
247 | 273 | ||
@@ -251,6 +277,8 @@ static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, | |||
251 | return err; | 277 | return err; |
252 | } | 278 | } |
253 | } else { | 279 | } else { |
280 | size_t size = bo->gem.size; | ||
281 | |||
254 | bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, | 282 | bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, |
255 | GFP_KERNEL | __GFP_NOWARN); | 283 | GFP_KERNEL | __GFP_NOWARN); |
256 | if (!bo->vaddr) { | 284 | if (!bo->vaddr) { |
@@ -274,7 +302,7 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size, | |||
274 | if (IS_ERR(bo)) | 302 | if (IS_ERR(bo)) |
275 | return bo; | 303 | return bo; |
276 | 304 | ||
277 | err = tegra_bo_alloc(drm, bo, size); | 305 | err = tegra_bo_alloc(drm, bo); |
278 | if (err < 0) | 306 | if (err < 0) |
279 | goto release; | 307 | goto release; |
280 | 308 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 7b5d22110f25..6c6b655defcf 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -406,11 +406,9 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv, | |||
406 | if (unlikely(ret != 0)) | 406 | if (unlikely(ret != 0)) |
407 | --dev_priv->num_3d_resources; | 407 | --dev_priv->num_3d_resources; |
408 | } else if (unhide_svga) { | 408 | } else if (unhide_svga) { |
409 | mutex_lock(&dev_priv->hw_mutex); | ||
410 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 409 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
411 | vmw_read(dev_priv, SVGA_REG_ENABLE) & | 410 | vmw_read(dev_priv, SVGA_REG_ENABLE) & |
412 | ~SVGA_REG_ENABLE_HIDE); | 411 | ~SVGA_REG_ENABLE_HIDE); |
413 | mutex_unlock(&dev_priv->hw_mutex); | ||
414 | } | 412 | } |
415 | 413 | ||
416 | mutex_unlock(&dev_priv->release_mutex); | 414 | mutex_unlock(&dev_priv->release_mutex); |
@@ -433,13 +431,10 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv, | |||
433 | mutex_lock(&dev_priv->release_mutex); | 431 | mutex_lock(&dev_priv->release_mutex); |
434 | if (unlikely(--dev_priv->num_3d_resources == 0)) | 432 | if (unlikely(--dev_priv->num_3d_resources == 0)) |
435 | vmw_release_device(dev_priv); | 433 | vmw_release_device(dev_priv); |
436 | else if (hide_svga) { | 434 | else if (hide_svga) |
437 | mutex_lock(&dev_priv->hw_mutex); | ||
438 | vmw_write(dev_priv, SVGA_REG_ENABLE, | 435 | vmw_write(dev_priv, SVGA_REG_ENABLE, |
439 | vmw_read(dev_priv, SVGA_REG_ENABLE) | | 436 | vmw_read(dev_priv, SVGA_REG_ENABLE) | |
440 | SVGA_REG_ENABLE_HIDE); | 437 | SVGA_REG_ENABLE_HIDE); |
441 | mutex_unlock(&dev_priv->hw_mutex); | ||
442 | } | ||
443 | 438 | ||
444 | n3d = (int32_t) dev_priv->num_3d_resources; | 439 | n3d = (int32_t) dev_priv->num_3d_resources; |
445 | mutex_unlock(&dev_priv->release_mutex); | 440 | mutex_unlock(&dev_priv->release_mutex); |
@@ -600,12 +595,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
600 | dev_priv->dev = dev; | 595 | dev_priv->dev = dev; |
601 | dev_priv->vmw_chipset = chipset; | 596 | dev_priv->vmw_chipset = chipset; |
602 | dev_priv->last_read_seqno = (uint32_t) -100; | 597 | dev_priv->last_read_seqno = (uint32_t) -100; |
603 | mutex_init(&dev_priv->hw_mutex); | ||
604 | mutex_init(&dev_priv->cmdbuf_mutex); | 598 | mutex_init(&dev_priv->cmdbuf_mutex); |
605 | mutex_init(&dev_priv->release_mutex); | 599 | mutex_init(&dev_priv->release_mutex); |
606 | mutex_init(&dev_priv->binding_mutex); | 600 | mutex_init(&dev_priv->binding_mutex); |
607 | rwlock_init(&dev_priv->resource_lock); | 601 | rwlock_init(&dev_priv->resource_lock); |
608 | ttm_lock_init(&dev_priv->reservation_sem); | 602 | ttm_lock_init(&dev_priv->reservation_sem); |
603 | spin_lock_init(&dev_priv->hw_lock); | ||
604 | spin_lock_init(&dev_priv->waiter_lock); | ||
605 | spin_lock_init(&dev_priv->cap_lock); | ||
609 | 606 | ||
610 | for (i = vmw_res_context; i < vmw_res_max; ++i) { | 607 | for (i = vmw_res_context; i < vmw_res_max; ++i) { |
611 | idr_init(&dev_priv->res_idr[i]); | 608 | idr_init(&dev_priv->res_idr[i]); |
@@ -626,14 +623,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
626 | 623 | ||
627 | dev_priv->enable_fb = enable_fbdev; | 624 | dev_priv->enable_fb = enable_fbdev; |
628 | 625 | ||
629 | mutex_lock(&dev_priv->hw_mutex); | ||
630 | |||
631 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 626 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
632 | svga_id = vmw_read(dev_priv, SVGA_REG_ID); | 627 | svga_id = vmw_read(dev_priv, SVGA_REG_ID); |
633 | if (svga_id != SVGA_ID_2) { | 628 | if (svga_id != SVGA_ID_2) { |
634 | ret = -ENOSYS; | 629 | ret = -ENOSYS; |
635 | DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); | 630 | DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); |
636 | mutex_unlock(&dev_priv->hw_mutex); | ||
637 | goto out_err0; | 631 | goto out_err0; |
638 | } | 632 | } |
639 | 633 | ||
@@ -683,10 +677,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
683 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 677 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
684 | 678 | ||
685 | ret = vmw_dma_masks(dev_priv); | 679 | ret = vmw_dma_masks(dev_priv); |
686 | if (unlikely(ret != 0)) { | 680 | if (unlikely(ret != 0)) |
687 | mutex_unlock(&dev_priv->hw_mutex); | ||
688 | goto out_err0; | 681 | goto out_err0; |
689 | } | ||
690 | 682 | ||
691 | /* | 683 | /* |
692 | * Limit back buffer size to VRAM size. Remove this once | 684 | * Limit back buffer size to VRAM size. Remove this once |
@@ -695,8 +687,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
695 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) | 687 | if (dev_priv->prim_bb_mem > dev_priv->vram_size) |
696 | dev_priv->prim_bb_mem = dev_priv->vram_size; | 688 | dev_priv->prim_bb_mem = dev_priv->vram_size; |
697 | 689 | ||
698 | mutex_unlock(&dev_priv->hw_mutex); | ||
699 | |||
700 | vmw_print_capabilities(dev_priv->capabilities); | 690 | vmw_print_capabilities(dev_priv->capabilities); |
701 | 691 | ||
702 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { | 692 | if (dev_priv->capabilities & SVGA_CAP_GMR2) { |
@@ -1160,9 +1150,7 @@ static int vmw_master_set(struct drm_device *dev, | |||
1160 | if (unlikely(ret != 0)) | 1150 | if (unlikely(ret != 0)) |
1161 | return ret; | 1151 | return ret; |
1162 | vmw_kms_save_vga(dev_priv); | 1152 | vmw_kms_save_vga(dev_priv); |
1163 | mutex_lock(&dev_priv->hw_mutex); | ||
1164 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); | 1153 | vmw_write(dev_priv, SVGA_REG_TRACES, 0); |
1165 | mutex_unlock(&dev_priv->hw_mutex); | ||
1166 | } | 1154 | } |
1167 | 1155 | ||
1168 | if (active) { | 1156 | if (active) { |
@@ -1196,9 +1184,7 @@ out_no_active_lock: | |||
1196 | if (!dev_priv->enable_fb) { | 1184 | if (!dev_priv->enable_fb) { |
1197 | vmw_kms_restore_vga(dev_priv); | 1185 | vmw_kms_restore_vga(dev_priv); |
1198 | vmw_3d_resource_dec(dev_priv, true); | 1186 | vmw_3d_resource_dec(dev_priv, true); |
1199 | mutex_lock(&dev_priv->hw_mutex); | ||
1200 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 1187 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
1201 | mutex_unlock(&dev_priv->hw_mutex); | ||
1202 | } | 1188 | } |
1203 | return ret; | 1189 | return ret; |
1204 | } | 1190 | } |
@@ -1233,9 +1219,7 @@ static void vmw_master_drop(struct drm_device *dev, | |||
1233 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); | 1219 | DRM_ERROR("Unable to clean VRAM on master drop.\n"); |
1234 | vmw_kms_restore_vga(dev_priv); | 1220 | vmw_kms_restore_vga(dev_priv); |
1235 | vmw_3d_resource_dec(dev_priv, true); | 1221 | vmw_3d_resource_dec(dev_priv, true); |
1236 | mutex_lock(&dev_priv->hw_mutex); | ||
1237 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); | 1222 | vmw_write(dev_priv, SVGA_REG_TRACES, 1); |
1238 | mutex_unlock(&dev_priv->hw_mutex); | ||
1239 | } | 1223 | } |
1240 | 1224 | ||
1241 | dev_priv->active_master = &dev_priv->fbdev_master; | 1225 | dev_priv->active_master = &dev_priv->fbdev_master; |
@@ -1367,10 +1351,8 @@ static void vmw_pm_complete(struct device *kdev) | |||
1367 | struct drm_device *dev = pci_get_drvdata(pdev); | 1351 | struct drm_device *dev = pci_get_drvdata(pdev); |
1368 | struct vmw_private *dev_priv = vmw_priv(dev); | 1352 | struct vmw_private *dev_priv = vmw_priv(dev); |
1369 | 1353 | ||
1370 | mutex_lock(&dev_priv->hw_mutex); | ||
1371 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | 1354 | vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); |
1372 | (void) vmw_read(dev_priv, SVGA_REG_ID); | 1355 | (void) vmw_read(dev_priv, SVGA_REG_ID); |
1373 | mutex_unlock(&dev_priv->hw_mutex); | ||
1374 | 1356 | ||
1375 | /** | 1357 | /** |
1376 | * Reclaim 3d reference held by fbdev and potentially | 1358 | * Reclaim 3d reference held by fbdev and potentially |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 4ee799b43d5d..d26a6daa9719 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -399,7 +399,8 @@ struct vmw_private { | |||
399 | uint32_t memory_size; | 399 | uint32_t memory_size; |
400 | bool has_gmr; | 400 | bool has_gmr; |
401 | bool has_mob; | 401 | bool has_mob; |
402 | struct mutex hw_mutex; | 402 | spinlock_t hw_lock; |
403 | spinlock_t cap_lock; | ||
403 | 404 | ||
404 | /* | 405 | /* |
405 | * VGA registers. | 406 | * VGA registers. |
@@ -449,8 +450,9 @@ struct vmw_private { | |||
449 | atomic_t marker_seq; | 450 | atomic_t marker_seq; |
450 | wait_queue_head_t fence_queue; | 451 | wait_queue_head_t fence_queue; |
451 | wait_queue_head_t fifo_queue; | 452 | wait_queue_head_t fifo_queue; |
452 | int fence_queue_waiters; /* Protected by hw_mutex */ | 453 | spinlock_t waiter_lock; |
453 | int goal_queue_waiters; /* Protected by hw_mutex */ | 454 | int fence_queue_waiters; /* Protected by waiter_lock */ |
455 | int goal_queue_waiters; /* Protected by waiter_lock */ | ||
454 | atomic_t fifo_queue_waiters; | 456 | atomic_t fifo_queue_waiters; |
455 | uint32_t last_read_seqno; | 457 | uint32_t last_read_seqno; |
456 | spinlock_t irq_lock; | 458 | spinlock_t irq_lock; |
@@ -553,20 +555,35 @@ static inline struct vmw_master *vmw_master(struct drm_master *master) | |||
553 | return (struct vmw_master *) master->driver_priv; | 555 | return (struct vmw_master *) master->driver_priv; |
554 | } | 556 | } |
555 | 557 | ||
558 | /* | ||
559 | * The locking here is fine-grained, so that it is performed once | ||
560 | * for every read- and write operation. This is of course costly, but we | ||
561 | * don't perform much register access in the timing critical paths anyway. | ||
562 | * Instead we have the extra benefit of being sure that we don't forget | ||
563 | * the hw lock around register accesses. | ||
564 | */ | ||
556 | static inline void vmw_write(struct vmw_private *dev_priv, | 565 | static inline void vmw_write(struct vmw_private *dev_priv, |
557 | unsigned int offset, uint32_t value) | 566 | unsigned int offset, uint32_t value) |
558 | { | 567 | { |
568 | unsigned long irq_flags; | ||
569 | |||
570 | spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | ||
559 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); | 571 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
560 | outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); | 572 | outl(value, dev_priv->io_start + VMWGFX_VALUE_PORT); |
573 | spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | ||
561 | } | 574 | } |
562 | 575 | ||
563 | static inline uint32_t vmw_read(struct vmw_private *dev_priv, | 576 | static inline uint32_t vmw_read(struct vmw_private *dev_priv, |
564 | unsigned int offset) | 577 | unsigned int offset) |
565 | { | 578 | { |
566 | uint32_t val; | 579 | unsigned long irq_flags; |
580 | u32 val; | ||
567 | 581 | ||
582 | spin_lock_irqsave(&dev_priv->hw_lock, irq_flags); | ||
568 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); | 583 | outl(offset, dev_priv->io_start + VMWGFX_INDEX_PORT); |
569 | val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); | 584 | val = inl(dev_priv->io_start + VMWGFX_VALUE_PORT); |
585 | spin_unlock_irqrestore(&dev_priv->hw_lock, irq_flags); | ||
586 | |||
570 | return val; | 587 | return val; |
571 | } | 588 | } |
572 | 589 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index b7594cb758af..945f1e0dad92 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | |||
@@ -35,7 +35,7 @@ struct vmw_fence_manager { | |||
35 | struct vmw_private *dev_priv; | 35 | struct vmw_private *dev_priv; |
36 | spinlock_t lock; | 36 | spinlock_t lock; |
37 | struct list_head fence_list; | 37 | struct list_head fence_list; |
38 | struct work_struct work, ping_work; | 38 | struct work_struct work; |
39 | u32 user_fence_size; | 39 | u32 user_fence_size; |
40 | u32 fence_size; | 40 | u32 fence_size; |
41 | u32 event_fence_action_size; | 41 | u32 event_fence_action_size; |
@@ -134,14 +134,6 @@ static const char *vmw_fence_get_timeline_name(struct fence *f) | |||
134 | return "svga"; | 134 | return "svga"; |
135 | } | 135 | } |
136 | 136 | ||
137 | static void vmw_fence_ping_func(struct work_struct *work) | ||
138 | { | ||
139 | struct vmw_fence_manager *fman = | ||
140 | container_of(work, struct vmw_fence_manager, ping_work); | ||
141 | |||
142 | vmw_fifo_ping_host(fman->dev_priv, SVGA_SYNC_GENERIC); | ||
143 | } | ||
144 | |||
145 | static bool vmw_fence_enable_signaling(struct fence *f) | 137 | static bool vmw_fence_enable_signaling(struct fence *f) |
146 | { | 138 | { |
147 | struct vmw_fence_obj *fence = | 139 | struct vmw_fence_obj *fence = |
@@ -155,11 +147,7 @@ static bool vmw_fence_enable_signaling(struct fence *f) | |||
155 | if (seqno - fence->base.seqno < VMW_FENCE_WRAP) | 147 | if (seqno - fence->base.seqno < VMW_FENCE_WRAP) |
156 | return false; | 148 | return false; |
157 | 149 | ||
158 | if (mutex_trylock(&dev_priv->hw_mutex)) { | 150 | vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); |
159 | vmw_fifo_ping_host_locked(dev_priv, SVGA_SYNC_GENERIC); | ||
160 | mutex_unlock(&dev_priv->hw_mutex); | ||
161 | } else | ||
162 | schedule_work(&fman->ping_work); | ||
163 | 151 | ||
164 | return true; | 152 | return true; |
165 | } | 153 | } |
@@ -305,7 +293,6 @@ struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) | |||
305 | INIT_LIST_HEAD(&fman->fence_list); | 293 | INIT_LIST_HEAD(&fman->fence_list); |
306 | INIT_LIST_HEAD(&fman->cleanup_list); | 294 | INIT_LIST_HEAD(&fman->cleanup_list); |
307 | INIT_WORK(&fman->work, &vmw_fence_work_func); | 295 | INIT_WORK(&fman->work, &vmw_fence_work_func); |
308 | INIT_WORK(&fman->ping_work, &vmw_fence_ping_func); | ||
309 | fman->fifo_down = true; | 296 | fman->fifo_down = true; |
310 | fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); | 297 | fman->user_fence_size = ttm_round_pot(sizeof(struct vmw_user_fence)); |
311 | fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); | 298 | fman->fence_size = ttm_round_pot(sizeof(struct vmw_fence_obj)); |
@@ -323,7 +310,6 @@ void vmw_fence_manager_takedown(struct vmw_fence_manager *fman) | |||
323 | bool lists_empty; | 310 | bool lists_empty; |
324 | 311 | ||
325 | (void) cancel_work_sync(&fman->work); | 312 | (void) cancel_work_sync(&fman->work); |
326 | (void) cancel_work_sync(&fman->ping_work); | ||
327 | 313 | ||
328 | spin_lock_irqsave(&fman->lock, irq_flags); | 314 | spin_lock_irqsave(&fman->lock, irq_flags); |
329 | lists_empty = list_empty(&fman->fence_list) && | 315 | lists_empty = list_empty(&fman->fence_list) && |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 09e10aefcd8e..39f2b03888e7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -44,10 +44,10 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | |||
44 | if (!dev_priv->has_mob) | 44 | if (!dev_priv->has_mob) |
45 | return false; | 45 | return false; |
46 | 46 | ||
47 | mutex_lock(&dev_priv->hw_mutex); | 47 | spin_lock(&dev_priv->cap_lock); |
48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); | 48 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_3D); |
49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 49 | result = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
50 | mutex_unlock(&dev_priv->hw_mutex); | 50 | spin_unlock(&dev_priv->cap_lock); |
51 | 51 | ||
52 | return (result != 0); | 52 | return (result != 0); |
53 | } | 53 | } |
@@ -120,7 +120,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
120 | DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); | 120 | DRM_INFO("height %d\n", vmw_read(dev_priv, SVGA_REG_HEIGHT)); |
121 | DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); | 121 | DRM_INFO("bpp %d\n", vmw_read(dev_priv, SVGA_REG_BITS_PER_PIXEL)); |
122 | 122 | ||
123 | mutex_lock(&dev_priv->hw_mutex); | ||
124 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); | 123 | dev_priv->enable_state = vmw_read(dev_priv, SVGA_REG_ENABLE); |
125 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); | 124 | dev_priv->config_done_state = vmw_read(dev_priv, SVGA_REG_CONFIG_DONE); |
126 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); | 125 | dev_priv->traces_state = vmw_read(dev_priv, SVGA_REG_TRACES); |
@@ -143,7 +142,6 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
143 | mb(); | 142 | mb(); |
144 | 143 | ||
145 | vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); | 144 | vmw_write(dev_priv, SVGA_REG_CONFIG_DONE, 1); |
146 | mutex_unlock(&dev_priv->hw_mutex); | ||
147 | 145 | ||
148 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); | 146 | max = ioread32(fifo_mem + SVGA_FIFO_MAX); |
149 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); | 147 | min = ioread32(fifo_mem + SVGA_FIFO_MIN); |
@@ -160,31 +158,28 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
160 | return vmw_fifo_send_fence(dev_priv, &dummy); | 158 | return vmw_fifo_send_fence(dev_priv, &dummy); |
161 | } | 159 | } |
162 | 160 | ||
163 | void vmw_fifo_ping_host_locked(struct vmw_private *dev_priv, uint32_t reason) | 161 | void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) |
164 | { | 162 | { |
165 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 163 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
164 | static DEFINE_SPINLOCK(ping_lock); | ||
165 | unsigned long irq_flags; | ||
166 | 166 | ||
167 | /* | ||
168 | * The ping_lock is needed because we don't have an atomic | ||
169 | * test-and-set of the SVGA_FIFO_BUSY register. | ||
170 | */ | ||
171 | spin_lock_irqsave(&ping_lock, irq_flags); | ||
167 | if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { | 172 | if (unlikely(ioread32(fifo_mem + SVGA_FIFO_BUSY) == 0)) { |
168 | iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); | 173 | iowrite32(1, fifo_mem + SVGA_FIFO_BUSY); |
169 | vmw_write(dev_priv, SVGA_REG_SYNC, reason); | 174 | vmw_write(dev_priv, SVGA_REG_SYNC, reason); |
170 | } | 175 | } |
171 | } | 176 | spin_unlock_irqrestore(&ping_lock, irq_flags); |
172 | |||
173 | void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) | ||
174 | { | ||
175 | mutex_lock(&dev_priv->hw_mutex); | ||
176 | |||
177 | vmw_fifo_ping_host_locked(dev_priv, reason); | ||
178 | |||
179 | mutex_unlock(&dev_priv->hw_mutex); | ||
180 | } | 177 | } |
181 | 178 | ||
182 | void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | 179 | void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) |
183 | { | 180 | { |
184 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 181 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
185 | 182 | ||
186 | mutex_lock(&dev_priv->hw_mutex); | ||
187 | |||
188 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); | 183 | vmw_write(dev_priv, SVGA_REG_SYNC, SVGA_SYNC_GENERIC); |
189 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) | 184 | while (vmw_read(dev_priv, SVGA_REG_BUSY) != 0) |
190 | ; | 185 | ; |
@@ -198,7 +193,6 @@ void vmw_fifo_release(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) | |||
198 | vmw_write(dev_priv, SVGA_REG_TRACES, | 193 | vmw_write(dev_priv, SVGA_REG_TRACES, |
199 | dev_priv->traces_state); | 194 | dev_priv->traces_state); |
200 | 195 | ||
201 | mutex_unlock(&dev_priv->hw_mutex); | ||
202 | vmw_marker_queue_takedown(&fifo->marker_queue); | 196 | vmw_marker_queue_takedown(&fifo->marker_queue); |
203 | 197 | ||
204 | if (likely(fifo->static_buffer != NULL)) { | 198 | if (likely(fifo->static_buffer != NULL)) { |
@@ -271,7 +265,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
271 | return vmw_fifo_wait_noirq(dev_priv, bytes, | 265 | return vmw_fifo_wait_noirq(dev_priv, bytes, |
272 | interruptible, timeout); | 266 | interruptible, timeout); |
273 | 267 | ||
274 | mutex_lock(&dev_priv->hw_mutex); | 268 | spin_lock(&dev_priv->waiter_lock); |
275 | if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { | 269 | if (atomic_add_return(1, &dev_priv->fifo_queue_waiters) > 0) { |
276 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); | 270 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
277 | outl(SVGA_IRQFLAG_FIFO_PROGRESS, | 271 | outl(SVGA_IRQFLAG_FIFO_PROGRESS, |
@@ -280,7 +274,7 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
280 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 274 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
281 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 275 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
282 | } | 276 | } |
283 | mutex_unlock(&dev_priv->hw_mutex); | 277 | spin_unlock(&dev_priv->waiter_lock); |
284 | 278 | ||
285 | if (interruptible) | 279 | if (interruptible) |
286 | ret = wait_event_interruptible_timeout | 280 | ret = wait_event_interruptible_timeout |
@@ -296,14 +290,14 @@ static int vmw_fifo_wait(struct vmw_private *dev_priv, | |||
296 | else if (likely(ret > 0)) | 290 | else if (likely(ret > 0)) |
297 | ret = 0; | 291 | ret = 0; |
298 | 292 | ||
299 | mutex_lock(&dev_priv->hw_mutex); | 293 | spin_lock(&dev_priv->waiter_lock); |
300 | if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { | 294 | if (atomic_dec_and_test(&dev_priv->fifo_queue_waiters)) { |
301 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); | 295 | spin_lock_irqsave(&dev_priv->irq_lock, irq_flags); |
302 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FIFO_PROGRESS; | 296 | dev_priv->irq_mask &= ~SVGA_IRQFLAG_FIFO_PROGRESS; |
303 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 297 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
304 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 298 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
305 | } | 299 | } |
306 | mutex_unlock(&dev_priv->hw_mutex); | 300 | spin_unlock(&dev_priv->waiter_lock); |
307 | 301 | ||
308 | return ret; | 302 | return ret; |
309 | } | 303 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 37881ecf5d7a..69c8ce23123c 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -135,13 +135,13 @@ static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, | |||
135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); | 135 | (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); |
136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; | 136 | compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; |
137 | 137 | ||
138 | mutex_lock(&dev_priv->hw_mutex); | 138 | spin_lock(&dev_priv->cap_lock); |
139 | for (i = 0; i < max_size; ++i) { | 139 | for (i = 0; i < max_size; ++i) { |
140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 140 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
141 | compat_cap->pairs[i][0] = i; | 141 | compat_cap->pairs[i][0] = i; |
142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 142 | compat_cap->pairs[i][1] = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
143 | } | 143 | } |
144 | mutex_unlock(&dev_priv->hw_mutex); | 144 | spin_unlock(&dev_priv->cap_lock); |
145 | 145 | ||
146 | return 0; | 146 | return 0; |
147 | } | 147 | } |
@@ -191,12 +191,12 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, | |||
191 | if (num > SVGA3D_DEVCAP_MAX) | 191 | if (num > SVGA3D_DEVCAP_MAX) |
192 | num = SVGA3D_DEVCAP_MAX; | 192 | num = SVGA3D_DEVCAP_MAX; |
193 | 193 | ||
194 | mutex_lock(&dev_priv->hw_mutex); | 194 | spin_lock(&dev_priv->cap_lock); |
195 | for (i = 0; i < num; ++i) { | 195 | for (i = 0; i < num; ++i) { |
196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); | 196 | vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); |
197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); | 197 | *bounce32++ = vmw_read(dev_priv, SVGA_REG_DEV_CAP); |
198 | } | 198 | } |
199 | mutex_unlock(&dev_priv->hw_mutex); | 199 | spin_unlock(&dev_priv->cap_lock); |
200 | } else if (gb_objects) { | 200 | } else if (gb_objects) { |
201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); | 201 | ret = vmw_fill_compat_cap(dev_priv, bounce, size); |
202 | if (unlikely(ret != 0)) | 202 | if (unlikely(ret != 0)) |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 0c423766c441..9fe9827ee499 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | |||
@@ -62,13 +62,8 @@ irqreturn_t vmw_irq_handler(int irq, void *arg) | |||
62 | 62 | ||
63 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) | 63 | static bool vmw_fifo_idle(struct vmw_private *dev_priv, uint32_t seqno) |
64 | { | 64 | { |
65 | uint32_t busy; | ||
66 | 65 | ||
67 | mutex_lock(&dev_priv->hw_mutex); | 66 | return (vmw_read(dev_priv, SVGA_REG_BUSY) == 0); |
68 | busy = vmw_read(dev_priv, SVGA_REG_BUSY); | ||
69 | mutex_unlock(&dev_priv->hw_mutex); | ||
70 | |||
71 | return (busy == 0); | ||
72 | } | 67 | } |
73 | 68 | ||
74 | void vmw_update_seqno(struct vmw_private *dev_priv, | 69 | void vmw_update_seqno(struct vmw_private *dev_priv, |
@@ -184,7 +179,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, | |||
184 | 179 | ||
185 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) | 180 | void vmw_seqno_waiter_add(struct vmw_private *dev_priv) |
186 | { | 181 | { |
187 | mutex_lock(&dev_priv->hw_mutex); | 182 | spin_lock(&dev_priv->waiter_lock); |
188 | if (dev_priv->fence_queue_waiters++ == 0) { | 183 | if (dev_priv->fence_queue_waiters++ == 0) { |
189 | unsigned long irq_flags; | 184 | unsigned long irq_flags; |
190 | 185 | ||
@@ -195,12 +190,12 @@ void vmw_seqno_waiter_add(struct vmw_private *dev_priv) | |||
195 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 190 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
196 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 191 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
197 | } | 192 | } |
198 | mutex_unlock(&dev_priv->hw_mutex); | 193 | spin_unlock(&dev_priv->waiter_lock); |
199 | } | 194 | } |
200 | 195 | ||
201 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) | 196 | void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) |
202 | { | 197 | { |
203 | mutex_lock(&dev_priv->hw_mutex); | 198 | spin_lock(&dev_priv->waiter_lock); |
204 | if (--dev_priv->fence_queue_waiters == 0) { | 199 | if (--dev_priv->fence_queue_waiters == 0) { |
205 | unsigned long irq_flags; | 200 | unsigned long irq_flags; |
206 | 201 | ||
@@ -209,13 +204,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) | |||
209 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 204 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
210 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 205 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
211 | } | 206 | } |
212 | mutex_unlock(&dev_priv->hw_mutex); | 207 | spin_unlock(&dev_priv->waiter_lock); |
213 | } | 208 | } |
214 | 209 | ||
215 | 210 | ||
216 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) | 211 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
217 | { | 212 | { |
218 | mutex_lock(&dev_priv->hw_mutex); | 213 | spin_lock(&dev_priv->waiter_lock); |
219 | if (dev_priv->goal_queue_waiters++ == 0) { | 214 | if (dev_priv->goal_queue_waiters++ == 0) { |
220 | unsigned long irq_flags; | 215 | unsigned long irq_flags; |
221 | 216 | ||
@@ -226,12 +221,12 @@ void vmw_goal_waiter_add(struct vmw_private *dev_priv) | |||
226 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 221 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
227 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 222 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
228 | } | 223 | } |
229 | mutex_unlock(&dev_priv->hw_mutex); | 224 | spin_unlock(&dev_priv->waiter_lock); |
230 | } | 225 | } |
231 | 226 | ||
232 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) | 227 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
233 | { | 228 | { |
234 | mutex_lock(&dev_priv->hw_mutex); | 229 | spin_lock(&dev_priv->waiter_lock); |
235 | if (--dev_priv->goal_queue_waiters == 0) { | 230 | if (--dev_priv->goal_queue_waiters == 0) { |
236 | unsigned long irq_flags; | 231 | unsigned long irq_flags; |
237 | 232 | ||
@@ -240,7 +235,7 @@ void vmw_goal_waiter_remove(struct vmw_private *dev_priv) | |||
240 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); | 235 | vmw_write(dev_priv, SVGA_REG_IRQMASK, dev_priv->irq_mask); |
241 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); | 236 | spin_unlock_irqrestore(&dev_priv->irq_lock, irq_flags); |
242 | } | 237 | } |
243 | mutex_unlock(&dev_priv->hw_mutex); | 238 | spin_unlock(&dev_priv->waiter_lock); |
244 | } | 239 | } |
245 | 240 | ||
246 | int vmw_wait_seqno(struct vmw_private *dev_priv, | 241 | int vmw_wait_seqno(struct vmw_private *dev_priv, |
@@ -315,9 +310,7 @@ void vmw_irq_uninstall(struct drm_device *dev) | |||
315 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) | 310 | if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) |
316 | return; | 311 | return; |
317 | 312 | ||
318 | mutex_lock(&dev_priv->hw_mutex); | ||
319 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); | 313 | vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); |
320 | mutex_unlock(&dev_priv->hw_mutex); | ||
321 | 314 | ||
322 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); | 315 | status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
323 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); | 316 | outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 3725b521d931..8725b79e7847 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -1828,9 +1828,7 @@ vmw_du_connector_detect(struct drm_connector *connector, bool force) | |||
1828 | struct vmw_private *dev_priv = vmw_priv(dev); | 1828 | struct vmw_private *dev_priv = vmw_priv(dev); |
1829 | struct vmw_display_unit *du = vmw_connector_to_du(connector); | 1829 | struct vmw_display_unit *du = vmw_connector_to_du(connector); |
1830 | 1830 | ||
1831 | mutex_lock(&dev_priv->hw_mutex); | ||
1832 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); | 1831 | num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS); |
1833 | mutex_unlock(&dev_priv->hw_mutex); | ||
1834 | 1832 | ||
1835 | return ((vmw_connector_to_du(connector)->unit < num_displays && | 1833 | return ((vmw_connector_to_du(connector)->unit < num_displays && |
1836 | du->pref_active) ? | 1834 | du->pref_active) ? |
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 230b6f887cd8..dfdc26970022 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -27,7 +27,8 @@ if HID | |||
27 | 27 | ||
28 | config HID_BATTERY_STRENGTH | 28 | config HID_BATTERY_STRENGTH |
29 | bool "Battery level reporting for HID devices" | 29 | bool "Battery level reporting for HID devices" |
30 | depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY | 30 | depends on HID |
31 | select POWER_SUPPLY | ||
31 | default n | 32 | default n |
32 | ---help--- | 33 | ---help--- |
33 | This option adds support of reporting battery strength (for HID devices | 34 | This option adds support of reporting battery strength (for HID devices |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c3d0ac1a0988..8b638792cb43 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1805,6 +1805,7 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1805 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, | 1805 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, |
1806 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, | 1806 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_I405X) }, |
1807 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | 1807 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
1808 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, | ||
1808 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 1809 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
1809 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1810 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1810 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, | 1811 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 7460f3402298..9243359c1821 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -526,6 +526,7 @@ | |||
526 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 | 526 | #define USB_DEVICE_ID_KYE_GPEN_560 0x5003 |
527 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 | 527 | #define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 |
528 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 | 528 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 |
529 | #define USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2 0x501a | ||
529 | #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 | 530 | #define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 |
530 | 531 | ||
531 | #define USB_VENDOR_ID_LABTEC 0x1020 | 532 | #define USB_VENDOR_ID_LABTEC 0x1020 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index e0a0f06ac5ef..9505605b6e22 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -312,6 +312,9 @@ static const struct hid_device_id hid_battery_quirks[] = { | |||
312 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), | 312 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI), |
313 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 313 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
314 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | 314 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
315 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO), | ||
316 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | ||
317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
315 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), | 318 | USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), |
316 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, | 319 | HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE }, |
317 | {} | 320 | {} |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index b92bf01a1ae8..158fcf577fae 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
@@ -323,6 +323,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
323 | } | 323 | } |
324 | break; | 324 | break; |
325 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: | 325 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: |
326 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: | ||
326 | if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { | 327 | if (*rsize == MOUSEPEN_I608X_RDESC_ORIG_SIZE) { |
327 | rdesc = mousepen_i608x_rdesc_fixed; | 328 | rdesc = mousepen_i608x_rdesc_fixed; |
328 | *rsize = sizeof(mousepen_i608x_rdesc_fixed); | 329 | *rsize = sizeof(mousepen_i608x_rdesc_fixed); |
@@ -415,6 +416,7 @@ static int kye_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
415 | switch (id->product) { | 416 | switch (id->product) { |
416 | case USB_DEVICE_ID_KYE_EASYPEN_I405X: | 417 | case USB_DEVICE_ID_KYE_EASYPEN_I405X: |
417 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: | 418 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X: |
419 | case USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2: | ||
418 | case USB_DEVICE_ID_KYE_EASYPEN_M610X: | 420 | case USB_DEVICE_ID_KYE_EASYPEN_M610X: |
419 | ret = kye_tablet_enable(hdev); | 421 | ret = kye_tablet_enable(hdev); |
420 | if (ret) { | 422 | if (ret) { |
@@ -446,6 +448,8 @@ static const struct hid_device_id kye_devices[] = { | |||
446 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | 448 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
447 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, | 449 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X) }, |
448 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | 450 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
451 | USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2) }, | ||
452 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | ||
449 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 453 | USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
450 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, | 454 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, |
451 | USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, | 455 | USB_DEVICE_ID_GENIUS_GILA_GAMING_MOUSE) }, |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index c917ab61aafa..5bc6d80d5be7 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -962,10 +962,24 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
962 | 962 | ||
963 | switch (data[0]) { | 963 | switch (data[0]) { |
964 | case REPORT_ID_DJ_SHORT: | 964 | case REPORT_ID_DJ_SHORT: |
965 | if (size != DJREPORT_SHORT_LENGTH) { | ||
966 | dev_err(&hdev->dev, "DJ report of bad size (%d)", size); | ||
967 | return false; | ||
968 | } | ||
965 | return logi_dj_dj_event(hdev, report, data, size); | 969 | return logi_dj_dj_event(hdev, report, data, size); |
966 | case REPORT_ID_HIDPP_SHORT: | 970 | case REPORT_ID_HIDPP_SHORT: |
967 | /* intentional fallthrough */ | 971 | if (size != HIDPP_REPORT_SHORT_LENGTH) { |
972 | dev_err(&hdev->dev, | ||
973 | "Short HID++ report of bad size (%d)", size); | ||
974 | return false; | ||
975 | } | ||
976 | return logi_dj_hidpp_event(hdev, report, data, size); | ||
968 | case REPORT_ID_HIDPP_LONG: | 977 | case REPORT_ID_HIDPP_LONG: |
978 | if (size != HIDPP_REPORT_LONG_LENGTH) { | ||
979 | dev_err(&hdev->dev, | ||
980 | "Long HID++ report of bad size (%d)", size); | ||
981 | return false; | ||
982 | } | ||
969 | return logi_dj_hidpp_event(hdev, report, data, size); | 983 | return logi_dj_hidpp_event(hdev, report, data, size); |
970 | } | 984 | } |
971 | 985 | ||
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 2f420c0b6609..a93cefe0e522 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c | |||
@@ -282,6 +282,33 @@ static inline bool hidpp_report_is_connect_event(struct hidpp_report *report) | |||
282 | (report->rap.sub_id == 0x41); | 282 | (report->rap.sub_id == 0x41); |
283 | } | 283 | } |
284 | 284 | ||
285 | /** | ||
286 | * hidpp_prefix_name() prefixes the current given name with "Logitech ". | ||
287 | */ | ||
288 | static void hidpp_prefix_name(char **name, int name_length) | ||
289 | { | ||
290 | #define PREFIX_LENGTH 9 /* "Logitech " */ | ||
291 | |||
292 | int new_length; | ||
293 | char *new_name; | ||
294 | |||
295 | if (name_length > PREFIX_LENGTH && | ||
296 | strncmp(*name, "Logitech ", PREFIX_LENGTH) == 0) | ||
297 | /* The prefix has is already in the name */ | ||
298 | return; | ||
299 | |||
300 | new_length = PREFIX_LENGTH + name_length; | ||
301 | new_name = kzalloc(new_length, GFP_KERNEL); | ||
302 | if (!new_name) | ||
303 | return; | ||
304 | |||
305 | snprintf(new_name, new_length, "Logitech %s", *name); | ||
306 | |||
307 | kfree(*name); | ||
308 | |||
309 | *name = new_name; | ||
310 | } | ||
311 | |||
285 | /* -------------------------------------------------------------------------- */ | 312 | /* -------------------------------------------------------------------------- */ |
286 | /* HIDP++ 1.0 commands */ | 313 | /* HIDP++ 1.0 commands */ |
287 | /* -------------------------------------------------------------------------- */ | 314 | /* -------------------------------------------------------------------------- */ |
@@ -321,6 +348,10 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev) | |||
321 | return NULL; | 348 | return NULL; |
322 | 349 | ||
323 | memcpy(name, &response.rap.params[2], len); | 350 | memcpy(name, &response.rap.params[2], len); |
351 | |||
352 | /* include the terminating '\0' */ | ||
353 | hidpp_prefix_name(&name, len + 1); | ||
354 | |||
324 | return name; | 355 | return name; |
325 | } | 356 | } |
326 | 357 | ||
@@ -498,6 +529,9 @@ static char *hidpp_get_device_name(struct hidpp_device *hidpp) | |||
498 | index += ret; | 529 | index += ret; |
499 | } | 530 | } |
500 | 531 | ||
532 | /* include the terminating '\0' */ | ||
533 | hidpp_prefix_name(&name, __name_length + 1); | ||
534 | |||
501 | return name; | 535 | return name; |
502 | } | 536 | } |
503 | 537 | ||
@@ -794,18 +828,25 @@ static int wtp_raw_event(struct hid_device *hdev, u8 *data, int size) | |||
794 | 828 | ||
795 | switch (data[0]) { | 829 | switch (data[0]) { |
796 | case 0x02: | 830 | case 0x02: |
831 | if (size < 2) { | ||
832 | hid_err(hdev, "Received HID report of bad size (%d)", | ||
833 | size); | ||
834 | return 1; | ||
835 | } | ||
797 | if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { | 836 | if (hidpp->quirks & HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS) { |
798 | input_event(wd->input, EV_KEY, BTN_LEFT, | 837 | input_event(wd->input, EV_KEY, BTN_LEFT, |
799 | !!(data[1] & 0x01)); | 838 | !!(data[1] & 0x01)); |
800 | input_event(wd->input, EV_KEY, BTN_RIGHT, | 839 | input_event(wd->input, EV_KEY, BTN_RIGHT, |
801 | !!(data[1] & 0x02)); | 840 | !!(data[1] & 0x02)); |
802 | input_sync(wd->input); | 841 | input_sync(wd->input); |
842 | return 0; | ||
803 | } else { | 843 | } else { |
804 | if (size < 21) | 844 | if (size < 21) |
805 | return 1; | 845 | return 1; |
806 | return wtp_mouse_raw_xy_event(hidpp, &data[7]); | 846 | return wtp_mouse_raw_xy_event(hidpp, &data[7]); |
807 | } | 847 | } |
808 | case REPORT_ID_HIDPP_LONG: | 848 | case REPORT_ID_HIDPP_LONG: |
849 | /* size is already checked in hidpp_raw_event. */ | ||
809 | if ((report->fap.feature_index != wd->mt_feature_index) || | 850 | if ((report->fap.feature_index != wd->mt_feature_index) || |
810 | (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) | 851 | (report->fap.funcindex_clientid != EVENT_TOUCHPAD_RAW_XY)) |
811 | return 1; | 852 | return 1; |
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 1a07e07d99a0..47d7e74231e5 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
@@ -35,6 +35,8 @@ static struct class *pyra_class; | |||
35 | static void profile_activated(struct pyra_device *pyra, | 35 | static void profile_activated(struct pyra_device *pyra, |
36 | unsigned int new_profile) | 36 | unsigned int new_profile) |
37 | { | 37 | { |
38 | if (new_profile >= ARRAY_SIZE(pyra->profile_settings)) | ||
39 | return; | ||
38 | pyra->actual_profile = new_profile; | 40 | pyra->actual_profile = new_profile; |
39 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; | 41 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; |
40 | } | 42 | } |
@@ -257,9 +259,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, | |||
257 | if (off != 0 || count != PYRA_SIZE_SETTINGS) | 259 | if (off != 0 || count != PYRA_SIZE_SETTINGS) |
258 | return -EINVAL; | 260 | return -EINVAL; |
259 | 261 | ||
260 | mutex_lock(&pyra->pyra_lock); | ||
261 | |||
262 | settings = (struct pyra_settings const *)buf; | 262 | settings = (struct pyra_settings const *)buf; |
263 | if (settings->startup_profile >= ARRAY_SIZE(pyra->profile_settings)) | ||
264 | return -EINVAL; | ||
265 | |||
266 | mutex_lock(&pyra->pyra_lock); | ||
263 | 267 | ||
264 | retval = pyra_set_settings(usb_dev, settings); | 268 | retval = pyra_set_settings(usb_dev, settings); |
265 | if (retval) { | 269 | if (retval) { |
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index d32037cbf9db..d43e967e7533 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c | |||
@@ -706,12 +706,7 @@ static int i2c_hid_start(struct hid_device *hid) | |||
706 | 706 | ||
707 | static void i2c_hid_stop(struct hid_device *hid) | 707 | static void i2c_hid_stop(struct hid_device *hid) |
708 | { | 708 | { |
709 | struct i2c_client *client = hid->driver_data; | ||
710 | struct i2c_hid *ihid = i2c_get_clientdata(client); | ||
711 | |||
712 | hid->claimed = 0; | 709 | hid->claimed = 0; |
713 | |||
714 | i2c_hid_free_buffers(ihid); | ||
715 | } | 710 | } |
716 | 711 | ||
717 | static int i2c_hid_open(struct hid_device *hid) | 712 | static int i2c_hid_open(struct hid_device *hid) |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index dc89be90b35e..b27b3d33ebab 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -124,6 +124,7 @@ static const struct hid_blacklist { | |||
124 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, | 124 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, |
125 | { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, | 125 | { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, |
126 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, | 126 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, |
127 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_2, HID_QUIRK_MULTI_INPUT }, | ||
127 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, | 128 | { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, |
128 | { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, | 129 | { USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS }, |
129 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, | 130 | { USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6529c09c46f0..a7de26d1ac80 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -574,6 +574,16 @@ config SENSORS_IIO_HWMON | |||
574 | for those channels specified in the map. This map can be provided | 574 | for those channels specified in the map. This map can be provided |
575 | either via platform data or the device tree bindings. | 575 | either via platform data or the device tree bindings. |
576 | 576 | ||
577 | config SENSORS_I5500 | ||
578 | tristate "Intel 5500/5520/X58 temperature sensor" | ||
579 | depends on X86 && PCI | ||
580 | help | ||
581 | If you say yes here you get support for the temperature | ||
582 | sensor inside the Intel 5500, 5520 and X58 chipsets. | ||
583 | |||
584 | This driver can also be built as a module. If so, the module | ||
585 | will be called i5500_temp. | ||
586 | |||
577 | config SENSORS_CORETEMP | 587 | config SENSORS_CORETEMP |
578 | tristate "Intel Core/Core2/Atom temperature sensor" | 588 | tristate "Intel Core/Core2/Atom temperature sensor" |
579 | depends on X86 | 589 | depends on X86 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 67280643bcf0..6c941472e707 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -68,6 +68,7 @@ obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o | |||
68 | obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o | 68 | obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o |
69 | obj-$(CONFIG_SENSORS_HTU21) += htu21.o | 69 | obj-$(CONFIG_SENSORS_HTU21) += htu21.o |
70 | obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o | 70 | obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o |
71 | obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o | ||
71 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | 72 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o |
72 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | 73 | obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o |
73 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 74 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
diff --git a/drivers/hwmon/i5500_temp.c b/drivers/hwmon/i5500_temp.c new file mode 100644 index 000000000000..3e3ccbf18b4e --- /dev/null +++ b/drivers/hwmon/i5500_temp.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * i5500_temp - Driver for Intel 5500/5520/X58 chipset thermal sensor | ||
3 | * | ||
4 | * Copyright (C) 2012, 2014 Jean Delvare <jdelvare@suse.de> | ||
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 as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/pci.h> | ||
23 | #include <linux/hwmon.h> | ||
24 | #include <linux/hwmon-sysfs.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/mutex.h> | ||
27 | |||
28 | /* Register definitions from datasheet */ | ||
29 | #define REG_TSTHRCATA 0xE2 | ||
30 | #define REG_TSCTRL 0xE8 | ||
31 | #define REG_TSTHRRPEX 0xEB | ||
32 | #define REG_TSTHRLO 0xEC | ||
33 | #define REG_TSTHRHI 0xEE | ||
34 | #define REG_CTHINT 0xF0 | ||
35 | #define REG_TSFSC 0xF3 | ||
36 | #define REG_CTSTS 0xF4 | ||
37 | #define REG_TSTHRRQPI 0xF5 | ||
38 | #define REG_CTCTRL 0xF7 | ||
39 | #define REG_TSTIMER 0xF8 | ||
40 | |||
41 | /* | ||
42 | * Sysfs stuff | ||
43 | */ | ||
44 | |||
45 | /* Sensor resolution : 0.5 degree C */ | ||
46 | static ssize_t show_temp(struct device *dev, | ||
47 | struct device_attribute *devattr, char *buf) | ||
48 | { | ||
49 | struct pci_dev *pdev = to_pci_dev(dev->parent); | ||
50 | long temp; | ||
51 | u16 tsthrhi; | ||
52 | s8 tsfsc; | ||
53 | |||
54 | pci_read_config_word(pdev, REG_TSTHRHI, &tsthrhi); | ||
55 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); | ||
56 | temp = ((long)tsthrhi - tsfsc) * 500; | ||
57 | |||
58 | return sprintf(buf, "%ld\n", temp); | ||
59 | } | ||
60 | |||
61 | static ssize_t show_thresh(struct device *dev, | ||
62 | struct device_attribute *devattr, char *buf) | ||
63 | { | ||
64 | struct pci_dev *pdev = to_pci_dev(dev->parent); | ||
65 | int reg = to_sensor_dev_attr(devattr)->index; | ||
66 | long temp; | ||
67 | u16 tsthr; | ||
68 | |||
69 | pci_read_config_word(pdev, reg, &tsthr); | ||
70 | temp = tsthr * 500; | ||
71 | |||
72 | return sprintf(buf, "%ld\n", temp); | ||
73 | } | ||
74 | |||
75 | static ssize_t show_alarm(struct device *dev, | ||
76 | struct device_attribute *devattr, char *buf) | ||
77 | { | ||
78 | struct pci_dev *pdev = to_pci_dev(dev->parent); | ||
79 | int nr = to_sensor_dev_attr(devattr)->index; | ||
80 | u8 ctsts; | ||
81 | |||
82 | pci_read_config_byte(pdev, REG_CTSTS, &ctsts); | ||
83 | return sprintf(buf, "%u\n", (unsigned int)ctsts & (1 << nr)); | ||
84 | } | ||
85 | |||
86 | static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); | ||
87 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_thresh, NULL, 0xE2); | ||
88 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_thresh, NULL, 0xEC); | ||
89 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_thresh, NULL, 0xEE); | ||
90 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
91 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
92 | |||
93 | static struct attribute *i5500_temp_attrs[] = { | ||
94 | &dev_attr_temp1_input.attr, | ||
95 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
96 | &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, | ||
97 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
98 | &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, | ||
99 | &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, | ||
100 | NULL | ||
101 | }; | ||
102 | |||
103 | ATTRIBUTE_GROUPS(i5500_temp); | ||
104 | |||
105 | static const struct pci_device_id i5500_temp_ids[] = { | ||
106 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3438) }, | ||
107 | { 0 }, | ||
108 | }; | ||
109 | |||
110 | MODULE_DEVICE_TABLE(pci, i5500_temp_ids); | ||
111 | |||
112 | static int i5500_temp_probe(struct pci_dev *pdev, | ||
113 | const struct pci_device_id *id) | ||
114 | { | ||
115 | int err; | ||
116 | struct device *hwmon_dev; | ||
117 | u32 tstimer; | ||
118 | s8 tsfsc; | ||
119 | |||
120 | err = pci_enable_device(pdev); | ||
121 | if (err) { | ||
122 | dev_err(&pdev->dev, "Failed to enable device\n"); | ||
123 | return err; | ||
124 | } | ||
125 | |||
126 | pci_read_config_byte(pdev, REG_TSFSC, &tsfsc); | ||
127 | pci_read_config_dword(pdev, REG_TSTIMER, &tstimer); | ||
128 | if (tsfsc == 0x7F && tstimer == 0x07D30D40) { | ||
129 | dev_notice(&pdev->dev, "Sensor seems to be disabled\n"); | ||
130 | return -ENODEV; | ||
131 | } | ||
132 | |||
133 | hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, | ||
134 | "intel5500", NULL, | ||
135 | i5500_temp_groups); | ||
136 | return PTR_ERR_OR_ZERO(hwmon_dev); | ||
137 | } | ||
138 | |||
139 | static struct pci_driver i5500_temp_driver = { | ||
140 | .name = "i5500_temp", | ||
141 | .id_table = i5500_temp_ids, | ||
142 | .probe = i5500_temp_probe, | ||
143 | }; | ||
144 | |||
145 | module_pci_driver(i5500_temp_driver); | ||
146 | |||
147 | MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); | ||
148 | MODULE_DESCRIPTION("Intel 5500/5520/X58 chipset thermal sensor driver"); | ||
149 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 31e8308ba899..ab838d9e28b6 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -881,6 +881,7 @@ config I2C_XLR | |||
881 | config I2C_RCAR | 881 | config I2C_RCAR |
882 | tristate "Renesas R-Car I2C Controller" | 882 | tristate "Renesas R-Car I2C Controller" |
883 | depends on ARCH_SHMOBILE || COMPILE_TEST | 883 | depends on ARCH_SHMOBILE || COMPILE_TEST |
884 | select I2C_SLAVE | ||
884 | help | 885 | help |
885 | If you say yes to this option, support will be included for the | 886 | If you say yes to this option, support will be included for the |
886 | R-Car I2C controller. | 887 | R-Car I2C controller. |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index bff20a589621..958c8db4ec30 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -785,14 +785,16 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, | |||
785 | int ret; | 785 | int ret; |
786 | 786 | ||
787 | pm_runtime_get_sync(&adap->dev); | 787 | pm_runtime_get_sync(&adap->dev); |
788 | clk_prepare_enable(i2c->clk); | 788 | ret = clk_enable(i2c->clk); |
789 | if (ret) | ||
790 | return ret; | ||
789 | 791 | ||
790 | for (retry = 0; retry < adap->retries; retry++) { | 792 | for (retry = 0; retry < adap->retries; retry++) { |
791 | 793 | ||
792 | ret = s3c24xx_i2c_doxfer(i2c, msgs, num); | 794 | ret = s3c24xx_i2c_doxfer(i2c, msgs, num); |
793 | 795 | ||
794 | if (ret != -EAGAIN) { | 796 | if (ret != -EAGAIN) { |
795 | clk_disable_unprepare(i2c->clk); | 797 | clk_disable(i2c->clk); |
796 | pm_runtime_put(&adap->dev); | 798 | pm_runtime_put(&adap->dev); |
797 | return ret; | 799 | return ret; |
798 | } | 800 | } |
@@ -802,7 +804,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, | |||
802 | udelay(100); | 804 | udelay(100); |
803 | } | 805 | } |
804 | 806 | ||
805 | clk_disable_unprepare(i2c->clk); | 807 | clk_disable(i2c->clk); |
806 | pm_runtime_put(&adap->dev); | 808 | pm_runtime_put(&adap->dev); |
807 | return -EREMOTEIO; | 809 | return -EREMOTEIO; |
808 | } | 810 | } |
@@ -1197,7 +1199,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1197 | 1199 | ||
1198 | clk_prepare_enable(i2c->clk); | 1200 | clk_prepare_enable(i2c->clk); |
1199 | ret = s3c24xx_i2c_init(i2c); | 1201 | ret = s3c24xx_i2c_init(i2c); |
1200 | clk_disable_unprepare(i2c->clk); | 1202 | clk_disable(i2c->clk); |
1201 | if (ret != 0) { | 1203 | if (ret != 0) { |
1202 | dev_err(&pdev->dev, "I2C controller init failed\n"); | 1204 | dev_err(&pdev->dev, "I2C controller init failed\n"); |
1203 | return ret; | 1205 | return ret; |
@@ -1210,6 +1212,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1210 | i2c->irq = ret = platform_get_irq(pdev, 0); | 1212 | i2c->irq = ret = platform_get_irq(pdev, 0); |
1211 | if (ret <= 0) { | 1213 | if (ret <= 0) { |
1212 | dev_err(&pdev->dev, "cannot find IRQ\n"); | 1214 | dev_err(&pdev->dev, "cannot find IRQ\n"); |
1215 | clk_unprepare(i2c->clk); | ||
1213 | return ret; | 1216 | return ret; |
1214 | } | 1217 | } |
1215 | 1218 | ||
@@ -1218,6 +1221,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1218 | 1221 | ||
1219 | if (ret != 0) { | 1222 | if (ret != 0) { |
1220 | dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); | 1223 | dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); |
1224 | clk_unprepare(i2c->clk); | ||
1221 | return ret; | 1225 | return ret; |
1222 | } | 1226 | } |
1223 | } | 1227 | } |
@@ -1225,6 +1229,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1225 | ret = s3c24xx_i2c_register_cpufreq(i2c); | 1229 | ret = s3c24xx_i2c_register_cpufreq(i2c); |
1226 | if (ret < 0) { | 1230 | if (ret < 0) { |
1227 | dev_err(&pdev->dev, "failed to register cpufreq notifier\n"); | 1231 | dev_err(&pdev->dev, "failed to register cpufreq notifier\n"); |
1232 | clk_unprepare(i2c->clk); | ||
1228 | return ret; | 1233 | return ret; |
1229 | } | 1234 | } |
1230 | 1235 | ||
@@ -1241,6 +1246,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) | |||
1241 | if (ret < 0) { | 1246 | if (ret < 0) { |
1242 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); | 1247 | dev_err(&pdev->dev, "failed to add bus to i2c core\n"); |
1243 | s3c24xx_i2c_deregister_cpufreq(i2c); | 1248 | s3c24xx_i2c_deregister_cpufreq(i2c); |
1249 | clk_unprepare(i2c->clk); | ||
1244 | return ret; | 1250 | return ret; |
1245 | } | 1251 | } |
1246 | 1252 | ||
@@ -1262,6 +1268,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev) | |||
1262 | { | 1268 | { |
1263 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | 1269 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
1264 | 1270 | ||
1271 | clk_unprepare(i2c->clk); | ||
1272 | |||
1265 | pm_runtime_disable(&i2c->adap.dev); | 1273 | pm_runtime_disable(&i2c->adap.dev); |
1266 | pm_runtime_disable(&pdev->dev); | 1274 | pm_runtime_disable(&pdev->dev); |
1267 | 1275 | ||
@@ -1293,13 +1301,16 @@ static int s3c24xx_i2c_resume_noirq(struct device *dev) | |||
1293 | { | 1301 | { |
1294 | struct platform_device *pdev = to_platform_device(dev); | 1302 | struct platform_device *pdev = to_platform_device(dev); |
1295 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); | 1303 | struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); |
1304 | int ret; | ||
1296 | 1305 | ||
1297 | if (!IS_ERR(i2c->sysreg)) | 1306 | if (!IS_ERR(i2c->sysreg)) |
1298 | regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg); | 1307 | regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg); |
1299 | 1308 | ||
1300 | clk_prepare_enable(i2c->clk); | 1309 | ret = clk_enable(i2c->clk); |
1310 | if (ret) | ||
1311 | return ret; | ||
1301 | s3c24xx_i2c_init(i2c); | 1312 | s3c24xx_i2c_init(i2c); |
1302 | clk_disable_unprepare(i2c->clk); | 1313 | clk_disable(i2c->clk); |
1303 | i2c->suspended = 0; | 1314 | i2c->suspended = 0; |
1304 | 1315 | ||
1305 | return 0; | 1316 | return 0; |
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 440d5dbc8b5f..007818b3e174 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -139,6 +139,7 @@ struct sh_mobile_i2c_data { | |||
139 | int pos; | 139 | int pos; |
140 | int sr; | 140 | int sr; |
141 | bool send_stop; | 141 | bool send_stop; |
142 | bool stop_after_dma; | ||
142 | 143 | ||
143 | struct resource *res; | 144 | struct resource *res; |
144 | struct dma_chan *dma_tx; | 145 | struct dma_chan *dma_tx; |
@@ -407,7 +408,7 @@ static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd) | |||
407 | 408 | ||
408 | if (pd->pos == pd->msg->len) { | 409 | if (pd->pos == pd->msg->len) { |
409 | /* Send stop if we haven't yet (DMA case) */ | 410 | /* Send stop if we haven't yet (DMA case) */ |
410 | if (pd->send_stop && (iic_rd(pd, ICCR) & ICCR_BBSY)) | 411 | if (pd->send_stop && pd->stop_after_dma) |
411 | i2c_op(pd, OP_TX_STOP, 0); | 412 | i2c_op(pd, OP_TX_STOP, 0); |
412 | return 1; | 413 | return 1; |
413 | } | 414 | } |
@@ -449,6 +450,13 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd) | |||
449 | real_pos = pd->pos - 2; | 450 | real_pos = pd->pos - 2; |
450 | 451 | ||
451 | if (pd->pos == pd->msg->len) { | 452 | if (pd->pos == pd->msg->len) { |
453 | if (pd->stop_after_dma) { | ||
454 | /* Simulate PIO end condition after DMA transfer */ | ||
455 | i2c_op(pd, OP_RX_STOP, 0); | ||
456 | pd->pos++; | ||
457 | break; | ||
458 | } | ||
459 | |||
452 | if (real_pos < 0) { | 460 | if (real_pos < 0) { |
453 | i2c_op(pd, OP_RX_STOP, 0); | 461 | i2c_op(pd, OP_RX_STOP, 0); |
454 | break; | 462 | break; |
@@ -536,6 +544,7 @@ static void sh_mobile_i2c_dma_callback(void *data) | |||
536 | 544 | ||
537 | sh_mobile_i2c_dma_unmap(pd); | 545 | sh_mobile_i2c_dma_unmap(pd); |
538 | pd->pos = pd->msg->len; | 546 | pd->pos = pd->msg->len; |
547 | pd->stop_after_dma = true; | ||
539 | 548 | ||
540 | iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); | 549 | iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE); |
541 | } | 550 | } |
@@ -726,6 +735,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, | |||
726 | bool do_start = pd->send_stop || !i; | 735 | bool do_start = pd->send_stop || !i; |
727 | msg = &msgs[i]; | 736 | msg = &msgs[i]; |
728 | pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; | 737 | pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; |
738 | pd->stop_after_dma = false; | ||
729 | 739 | ||
730 | err = start_ch(pd, msg, do_start); | 740 | err = start_ch(pd, msg, do_start); |
731 | if (err) | 741 | if (err) |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 39d25a8cb1ad..e9eae57a2b50 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -2972,6 +2972,7 @@ trace: | |||
2972 | } | 2972 | } |
2973 | EXPORT_SYMBOL(i2c_smbus_xfer); | 2973 | EXPORT_SYMBOL(i2c_smbus_xfer); |
2974 | 2974 | ||
2975 | #if IS_ENABLED(CONFIG_I2C_SLAVE) | ||
2975 | int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) | 2976 | int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb) |
2976 | { | 2977 | { |
2977 | int ret; | 2978 | int ret; |
@@ -3019,6 +3020,7 @@ int i2c_slave_unregister(struct i2c_client *client) | |||
3019 | return ret; | 3020 | return ret; |
3020 | } | 3021 | } |
3021 | EXPORT_SYMBOL_GPL(i2c_slave_unregister); | 3022 | EXPORT_SYMBOL_GPL(i2c_slave_unregister); |
3023 | #endif | ||
3022 | 3024 | ||
3023 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | 3025 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
3024 | MODULE_DESCRIPTION("I2C-Bus main module"); | 3026 | MODULE_DESCRIPTION("I2C-Bus main module"); |
diff --git a/drivers/i2c/i2c-slave-eeprom.c b/drivers/i2c/i2c-slave-eeprom.c index 6631400b5f02..cf9b09db092f 100644 --- a/drivers/i2c/i2c-slave-eeprom.c +++ b/drivers/i2c/i2c-slave-eeprom.c | |||
@@ -74,7 +74,7 @@ static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj | |||
74 | struct eeprom_data *eeprom; | 74 | struct eeprom_data *eeprom; |
75 | unsigned long flags; | 75 | unsigned long flags; |
76 | 76 | ||
77 | if (off + count >= attr->size) | 77 | if (off + count > attr->size) |
78 | return -EFBIG; | 78 | return -EFBIG; |
79 | 79 | ||
80 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); | 80 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
@@ -92,7 +92,7 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob | |||
92 | struct eeprom_data *eeprom; | 92 | struct eeprom_data *eeprom; |
93 | unsigned long flags; | 93 | unsigned long flags; |
94 | 94 | ||
95 | if (off + count >= attr->size) | 95 | if (off + count > attr->size) |
96 | return -EFBIG; | 96 | return -EFBIG; |
97 | 97 | ||
98 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); | 98 | eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index e37412da15f5..b99de00e57b8 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c | |||
@@ -143,9 +143,15 @@ static int ad799x_write_config(struct ad799x_state *st, u16 val) | |||
143 | case ad7998: | 143 | case ad7998: |
144 | return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG, | 144 | return i2c_smbus_write_word_swapped(st->client, AD7998_CONF_REG, |
145 | val); | 145 | val); |
146 | default: | 146 | case ad7992: |
147 | case ad7993: | ||
148 | case ad7994: | ||
147 | return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG, | 149 | return i2c_smbus_write_byte_data(st->client, AD7998_CONF_REG, |
148 | val); | 150 | val); |
151 | default: | ||
152 | /* Will be written when doing a conversion */ | ||
153 | st->config = val; | ||
154 | return 0; | ||
149 | } | 155 | } |
150 | } | 156 | } |
151 | 157 | ||
@@ -155,8 +161,13 @@ static int ad799x_read_config(struct ad799x_state *st) | |||
155 | case ad7997: | 161 | case ad7997: |
156 | case ad7998: | 162 | case ad7998: |
157 | return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG); | 163 | return i2c_smbus_read_word_swapped(st->client, AD7998_CONF_REG); |
158 | default: | 164 | case ad7992: |
165 | case ad7993: | ||
166 | case ad7994: | ||
159 | return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG); | 167 | return i2c_smbus_read_byte_data(st->client, AD7998_CONF_REG); |
168 | default: | ||
169 | /* No readback support */ | ||
170 | return st->config; | ||
160 | } | 171 | } |
161 | } | 172 | } |
162 | 173 | ||
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 866fe904cba2..90c8cb727cc7 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c | |||
@@ -449,6 +449,9 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2, | |||
449 | if (val2 == NULL) | 449 | if (val2 == NULL) |
450 | val2 = &unused; | 450 | val2 = &unused; |
451 | 451 | ||
452 | if(!iio_channel_has_info(chan->channel, info)) | ||
453 | return -EINVAL; | ||
454 | |||
452 | if (chan->indio_dev->info->read_raw_multi) { | 455 | if (chan->indio_dev->info->read_raw_multi) { |
453 | ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, | 456 | ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev, |
454 | chan->channel, INDIO_MAX_RAW_ELEMENTS, | 457 | chan->channel, INDIO_MAX_RAW_ELEMENTS, |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 57ecc5b204f3..9117b7a2d5f8 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -1114,7 +1114,8 @@ static int mlx4_ib_tunnel_steer_add(struct ib_qp *qp, struct ib_flow_attr *flow_ | |||
1114 | struct mlx4_dev *dev = to_mdev(qp->device)->dev; | 1114 | struct mlx4_dev *dev = to_mdev(qp->device)->dev; |
1115 | int err = 0; | 1115 | int err = 0; |
1116 | 1116 | ||
1117 | if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) | 1117 | if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || |
1118 | dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) | ||
1118 | return 0; /* do nothing */ | 1119 | return 0; /* do nothing */ |
1119 | 1120 | ||
1120 | ib_flow = flow_attr + 1; | 1121 | ib_flow = flow_attr + 1; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 8afa28e4570e..18d4b2c8fe55 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -28,6 +28,13 @@ | |||
28 | #include <linux/cdev.h> | 28 | #include <linux/cdev.h> |
29 | #include "input-compat.h" | 29 | #include "input-compat.h" |
30 | 30 | ||
31 | enum evdev_clock_type { | ||
32 | EV_CLK_REAL = 0, | ||
33 | EV_CLK_MONO, | ||
34 | EV_CLK_BOOT, | ||
35 | EV_CLK_MAX | ||
36 | }; | ||
37 | |||
31 | struct evdev { | 38 | struct evdev { |
32 | int open; | 39 | int open; |
33 | struct input_handle handle; | 40 | struct input_handle handle; |
@@ -49,12 +56,32 @@ struct evdev_client { | |||
49 | struct fasync_struct *fasync; | 56 | struct fasync_struct *fasync; |
50 | struct evdev *evdev; | 57 | struct evdev *evdev; |
51 | struct list_head node; | 58 | struct list_head node; |
52 | int clkid; | 59 | int clk_type; |
53 | bool revoked; | 60 | bool revoked; |
54 | unsigned int bufsize; | 61 | unsigned int bufsize; |
55 | struct input_event buffer[]; | 62 | struct input_event buffer[]; |
56 | }; | 63 | }; |
57 | 64 | ||
65 | static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) | ||
66 | { | ||
67 | switch (clkid) { | ||
68 | |||
69 | case CLOCK_REALTIME: | ||
70 | client->clk_type = EV_CLK_REAL; | ||
71 | break; | ||
72 | case CLOCK_MONOTONIC: | ||
73 | client->clk_type = EV_CLK_MONO; | ||
74 | break; | ||
75 | case CLOCK_BOOTTIME: | ||
76 | client->clk_type = EV_CLK_BOOT; | ||
77 | break; | ||
78 | default: | ||
79 | return -EINVAL; | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
58 | /* flush queued events of type @type, caller must hold client->buffer_lock */ | 85 | /* flush queued events of type @type, caller must hold client->buffer_lock */ |
59 | static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) | 86 | static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) |
60 | { | 87 | { |
@@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client) | |||
108 | struct input_event ev; | 135 | struct input_event ev; |
109 | ktime_t time; | 136 | ktime_t time; |
110 | 137 | ||
111 | time = (client->clkid == CLOCK_MONOTONIC) ? | 138 | time = client->clk_type == EV_CLK_REAL ? |
112 | ktime_get() : ktime_get_real(); | 139 | ktime_get_real() : |
140 | client->clk_type == EV_CLK_MONO ? | ||
141 | ktime_get() : | ||
142 | ktime_get_boottime(); | ||
113 | 143 | ||
114 | ev.time = ktime_to_timeval(time); | 144 | ev.time = ktime_to_timeval(time); |
115 | ev.type = EV_SYN; | 145 | ev.type = EV_SYN; |
@@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client, | |||
159 | 189 | ||
160 | static void evdev_pass_values(struct evdev_client *client, | 190 | static void evdev_pass_values(struct evdev_client *client, |
161 | const struct input_value *vals, unsigned int count, | 191 | const struct input_value *vals, unsigned int count, |
162 | ktime_t mono, ktime_t real) | 192 | ktime_t *ev_time) |
163 | { | 193 | { |
164 | struct evdev *evdev = client->evdev; | 194 | struct evdev *evdev = client->evdev; |
165 | const struct input_value *v; | 195 | const struct input_value *v; |
@@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client, | |||
169 | if (client->revoked) | 199 | if (client->revoked) |
170 | return; | 200 | return; |
171 | 201 | ||
172 | event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? | 202 | event.time = ktime_to_timeval(ev_time[client->clk_type]); |
173 | mono : real); | ||
174 | 203 | ||
175 | /* Interrupts are disabled, just acquire the lock. */ | 204 | /* Interrupts are disabled, just acquire the lock. */ |
176 | spin_lock(&client->buffer_lock); | 205 | spin_lock(&client->buffer_lock); |
@@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle, | |||
198 | { | 227 | { |
199 | struct evdev *evdev = handle->private; | 228 | struct evdev *evdev = handle->private; |
200 | struct evdev_client *client; | 229 | struct evdev_client *client; |
201 | ktime_t time_mono, time_real; | 230 | ktime_t ev_time[EV_CLK_MAX]; |
202 | 231 | ||
203 | time_mono = ktime_get(); | 232 | ev_time[EV_CLK_MONO] = ktime_get(); |
204 | time_real = ktime_mono_to_real(time_mono); | 233 | ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); |
234 | ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO], | ||
235 | TK_OFFS_BOOT); | ||
205 | 236 | ||
206 | rcu_read_lock(); | 237 | rcu_read_lock(); |
207 | 238 | ||
208 | client = rcu_dereference(evdev->grab); | 239 | client = rcu_dereference(evdev->grab); |
209 | 240 | ||
210 | if (client) | 241 | if (client) |
211 | evdev_pass_values(client, vals, count, time_mono, time_real); | 242 | evdev_pass_values(client, vals, count, ev_time); |
212 | else | 243 | else |
213 | list_for_each_entry_rcu(client, &evdev->client_list, node) | 244 | list_for_each_entry_rcu(client, &evdev->client_list, node) |
214 | evdev_pass_values(client, vals, count, | 245 | evdev_pass_values(client, vals, count, ev_time); |
215 | time_mono, time_real); | ||
216 | 246 | ||
217 | rcu_read_unlock(); | 247 | rcu_read_unlock(); |
218 | } | 248 | } |
@@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
877 | case EVIOCSCLOCKID: | 907 | case EVIOCSCLOCKID: |
878 | if (copy_from_user(&i, p, sizeof(unsigned int))) | 908 | if (copy_from_user(&i, p, sizeof(unsigned int))) |
879 | return -EFAULT; | 909 | return -EFAULT; |
880 | if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) | 910 | |
881 | return -EINVAL; | 911 | return evdev_set_clk_type(client, i); |
882 | client->clkid = i; | ||
883 | return 0; | ||
884 | 912 | ||
885 | case EVIOCGKEYCODE: | 913 | case EVIOCGKEYCODE: |
886 | return evdev_handle_get_keycode(dev, p); | 914 | return evdev_handle_get_keycode(dev, p); |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 04217c2e345c..213e3a1903ee 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | |||
1974 | 1974 | ||
1975 | events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ | 1975 | events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ |
1976 | 1976 | ||
1977 | for (i = 0; i < ABS_CNT; i++) { | 1977 | if (test_bit(EV_ABS, dev->evbit)) { |
1978 | if (test_bit(i, dev->absbit)) { | 1978 | for (i = 0; i < ABS_CNT; i++) { |
1979 | if (input_is_mt_axis(i)) | 1979 | if (test_bit(i, dev->absbit)) { |
1980 | events += mt_slots; | 1980 | if (input_is_mt_axis(i)) |
1981 | else | 1981 | events += mt_slots; |
1982 | events++; | 1982 | else |
1983 | events++; | ||
1984 | } | ||
1983 | } | 1985 | } |
1984 | } | 1986 | } |
1985 | 1987 | ||
1986 | for (i = 0; i < REL_CNT; i++) | 1988 | if (test_bit(EV_REL, dev->evbit)) { |
1987 | if (test_bit(i, dev->relbit)) | 1989 | for (i = 0; i < REL_CNT; i++) |
1988 | events++; | 1990 | if (test_bit(i, dev->relbit)) |
1991 | events++; | ||
1992 | } | ||
1989 | 1993 | ||
1990 | /* Make room for KEY and MSC events */ | 1994 | /* Make room for KEY and MSC events */ |
1991 | events += 7; | 1995 | events += 7; |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 96ee26c555e0..a5d9b3f3c871 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC | |||
559 | config KEYBOARD_STMPE | 559 | config KEYBOARD_STMPE |
560 | tristate "STMPE keypad support" | 560 | tristate "STMPE keypad support" |
561 | depends on MFD_STMPE | 561 | depends on MFD_STMPE |
562 | depends on OF | ||
562 | select INPUT_MATRIXKMAP | 563 | select INPUT_MATRIXKMAP |
563 | help | 564 | help |
564 | Say Y here if you want to use the keypad controller on STMPE I/O | 565 | Say Y here if you want to use the keypad controller on STMPE I/O |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index d4dd78a7d56b..883d6aed5b9a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -35,9 +35,13 @@ | |||
35 | struct gpio_button_data { | 35 | struct gpio_button_data { |
36 | const struct gpio_keys_button *button; | 36 | const struct gpio_keys_button *button; |
37 | struct input_dev *input; | 37 | struct input_dev *input; |
38 | struct timer_list timer; | 38 | |
39 | struct work_struct work; | 39 | struct timer_list release_timer; |
40 | unsigned int timer_debounce; /* in msecs */ | 40 | unsigned int release_delay; /* in msecs, for IRQ-only buttons */ |
41 | |||
42 | struct delayed_work work; | ||
43 | unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */ | ||
44 | |||
41 | unsigned int irq; | 45 | unsigned int irq; |
42 | spinlock_t lock; | 46 | spinlock_t lock; |
43 | bool disabled; | 47 | bool disabled; |
@@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) | |||
116 | { | 120 | { |
117 | if (!bdata->disabled) { | 121 | if (!bdata->disabled) { |
118 | /* | 122 | /* |
119 | * Disable IRQ and possible debouncing timer. | 123 | * Disable IRQ and associated timer/work structure. |
120 | */ | 124 | */ |
121 | disable_irq(bdata->irq); | 125 | disable_irq(bdata->irq); |
122 | if (bdata->timer_debounce) | 126 | |
123 | del_timer_sync(&bdata->timer); | 127 | if (gpio_is_valid(bdata->button->gpio)) |
128 | cancel_delayed_work_sync(&bdata->work); | ||
129 | else | ||
130 | del_timer_sync(&bdata->release_timer); | ||
124 | 131 | ||
125 | bdata->disabled = true; | 132 | bdata->disabled = true; |
126 | } | 133 | } |
@@ -343,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) | |||
343 | static void gpio_keys_gpio_work_func(struct work_struct *work) | 350 | static void gpio_keys_gpio_work_func(struct work_struct *work) |
344 | { | 351 | { |
345 | struct gpio_button_data *bdata = | 352 | struct gpio_button_data *bdata = |
346 | container_of(work, struct gpio_button_data, work); | 353 | container_of(work, struct gpio_button_data, work.work); |
347 | 354 | ||
348 | gpio_keys_gpio_report_event(bdata); | 355 | gpio_keys_gpio_report_event(bdata); |
349 | 356 | ||
@@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) | |||
351 | pm_relax(bdata->input->dev.parent); | 358 | pm_relax(bdata->input->dev.parent); |
352 | } | 359 | } |
353 | 360 | ||
354 | static void gpio_keys_gpio_timer(unsigned long _data) | ||
355 | { | ||
356 | struct gpio_button_data *bdata = (struct gpio_button_data *)_data; | ||
357 | |||
358 | schedule_work(&bdata->work); | ||
359 | } | ||
360 | |||
361 | static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) | 361 | static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) |
362 | { | 362 | { |
363 | struct gpio_button_data *bdata = dev_id; | 363 | struct gpio_button_data *bdata = dev_id; |
@@ -366,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) | |||
366 | 366 | ||
367 | if (bdata->button->wakeup) | 367 | if (bdata->button->wakeup) |
368 | pm_stay_awake(bdata->input->dev.parent); | 368 | pm_stay_awake(bdata->input->dev.parent); |
369 | if (bdata->timer_debounce) | 369 | |
370 | mod_timer(&bdata->timer, | 370 | mod_delayed_work(system_wq, |
371 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); | 371 | &bdata->work, |
372 | else | 372 | msecs_to_jiffies(bdata->software_debounce)); |
373 | schedule_work(&bdata->work); | ||
374 | 373 | ||
375 | return IRQ_HANDLED; | 374 | return IRQ_HANDLED; |
376 | } | 375 | } |
@@ -408,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) | |||
408 | input_event(input, EV_KEY, button->code, 1); | 407 | input_event(input, EV_KEY, button->code, 1); |
409 | input_sync(input); | 408 | input_sync(input); |
410 | 409 | ||
411 | if (!bdata->timer_debounce) { | 410 | if (!bdata->release_delay) { |
412 | input_event(input, EV_KEY, button->code, 0); | 411 | input_event(input, EV_KEY, button->code, 0); |
413 | input_sync(input); | 412 | input_sync(input); |
414 | goto out; | 413 | goto out; |
@@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) | |||
417 | bdata->key_pressed = true; | 416 | bdata->key_pressed = true; |
418 | } | 417 | } |
419 | 418 | ||
420 | if (bdata->timer_debounce) | 419 | if (bdata->release_delay) |
421 | mod_timer(&bdata->timer, | 420 | mod_timer(&bdata->release_timer, |
422 | jiffies + msecs_to_jiffies(bdata->timer_debounce)); | 421 | jiffies + msecs_to_jiffies(bdata->release_delay)); |
423 | out: | 422 | out: |
424 | spin_unlock_irqrestore(&bdata->lock, flags); | 423 | spin_unlock_irqrestore(&bdata->lock, flags); |
425 | return IRQ_HANDLED; | 424 | return IRQ_HANDLED; |
@@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data) | |||
429 | { | 428 | { |
430 | struct gpio_button_data *bdata = data; | 429 | struct gpio_button_data *bdata = data; |
431 | 430 | ||
432 | if (bdata->timer_debounce) | 431 | if (gpio_is_valid(bdata->button->gpio)) |
433 | del_timer_sync(&bdata->timer); | 432 | cancel_delayed_work_sync(&bdata->work); |
434 | 433 | else | |
435 | cancel_work_sync(&bdata->work); | 434 | del_timer_sync(&bdata->release_timer); |
436 | } | 435 | } |
437 | 436 | ||
438 | static int gpio_keys_setup_key(struct platform_device *pdev, | 437 | static int gpio_keys_setup_key(struct platform_device *pdev, |
@@ -466,23 +465,25 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
466 | button->debounce_interval * 1000); | 465 | button->debounce_interval * 1000); |
467 | /* use timer if gpiolib doesn't provide debounce */ | 466 | /* use timer if gpiolib doesn't provide debounce */ |
468 | if (error < 0) | 467 | if (error < 0) |
469 | bdata->timer_debounce = | 468 | bdata->software_debounce = |
470 | button->debounce_interval; | 469 | button->debounce_interval; |
471 | } | 470 | } |
472 | 471 | ||
473 | irq = gpio_to_irq(button->gpio); | 472 | if (button->irq) { |
474 | if (irq < 0) { | 473 | bdata->irq = button->irq; |
475 | error = irq; | 474 | } else { |
476 | dev_err(dev, | 475 | irq = gpio_to_irq(button->gpio); |
477 | "Unable to get irq number for GPIO %d, error %d\n", | 476 | if (irq < 0) { |
478 | button->gpio, error); | 477 | error = irq; |
479 | return error; | 478 | dev_err(dev, |
479 | "Unable to get irq number for GPIO %d, error %d\n", | ||
480 | button->gpio, error); | ||
481 | return error; | ||
482 | } | ||
483 | bdata->irq = irq; | ||
480 | } | 484 | } |
481 | bdata->irq = irq; | ||
482 | 485 | ||
483 | INIT_WORK(&bdata->work, gpio_keys_gpio_work_func); | 486 | INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); |
484 | setup_timer(&bdata->timer, | ||
485 | gpio_keys_gpio_timer, (unsigned long)bdata); | ||
486 | 487 | ||
487 | isr = gpio_keys_gpio_isr; | 488 | isr = gpio_keys_gpio_isr; |
488 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; | 489 | irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; |
@@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
499 | return -EINVAL; | 500 | return -EINVAL; |
500 | } | 501 | } |
501 | 502 | ||
502 | bdata->timer_debounce = button->debounce_interval; | 503 | bdata->release_delay = button->debounce_interval; |
503 | setup_timer(&bdata->timer, | 504 | setup_timer(&bdata->release_timer, |
504 | gpio_keys_irq_timer, (unsigned long)bdata); | 505 | gpio_keys_irq_timer, (unsigned long)bdata); |
505 | 506 | ||
506 | isr = gpio_keys_irq_isr; | 507 | isr = gpio_keys_irq_isr; |
@@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, | |||
510 | input_set_capability(input, button->type ?: EV_KEY, button->code); | 511 | input_set_capability(input, button->type ?: EV_KEY, button->code); |
511 | 512 | ||
512 | /* | 513 | /* |
513 | * Install custom action to cancel debounce timer and | 514 | * Install custom action to cancel release timer and |
514 | * workqueue item. | 515 | * workqueue item. |
515 | */ | 516 | */ |
516 | error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); | 517 | error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); |
@@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
618 | 619 | ||
619 | i = 0; | 620 | i = 0; |
620 | for_each_child_of_node(node, pp) { | 621 | for_each_child_of_node(node, pp) { |
621 | int gpio = -1; | ||
622 | enum of_gpio_flags flags; | 622 | enum of_gpio_flags flags; |
623 | 623 | ||
624 | button = &pdata->buttons[i++]; | 624 | button = &pdata->buttons[i++]; |
625 | 625 | ||
626 | if (!of_find_property(pp, "gpios", NULL)) { | 626 | button->gpio = of_get_gpio_flags(pp, 0, &flags); |
627 | button->irq = irq_of_parse_and_map(pp, 0); | 627 | if (button->gpio < 0) { |
628 | if (button->irq == 0) { | 628 | error = button->gpio; |
629 | i--; | 629 | if (error != -ENOENT) { |
630 | pdata->nbuttons--; | ||
631 | dev_warn(dev, "Found button without gpios or irqs\n"); | ||
632 | continue; | ||
633 | } | ||
634 | } else { | ||
635 | gpio = of_get_gpio_flags(pp, 0, &flags); | ||
636 | if (gpio < 0) { | ||
637 | error = gpio; | ||
638 | if (error != -EPROBE_DEFER) | 630 | if (error != -EPROBE_DEFER) |
639 | dev_err(dev, | 631 | dev_err(dev, |
640 | "Failed to get gpio flags, error: %d\n", | 632 | "Failed to get gpio flags, error: %d\n", |
641 | error); | 633 | error); |
642 | return ERR_PTR(error); | 634 | return ERR_PTR(error); |
643 | } | 635 | } |
636 | } else { | ||
637 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | ||
644 | } | 638 | } |
645 | 639 | ||
646 | button->gpio = gpio; | 640 | button->irq = irq_of_parse_and_map(pp, 0); |
647 | button->active_low = flags & OF_GPIO_ACTIVE_LOW; | 641 | |
642 | if (!gpio_is_valid(button->gpio) && !button->irq) { | ||
643 | dev_err(dev, "Found button without gpios or irqs\n"); | ||
644 | return ERR_PTR(-EINVAL); | ||
645 | } | ||
648 | 646 | ||
649 | if (of_property_read_u32(pp, "linux,code", &button->code)) { | 647 | if (of_property_read_u32(pp, "linux,code", &button->code)) { |
650 | dev_err(dev, "Button without keycode: 0x%x\n", | 648 | dev_err(dev, "Button without keycode: 0x%x\n", |
@@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev) | |||
659 | 657 | ||
660 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); | 658 | button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); |
661 | 659 | ||
660 | button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL); | ||
661 | |||
662 | if (of_property_read_u32(pp, "debounce-interval", | 662 | if (of_property_read_u32(pp, "debounce-interval", |
663 | &button->debounce_interval)) | 663 | &button->debounce_interval)) |
664 | button->debounce_interval = 5; | 664 | button->debounce_interval = 5; |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 610a8af795a1..5b152f25a8e1 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -473,7 +473,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) | |||
473 | if (error) | 473 | if (error) |
474 | goto bail1; | 474 | goto bail1; |
475 | 475 | ||
476 | init_completion(&dev->cmd_done); | 476 | reinit_completion(&dev->cmd_done); |
477 | serio_write(serio, 0); | 477 | serio_write(serio, 0); |
478 | serio_write(serio, 0); | 478 | serio_write(serio, 0); |
479 | serio_write(serio, HIL_PKT_CMD >> 8); | 479 | serio_write(serio, HIL_PKT_CMD >> 8); |
@@ -482,7 +482,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) | |||
482 | if (error) | 482 | if (error) |
483 | goto bail1; | 483 | goto bail1; |
484 | 484 | ||
485 | init_completion(&dev->cmd_done); | 485 | reinit_completion(&dev->cmd_done); |
486 | serio_write(serio, 0); | 486 | serio_write(serio, 0); |
487 | serio_write(serio, 0); | 487 | serio_write(serio, 0); |
488 | serio_write(serio, HIL_PKT_CMD >> 8); | 488 | serio_write(serio, HIL_PKT_CMD >> 8); |
@@ -491,7 +491,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) | |||
491 | if (error) | 491 | if (error) |
492 | goto bail1; | 492 | goto bail1; |
493 | 493 | ||
494 | init_completion(&dev->cmd_done); | 494 | reinit_completion(&dev->cmd_done); |
495 | serio_write(serio, 0); | 495 | serio_write(serio, 0); |
496 | serio_write(serio, 0); | 496 | serio_write(serio, 0); |
497 | serio_write(serio, HIL_PKT_CMD >> 8); | 497 | serio_write(serio, HIL_PKT_CMD >> 8); |
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index ef5e67fb567e..fe6e3f22eed7 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -45,13 +45,14 @@ | |||
45 | #define STMPE_KEYPAD_MAX_ROWS 8 | 45 | #define STMPE_KEYPAD_MAX_ROWS 8 |
46 | #define STMPE_KEYPAD_MAX_COLS 8 | 46 | #define STMPE_KEYPAD_MAX_COLS 8 |
47 | #define STMPE_KEYPAD_ROW_SHIFT 3 | 47 | #define STMPE_KEYPAD_ROW_SHIFT 3 |
48 | #define STMPE_KEYPAD_KEYMAP_SIZE \ | 48 | #define STMPE_KEYPAD_KEYMAP_MAX_SIZE \ |
49 | (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS) | 49 | (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS) |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * struct stmpe_keypad_variant - model-specific attributes | 52 | * struct stmpe_keypad_variant - model-specific attributes |
53 | * @auto_increment: whether the KPC_DATA_BYTE register address | 53 | * @auto_increment: whether the KPC_DATA_BYTE register address |
54 | * auto-increments on multiple read | 54 | * auto-increments on multiple read |
55 | * @set_pullup: whether the pins need to have their pull-ups set | ||
55 | * @num_data: number of data bytes | 56 | * @num_data: number of data bytes |
56 | * @num_normal_data: number of normal keys' data bytes | 57 | * @num_normal_data: number of normal keys' data bytes |
57 | * @max_cols: maximum number of columns supported | 58 | * @max_cols: maximum number of columns supported |
@@ -61,6 +62,7 @@ | |||
61 | */ | 62 | */ |
62 | struct stmpe_keypad_variant { | 63 | struct stmpe_keypad_variant { |
63 | bool auto_increment; | 64 | bool auto_increment; |
65 | bool set_pullup; | ||
64 | int num_data; | 66 | int num_data; |
65 | int num_normal_data; | 67 | int num_normal_data; |
66 | int max_cols; | 68 | int max_cols; |
@@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | |||
81 | }, | 83 | }, |
82 | [STMPE2401] = { | 84 | [STMPE2401] = { |
83 | .auto_increment = false, | 85 | .auto_increment = false, |
86 | .set_pullup = true, | ||
84 | .num_data = 3, | 87 | .num_data = 3, |
85 | .num_normal_data = 2, | 88 | .num_normal_data = 2, |
86 | .max_cols = 8, | 89 | .max_cols = 8, |
@@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | |||
90 | }, | 93 | }, |
91 | [STMPE2403] = { | 94 | [STMPE2403] = { |
92 | .auto_increment = true, | 95 | .auto_increment = true, |
96 | .set_pullup = true, | ||
93 | .num_data = 5, | 97 | .num_data = 5, |
94 | .num_normal_data = 3, | 98 | .num_normal_data = 3, |
95 | .max_cols = 8, | 99 | .max_cols = 8, |
@@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | |||
99 | }, | 103 | }, |
100 | }; | 104 | }; |
101 | 105 | ||
106 | /** | ||
107 | * struct stmpe_keypad - STMPE keypad state container | ||
108 | * @stmpe: pointer to parent STMPE device | ||
109 | * @input: spawned input device | ||
110 | * @variant: STMPE variant | ||
111 | * @debounce_ms: debounce interval, in ms. Maximum is | ||
112 | * %STMPE_KEYPAD_MAX_DEBOUNCE. | ||
113 | * @scan_count: number of key scanning cycles to confirm key data. | ||
114 | * Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT. | ||
115 | * @no_autorepeat: disable key autorepeat | ||
116 | * @rows: bitmask for the rows | ||
117 | * @cols: bitmask for the columns | ||
118 | * @keymap: the keymap | ||
119 | */ | ||
102 | struct stmpe_keypad { | 120 | struct stmpe_keypad { |
103 | struct stmpe *stmpe; | 121 | struct stmpe *stmpe; |
104 | struct input_dev *input; | 122 | struct input_dev *input; |
105 | const struct stmpe_keypad_variant *variant; | 123 | const struct stmpe_keypad_variant *variant; |
106 | const struct stmpe_keypad_platform_data *plat; | 124 | unsigned int debounce_ms; |
107 | 125 | unsigned int scan_count; | |
126 | bool no_autorepeat; | ||
108 | unsigned int rows; | 127 | unsigned int rows; |
109 | unsigned int cols; | 128 | unsigned int cols; |
110 | 129 | unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE]; | |
111 | unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE]; | ||
112 | }; | 130 | }; |
113 | 131 | ||
114 | static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) | 132 | static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) |
@@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
171 | unsigned int col_gpios = variant->col_gpios; | 189 | unsigned int col_gpios = variant->col_gpios; |
172 | unsigned int row_gpios = variant->row_gpios; | 190 | unsigned int row_gpios = variant->row_gpios; |
173 | struct stmpe *stmpe = keypad->stmpe; | 191 | struct stmpe *stmpe = keypad->stmpe; |
192 | u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB]; | ||
174 | unsigned int pins = 0; | 193 | unsigned int pins = 0; |
194 | unsigned int pu_pins = 0; | ||
195 | int ret; | ||
175 | int i; | 196 | int i; |
176 | 197 | ||
177 | /* | 198 | /* |
@@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
188 | for (i = 0; i < variant->max_cols; i++) { | 209 | for (i = 0; i < variant->max_cols; i++) { |
189 | int num = __ffs(col_gpios); | 210 | int num = __ffs(col_gpios); |
190 | 211 | ||
191 | if (keypad->cols & (1 << i)) | 212 | if (keypad->cols & (1 << i)) { |
192 | pins |= 1 << num; | 213 | pins |= 1 << num; |
214 | pu_pins |= 1 << num; | ||
215 | } | ||
193 | 216 | ||
194 | col_gpios &= ~(1 << num); | 217 | col_gpios &= ~(1 << num); |
195 | } | 218 | } |
@@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
203 | row_gpios &= ~(1 << num); | 226 | row_gpios &= ~(1 << num); |
204 | } | 227 | } |
205 | 228 | ||
206 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); | 229 | ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); |
230 | if (ret) | ||
231 | return ret; | ||
232 | |||
233 | /* | ||
234 | * On STMPE24xx, set pin bias to pull-up on all keypad input | ||
235 | * pins (columns), this incidentally happen to be maximum 8 pins | ||
236 | * and placed at GPIO0-7 so only the LSB of the pull up register | ||
237 | * ever needs to be written. | ||
238 | */ | ||
239 | if (variant->set_pullup) { | ||
240 | u8 val; | ||
241 | |||
242 | ret = stmpe_reg_read(stmpe, pureg); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | /* Do not touch unused pins, may be used for GPIO */ | ||
247 | val = ret & ~pu_pins; | ||
248 | val |= pu_pins; | ||
249 | |||
250 | ret = stmpe_reg_write(stmpe, pureg, val); | ||
251 | } | ||
252 | |||
253 | return 0; | ||
207 | } | 254 | } |
208 | 255 | ||
209 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | 256 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) |
210 | { | 257 | { |
211 | const struct stmpe_keypad_platform_data *plat = keypad->plat; | ||
212 | const struct stmpe_keypad_variant *variant = keypad->variant; | 258 | const struct stmpe_keypad_variant *variant = keypad->variant; |
213 | struct stmpe *stmpe = keypad->stmpe; | 259 | struct stmpe *stmpe = keypad->stmpe; |
214 | int ret; | 260 | int ret; |
215 | 261 | ||
216 | if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) | 262 | if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) |
217 | return -EINVAL; | 263 | return -EINVAL; |
218 | 264 | ||
219 | if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) | 265 | if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) |
220 | return -EINVAL; | 266 | return -EINVAL; |
221 | 267 | ||
222 | ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD); | 268 | ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD); |
@@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | |||
245 | 291 | ||
246 | ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, | 292 | ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, |
247 | STMPE_KPC_CTRL_MSB_SCAN_COUNT, | 293 | STMPE_KPC_CTRL_MSB_SCAN_COUNT, |
248 | plat->scan_count << 4); | 294 | keypad->scan_count << 4); |
249 | if (ret < 0) | 295 | if (ret < 0) |
250 | return ret; | 296 | return ret; |
251 | 297 | ||
@@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | |||
253 | STMPE_KPC_CTRL_LSB_SCAN | | 299 | STMPE_KPC_CTRL_LSB_SCAN | |
254 | STMPE_KPC_CTRL_LSB_DEBOUNCE, | 300 | STMPE_KPC_CTRL_LSB_DEBOUNCE, |
255 | STMPE_KPC_CTRL_LSB_SCAN | | 301 | STMPE_KPC_CTRL_LSB_SCAN | |
256 | (plat->debounce_ms << 1)); | 302 | (keypad->debounce_ms << 1)); |
257 | } | 303 | } |
258 | 304 | ||
259 | static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) | 305 | static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad, |
306 | u32 used_rows, u32 used_cols) | ||
260 | { | 307 | { |
261 | int row, col; | 308 | int row, col; |
262 | 309 | ||
263 | for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { | 310 | for (row = 0; row < used_rows; row++) { |
264 | for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { | 311 | for (col = 0; col < used_cols; col++) { |
265 | int code = MATRIX_SCAN_CODE(row, col, | 312 | int code = MATRIX_SCAN_CODE(row, col, |
266 | STMPE_KEYPAD_ROW_SHIFT); | 313 | STMPE_KEYPAD_ROW_SHIFT); |
267 | if (keypad->keymap[code] != KEY_RESERVED) { | 314 | if (keypad->keymap[code] != KEY_RESERVED) { |
268 | keypad->rows |= 1 << row; | 315 | keypad->rows |= 1 << row; |
269 | keypad->cols |= 1 << col; | 316 | keypad->cols |= 1 << col; |
@@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) | |||
272 | } | 319 | } |
273 | } | 320 | } |
274 | 321 | ||
275 | #ifdef CONFIG_OF | ||
276 | static const struct stmpe_keypad_platform_data * | ||
277 | stmpe_keypad_of_probe(struct device *dev) | ||
278 | { | ||
279 | struct device_node *np = dev->of_node; | ||
280 | struct stmpe_keypad_platform_data *plat; | ||
281 | |||
282 | if (!np) | ||
283 | return ERR_PTR(-ENODEV); | ||
284 | |||
285 | plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); | ||
286 | if (!plat) | ||
287 | return ERR_PTR(-ENOMEM); | ||
288 | |||
289 | of_property_read_u32(np, "debounce-interval", &plat->debounce_ms); | ||
290 | of_property_read_u32(np, "st,scan-count", &plat->scan_count); | ||
291 | |||
292 | plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); | ||
293 | |||
294 | return plat; | ||
295 | } | ||
296 | #else | ||
297 | static inline const struct stmpe_keypad_platform_data * | ||
298 | stmpe_keypad_of_probe(struct device *dev) | ||
299 | { | ||
300 | return ERR_PTR(-EINVAL); | ||
301 | } | ||
302 | #endif | ||
303 | |||
304 | static int stmpe_keypad_probe(struct platform_device *pdev) | 322 | static int stmpe_keypad_probe(struct platform_device *pdev) |
305 | { | 323 | { |
306 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); | 324 | struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); |
307 | const struct stmpe_keypad_platform_data *plat; | 325 | struct device_node *np = pdev->dev.of_node; |
308 | struct stmpe_keypad *keypad; | 326 | struct stmpe_keypad *keypad; |
309 | struct input_dev *input; | 327 | struct input_dev *input; |
328 | u32 rows; | ||
329 | u32 cols; | ||
310 | int error; | 330 | int error; |
311 | int irq; | 331 | int irq; |
312 | 332 | ||
313 | plat = stmpe->pdata->keypad; | ||
314 | if (!plat) { | ||
315 | plat = stmpe_keypad_of_probe(&pdev->dev); | ||
316 | if (IS_ERR(plat)) | ||
317 | return PTR_ERR(plat); | ||
318 | } | ||
319 | |||
320 | irq = platform_get_irq(pdev, 0); | 333 | irq = platform_get_irq(pdev, 0); |
321 | if (irq < 0) | 334 | if (irq < 0) |
322 | return irq; | 335 | return irq; |
@@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev) | |||
326 | if (!keypad) | 339 | if (!keypad) |
327 | return -ENOMEM; | 340 | return -ENOMEM; |
328 | 341 | ||
342 | keypad->stmpe = stmpe; | ||
343 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; | ||
344 | |||
345 | of_property_read_u32(np, "debounce-interval", &keypad->debounce_ms); | ||
346 | of_property_read_u32(np, "st,scan-count", &keypad->scan_count); | ||
347 | keypad->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat"); | ||
348 | |||
329 | input = devm_input_allocate_device(&pdev->dev); | 349 | input = devm_input_allocate_device(&pdev->dev); |
330 | if (!input) | 350 | if (!input) |
331 | return -ENOMEM; | 351 | return -ENOMEM; |
@@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev) | |||
334 | input->id.bustype = BUS_I2C; | 354 | input->id.bustype = BUS_I2C; |
335 | input->dev.parent = &pdev->dev; | 355 | input->dev.parent = &pdev->dev; |
336 | 356 | ||
337 | error = matrix_keypad_build_keymap(plat->keymap_data, NULL, | 357 | error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); |
338 | STMPE_KEYPAD_MAX_ROWS, | 358 | if (error) |
339 | STMPE_KEYPAD_MAX_COLS, | 359 | return error; |
360 | |||
361 | error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, | ||
340 | keypad->keymap, input); | 362 | keypad->keymap, input); |
341 | if (error) | 363 | if (error) |
342 | return error; | 364 | return error; |
343 | 365 | ||
344 | input_set_capability(input, EV_MSC, MSC_SCAN); | 366 | input_set_capability(input, EV_MSC, MSC_SCAN); |
345 | if (!plat->no_autorepeat) | 367 | if (!keypad->no_autorepeat) |
346 | __set_bit(EV_REP, input->evbit); | 368 | __set_bit(EV_REP, input->evbit); |
347 | 369 | ||
348 | stmpe_keypad_fill_used_pins(keypad); | 370 | stmpe_keypad_fill_used_pins(keypad, rows, cols); |
349 | 371 | ||
350 | keypad->stmpe = stmpe; | ||
351 | keypad->plat = plat; | ||
352 | keypad->input = input; | 372 | keypad->input = input; |
353 | keypad->variant = &stmpe_keypad_variants[stmpe->partnum]; | ||
354 | 373 | ||
355 | error = stmpe_keypad_chip_init(keypad); | 374 | error = stmpe_keypad_chip_init(keypad); |
356 | if (error < 0) | 375 | if (error < 0) |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index d125a019383f..d88d73d83552 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, | |||
881 | unsigned char *pkt, | 881 | unsigned char *pkt, |
882 | unsigned char pkt_id) | 882 | unsigned char pkt_id) |
883 | { | 883 | { |
884 | /* | ||
885 | * packet-fmt b7 b6 b5 b4 b3 b2 b1 b0 | ||
886 | * Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0 | ||
887 | * Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0 | ||
888 | * Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3 | ||
889 | * Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5 | ||
890 | * Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0 | ||
891 | * Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4 | ||
892 | * Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1 | ||
893 | * Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0 | ||
894 | * Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4 | ||
895 | * Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0 | ||
896 | * L: Left button | ||
897 | * R / M: Non-clickpads: Right / Middle button | ||
898 | * Clickpads: When > 2 fingers are down, and some fingers | ||
899 | * are in the button area, then the 2 coordinates reported | ||
900 | * are for fingers outside the button area and these report | ||
901 | * extra fingers being present in the right / left button | ||
902 | * area. Note these fingers are not added to the F field! | ||
903 | * so if a TWO packet is received and R = 1 then there are | ||
904 | * 3 fingers down, etc. | ||
905 | * TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt | ||
906 | * 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt | ||
907 | * otherwise byte 0 bit 4 must be set and byte 0/4/5 are | ||
908 | * in NEW fmt | ||
909 | * F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ... | ||
910 | */ | ||
911 | |||
884 | mt[0].x = ((pkt[2] & 0x80) << 4); | 912 | mt[0].x = ((pkt[2] & 0x80) << 4); |
885 | mt[0].x |= ((pkt[2] & 0x3F) << 5); | 913 | mt[0].x |= ((pkt[2] & 0x3F) << 5); |
886 | mt[0].x |= ((pkt[3] & 0x30) >> 1); | 914 | mt[0].x |= ((pkt[3] & 0x30) >> 1); |
@@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, | |||
919 | 947 | ||
920 | static int alps_get_mt_count(struct input_mt_pos *mt) | 948 | static int alps_get_mt_count(struct input_mt_pos *mt) |
921 | { | 949 | { |
922 | int i; | 950 | int i, fingers = 0; |
923 | 951 | ||
924 | for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++) | 952 | for (i = 0; i < MAX_TOUCHES; i++) { |
925 | /* empty */; | 953 | if (mt[i].x != 0 || mt[i].y != 0) |
954 | fingers++; | ||
955 | } | ||
926 | 956 | ||
927 | return i; | 957 | return fingers; |
928 | } | 958 | } |
929 | 959 | ||
930 | static int alps_decode_packet_v7(struct alps_fields *f, | 960 | static int alps_decode_packet_v7(struct alps_fields *f, |
931 | unsigned char *p, | 961 | unsigned char *p, |
932 | struct psmouse *psmouse) | 962 | struct psmouse *psmouse) |
933 | { | 963 | { |
964 | struct alps_data *priv = psmouse->private; | ||
934 | unsigned char pkt_id; | 965 | unsigned char pkt_id; |
935 | 966 | ||
936 | pkt_id = alps_get_packet_id_v7(p); | 967 | pkt_id = alps_get_packet_id_v7(p); |
@@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f, | |||
938 | return 0; | 969 | return 0; |
939 | if (pkt_id == V7_PACKET_ID_UNKNOWN) | 970 | if (pkt_id == V7_PACKET_ID_UNKNOWN) |
940 | return -1; | 971 | return -1; |
972 | /* | ||
973 | * NEW packets are send to indicate a discontinuity in the finger | ||
974 | * coordinate reporting. Specifically a finger may have moved from | ||
975 | * slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for | ||
976 | * us. | ||
977 | * | ||
978 | * NEW packets have 3 problems: | ||
979 | * 1) They do not contain middle / right button info (on non clickpads) | ||
980 | * this can be worked around by preserving the old button state | ||
981 | * 2) They do not contain an accurate fingercount, and they are | ||
982 | * typically send when the number of fingers changes. We cannot use | ||
983 | * the old finger count as that may mismatch with the amount of | ||
984 | * touch coordinates we've available in the NEW packet | ||
985 | * 3) Their x data for the second touch is inaccurate leading to | ||
986 | * a possible jump of the x coordinate by 16 units when the first | ||
987 | * non NEW packet comes in | ||
988 | * Since problems 2 & 3 cannot be worked around, just ignore them. | ||
989 | */ | ||
990 | if (pkt_id == V7_PACKET_ID_NEW) | ||
991 | return 1; | ||
941 | 992 | ||
942 | alps_get_finger_coordinate_v7(f->mt, p, pkt_id); | 993 | alps_get_finger_coordinate_v7(f->mt, p, pkt_id); |
943 | 994 | ||
944 | if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) { | 995 | if (pkt_id == V7_PACKET_ID_TWO) |
945 | f->left = (p[0] & 0x80) >> 7; | 996 | f->fingers = alps_get_mt_count(f->mt); |
997 | else /* pkt_id == V7_PACKET_ID_MULTI */ | ||
998 | f->fingers = 3 + (p[5] & 0x03); | ||
999 | |||
1000 | f->left = (p[0] & 0x80) >> 7; | ||
1001 | if (priv->flags & ALPS_BUTTONPAD) { | ||
1002 | if (p[0] & 0x20) | ||
1003 | f->fingers++; | ||
1004 | if (p[0] & 0x10) | ||
1005 | f->fingers++; | ||
1006 | } else { | ||
946 | f->right = (p[0] & 0x20) >> 5; | 1007 | f->right = (p[0] & 0x20) >> 5; |
947 | f->middle = (p[0] & 0x10) >> 4; | 1008 | f->middle = (p[0] & 0x10) >> 4; |
948 | } | 1009 | } |
949 | 1010 | ||
950 | if (pkt_id == V7_PACKET_ID_TWO) | 1011 | /* Sometimes a single touch is reported in mt[1] rather then mt[0] */ |
951 | f->fingers = alps_get_mt_count(f->mt); | 1012 | if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) { |
952 | else if (pkt_id == V7_PACKET_ID_MULTI) | 1013 | f->mt[0].x = f->mt[1].x; |
953 | f->fingers = 3 + (p[5] & 0x03); | 1014 | f->mt[0].y = f->mt[1].y; |
1015 | f->mt[1].x = 0; | ||
1016 | f->mt[1].y = 0; | ||
1017 | } | ||
954 | 1018 | ||
955 | return 0; | 1019 | return 0; |
956 | } | 1020 | } |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index f2b978026407..6e22682c8255 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1097,6 +1097,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, | |||
1097 | * Asus UX31 0x361f00 20, 15, 0e clickpad | 1097 | * Asus UX31 0x361f00 20, 15, 0e clickpad |
1098 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad | 1098 | * Asus UX32VD 0x361f02 00, 15, 0e clickpad |
1099 | * Avatar AVIU-145A2 0x361f00 ? clickpad | 1099 | * Avatar AVIU-145A2 0x361f00 ? clickpad |
1100 | * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons | ||
1101 | * Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons | ||
1100 | * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) | 1102 | * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) |
1101 | * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons | 1103 | * Gigabyte U2442 0x450f01 58, 17, 0c 2 hw buttons |
1102 | * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) | 1104 | * Lenovo L430 0x350f02 b9, 15, 0c 2 hw buttons (*) |
@@ -1475,6 +1477,20 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { | |||
1475 | DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), | 1477 | DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), |
1476 | }, | 1478 | }, |
1477 | }, | 1479 | }, |
1480 | { | ||
1481 | /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ | ||
1482 | .matches = { | ||
1483 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
1484 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"), | ||
1485 | }, | ||
1486 | }, | ||
1487 | { | ||
1488 | /* Fujitsu LIFEBOOK E544 does not work with crc_enabled == 0 */ | ||
1489 | .matches = { | ||
1490 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
1491 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"), | ||
1492 | }, | ||
1493 | }, | ||
1478 | #endif | 1494 | #endif |
1479 | { } | 1495 | { } |
1480 | }; | 1496 | }; |
@@ -1520,6 +1536,8 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1520 | case 7: | 1536 | case 7: |
1521 | case 8: | 1537 | case 8: |
1522 | case 9: | 1538 | case 9: |
1539 | case 10: | ||
1540 | case 13: | ||
1523 | etd->hw_version = 4; | 1541 | etd->hw_version = 4; |
1524 | break; | 1542 | break; |
1525 | default: | 1543 | default: |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f9472920d986..23e26e0768b5 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -135,8 +135,9 @@ static const struct min_max_quirk min_max_pnpid_table[] = { | |||
135 | 1232, 5710, 1156, 4696 | 135 | 1232, 5710, 1156, 4696 |
136 | }, | 136 | }, |
137 | { | 137 | { |
138 | (const char * const []){"LEN0034", "LEN0036", "LEN0039", | 138 | (const char * const []){"LEN0034", "LEN0036", "LEN0037", |
139 | "LEN2002", "LEN2004", NULL}, | 139 | "LEN0039", "LEN2002", "LEN2004", |
140 | NULL}, | ||
140 | 1024, 5112, 2024, 4832 | 141 | 1024, 5112, 2024, 4832 |
141 | }, | 142 | }, |
142 | { | 143 | { |
@@ -165,7 +166,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
165 | "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */ | 166 | "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */ |
166 | "LEN0035", /* X240 */ | 167 | "LEN0035", /* X240 */ |
167 | "LEN0036", /* T440 */ | 168 | "LEN0036", /* T440 */ |
168 | "LEN0037", | 169 | "LEN0037", /* X1 Carbon 2nd */ |
169 | "LEN0038", | 170 | "LEN0038", |
170 | "LEN0039", /* T440s */ | 171 | "LEN0039", /* T440s */ |
171 | "LEN0041", | 172 | "LEN0041", |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 30c8b6998808..354d47ecd66a 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH); | |||
227 | TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH); | 227 | TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH); |
228 | TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); | 228 | TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); |
229 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); | 229 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); |
230 | TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); | ||
230 | 231 | ||
231 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0, | 232 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0, |
232 | TP_DEF_PTSON); | 233 | TP_DEF_PTSON); |
@@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = { | |||
246 | &psmouse_attr_upthresh.dattr.attr, | 247 | &psmouse_attr_upthresh.dattr.attr, |
247 | &psmouse_attr_ztime.dattr.attr, | 248 | &psmouse_attr_ztime.dattr.attr, |
248 | &psmouse_attr_jenks.dattr.attr, | 249 | &psmouse_attr_jenks.dattr.attr, |
250 | &psmouse_attr_drift_time.dattr.attr, | ||
249 | &psmouse_attr_press_to_select.dattr.attr, | 251 | &psmouse_attr_press_to_select.dattr.attr, |
250 | &psmouse_attr_skipback.dattr.attr, | 252 | &psmouse_attr_skipback.dattr.attr, |
251 | &psmouse_attr_ext_dev.dattr.attr, | 253 | &psmouse_attr_ext_dev.dattr.attr, |
@@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state) | |||
312 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh); | 314 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh); |
313 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime); | 315 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime); |
314 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks); | 316 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks); |
317 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time); | ||
315 | 318 | ||
316 | /* toggles */ | 319 | /* toggles */ |
317 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select); | 320 | TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select); |
@@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp) | |||
332 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh); | 335 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh); |
333 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime); | 336 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime); |
334 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks); | 337 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks); |
338 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time); | ||
335 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia); | 339 | TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia); |
336 | 340 | ||
337 | /* toggles */ | 341 | /* toggles */ |
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index ecd0547964a5..5617ed3a7d7a 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -70,6 +70,9 @@ | |||
70 | #define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */ | 70 | #define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */ |
71 | #define TP_Z_TIME 0x5E /* How sharp of a press */ | 71 | #define TP_Z_TIME 0x5E /* How sharp of a press */ |
72 | #define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */ | 72 | #define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */ |
73 | #define TP_DRIFT_TIME 0x5F /* How long a 'hands off' condition */ | ||
74 | /* must last (x*107ms) for drift */ | ||
75 | /* correction to occur */ | ||
73 | 76 | ||
74 | /* | 77 | /* |
75 | * Toggling Flag bits | 78 | * Toggling Flag bits |
@@ -120,6 +123,7 @@ | |||
120 | #define TP_DEF_UP_THRESH 0xFF | 123 | #define TP_DEF_UP_THRESH 0xFF |
121 | #define TP_DEF_Z_TIME 0x26 | 124 | #define TP_DEF_Z_TIME 0x26 |
122 | #define TP_DEF_JENKS_CURV 0x87 | 125 | #define TP_DEF_JENKS_CURV 0x87 |
126 | #define TP_DEF_DRIFT_TIME 0x05 | ||
123 | 127 | ||
124 | /* Toggles */ | 128 | /* Toggles */ |
125 | #define TP_DEF_MB 0x00 | 129 | #define TP_DEF_MB 0x00 |
@@ -137,6 +141,7 @@ struct trackpoint_data | |||
137 | unsigned char draghys, mindrag; | 141 | unsigned char draghys, mindrag; |
138 | unsigned char thresh, upthresh; | 142 | unsigned char thresh, upthresh; |
139 | unsigned char ztime, jenks; | 143 | unsigned char ztime, jenks; |
144 | unsigned char drift_time; | ||
140 | 145 | ||
141 | /* toggles */ | 146 | /* toggles */ |
142 | unsigned char press_to_select; | 147 | unsigned char press_to_select; |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index c66d1b53843e..c11556563ef0 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -152,6 +152,14 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
152 | }, | 152 | }, |
153 | }, | 153 | }, |
154 | { | 154 | { |
155 | /* Medion Akoya E7225 */ | ||
156 | .matches = { | ||
157 | DMI_MATCH(DMI_SYS_VENDOR, "Medion"), | ||
158 | DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), | ||
159 | DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), | ||
160 | }, | ||
161 | }, | ||
162 | { | ||
155 | /* Blue FB5601 */ | 163 | /* Blue FB5601 */ |
156 | .matches = { | 164 | .matches = { |
157 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), | 165 | DMI_MATCH(DMI_SYS_VENDOR, "blue"), |
@@ -415,6 +423,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
415 | }, | 423 | }, |
416 | }, | 424 | }, |
417 | { | 425 | { |
426 | /* Acer Aspire 7738 */ | ||
427 | .matches = { | ||
428 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
429 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), | ||
430 | }, | ||
431 | }, | ||
432 | { | ||
418 | /* Gericom Bellagio */ | 433 | /* Gericom Bellagio */ |
419 | .matches = { | 434 | .matches = { |
420 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), | 435 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), |
@@ -745,6 +760,35 @@ static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { | |||
745 | { } | 760 | { } |
746 | }; | 761 | }; |
747 | 762 | ||
763 | /* | ||
764 | * Some laptops need keyboard reset before probing for the trackpad to get | ||
765 | * it detected, initialised & finally work. | ||
766 | */ | ||
767 | static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { | ||
768 | { | ||
769 | /* Gigabyte P35 v2 - Elantech touchpad */ | ||
770 | .matches = { | ||
771 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
772 | DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), | ||
773 | }, | ||
774 | }, | ||
775 | { | ||
776 | /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ | ||
777 | .matches = { | ||
778 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
779 | DMI_MATCH(DMI_PRODUCT_NAME, "X3"), | ||
780 | }, | ||
781 | }, | ||
782 | { | ||
783 | /* Gigabyte P34 - Elantech touchpad */ | ||
784 | .matches = { | ||
785 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
786 | DMI_MATCH(DMI_PRODUCT_NAME, "P34"), | ||
787 | }, | ||
788 | }, | ||
789 | { } | ||
790 | }; | ||
791 | |||
748 | #endif /* CONFIG_X86 */ | 792 | #endif /* CONFIG_X86 */ |
749 | 793 | ||
750 | #ifdef CONFIG_PNP | 794 | #ifdef CONFIG_PNP |
@@ -1040,6 +1084,9 @@ static int __init i8042_platform_init(void) | |||
1040 | if (dmi_check_system(i8042_dmi_dritek_table)) | 1084 | if (dmi_check_system(i8042_dmi_dritek_table)) |
1041 | i8042_dritek = true; | 1085 | i8042_dritek = true; |
1042 | 1086 | ||
1087 | if (dmi_check_system(i8042_dmi_kbdreset_table)) | ||
1088 | i8042_kbdreset = true; | ||
1089 | |||
1043 | /* | 1090 | /* |
1044 | * A20 was already enabled during early kernel init. But some buggy | 1091 | * A20 was already enabled during early kernel init. But some buggy |
1045 | * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to | 1092 | * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 924e4bf357fb..986a71c614b0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -67,6 +67,10 @@ static bool i8042_notimeout; | |||
67 | module_param_named(notimeout, i8042_notimeout, bool, 0); | 67 | module_param_named(notimeout, i8042_notimeout, bool, 0); |
68 | MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); | 68 | MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042"); |
69 | 69 | ||
70 | static bool i8042_kbdreset; | ||
71 | module_param_named(kbdreset, i8042_kbdreset, bool, 0); | ||
72 | MODULE_PARM_DESC(kbdreset, "Reset device connected to KBD port"); | ||
73 | |||
70 | #ifdef CONFIG_X86 | 74 | #ifdef CONFIG_X86 |
71 | static bool i8042_dritek; | 75 | static bool i8042_dritek; |
72 | module_param_named(dritek, i8042_dritek, bool, 0); | 76 | module_param_named(dritek, i8042_dritek, bool, 0); |
@@ -790,6 +794,16 @@ static int __init i8042_check_aux(void) | |||
790 | return -1; | 794 | return -1; |
791 | 795 | ||
792 | /* | 796 | /* |
797 | * Reset keyboard (needed on some laptops to successfully detect | ||
798 | * touchpad, e.g., some Gigabyte laptop models with Elantech | ||
799 | * touchpads). | ||
800 | */ | ||
801 | if (i8042_kbdreset) { | ||
802 | pr_warn("Attempting to reset device connected to KBD port\n"); | ||
803 | i8042_kbd_write(NULL, (unsigned char) 0xff); | ||
804 | } | ||
805 | |||
806 | /* | ||
793 | * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and | 807 | * Test AUX IRQ delivery to make sure BIOS did not grab the IRQ and |
794 | * used it for a PCI card or somethig else. | 808 | * used it for a PCI card or somethig else. |
795 | */ | 809 | */ |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index bb070206223c..95ee92a91bd2 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -99,13 +99,9 @@ | |||
99 | #define MXT_T6_STATUS_COMSERR (1 << 2) | 99 | #define MXT_T6_STATUS_COMSERR (1 << 2) |
100 | 100 | ||
101 | /* MXT_GEN_POWER_T7 field */ | 101 | /* MXT_GEN_POWER_T7 field */ |
102 | struct t7_config { | 102 | #define MXT_POWER_IDLEACQINT 0 |
103 | u8 idle; | 103 | #define MXT_POWER_ACTVACQINT 1 |
104 | u8 active; | 104 | #define MXT_POWER_ACTV2IDLETO 2 |
105 | } __packed; | ||
106 | |||
107 | #define MXT_POWER_CFG_RUN 0 | ||
108 | #define MXT_POWER_CFG_DEEPSLEEP 1 | ||
109 | 105 | ||
110 | /* MXT_GEN_ACQUIRE_T8 field */ | 106 | /* MXT_GEN_ACQUIRE_T8 field */ |
111 | #define MXT_ACQUIRE_CHRGTIME 0 | 107 | #define MXT_ACQUIRE_CHRGTIME 0 |
@@ -117,6 +113,7 @@ struct t7_config { | |||
117 | #define MXT_ACQUIRE_ATCHCALSTHR 7 | 113 | #define MXT_ACQUIRE_ATCHCALSTHR 7 |
118 | 114 | ||
119 | /* MXT_TOUCH_MULTI_T9 field */ | 115 | /* MXT_TOUCH_MULTI_T9 field */ |
116 | #define MXT_TOUCH_CTRL 0 | ||
120 | #define MXT_T9_ORIENT 9 | 117 | #define MXT_T9_ORIENT 9 |
121 | #define MXT_T9_RANGE 18 | 118 | #define MXT_T9_RANGE 18 |
122 | 119 | ||
@@ -256,7 +253,6 @@ struct mxt_data { | |||
256 | bool update_input; | 253 | bool update_input; |
257 | u8 last_message_count; | 254 | u8 last_message_count; |
258 | u8 num_touchids; | 255 | u8 num_touchids; |
259 | struct t7_config t7_cfg; | ||
260 | 256 | ||
261 | /* Cached parameters from object table */ | 257 | /* Cached parameters from object table */ |
262 | u16 T5_address; | 258 | u16 T5_address; |
@@ -672,6 +668,20 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg) | |||
672 | data->t6_status = status; | 668 | data->t6_status = status; |
673 | } | 669 | } |
674 | 670 | ||
671 | static int mxt_write_object(struct mxt_data *data, | ||
672 | u8 type, u8 offset, u8 val) | ||
673 | { | ||
674 | struct mxt_object *object; | ||
675 | u16 reg; | ||
676 | |||
677 | object = mxt_get_object(data, type); | ||
678 | if (!object || offset >= mxt_obj_size(object)) | ||
679 | return -EINVAL; | ||
680 | |||
681 | reg = object->start_address; | ||
682 | return mxt_write_reg(data->client, reg + offset, val); | ||
683 | } | ||
684 | |||
675 | static void mxt_input_button(struct mxt_data *data, u8 *message) | 685 | static void mxt_input_button(struct mxt_data *data, u8 *message) |
676 | { | 686 | { |
677 | struct input_dev *input = data->input_dev; | 687 | struct input_dev *input = data->input_dev; |
@@ -1742,60 +1752,6 @@ err_free_object_table: | |||
1742 | return error; | 1752 | return error; |
1743 | } | 1753 | } |
1744 | 1754 | ||
1745 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) | ||
1746 | { | ||
1747 | struct device *dev = &data->client->dev; | ||
1748 | int error; | ||
1749 | struct t7_config *new_config; | ||
1750 | struct t7_config deepsleep = { .active = 0, .idle = 0 }; | ||
1751 | |||
1752 | if (sleep == MXT_POWER_CFG_DEEPSLEEP) | ||
1753 | new_config = &deepsleep; | ||
1754 | else | ||
1755 | new_config = &data->t7_cfg; | ||
1756 | |||
1757 | error = __mxt_write_reg(data->client, data->T7_address, | ||
1758 | sizeof(data->t7_cfg), new_config); | ||
1759 | if (error) | ||
1760 | return error; | ||
1761 | |||
1762 | dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n", | ||
1763 | new_config->active, new_config->idle); | ||
1764 | |||
1765 | return 0; | ||
1766 | } | ||
1767 | |||
1768 | static int mxt_init_t7_power_cfg(struct mxt_data *data) | ||
1769 | { | ||
1770 | struct device *dev = &data->client->dev; | ||
1771 | int error; | ||
1772 | bool retry = false; | ||
1773 | |||
1774 | recheck: | ||
1775 | error = __mxt_read_reg(data->client, data->T7_address, | ||
1776 | sizeof(data->t7_cfg), &data->t7_cfg); | ||
1777 | if (error) | ||
1778 | return error; | ||
1779 | |||
1780 | if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) { | ||
1781 | if (!retry) { | ||
1782 | dev_dbg(dev, "T7 cfg zero, resetting\n"); | ||
1783 | mxt_soft_reset(data); | ||
1784 | retry = true; | ||
1785 | goto recheck; | ||
1786 | } else { | ||
1787 | dev_dbg(dev, "T7 cfg zero after reset, overriding\n"); | ||
1788 | data->t7_cfg.active = 20; | ||
1789 | data->t7_cfg.idle = 100; | ||
1790 | return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); | ||
1791 | } | ||
1792 | } | ||
1793 | |||
1794 | dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n", | ||
1795 | data->t7_cfg.active, data->t7_cfg.idle); | ||
1796 | return 0; | ||
1797 | } | ||
1798 | |||
1799 | static int mxt_configure_objects(struct mxt_data *data, | 1755 | static int mxt_configure_objects(struct mxt_data *data, |
1800 | const struct firmware *cfg) | 1756 | const struct firmware *cfg) |
1801 | { | 1757 | { |
@@ -1809,12 +1765,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
1809 | dev_warn(dev, "Error %d updating config\n", error); | 1765 | dev_warn(dev, "Error %d updating config\n", error); |
1810 | } | 1766 | } |
1811 | 1767 | ||
1812 | error = mxt_init_t7_power_cfg(data); | ||
1813 | if (error) { | ||
1814 | dev_err(dev, "Failed to initialize power cfg\n"); | ||
1815 | return error; | ||
1816 | } | ||
1817 | |||
1818 | error = mxt_initialize_t9_input_device(data); | 1768 | error = mxt_initialize_t9_input_device(data); |
1819 | if (error) | 1769 | if (error) |
1820 | return error; | 1770 | return error; |
@@ -2093,15 +2043,16 @@ static const struct attribute_group mxt_attr_group = { | |||
2093 | 2043 | ||
2094 | static void mxt_start(struct mxt_data *data) | 2044 | static void mxt_start(struct mxt_data *data) |
2095 | { | 2045 | { |
2096 | mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); | 2046 | /* Touch enable */ |
2097 | 2047 | mxt_write_object(data, | |
2098 | /* Recalibrate since chip has been in deep sleep */ | 2048 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); |
2099 | mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); | ||
2100 | } | 2049 | } |
2101 | 2050 | ||
2102 | static void mxt_stop(struct mxt_data *data) | 2051 | static void mxt_stop(struct mxt_data *data) |
2103 | { | 2052 | { |
2104 | mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); | 2053 | /* Touch disable */ |
2054 | mxt_write_object(data, | ||
2055 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0); | ||
2105 | } | 2056 | } |
2106 | 2057 | ||
2107 | static int mxt_input_open(struct input_dev *dev) | 2058 | static int mxt_input_open(struct input_dev *dev) |
@@ -2266,6 +2217,8 @@ static int __maybe_unused mxt_resume(struct device *dev) | |||
2266 | struct mxt_data *data = i2c_get_clientdata(client); | 2217 | struct mxt_data *data = i2c_get_clientdata(client); |
2267 | struct input_dev *input_dev = data->input_dev; | 2218 | struct input_dev *input_dev = data->input_dev; |
2268 | 2219 | ||
2220 | mxt_soft_reset(data); | ||
2221 | |||
2269 | mutex_lock(&input_dev->mutex); | 2222 | mutex_lock(&input_dev->mutex); |
2270 | 2223 | ||
2271 | if (input_dev->users) | 2224 | if (input_dev->users) |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 3793fcc7e5db..d4c24fb7704f 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, | |||
850 | } | 850 | } |
851 | 851 | ||
852 | #define EDT_ATTR_CHECKSET(name, reg) \ | 852 | #define EDT_ATTR_CHECKSET(name, reg) \ |
853 | do { \ | ||
853 | if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \ | 854 | if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \ |
854 | pdata->name <= edt_ft5x06_attr_##name.limit_high) \ | 855 | pdata->name <= edt_ft5x06_attr_##name.limit_high) \ |
855 | edt_ft5x06_register_write(tsdata, reg, pdata->name) | 856 | edt_ft5x06_register_write(tsdata, reg, pdata->name); \ |
857 | } while (0) | ||
856 | 858 | ||
857 | #define EDT_GET_PROP(name, reg) { \ | 859 | #define EDT_GET_PROP(name, reg) { \ |
858 | u32 val; \ | 860 | u32 val; \ |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 1232336b960e..40dfbc0444c0 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -4029,14 +4029,6 @@ static int device_notifier(struct notifier_block *nb, | |||
4029 | if (action != BUS_NOTIFY_REMOVED_DEVICE) | 4029 | if (action != BUS_NOTIFY_REMOVED_DEVICE) |
4030 | return 0; | 4030 | return 0; |
4031 | 4031 | ||
4032 | /* | ||
4033 | * If the device is still attached to a device driver we can't | ||
4034 | * tear down the domain yet as DMA mappings may still be in use. | ||
4035 | * Wait for the BUS_NOTIFY_UNBOUND_DRIVER event to do that. | ||
4036 | */ | ||
4037 | if (action == BUS_NOTIFY_DEL_DEVICE && dev->driver != NULL) | ||
4038 | return 0; | ||
4039 | |||
4040 | domain = find_domain(dev); | 4032 | domain = find_domain(dev); |
4041 | if (!domain) | 4033 | if (!domain) |
4042 | return 0; | 4034 | return 0; |
@@ -4428,6 +4420,10 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, | |||
4428 | domain_remove_one_dev_info(old_domain, dev); | 4420 | domain_remove_one_dev_info(old_domain, dev); |
4429 | else | 4421 | else |
4430 | domain_remove_dev_info(old_domain); | 4422 | domain_remove_dev_info(old_domain); |
4423 | |||
4424 | if (!domain_type_is_vm_or_si(old_domain) && | ||
4425 | list_empty(&old_domain->devices)) | ||
4426 | domain_exit(old_domain); | ||
4431 | } | 4427 | } |
4432 | } | 4428 | } |
4433 | 4429 | ||
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 68dfb0fd5ee9..748693192c20 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c | |||
@@ -558,7 +558,7 @@ static pmd_t *ipmmu_alloc_pmd(struct ipmmu_vmsa_device *mmu, pgd_t *pgd, | |||
558 | 558 | ||
559 | static u64 ipmmu_page_prot(unsigned int prot, u64 type) | 559 | static u64 ipmmu_page_prot(unsigned int prot, u64 type) |
560 | { | 560 | { |
561 | u64 pgprot = ARM_VMSA_PTE_XN | ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF | 561 | u64 pgprot = ARM_VMSA_PTE_nG | ARM_VMSA_PTE_AF |
562 | | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV | 562 | | ARM_VMSA_PTE_SH_IS | ARM_VMSA_PTE_AP_UNPRIV |
563 | | ARM_VMSA_PTE_NS | type; | 563 | | ARM_VMSA_PTE_NS | type; |
564 | 564 | ||
@@ -568,8 +568,8 @@ static u64 ipmmu_page_prot(unsigned int prot, u64 type) | |||
568 | if (prot & IOMMU_CACHE) | 568 | if (prot & IOMMU_CACHE) |
569 | pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT; | 569 | pgprot |= IMMAIR_ATTR_IDX_WBRWA << ARM_VMSA_PTE_ATTRINDX_SHIFT; |
570 | 570 | ||
571 | if (prot & IOMMU_EXEC) | 571 | if (prot & IOMMU_NOEXEC) |
572 | pgprot &= ~ARM_VMSA_PTE_XN; | 572 | pgprot |= ARM_VMSA_PTE_XN; |
573 | else if (!(prot & (IOMMU_READ | IOMMU_WRITE))) | 573 | else if (!(prot & (IOMMU_READ | IOMMU_WRITE))) |
574 | /* If no access create a faulting entry to avoid TLB fills. */ | 574 | /* If no access create a faulting entry to avoid TLB fills. */ |
575 | pgprot &= ~ARM_VMSA_PTE_PAGE; | 575 | pgprot &= ~ARM_VMSA_PTE_PAGE; |
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index b2023af384b9..6a8b1ec4a48a 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c | |||
@@ -1009,7 +1009,6 @@ static struct platform_driver rk_iommu_driver = { | |||
1009 | .remove = rk_iommu_remove, | 1009 | .remove = rk_iommu_remove, |
1010 | .driver = { | 1010 | .driver = { |
1011 | .name = "rk_iommu", | 1011 | .name = "rk_iommu", |
1012 | .owner = THIS_MODULE, | ||
1013 | .of_match_table = of_match_ptr(rk_iommu_dt_ids), | 1012 | .of_match_table = of_match_ptr(rk_iommu_dt_ids), |
1014 | }, | 1013 | }, |
1015 | }; | 1014 | }; |
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c index f722a0c466cf..c48da057dbb1 100644 --- a/drivers/iommu/tegra-gart.c +++ b/drivers/iommu/tegra-gart.c | |||
@@ -315,6 +315,7 @@ static const struct iommu_ops gart_iommu_ops = { | |||
315 | .attach_dev = gart_iommu_attach_dev, | 315 | .attach_dev = gart_iommu_attach_dev, |
316 | .detach_dev = gart_iommu_detach_dev, | 316 | .detach_dev = gart_iommu_detach_dev, |
317 | .map = gart_iommu_map, | 317 | .map = gart_iommu_map, |
318 | .map_sg = default_iommu_map_sg, | ||
318 | .unmap = gart_iommu_unmap, | 319 | .unmap = gart_iommu_unmap, |
319 | .iova_to_phys = gart_iommu_iova_to_phys, | 320 | .iova_to_phys = gart_iommu_iova_to_phys, |
320 | .pgsize_bitmap = GART_IOMMU_PGSIZES, | 321 | .pgsize_bitmap = GART_IOMMU_PGSIZES, |
@@ -395,7 +396,7 @@ static int tegra_gart_probe(struct platform_device *pdev) | |||
395 | do_gart_setup(gart, NULL); | 396 | do_gart_setup(gart, NULL); |
396 | 397 | ||
397 | gart_handle = gart; | 398 | gart_handle = gart; |
398 | bus_set_iommu(&platform_bus_type, &gart_iommu_ops); | 399 | |
399 | return 0; | 400 | return 0; |
400 | } | 401 | } |
401 | 402 | ||
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index d111ac779c40..63cd031b2c28 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define AT91_AIC_IRQ_MIN_PRIORITY 0 | 28 | #define AT91_AIC_IRQ_MIN_PRIORITY 0 |
29 | #define AT91_AIC_IRQ_MAX_PRIORITY 7 | 29 | #define AT91_AIC_IRQ_MAX_PRIORITY 7 |
30 | 30 | ||
31 | #define AT91_AIC_SRCTYPE GENMASK(7, 6) | 31 | #define AT91_AIC_SRCTYPE GENMASK(6, 5) |
32 | #define AT91_AIC_SRCTYPE_LOW (0 << 5) | 32 | #define AT91_AIC_SRCTYPE_LOW (0 << 5) |
33 | #define AT91_AIC_SRCTYPE_FALLING (1 << 5) | 33 | #define AT91_AIC_SRCTYPE_FALLING (1 << 5) |
34 | #define AT91_AIC_SRCTYPE_HIGH (2 << 5) | 34 | #define AT91_AIC_SRCTYPE_HIGH (2 << 5) |
@@ -74,7 +74,7 @@ int aic_common_set_type(struct irq_data *d, unsigned type, unsigned *val) | |||
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | } | 75 | } |
76 | 76 | ||
77 | *val &= AT91_AIC_SRCTYPE; | 77 | *val &= ~AT91_AIC_SRCTYPE; |
78 | *val |= aic_type; | 78 | *val |= aic_type; |
79 | 79 | ||
80 | return 0; | 80 | return 0; |
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 86e4684adeb1..d8996bdf0f61 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -1053,7 +1053,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, | |||
1053 | * of two entries. No, the architecture doesn't let you | 1053 | * of two entries. No, the architecture doesn't let you |
1054 | * express an ITT with a single entry. | 1054 | * express an ITT with a single entry. |
1055 | */ | 1055 | */ |
1056 | nr_ites = max(2, roundup_pow_of_two(nvecs)); | 1056 | nr_ites = max(2UL, roundup_pow_of_two(nvecs)); |
1057 | sz = nr_ites * its->ite_size; | 1057 | sz = nr_ites * its->ite_size; |
1058 | sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; | 1058 | sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; |
1059 | itt = kmalloc(sz, GFP_KERNEL); | 1059 | itt = kmalloc(sz, GFP_KERNEL); |
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c index 29b8f21b74d0..6bc2deb73d53 100644 --- a/drivers/irqchip/irq-hip04.c +++ b/drivers/irqchip/irq-hip04.c | |||
@@ -381,7 +381,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent) | |||
381 | * It will be refined as each CPU probes its ID. | 381 | * It will be refined as each CPU probes its ID. |
382 | */ | 382 | */ |
383 | for (i = 0; i < NR_HIP04_CPU_IF; i++) | 383 | for (i = 0; i < NR_HIP04_CPU_IF; i++) |
384 | hip04_cpu_map[i] = 0xff; | 384 | hip04_cpu_map[i] = 0xffff; |
385 | 385 | ||
386 | /* | 386 | /* |
387 | * Find out how many interrupts are supported. | 387 | * Find out how many interrupts are supported. |
diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 7e342df6a62f..0b0d2c00a2df 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c | |||
@@ -137,9 +137,9 @@ static int __init mtk_sysirq_of_init(struct device_node *node, | |||
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | 138 | ||
139 | chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); | 139 | chip_data->intpol_base = of_io_request_and_map(node, 0, "intpol"); |
140 | if (!chip_data->intpol_base) { | 140 | if (IS_ERR(chip_data->intpol_base)) { |
141 | pr_err("mtk_sysirq: unable to map sysirq register\n"); | 141 | pr_err("mtk_sysirq: unable to map sysirq register\n"); |
142 | ret = -ENOMEM; | 142 | ret = PTR_ERR(chip_data->intpol_base); |
143 | goto out_free; | 143 | goto out_free; |
144 | } | 144 | } |
145 | 145 | ||
diff --git a/drivers/irqchip/irq-omap-intc.c b/drivers/irqchip/irq-omap-intc.c index 28718d3e8281..c03f140acbae 100644 --- a/drivers/irqchip/irq-omap-intc.c +++ b/drivers/irqchip/irq-omap-intc.c | |||
@@ -263,7 +263,7 @@ static int __init omap_init_irq_of(struct device_node *node) | |||
263 | return ret; | 263 | return ret; |
264 | } | 264 | } |
265 | 265 | ||
266 | static int __init omap_init_irq_legacy(u32 base) | 266 | static int __init omap_init_irq_legacy(u32 base, struct device_node *node) |
267 | { | 267 | { |
268 | int j, irq_base; | 268 | int j, irq_base; |
269 | 269 | ||
@@ -277,7 +277,7 @@ static int __init omap_init_irq_legacy(u32 base) | |||
277 | irq_base = 0; | 277 | irq_base = 0; |
278 | } | 278 | } |
279 | 279 | ||
280 | domain = irq_domain_add_legacy(NULL, omap_nr_irqs, irq_base, 0, | 280 | domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0, |
281 | &irq_domain_simple_ops, NULL); | 281 | &irq_domain_simple_ops, NULL); |
282 | 282 | ||
283 | omap_irq_soft_reset(); | 283 | omap_irq_soft_reset(); |
@@ -301,10 +301,26 @@ static int __init omap_init_irq(u32 base, struct device_node *node) | |||
301 | { | 301 | { |
302 | int ret; | 302 | int ret; |
303 | 303 | ||
304 | if (node) | 304 | /* |
305 | * FIXME legacy OMAP DMA driver sitting under arch/arm/plat-omap/dma.c | ||
306 | * depends is still not ready for linear IRQ domains; because of that | ||
307 | * we need to temporarily "blacklist" OMAP2 and OMAP3 devices from using | ||
308 | * linear IRQ Domain until that driver is finally fixed. | ||
309 | */ | ||
310 | if (of_device_is_compatible(node, "ti,omap2-intc") || | ||
311 | of_device_is_compatible(node, "ti,omap3-intc")) { | ||
312 | struct resource res; | ||
313 | |||
314 | if (of_address_to_resource(node, 0, &res)) | ||
315 | return -ENOMEM; | ||
316 | |||
317 | base = res.start; | ||
318 | ret = omap_init_irq_legacy(base, node); | ||
319 | } else if (node) { | ||
305 | ret = omap_init_irq_of(node); | 320 | ret = omap_init_irq_of(node); |
306 | else | 321 | } else { |
307 | ret = omap_init_irq_legacy(base); | 322 | ret = omap_init_irq_legacy(base, NULL); |
323 | } | ||
308 | 324 | ||
309 | if (ret == 0) | 325 | if (ret == 0) |
310 | omap_irq_enable_protection(); | 326 | omap_irq_enable_protection(); |
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index a82e542ffc21..0b380603a578 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c | |||
@@ -4880,7 +4880,7 @@ static void sig_ind(PLCI *plci) | |||
4880 | byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ | 4880 | byte SS_Ind[] = "\x05\x02\x00\x02\x00\x00"; /* Hold_Ind struct*/ |
4881 | byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; | 4881 | byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00"; |
4882 | byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; | 4882 | byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; |
4883 | byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00"; | 4883 | byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\x00\x00\x00\x00"; |
4884 | byte force_mt_info = false; | 4884 | byte force_mt_info = false; |
4885 | byte dir; | 4885 | byte dir; |
4886 | dword d; | 4886 | dword d; |
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 26515c27ea8c..25e419752a7b 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c | |||
@@ -330,18 +330,18 @@ create_netxbig_led(struct platform_device *pdev, | |||
330 | led_dat->sata = 0; | 330 | led_dat->sata = 0; |
331 | led_dat->cdev.brightness = LED_OFF; | 331 | led_dat->cdev.brightness = LED_OFF; |
332 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 332 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
333 | /* | ||
334 | * If available, expose the SATA activity blink capability through | ||
335 | * a "sata" sysfs attribute. | ||
336 | */ | ||
337 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
338 | led_dat->cdev.groups = netxbig_led_groups; | ||
339 | led_dat->mode_addr = template->mode_addr; | 333 | led_dat->mode_addr = template->mode_addr; |
340 | led_dat->mode_val = template->mode_val; | 334 | led_dat->mode_val = template->mode_val; |
341 | led_dat->bright_addr = template->bright_addr; | 335 | led_dat->bright_addr = template->bright_addr; |
342 | led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; | 336 | led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; |
343 | led_dat->timer = pdata->timer; | 337 | led_dat->timer = pdata->timer; |
344 | led_dat->num_timer = pdata->num_timer; | 338 | led_dat->num_timer = pdata->num_timer; |
339 | /* | ||
340 | * If available, expose the SATA activity blink capability through | ||
341 | * a "sata" sysfs attribute. | ||
342 | */ | ||
343 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
344 | led_dat->cdev.groups = netxbig_led_groups; | ||
345 | 345 | ||
346 | return led_classdev_register(&pdev->dev, &led_dat->cdev); | 346 | return led_classdev_register(&pdev->dev, &led_dat->cdev); |
347 | } | 347 | } |
diff --git a/drivers/mcb/mcb-internal.h b/drivers/mcb/mcb-internal.h index f956ef26c0ce..fb7493dcfb79 100644 --- a/drivers/mcb/mcb-internal.h +++ b/drivers/mcb/mcb-internal.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45 | 7 | #define PCI_DEVICE_ID_MEN_CHAMELEON 0x4d45 |
8 | #define CHAMELEON_FILENAME_LEN 12 | 8 | #define CHAMELEON_FILENAME_LEN 12 |
9 | #define CHAMELEONV2_MAGIC 0xabce | 9 | #define CHAMELEONV2_MAGIC 0xabce |
10 | #define CHAM_HEADER_SIZE 0x200 | ||
10 | 11 | ||
11 | enum chameleon_descriptor_type { | 12 | enum chameleon_descriptor_type { |
12 | CHAMELEON_DTYPE_GENERAL = 0x0, | 13 | CHAMELEON_DTYPE_GENERAL = 0x0, |
diff --git a/drivers/mcb/mcb-pci.c b/drivers/mcb/mcb-pci.c index b59181965643..5e1bd5db02c8 100644 --- a/drivers/mcb/mcb-pci.c +++ b/drivers/mcb/mcb-pci.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | struct priv { | 18 | struct priv { |
19 | struct mcb_bus *bus; | 19 | struct mcb_bus *bus; |
20 | phys_addr_t mapbase; | ||
20 | void __iomem *base; | 21 | void __iomem *base; |
21 | }; | 22 | }; |
22 | 23 | ||
@@ -31,8 +32,8 @@ static int mcb_pci_get_irq(struct mcb_device *mdev) | |||
31 | 32 | ||
32 | static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 33 | static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
33 | { | 34 | { |
35 | struct resource *res; | ||
34 | struct priv *priv; | 36 | struct priv *priv; |
35 | phys_addr_t mapbase; | ||
36 | int ret; | 37 | int ret; |
37 | int num_cells; | 38 | int num_cells; |
38 | unsigned long flags; | 39 | unsigned long flags; |
@@ -47,19 +48,21 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
47 | return -ENODEV; | 48 | return -ENODEV; |
48 | } | 49 | } |
49 | 50 | ||
50 | mapbase = pci_resource_start(pdev, 0); | 51 | priv->mapbase = pci_resource_start(pdev, 0); |
51 | if (!mapbase) { | 52 | if (!priv->mapbase) { |
52 | dev_err(&pdev->dev, "No PCI resource\n"); | 53 | dev_err(&pdev->dev, "No PCI resource\n"); |
53 | goto err_start; | 54 | goto err_start; |
54 | } | 55 | } |
55 | 56 | ||
56 | ret = pci_request_region(pdev, 0, KBUILD_MODNAME); | 57 | res = request_mem_region(priv->mapbase, CHAM_HEADER_SIZE, |
57 | if (ret) { | 58 | KBUILD_MODNAME); |
58 | dev_err(&pdev->dev, "Failed to request PCI BARs\n"); | 59 | if (IS_ERR(res)) { |
60 | dev_err(&pdev->dev, "Failed to request PCI memory\n"); | ||
61 | ret = PTR_ERR(res); | ||
59 | goto err_start; | 62 | goto err_start; |
60 | } | 63 | } |
61 | 64 | ||
62 | priv->base = pci_iomap(pdev, 0, 0); | 65 | priv->base = ioremap(priv->mapbase, CHAM_HEADER_SIZE); |
63 | if (!priv->base) { | 66 | if (!priv->base) { |
64 | dev_err(&pdev->dev, "Cannot ioremap\n"); | 67 | dev_err(&pdev->dev, "Cannot ioremap\n"); |
65 | ret = -ENOMEM; | 68 | ret = -ENOMEM; |
@@ -84,7 +87,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
84 | 87 | ||
85 | priv->bus->get_irq = mcb_pci_get_irq; | 88 | priv->bus->get_irq = mcb_pci_get_irq; |
86 | 89 | ||
87 | ret = chameleon_parse_cells(priv->bus, mapbase, priv->base); | 90 | ret = chameleon_parse_cells(priv->bus, priv->mapbase, priv->base); |
88 | if (ret < 0) | 91 | if (ret < 0) |
89 | goto err_drvdata; | 92 | goto err_drvdata; |
90 | num_cells = ret; | 93 | num_cells = ret; |
@@ -93,8 +96,10 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
93 | 96 | ||
94 | mcb_bus_add_devices(priv->bus); | 97 | mcb_bus_add_devices(priv->bus); |
95 | 98 | ||
99 | return 0; | ||
100 | |||
96 | err_drvdata: | 101 | err_drvdata: |
97 | pci_iounmap(pdev, priv->base); | 102 | iounmap(priv->base); |
98 | err_ioremap: | 103 | err_ioremap: |
99 | pci_release_region(pdev, 0); | 104 | pci_release_region(pdev, 0); |
100 | err_start: | 105 | err_start: |
@@ -107,6 +112,10 @@ static void mcb_pci_remove(struct pci_dev *pdev) | |||
107 | struct priv *priv = pci_get_drvdata(pdev); | 112 | struct priv *priv = pci_get_drvdata(pdev); |
108 | 113 | ||
109 | mcb_release_bus(priv->bus); | 114 | mcb_release_bus(priv->bus); |
115 | |||
116 | iounmap(priv->base); | ||
117 | release_region(priv->mapbase, CHAM_HEADER_SIZE); | ||
118 | pci_disable_device(pdev); | ||
110 | } | 119 | } |
111 | 120 | ||
112 | static const struct pci_device_id mcb_pci_tbl[] = { | 121 | static const struct pci_device_id mcb_pci_tbl[] = { |
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 9fc616c2755e..c1c010498a21 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c | |||
@@ -94,6 +94,9 @@ struct cache_disk_superblock { | |||
94 | } __packed; | 94 | } __packed; |
95 | 95 | ||
96 | struct dm_cache_metadata { | 96 | struct dm_cache_metadata { |
97 | atomic_t ref_count; | ||
98 | struct list_head list; | ||
99 | |||
97 | struct block_device *bdev; | 100 | struct block_device *bdev; |
98 | struct dm_block_manager *bm; | 101 | struct dm_block_manager *bm; |
99 | struct dm_space_map *metadata_sm; | 102 | struct dm_space_map *metadata_sm; |
@@ -669,10 +672,10 @@ static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned *flags) | |||
669 | 672 | ||
670 | /*----------------------------------------------------------------*/ | 673 | /*----------------------------------------------------------------*/ |
671 | 674 | ||
672 | struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, | 675 | static struct dm_cache_metadata *metadata_open(struct block_device *bdev, |
673 | sector_t data_block_size, | 676 | sector_t data_block_size, |
674 | bool may_format_device, | 677 | bool may_format_device, |
675 | size_t policy_hint_size) | 678 | size_t policy_hint_size) |
676 | { | 679 | { |
677 | int r; | 680 | int r; |
678 | struct dm_cache_metadata *cmd; | 681 | struct dm_cache_metadata *cmd; |
@@ -680,9 +683,10 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, | |||
680 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | 683 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); |
681 | if (!cmd) { | 684 | if (!cmd) { |
682 | DMERR("could not allocate metadata struct"); | 685 | DMERR("could not allocate metadata struct"); |
683 | return NULL; | 686 | return ERR_PTR(-ENOMEM); |
684 | } | 687 | } |
685 | 688 | ||
689 | atomic_set(&cmd->ref_count, 1); | ||
686 | init_rwsem(&cmd->root_lock); | 690 | init_rwsem(&cmd->root_lock); |
687 | cmd->bdev = bdev; | 691 | cmd->bdev = bdev; |
688 | cmd->data_block_size = data_block_size; | 692 | cmd->data_block_size = data_block_size; |
@@ -705,10 +709,96 @@ struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, | |||
705 | return cmd; | 709 | return cmd; |
706 | } | 710 | } |
707 | 711 | ||
712 | /* | ||
713 | * We keep a little list of ref counted metadata objects to prevent two | ||
714 | * different target instances creating separate bufio instances. This is | ||
715 | * an issue if a table is reloaded before the suspend. | ||
716 | */ | ||
717 | static DEFINE_MUTEX(table_lock); | ||
718 | static LIST_HEAD(table); | ||
719 | |||
720 | static struct dm_cache_metadata *lookup(struct block_device *bdev) | ||
721 | { | ||
722 | struct dm_cache_metadata *cmd; | ||
723 | |||
724 | list_for_each_entry(cmd, &table, list) | ||
725 | if (cmd->bdev == bdev) { | ||
726 | atomic_inc(&cmd->ref_count); | ||
727 | return cmd; | ||
728 | } | ||
729 | |||
730 | return NULL; | ||
731 | } | ||
732 | |||
733 | static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, | ||
734 | sector_t data_block_size, | ||
735 | bool may_format_device, | ||
736 | size_t policy_hint_size) | ||
737 | { | ||
738 | struct dm_cache_metadata *cmd, *cmd2; | ||
739 | |||
740 | mutex_lock(&table_lock); | ||
741 | cmd = lookup(bdev); | ||
742 | mutex_unlock(&table_lock); | ||
743 | |||
744 | if (cmd) | ||
745 | return cmd; | ||
746 | |||
747 | cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); | ||
748 | if (!IS_ERR(cmd)) { | ||
749 | mutex_lock(&table_lock); | ||
750 | cmd2 = lookup(bdev); | ||
751 | if (cmd2) { | ||
752 | mutex_unlock(&table_lock); | ||
753 | __destroy_persistent_data_objects(cmd); | ||
754 | kfree(cmd); | ||
755 | return cmd2; | ||
756 | } | ||
757 | list_add(&cmd->list, &table); | ||
758 | mutex_unlock(&table_lock); | ||
759 | } | ||
760 | |||
761 | return cmd; | ||
762 | } | ||
763 | |||
764 | static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size) | ||
765 | { | ||
766 | if (cmd->data_block_size != data_block_size) { | ||
767 | DMERR("data_block_size (%llu) different from that in metadata (%llu)\n", | ||
768 | (unsigned long long) data_block_size, | ||
769 | (unsigned long long) cmd->data_block_size); | ||
770 | return false; | ||
771 | } | ||
772 | |||
773 | return true; | ||
774 | } | ||
775 | |||
776 | struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, | ||
777 | sector_t data_block_size, | ||
778 | bool may_format_device, | ||
779 | size_t policy_hint_size) | ||
780 | { | ||
781 | struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, | ||
782 | may_format_device, policy_hint_size); | ||
783 | |||
784 | if (!IS_ERR(cmd) && !same_params(cmd, data_block_size)) { | ||
785 | dm_cache_metadata_close(cmd); | ||
786 | return ERR_PTR(-EINVAL); | ||
787 | } | ||
788 | |||
789 | return cmd; | ||
790 | } | ||
791 | |||
708 | void dm_cache_metadata_close(struct dm_cache_metadata *cmd) | 792 | void dm_cache_metadata_close(struct dm_cache_metadata *cmd) |
709 | { | 793 | { |
710 | __destroy_persistent_data_objects(cmd); | 794 | if (atomic_dec_and_test(&cmd->ref_count)) { |
711 | kfree(cmd); | 795 | mutex_lock(&table_lock); |
796 | list_del(&cmd->list); | ||
797 | mutex_unlock(&table_lock); | ||
798 | |||
799 | __destroy_persistent_data_objects(cmd); | ||
800 | kfree(cmd); | ||
801 | } | ||
712 | } | 802 | } |
713 | 803 | ||
714 | /* | 804 | /* |
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1e96d7889f51..e1650539cc2f 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c | |||
@@ -221,7 +221,13 @@ struct cache { | |||
221 | struct list_head need_commit_migrations; | 221 | struct list_head need_commit_migrations; |
222 | sector_t migration_threshold; | 222 | sector_t migration_threshold; |
223 | wait_queue_head_t migration_wait; | 223 | wait_queue_head_t migration_wait; |
224 | atomic_t nr_migrations; | 224 | atomic_t nr_allocated_migrations; |
225 | |||
226 | /* | ||
227 | * The number of in flight migrations that are performing | ||
228 | * background io. eg, promotion, writeback. | ||
229 | */ | ||
230 | atomic_t nr_io_migrations; | ||
225 | 231 | ||
226 | wait_queue_head_t quiescing_wait; | 232 | wait_queue_head_t quiescing_wait; |
227 | atomic_t quiescing; | 233 | atomic_t quiescing; |
@@ -258,7 +264,6 @@ struct cache { | |||
258 | struct dm_deferred_set *all_io_ds; | 264 | struct dm_deferred_set *all_io_ds; |
259 | 265 | ||
260 | mempool_t *migration_pool; | 266 | mempool_t *migration_pool; |
261 | struct dm_cache_migration *next_migration; | ||
262 | 267 | ||
263 | struct dm_cache_policy *policy; | 268 | struct dm_cache_policy *policy; |
264 | unsigned policy_nr_args; | 269 | unsigned policy_nr_args; |
@@ -350,10 +355,31 @@ static void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell *cel | |||
350 | dm_bio_prison_free_cell(cache->prison, cell); | 355 | dm_bio_prison_free_cell(cache->prison, cell); |
351 | } | 356 | } |
352 | 357 | ||
358 | static struct dm_cache_migration *alloc_migration(struct cache *cache) | ||
359 | { | ||
360 | struct dm_cache_migration *mg; | ||
361 | |||
362 | mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); | ||
363 | if (mg) { | ||
364 | mg->cache = cache; | ||
365 | atomic_inc(&mg->cache->nr_allocated_migrations); | ||
366 | } | ||
367 | |||
368 | return mg; | ||
369 | } | ||
370 | |||
371 | static void free_migration(struct dm_cache_migration *mg) | ||
372 | { | ||
373 | if (atomic_dec_and_test(&mg->cache->nr_allocated_migrations)) | ||
374 | wake_up(&mg->cache->migration_wait); | ||
375 | |||
376 | mempool_free(mg, mg->cache->migration_pool); | ||
377 | } | ||
378 | |||
353 | static int prealloc_data_structs(struct cache *cache, struct prealloc *p) | 379 | static int prealloc_data_structs(struct cache *cache, struct prealloc *p) |
354 | { | 380 | { |
355 | if (!p->mg) { | 381 | if (!p->mg) { |
356 | p->mg = mempool_alloc(cache->migration_pool, GFP_NOWAIT); | 382 | p->mg = alloc_migration(cache); |
357 | if (!p->mg) | 383 | if (!p->mg) |
358 | return -ENOMEM; | 384 | return -ENOMEM; |
359 | } | 385 | } |
@@ -382,7 +408,7 @@ static void prealloc_free_structs(struct cache *cache, struct prealloc *p) | |||
382 | free_prison_cell(cache, p->cell1); | 408 | free_prison_cell(cache, p->cell1); |
383 | 409 | ||
384 | if (p->mg) | 410 | if (p->mg) |
385 | mempool_free(p->mg, cache->migration_pool); | 411 | free_migration(p->mg); |
386 | } | 412 | } |
387 | 413 | ||
388 | static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p) | 414 | static struct dm_cache_migration *prealloc_get_migration(struct prealloc *p) |
@@ -854,24 +880,14 @@ static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, | |||
854 | * Migration covers moving data from the origin device to the cache, or | 880 | * Migration covers moving data from the origin device to the cache, or |
855 | * vice versa. | 881 | * vice versa. |
856 | *--------------------------------------------------------------*/ | 882 | *--------------------------------------------------------------*/ |
857 | static void free_migration(struct dm_cache_migration *mg) | 883 | static void inc_io_migrations(struct cache *cache) |
858 | { | ||
859 | mempool_free(mg, mg->cache->migration_pool); | ||
860 | } | ||
861 | |||
862 | static void inc_nr_migrations(struct cache *cache) | ||
863 | { | 884 | { |
864 | atomic_inc(&cache->nr_migrations); | 885 | atomic_inc(&cache->nr_io_migrations); |
865 | } | 886 | } |
866 | 887 | ||
867 | static void dec_nr_migrations(struct cache *cache) | 888 | static void dec_io_migrations(struct cache *cache) |
868 | { | 889 | { |
869 | atomic_dec(&cache->nr_migrations); | 890 | atomic_dec(&cache->nr_io_migrations); |
870 | |||
871 | /* | ||
872 | * Wake the worker in case we're suspending the target. | ||
873 | */ | ||
874 | wake_up(&cache->migration_wait); | ||
875 | } | 891 | } |
876 | 892 | ||
877 | static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, | 893 | static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, |
@@ -894,11 +910,10 @@ static void cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell, | |||
894 | wake_worker(cache); | 910 | wake_worker(cache); |
895 | } | 911 | } |
896 | 912 | ||
897 | static void cleanup_migration(struct dm_cache_migration *mg) | 913 | static void free_io_migration(struct dm_cache_migration *mg) |
898 | { | 914 | { |
899 | struct cache *cache = mg->cache; | 915 | dec_io_migrations(mg->cache); |
900 | free_migration(mg); | 916 | free_migration(mg); |
901 | dec_nr_migrations(cache); | ||
902 | } | 917 | } |
903 | 918 | ||
904 | static void migration_failure(struct dm_cache_migration *mg) | 919 | static void migration_failure(struct dm_cache_migration *mg) |
@@ -923,7 +938,7 @@ static void migration_failure(struct dm_cache_migration *mg) | |||
923 | cell_defer(cache, mg->new_ocell, true); | 938 | cell_defer(cache, mg->new_ocell, true); |
924 | } | 939 | } |
925 | 940 | ||
926 | cleanup_migration(mg); | 941 | free_io_migration(mg); |
927 | } | 942 | } |
928 | 943 | ||
929 | static void migration_success_pre_commit(struct dm_cache_migration *mg) | 944 | static void migration_success_pre_commit(struct dm_cache_migration *mg) |
@@ -934,7 +949,7 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) | |||
934 | if (mg->writeback) { | 949 | if (mg->writeback) { |
935 | clear_dirty(cache, mg->old_oblock, mg->cblock); | 950 | clear_dirty(cache, mg->old_oblock, mg->cblock); |
936 | cell_defer(cache, mg->old_ocell, false); | 951 | cell_defer(cache, mg->old_ocell, false); |
937 | cleanup_migration(mg); | 952 | free_io_migration(mg); |
938 | return; | 953 | return; |
939 | 954 | ||
940 | } else if (mg->demote) { | 955 | } else if (mg->demote) { |
@@ -944,14 +959,14 @@ static void migration_success_pre_commit(struct dm_cache_migration *mg) | |||
944 | mg->old_oblock); | 959 | mg->old_oblock); |
945 | if (mg->promote) | 960 | if (mg->promote) |
946 | cell_defer(cache, mg->new_ocell, true); | 961 | cell_defer(cache, mg->new_ocell, true); |
947 | cleanup_migration(mg); | 962 | free_io_migration(mg); |
948 | return; | 963 | return; |
949 | } | 964 | } |
950 | } else { | 965 | } else { |
951 | if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { | 966 | if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { |
952 | DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); | 967 | DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); |
953 | policy_remove_mapping(cache->policy, mg->new_oblock); | 968 | policy_remove_mapping(cache->policy, mg->new_oblock); |
954 | cleanup_migration(mg); | 969 | free_io_migration(mg); |
955 | return; | 970 | return; |
956 | } | 971 | } |
957 | } | 972 | } |
@@ -984,7 +999,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) | |||
984 | } else { | 999 | } else { |
985 | if (mg->invalidate) | 1000 | if (mg->invalidate) |
986 | policy_remove_mapping(cache->policy, mg->old_oblock); | 1001 | policy_remove_mapping(cache->policy, mg->old_oblock); |
987 | cleanup_migration(mg); | 1002 | free_io_migration(mg); |
988 | } | 1003 | } |
989 | 1004 | ||
990 | } else { | 1005 | } else { |
@@ -999,7 +1014,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg) | |||
999 | bio_endio(mg->new_ocell->holder, 0); | 1014 | bio_endio(mg->new_ocell->holder, 0); |
1000 | cell_defer(cache, mg->new_ocell, false); | 1015 | cell_defer(cache, mg->new_ocell, false); |
1001 | } | 1016 | } |
1002 | cleanup_migration(mg); | 1017 | free_io_migration(mg); |
1003 | } | 1018 | } |
1004 | } | 1019 | } |
1005 | 1020 | ||
@@ -1251,7 +1266,7 @@ static void promote(struct cache *cache, struct prealloc *structs, | |||
1251 | mg->new_ocell = cell; | 1266 | mg->new_ocell = cell; |
1252 | mg->start_jiffies = jiffies; | 1267 | mg->start_jiffies = jiffies; |
1253 | 1268 | ||
1254 | inc_nr_migrations(cache); | 1269 | inc_io_migrations(cache); |
1255 | quiesce_migration(mg); | 1270 | quiesce_migration(mg); |
1256 | } | 1271 | } |
1257 | 1272 | ||
@@ -1275,7 +1290,7 @@ static void writeback(struct cache *cache, struct prealloc *structs, | |||
1275 | mg->new_ocell = NULL; | 1290 | mg->new_ocell = NULL; |
1276 | mg->start_jiffies = jiffies; | 1291 | mg->start_jiffies = jiffies; |
1277 | 1292 | ||
1278 | inc_nr_migrations(cache); | 1293 | inc_io_migrations(cache); |
1279 | quiesce_migration(mg); | 1294 | quiesce_migration(mg); |
1280 | } | 1295 | } |
1281 | 1296 | ||
@@ -1302,7 +1317,7 @@ static void demote_then_promote(struct cache *cache, struct prealloc *structs, | |||
1302 | mg->new_ocell = new_ocell; | 1317 | mg->new_ocell = new_ocell; |
1303 | mg->start_jiffies = jiffies; | 1318 | mg->start_jiffies = jiffies; |
1304 | 1319 | ||
1305 | inc_nr_migrations(cache); | 1320 | inc_io_migrations(cache); |
1306 | quiesce_migration(mg); | 1321 | quiesce_migration(mg); |
1307 | } | 1322 | } |
1308 | 1323 | ||
@@ -1330,7 +1345,7 @@ static void invalidate(struct cache *cache, struct prealloc *structs, | |||
1330 | mg->new_ocell = NULL; | 1345 | mg->new_ocell = NULL; |
1331 | mg->start_jiffies = jiffies; | 1346 | mg->start_jiffies = jiffies; |
1332 | 1347 | ||
1333 | inc_nr_migrations(cache); | 1348 | inc_io_migrations(cache); |
1334 | quiesce_migration(mg); | 1349 | quiesce_migration(mg); |
1335 | } | 1350 | } |
1336 | 1351 | ||
@@ -1412,7 +1427,7 @@ static void process_discard_bio(struct cache *cache, struct prealloc *structs, | |||
1412 | 1427 | ||
1413 | static bool spare_migration_bandwidth(struct cache *cache) | 1428 | static bool spare_migration_bandwidth(struct cache *cache) |
1414 | { | 1429 | { |
1415 | sector_t current_volume = (atomic_read(&cache->nr_migrations) + 1) * | 1430 | sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) * |
1416 | cache->sectors_per_block; | 1431 | cache->sectors_per_block; |
1417 | return current_volume < cache->migration_threshold; | 1432 | return current_volume < cache->migration_threshold; |
1418 | } | 1433 | } |
@@ -1764,7 +1779,7 @@ static void stop_quiescing(struct cache *cache) | |||
1764 | 1779 | ||
1765 | static void wait_for_migrations(struct cache *cache) | 1780 | static void wait_for_migrations(struct cache *cache) |
1766 | { | 1781 | { |
1767 | wait_event(cache->migration_wait, !atomic_read(&cache->nr_migrations)); | 1782 | wait_event(cache->migration_wait, !atomic_read(&cache->nr_allocated_migrations)); |
1768 | } | 1783 | } |
1769 | 1784 | ||
1770 | static void stop_worker(struct cache *cache) | 1785 | static void stop_worker(struct cache *cache) |
@@ -1876,9 +1891,6 @@ static void destroy(struct cache *cache) | |||
1876 | { | 1891 | { |
1877 | unsigned i; | 1892 | unsigned i; |
1878 | 1893 | ||
1879 | if (cache->next_migration) | ||
1880 | mempool_free(cache->next_migration, cache->migration_pool); | ||
1881 | |||
1882 | if (cache->migration_pool) | 1894 | if (cache->migration_pool) |
1883 | mempool_destroy(cache->migration_pool); | 1895 | mempool_destroy(cache->migration_pool); |
1884 | 1896 | ||
@@ -2424,7 +2436,8 @@ static int cache_create(struct cache_args *ca, struct cache **result) | |||
2424 | INIT_LIST_HEAD(&cache->quiesced_migrations); | 2436 | INIT_LIST_HEAD(&cache->quiesced_migrations); |
2425 | INIT_LIST_HEAD(&cache->completed_migrations); | 2437 | INIT_LIST_HEAD(&cache->completed_migrations); |
2426 | INIT_LIST_HEAD(&cache->need_commit_migrations); | 2438 | INIT_LIST_HEAD(&cache->need_commit_migrations); |
2427 | atomic_set(&cache->nr_migrations, 0); | 2439 | atomic_set(&cache->nr_allocated_migrations, 0); |
2440 | atomic_set(&cache->nr_io_migrations, 0); | ||
2428 | init_waitqueue_head(&cache->migration_wait); | 2441 | init_waitqueue_head(&cache->migration_wait); |
2429 | 2442 | ||
2430 | init_waitqueue_head(&cache->quiescing_wait); | 2443 | init_waitqueue_head(&cache->quiescing_wait); |
@@ -2487,8 +2500,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) | |||
2487 | goto bad; | 2500 | goto bad; |
2488 | } | 2501 | } |
2489 | 2502 | ||
2490 | cache->next_migration = NULL; | ||
2491 | |||
2492 | cache->need_tick_bio = true; | 2503 | cache->need_tick_bio = true; |
2493 | cache->sized = false; | 2504 | cache->sized = false; |
2494 | cache->invalidate = false; | 2505 | cache->invalidate = false; |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 8735543eacdb..07705ee181e3 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1127,6 +1127,24 @@ static void schedule_external_copy(struct thin_c *tc, dm_block_t virt_block, | |||
1127 | schedule_zero(tc, virt_block, data_dest, cell, bio); | 1127 | schedule_zero(tc, virt_block, data_dest, cell, bio); |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); | ||
1131 | |||
1132 | static void check_for_space(struct pool *pool) | ||
1133 | { | ||
1134 | int r; | ||
1135 | dm_block_t nr_free; | ||
1136 | |||
1137 | if (get_pool_mode(pool) != PM_OUT_OF_DATA_SPACE) | ||
1138 | return; | ||
1139 | |||
1140 | r = dm_pool_get_free_block_count(pool->pmd, &nr_free); | ||
1141 | if (r) | ||
1142 | return; | ||
1143 | |||
1144 | if (nr_free) | ||
1145 | set_pool_mode(pool, PM_WRITE); | ||
1146 | } | ||
1147 | |||
1130 | /* | 1148 | /* |
1131 | * A non-zero return indicates read_only or fail_io mode. | 1149 | * A non-zero return indicates read_only or fail_io mode. |
1132 | * Many callers don't care about the return value. | 1150 | * Many callers don't care about the return value. |
@@ -1141,6 +1159,8 @@ static int commit(struct pool *pool) | |||
1141 | r = dm_pool_commit_metadata(pool->pmd); | 1159 | r = dm_pool_commit_metadata(pool->pmd); |
1142 | if (r) | 1160 | if (r) |
1143 | metadata_operation_failed(pool, "dm_pool_commit_metadata", r); | 1161 | metadata_operation_failed(pool, "dm_pool_commit_metadata", r); |
1162 | else | ||
1163 | check_for_space(pool); | ||
1144 | 1164 | ||
1145 | return r; | 1165 | return r; |
1146 | } | 1166 | } |
@@ -1159,8 +1179,6 @@ static void check_low_water_mark(struct pool *pool, dm_block_t free_blocks) | |||
1159 | } | 1179 | } |
1160 | } | 1180 | } |
1161 | 1181 | ||
1162 | static void set_pool_mode(struct pool *pool, enum pool_mode new_mode); | ||
1163 | |||
1164 | static int alloc_data_block(struct thin_c *tc, dm_block_t *result) | 1182 | static int alloc_data_block(struct thin_c *tc, dm_block_t *result) |
1165 | { | 1183 | { |
1166 | int r; | 1184 | int r; |
@@ -2155,7 +2173,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode new_mode) | |||
2155 | pool->process_cell = process_cell_read_only; | 2173 | pool->process_cell = process_cell_read_only; |
2156 | pool->process_discard_cell = process_discard_cell; | 2174 | pool->process_discard_cell = process_discard_cell; |
2157 | pool->process_prepared_mapping = process_prepared_mapping; | 2175 | pool->process_prepared_mapping = process_prepared_mapping; |
2158 | pool->process_prepared_discard = process_prepared_discard_passdown; | 2176 | pool->process_prepared_discard = process_prepared_discard; |
2159 | 2177 | ||
2160 | if (!pool->pf.error_if_no_space && no_space_timeout) | 2178 | if (!pool->pf.error_if_no_space && no_space_timeout) |
2161 | queue_delayed_work(pool->wq, &pool->no_space_timeout, no_space_timeout); | 2179 | queue_delayed_work(pool->wq, &pool->no_space_timeout, no_space_timeout); |
@@ -3367,6 +3385,12 @@ static int pool_message(struct dm_target *ti, unsigned argc, char **argv) | |||
3367 | struct pool_c *pt = ti->private; | 3385 | struct pool_c *pt = ti->private; |
3368 | struct pool *pool = pt->pool; | 3386 | struct pool *pool = pt->pool; |
3369 | 3387 | ||
3388 | if (get_pool_mode(pool) >= PM_READ_ONLY) { | ||
3389 | DMERR("%s: unable to service pool target messages in READ_ONLY or FAIL mode", | ||
3390 | dm_device_name(pool->pool_md)); | ||
3391 | return -EINVAL; | ||
3392 | } | ||
3393 | |||
3370 | if (!strcasecmp(argv[0], "create_thin")) | 3394 | if (!strcasecmp(argv[0], "create_thin")) |
3371 | r = process_create_thin_mesg(argc, argv, pool); | 3395 | r = process_create_thin_mesg(argc, argv, pool); |
3372 | 3396 | ||
@@ -3814,6 +3838,8 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
3814 | r = -EINVAL; | 3838 | r = -EINVAL; |
3815 | goto bad; | 3839 | goto bad; |
3816 | } | 3840 | } |
3841 | atomic_set(&tc->refcount, 1); | ||
3842 | init_completion(&tc->can_destroy); | ||
3817 | list_add_tail_rcu(&tc->list, &tc->pool->active_thins); | 3843 | list_add_tail_rcu(&tc->list, &tc->pool->active_thins); |
3818 | spin_unlock_irqrestore(&tc->pool->lock, flags); | 3844 | spin_unlock_irqrestore(&tc->pool->lock, flags); |
3819 | /* | 3845 | /* |
@@ -3826,9 +3852,6 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
3826 | 3852 | ||
3827 | dm_put(pool_md); | 3853 | dm_put(pool_md); |
3828 | 3854 | ||
3829 | atomic_set(&tc->refcount, 1); | ||
3830 | init_completion(&tc->can_destroy); | ||
3831 | |||
3832 | return 0; | 3855 | return 0; |
3833 | 3856 | ||
3834 | bad: | 3857 | bad: |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 4c06585bf165..2caf5b374649 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -206,6 +206,9 @@ struct mapped_device { | |||
206 | /* zero-length flush that will be cloned and submitted to targets */ | 206 | /* zero-length flush that will be cloned and submitted to targets */ |
207 | struct bio flush_bio; | 207 | struct bio flush_bio; |
208 | 208 | ||
209 | /* the number of internal suspends */ | ||
210 | unsigned internal_suspend_count; | ||
211 | |||
209 | struct dm_stats stats; | 212 | struct dm_stats stats; |
210 | }; | 213 | }; |
211 | 214 | ||
@@ -899,7 +902,7 @@ static void disable_write_same(struct mapped_device *md) | |||
899 | 902 | ||
900 | static void clone_endio(struct bio *bio, int error) | 903 | static void clone_endio(struct bio *bio, int error) |
901 | { | 904 | { |
902 | int r = 0; | 905 | int r = error; |
903 | struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone); | 906 | struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone); |
904 | struct dm_io *io = tio->io; | 907 | struct dm_io *io = tio->io; |
905 | struct mapped_device *md = tio->io->md; | 908 | struct mapped_device *md = tio->io->md; |
@@ -2928,7 +2931,7 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla | |||
2928 | { | 2931 | { |
2929 | struct dm_table *map = NULL; | 2932 | struct dm_table *map = NULL; |
2930 | 2933 | ||
2931 | if (dm_suspended_internally_md(md)) | 2934 | if (md->internal_suspend_count++) |
2932 | return; /* nested internal suspend */ | 2935 | return; /* nested internal suspend */ |
2933 | 2936 | ||
2934 | if (dm_suspended_md(md)) { | 2937 | if (dm_suspended_md(md)) { |
@@ -2953,7 +2956,9 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla | |||
2953 | 2956 | ||
2954 | static void __dm_internal_resume(struct mapped_device *md) | 2957 | static void __dm_internal_resume(struct mapped_device *md) |
2955 | { | 2958 | { |
2956 | if (!dm_suspended_internally_md(md)) | 2959 | BUG_ON(!md->internal_suspend_count); |
2960 | |||
2961 | if (--md->internal_suspend_count) | ||
2957 | return; /* resume from nested internal suspend */ | 2962 | return; /* resume from nested internal suspend */ |
2958 | 2963 | ||
2959 | if (dm_suspended_md(md)) | 2964 | if (dm_suspended_md(md)) |
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index db99ca2613ba..06931f6fa26c 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c | |||
@@ -614,7 +614,7 @@ struct cx23885_board cx23885_boards[] = { | |||
614 | .portb = CX23885_MPEG_DVB, | 614 | .portb = CX23885_MPEG_DVB, |
615 | }, | 615 | }, |
616 | [CX23885_BOARD_HAUPPAUGE_HVR4400] = { | 616 | [CX23885_BOARD_HAUPPAUGE_HVR4400] = { |
617 | .name = "Hauppauge WinTV-HVR4400", | 617 | .name = "Hauppauge WinTV-HVR4400/HVR5500", |
618 | .porta = CX23885_ANALOG_VIDEO, | 618 | .porta = CX23885_ANALOG_VIDEO, |
619 | .portb = CX23885_MPEG_DVB, | 619 | .portb = CX23885_MPEG_DVB, |
620 | .portc = CX23885_MPEG_DVB, | 620 | .portc = CX23885_MPEG_DVB, |
@@ -622,6 +622,10 @@ struct cx23885_board cx23885_boards[] = { | |||
622 | .tuner_addr = 0x60, /* 0xc0 >> 1 */ | 622 | .tuner_addr = 0x60, /* 0xc0 >> 1 */ |
623 | .tuner_bus = 1, | 623 | .tuner_bus = 1, |
624 | }, | 624 | }, |
625 | [CX23885_BOARD_HAUPPAUGE_STARBURST] = { | ||
626 | .name = "Hauppauge WinTV Starburst", | ||
627 | .portb = CX23885_MPEG_DVB, | ||
628 | }, | ||
625 | [CX23885_BOARD_AVERMEDIA_HC81R] = { | 629 | [CX23885_BOARD_AVERMEDIA_HC81R] = { |
626 | .name = "AVerTV Hybrid Express Slim HC81R", | 630 | .name = "AVerTV Hybrid Express Slim HC81R", |
627 | .tuner_type = TUNER_XC2028, | 631 | .tuner_type = TUNER_XC2028, |
@@ -936,19 +940,19 @@ struct cx23885_subid cx23885_subids[] = { | |||
936 | }, { | 940 | }, { |
937 | .subvendor = 0x0070, | 941 | .subvendor = 0x0070, |
938 | .subdevice = 0xc108, | 942 | .subdevice = 0xc108, |
939 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, | 943 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-4400 (Model 121xxx, Hybrid DVB-T/S2, IR) */ |
940 | }, { | 944 | }, { |
941 | .subvendor = 0x0070, | 945 | .subvendor = 0x0070, |
942 | .subdevice = 0xc138, | 946 | .subdevice = 0xc138, |
943 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, | 947 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ |
944 | }, { | 948 | }, { |
945 | .subvendor = 0x0070, | 949 | .subvendor = 0x0070, |
946 | .subdevice = 0xc12a, | 950 | .subdevice = 0xc12a, |
947 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, | 951 | .card = CX23885_BOARD_HAUPPAUGE_STARBURST, /* Hauppauge WinTV Starburst (Model 121x00, DVB-S2, IR) */ |
948 | }, { | 952 | }, { |
949 | .subvendor = 0x0070, | 953 | .subvendor = 0x0070, |
950 | .subdevice = 0xc1f8, | 954 | .subdevice = 0xc1f8, |
951 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, | 955 | .card = CX23885_BOARD_HAUPPAUGE_HVR4400, /* Hauppauge WinTV HVR-5500 (Model 121xxx, Hybrid DVB-T/C/S2, IR) */ |
952 | }, { | 956 | }, { |
953 | .subvendor = 0x1461, | 957 | .subvendor = 0x1461, |
954 | .subdevice = 0xd939, | 958 | .subdevice = 0xd939, |
@@ -1545,8 +1549,9 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) | |||
1545 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ | 1549 | cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ |
1546 | break; | 1550 | break; |
1547 | case CX23885_BOARD_HAUPPAUGE_HVR4400: | 1551 | case CX23885_BOARD_HAUPPAUGE_HVR4400: |
1552 | case CX23885_BOARD_HAUPPAUGE_STARBURST: | ||
1548 | /* GPIO-8 tda10071 demod reset */ | 1553 | /* GPIO-8 tda10071 demod reset */ |
1549 | /* GPIO-9 si2165 demod reset */ | 1554 | /* GPIO-9 si2165 demod reset (only HVR4400/HVR5500)*/ |
1550 | 1555 | ||
1551 | /* Put the parts into reset and back */ | 1556 | /* Put the parts into reset and back */ |
1552 | cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); | 1557 | cx23885_gpio_enable(dev, GPIO_8 | GPIO_9, 1); |
@@ -1872,6 +1877,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1872 | case CX23885_BOARD_HAUPPAUGE_HVR1850: | 1877 | case CX23885_BOARD_HAUPPAUGE_HVR1850: |
1873 | case CX23885_BOARD_HAUPPAUGE_HVR1290: | 1878 | case CX23885_BOARD_HAUPPAUGE_HVR1290: |
1874 | case CX23885_BOARD_HAUPPAUGE_HVR4400: | 1879 | case CX23885_BOARD_HAUPPAUGE_HVR4400: |
1880 | case CX23885_BOARD_HAUPPAUGE_STARBURST: | ||
1875 | case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: | 1881 | case CX23885_BOARD_HAUPPAUGE_IMPACTVCBE: |
1876 | if (dev->i2c_bus[0].i2c_rc == 0) | 1882 | if (dev->i2c_bus[0].i2c_rc == 0) |
1877 | hauppauge_eeprom(dev, eeprom+0xc0); | 1883 | hauppauge_eeprom(dev, eeprom+0xc0); |
@@ -1980,6 +1986,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) | |||
1980 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | 1986 | ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ |
1981 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | 1987 | ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; |
1982 | break; | 1988 | break; |
1989 | case CX23885_BOARD_HAUPPAUGE_STARBURST: | ||
1990 | ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ | ||
1991 | ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ | ||
1992 | ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; | ||
1993 | break; | ||
1983 | case CX23885_BOARD_DVBSKY_T9580: | 1994 | case CX23885_BOARD_DVBSKY_T9580: |
1984 | case CX23885_BOARD_DVBSKY_T982: | 1995 | case CX23885_BOARD_DVBSKY_T982: |
1985 | ts1->gen_ctrl_val = 0x5; /* Parallel */ | 1996 | ts1->gen_ctrl_val = 0x5; /* Parallel */ |
diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 1d9d0f86ca8c..1ad49946d7fa 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c | |||
@@ -2049,11 +2049,11 @@ static void cx23885_finidev(struct pci_dev *pci_dev) | |||
2049 | 2049 | ||
2050 | cx23885_shutdown(dev); | 2050 | cx23885_shutdown(dev); |
2051 | 2051 | ||
2052 | pci_disable_device(pci_dev); | ||
2053 | |||
2054 | /* unregister stuff */ | 2052 | /* unregister stuff */ |
2055 | free_irq(pci_dev->irq, dev); | 2053 | free_irq(pci_dev->irq, dev); |
2056 | 2054 | ||
2055 | pci_disable_device(pci_dev); | ||
2056 | |||
2057 | cx23885_dev_unregister(dev); | 2057 | cx23885_dev_unregister(dev); |
2058 | vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); | 2058 | vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); |
2059 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | 2059 | v4l2_ctrl_handler_free(&dev->ctrl_handler); |
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index c47d18270cfc..a9c450d4b54e 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c | |||
@@ -1710,6 +1710,17 @@ static int dvb_register(struct cx23885_tsport *port) | |||
1710 | break; | 1710 | break; |
1711 | } | 1711 | } |
1712 | break; | 1712 | break; |
1713 | case CX23885_BOARD_HAUPPAUGE_STARBURST: | ||
1714 | i2c_bus = &dev->i2c_bus[0]; | ||
1715 | fe0->dvb.frontend = dvb_attach(tda10071_attach, | ||
1716 | &hauppauge_tda10071_config, | ||
1717 | &i2c_bus->i2c_adap); | ||
1718 | if (fe0->dvb.frontend != NULL) { | ||
1719 | dvb_attach(a8293_attach, fe0->dvb.frontend, | ||
1720 | &i2c_bus->i2c_adap, | ||
1721 | &hauppauge_a8293_config); | ||
1722 | } | ||
1723 | break; | ||
1713 | case CX23885_BOARD_DVBSKY_T9580: | 1724 | case CX23885_BOARD_DVBSKY_T9580: |
1714 | case CX23885_BOARD_DVBSKY_S950: | 1725 | case CX23885_BOARD_DVBSKY_S950: |
1715 | i2c_bus = &dev->i2c_bus[0]; | 1726 | i2c_bus = &dev->i2c_bus[0]; |
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index f55cd12da0fd..36f2f96c40e4 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h | |||
@@ -99,6 +99,7 @@ | |||
99 | #define CX23885_BOARD_DVBSKY_S950 49 | 99 | #define CX23885_BOARD_DVBSKY_S950 49 |
100 | #define CX23885_BOARD_DVBSKY_S952 50 | 100 | #define CX23885_BOARD_DVBSKY_S952 50 |
101 | #define CX23885_BOARD_DVBSKY_T982 51 | 101 | #define CX23885_BOARD_DVBSKY_T982 51 |
102 | #define CX23885_BOARD_HAUPPAUGE_STARBURST 52 | ||
102 | 103 | ||
103 | #define GPIO_0 0x00000001 | 104 | #define GPIO_0 0x00000001 |
104 | #define GPIO_1 0x00000002 | 105 | #define GPIO_1 0x00000002 |
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index b463fe172d16..3fe9047ef466 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c | |||
@@ -602,10 +602,13 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) | |||
602 | strlcpy(cap->card, video->video.name, sizeof(cap->card)); | 602 | strlcpy(cap->card, video->video.name, sizeof(cap->card)); |
603 | strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); | 603 | strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); |
604 | 604 | ||
605 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | ||
606 | | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; | ||
607 | |||
605 | if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 608 | if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
606 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 609 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
607 | else | 610 | else |
608 | cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; | 611 | cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; |
609 | 612 | ||
610 | return 0; | 613 | return 0; |
611 | } | 614 | } |
diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8efe40337608..6d885239b16a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c | |||
@@ -760,8 +760,9 @@ static int isi_camera_querycap(struct soc_camera_host *ici, | |||
760 | { | 760 | { |
761 | strcpy(cap->driver, "atmel-isi"); | 761 | strcpy(cap->driver, "atmel-isi"); |
762 | strcpy(cap->card, "Atmel Image Sensor Interface"); | 762 | strcpy(cap->card, "Atmel Image Sensor Interface"); |
763 | cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | | 763 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
764 | V4L2_CAP_STREAMING); | 764 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
765 | |||
765 | return 0; | 766 | return 0; |
766 | } | 767 | } |
767 | 768 | ||
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c index ce72bd26a6ac..192377f55840 100644 --- a/drivers/media/platform/soc_camera/mx2_camera.c +++ b/drivers/media/platform/soc_camera/mx2_camera.c | |||
@@ -1256,7 +1256,8 @@ static int mx2_camera_querycap(struct soc_camera_host *ici, | |||
1256 | { | 1256 | { |
1257 | /* cap->name is set by the friendly caller:-> */ | 1257 | /* cap->name is set by the friendly caller:-> */ |
1258 | strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); | 1258 | strlcpy(cap->card, MX2_CAM_DRIVER_DESCRIPTION, sizeof(cap->card)); |
1259 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1259 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1260 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1260 | 1261 | ||
1261 | return 0; | 1262 | return 0; |
1262 | } | 1263 | } |
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c index a60c3bb0e4cc..0b3299dee05d 100644 --- a/drivers/media/platform/soc_camera/mx3_camera.c +++ b/drivers/media/platform/soc_camera/mx3_camera.c | |||
@@ -967,7 +967,8 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, | |||
967 | { | 967 | { |
968 | /* cap->name is set by the firendly caller:-> */ | 968 | /* cap->name is set by the firendly caller:-> */ |
969 | strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); | 969 | strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); |
970 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 970 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
971 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
971 | 972 | ||
972 | return 0; | 973 | return 0; |
973 | } | 974 | } |
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c index e6b93281f246..16f65ecb70a3 100644 --- a/drivers/media/platform/soc_camera/omap1_camera.c +++ b/drivers/media/platform/soc_camera/omap1_camera.c | |||
@@ -1427,7 +1427,8 @@ static int omap1_cam_querycap(struct soc_camera_host *ici, | |||
1427 | { | 1427 | { |
1428 | /* cap->name is set by the friendly caller:-> */ | 1428 | /* cap->name is set by the friendly caller:-> */ |
1429 | strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); | 1429 | strlcpy(cap->card, "OMAP1 Camera", sizeof(cap->card)); |
1430 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1430 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1431 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1431 | 1432 | ||
1432 | return 0; | 1433 | return 0; |
1433 | } | 1434 | } |
diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 951226af0eba..8d6e343fec0f 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c | |||
@@ -1576,7 +1576,8 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, | |||
1576 | { | 1576 | { |
1577 | /* cap->name is set by the firendly caller:-> */ | 1577 | /* cap->name is set by the firendly caller:-> */ |
1578 | strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); | 1578 | strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); |
1579 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1579 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1580 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1580 | 1581 | ||
1581 | return 0; | 1582 | return 0; |
1582 | } | 1583 | } |
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 0c1f55648106..9f1473c0a0cf 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c | |||
@@ -1799,7 +1799,9 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, | |||
1799 | struct v4l2_capability *cap) | 1799 | struct v4l2_capability *cap) |
1800 | { | 1800 | { |
1801 | strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); | 1801 | strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); |
1802 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1802 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1803 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1804 | |||
1803 | return 0; | 1805 | return 0; |
1804 | } | 1806 | } |
1805 | 1807 | ||
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 8b27b3eb2b25..71787702d4a2 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
@@ -1652,7 +1652,9 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, | |||
1652 | struct v4l2_capability *cap) | 1652 | struct v4l2_capability *cap) |
1653 | { | 1653 | { |
1654 | strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); | 1654 | strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); |
1655 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; | 1655 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; |
1656 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
1657 | |||
1656 | return 0; | 1658 | return 0; |
1657 | } | 1659 | } |
1658 | 1660 | ||
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 0f345b1f9014..f327c49d7e09 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
@@ -2232,7 +2232,7 @@ static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { | |||
2232 | { | 2232 | { |
2233 | "Mygica T230 DVB-T/T2/C", | 2233 | "Mygica T230 DVB-T/T2/C", |
2234 | { NULL }, | 2234 | { NULL }, |
2235 | { &cxusb_table[22], NULL }, | 2235 | { &cxusb_table[20], NULL }, |
2236 | }, | 2236 | }, |
2237 | } | 2237 | } |
2238 | }; | 2238 | }; |
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 1b158f1167ed..536210b39428 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c | |||
@@ -89,16 +89,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; | |||
89 | module_param_array(vbi_nr, int, NULL, 0444); | 89 | module_param_array(vbi_nr, int, NULL, 0444); |
90 | MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); | 90 | MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor"); |
91 | 91 | ||
92 | static struct v4l2_capability pvr_capability ={ | ||
93 | .driver = "pvrusb2", | ||
94 | .card = "Hauppauge WinTV pvr-usb2", | ||
95 | .bus_info = "usb", | ||
96 | .version = LINUX_VERSION_CODE, | ||
97 | .capabilities = (V4L2_CAP_VIDEO_CAPTURE | | ||
98 | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | | ||
99 | V4L2_CAP_READWRITE), | ||
100 | }; | ||
101 | |||
102 | static struct v4l2_fmtdesc pvr_fmtdesc [] = { | 92 | static struct v4l2_fmtdesc pvr_fmtdesc [] = { |
103 | { | 93 | { |
104 | .index = 0, | 94 | .index = 0, |
@@ -160,10 +150,22 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability * | |||
160 | struct pvr2_v4l2_fh *fh = file->private_data; | 150 | struct pvr2_v4l2_fh *fh = file->private_data; |
161 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; | 151 | struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; |
162 | 152 | ||
163 | memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); | 153 | strlcpy(cap->driver, "pvrusb2", sizeof(cap->driver)); |
164 | strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), | 154 | strlcpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw), |
165 | sizeof(cap->bus_info)); | 155 | sizeof(cap->bus_info)); |
166 | strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); | 156 | strlcpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card)); |
157 | cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | | ||
158 | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | | ||
159 | V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; | ||
160 | switch (fh->pdi->devbase.vfl_type) { | ||
161 | case VFL_TYPE_GRABBER: | ||
162 | cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; | ||
163 | break; | ||
164 | case VFL_TYPE_RADIO: | ||
165 | cap->device_caps = V4L2_CAP_RADIO; | ||
166 | break; | ||
167 | } | ||
168 | cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE; | ||
167 | return 0; | 169 | return 0; |
168 | } | 170 | } |
169 | 171 | ||
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index d09a8916e940..bc08a829bc13 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -3146,27 +3146,26 @@ static int vb2_thread(void *data) | |||
3146 | prequeue--; | 3146 | prequeue--; |
3147 | } else { | 3147 | } else { |
3148 | call_void_qop(q, wait_finish, q); | 3148 | call_void_qop(q, wait_finish, q); |
3149 | ret = vb2_internal_dqbuf(q, &fileio->b, 0); | 3149 | if (!threadio->stop) |
3150 | ret = vb2_internal_dqbuf(q, &fileio->b, 0); | ||
3150 | call_void_qop(q, wait_prepare, q); | 3151 | call_void_qop(q, wait_prepare, q); |
3151 | dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); | 3152 | dprintk(5, "file io: vb2_dqbuf result: %d\n", ret); |
3152 | } | 3153 | } |
3153 | if (threadio->stop) | 3154 | if (ret || threadio->stop) |
3154 | break; | ||
3155 | if (ret) | ||
3156 | break; | 3155 | break; |
3157 | try_to_freeze(); | 3156 | try_to_freeze(); |
3158 | 3157 | ||
3159 | vb = q->bufs[fileio->b.index]; | 3158 | vb = q->bufs[fileio->b.index]; |
3160 | if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) | 3159 | if (!(fileio->b.flags & V4L2_BUF_FLAG_ERROR)) |
3161 | ret = threadio->fnc(vb, threadio->priv); | 3160 | if (threadio->fnc(vb, threadio->priv)) |
3162 | if (ret) | 3161 | break; |
3163 | break; | ||
3164 | call_void_qop(q, wait_finish, q); | 3162 | call_void_qop(q, wait_finish, q); |
3165 | if (set_timestamp) | 3163 | if (set_timestamp) |
3166 | v4l2_get_timestamp(&fileio->b.timestamp); | 3164 | v4l2_get_timestamp(&fileio->b.timestamp); |
3167 | ret = vb2_internal_qbuf(q, &fileio->b); | 3165 | if (!threadio->stop) |
3166 | ret = vb2_internal_qbuf(q, &fileio->b); | ||
3168 | call_void_qop(q, wait_prepare, q); | 3167 | call_void_qop(q, wait_prepare, q); |
3169 | if (ret) | 3168 | if (ret || threadio->stop) |
3170 | break; | 3169 | break; |
3171 | } | 3170 | } |
3172 | 3171 | ||
@@ -3235,11 +3234,11 @@ int vb2_thread_stop(struct vb2_queue *q) | |||
3235 | threadio->stop = true; | 3234 | threadio->stop = true; |
3236 | vb2_internal_streamoff(q, q->type); | 3235 | vb2_internal_streamoff(q, q->type); |
3237 | call_void_qop(q, wait_prepare, q); | 3236 | call_void_qop(q, wait_prepare, q); |
3237 | err = kthread_stop(threadio->thread); | ||
3238 | q->fileio = NULL; | 3238 | q->fileio = NULL; |
3239 | fileio->req.count = 0; | 3239 | fileio->req.count = 0; |
3240 | vb2_reqbufs(q, &fileio->req); | 3240 | vb2_reqbufs(q, &fileio->req); |
3241 | kfree(fileio); | 3241 | kfree(fileio); |
3242 | err = kthread_stop(threadio->thread); | ||
3243 | threadio->thread = NULL; | 3242 | threadio->thread = NULL; |
3244 | kfree(threadio); | 3243 | kfree(threadio); |
3245 | q->fileio = NULL; | 3244 | q->fileio = NULL; |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 52a0c2f6264f..ae498b53ee40 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -554,7 +554,8 @@ int da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
554 | return ret; | 554 | return ret; |
555 | } | 555 | } |
556 | 556 | ||
557 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | 557 | ret = mfd_add_devices(da9052->dev, PLATFORM_DEVID_AUTO, |
558 | da9052_subdev_info, | ||
558 | ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); | 559 | ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); |
559 | if (ret) { | 560 | if (ret) { |
560 | dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret); | 561 | dev_err(da9052->dev, "mfd_add_devices failed: %d\n", ret); |
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c index dbdd0faeb6ce..210d1f85679e 100644 --- a/drivers/mfd/rtsx_usb.c +++ b/drivers/mfd/rtsx_usb.c | |||
@@ -681,21 +681,9 @@ static void rtsx_usb_disconnect(struct usb_interface *intf) | |||
681 | #ifdef CONFIG_PM | 681 | #ifdef CONFIG_PM |
682 | static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) | 682 | static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) |
683 | { | 683 | { |
684 | struct rtsx_ucr *ucr = | ||
685 | (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
686 | |||
687 | dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n", | 684 | dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n", |
688 | __func__, message.event); | 685 | __func__, message.event); |
689 | 686 | ||
690 | /* | ||
691 | * Call to make sure LED is off during suspend to save more power. | ||
692 | * It is NOT a permanent state and could be turned on anytime later. | ||
693 | * Thus no need to call turn_on when resunming. | ||
694 | */ | ||
695 | mutex_lock(&ucr->dev_mutex); | ||
696 | rtsx_usb_turn_off_led(ucr); | ||
697 | mutex_unlock(&ucr->dev_mutex); | ||
698 | |||
699 | return 0; | 687 | return 0; |
700 | } | 688 | } |
701 | 689 | ||
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index e2f9df1c0c36..2d7fae94c861 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = { | |||
519 | [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, | 519 | [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, |
520 | [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, | 520 | [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, |
521 | [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, | 521 | [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, |
522 | [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, | ||
522 | [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, | 523 | [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, |
523 | [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, | 524 | [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, |
524 | [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, | 525 | [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, |
@@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = { | |||
667 | [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, | 668 | [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, |
668 | [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, | 669 | [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, |
669 | [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, | 670 | [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, |
671 | [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, | ||
670 | [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, | 672 | [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, |
671 | [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, | 673 | [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, |
672 | }; | 674 | }; |
@@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = { | |||
750 | [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, | 752 | [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, |
751 | [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, | 753 | [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, |
752 | [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, | 754 | [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, |
755 | [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, | ||
756 | [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, | ||
753 | [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, | 757 | [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, |
754 | [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, | 758 | [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, |
755 | [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, | 759 | [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, |
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index bee0abf82040..84adb46b3e2f 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h | |||
@@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe); | |||
188 | #define STMPE1601_REG_GPIO_ED_MSB 0x8A | 188 | #define STMPE1601_REG_GPIO_ED_MSB 0x8A |
189 | #define STMPE1601_REG_GPIO_RE_LSB 0x8D | 189 | #define STMPE1601_REG_GPIO_RE_LSB 0x8D |
190 | #define STMPE1601_REG_GPIO_FE_LSB 0x8F | 190 | #define STMPE1601_REG_GPIO_FE_LSB 0x8F |
191 | #define STMPE1601_REG_GPIO_PU_LSB 0x91 | ||
191 | #define STMPE1601_REG_GPIO_AF_U_MSB 0x92 | 192 | #define STMPE1601_REG_GPIO_AF_U_MSB 0x92 |
192 | 193 | ||
193 | #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) | 194 | #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) |
@@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe); | |||
276 | #define STMPE24XX_REG_GPEDR_MSB 0x8C | 277 | #define STMPE24XX_REG_GPEDR_MSB 0x8C |
277 | #define STMPE24XX_REG_GPRER_LSB 0x91 | 278 | #define STMPE24XX_REG_GPRER_LSB 0x91 |
278 | #define STMPE24XX_REG_GPFER_LSB 0x94 | 279 | #define STMPE24XX_REG_GPFER_LSB 0x94 |
280 | #define STMPE24XX_REG_GPPUR_LSB 0x97 | ||
281 | #define STMPE24XX_REG_GPPDR_LSB 0x9a | ||
279 | #define STMPE24XX_REG_GPAFR_U_MSB 0x9B | 282 | #define STMPE24XX_REG_GPAFR_U_MSB 0x9B |
280 | 283 | ||
281 | #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) | 284 | #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) |
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 0d256cb002eb..d6b764349f9d 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c | |||
@@ -125,10 +125,21 @@ int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, | |||
125 | } | 125 | } |
126 | EXPORT_SYMBOL_GPL(tps65218_clear_bits); | 126 | EXPORT_SYMBOL_GPL(tps65218_clear_bits); |
127 | 127 | ||
128 | static const struct regmap_range tps65218_yes_ranges[] = { | ||
129 | regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2), | ||
130 | regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS), | ||
131 | }; | ||
132 | |||
133 | static const struct regmap_access_table tps65218_volatile_table = { | ||
134 | .yes_ranges = tps65218_yes_ranges, | ||
135 | .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges), | ||
136 | }; | ||
137 | |||
128 | static struct regmap_config tps65218_regmap_config = { | 138 | static struct regmap_config tps65218_regmap_config = { |
129 | .reg_bits = 8, | 139 | .reg_bits = 8, |
130 | .val_bits = 8, | 140 | .val_bits = 8, |
131 | .cache_type = REGCACHE_RBTREE, | 141 | .cache_type = REGCACHE_RBTREE, |
142 | .volatile_table = &tps65218_volatile_table, | ||
132 | }; | 143 | }; |
133 | 144 | ||
134 | static const struct regmap_irq tps65218_irqs[] = { | 145 | static const struct regmap_irq tps65218_irqs[] = { |
@@ -193,6 +204,7 @@ static struct regmap_irq_chip tps65218_irq_chip = { | |||
193 | 204 | ||
194 | .num_regs = 2, | 205 | .num_regs = 2, |
195 | .mask_base = TPS65218_REG_INT_MASK1, | 206 | .mask_base = TPS65218_REG_INT_MASK1, |
207 | .status_base = TPS65218_REG_INT1, | ||
196 | }; | 208 | }; |
197 | 209 | ||
198 | static const struct of_device_id of_tps65218_match_table[] = { | 210 | static const struct of_device_id of_tps65218_match_table[] = { |
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c index 51fd6b524371..d1b55fe62817 100644 --- a/drivers/misc/cxl/context.c +++ b/drivers/misc/cxl/context.c | |||
@@ -100,6 +100,46 @@ int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master, | |||
100 | return 0; | 100 | return 0; |
101 | } | 101 | } |
102 | 102 | ||
103 | static int cxl_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
104 | { | ||
105 | struct cxl_context *ctx = vma->vm_file->private_data; | ||
106 | unsigned long address = (unsigned long)vmf->virtual_address; | ||
107 | u64 area, offset; | ||
108 | |||
109 | offset = vmf->pgoff << PAGE_SHIFT; | ||
110 | |||
111 | pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n", | ||
112 | __func__, ctx->pe, address, offset); | ||
113 | |||
114 | if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { | ||
115 | area = ctx->afu->psn_phys; | ||
116 | if (offset > ctx->afu->adapter->ps_size) | ||
117 | return VM_FAULT_SIGBUS; | ||
118 | } else { | ||
119 | area = ctx->psn_phys; | ||
120 | if (offset > ctx->psn_size) | ||
121 | return VM_FAULT_SIGBUS; | ||
122 | } | ||
123 | |||
124 | mutex_lock(&ctx->status_mutex); | ||
125 | |||
126 | if (ctx->status != STARTED) { | ||
127 | mutex_unlock(&ctx->status_mutex); | ||
128 | pr_devel("%s: Context not started, failing problem state access\n", __func__); | ||
129 | return VM_FAULT_SIGBUS; | ||
130 | } | ||
131 | |||
132 | vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); | ||
133 | |||
134 | mutex_unlock(&ctx->status_mutex); | ||
135 | |||
136 | return VM_FAULT_NOPAGE; | ||
137 | } | ||
138 | |||
139 | static const struct vm_operations_struct cxl_mmap_vmops = { | ||
140 | .fault = cxl_mmap_fault, | ||
141 | }; | ||
142 | |||
103 | /* | 143 | /* |
104 | * Map a per-context mmio space into the given vma. | 144 | * Map a per-context mmio space into the given vma. |
105 | */ | 145 | */ |
@@ -108,26 +148,25 @@ int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma) | |||
108 | u64 len = vma->vm_end - vma->vm_start; | 148 | u64 len = vma->vm_end - vma->vm_start; |
109 | len = min(len, ctx->psn_size); | 149 | len = min(len, ctx->psn_size); |
110 | 150 | ||
111 | if (ctx->afu->current_mode == CXL_MODE_DEDICATED) { | 151 | if (ctx->afu->current_mode != CXL_MODE_DEDICATED) { |
112 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 152 | /* make sure there is a valid per process space for this AFU */ |
113 | return vm_iomap_memory(vma, ctx->afu->psn_phys, ctx->afu->adapter->ps_size); | 153 | if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { |
114 | } | 154 | pr_devel("AFU doesn't support mmio space\n"); |
155 | return -EINVAL; | ||
156 | } | ||
115 | 157 | ||
116 | /* make sure there is a valid per process space for this AFU */ | 158 | /* Can't mmap until the AFU is enabled */ |
117 | if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) { | 159 | if (!ctx->afu->enabled) |
118 | pr_devel("AFU doesn't support mmio space\n"); | 160 | return -EBUSY; |
119 | return -EINVAL; | ||
120 | } | 161 | } |
121 | 162 | ||
122 | /* Can't mmap until the AFU is enabled */ | ||
123 | if (!ctx->afu->enabled) | ||
124 | return -EBUSY; | ||
125 | |||
126 | pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__, | 163 | pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__, |
127 | ctx->psn_phys, ctx->pe , ctx->master); | 164 | ctx->psn_phys, ctx->pe , ctx->master); |
128 | 165 | ||
166 | vma->vm_flags |= VM_IO | VM_PFNMAP; | ||
129 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 167 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
130 | return vm_iomap_memory(vma, ctx->psn_phys, len); | 168 | vma->vm_ops = &cxl_mmap_vmops; |
169 | return 0; | ||
131 | } | 170 | } |
132 | 171 | ||
133 | /* | 172 | /* |
@@ -150,12 +189,6 @@ static void __detach_context(struct cxl_context *ctx) | |||
150 | afu_release_irqs(ctx); | 189 | afu_release_irqs(ctx); |
151 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ | 190 | flush_work(&ctx->fault_work); /* Only needed for dedicated process */ |
152 | wake_up_all(&ctx->wq); | 191 | wake_up_all(&ctx->wq); |
153 | |||
154 | /* Release Problem State Area mapping */ | ||
155 | mutex_lock(&ctx->mapping_lock); | ||
156 | if (ctx->mapping) | ||
157 | unmap_mapping_range(ctx->mapping, 0, 0, 1); | ||
158 | mutex_unlock(&ctx->mapping_lock); | ||
159 | } | 192 | } |
160 | 193 | ||
161 | /* | 194 | /* |
@@ -184,6 +217,17 @@ void cxl_context_detach_all(struct cxl_afu *afu) | |||
184 | * created and torn down after the IDR removed | 217 | * created and torn down after the IDR removed |
185 | */ | 218 | */ |
186 | __detach_context(ctx); | 219 | __detach_context(ctx); |
220 | |||
221 | /* | ||
222 | * We are force detaching - remove any active PSA mappings so | ||
223 | * userspace cannot interfere with the card if it comes back. | ||
224 | * Easiest way to exercise this is to unbind and rebind the | ||
225 | * driver via sysfs while it is in use. | ||
226 | */ | ||
227 | mutex_lock(&ctx->mapping_lock); | ||
228 | if (ctx->mapping) | ||
229 | unmap_mapping_range(ctx->mapping, 0, 0, 1); | ||
230 | mutex_unlock(&ctx->mapping_lock); | ||
187 | } | 231 | } |
188 | mutex_unlock(&afu->contexts_lock); | 232 | mutex_unlock(&afu->contexts_lock); |
189 | } | 233 | } |
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c index e9f2f10dbb37..b15d8113877c 100644 --- a/drivers/misc/cxl/file.c +++ b/drivers/misc/cxl/file.c | |||
@@ -140,18 +140,20 @@ static long afu_ioctl_start_work(struct cxl_context *ctx, | |||
140 | 140 | ||
141 | pr_devel("%s: pe: %i\n", __func__, ctx->pe); | 141 | pr_devel("%s: pe: %i\n", __func__, ctx->pe); |
142 | 142 | ||
143 | mutex_lock(&ctx->status_mutex); | 143 | /* Do this outside the status_mutex to avoid a circular dependency with |
144 | if (ctx->status != OPENED) { | 144 | * the locking in cxl_mmap_fault() */ |
145 | rc = -EIO; | ||
146 | goto out; | ||
147 | } | ||
148 | |||
149 | if (copy_from_user(&work, uwork, | 145 | if (copy_from_user(&work, uwork, |
150 | sizeof(struct cxl_ioctl_start_work))) { | 146 | sizeof(struct cxl_ioctl_start_work))) { |
151 | rc = -EFAULT; | 147 | rc = -EFAULT; |
152 | goto out; | 148 | goto out; |
153 | } | 149 | } |
154 | 150 | ||
151 | mutex_lock(&ctx->status_mutex); | ||
152 | if (ctx->status != OPENED) { | ||
153 | rc = -EIO; | ||
154 | goto out; | ||
155 | } | ||
156 | |||
155 | /* | 157 | /* |
156 | * if any of the reserved fields are set or any of the unused | 158 | * if any of the reserved fields are set or any of the unused |
157 | * flags are set it's invalid | 159 | * flags are set it's invalid |
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index ff2755062b44..06ff0a2ec960 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c | |||
@@ -234,6 +234,18 @@ static int mei_me_hw_reset(struct mei_device *dev, bool intr_enable) | |||
234 | struct mei_me_hw *hw = to_me_hw(dev); | 234 | struct mei_me_hw *hw = to_me_hw(dev); |
235 | u32 hcsr = mei_hcsr_read(hw); | 235 | u32 hcsr = mei_hcsr_read(hw); |
236 | 236 | ||
237 | /* H_RST may be found lit before reset is started, | ||
238 | * for example if preceding reset flow hasn't completed. | ||
239 | * In that case asserting H_RST will be ignored, therefore | ||
240 | * we need to clean H_RST bit to start a successful reset sequence. | ||
241 | */ | ||
242 | if ((hcsr & H_RST) == H_RST) { | ||
243 | dev_warn(dev->dev, "H_RST is set = 0x%08X", hcsr); | ||
244 | hcsr &= ~H_RST; | ||
245 | mei_me_reg_write(hw, H_CSR, hcsr); | ||
246 | hcsr = mei_hcsr_read(hw); | ||
247 | } | ||
248 | |||
237 | hcsr |= H_RST | H_IG | H_IS; | 249 | hcsr |= H_RST | H_IG | H_IS; |
238 | 250 | ||
239 | if (intr_enable) | 251 | if (intr_enable) |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 02ad79229f65..7466ce098e60 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -886,7 +886,7 @@ static int mmc_select_bus_width(struct mmc_card *card) | |||
886 | unsigned idx, bus_width = 0; | 886 | unsigned idx, bus_width = 0; |
887 | int err = 0; | 887 | int err = 0; |
888 | 888 | ||
889 | if (!mmc_can_ext_csd(card) && | 889 | if (!mmc_can_ext_csd(card) || |
890 | !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) | 890 | !(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) |
891 | return 0; | 891 | return 0; |
892 | 892 | ||
diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index e3e56d35f0ee..970314e0aac8 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c | |||
@@ -247,6 +247,7 @@ static const struct sdhci_acpi_uid_slot sdhci_acpi_uids[] = { | |||
247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, | 247 | { "INT33BB" , "3" , &sdhci_acpi_slot_int_sd }, |
248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, | 248 | { "INT33C6" , NULL, &sdhci_acpi_slot_int_sdio }, |
249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, | 249 | { "INT3436" , NULL, &sdhci_acpi_slot_int_sdio }, |
250 | { "INT344D" , NULL, &sdhci_acpi_slot_int_sdio }, | ||
250 | { "PNP0D40" }, | 251 | { "PNP0D40" }, |
251 | { }, | 252 | { }, |
252 | }; | 253 | }; |
@@ -257,6 +258,7 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { | |||
257 | { "INT33BB" }, | 258 | { "INT33BB" }, |
258 | { "INT33C6" }, | 259 | { "INT33C6" }, |
259 | { "INT3436" }, | 260 | { "INT3436" }, |
261 | { "INT344D" }, | ||
260 | { "PNP0D40" }, | 262 | { "PNP0D40" }, |
261 | { }, | 263 | { }, |
262 | }; | 264 | }; |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 03427755b902..4f38554ce679 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -993,6 +993,31 @@ static const struct pci_device_id pci_ids[] = { | |||
993 | .subdevice = PCI_ANY_ID, | 993 | .subdevice = PCI_ANY_ID, |
994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, | 994 | .driver_data = (kernel_ulong_t)&sdhci_intel_mrfl_mmc, |
995 | }, | 995 | }, |
996 | |||
997 | { | ||
998 | .vendor = PCI_VENDOR_ID_INTEL, | ||
999 | .device = PCI_DEVICE_ID_INTEL_SPT_EMMC, | ||
1000 | .subvendor = PCI_ANY_ID, | ||
1001 | .subdevice = PCI_ANY_ID, | ||
1002 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_emmc, | ||
1003 | }, | ||
1004 | |||
1005 | { | ||
1006 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1007 | .device = PCI_DEVICE_ID_INTEL_SPT_SDIO, | ||
1008 | .subvendor = PCI_ANY_ID, | ||
1009 | .subdevice = PCI_ANY_ID, | ||
1010 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sdio, | ||
1011 | }, | ||
1012 | |||
1013 | { | ||
1014 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1015 | .device = PCI_DEVICE_ID_INTEL_SPT_SD, | ||
1016 | .subvendor = PCI_ANY_ID, | ||
1017 | .subdevice = PCI_ANY_ID, | ||
1018 | .driver_data = (kernel_ulong_t)&sdhci_intel_byt_sd, | ||
1019 | }, | ||
1020 | |||
996 | { | 1021 | { |
997 | .vendor = PCI_VENDOR_ID_O2, | 1022 | .vendor = PCI_VENDOR_ID_O2, |
998 | .device = PCI_DEVICE_ID_O2_8120, | 1023 | .device = PCI_DEVICE_ID_O2_8120, |
diff --git a/drivers/mmc/host/sdhci-pci.h b/drivers/mmc/host/sdhci-pci.h index d57c3d169914..1ec684d06d54 100644 --- a/drivers/mmc/host/sdhci-pci.h +++ b/drivers/mmc/host/sdhci-pci.h | |||
@@ -21,6 +21,9 @@ | |||
21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 | 21 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC0 0x08e5 |
22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 | 22 | #define PCI_DEVICE_ID_INTEL_CLV_EMMC1 0x08e6 |
23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 | 23 | #define PCI_DEVICE_ID_INTEL_QRK_SD 0x08A7 |
24 | #define PCI_DEVICE_ID_INTEL_SPT_EMMC 0x9d2b | ||
25 | #define PCI_DEVICE_ID_INTEL_SPT_SDIO 0x9d2c | ||
26 | #define PCI_DEVICE_ID_INTEL_SPT_SD 0x9d2d | ||
24 | 27 | ||
25 | /* | 28 | /* |
26 | * PCI registers | 29 | * PCI registers |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 45238871192d..ca3424e7ef71 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -300,13 +300,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
300 | if (IS_ERR(host)) | 300 | if (IS_ERR(host)) |
301 | return PTR_ERR(host); | 301 | return PTR_ERR(host); |
302 | 302 | ||
303 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
304 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
305 | if (ret < 0) | ||
306 | goto err_mbus_win; | ||
307 | } | ||
308 | |||
309 | |||
310 | pltfm_host = sdhci_priv(host); | 303 | pltfm_host = sdhci_priv(host); |
311 | pltfm_host->priv = pxa; | 304 | pltfm_host->priv = pxa; |
312 | 305 | ||
@@ -325,6 +318,12 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) | |||
325 | if (!IS_ERR(pxa->clk_core)) | 318 | if (!IS_ERR(pxa->clk_core)) |
326 | clk_prepare_enable(pxa->clk_core); | 319 | clk_prepare_enable(pxa->clk_core); |
327 | 320 | ||
321 | if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { | ||
322 | ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); | ||
323 | if (ret < 0) | ||
324 | goto err_mbus_win; | ||
325 | } | ||
326 | |||
328 | /* enable 1/8V DDR capable */ | 327 | /* enable 1/8V DDR capable */ |
329 | host->mmc->caps |= MMC_CAP_1_8V_DDR; | 328 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
330 | 329 | ||
@@ -396,11 +395,11 @@ err_add_host: | |||
396 | pm_runtime_disable(&pdev->dev); | 395 | pm_runtime_disable(&pdev->dev); |
397 | err_of_parse: | 396 | err_of_parse: |
398 | err_cd_req: | 397 | err_cd_req: |
398 | err_mbus_win: | ||
399 | clk_disable_unprepare(pxa->clk_io); | 399 | clk_disable_unprepare(pxa->clk_io); |
400 | if (!IS_ERR(pxa->clk_core)) | 400 | if (!IS_ERR(pxa->clk_core)) |
401 | clk_disable_unprepare(pxa->clk_core); | 401 | clk_disable_unprepare(pxa->clk_core); |
402 | err_clk_get: | 402 | err_clk_get: |
403 | err_mbus_win: | ||
404 | sdhci_pltfm_free(pdev); | 403 | sdhci_pltfm_free(pdev); |
405 | return ret; | 404 | return ret; |
406 | } | 405 | } |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index cbb245b58538..f1a488ee432f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -259,8 +259,6 @@ static void sdhci_reinit(struct sdhci_host *host) | |||
259 | 259 | ||
260 | del_timer_sync(&host->tuning_timer); | 260 | del_timer_sync(&host->tuning_timer); |
261 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 261 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
262 | host->mmc->max_blk_count = | ||
263 | (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; | ||
264 | } | 262 | } |
265 | sdhci_enable_card_detection(host); | 263 | sdhci_enable_card_detection(host); |
266 | } | 264 | } |
@@ -1273,6 +1271,12 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned char mode, | |||
1273 | spin_unlock_irq(&host->lock); | 1271 | spin_unlock_irq(&host->lock); |
1274 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); | 1272 | mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); |
1275 | spin_lock_irq(&host->lock); | 1273 | spin_lock_irq(&host->lock); |
1274 | |||
1275 | if (mode != MMC_POWER_OFF) | ||
1276 | sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); | ||
1277 | else | ||
1278 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); | ||
1279 | |||
1276 | return; | 1280 | return; |
1277 | } | 1281 | } |
1278 | 1282 | ||
@@ -1353,6 +1357,8 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1353 | 1357 | ||
1354 | sdhci_runtime_pm_get(host); | 1358 | sdhci_runtime_pm_get(host); |
1355 | 1359 | ||
1360 | present = mmc_gpio_get_cd(host->mmc); | ||
1361 | |||
1356 | spin_lock_irqsave(&host->lock, flags); | 1362 | spin_lock_irqsave(&host->lock, flags); |
1357 | 1363 | ||
1358 | WARN_ON(host->mrq != NULL); | 1364 | WARN_ON(host->mrq != NULL); |
@@ -1381,7 +1387,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1381 | * zero: cd-gpio is used, and card is removed | 1387 | * zero: cd-gpio is used, and card is removed |
1382 | * one: cd-gpio is used, and card is present | 1388 | * one: cd-gpio is used, and card is present |
1383 | */ | 1389 | */ |
1384 | present = mmc_gpio_get_cd(host->mmc); | ||
1385 | if (present < 0) { | 1390 | if (present < 0) { |
1386 | /* If polling, assume that the card is always present. */ | 1391 | /* If polling, assume that the card is always present. */ |
1387 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | 1392 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) |
@@ -1880,6 +1885,18 @@ static int sdhci_card_busy(struct mmc_host *mmc) | |||
1880 | return !(present_state & SDHCI_DATA_LVL_MASK); | 1885 | return !(present_state & SDHCI_DATA_LVL_MASK); |
1881 | } | 1886 | } |
1882 | 1887 | ||
1888 | static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) | ||
1889 | { | ||
1890 | struct sdhci_host *host = mmc_priv(mmc); | ||
1891 | unsigned long flags; | ||
1892 | |||
1893 | spin_lock_irqsave(&host->lock, flags); | ||
1894 | host->flags |= SDHCI_HS400_TUNING; | ||
1895 | spin_unlock_irqrestore(&host->lock, flags); | ||
1896 | |||
1897 | return 0; | ||
1898 | } | ||
1899 | |||
1883 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | 1900 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
1884 | { | 1901 | { |
1885 | struct sdhci_host *host = mmc_priv(mmc); | 1902 | struct sdhci_host *host = mmc_priv(mmc); |
@@ -1887,10 +1904,18 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1887 | int tuning_loop_counter = MAX_TUNING_LOOP; | 1904 | int tuning_loop_counter = MAX_TUNING_LOOP; |
1888 | int err = 0; | 1905 | int err = 0; |
1889 | unsigned long flags; | 1906 | unsigned long flags; |
1907 | unsigned int tuning_count = 0; | ||
1908 | bool hs400_tuning; | ||
1890 | 1909 | ||
1891 | sdhci_runtime_pm_get(host); | 1910 | sdhci_runtime_pm_get(host); |
1892 | spin_lock_irqsave(&host->lock, flags); | 1911 | spin_lock_irqsave(&host->lock, flags); |
1893 | 1912 | ||
1913 | hs400_tuning = host->flags & SDHCI_HS400_TUNING; | ||
1914 | host->flags &= ~SDHCI_HS400_TUNING; | ||
1915 | |||
1916 | if (host->tuning_mode == SDHCI_TUNING_MODE_1) | ||
1917 | tuning_count = host->tuning_count; | ||
1918 | |||
1894 | /* | 1919 | /* |
1895 | * The Host Controller needs tuning only in case of SDR104 mode | 1920 | * The Host Controller needs tuning only in case of SDR104 mode |
1896 | * and for SDR50 mode when Use Tuning for SDR50 is set in the | 1921 | * and for SDR50 mode when Use Tuning for SDR50 is set in the |
@@ -1899,8 +1924,20 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1899 | * tuning function has to be executed. | 1924 | * tuning function has to be executed. |
1900 | */ | 1925 | */ |
1901 | switch (host->timing) { | 1926 | switch (host->timing) { |
1927 | /* HS400 tuning is done in HS200 mode */ | ||
1902 | case MMC_TIMING_MMC_HS400: | 1928 | case MMC_TIMING_MMC_HS400: |
1929 | err = -EINVAL; | ||
1930 | goto out_unlock; | ||
1931 | |||
1903 | case MMC_TIMING_MMC_HS200: | 1932 | case MMC_TIMING_MMC_HS200: |
1933 | /* | ||
1934 | * Periodic re-tuning for HS400 is not expected to be needed, so | ||
1935 | * disable it here. | ||
1936 | */ | ||
1937 | if (hs400_tuning) | ||
1938 | tuning_count = 0; | ||
1939 | break; | ||
1940 | |||
1904 | case MMC_TIMING_UHS_SDR104: | 1941 | case MMC_TIMING_UHS_SDR104: |
1905 | break; | 1942 | break; |
1906 | 1943 | ||
@@ -1911,9 +1948,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
1911 | /* FALLTHROUGH */ | 1948 | /* FALLTHROUGH */ |
1912 | 1949 | ||
1913 | default: | 1950 | default: |
1914 | spin_unlock_irqrestore(&host->lock, flags); | 1951 | goto out_unlock; |
1915 | sdhci_runtime_pm_put(host); | ||
1916 | return 0; | ||
1917 | } | 1952 | } |
1918 | 1953 | ||
1919 | if (host->ops->platform_execute_tuning) { | 1954 | if (host->ops->platform_execute_tuning) { |
@@ -2037,24 +2072,11 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) | |||
2037 | } | 2072 | } |
2038 | 2073 | ||
2039 | out: | 2074 | out: |
2040 | /* | 2075 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
2041 | * If this is the very first time we are here, we start the retuning | 2076 | |
2042 | * timer. Since only during the first time, SDHCI_NEEDS_RETUNING | 2077 | if (tuning_count) { |
2043 | * flag won't be set, we check this condition before actually starting | ||
2044 | * the timer. | ||
2045 | */ | ||
2046 | if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count && | ||
2047 | (host->tuning_mode == SDHCI_TUNING_MODE_1)) { | ||
2048 | host->flags |= SDHCI_USING_RETUNING_TIMER; | 2078 | host->flags |= SDHCI_USING_RETUNING_TIMER; |
2049 | mod_timer(&host->tuning_timer, jiffies + | 2079 | mod_timer(&host->tuning_timer, jiffies + tuning_count * HZ); |
2050 | host->tuning_count * HZ); | ||
2051 | /* Tuning mode 1 limits the maximum data length to 4MB */ | ||
2052 | mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size; | ||
2053 | } else if (host->flags & SDHCI_USING_RETUNING_TIMER) { | ||
2054 | host->flags &= ~SDHCI_NEEDS_RETUNING; | ||
2055 | /* Reload the new initial value for timer */ | ||
2056 | mod_timer(&host->tuning_timer, jiffies + | ||
2057 | host->tuning_count * HZ); | ||
2058 | } | 2080 | } |
2059 | 2081 | ||
2060 | /* | 2082 | /* |
@@ -2070,6 +2092,7 @@ out: | |||
2070 | 2092 | ||
2071 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); | 2093 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); |
2072 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); | 2094 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
2095 | out_unlock: | ||
2073 | spin_unlock_irqrestore(&host->lock, flags); | 2096 | spin_unlock_irqrestore(&host->lock, flags); |
2074 | sdhci_runtime_pm_put(host); | 2097 | sdhci_runtime_pm_put(host); |
2075 | 2098 | ||
@@ -2110,15 +2133,18 @@ static void sdhci_card_event(struct mmc_host *mmc) | |||
2110 | { | 2133 | { |
2111 | struct sdhci_host *host = mmc_priv(mmc); | 2134 | struct sdhci_host *host = mmc_priv(mmc); |
2112 | unsigned long flags; | 2135 | unsigned long flags; |
2136 | int present; | ||
2113 | 2137 | ||
2114 | /* First check if client has provided their own card event */ | 2138 | /* First check if client has provided their own card event */ |
2115 | if (host->ops->card_event) | 2139 | if (host->ops->card_event) |
2116 | host->ops->card_event(host); | 2140 | host->ops->card_event(host); |
2117 | 2141 | ||
2142 | present = sdhci_do_get_cd(host); | ||
2143 | |||
2118 | spin_lock_irqsave(&host->lock, flags); | 2144 | spin_lock_irqsave(&host->lock, flags); |
2119 | 2145 | ||
2120 | /* Check host->mrq first in case we are runtime suspended */ | 2146 | /* Check host->mrq first in case we are runtime suspended */ |
2121 | if (host->mrq && !sdhci_do_get_cd(host)) { | 2147 | if (host->mrq && !present) { |
2122 | pr_err("%s: Card removed during transfer!\n", | 2148 | pr_err("%s: Card removed during transfer!\n", |
2123 | mmc_hostname(host->mmc)); | 2149 | mmc_hostname(host->mmc)); |
2124 | pr_err("%s: Resetting controller.\n", | 2150 | pr_err("%s: Resetting controller.\n", |
@@ -2142,6 +2168,7 @@ static const struct mmc_host_ops sdhci_ops = { | |||
2142 | .hw_reset = sdhci_hw_reset, | 2168 | .hw_reset = sdhci_hw_reset, |
2143 | .enable_sdio_irq = sdhci_enable_sdio_irq, | 2169 | .enable_sdio_irq = sdhci_enable_sdio_irq, |
2144 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, | 2170 | .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, |
2171 | .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, | ||
2145 | .execute_tuning = sdhci_execute_tuning, | 2172 | .execute_tuning = sdhci_execute_tuning, |
2146 | .card_event = sdhci_card_event, | 2173 | .card_event = sdhci_card_event, |
2147 | .card_busy = sdhci_card_busy, | 2174 | .card_busy = sdhci_card_busy, |
@@ -3260,8 +3287,9 @@ int sdhci_add_host(struct sdhci_host *host) | |||
3260 | mmc->max_segs = SDHCI_MAX_SEGS; | 3287 | mmc->max_segs = SDHCI_MAX_SEGS; |
3261 | 3288 | ||
3262 | /* | 3289 | /* |
3263 | * Maximum number of sectors in one transfer. Limited by DMA boundary | 3290 | * Maximum number of sectors in one transfer. Limited by SDMA boundary |
3264 | * size (512KiB). | 3291 | * size (512KiB). Note some tuning modes impose a 4MiB limit, but this |
3292 | * is less anyway. | ||
3265 | */ | 3293 | */ |
3266 | mmc->max_req_size = 524288; | 3294 | mmc->max_req_size = 524288; |
3267 | 3295 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 184c434ae305..0dceba1a2ba1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1648,7 +1648,7 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1648 | /* slave is not a slave or master is not master of this slave */ | 1648 | /* slave is not a slave or master is not master of this slave */ |
1649 | if (!(slave_dev->flags & IFF_SLAVE) || | 1649 | if (!(slave_dev->flags & IFF_SLAVE) || |
1650 | !netdev_has_upper_dev(slave_dev, bond_dev)) { | 1650 | !netdev_has_upper_dev(slave_dev, bond_dev)) { |
1651 | netdev_err(bond_dev, "cannot release %s\n", | 1651 | netdev_dbg(bond_dev, "cannot release %s\n", |
1652 | slave_dev->name); | 1652 | slave_dev->name); |
1653 | return -EINVAL; | 1653 | return -EINVAL; |
1654 | } | 1654 | } |
diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index a5fefb9059c5..b306210b02b7 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c | |||
@@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, int quota) | |||
257 | struct vringh_kiov *riov = &cfv->ctx.riov; | 257 | struct vringh_kiov *riov = &cfv->ctx.riov; |
258 | unsigned int skb_len; | 258 | unsigned int skb_len; |
259 | 259 | ||
260 | again: | ||
261 | do { | 260 | do { |
262 | skb = NULL; | 261 | skb = NULL; |
263 | 262 | ||
@@ -322,7 +321,6 @@ exit: | |||
322 | napi_schedule_prep(napi)) { | 321 | napi_schedule_prep(napi)) { |
323 | vringh_notify_disable_kern(cfv->vr_rx); | 322 | vringh_notify_disable_kern(cfv->vr_rx); |
324 | __napi_schedule(napi); | 323 | __napi_schedule(napi); |
325 | goto again; | ||
326 | } | 324 | } |
327 | break; | 325 | break; |
328 | 326 | ||
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index f94a9fa60488..c672c4dcffac 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -615,6 +615,9 @@ static void c_can_stop(struct net_device *dev) | |||
615 | 615 | ||
616 | c_can_irq_control(priv, false); | 616 | c_can_irq_control(priv, false); |
617 | 617 | ||
618 | /* put ctrl to init on stop to end ongoing transmission */ | ||
619 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_INIT); | ||
620 | |||
618 | /* deactivate pins */ | 621 | /* deactivate pins */ |
619 | pinctrl_pm_select_sleep_state(dev->dev.parent); | 622 | pinctrl_pm_select_sleep_state(dev->dev.parent); |
620 | priv->can.state = CAN_STATE_STOPPED; | 623 | priv->can.state = CAN_STATE_STOPPED; |
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f363972cd77d..e36d10520e24 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -103,27 +103,34 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) | |||
103 | mask = 1 << raminit->bits.start | 1 << raminit->bits.done; | 103 | mask = 1 << raminit->bits.start | 1 << raminit->bits.done; |
104 | regmap_read(raminit->syscon, raminit->reg, &ctrl); | 104 | regmap_read(raminit->syscon, raminit->reg, &ctrl); |
105 | 105 | ||
106 | /* We clear the done and start bit first. The start bit is | 106 | /* We clear the start bit first. The start bit is |
107 | * looking at the 0 -> transition, but is not self clearing; | 107 | * looking at the 0 -> transition, but is not self clearing; |
108 | * And we clear the init done bit as well. | ||
109 | * NOTE: DONE must be written with 1 to clear it. | 108 | * NOTE: DONE must be written with 1 to clear it. |
109 | * We can't clear the DONE bit here using regmap_update_bits() | ||
110 | * as it will bypass the write if initial condition is START:0 DONE:1 | ||
111 | * e.g. on DRA7 which needs START pulse. | ||
110 | */ | 112 | */ |
111 | ctrl &= ~(1 << raminit->bits.start); | 113 | ctrl &= ~mask; /* START = 0, DONE = 0 */ |
112 | ctrl |= 1 << raminit->bits.done; | 114 | regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); |
113 | regmap_write(raminit->syscon, raminit->reg, ctrl); | ||
114 | 115 | ||
115 | ctrl &= ~(1 << raminit->bits.done); | 116 | /* check if START bit is 0. Ignore DONE bit for now |
116 | c_can_hw_raminit_wait_syscon(priv, mask, ctrl); | 117 | * as it can be either 0 or 1. |
118 | */ | ||
119 | c_can_hw_raminit_wait_syscon(priv, 1 << raminit->bits.start, ctrl); | ||
117 | 120 | ||
118 | if (enable) { | 121 | if (enable) { |
119 | /* Set start bit and wait for the done bit. */ | 122 | /* Clear DONE bit & set START bit. */ |
120 | ctrl |= 1 << raminit->bits.start; | 123 | ctrl |= 1 << raminit->bits.start; |
121 | regmap_write(raminit->syscon, raminit->reg, ctrl); | 124 | /* DONE must be written with 1 to clear it */ |
122 | 125 | ctrl |= 1 << raminit->bits.done; | |
126 | regmap_update_bits(raminit->syscon, raminit->reg, mask, ctrl); | ||
127 | /* prevent further clearing of DONE bit */ | ||
128 | ctrl &= ~(1 << raminit->bits.done); | ||
123 | /* clear START bit if start pulse is needed */ | 129 | /* clear START bit if start pulse is needed */ |
124 | if (raminit->needs_pulse) { | 130 | if (raminit->needs_pulse) { |
125 | ctrl &= ~(1 << raminit->bits.start); | 131 | ctrl &= ~(1 << raminit->bits.start); |
126 | regmap_write(raminit->syscon, raminit->reg, ctrl); | 132 | regmap_update_bits(raminit->syscon, raminit->reg, |
133 | mask, ctrl); | ||
127 | } | 134 | } |
128 | 135 | ||
129 | ctrl |= 1 << raminit->bits.done; | 136 | ctrl |= 1 << raminit->bits.done; |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 3ec8f6f25e5f..847c1f813261 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -807,10 +807,14 @@ static int can_changelink(struct net_device *dev, | |||
807 | if (dev->flags & IFF_UP) | 807 | if (dev->flags & IFF_UP) |
808 | return -EBUSY; | 808 | return -EBUSY; |
809 | cm = nla_data(data[IFLA_CAN_CTRLMODE]); | 809 | cm = nla_data(data[IFLA_CAN_CTRLMODE]); |
810 | if (cm->flags & ~priv->ctrlmode_supported) | 810 | |
811 | /* check whether changed bits are allowed to be modified */ | ||
812 | if (cm->mask & ~priv->ctrlmode_supported) | ||
811 | return -EOPNOTSUPP; | 813 | return -EOPNOTSUPP; |
814 | |||
815 | /* clear bits to be modified and copy the flag values */ | ||
812 | priv->ctrlmode &= ~cm->mask; | 816 | priv->ctrlmode &= ~cm->mask; |
813 | priv->ctrlmode |= cm->flags; | 817 | priv->ctrlmode |= (cm->flags & cm->mask); |
814 | 818 | ||
815 | /* CAN_CTRLMODE_FD can only be set when driver supports FD */ | 819 | /* CAN_CTRLMODE_FD can only be set when driver supports FD */ |
816 | if (priv->ctrlmode & CAN_CTRLMODE_FD) | 820 | if (priv->ctrlmode & CAN_CTRLMODE_FD) |
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index d7bc462aafdc..244529881be9 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c | |||
@@ -955,6 +955,11 @@ static struct net_device *alloc_m_can_dev(void) | |||
955 | priv->can.data_bittiming_const = &m_can_data_bittiming_const; | 955 | priv->can.data_bittiming_const = &m_can_data_bittiming_const; |
956 | priv->can.do_set_mode = m_can_set_mode; | 956 | priv->can.do_set_mode = m_can_set_mode; |
957 | priv->can.do_get_berr_counter = m_can_get_berr_counter; | 957 | priv->can.do_get_berr_counter = m_can_get_berr_counter; |
958 | |||
959 | /* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */ | ||
960 | priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO; | ||
961 | |||
962 | /* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */ | ||
958 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | | 963 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
959 | CAN_CTRLMODE_LISTENONLY | | 964 | CAN_CTRLMODE_LISTENONLY | |
960 | CAN_CTRLMODE_BERR_REPORTING | | 965 | CAN_CTRLMODE_BERR_REPORTING | |
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 541fb7a05625..7af379ca861b 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c | |||
@@ -520,10 +520,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev, | |||
520 | skb = alloc_can_err_skb(priv->netdev, &cf); | 520 | skb = alloc_can_err_skb(priv->netdev, &cf); |
521 | if (skb) { | 521 | if (skb) { |
522 | cf->can_id |= CAN_ERR_RESTARTED; | 522 | cf->can_id |= CAN_ERR_RESTARTED; |
523 | netif_rx(skb); | ||
524 | 523 | ||
525 | stats->rx_packets++; | 524 | stats->rx_packets++; |
526 | stats->rx_bytes += cf->can_dlc; | 525 | stats->rx_bytes += cf->can_dlc; |
526 | netif_rx(skb); | ||
527 | } else { | 527 | } else { |
528 | netdev_err(priv->netdev, | 528 | netdev_err(priv->netdev, |
529 | "No memory left for err_skb\n"); | 529 | "No memory left for err_skb\n"); |
@@ -587,7 +587,7 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv, | |||
587 | usb_sndbulkpipe(dev->udev, | 587 | usb_sndbulkpipe(dev->udev, |
588 | dev->bulk_out->bEndpointAddress), | 588 | dev->bulk_out->bEndpointAddress), |
589 | buf, msg->len, | 589 | buf, msg->len, |
590 | kvaser_usb_simple_msg_callback, priv); | 590 | kvaser_usb_simple_msg_callback, netdev); |
591 | usb_anchor_urb(urb, &priv->tx_submitted); | 591 | usb_anchor_urb(urb, &priv->tx_submitted); |
592 | 592 | ||
593 | err = usb_submit_urb(urb, GFP_ATOMIC); | 593 | err = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -662,11 +662,6 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
662 | priv = dev->nets[channel]; | 662 | priv = dev->nets[channel]; |
663 | stats = &priv->netdev->stats; | 663 | stats = &priv->netdev->stats; |
664 | 664 | ||
665 | if (status & M16C_STATE_BUS_RESET) { | ||
666 | kvaser_usb_unlink_tx_urbs(priv); | ||
667 | return; | ||
668 | } | ||
669 | |||
670 | skb = alloc_can_err_skb(priv->netdev, &cf); | 665 | skb = alloc_can_err_skb(priv->netdev, &cf); |
671 | if (!skb) { | 666 | if (!skb) { |
672 | stats->rx_dropped++; | 667 | stats->rx_dropped++; |
@@ -677,7 +672,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
677 | 672 | ||
678 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); | 673 | netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status); |
679 | 674 | ||
680 | if (status & M16C_STATE_BUS_OFF) { | 675 | if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { |
681 | cf->can_id |= CAN_ERR_BUSOFF; | 676 | cf->can_id |= CAN_ERR_BUSOFF; |
682 | 677 | ||
683 | priv->can.can_stats.bus_off++; | 678 | priv->can.can_stats.bus_off++; |
@@ -703,9 +698,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
703 | } | 698 | } |
704 | 699 | ||
705 | new_state = CAN_STATE_ERROR_PASSIVE; | 700 | new_state = CAN_STATE_ERROR_PASSIVE; |
706 | } | 701 | } else if (status & M16C_STATE_BUS_ERROR) { |
707 | |||
708 | if (status == M16C_STATE_BUS_ERROR) { | ||
709 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && | 702 | if ((priv->can.state < CAN_STATE_ERROR_WARNING) && |
710 | ((txerr >= 96) || (rxerr >= 96))) { | 703 | ((txerr >= 96) || (rxerr >= 96))) { |
711 | cf->can_id |= CAN_ERR_CRTL; | 704 | cf->can_id |= CAN_ERR_CRTL; |
@@ -715,7 +708,8 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
715 | 708 | ||
716 | priv->can.can_stats.error_warning++; | 709 | priv->can.can_stats.error_warning++; |
717 | new_state = CAN_STATE_ERROR_WARNING; | 710 | new_state = CAN_STATE_ERROR_WARNING; |
718 | } else if (priv->can.state > CAN_STATE_ERROR_ACTIVE) { | 711 | } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && |
712 | ((txerr < 96) && (rxerr < 96))) { | ||
719 | cf->can_id |= CAN_ERR_PROT; | 713 | cf->can_id |= CAN_ERR_PROT; |
720 | cf->data[2] = CAN_ERR_PROT_ACTIVE; | 714 | cf->data[2] = CAN_ERR_PROT_ACTIVE; |
721 | 715 | ||
@@ -770,10 +764,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev, | |||
770 | 764 | ||
771 | priv->can.state = new_state; | 765 | priv->can.state = new_state; |
772 | 766 | ||
773 | netif_rx(skb); | ||
774 | |||
775 | stats->rx_packets++; | 767 | stats->rx_packets++; |
776 | stats->rx_bytes += cf->can_dlc; | 768 | stats->rx_bytes += cf->can_dlc; |
769 | netif_rx(skb); | ||
777 | } | 770 | } |
778 | 771 | ||
779 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | 772 | static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, |
@@ -805,10 +798,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv, | |||
805 | stats->rx_over_errors++; | 798 | stats->rx_over_errors++; |
806 | stats->rx_errors++; | 799 | stats->rx_errors++; |
807 | 800 | ||
808 | netif_rx(skb); | ||
809 | |||
810 | stats->rx_packets++; | 801 | stats->rx_packets++; |
811 | stats->rx_bytes += cf->can_dlc; | 802 | stats->rx_bytes += cf->can_dlc; |
803 | netif_rx(skb); | ||
812 | } | 804 | } |
813 | } | 805 | } |
814 | 806 | ||
@@ -887,10 +879,9 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev, | |||
887 | cf->can_dlc); | 879 | cf->can_dlc); |
888 | } | 880 | } |
889 | 881 | ||
890 | netif_rx(skb); | ||
891 | |||
892 | stats->rx_packets++; | 882 | stats->rx_packets++; |
893 | stats->rx_bytes += cf->can_dlc; | 883 | stats->rx_bytes += cf->can_dlc; |
884 | netif_rx(skb); | ||
894 | } | 885 | } |
895 | 886 | ||
896 | static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, | 887 | static void kvaser_usb_start_chip_reply(const struct kvaser_usb *dev, |
@@ -1246,6 +1237,9 @@ static int kvaser_usb_close(struct net_device *netdev) | |||
1246 | if (err) | 1237 | if (err) |
1247 | netdev_warn(netdev, "Cannot stop device, error %d\n", err); | 1238 | netdev_warn(netdev, "Cannot stop device, error %d\n", err); |
1248 | 1239 | ||
1240 | /* reset tx contexts */ | ||
1241 | kvaser_usb_unlink_tx_urbs(priv); | ||
1242 | |||
1249 | priv->can.state = CAN_STATE_STOPPED; | 1243 | priv->can.state = CAN_STATE_STOPPED; |
1250 | close_candev(priv->netdev); | 1244 | close_candev(priv->netdev); |
1251 | 1245 | ||
@@ -1294,12 +1288,14 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1294 | if (!urb) { | 1288 | if (!urb) { |
1295 | netdev_err(netdev, "No memory left for URBs\n"); | 1289 | netdev_err(netdev, "No memory left for URBs\n"); |
1296 | stats->tx_dropped++; | 1290 | stats->tx_dropped++; |
1297 | goto nourbmem; | 1291 | dev_kfree_skb(skb); |
1292 | return NETDEV_TX_OK; | ||
1298 | } | 1293 | } |
1299 | 1294 | ||
1300 | buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); | 1295 | buf = kmalloc(sizeof(struct kvaser_msg), GFP_ATOMIC); |
1301 | if (!buf) { | 1296 | if (!buf) { |
1302 | stats->tx_dropped++; | 1297 | stats->tx_dropped++; |
1298 | dev_kfree_skb(skb); | ||
1303 | goto nobufmem; | 1299 | goto nobufmem; |
1304 | } | 1300 | } |
1305 | 1301 | ||
@@ -1334,6 +1330,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1334 | } | 1330 | } |
1335 | } | 1331 | } |
1336 | 1332 | ||
1333 | /* This should never happen; it implies a flow control bug */ | ||
1337 | if (!context) { | 1334 | if (!context) { |
1338 | netdev_warn(netdev, "cannot find free context\n"); | 1335 | netdev_warn(netdev, "cannot find free context\n"); |
1339 | ret = NETDEV_TX_BUSY; | 1336 | ret = NETDEV_TX_BUSY; |
@@ -1364,9 +1361,6 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, | |||
1364 | if (unlikely(err)) { | 1361 | if (unlikely(err)) { |
1365 | can_free_echo_skb(netdev, context->echo_index); | 1362 | can_free_echo_skb(netdev, context->echo_index); |
1366 | 1363 | ||
1367 | skb = NULL; /* set to NULL to avoid double free in | ||
1368 | * dev_kfree_skb(skb) */ | ||
1369 | |||
1370 | atomic_dec(&priv->active_tx_urbs); | 1364 | atomic_dec(&priv->active_tx_urbs); |
1371 | usb_unanchor_urb(urb); | 1365 | usb_unanchor_urb(urb); |
1372 | 1366 | ||
@@ -1388,8 +1382,6 @@ releasebuf: | |||
1388 | kfree(buf); | 1382 | kfree(buf); |
1389 | nobufmem: | 1383 | nobufmem: |
1390 | usb_free_urb(urb); | 1384 | usb_free_urb(urb); |
1391 | nourbmem: | ||
1392 | dev_kfree_skb(skb); | ||
1393 | return ret; | 1385 | return ret; |
1394 | } | 1386 | } |
1395 | 1387 | ||
@@ -1502,6 +1494,10 @@ static int kvaser_usb_init_one(struct usb_interface *intf, | |||
1502 | struct kvaser_usb_net_priv *priv; | 1494 | struct kvaser_usb_net_priv *priv; |
1503 | int i, err; | 1495 | int i, err; |
1504 | 1496 | ||
1497 | err = kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, channel); | ||
1498 | if (err) | ||
1499 | return err; | ||
1500 | |||
1505 | netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); | 1501 | netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS); |
1506 | if (!netdev) { | 1502 | if (!netdev) { |
1507 | dev_err(&intf->dev, "Cannot alloc candev\n"); | 1503 | dev_err(&intf->dev, "Cannot alloc candev\n"); |
@@ -1588,7 +1584,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
1588 | { | 1584 | { |
1589 | struct kvaser_usb *dev; | 1585 | struct kvaser_usb *dev; |
1590 | int err = -ENOMEM; | 1586 | int err = -ENOMEM; |
1591 | int i; | 1587 | int i, retry = 3; |
1592 | 1588 | ||
1593 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); | 1589 | dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); |
1594 | if (!dev) | 1590 | if (!dev) |
@@ -1606,10 +1602,15 @@ static int kvaser_usb_probe(struct usb_interface *intf, | |||
1606 | 1602 | ||
1607 | usb_set_intfdata(intf, dev); | 1603 | usb_set_intfdata(intf, dev); |
1608 | 1604 | ||
1609 | for (i = 0; i < MAX_NET_DEVICES; i++) | 1605 | /* On some x86 laptops, plugging a Kvaser device again after |
1610 | kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i); | 1606 | * an unplug makes the firmware always ignore the very first |
1607 | * command. For such a case, provide some room for retries | ||
1608 | * instead of completely exiting the driver. | ||
1609 | */ | ||
1610 | do { | ||
1611 | err = kvaser_usb_get_software_info(dev); | ||
1612 | } while (--retry && err == -ETIMEDOUT); | ||
1611 | 1613 | ||
1612 | err = kvaser_usb_get_software_info(dev); | ||
1613 | if (err) { | 1614 | if (err) { |
1614 | dev_err(&intf->dev, | 1615 | dev_err(&intf->dev, |
1615 | "Cannot get software infos, error %d\n", err); | 1616 | "Cannot get software infos, error %d\n", err); |
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c index 89c8d9fc97de..57e97910c728 100644 --- a/drivers/net/ethernet/8390/ne2k-pci.c +++ b/drivers/net/ethernet/8390/ne2k-pci.c | |||
@@ -246,13 +246,13 @@ static int ne2k_pci_init_one(struct pci_dev *pdev, | |||
246 | 246 | ||
247 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { | 247 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { |
248 | dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); | 248 | dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); |
249 | return -ENODEV; | 249 | goto err_out; |
250 | } | 250 | } |
251 | 251 | ||
252 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { | 252 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { |
253 | dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", | 253 | dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", |
254 | NE_IO_EXTENT, ioaddr); | 254 | NE_IO_EXTENT, ioaddr); |
255 | return -EBUSY; | 255 | goto err_out; |
256 | } | 256 | } |
257 | 257 | ||
258 | reg0 = inb(ioaddr); | 258 | reg0 = inb(ioaddr); |
@@ -392,6 +392,8 @@ err_out_free_netdev: | |||
392 | free_netdev (dev); | 392 | free_netdev (dev); |
393 | err_out_free_res: | 393 | err_out_free_res: |
394 | release_region (ioaddr, NE_IO_EXTENT); | 394 | release_region (ioaddr, NE_IO_EXTENT); |
395 | err_out: | ||
396 | pci_disable_device(pdev); | ||
395 | return -ENODEV; | 397 | return -ENODEV; |
396 | } | 398 | } |
397 | 399 | ||
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index df76050d0a9d..eadcb053807e 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
@@ -156,18 +156,6 @@ source "drivers/net/ethernet/realtek/Kconfig" | |||
156 | source "drivers/net/ethernet/renesas/Kconfig" | 156 | source "drivers/net/ethernet/renesas/Kconfig" |
157 | source "drivers/net/ethernet/rdc/Kconfig" | 157 | source "drivers/net/ethernet/rdc/Kconfig" |
158 | source "drivers/net/ethernet/rocker/Kconfig" | 158 | source "drivers/net/ethernet/rocker/Kconfig" |
159 | |||
160 | config S6GMAC | ||
161 | tristate "S6105 GMAC ethernet support" | ||
162 | depends on XTENSA_VARIANT_S6000 | ||
163 | select PHYLIB | ||
164 | ---help--- | ||
165 | This driver supports the on chip ethernet device on the | ||
166 | S6105 xtensa processor. | ||
167 | |||
168 | To compile this driver as a module, choose M here. The module | ||
169 | will be called s6gmac. | ||
170 | |||
171 | source "drivers/net/ethernet/samsung/Kconfig" | 159 | source "drivers/net/ethernet/samsung/Kconfig" |
172 | source "drivers/net/ethernet/seeq/Kconfig" | 160 | source "drivers/net/ethernet/seeq/Kconfig" |
173 | source "drivers/net/ethernet/silan/Kconfig" | 161 | source "drivers/net/ethernet/silan/Kconfig" |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index bf56f8b36e90..1367afcd0a8b 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
@@ -66,7 +66,6 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/ | |||
66 | obj-$(CONFIG_SH_ETH) += renesas/ | 66 | obj-$(CONFIG_SH_ETH) += renesas/ |
67 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ | 67 | obj-$(CONFIG_NET_VENDOR_RDC) += rdc/ |
68 | obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ | 68 | obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/ |
69 | obj-$(CONFIG_S6GMAC) += s6gmac.o | ||
70 | obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ | 69 | obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/ |
71 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ | 70 | obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/ |
72 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ | 71 | obj-$(CONFIG_NET_VENDOR_SILAN) += silan/ |
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 1fcd5568a352..f3470d96837a 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
@@ -850,8 +850,10 @@ static int emac_probe(struct platform_device *pdev) | |||
850 | } | 850 | } |
851 | 851 | ||
852 | db->clk = devm_clk_get(&pdev->dev, NULL); | 852 | db->clk = devm_clk_get(&pdev->dev, NULL); |
853 | if (IS_ERR(db->clk)) | 853 | if (IS_ERR(db->clk)) { |
854 | ret = PTR_ERR(db->clk); | ||
854 | goto out; | 855 | goto out; |
856 | } | ||
855 | 857 | ||
856 | clk_prepare_enable(db->clk); | 858 | clk_prepare_enable(db->clk); |
857 | 859 | ||
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index 3498760dc22a..760c72c6e2ac 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c | |||
@@ -1170,10 +1170,6 @@ tx_request_irq_error: | |||
1170 | init_error: | 1170 | init_error: |
1171 | free_skbufs(dev); | 1171 | free_skbufs(dev); |
1172 | alloc_skbuf_error: | 1172 | alloc_skbuf_error: |
1173 | if (priv->phydev) { | ||
1174 | phy_disconnect(priv->phydev); | ||
1175 | priv->phydev = NULL; | ||
1176 | } | ||
1177 | phy_error: | 1173 | phy_error: |
1178 | return ret; | 1174 | return ret; |
1179 | } | 1175 | } |
@@ -1186,12 +1182,9 @@ static int tse_shutdown(struct net_device *dev) | |||
1186 | int ret; | 1182 | int ret; |
1187 | unsigned long int flags; | 1183 | unsigned long int flags; |
1188 | 1184 | ||
1189 | /* Stop and disconnect the PHY */ | 1185 | /* Stop the PHY */ |
1190 | if (priv->phydev) { | 1186 | if (priv->phydev) |
1191 | phy_stop(priv->phydev); | 1187 | phy_stop(priv->phydev); |
1192 | phy_disconnect(priv->phydev); | ||
1193 | priv->phydev = NULL; | ||
1194 | } | ||
1195 | 1188 | ||
1196 | netif_stop_queue(dev); | 1189 | netif_stop_queue(dev); |
1197 | napi_disable(&priv->napi); | 1190 | napi_disable(&priv->napi); |
@@ -1525,6 +1518,10 @@ err_free_netdev: | |||
1525 | static int altera_tse_remove(struct platform_device *pdev) | 1518 | static int altera_tse_remove(struct platform_device *pdev) |
1526 | { | 1519 | { |
1527 | struct net_device *ndev = platform_get_drvdata(pdev); | 1520 | struct net_device *ndev = platform_get_drvdata(pdev); |
1521 | struct altera_tse_private *priv = netdev_priv(ndev); | ||
1522 | |||
1523 | if (priv->phydev) | ||
1524 | phy_disconnect(priv->phydev); | ||
1528 | 1525 | ||
1529 | platform_set_drvdata(pdev, NULL); | 1526 | platform_set_drvdata(pdev, NULL); |
1530 | altera_tse_mdio_destroy(ndev); | 1527 | altera_tse_mdio_destroy(ndev); |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 75b08c63d39f..29a09271b64a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h | |||
@@ -767,16 +767,17 @@ | |||
767 | #define MTL_Q_RQOMR 0x40 | 767 | #define MTL_Q_RQOMR 0x40 |
768 | #define MTL_Q_RQMPOCR 0x44 | 768 | #define MTL_Q_RQMPOCR 0x44 |
769 | #define MTL_Q_RQDR 0x4c | 769 | #define MTL_Q_RQDR 0x4c |
770 | #define MTL_Q_RQFCR 0x50 | ||
770 | #define MTL_Q_IER 0x70 | 771 | #define MTL_Q_IER 0x70 |
771 | #define MTL_Q_ISR 0x74 | 772 | #define MTL_Q_ISR 0x74 |
772 | 773 | ||
773 | /* MTL queue register entry bit positions and sizes */ | 774 | /* MTL queue register entry bit positions and sizes */ |
775 | #define MTL_Q_RQFCR_RFA_INDEX 1 | ||
776 | #define MTL_Q_RQFCR_RFA_WIDTH 6 | ||
777 | #define MTL_Q_RQFCR_RFD_INDEX 17 | ||
778 | #define MTL_Q_RQFCR_RFD_WIDTH 6 | ||
774 | #define MTL_Q_RQOMR_EHFC_INDEX 7 | 779 | #define MTL_Q_RQOMR_EHFC_INDEX 7 |
775 | #define MTL_Q_RQOMR_EHFC_WIDTH 1 | 780 | #define MTL_Q_RQOMR_EHFC_WIDTH 1 |
776 | #define MTL_Q_RQOMR_RFA_INDEX 8 | ||
777 | #define MTL_Q_RQOMR_RFA_WIDTH 3 | ||
778 | #define MTL_Q_RQOMR_RFD_INDEX 13 | ||
779 | #define MTL_Q_RQOMR_RFD_WIDTH 3 | ||
780 | #define MTL_Q_RQOMR_RQS_INDEX 16 | 781 | #define MTL_Q_RQOMR_RQS_INDEX 16 |
781 | #define MTL_Q_RQOMR_RQS_WIDTH 9 | 782 | #define MTL_Q_RQOMR_RQS_WIDTH 9 |
782 | #define MTL_Q_RQOMR_RSF_INDEX 5 | 783 | #define MTL_Q_RQOMR_RSF_INDEX 5 |
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 53f5f66ec2ee..4c66cd1d1e60 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c | |||
@@ -2079,10 +2079,10 @@ static void xgbe_config_flow_control_threshold(struct xgbe_prv_data *pdata) | |||
2079 | 2079 | ||
2080 | for (i = 0; i < pdata->rx_q_count; i++) { | 2080 | for (i = 0; i < pdata->rx_q_count; i++) { |
2081 | /* Activate flow control when less than 4k left in fifo */ | 2081 | /* Activate flow control when less than 4k left in fifo */ |
2082 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFA, 2); | 2082 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFA, 2); |
2083 | 2083 | ||
2084 | /* De-activate flow control when more than 6k left in fifo */ | 2084 | /* De-activate flow control when more than 6k left in fifo */ |
2085 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, RFD, 4); | 2085 | XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQFCR, RFD, 4); |
2086 | } | 2086 | } |
2087 | } | 2087 | } |
2088 | 2088 | ||
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index e398eda07298..c8af3ce3ea38 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c | |||
@@ -184,15 +184,16 @@ static void alx_schedule_reset(struct alx_priv *alx) | |||
184 | schedule_work(&alx->reset_wk); | 184 | schedule_work(&alx->reset_wk); |
185 | } | 185 | } |
186 | 186 | ||
187 | static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) | 187 | static int alx_clean_rx_irq(struct alx_priv *alx, int budget) |
188 | { | 188 | { |
189 | struct alx_rx_queue *rxq = &alx->rxq; | 189 | struct alx_rx_queue *rxq = &alx->rxq; |
190 | struct alx_rrd *rrd; | 190 | struct alx_rrd *rrd; |
191 | struct alx_buffer *rxb; | 191 | struct alx_buffer *rxb; |
192 | struct sk_buff *skb; | 192 | struct sk_buff *skb; |
193 | u16 length, rfd_cleaned = 0; | 193 | u16 length, rfd_cleaned = 0; |
194 | int work = 0; | ||
194 | 195 | ||
195 | while (budget > 0) { | 196 | while (work < budget) { |
196 | rrd = &rxq->rrd[rxq->rrd_read_idx]; | 197 | rrd = &rxq->rrd[rxq->rrd_read_idx]; |
197 | if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT))) | 198 | if (!(rrd->word3 & cpu_to_le32(1 << RRD_UPDATED_SHIFT))) |
198 | break; | 199 | break; |
@@ -203,7 +204,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) | |||
203 | ALX_GET_FIELD(le32_to_cpu(rrd->word0), | 204 | ALX_GET_FIELD(le32_to_cpu(rrd->word0), |
204 | RRD_NOR) != 1) { | 205 | RRD_NOR) != 1) { |
205 | alx_schedule_reset(alx); | 206 | alx_schedule_reset(alx); |
206 | return 0; | 207 | return work; |
207 | } | 208 | } |
208 | 209 | ||
209 | rxb = &rxq->bufs[rxq->read_idx]; | 210 | rxb = &rxq->bufs[rxq->read_idx]; |
@@ -243,7 +244,7 @@ static bool alx_clean_rx_irq(struct alx_priv *alx, int budget) | |||
243 | } | 244 | } |
244 | 245 | ||
245 | napi_gro_receive(&alx->napi, skb); | 246 | napi_gro_receive(&alx->napi, skb); |
246 | budget--; | 247 | work++; |
247 | 248 | ||
248 | next_pkt: | 249 | next_pkt: |
249 | if (++rxq->read_idx == alx->rx_ringsz) | 250 | if (++rxq->read_idx == alx->rx_ringsz) |
@@ -258,21 +259,22 @@ next_pkt: | |||
258 | if (rfd_cleaned) | 259 | if (rfd_cleaned) |
259 | alx_refill_rx_ring(alx, GFP_ATOMIC); | 260 | alx_refill_rx_ring(alx, GFP_ATOMIC); |
260 | 261 | ||
261 | return budget > 0; | 262 | return work; |
262 | } | 263 | } |
263 | 264 | ||
264 | static int alx_poll(struct napi_struct *napi, int budget) | 265 | static int alx_poll(struct napi_struct *napi, int budget) |
265 | { | 266 | { |
266 | struct alx_priv *alx = container_of(napi, struct alx_priv, napi); | 267 | struct alx_priv *alx = container_of(napi, struct alx_priv, napi); |
267 | struct alx_hw *hw = &alx->hw; | 268 | struct alx_hw *hw = &alx->hw; |
268 | bool complete = true; | ||
269 | unsigned long flags; | 269 | unsigned long flags; |
270 | bool tx_complete; | ||
271 | int work; | ||
270 | 272 | ||
271 | complete = alx_clean_tx_irq(alx) && | 273 | tx_complete = alx_clean_tx_irq(alx); |
272 | alx_clean_rx_irq(alx, budget); | 274 | work = alx_clean_rx_irq(alx, budget); |
273 | 275 | ||
274 | if (!complete) | 276 | if (!tx_complete || work == budget) |
275 | return 1; | 277 | return budget; |
276 | 278 | ||
277 | napi_complete(&alx->napi); | 279 | napi_complete(&alx->napi); |
278 | 280 | ||
@@ -284,7 +286,7 @@ static int alx_poll(struct napi_struct *napi, int budget) | |||
284 | 286 | ||
285 | alx_post_write(hw); | 287 | alx_post_write(hw); |
286 | 288 | ||
287 | return 0; | 289 | return work; |
288 | } | 290 | } |
289 | 291 | ||
290 | static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr) | 292 | static irqreturn_t alx_intr_handle(struct alx_priv *alx, u32 intr) |
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 05c6af6c418f..3007d95fbb9f 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c | |||
@@ -1167,10 +1167,10 @@ static int bgmac_poll(struct napi_struct *napi, int weight) | |||
1167 | bgmac->int_status = 0; | 1167 | bgmac->int_status = 0; |
1168 | } | 1168 | } |
1169 | 1169 | ||
1170 | if (handled < weight) | 1170 | if (handled < weight) { |
1171 | napi_complete(napi); | 1171 | napi_complete(napi); |
1172 | 1172 | bgmac_chip_intrs_on(bgmac); | |
1173 | bgmac_chip_intrs_on(bgmac); | 1173 | } |
1174 | 1174 | ||
1175 | return handled; | 1175 | return handled; |
1176 | } | 1176 | } |
@@ -1515,6 +1515,8 @@ static int bgmac_probe(struct bcma_device *core) | |||
1515 | if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) | 1515 | if (core->bus->sprom.boardflags_lo & BGMAC_BFL_ENETADM) |
1516 | bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); | 1516 | bgmac_warn(bgmac, "Support for ADMtek ethernet switch not implemented\n"); |
1517 | 1517 | ||
1518 | netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); | ||
1519 | |||
1518 | err = bgmac_mii_register(bgmac); | 1520 | err = bgmac_mii_register(bgmac); |
1519 | if (err) { | 1521 | if (err) { |
1520 | bgmac_err(bgmac, "Cannot register MDIO\n"); | 1522 | bgmac_err(bgmac, "Cannot register MDIO\n"); |
@@ -1529,8 +1531,6 @@ static int bgmac_probe(struct bcma_device *core) | |||
1529 | 1531 | ||
1530 | netif_carrier_off(net_dev); | 1532 | netif_carrier_off(net_dev); |
1531 | 1533 | ||
1532 | netif_napi_add(net_dev, &bgmac->napi, bgmac_poll, BGMAC_WEIGHT); | ||
1533 | |||
1534 | return 0; | 1534 | return 0; |
1535 | 1535 | ||
1536 | err_mii_unregister: | 1536 | err_mii_unregister: |
@@ -1549,9 +1549,9 @@ static void bgmac_remove(struct bcma_device *core) | |||
1549 | { | 1549 | { |
1550 | struct bgmac *bgmac = bcma_get_drvdata(core); | 1550 | struct bgmac *bgmac = bcma_get_drvdata(core); |
1551 | 1551 | ||
1552 | netif_napi_del(&bgmac->napi); | ||
1553 | unregister_netdev(bgmac->net_dev); | 1552 | unregister_netdev(bgmac->net_dev); |
1554 | bgmac_mii_unregister(bgmac); | 1553 | bgmac_mii_unregister(bgmac); |
1554 | netif_napi_del(&bgmac->napi); | ||
1555 | bgmac_dma_free(bgmac); | 1555 | bgmac_dma_free(bgmac); |
1556 | bcma_set_drvdata(core, NULL); | 1556 | bcma_set_drvdata(core, NULL); |
1557 | free_netdev(bgmac->net_dev); | 1557 | free_netdev(bgmac->net_dev); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 1d1147c93d59..e468ed3f210f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -3175,7 +3175,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) | |||
3175 | } | 3175 | } |
3176 | #endif | 3176 | #endif |
3177 | if (!bnx2x_fp_lock_napi(fp)) | 3177 | if (!bnx2x_fp_lock_napi(fp)) |
3178 | return work_done; | 3178 | return budget; |
3179 | 3179 | ||
3180 | for_each_cos_in_tx_queue(fp, cos) | 3180 | for_each_cos_in_tx_queue(fp, cos) |
3181 | if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) | 3181 | if (bnx2x_tx_queue_has_work(fp->txdata_ptr[cos])) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9f5e38769a29..72eef9fc883e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -12553,9 +12553,11 @@ static int bnx2x_get_phys_port_id(struct net_device *netdev, | |||
12553 | return 0; | 12553 | return 0; |
12554 | } | 12554 | } |
12555 | 12555 | ||
12556 | static bool bnx2x_gso_check(struct sk_buff *skb, struct net_device *dev) | 12556 | static netdev_features_t bnx2x_features_check(struct sk_buff *skb, |
12557 | struct net_device *dev, | ||
12558 | netdev_features_t features) | ||
12557 | { | 12559 | { |
12558 | return vxlan_gso_check(skb); | 12560 | return vxlan_features_check(skb, features); |
12559 | } | 12561 | } |
12560 | 12562 | ||
12561 | static const struct net_device_ops bnx2x_netdev_ops = { | 12563 | static const struct net_device_ops bnx2x_netdev_ops = { |
@@ -12589,7 +12591,7 @@ static const struct net_device_ops bnx2x_netdev_ops = { | |||
12589 | #endif | 12591 | #endif |
12590 | .ndo_get_phys_port_id = bnx2x_get_phys_port_id, | 12592 | .ndo_get_phys_port_id = bnx2x_get_phys_port_id, |
12591 | .ndo_set_vf_link_state = bnx2x_set_vf_link_state, | 12593 | .ndo_set_vf_link_state = bnx2x_set_vf_link_state, |
12592 | .ndo_gso_check = bnx2x_gso_check, | 12594 | .ndo_features_check = bnx2x_features_check, |
12593 | }; | 12595 | }; |
12594 | 12596 | ||
12595 | static int bnx2x_set_coherency_mask(struct bnx2x *bp) | 12597 | static int bnx2x_set_coherency_mask(struct bnx2x *bp) |
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index bb48a610b72a..96bf01ba32dd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -7413,6 +7413,8 @@ static inline void tg3_netif_start(struct tg3 *tp) | |||
7413 | } | 7413 | } |
7414 | 7414 | ||
7415 | static void tg3_irq_quiesce(struct tg3 *tp) | 7415 | static void tg3_irq_quiesce(struct tg3 *tp) |
7416 | __releases(tp->lock) | ||
7417 | __acquires(tp->lock) | ||
7416 | { | 7418 | { |
7417 | int i; | 7419 | int i; |
7418 | 7420 | ||
@@ -7421,8 +7423,12 @@ static void tg3_irq_quiesce(struct tg3 *tp) | |||
7421 | tp->irq_sync = 1; | 7423 | tp->irq_sync = 1; |
7422 | smp_mb(); | 7424 | smp_mb(); |
7423 | 7425 | ||
7426 | spin_unlock_bh(&tp->lock); | ||
7427 | |||
7424 | for (i = 0; i < tp->irq_cnt; i++) | 7428 | for (i = 0; i < tp->irq_cnt; i++) |
7425 | synchronize_irq(tp->napi[i].irq_vec); | 7429 | synchronize_irq(tp->napi[i].irq_vec); |
7430 | |||
7431 | spin_lock_bh(&tp->lock); | ||
7426 | } | 7432 | } |
7427 | 7433 | ||
7428 | /* Fully shutdown all tg3 driver activity elsewhere in the system. | 7434 | /* Fully shutdown all tg3 driver activity elsewhere in the system. |
@@ -9018,6 +9024,8 @@ static void tg3_restore_clk(struct tg3 *tp) | |||
9018 | 9024 | ||
9019 | /* tp->lock is held. */ | 9025 | /* tp->lock is held. */ |
9020 | static int tg3_chip_reset(struct tg3 *tp) | 9026 | static int tg3_chip_reset(struct tg3 *tp) |
9027 | __releases(tp->lock) | ||
9028 | __acquires(tp->lock) | ||
9021 | { | 9029 | { |
9022 | u32 val; | 9030 | u32 val; |
9023 | void (*write_op)(struct tg3 *, u32, u32); | 9031 | void (*write_op)(struct tg3 *, u32, u32); |
@@ -9073,9 +9081,13 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
9073 | } | 9081 | } |
9074 | smp_mb(); | 9082 | smp_mb(); |
9075 | 9083 | ||
9084 | tg3_full_unlock(tp); | ||
9085 | |||
9076 | for (i = 0; i < tp->irq_cnt; i++) | 9086 | for (i = 0; i < tp->irq_cnt; i++) |
9077 | synchronize_irq(tp->napi[i].irq_vec); | 9087 | synchronize_irq(tp->napi[i].irq_vec); |
9078 | 9088 | ||
9089 | tg3_full_lock(tp, 0); | ||
9090 | |||
9079 | if (tg3_asic_rev(tp) == ASIC_REV_57780) { | 9091 | if (tg3_asic_rev(tp) == ASIC_REV_57780) { |
9080 | val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; | 9092 | val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN; |
9081 | tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); | 9093 | tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS); |
@@ -10903,11 +10915,13 @@ static void tg3_timer(unsigned long __opaque) | |||
10903 | { | 10915 | { |
10904 | struct tg3 *tp = (struct tg3 *) __opaque; | 10916 | struct tg3 *tp = (struct tg3 *) __opaque; |
10905 | 10917 | ||
10906 | if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) | ||
10907 | goto restart_timer; | ||
10908 | |||
10909 | spin_lock(&tp->lock); | 10918 | spin_lock(&tp->lock); |
10910 | 10919 | ||
10920 | if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING)) { | ||
10921 | spin_unlock(&tp->lock); | ||
10922 | goto restart_timer; | ||
10923 | } | ||
10924 | |||
10911 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || | 10925 | if (tg3_asic_rev(tp) == ASIC_REV_5717 || |
10912 | tg3_flag(tp, 57765_CLASS)) | 10926 | tg3_flag(tp, 57765_CLASS)) |
10913 | tg3_chk_missed_msi(tp); | 10927 | tg3_chk_missed_msi(tp); |
@@ -11101,11 +11115,13 @@ static void tg3_reset_task(struct work_struct *work) | |||
11101 | struct tg3 *tp = container_of(work, struct tg3, reset_task); | 11115 | struct tg3 *tp = container_of(work, struct tg3, reset_task); |
11102 | int err; | 11116 | int err; |
11103 | 11117 | ||
11118 | rtnl_lock(); | ||
11104 | tg3_full_lock(tp, 0); | 11119 | tg3_full_lock(tp, 0); |
11105 | 11120 | ||
11106 | if (!netif_running(tp->dev)) { | 11121 | if (!netif_running(tp->dev)) { |
11107 | tg3_flag_clear(tp, RESET_TASK_PENDING); | 11122 | tg3_flag_clear(tp, RESET_TASK_PENDING); |
11108 | tg3_full_unlock(tp); | 11123 | tg3_full_unlock(tp); |
11124 | rtnl_unlock(); | ||
11109 | return; | 11125 | return; |
11110 | } | 11126 | } |
11111 | 11127 | ||
@@ -11138,6 +11154,7 @@ out: | |||
11138 | tg3_phy_start(tp); | 11154 | tg3_phy_start(tp); |
11139 | 11155 | ||
11140 | tg3_flag_clear(tp, RESET_TASK_PENDING); | 11156 | tg3_flag_clear(tp, RESET_TASK_PENDING); |
11157 | rtnl_unlock(); | ||
11141 | } | 11158 | } |
11142 | 11159 | ||
11143 | static int tg3_request_irq(struct tg3 *tp, int irq_num) | 11160 | static int tg3_request_irq(struct tg3 *tp, int irq_num) |
@@ -17800,23 +17817,6 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
17800 | goto err_out_apeunmap; | 17817 | goto err_out_apeunmap; |
17801 | } | 17818 | } |
17802 | 17819 | ||
17803 | /* | ||
17804 | * Reset chip in case UNDI or EFI driver did not shutdown | ||
17805 | * DMA self test will enable WDMAC and we'll see (spurious) | ||
17806 | * pending DMA on the PCI bus at that point. | ||
17807 | */ | ||
17808 | if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || | ||
17809 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | ||
17810 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | ||
17811 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
17812 | } | ||
17813 | |||
17814 | err = tg3_test_dma(tp); | ||
17815 | if (err) { | ||
17816 | dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); | ||
17817 | goto err_out_apeunmap; | ||
17818 | } | ||
17819 | |||
17820 | intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; | 17820 | intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; |
17821 | rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; | 17821 | rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; |
17822 | sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; | 17822 | sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; |
@@ -17861,6 +17861,23 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
17861 | sndmbx += 0xc; | 17861 | sndmbx += 0xc; |
17862 | } | 17862 | } |
17863 | 17863 | ||
17864 | /* | ||
17865 | * Reset chip in case UNDI or EFI driver did not shutdown | ||
17866 | * DMA self test will enable WDMAC and we'll see (spurious) | ||
17867 | * pending DMA on the PCI bus at that point. | ||
17868 | */ | ||
17869 | if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) || | ||
17870 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | ||
17871 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | ||
17872 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
17873 | } | ||
17874 | |||
17875 | err = tg3_test_dma(tp); | ||
17876 | if (err) { | ||
17877 | dev_err(&pdev->dev, "DMA engine test failed, aborting\n"); | ||
17878 | goto err_out_apeunmap; | ||
17879 | } | ||
17880 | |||
17864 | tg3_init_coal(tp); | 17881 | tg3_init_coal(tp); |
17865 | 17882 | ||
17866 | pci_set_drvdata(pdev, dev); | 17883 | pci_set_drvdata(pdev, dev); |
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 7d6aa8c87df8..619083a860a4 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c | |||
@@ -172,7 +172,7 @@ bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len) | |||
172 | 172 | ||
173 | /* Retrieve flash partition info */ | 173 | /* Retrieve flash partition info */ |
174 | fcomp.comp_status = 0; | 174 | fcomp.comp_status = 0; |
175 | init_completion(&fcomp.comp); | 175 | reinit_completion(&fcomp.comp); |
176 | spin_lock_irqsave(&bnad->bna_lock, flags); | 176 | spin_lock_irqsave(&bnad->bna_lock, flags); |
177 | ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr, | 177 | ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr, |
178 | bnad_cb_completion, &fcomp); | 178 | bnad_cb_completion, &fcomp); |
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 55eb7f2af2b4..7ef55f5fa664 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c | |||
@@ -340,7 +340,7 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
340 | res = PTR_ERR(lp->pclk); | 340 | res = PTR_ERR(lp->pclk); |
341 | goto err_free_dev; | 341 | goto err_free_dev; |
342 | } | 342 | } |
343 | clk_enable(lp->pclk); | 343 | clk_prepare_enable(lp->pclk); |
344 | 344 | ||
345 | lp->hclk = ERR_PTR(-ENOENT); | 345 | lp->hclk = ERR_PTR(-ENOENT); |
346 | lp->tx_clk = ERR_PTR(-ENOENT); | 346 | lp->tx_clk = ERR_PTR(-ENOENT); |
@@ -406,7 +406,7 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
406 | err_out_unregister_netdev: | 406 | err_out_unregister_netdev: |
407 | unregister_netdev(dev); | 407 | unregister_netdev(dev); |
408 | err_disable_clock: | 408 | err_disable_clock: |
409 | clk_disable(lp->pclk); | 409 | clk_disable_unprepare(lp->pclk); |
410 | err_free_dev: | 410 | err_free_dev: |
411 | free_netdev(dev); | 411 | free_netdev(dev); |
412 | return res; | 412 | return res; |
@@ -424,7 +424,7 @@ static int at91ether_remove(struct platform_device *pdev) | |||
424 | kfree(lp->mii_bus->irq); | 424 | kfree(lp->mii_bus->irq); |
425 | mdiobus_free(lp->mii_bus); | 425 | mdiobus_free(lp->mii_bus); |
426 | unregister_netdev(dev); | 426 | unregister_netdev(dev); |
427 | clk_disable(lp->pclk); | 427 | clk_disable_unprepare(lp->pclk); |
428 | free_netdev(dev); | 428 | free_netdev(dev); |
429 | 429 | ||
430 | return 0; | 430 | return 0; |
@@ -440,7 +440,7 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
440 | netif_stop_queue(net_dev); | 440 | netif_stop_queue(net_dev); |
441 | netif_device_detach(net_dev); | 441 | netif_device_detach(net_dev); |
442 | 442 | ||
443 | clk_disable(lp->pclk); | 443 | clk_disable_unprepare(lp->pclk); |
444 | } | 444 | } |
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
@@ -451,7 +451,7 @@ static int at91ether_resume(struct platform_device *pdev) | |||
451 | struct macb *lp = netdev_priv(net_dev); | 451 | struct macb *lp = netdev_priv(net_dev); |
452 | 452 | ||
453 | if (netif_running(net_dev)) { | 453 | if (netif_running(net_dev)) { |
454 | clk_enable(lp->pclk); | 454 | clk_prepare_enable(lp->pclk); |
455 | 455 | ||
456 | netif_device_attach(net_dev); | 456 | netif_device_attach(net_dev); |
457 | netif_start_queue(net_dev); | 457 | netif_start_queue(net_dev); |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h index d00a751f0588..6049f70e110c 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | |||
@@ -96,6 +96,9 @@ struct port_info { | |||
96 | s16 xact_addr_filt; /* index of our MAC address filter */ | 96 | s16 xact_addr_filt; /* index of our MAC address filter */ |
97 | u16 rss_size; /* size of VI's RSS table slice */ | 97 | u16 rss_size; /* size of VI's RSS table slice */ |
98 | u8 pidx; /* index into adapter port[] */ | 98 | u8 pidx; /* index into adapter port[] */ |
99 | s8 mdio_addr; | ||
100 | u8 port_type; /* firmware port type */ | ||
101 | u8 mod_type; /* firmware module type */ | ||
99 | u8 port_id; /* physical port ID */ | 102 | u8 port_id; /* physical port ID */ |
100 | u8 nqsets; /* # of "Queue Sets" */ | 103 | u8 nqsets; /* # of "Queue Sets" */ |
101 | u8 first_qset; /* index of first "Queue Set" */ | 104 | u8 first_qset; /* index of first "Queue Set" */ |
@@ -522,6 +525,7 @@ static inline struct adapter *netdev2adap(const struct net_device *dev) | |||
522 | * is "contracted" to provide for the common code. | 525 | * is "contracted" to provide for the common code. |
523 | */ | 526 | */ |
524 | void t4vf_os_link_changed(struct adapter *, int, int); | 527 | void t4vf_os_link_changed(struct adapter *, int, int); |
528 | void t4vf_os_portmod_changed(struct adapter *, int); | ||
525 | 529 | ||
526 | /* | 530 | /* |
527 | * SGE function prototype declarations. | 531 | * SGE function prototype declarations. |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index aa74ec34a467..a936ee8958c7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/etherdevice.h> | 44 | #include <linux/etherdevice.h> |
45 | #include <linux/debugfs.h> | 45 | #include <linux/debugfs.h> |
46 | #include <linux/ethtool.h> | 46 | #include <linux/ethtool.h> |
47 | #include <linux/mdio.h> | ||
47 | 48 | ||
48 | #include "t4vf_common.h" | 49 | #include "t4vf_common.h" |
49 | #include "t4vf_defs.h" | 50 | #include "t4vf_defs.h" |
@@ -210,6 +211,38 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok) | |||
210 | } | 211 | } |
211 | 212 | ||
212 | /* | 213 | /* |
214 | * THe port module type has changed on the indicated "port" (Virtual | ||
215 | * Interface). | ||
216 | */ | ||
217 | void t4vf_os_portmod_changed(struct adapter *adapter, int pidx) | ||
218 | { | ||
219 | static const char * const mod_str[] = { | ||
220 | NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM" | ||
221 | }; | ||
222 | const struct net_device *dev = adapter->port[pidx]; | ||
223 | const struct port_info *pi = netdev_priv(dev); | ||
224 | |||
225 | if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) | ||
226 | dev_info(adapter->pdev_dev, "%s: port module unplugged\n", | ||
227 | dev->name); | ||
228 | else if (pi->mod_type < ARRAY_SIZE(mod_str)) | ||
229 | dev_info(adapter->pdev_dev, "%s: %s port module inserted\n", | ||
230 | dev->name, mod_str[pi->mod_type]); | ||
231 | else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED) | ||
232 | dev_info(adapter->pdev_dev, "%s: unsupported optical port " | ||
233 | "module inserted\n", dev->name); | ||
234 | else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) | ||
235 | dev_info(adapter->pdev_dev, "%s: unknown port module inserted," | ||
236 | "forcing TWINAX\n", dev->name); | ||
237 | else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR) | ||
238 | dev_info(adapter->pdev_dev, "%s: transceiver module error\n", | ||
239 | dev->name); | ||
240 | else | ||
241 | dev_info(adapter->pdev_dev, "%s: unknown module type %d " | ||
242 | "inserted\n", dev->name, pi->mod_type); | ||
243 | } | ||
244 | |||
245 | /* | ||
213 | * Net device operations. | 246 | * Net device operations. |
214 | * ====================== | 247 | * ====================== |
215 | */ | 248 | */ |
@@ -1193,24 +1226,103 @@ static void cxgb4vf_poll_controller(struct net_device *dev) | |||
1193 | * state of the port to which we're linked. | 1226 | * state of the port to which we're linked. |
1194 | */ | 1227 | */ |
1195 | 1228 | ||
1196 | /* | 1229 | static unsigned int t4vf_from_fw_linkcaps(enum fw_port_type type, |
1197 | * Return current port link settings. | 1230 | unsigned int caps) |
1198 | */ | 1231 | { |
1199 | static int cxgb4vf_get_settings(struct net_device *dev, | 1232 | unsigned int v = 0; |
1200 | struct ethtool_cmd *cmd) | 1233 | |
1201 | { | 1234 | if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI || |
1202 | const struct port_info *pi = netdev_priv(dev); | 1235 | type == FW_PORT_TYPE_BT_XAUI) { |
1236 | v |= SUPPORTED_TP; | ||
1237 | if (caps & FW_PORT_CAP_SPEED_100M) | ||
1238 | v |= SUPPORTED_100baseT_Full; | ||
1239 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
1240 | v |= SUPPORTED_1000baseT_Full; | ||
1241 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
1242 | v |= SUPPORTED_10000baseT_Full; | ||
1243 | } else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) { | ||
1244 | v |= SUPPORTED_Backplane; | ||
1245 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
1246 | v |= SUPPORTED_1000baseKX_Full; | ||
1247 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
1248 | v |= SUPPORTED_10000baseKX4_Full; | ||
1249 | } else if (type == FW_PORT_TYPE_KR) | ||
1250 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full; | ||
1251 | else if (type == FW_PORT_TYPE_BP_AP) | ||
1252 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
1253 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full; | ||
1254 | else if (type == FW_PORT_TYPE_BP4_AP) | ||
1255 | v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC | | ||
1256 | SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full | | ||
1257 | SUPPORTED_10000baseKX4_Full; | ||
1258 | else if (type == FW_PORT_TYPE_FIBER_XFI || | ||
1259 | type == FW_PORT_TYPE_FIBER_XAUI || | ||
1260 | type == FW_PORT_TYPE_SFP || | ||
1261 | type == FW_PORT_TYPE_QSFP_10G || | ||
1262 | type == FW_PORT_TYPE_QSA) { | ||
1263 | v |= SUPPORTED_FIBRE; | ||
1264 | if (caps & FW_PORT_CAP_SPEED_1G) | ||
1265 | v |= SUPPORTED_1000baseT_Full; | ||
1266 | if (caps & FW_PORT_CAP_SPEED_10G) | ||
1267 | v |= SUPPORTED_10000baseT_Full; | ||
1268 | } else if (type == FW_PORT_TYPE_BP40_BA || | ||
1269 | type == FW_PORT_TYPE_QSFP) { | ||
1270 | v |= SUPPORTED_40000baseSR4_Full; | ||
1271 | v |= SUPPORTED_FIBRE; | ||
1272 | } | ||
1273 | |||
1274 | if (caps & FW_PORT_CAP_ANEG) | ||
1275 | v |= SUPPORTED_Autoneg; | ||
1276 | return v; | ||
1277 | } | ||
1278 | |||
1279 | static int cxgb4vf_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1280 | { | ||
1281 | const struct port_info *p = netdev_priv(dev); | ||
1282 | |||
1283 | if (p->port_type == FW_PORT_TYPE_BT_SGMII || | ||
1284 | p->port_type == FW_PORT_TYPE_BT_XFI || | ||
1285 | p->port_type == FW_PORT_TYPE_BT_XAUI) | ||
1286 | cmd->port = PORT_TP; | ||
1287 | else if (p->port_type == FW_PORT_TYPE_FIBER_XFI || | ||
1288 | p->port_type == FW_PORT_TYPE_FIBER_XAUI) | ||
1289 | cmd->port = PORT_FIBRE; | ||
1290 | else if (p->port_type == FW_PORT_TYPE_SFP || | ||
1291 | p->port_type == FW_PORT_TYPE_QSFP_10G || | ||
1292 | p->port_type == FW_PORT_TYPE_QSA || | ||
1293 | p->port_type == FW_PORT_TYPE_QSFP) { | ||
1294 | if (p->mod_type == FW_PORT_MOD_TYPE_LR || | ||
1295 | p->mod_type == FW_PORT_MOD_TYPE_SR || | ||
1296 | p->mod_type == FW_PORT_MOD_TYPE_ER || | ||
1297 | p->mod_type == FW_PORT_MOD_TYPE_LRM) | ||
1298 | cmd->port = PORT_FIBRE; | ||
1299 | else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE || | ||
1300 | p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE) | ||
1301 | cmd->port = PORT_DA; | ||
1302 | else | ||
1303 | cmd->port = PORT_OTHER; | ||
1304 | } else | ||
1305 | cmd->port = PORT_OTHER; | ||
1203 | 1306 | ||
1204 | cmd->supported = pi->link_cfg.supported; | 1307 | if (p->mdio_addr >= 0) { |
1205 | cmd->advertising = pi->link_cfg.advertising; | 1308 | cmd->phy_address = p->mdio_addr; |
1309 | cmd->transceiver = XCVR_EXTERNAL; | ||
1310 | cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ? | ||
1311 | MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45; | ||
1312 | } else { | ||
1313 | cmd->phy_address = 0; /* not really, but no better option */ | ||
1314 | cmd->transceiver = XCVR_INTERNAL; | ||
1315 | cmd->mdio_support = 0; | ||
1316 | } | ||
1317 | |||
1318 | cmd->supported = t4vf_from_fw_linkcaps(p->port_type, | ||
1319 | p->link_cfg.supported); | ||
1320 | cmd->advertising = t4vf_from_fw_linkcaps(p->port_type, | ||
1321 | p->link_cfg.advertising); | ||
1206 | ethtool_cmd_speed_set(cmd, | 1322 | ethtool_cmd_speed_set(cmd, |
1207 | netif_carrier_ok(dev) ? pi->link_cfg.speed : -1); | 1323 | netif_carrier_ok(dev) ? p->link_cfg.speed : 0); |
1208 | cmd->duplex = DUPLEX_FULL; | 1324 | cmd->duplex = DUPLEX_FULL; |
1209 | 1325 | cmd->autoneg = p->link_cfg.autoneg; | |
1210 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; | ||
1211 | cmd->phy_address = pi->port_id; | ||
1212 | cmd->transceiver = XCVR_EXTERNAL; | ||
1213 | cmd->autoneg = pi->link_cfg.autoneg; | ||
1214 | cmd->maxtxpkt = 0; | 1326 | cmd->maxtxpkt = 0; |
1215 | cmd->maxrxpkt = 0; | 1327 | cmd->maxrxpkt = 0; |
1216 | return 0; | 1328 | return 0; |
@@ -2318,7 +2430,7 @@ static void cfg_queues(struct adapter *adapter) | |||
2318 | */ | 2430 | */ |
2319 | n10g = 0; | 2431 | n10g = 0; |
2320 | for_each_port(adapter, pidx) | 2432 | for_each_port(adapter, pidx) |
2321 | n10g += is_10g_port(&adap2pinfo(adapter, pidx)->link_cfg); | 2433 | n10g += is_x_10g_port(&adap2pinfo(adapter, pidx)->link_cfg); |
2322 | 2434 | ||
2323 | /* | 2435 | /* |
2324 | * We default to 1 queue per non-10G port and up to # of cores queues | 2436 | * We default to 1 queue per non-10G port and up to # of cores queues |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h index 8d3237f5e364..b9debb4f29a3 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | |||
@@ -230,7 +230,7 @@ struct adapter_params { | |||
230 | 230 | ||
231 | static inline bool is_10g_port(const struct link_config *lc) | 231 | static inline bool is_10g_port(const struct link_config *lc) |
232 | { | 232 | { |
233 | return (lc->supported & SUPPORTED_10000baseT_Full) != 0; | 233 | return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0; |
234 | } | 234 | } |
235 | 235 | ||
236 | static inline bool is_x_10g_port(const struct link_config *lc) | 236 | static inline bool is_x_10g_port(const struct link_config *lc) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c index 02e8833b7797..60426cf890a7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | |||
@@ -245,6 +245,10 @@ static int hash_mac_addr(const u8 *addr) | |||
245 | return a & 0x3f; | 245 | return a & 0x3f; |
246 | } | 246 | } |
247 | 247 | ||
248 | #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | ||
249 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ | ||
250 | FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG) | ||
251 | |||
248 | /** | 252 | /** |
249 | * init_link_config - initialize a link's SW state | 253 | * init_link_config - initialize a link's SW state |
250 | * @lc: structure holding the link state | 254 | * @lc: structure holding the link state |
@@ -259,8 +263,8 @@ static void init_link_config(struct link_config *lc, unsigned int caps) | |||
259 | lc->requested_speed = 0; | 263 | lc->requested_speed = 0; |
260 | lc->speed = 0; | 264 | lc->speed = 0; |
261 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; | 265 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; |
262 | if (lc->supported & SUPPORTED_Autoneg) { | 266 | if (lc->supported & FW_PORT_CAP_ANEG) { |
263 | lc->advertising = lc->supported; | 267 | lc->advertising = lc->supported & ADVERT_MASK; |
264 | lc->autoneg = AUTONEG_ENABLE; | 268 | lc->autoneg = AUTONEG_ENABLE; |
265 | lc->requested_fc |= PAUSE_AUTONEG; | 269 | lc->requested_fc |= PAUSE_AUTONEG; |
266 | } else { | 270 | } else { |
@@ -280,7 +284,6 @@ int t4vf_port_init(struct adapter *adapter, int pidx) | |||
280 | struct fw_vi_cmd vi_cmd, vi_rpl; | 284 | struct fw_vi_cmd vi_cmd, vi_rpl; |
281 | struct fw_port_cmd port_cmd, port_rpl; | 285 | struct fw_port_cmd port_cmd, port_rpl; |
282 | int v; | 286 | int v; |
283 | u32 word; | ||
284 | 287 | ||
285 | /* | 288 | /* |
286 | * Execute a VI Read command to get our Virtual Interface information | 289 | * Execute a VI Read command to get our Virtual Interface information |
@@ -319,19 +322,13 @@ int t4vf_port_init(struct adapter *adapter, int pidx) | |||
319 | if (v) | 322 | if (v) |
320 | return v; | 323 | return v; |
321 | 324 | ||
322 | v = 0; | 325 | v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype); |
323 | word = be16_to_cpu(port_rpl.u.info.pcap); | 326 | pi->mdio_addr = (v & FW_PORT_CMD_MDIOCAP_F) ? |
324 | if (word & FW_PORT_CAP_SPEED_100M) | 327 | FW_PORT_CMD_MDIOADDR_G(v) : -1; |
325 | v |= SUPPORTED_100baseT_Full; | 328 | pi->port_type = FW_PORT_CMD_PTYPE_G(v); |
326 | if (word & FW_PORT_CAP_SPEED_1G) | 329 | pi->mod_type = FW_PORT_MOD_TYPE_NA; |
327 | v |= SUPPORTED_1000baseT_Full; | 330 | |
328 | if (word & FW_PORT_CAP_SPEED_10G) | 331 | init_link_config(&pi->link_cfg, be16_to_cpu(port_rpl.u.info.pcap)); |
329 | v |= SUPPORTED_10000baseT_Full; | ||
330 | if (word & FW_PORT_CAP_SPEED_40G) | ||
331 | v |= SUPPORTED_40000baseSR4_Full; | ||
332 | if (word & FW_PORT_CAP_ANEG) | ||
333 | v |= SUPPORTED_Autoneg; | ||
334 | init_link_config(&pi->link_cfg, v); | ||
335 | 332 | ||
336 | return 0; | 333 | return 0; |
337 | } | 334 | } |
@@ -1491,7 +1488,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
1491 | */ | 1488 | */ |
1492 | const struct fw_port_cmd *port_cmd = | 1489 | const struct fw_port_cmd *port_cmd = |
1493 | (const struct fw_port_cmd *)rpl; | 1490 | (const struct fw_port_cmd *)rpl; |
1494 | u32 word; | 1491 | u32 stat, mod; |
1495 | int action, port_id, link_ok, speed, fc, pidx; | 1492 | int action, port_id, link_ok, speed, fc, pidx; |
1496 | 1493 | ||
1497 | /* | 1494 | /* |
@@ -1509,21 +1506,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
1509 | port_id = FW_PORT_CMD_PORTID_G( | 1506 | port_id = FW_PORT_CMD_PORTID_G( |
1510 | be32_to_cpu(port_cmd->op_to_portid)); | 1507 | be32_to_cpu(port_cmd->op_to_portid)); |
1511 | 1508 | ||
1512 | word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); | 1509 | stat = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype); |
1513 | link_ok = (word & FW_PORT_CMD_LSTATUS_F) != 0; | 1510 | link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0; |
1514 | speed = 0; | 1511 | speed = 0; |
1515 | fc = 0; | 1512 | fc = 0; |
1516 | if (word & FW_PORT_CMD_RXPAUSE_F) | 1513 | if (stat & FW_PORT_CMD_RXPAUSE_F) |
1517 | fc |= PAUSE_RX; | 1514 | fc |= PAUSE_RX; |
1518 | if (word & FW_PORT_CMD_TXPAUSE_F) | 1515 | if (stat & FW_PORT_CMD_TXPAUSE_F) |
1519 | fc |= PAUSE_TX; | 1516 | fc |= PAUSE_TX; |
1520 | if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) | 1517 | if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) |
1521 | speed = 100; | 1518 | speed = 100; |
1522 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) | 1519 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) |
1523 | speed = 1000; | 1520 | speed = 1000; |
1524 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) | 1521 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) |
1525 | speed = 10000; | 1522 | speed = 10000; |
1526 | else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) | 1523 | else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) |
1527 | speed = 40000; | 1524 | speed = 40000; |
1528 | 1525 | ||
1529 | /* | 1526 | /* |
@@ -1540,12 +1537,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl) | |||
1540 | continue; | 1537 | continue; |
1541 | 1538 | ||
1542 | lc = &pi->link_cfg; | 1539 | lc = &pi->link_cfg; |
1540 | |||
1541 | mod = FW_PORT_CMD_MODTYPE_G(stat); | ||
1542 | if (mod != pi->mod_type) { | ||
1543 | pi->mod_type = mod; | ||
1544 | t4vf_os_portmod_changed(adapter, pidx); | ||
1545 | } | ||
1546 | |||
1543 | if (link_ok != lc->link_ok || speed != lc->speed || | 1547 | if (link_ok != lc->link_ok || speed != lc->speed || |
1544 | fc != lc->fc) { | 1548 | fc != lc->fc) { |
1545 | /* something changed */ | 1549 | /* something changed */ |
1546 | lc->link_ok = link_ok; | 1550 | lc->link_ok = link_ok; |
1547 | lc->speed = speed; | 1551 | lc->speed = speed; |
1548 | lc->fc = fc; | 1552 | lc->fc = fc; |
1553 | lc->supported = | ||
1554 | be16_to_cpu(port_cmd->u.info.pcap); | ||
1549 | t4vf_os_link_changed(adapter, pidx, link_ok); | 1555 | t4vf_os_link_changed(adapter, pidx, link_ok); |
1550 | } | 1556 | } |
1551 | } | 1557 | } |
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 868d0f605d60..e356afa44e7d 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -1060,10 +1060,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, | |||
1060 | PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); | 1060 | PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) { | 1063 | /* Hardware does not provide whole packet checksum. It only |
1064 | skb->csum = htons(checksum); | 1064 | * provides pseudo checksum. Since hw validates the packet |
1065 | skb->ip_summed = CHECKSUM_COMPLETE; | 1065 | * checksum but not provide us the checksum value. use |
1066 | } | 1066 | * CHECSUM_UNNECESSARY. |
1067 | */ | ||
1068 | if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok && | ||
1069 | ipv4_csum_ok) | ||
1070 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1067 | 1071 | ||
1068 | if (vlan_stripped) | 1072 | if (vlan_stripped) |
1069 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); | 1073 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); |
@@ -1331,7 +1335,7 @@ static int enic_poll_msix_rq(struct napi_struct *napi, int budget) | |||
1331 | int err; | 1335 | int err; |
1332 | 1336 | ||
1333 | if (!enic_poll_lock_napi(&enic->rq[rq])) | 1337 | if (!enic_poll_lock_napi(&enic->rq[rq])) |
1334 | return work_done; | 1338 | return budget; |
1335 | /* Service RQ | 1339 | /* Service RQ |
1336 | */ | 1340 | */ |
1337 | 1341 | ||
@@ -1612,7 +1616,7 @@ static int enic_open(struct net_device *netdev) | |||
1612 | if (vnic_rq_desc_used(&enic->rq[i]) == 0) { | 1616 | if (vnic_rq_desc_used(&enic->rq[i]) == 0) { |
1613 | netdev_err(netdev, "Unable to alloc receive buffers\n"); | 1617 | netdev_err(netdev, "Unable to alloc receive buffers\n"); |
1614 | err = -ENOMEM; | 1618 | err = -ENOMEM; |
1615 | goto err_out_notify_unset; | 1619 | goto err_out_free_rq; |
1616 | } | 1620 | } |
1617 | } | 1621 | } |
1618 | 1622 | ||
@@ -1645,7 +1649,9 @@ static int enic_open(struct net_device *netdev) | |||
1645 | 1649 | ||
1646 | return 0; | 1650 | return 0; |
1647 | 1651 | ||
1648 | err_out_notify_unset: | 1652 | err_out_free_rq: |
1653 | for (i = 0; i < enic->rq_count; i++) | ||
1654 | vnic_rq_clean(&enic->rq[i], enic_free_rq_buf); | ||
1649 | enic_dev_notify_unset(enic); | 1655 | enic_dev_notify_unset(enic); |
1650 | err_out_free_intr: | 1656 | err_out_free_intr: |
1651 | enic_free_intr(enic); | 1657 | enic_free_intr(enic); |
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index a379c3e4b57f..13d00a38a5bd 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c | |||
@@ -398,13 +398,8 @@ static int dnet_poll(struct napi_struct *napi, int budget) | |||
398 | * break out of while loop if there are no more | 398 | * break out of while loop if there are no more |
399 | * packets waiting | 399 | * packets waiting |
400 | */ | 400 | */ |
401 | if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) { | 401 | if (!(dnet_readl(bp, RX_FIFO_WCNT) >> 16)) |
402 | napi_complete(napi); | 402 | break; |
403 | int_enable = dnet_readl(bp, INTR_ENB); | ||
404 | int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; | ||
405 | dnet_writel(bp, int_enable, INTR_ENB); | ||
406 | return 0; | ||
407 | } | ||
408 | 403 | ||
409 | cmd_word = dnet_readl(bp, RX_LEN_FIFO); | 404 | cmd_word = dnet_readl(bp, RX_LEN_FIFO); |
410 | pkt_len = cmd_word & 0xFFFF; | 405 | pkt_len = cmd_word & 0xFFFF; |
@@ -433,20 +428,17 @@ static int dnet_poll(struct napi_struct *napi, int budget) | |||
433 | "size %u.\n", dev->name, pkt_len); | 428 | "size %u.\n", dev->name, pkt_len); |
434 | } | 429 | } |
435 | 430 | ||
436 | budget -= npackets; | ||
437 | |||
438 | if (npackets < budget) { | 431 | if (npackets < budget) { |
439 | /* We processed all packets available. Tell NAPI it can | 432 | /* We processed all packets available. Tell NAPI it can |
440 | * stop polling then re-enable rx interrupts */ | 433 | * stop polling then re-enable rx interrupts. |
434 | */ | ||
441 | napi_complete(napi); | 435 | napi_complete(napi); |
442 | int_enable = dnet_readl(bp, INTR_ENB); | 436 | int_enable = dnet_readl(bp, INTR_ENB); |
443 | int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; | 437 | int_enable |= DNET_INTR_SRC_RX_CMDFIFOAF; |
444 | dnet_writel(bp, int_enable, INTR_ENB); | 438 | dnet_writel(bp, int_enable, INTR_ENB); |
445 | return 0; | ||
446 | } | 439 | } |
447 | 440 | ||
448 | /* There are still packets waiting */ | 441 | return npackets; |
449 | return 1; | ||
450 | } | 442 | } |
451 | 443 | ||
452 | static irqreturn_t dnet_interrupt(int irq, void *dev_id) | 444 | static irqreturn_t dnet_interrupt(int irq, void *dev_id) |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 196073110e32..d48806b5cd88 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -4383,8 +4383,9 @@ static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, | |||
4383 | * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload | 4383 | * distinguish various types of transports (VxLAN, GRE, NVGRE ..). So, offload |
4384 | * is expected to work across all types of IP tunnels once exported. Skyhawk | 4384 | * is expected to work across all types of IP tunnels once exported. Skyhawk |
4385 | * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN | 4385 | * supports offloads for either VxLAN or NVGRE, exclusively. So we export VxLAN |
4386 | * offloads in hw_enc_features only when a VxLAN port is added. Note this only | 4386 | * offloads in hw_enc_features only when a VxLAN port is added. If other (non |
4387 | * ensures that other tunnels work fine while VxLAN offloads are not enabled. | 4387 | * VxLAN) tunnels are configured while VxLAN offloads are enabled, offloads for |
4388 | * those other tunnels are unexported on the fly through ndo_features_check(). | ||
4388 | * | 4389 | * |
4389 | * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack | 4390 | * Skyhawk supports VxLAN offloads only for one UDP dport. So, if the stack |
4390 | * adds more than one port, disable offloads and don't re-enable them again | 4391 | * adds more than one port, disable offloads and don't re-enable them again |
@@ -4459,9 +4460,45 @@ done: | |||
4459 | adapter->vxlan_port_count--; | 4460 | adapter->vxlan_port_count--; |
4460 | } | 4461 | } |
4461 | 4462 | ||
4462 | static bool be_gso_check(struct sk_buff *skb, struct net_device *dev) | 4463 | static netdev_features_t be_features_check(struct sk_buff *skb, |
4464 | struct net_device *dev, | ||
4465 | netdev_features_t features) | ||
4463 | { | 4466 | { |
4464 | return vxlan_gso_check(skb); | 4467 | struct be_adapter *adapter = netdev_priv(dev); |
4468 | u8 l4_hdr = 0; | ||
4469 | |||
4470 | /* The code below restricts offload features for some tunneled packets. | ||
4471 | * Offload features for normal (non tunnel) packets are unchanged. | ||
4472 | */ | ||
4473 | if (!skb->encapsulation || | ||
4474 | !(adapter->flags & BE_FLAGS_VXLAN_OFFLOADS)) | ||
4475 | return features; | ||
4476 | |||
4477 | /* It's an encapsulated packet and VxLAN offloads are enabled. We | ||
4478 | * should disable tunnel offload features if it's not a VxLAN packet, | ||
4479 | * as tunnel offloads have been enabled only for VxLAN. This is done to | ||
4480 | * allow other tunneled traffic like GRE work fine while VxLAN | ||
4481 | * offloads are configured in Skyhawk-R. | ||
4482 | */ | ||
4483 | switch (vlan_get_protocol(skb)) { | ||
4484 | case htons(ETH_P_IP): | ||
4485 | l4_hdr = ip_hdr(skb)->protocol; | ||
4486 | break; | ||
4487 | case htons(ETH_P_IPV6): | ||
4488 | l4_hdr = ipv6_hdr(skb)->nexthdr; | ||
4489 | break; | ||
4490 | default: | ||
4491 | return features; | ||
4492 | } | ||
4493 | |||
4494 | if (l4_hdr != IPPROTO_UDP || | ||
4495 | skb->inner_protocol_type != ENCAP_TYPE_ETHER || | ||
4496 | skb->inner_protocol != htons(ETH_P_TEB) || | ||
4497 | skb_inner_mac_header(skb) - skb_transport_header(skb) != | ||
4498 | sizeof(struct udphdr) + sizeof(struct vxlanhdr)) | ||
4499 | return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); | ||
4500 | |||
4501 | return features; | ||
4465 | } | 4502 | } |
4466 | #endif | 4503 | #endif |
4467 | 4504 | ||
@@ -4492,7 +4529,7 @@ static const struct net_device_ops be_netdev_ops = { | |||
4492 | #ifdef CONFIG_BE2NET_VXLAN | 4529 | #ifdef CONFIG_BE2NET_VXLAN |
4493 | .ndo_add_vxlan_port = be_add_vxlan_port, | 4530 | .ndo_add_vxlan_port = be_add_vxlan_port, |
4494 | .ndo_del_vxlan_port = be_del_vxlan_port, | 4531 | .ndo_del_vxlan_port = be_del_vxlan_port, |
4495 | .ndo_gso_check = be_gso_check, | 4532 | .ndo_features_check = be_features_check, |
4496 | #endif | 4533 | #endif |
4497 | }; | 4534 | }; |
4498 | 4535 | ||
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 469691ad4a1e..40132929daf7 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
@@ -424,6 +424,8 @@ struct bufdesc_ex { | |||
424 | * (40ns * 6). | 424 | * (40ns * 6). |
425 | */ | 425 | */ |
426 | #define FEC_QUIRK_BUG_CAPTURE (1 << 10) | 426 | #define FEC_QUIRK_BUG_CAPTURE (1 << 10) |
427 | /* Controller has only one MDIO bus */ | ||
428 | #define FEC_QUIRK_SINGLE_MDIO (1 << 11) | ||
427 | 429 | ||
428 | struct fec_enet_priv_tx_q { | 430 | struct fec_enet_priv_tx_q { |
429 | int index; | 431 | int index; |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5ebdf8dc8a31..bba87775419d 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -91,7 +91,8 @@ static struct platform_device_id fec_devtype[] = { | |||
91 | .driver_data = 0, | 91 | .driver_data = 0, |
92 | }, { | 92 | }, { |
93 | .name = "imx28-fec", | 93 | .name = "imx28-fec", |
94 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, | 94 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | |
95 | FEC_QUIRK_SINGLE_MDIO, | ||
95 | }, { | 96 | }, { |
96 | .name = "imx6q-fec", | 97 | .name = "imx6q-fec", |
97 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | | 98 | .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | |
@@ -1937,7 +1938,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
1937 | int err = -ENXIO, i; | 1938 | int err = -ENXIO, i; |
1938 | 1939 | ||
1939 | /* | 1940 | /* |
1940 | * The dual fec interfaces are not equivalent with enet-mac. | 1941 | * The i.MX28 dual fec interfaces are not equal. |
1941 | * Here are the differences: | 1942 | * Here are the differences: |
1942 | * | 1943 | * |
1943 | * - fec0 supports MII & RMII modes while fec1 only supports RMII | 1944 | * - fec0 supports MII & RMII modes while fec1 only supports RMII |
@@ -1952,7 +1953,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
1952 | * mdio interface in board design, and need to be configured by | 1953 | * mdio interface in board design, and need to be configured by |
1953 | * fec0 mii_bus. | 1954 | * fec0 mii_bus. |
1954 | */ | 1955 | */ |
1955 | if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { | 1956 | if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) { |
1956 | /* fec1 uses fec0 mii_bus */ | 1957 | /* fec1 uses fec0 mii_bus */ |
1957 | if (mii_cnt && fec0_mii_bus) { | 1958 | if (mii_cnt && fec0_mii_bus) { |
1958 | fep->mii_bus = fec0_mii_bus; | 1959 | fep->mii_bus = fec0_mii_bus; |
@@ -2015,7 +2016,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
2015 | mii_cnt++; | 2016 | mii_cnt++; |
2016 | 2017 | ||
2017 | /* save fec0 mii_bus */ | 2018 | /* save fec0 mii_bus */ |
2018 | if (fep->quirks & FEC_QUIRK_ENET_MAC) | 2019 | if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) |
2019 | fec0_mii_bus = fep->mii_bus; | 2020 | fec0_mii_bus = fep->mii_bus; |
2020 | 2021 | ||
2021 | return 0; | 2022 | return 0; |
@@ -3129,6 +3130,7 @@ fec_probe(struct platform_device *pdev) | |||
3129 | pdev->id_entry = of_id->data; | 3130 | pdev->id_entry = of_id->data; |
3130 | fep->quirks = pdev->id_entry->driver_data; | 3131 | fep->quirks = pdev->id_entry->driver_data; |
3131 | 3132 | ||
3133 | fep->netdev = ndev; | ||
3132 | fep->num_rx_queues = num_rx_qs; | 3134 | fep->num_rx_queues = num_rx_qs; |
3133 | fep->num_tx_queues = num_tx_qs; | 3135 | fep->num_tx_queues = num_tx_qs; |
3134 | 3136 | ||
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 5b8300a32bf5..4d61ef50b465 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig | |||
@@ -281,6 +281,17 @@ config I40E_DCB | |||
281 | 281 | ||
282 | If unsure, say N. | 282 | If unsure, say N. |
283 | 283 | ||
284 | config I40E_FCOE | ||
285 | bool "Fibre Channel over Ethernet (FCoE)" | ||
286 | default n | ||
287 | depends on I40E && DCB && FCOE | ||
288 | ---help--- | ||
289 | Say Y here if you want to use Fibre Channel over Ethernet (FCoE) | ||
290 | in the driver. This will create new netdev for exclusive FCoE | ||
291 | use with XL710 FCoE offloads enabled. | ||
292 | |||
293 | If unsure, say N. | ||
294 | |||
284 | config I40EVF | 295 | config I40EVF |
285 | tristate "Intel(R) XL710 X710 Virtual Function Ethernet support" | 296 | tristate "Intel(R) XL710 X710 Virtual Function Ethernet support" |
286 | depends on PCI_MSI | 297 | depends on PCI_MSI |
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 781065eb5431..e9c3a87e5b11 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c | |||
@@ -1543,7 +1543,7 @@ static int e100_phy_init(struct nic *nic) | |||
1543 | mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); | 1543 | mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); |
1544 | } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && | 1544 | } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && |
1545 | (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && | 1545 | (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && |
1546 | !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { | 1546 | (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { |
1547 | /* enable/disable MDI/MDI-X auto-switching. */ | 1547 | /* enable/disable MDI/MDI-X auto-switching. */ |
1548 | mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, | 1548 | mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, |
1549 | nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); | 1549 | nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); |
diff --git a/drivers/net/ethernet/intel/i40e/Makefile b/drivers/net/ethernet/intel/i40e/Makefile index 4b94ddb29c24..c40581999121 100644 --- a/drivers/net/ethernet/intel/i40e/Makefile +++ b/drivers/net/ethernet/intel/i40e/Makefile | |||
@@ -44,4 +44,4 @@ i40e-objs := i40e_main.o \ | |||
44 | i40e_virtchnl_pf.o | 44 | i40e_virtchnl_pf.o |
45 | 45 | ||
46 | i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o | 46 | i40e-$(CONFIG_I40E_DCB) += i40e_dcb.o i40e_dcb_nl.o |
47 | i40e-$(CONFIG_FCOE:m=y) += i40e_fcoe.o | 47 | i40e-$(CONFIG_I40E_FCOE) += i40e_fcoe.o |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 433a55886ad2..cb0de455683e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c | |||
@@ -829,7 +829,7 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, | |||
829 | if (desc_n >= ring->count || desc_n < 0) { | 829 | if (desc_n >= ring->count || desc_n < 0) { |
830 | dev_info(&pf->pdev->dev, | 830 | dev_info(&pf->pdev->dev, |
831 | "descriptor %d not found\n", desc_n); | 831 | "descriptor %d not found\n", desc_n); |
832 | return; | 832 | goto out; |
833 | } | 833 | } |
834 | if (!is_rx_ring) { | 834 | if (!is_rx_ring) { |
835 | txd = I40E_TX_DESC(ring, desc_n); | 835 | txd = I40E_TX_DESC(ring, desc_n); |
@@ -855,6 +855,8 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, | |||
855 | } else { | 855 | } else { |
856 | dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n"); | 856 | dev_info(&pf->pdev->dev, "dump desc rx/tx <vsi_seid> <ring_id> [<desc_n>]\n"); |
857 | } | 857 | } |
858 | |||
859 | out: | ||
858 | kfree(ring); | 860 | kfree(ring); |
859 | } | 861 | } |
860 | 862 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_osdep.h b/drivers/net/ethernet/intel/i40e/i40e_osdep.h index 045b5c4b98b3..ad802dd0f67a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_osdep.h +++ b/drivers/net/ethernet/intel/i40e/i40e_osdep.h | |||
@@ -78,7 +78,7 @@ do { \ | |||
78 | } while (0) | 78 | } while (0) |
79 | 79 | ||
80 | typedef enum i40e_status_code i40e_status; | 80 | typedef enum i40e_status_code i40e_status; |
81 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 81 | #ifdef CONFIG_I40E_FCOE |
82 | #define I40E_FCOE | 82 | #define I40E_FCOE |
83 | #endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */ | 83 | #endif |
84 | #endif /* _I40E_OSDEP_H_ */ | 84 | #endif /* _I40E_OSDEP_H_ */ |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 04b441460bbd..cecb340898fe 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -658,6 +658,8 @@ static inline u32 i40e_get_head(struct i40e_ring *tx_ring) | |||
658 | return le32_to_cpu(*(volatile __le32 *)head); | 658 | return le32_to_cpu(*(volatile __le32 *)head); |
659 | } | 659 | } |
660 | 660 | ||
661 | #define WB_STRIDE 0x3 | ||
662 | |||
661 | /** | 663 | /** |
662 | * i40e_clean_tx_irq - Reclaim resources after transmit completes | 664 | * i40e_clean_tx_irq - Reclaim resources after transmit completes |
663 | * @tx_ring: tx ring to clean | 665 | * @tx_ring: tx ring to clean |
@@ -759,6 +761,18 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) | |||
759 | tx_ring->q_vector->tx.total_bytes += total_bytes; | 761 | tx_ring->q_vector->tx.total_bytes += total_bytes; |
760 | tx_ring->q_vector->tx.total_packets += total_packets; | 762 | tx_ring->q_vector->tx.total_packets += total_packets; |
761 | 763 | ||
764 | /* check to see if there are any non-cache aligned descriptors | ||
765 | * waiting to be written back, and kick the hardware to force | ||
766 | * them to be written back in case of napi polling | ||
767 | */ | ||
768 | if (budget && | ||
769 | !((i & WB_STRIDE) == WB_STRIDE) && | ||
770 | !test_bit(__I40E_DOWN, &tx_ring->vsi->state) && | ||
771 | (I40E_DESC_UNUSED(tx_ring) != tx_ring->count)) | ||
772 | tx_ring->arm_wb = true; | ||
773 | else | ||
774 | tx_ring->arm_wb = false; | ||
775 | |||
762 | if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) { | 776 | if (check_for_tx_hang(tx_ring) && i40e_check_tx_hang(tx_ring)) { |
763 | /* schedule immediate reset if we believe we hung */ | 777 | /* schedule immediate reset if we believe we hung */ |
764 | dev_info(tx_ring->dev, "Detected Tx Unit Hang\n" | 778 | dev_info(tx_ring->dev, "Detected Tx Unit Hang\n" |
@@ -777,13 +791,16 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) | |||
777 | netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); | 791 | netif_stop_subqueue(tx_ring->netdev, tx_ring->queue_index); |
778 | 792 | ||
779 | dev_info(tx_ring->dev, | 793 | dev_info(tx_ring->dev, |
780 | "tx hang detected on queue %d, resetting adapter\n", | 794 | "tx hang detected on queue %d, reset requested\n", |
781 | tx_ring->queue_index); | 795 | tx_ring->queue_index); |
782 | 796 | ||
783 | tx_ring->netdev->netdev_ops->ndo_tx_timeout(tx_ring->netdev); | 797 | /* do not fire the reset immediately, wait for the stack to |
798 | * decide we are truly stuck, also prevents every queue from | ||
799 | * simultaneously requesting a reset | ||
800 | */ | ||
784 | 801 | ||
785 | /* the adapter is about to reset, no point in enabling stuff */ | 802 | /* the adapter is about to reset, no point in enabling polling */ |
786 | return true; | 803 | budget = 1; |
787 | } | 804 | } |
788 | 805 | ||
789 | netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev, | 806 | netdev_tx_completed_queue(netdev_get_tx_queue(tx_ring->netdev, |
@@ -806,7 +823,25 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget) | |||
806 | } | 823 | } |
807 | } | 824 | } |
808 | 825 | ||
809 | return budget > 0; | 826 | return !!budget; |
827 | } | ||
828 | |||
829 | /** | ||
830 | * i40e_force_wb - Arm hardware to do a wb on noncache aligned descriptors | ||
831 | * @vsi: the VSI we care about | ||
832 | * @q_vector: the vector on which to force writeback | ||
833 | * | ||
834 | **/ | ||
835 | static void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector) | ||
836 | { | ||
837 | u32 val = I40E_PFINT_DYN_CTLN_INTENA_MASK | | ||
838 | I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK | | ||
839 | I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK | ||
840 | /* allow 00 to be written to the index */; | ||
841 | |||
842 | wr32(&vsi->back->hw, | ||
843 | I40E_PFINT_DYN_CTLN(q_vector->v_idx + vsi->base_vector - 1), | ||
844 | val); | ||
810 | } | 845 | } |
811 | 846 | ||
812 | /** | 847 | /** |
@@ -1290,9 +1325,7 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
1290 | * so the total length of IPv4 header is IHL*4 bytes | 1325 | * so the total length of IPv4 header is IHL*4 bytes |
1291 | * The UDP_0 bit *may* bet set if the *inner* header is UDP | 1326 | * The UDP_0 bit *may* bet set if the *inner* header is UDP |
1292 | */ | 1327 | */ |
1293 | if (ipv4_tunnel && | 1328 | if (ipv4_tunnel) { |
1294 | (decoded.inner_prot != I40E_RX_PTYPE_INNER_PROT_UDP) && | ||
1295 | !(rx_status & (1 << I40E_RX_DESC_STATUS_UDP_0_SHIFT))) { | ||
1296 | skb->transport_header = skb->mac_header + | 1329 | skb->transport_header = skb->mac_header + |
1297 | sizeof(struct ethhdr) + | 1330 | sizeof(struct ethhdr) + |
1298 | (ip_hdr(skb)->ihl * 4); | 1331 | (ip_hdr(skb)->ihl * 4); |
@@ -1302,15 +1335,19 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
1302 | skb->protocol == htons(ETH_P_8021AD)) | 1335 | skb->protocol == htons(ETH_P_8021AD)) |
1303 | ? VLAN_HLEN : 0; | 1336 | ? VLAN_HLEN : 0; |
1304 | 1337 | ||
1305 | rx_udp_csum = udp_csum(skb); | 1338 | if ((ip_hdr(skb)->protocol == IPPROTO_UDP) && |
1306 | iph = ip_hdr(skb); | 1339 | (udp_hdr(skb)->check != 0)) { |
1307 | csum = csum_tcpudp_magic( | 1340 | rx_udp_csum = udp_csum(skb); |
1308 | iph->saddr, iph->daddr, | 1341 | iph = ip_hdr(skb); |
1309 | (skb->len - skb_transport_offset(skb)), | 1342 | csum = csum_tcpudp_magic( |
1310 | IPPROTO_UDP, rx_udp_csum); | 1343 | iph->saddr, iph->daddr, |
1344 | (skb->len - skb_transport_offset(skb)), | ||
1345 | IPPROTO_UDP, rx_udp_csum); | ||
1311 | 1346 | ||
1312 | if (udp_hdr(skb)->check != csum) | 1347 | if (udp_hdr(skb)->check != csum) |
1313 | goto checksum_fail; | 1348 | goto checksum_fail; |
1349 | |||
1350 | } /* else its GRE and so no outer UDP header */ | ||
1314 | } | 1351 | } |
1315 | 1352 | ||
1316 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1353 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -1581,6 +1618,7 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) | |||
1581 | struct i40e_vsi *vsi = q_vector->vsi; | 1618 | struct i40e_vsi *vsi = q_vector->vsi; |
1582 | struct i40e_ring *ring; | 1619 | struct i40e_ring *ring; |
1583 | bool clean_complete = true; | 1620 | bool clean_complete = true; |
1621 | bool arm_wb = false; | ||
1584 | int budget_per_ring; | 1622 | int budget_per_ring; |
1585 | 1623 | ||
1586 | if (test_bit(__I40E_DOWN, &vsi->state)) { | 1624 | if (test_bit(__I40E_DOWN, &vsi->state)) { |
@@ -1591,8 +1629,10 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) | |||
1591 | /* Since the actual Tx work is minimal, we can give the Tx a larger | 1629 | /* Since the actual Tx work is minimal, we can give the Tx a larger |
1592 | * budget and be more aggressive about cleaning up the Tx descriptors. | 1630 | * budget and be more aggressive about cleaning up the Tx descriptors. |
1593 | */ | 1631 | */ |
1594 | i40e_for_each_ring(ring, q_vector->tx) | 1632 | i40e_for_each_ring(ring, q_vector->tx) { |
1595 | clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit); | 1633 | clean_complete &= i40e_clean_tx_irq(ring, vsi->work_limit); |
1634 | arm_wb |= ring->arm_wb; | ||
1635 | } | ||
1596 | 1636 | ||
1597 | /* We attempt to distribute budget to each Rx queue fairly, but don't | 1637 | /* We attempt to distribute budget to each Rx queue fairly, but don't |
1598 | * allow the budget to go below 1 because that would exit polling early. | 1638 | * allow the budget to go below 1 because that would exit polling early. |
@@ -1603,8 +1643,11 @@ int i40e_napi_poll(struct napi_struct *napi, int budget) | |||
1603 | clean_complete &= i40e_clean_rx_irq(ring, budget_per_ring); | 1643 | clean_complete &= i40e_clean_rx_irq(ring, budget_per_ring); |
1604 | 1644 | ||
1605 | /* If work not completed, return budget and polling will return */ | 1645 | /* If work not completed, return budget and polling will return */ |
1606 | if (!clean_complete) | 1646 | if (!clean_complete) { |
1647 | if (arm_wb) | ||
1648 | i40e_force_wb(vsi, q_vector); | ||
1607 | return budget; | 1649 | return budget; |
1650 | } | ||
1608 | 1651 | ||
1609 | /* Work is done so exit the polling mode and re-enable the interrupt */ | 1652 | /* Work is done so exit the polling mode and re-enable the interrupt */ |
1610 | napi_complete(napi); | 1653 | napi_complete(napi); |
@@ -1840,17 +1883,16 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, | |||
1840 | if (err < 0) | 1883 | if (err < 0) |
1841 | return err; | 1884 | return err; |
1842 | 1885 | ||
1843 | if (protocol == htons(ETH_P_IP)) { | 1886 | iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); |
1844 | iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); | 1887 | ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb); |
1888 | |||
1889 | if (iph->version == 4) { | ||
1845 | tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); | 1890 | tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); |
1846 | iph->tot_len = 0; | 1891 | iph->tot_len = 0; |
1847 | iph->check = 0; | 1892 | iph->check = 0; |
1848 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, | 1893 | tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, |
1849 | 0, IPPROTO_TCP, 0); | 1894 | 0, IPPROTO_TCP, 0); |
1850 | } else if (skb_is_gso_v6(skb)) { | 1895 | } else if (ipv6h->version == 6) { |
1851 | |||
1852 | ipv6h = skb->encapsulation ? inner_ipv6_hdr(skb) | ||
1853 | : ipv6_hdr(skb); | ||
1854 | tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); | 1896 | tcph = skb->encapsulation ? inner_tcp_hdr(skb) : tcp_hdr(skb); |
1855 | ipv6h->payload_len = 0; | 1897 | ipv6h->payload_len = 0; |
1856 | tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, | 1898 | tcph->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, |
@@ -1946,13 +1988,9 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, | |||
1946 | I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; | 1988 | I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; |
1947 | } | 1989 | } |
1948 | } else if (tx_flags & I40E_TX_FLAGS_IPV6) { | 1990 | } else if (tx_flags & I40E_TX_FLAGS_IPV6) { |
1949 | if (tx_flags & I40E_TX_FLAGS_TSO) { | 1991 | *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; |
1950 | *cd_tunneling |= I40E_TX_CTX_EXT_IP_IPV6; | 1992 | if (tx_flags & I40E_TX_FLAGS_TSO) |
1951 | ip_hdr(skb)->check = 0; | 1993 | ip_hdr(skb)->check = 0; |
1952 | } else { | ||
1953 | *cd_tunneling |= | ||
1954 | I40E_TX_CTX_EXT_IP_IPV4_NO_CSUM; | ||
1955 | } | ||
1956 | } | 1994 | } |
1957 | 1995 | ||
1958 | /* Now set the ctx descriptor fields */ | 1996 | /* Now set the ctx descriptor fields */ |
@@ -1962,7 +2000,10 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags, | |||
1962 | ((skb_inner_network_offset(skb) - | 2000 | ((skb_inner_network_offset(skb) - |
1963 | skb_transport_offset(skb)) >> 1) << | 2001 | skb_transport_offset(skb)) >> 1) << |
1964 | I40E_TXD_CTX_QW0_NATLEN_SHIFT; | 2002 | I40E_TXD_CTX_QW0_NATLEN_SHIFT; |
1965 | 2003 | if (this_ip_hdr->version == 6) { | |
2004 | tx_flags &= ~I40E_TX_FLAGS_IPV4; | ||
2005 | tx_flags |= I40E_TX_FLAGS_IPV6; | ||
2006 | } | ||
1966 | } else { | 2007 | } else { |
1967 | network_hdr_len = skb_network_header_len(skb); | 2008 | network_hdr_len = skb_network_header_len(skb); |
1968 | this_ip_hdr = ip_hdr(skb); | 2009 | this_ip_hdr = ip_hdr(skb); |
@@ -2198,7 +2239,6 @@ static void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, | |||
2198 | /* Place RS bit on last descriptor of any packet that spans across the | 2239 | /* Place RS bit on last descriptor of any packet that spans across the |
2199 | * 4th descriptor (WB_STRIDE aka 0x3) in a 64B cacheline. | 2240 | * 4th descriptor (WB_STRIDE aka 0x3) in a 64B cacheline. |
2200 | */ | 2241 | */ |
2201 | #define WB_STRIDE 0x3 | ||
2202 | if (((i & WB_STRIDE) != WB_STRIDE) && | 2242 | if (((i & WB_STRIDE) != WB_STRIDE) && |
2203 | (first <= &tx_ring->tx_bi[i]) && | 2243 | (first <= &tx_ring->tx_bi[i]) && |
2204 | (first >= &tx_ring->tx_bi[i & ~WB_STRIDE])) { | 2244 | (first >= &tx_ring->tx_bi[i & ~WB_STRIDE])) { |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index e60d3accb2e2..18b00231d2f1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h | |||
@@ -241,6 +241,7 @@ struct i40e_ring { | |||
241 | unsigned long last_rx_timestamp; | 241 | unsigned long last_rx_timestamp; |
242 | 242 | ||
243 | bool ring_active; /* is ring online or not */ | 243 | bool ring_active; /* is ring online or not */ |
244 | bool arm_wb; /* do something to arm write back */ | ||
244 | 245 | ||
245 | /* stats structs */ | 246 | /* stats structs */ |
246 | struct i40e_queue_stats stats; | 247 | struct i40e_queue_stats stats; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 051ea94bdcd3..0f69ef81751a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -1125,7 +1125,7 @@ static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) | |||
1125 | u32 swmask = mask; | 1125 | u32 swmask = mask; |
1126 | u32 fwmask = mask << 16; | 1126 | u32 fwmask = mask << 16; |
1127 | s32 ret_val = 0; | 1127 | s32 ret_val = 0; |
1128 | s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ | 1128 | s32 i = 0, timeout = 200; |
1129 | 1129 | ||
1130 | while (i < timeout) { | 1130 | while (i < timeout) { |
1131 | if (igb_get_hw_semaphore(hw)) { | 1131 | if (igb_get_hw_semaphore(hw)) { |
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index a62fc38f045e..1c75829eb166 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -192,6 +192,10 @@ static char mv643xx_eth_driver_version[] = "1.4"; | |||
192 | #define IS_TSO_HEADER(txq, addr) \ | 192 | #define IS_TSO_HEADER(txq, addr) \ |
193 | ((addr >= txq->tso_hdrs_dma) && \ | 193 | ((addr >= txq->tso_hdrs_dma) && \ |
194 | (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) | 194 | (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE)) |
195 | |||
196 | #define DESC_DMA_MAP_SINGLE 0 | ||
197 | #define DESC_DMA_MAP_PAGE 1 | ||
198 | |||
195 | /* | 199 | /* |
196 | * RX/TX descriptors. | 200 | * RX/TX descriptors. |
197 | */ | 201 | */ |
@@ -362,6 +366,7 @@ struct tx_queue { | |||
362 | dma_addr_t tso_hdrs_dma; | 366 | dma_addr_t tso_hdrs_dma; |
363 | 367 | ||
364 | struct tx_desc *tx_desc_area; | 368 | struct tx_desc *tx_desc_area; |
369 | char *tx_desc_mapping; /* array to track the type of the dma mapping */ | ||
365 | dma_addr_t tx_desc_dma; | 370 | dma_addr_t tx_desc_dma; |
366 | int tx_desc_area_size; | 371 | int tx_desc_area_size; |
367 | 372 | ||
@@ -750,6 +755,7 @@ txq_put_data_tso(struct net_device *dev, struct tx_queue *txq, | |||
750 | if (txq->tx_curr_desc == txq->tx_ring_size) | 755 | if (txq->tx_curr_desc == txq->tx_ring_size) |
751 | txq->tx_curr_desc = 0; | 756 | txq->tx_curr_desc = 0; |
752 | desc = &txq->tx_desc_area[tx_index]; | 757 | desc = &txq->tx_desc_area[tx_index]; |
758 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | ||
753 | 759 | ||
754 | desc->l4i_chk = 0; | 760 | desc->l4i_chk = 0; |
755 | desc->byte_cnt = length; | 761 | desc->byte_cnt = length; |
@@ -879,14 +885,13 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
879 | skb_frag_t *this_frag; | 885 | skb_frag_t *this_frag; |
880 | int tx_index; | 886 | int tx_index; |
881 | struct tx_desc *desc; | 887 | struct tx_desc *desc; |
882 | void *addr; | ||
883 | 888 | ||
884 | this_frag = &skb_shinfo(skb)->frags[frag]; | 889 | this_frag = &skb_shinfo(skb)->frags[frag]; |
885 | addr = page_address(this_frag->page.p) + this_frag->page_offset; | ||
886 | tx_index = txq->tx_curr_desc++; | 890 | tx_index = txq->tx_curr_desc++; |
887 | if (txq->tx_curr_desc == txq->tx_ring_size) | 891 | if (txq->tx_curr_desc == txq->tx_ring_size) |
888 | txq->tx_curr_desc = 0; | 892 | txq->tx_curr_desc = 0; |
889 | desc = &txq->tx_desc_area[tx_index]; | 893 | desc = &txq->tx_desc_area[tx_index]; |
894 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_PAGE; | ||
890 | 895 | ||
891 | /* | 896 | /* |
892 | * The last fragment will generate an interrupt | 897 | * The last fragment will generate an interrupt |
@@ -902,8 +907,9 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) | |||
902 | 907 | ||
903 | desc->l4i_chk = 0; | 908 | desc->l4i_chk = 0; |
904 | desc->byte_cnt = skb_frag_size(this_frag); | 909 | desc->byte_cnt = skb_frag_size(this_frag); |
905 | desc->buf_ptr = dma_map_single(mp->dev->dev.parent, addr, | 910 | desc->buf_ptr = skb_frag_dma_map(mp->dev->dev.parent, |
906 | desc->byte_cnt, DMA_TO_DEVICE); | 911 | this_frag, 0, desc->byte_cnt, |
912 | DMA_TO_DEVICE); | ||
907 | } | 913 | } |
908 | } | 914 | } |
909 | 915 | ||
@@ -936,6 +942,7 @@ static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb, | |||
936 | if (txq->tx_curr_desc == txq->tx_ring_size) | 942 | if (txq->tx_curr_desc == txq->tx_ring_size) |
937 | txq->tx_curr_desc = 0; | 943 | txq->tx_curr_desc = 0; |
938 | desc = &txq->tx_desc_area[tx_index]; | 944 | desc = &txq->tx_desc_area[tx_index]; |
945 | txq->tx_desc_mapping[tx_index] = DESC_DMA_MAP_SINGLE; | ||
939 | 946 | ||
940 | if (nr_frags) { | 947 | if (nr_frags) { |
941 | txq_submit_frag_skb(txq, skb); | 948 | txq_submit_frag_skb(txq, skb); |
@@ -1047,9 +1054,12 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
1047 | int tx_index; | 1054 | int tx_index; |
1048 | struct tx_desc *desc; | 1055 | struct tx_desc *desc; |
1049 | u32 cmd_sts; | 1056 | u32 cmd_sts; |
1057 | char desc_dma_map; | ||
1050 | 1058 | ||
1051 | tx_index = txq->tx_used_desc; | 1059 | tx_index = txq->tx_used_desc; |
1052 | desc = &txq->tx_desc_area[tx_index]; | 1060 | desc = &txq->tx_desc_area[tx_index]; |
1061 | desc_dma_map = txq->tx_desc_mapping[tx_index]; | ||
1062 | |||
1053 | cmd_sts = desc->cmd_sts; | 1063 | cmd_sts = desc->cmd_sts; |
1054 | 1064 | ||
1055 | if (cmd_sts & BUFFER_OWNED_BY_DMA) { | 1065 | if (cmd_sts & BUFFER_OWNED_BY_DMA) { |
@@ -1065,9 +1075,19 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
1065 | reclaimed++; | 1075 | reclaimed++; |
1066 | txq->tx_desc_count--; | 1076 | txq->tx_desc_count--; |
1067 | 1077 | ||
1068 | if (!IS_TSO_HEADER(txq, desc->buf_ptr)) | 1078 | if (!IS_TSO_HEADER(txq, desc->buf_ptr)) { |
1069 | dma_unmap_single(mp->dev->dev.parent, desc->buf_ptr, | 1079 | |
1070 | desc->byte_cnt, DMA_TO_DEVICE); | 1080 | if (desc_dma_map == DESC_DMA_MAP_PAGE) |
1081 | dma_unmap_page(mp->dev->dev.parent, | ||
1082 | desc->buf_ptr, | ||
1083 | desc->byte_cnt, | ||
1084 | DMA_TO_DEVICE); | ||
1085 | else | ||
1086 | dma_unmap_single(mp->dev->dev.parent, | ||
1087 | desc->buf_ptr, | ||
1088 | desc->byte_cnt, | ||
1089 | DMA_TO_DEVICE); | ||
1090 | } | ||
1071 | 1091 | ||
1072 | if (cmd_sts & TX_ENABLE_INTERRUPT) { | 1092 | if (cmd_sts & TX_ENABLE_INTERRUPT) { |
1073 | struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); | 1093 | struct sk_buff *skb = __skb_dequeue(&txq->tx_skb); |
@@ -1996,6 +2016,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
1996 | struct tx_queue *txq = mp->txq + index; | 2016 | struct tx_queue *txq = mp->txq + index; |
1997 | struct tx_desc *tx_desc; | 2017 | struct tx_desc *tx_desc; |
1998 | int size; | 2018 | int size; |
2019 | int ret; | ||
1999 | int i; | 2020 | int i; |
2000 | 2021 | ||
2001 | txq->index = index; | 2022 | txq->index = index; |
@@ -2048,18 +2069,34 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
2048 | nexti * sizeof(struct tx_desc); | 2069 | nexti * sizeof(struct tx_desc); |
2049 | } | 2070 | } |
2050 | 2071 | ||
2072 | txq->tx_desc_mapping = kcalloc(txq->tx_ring_size, sizeof(char), | ||
2073 | GFP_KERNEL); | ||
2074 | if (!txq->tx_desc_mapping) { | ||
2075 | ret = -ENOMEM; | ||
2076 | goto err_free_desc_area; | ||
2077 | } | ||
2078 | |||
2051 | /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ | 2079 | /* Allocate DMA buffers for TSO MAC/IP/TCP headers */ |
2052 | txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, | 2080 | txq->tso_hdrs = dma_alloc_coherent(mp->dev->dev.parent, |
2053 | txq->tx_ring_size * TSO_HEADER_SIZE, | 2081 | txq->tx_ring_size * TSO_HEADER_SIZE, |
2054 | &txq->tso_hdrs_dma, GFP_KERNEL); | 2082 | &txq->tso_hdrs_dma, GFP_KERNEL); |
2055 | if (txq->tso_hdrs == NULL) { | 2083 | if (txq->tso_hdrs == NULL) { |
2056 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | 2084 | ret = -ENOMEM; |
2057 | txq->tx_desc_area, txq->tx_desc_dma); | 2085 | goto err_free_desc_mapping; |
2058 | return -ENOMEM; | ||
2059 | } | 2086 | } |
2060 | skb_queue_head_init(&txq->tx_skb); | 2087 | skb_queue_head_init(&txq->tx_skb); |
2061 | 2088 | ||
2062 | return 0; | 2089 | return 0; |
2090 | |||
2091 | err_free_desc_mapping: | ||
2092 | kfree(txq->tx_desc_mapping); | ||
2093 | err_free_desc_area: | ||
2094 | if (index == 0 && size <= mp->tx_desc_sram_size) | ||
2095 | iounmap(txq->tx_desc_area); | ||
2096 | else | ||
2097 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | ||
2098 | txq->tx_desc_area, txq->tx_desc_dma); | ||
2099 | return ret; | ||
2063 | } | 2100 | } |
2064 | 2101 | ||
2065 | static void txq_deinit(struct tx_queue *txq) | 2102 | static void txq_deinit(struct tx_queue *txq) |
@@ -2077,6 +2114,8 @@ static void txq_deinit(struct tx_queue *txq) | |||
2077 | else | 2114 | else |
2078 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, | 2115 | dma_free_coherent(mp->dev->dev.parent, txq->tx_desc_area_size, |
2079 | txq->tx_desc_area, txq->tx_desc_dma); | 2116 | txq->tx_desc_area, txq->tx_desc_dma); |
2117 | kfree(txq->tx_desc_mapping); | ||
2118 | |||
2080 | if (txq->tso_hdrs) | 2119 | if (txq->tso_hdrs) |
2081 | dma_free_coherent(mp->dev->dev.parent, | 2120 | dma_free_coherent(mp->dev->dev.parent, |
2082 | txq->tx_ring_size * TSO_HEADER_SIZE, | 2121 | txq->tx_ring_size * TSO_HEADER_SIZE, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 190cbd931f6b..ac6a8f1eea6c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -475,7 +475,8 @@ static int mlx4_en_tunnel_steer_add(struct mlx4_en_priv *priv, unsigned char *ad | |||
475 | { | 475 | { |
476 | int err; | 476 | int err; |
477 | 477 | ||
478 | if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) | 478 | if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN || |
479 | priv->mdev->dev->caps.dmfs_high_steer_mode == MLX4_STEERING_DMFS_A0_STATIC) | ||
479 | return 0; /* do nothing */ | 480 | return 0; /* do nothing */ |
480 | 481 | ||
481 | err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn, | 482 | err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn, |
@@ -2365,9 +2366,11 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev, | |||
2365 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); | 2366 | queue_work(priv->mdev->workqueue, &priv->vxlan_del_task); |
2366 | } | 2367 | } |
2367 | 2368 | ||
2368 | static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev) | 2369 | static netdev_features_t mlx4_en_features_check(struct sk_buff *skb, |
2370 | struct net_device *dev, | ||
2371 | netdev_features_t features) | ||
2369 | { | 2372 | { |
2370 | return vxlan_gso_check(skb); | 2373 | return vxlan_features_check(skb, features); |
2371 | } | 2374 | } |
2372 | #endif | 2375 | #endif |
2373 | 2376 | ||
@@ -2400,7 +2403,7 @@ static const struct net_device_ops mlx4_netdev_ops = { | |||
2400 | #ifdef CONFIG_MLX4_EN_VXLAN | 2403 | #ifdef CONFIG_MLX4_EN_VXLAN |
2401 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | 2404 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, |
2402 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | 2405 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, |
2403 | .ndo_gso_check = mlx4_en_gso_check, | 2406 | .ndo_features_check = mlx4_en_features_check, |
2404 | #endif | 2407 | #endif |
2405 | }; | 2408 | }; |
2406 | 2409 | ||
@@ -2434,7 +2437,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = { | |||
2434 | #ifdef CONFIG_MLX4_EN_VXLAN | 2437 | #ifdef CONFIG_MLX4_EN_VXLAN |
2435 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, | 2438 | .ndo_add_vxlan_port = mlx4_en_add_vxlan_port, |
2436 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, | 2439 | .ndo_del_vxlan_port = mlx4_en_del_vxlan_port, |
2437 | .ndo_gso_check = mlx4_en_gso_check, | 2440 | .ndo_features_check = mlx4_en_features_check, |
2438 | #endif | 2441 | #endif |
2439 | }; | 2442 | }; |
2440 | 2443 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index a308d41e4de0..e3357bf523df 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -962,7 +962,17 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
962 | tx_desc->ctrl.owner_opcode = op_own; | 962 | tx_desc->ctrl.owner_opcode = op_own; |
963 | if (send_doorbell) { | 963 | if (send_doorbell) { |
964 | wmb(); | 964 | wmb(); |
965 | iowrite32(ring->doorbell_qpn, | 965 | /* Since there is no iowrite*_native() that writes the |
966 | * value as is, without byteswapping - using the one | ||
967 | * the doesn't do byteswapping in the relevant arch | ||
968 | * endianness. | ||
969 | */ | ||
970 | #if defined(__LITTLE_ENDIAN) | ||
971 | iowrite32( | ||
972 | #else | ||
973 | iowrite32be( | ||
974 | #endif | ||
975 | ring->doorbell_qpn, | ||
966 | ring->bf.uar->map + MLX4_SEND_DOORBELL); | 976 | ring->bf.uar->map + MLX4_SEND_DOORBELL); |
967 | } else { | 977 | } else { |
968 | ring->xmit_more++; | 978 | ring->xmit_more++; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 943cbd47d832..6e08352ec994 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1744,8 +1744,7 @@ static void choose_tunnel_offload_mode(struct mlx4_dev *dev, | |||
1744 | struct mlx4_dev_cap *dev_cap) | 1744 | struct mlx4_dev_cap *dev_cap) |
1745 | { | 1745 | { |
1746 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && | 1746 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED && |
1747 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS && | 1747 | dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_VXLAN_OFFLOADS) |
1748 | dev->caps.dmfs_high_steer_mode != MLX4_STEERING_DMFS_A0_STATIC) | ||
1749 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; | 1748 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_VXLAN; |
1750 | else | 1749 | else |
1751 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; | 1750 | dev->caps.tunnel_offload_mode = MLX4_TUNNEL_OFFLOAD_MODE_NONE; |
@@ -1829,7 +1828,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1829 | err = mlx4_dev_cap(dev, &dev_cap); | 1828 | err = mlx4_dev_cap(dev, &dev_cap); |
1830 | if (err) { | 1829 | if (err) { |
1831 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); | 1830 | mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting\n"); |
1832 | goto err_stop_fw; | 1831 | return err; |
1833 | } | 1832 | } |
1834 | 1833 | ||
1835 | choose_steering_mode(dev, &dev_cap); | 1834 | choose_steering_mode(dev, &dev_cap); |
@@ -1860,7 +1859,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1860 | &init_hca); | 1859 | &init_hca); |
1861 | if ((long long) icm_size < 0) { | 1860 | if ((long long) icm_size < 0) { |
1862 | err = icm_size; | 1861 | err = icm_size; |
1863 | goto err_stop_fw; | 1862 | return err; |
1864 | } | 1863 | } |
1865 | 1864 | ||
1866 | dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; | 1865 | dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1; |
@@ -1874,7 +1873,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1874 | 1873 | ||
1875 | err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); | 1874 | err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size); |
1876 | if (err) | 1875 | if (err) |
1877 | goto err_stop_fw; | 1876 | return err; |
1878 | 1877 | ||
1879 | err = mlx4_INIT_HCA(dev, &init_hca); | 1878 | err = mlx4_INIT_HCA(dev, &init_hca); |
1880 | if (err) { | 1879 | if (err) { |
@@ -1886,7 +1885,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1886 | err = mlx4_query_func(dev, &dev_cap); | 1885 | err = mlx4_query_func(dev, &dev_cap); |
1887 | if (err < 0) { | 1886 | if (err < 0) { |
1888 | mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); | 1887 | mlx4_err(dev, "QUERY_FUNC command failed, aborting.\n"); |
1889 | goto err_stop_fw; | 1888 | goto err_close; |
1890 | } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { | 1889 | } else if (err & MLX4_QUERY_FUNC_NUM_SYS_EQS) { |
1891 | dev->caps.num_eqs = dev_cap.max_eqs; | 1890 | dev->caps.num_eqs = dev_cap.max_eqs; |
1892 | dev->caps.reserved_eqs = dev_cap.reserved_eqs; | 1891 | dev->caps.reserved_eqs = dev_cap.reserved_eqs; |
@@ -2006,11 +2005,6 @@ err_free_icm: | |||
2006 | if (!mlx4_is_slave(dev)) | 2005 | if (!mlx4_is_slave(dev)) |
2007 | mlx4_free_icms(dev); | 2006 | mlx4_free_icms(dev); |
2008 | 2007 | ||
2009 | err_stop_fw: | ||
2010 | if (!mlx4_is_slave(dev)) { | ||
2011 | mlx4_UNMAP_FA(dev); | ||
2012 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | ||
2013 | } | ||
2014 | return err; | 2008 | return err; |
2015 | } | 2009 | } |
2016 | 2010 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index d6f549685c0f..7094a9c70fd5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -584,6 +584,7 @@ EXPORT_SYMBOL_GPL(mlx4_mr_free); | |||
584 | void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) | 584 | void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) |
585 | { | 585 | { |
586 | mlx4_mtt_cleanup(dev, &mr->mtt); | 586 | mlx4_mtt_cleanup(dev, &mr->mtt); |
587 | mr->mtt.order = -1; | ||
587 | } | 588 | } |
588 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); | 589 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); |
589 | 590 | ||
@@ -593,14 +594,14 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, | |||
593 | { | 594 | { |
594 | int err; | 595 | int err; |
595 | 596 | ||
596 | mpt_entry->start = cpu_to_be64(iova); | ||
597 | mpt_entry->length = cpu_to_be64(size); | ||
598 | mpt_entry->entity_size = cpu_to_be32(page_shift); | ||
599 | |||
600 | err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); | 597 | err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); |
601 | if (err) | 598 | if (err) |
602 | return err; | 599 | return err; |
603 | 600 | ||
601 | mpt_entry->start = cpu_to_be64(mr->iova); | ||
602 | mpt_entry->length = cpu_to_be64(mr->size); | ||
603 | mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); | ||
604 | |||
604 | mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK | | 605 | mpt_entry->pd_flags &= cpu_to_be32(MLX4_MPT_PD_MASK | |
605 | MLX4_MPT_PD_FLAG_EN_INV); | 606 | MLX4_MPT_PD_FLAG_EN_INV); |
606 | mpt_entry->flags &= cpu_to_be32(MLX4_MPT_FLAG_FREE | | 607 | mpt_entry->flags &= cpu_to_be32(MLX4_MPT_FLAG_FREE | |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index f1ebed6c63b1..2fa6ae026e4f 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
@@ -2303,12 +2303,6 @@ static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p) | |||
2303 | 2303 | ||
2304 | /* Spanning Tree */ | 2304 | /* Spanning Tree */ |
2305 | 2305 | ||
2306 | static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set) | ||
2307 | { | ||
2308 | port_cfg(hw, p, | ||
2309 | KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set); | ||
2310 | } | ||
2311 | |||
2312 | static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) | 2306 | static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set) |
2313 | { | 2307 | { |
2314 | port_cfg(hw, p, | 2308 | port_cfg(hw, p, |
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index af099057f0e9..71af98bb72cb 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c | |||
@@ -4033,8 +4033,10 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4033 | (void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | 4033 | (void)pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); |
4034 | mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), | 4034 | mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd), |
4035 | &mgp->cmd_bus, GFP_KERNEL); | 4035 | &mgp->cmd_bus, GFP_KERNEL); |
4036 | if (mgp->cmd == NULL) | 4036 | if (!mgp->cmd) { |
4037 | status = -ENOMEM; | ||
4037 | goto abort_with_enabled; | 4038 | goto abort_with_enabled; |
4039 | } | ||
4038 | 4040 | ||
4039 | mgp->board_span = pci_resource_len(pdev, 0); | 4041 | mgp->board_span = pci_resource_len(pdev, 0); |
4040 | mgp->iomem_base = pci_resource_start(pdev, 0); | 4042 | mgp->iomem_base = pci_resource_start(pdev, 0); |
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index f5e4b820128b..db0c7a9aee60 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c | |||
@@ -6987,7 +6987,9 @@ static int s2io_add_isr(struct s2io_nic *sp) | |||
6987 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { | 6987 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { |
6988 | if (sp->s2io_entries[i].type == | 6988 | if (sp->s2io_entries[i].type == |
6989 | MSIX_RING_TYPE) { | 6989 | MSIX_RING_TYPE) { |
6990 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 6990 | snprintf(sp->desc[i], |
6991 | sizeof(sp->desc[i]), | ||
6992 | "%s:MSI-X-%d-RX", | ||
6991 | dev->name, i); | 6993 | dev->name, i); |
6992 | err = request_irq(sp->entries[i].vector, | 6994 | err = request_irq(sp->entries[i].vector, |
6993 | s2io_msix_ring_handle, | 6995 | s2io_msix_ring_handle, |
@@ -6996,7 +6998,9 @@ static int s2io_add_isr(struct s2io_nic *sp) | |||
6996 | sp->s2io_entries[i].arg); | 6998 | sp->s2io_entries[i].arg); |
6997 | } else if (sp->s2io_entries[i].type == | 6999 | } else if (sp->s2io_entries[i].type == |
6998 | MSIX_ALARM_TYPE) { | 7000 | MSIX_ALARM_TYPE) { |
6999 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | 7001 | snprintf(sp->desc[i], |
7002 | sizeof(sp->desc[i]), | ||
7003 | "%s:MSI-X-%d-TX", | ||
7000 | dev->name, i); | 7004 | dev->name, i); |
7001 | err = request_irq(sp->entries[i].vector, | 7005 | err = request_irq(sp->entries[i].vector, |
7002 | s2io_msix_fifo_handle, | 7006 | s2io_msix_fifo_handle, |
@@ -8154,7 +8158,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8154 | "%s: UDP Fragmentation Offload(UFO) enabled\n", | 8158 | "%s: UDP Fragmentation Offload(UFO) enabled\n", |
8155 | dev->name); | 8159 | dev->name); |
8156 | /* Initialize device name */ | 8160 | /* Initialize device name */ |
8157 | sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); | 8161 | snprintf(sp->name, sizeof(sp->name), "%s Neterion %s", dev->name, |
8162 | sp->product_name); | ||
8158 | 8163 | ||
8159 | if (vlan_tag_strip) | 8164 | if (vlan_tag_strip) |
8160 | sp->vlan_strip_flag = 1; | 8165 | sp->vlan_strip_flag = 1; |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 613037584d08..c531c8ae1be4 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
2388 | 2388 | ||
2389 | work_done = netxen_process_rcv_ring(sds_ring, budget); | 2389 | work_done = netxen_process_rcv_ring(sds_ring, budget); |
2390 | 2390 | ||
2391 | if ((work_done < budget) && tx_complete) { | 2391 | if (!tx_complete) |
2392 | work_done = budget; | ||
2393 | |||
2394 | if (work_done < budget) { | ||
2392 | napi_complete(&sds_ring->napi); | 2395 | napi_complete(&sds_ring->napi); |
2393 | if (test_bit(__NX_DEV_UP, &adapter->state)) | 2396 | if (test_bit(__NX_DEV_UP, &adapter->state)) |
2394 | netxen_nic_enable_int(sds_ring); | 2397 | netxen_nic_enable_int(sds_ring); |
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index c2f09af5c25b..4847713211ca 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c | |||
@@ -146,10 +146,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) | |||
146 | { | 146 | { |
147 | int i = 0; | 147 | int i = 0; |
148 | 148 | ||
149 | while (i < 10) { | 149 | do { |
150 | if (i) | ||
151 | ssleep(1); | ||
152 | |||
153 | if (ql_sem_lock(qdev, | 150 | if (ql_sem_lock(qdev, |
154 | QL_DRVR_SEM_MASK, | 151 | QL_DRVR_SEM_MASK, |
155 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) | 152 | (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) |
@@ -158,7 +155,8 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) | |||
158 | "driver lock acquired\n"); | 155 | "driver lock acquired\n"); |
159 | return 1; | 156 | return 1; |
160 | } | 157 | } |
161 | } | 158 | ssleep(1); |
159 | } while (++i < 10); | ||
162 | 160 | ||
163 | netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); | 161 | netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); |
164 | return 0; | 162 | return 0; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 1aa25b13ace1..2528c3fb6b90 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -505,9 +505,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev, | |||
505 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; | 505 | adapter->flags |= QLCNIC_DEL_VXLAN_PORT; |
506 | } | 506 | } |
507 | 507 | ||
508 | static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev) | 508 | static netdev_features_t qlcnic_features_check(struct sk_buff *skb, |
509 | struct net_device *dev, | ||
510 | netdev_features_t features) | ||
509 | { | 511 | { |
510 | return vxlan_gso_check(skb); | 512 | return vxlan_features_check(skb, features); |
511 | } | 513 | } |
512 | #endif | 514 | #endif |
513 | 515 | ||
@@ -532,7 +534,7 @@ static const struct net_device_ops qlcnic_netdev_ops = { | |||
532 | #ifdef CONFIG_QLCNIC_VXLAN | 534 | #ifdef CONFIG_QLCNIC_VXLAN |
533 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, | 535 | .ndo_add_vxlan_port = qlcnic_add_vxlan_port, |
534 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, | 536 | .ndo_del_vxlan_port = qlcnic_del_vxlan_port, |
535 | .ndo_gso_check = qlcnic_gso_check, | 537 | .ndo_features_check = qlcnic_features_check, |
536 | #endif | 538 | #endif |
537 | #ifdef CONFIG_NET_POLL_CONTROLLER | 539 | #ifdef CONFIG_NET_POLL_CONTROLLER |
538 | .ndo_poll_controller = qlcnic_poll_controller, | 540 | .ndo_poll_controller = qlcnic_poll_controller, |
@@ -2603,6 +2605,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2603 | } else { | 2605 | } else { |
2604 | dev_err(&pdev->dev, | 2606 | dev_err(&pdev->dev, |
2605 | "%s: failed. Please Reboot\n", __func__); | 2607 | "%s: failed. Please Reboot\n", __func__); |
2608 | err = -ENODEV; | ||
2606 | goto err_out_free_hw; | 2609 | goto err_out_free_hw; |
2607 | } | 2610 | } |
2608 | 2611 | ||
diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index 6d0b9dfac313..78bb4ceb1cdd 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c | |||
@@ -787,10 +787,10 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev) | |||
787 | if (rc) | 787 | if (rc) |
788 | goto err_out; | 788 | goto err_out; |
789 | 789 | ||
790 | disable_dev_on_err = 1; | ||
790 | rc = pci_request_regions (pdev, DRV_NAME); | 791 | rc = pci_request_regions (pdev, DRV_NAME); |
791 | if (rc) | 792 | if (rc) |
792 | goto err_out; | 793 | goto err_out; |
793 | disable_dev_on_err = 1; | ||
794 | 794 | ||
795 | pci_set_master (pdev); | 795 | pci_set_master (pdev); |
796 | 796 | ||
@@ -1110,6 +1110,7 @@ static int rtl8139_init_one(struct pci_dev *pdev, | |||
1110 | return 0; | 1110 | return 0; |
1111 | 1111 | ||
1112 | err_out: | 1112 | err_out: |
1113 | netif_napi_del(&tp->napi); | ||
1113 | __rtl8139_cleanup_dev (dev); | 1114 | __rtl8139_cleanup_dev (dev); |
1114 | pci_disable_device (pdev); | 1115 | pci_disable_device (pdev); |
1115 | return i; | 1116 | return i; |
@@ -1124,6 +1125,7 @@ static void rtl8139_remove_one(struct pci_dev *pdev) | |||
1124 | assert (dev != NULL); | 1125 | assert (dev != NULL); |
1125 | 1126 | ||
1126 | cancel_delayed_work_sync(&tp->thread); | 1127 | cancel_delayed_work_sync(&tp->thread); |
1128 | netif_napi_del(&tp->napi); | ||
1127 | 1129 | ||
1128 | unregister_netdev (dev); | 1130 | unregister_netdev (dev); |
1129 | 1131 | ||
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c29ba80ae02b..04283fe0e6a7 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -396,6 +396,9 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
396 | [TSU_ADRL31] = 0x01fc, | 396 | [TSU_ADRL31] = 0x01fc, |
397 | }; | 397 | }; |
398 | 398 | ||
399 | static void sh_eth_rcv_snd_disable(struct net_device *ndev); | ||
400 | static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev); | ||
401 | |||
399 | static bool sh_eth_is_gether(struct sh_eth_private *mdp) | 402 | static bool sh_eth_is_gether(struct sh_eth_private *mdp) |
400 | { | 403 | { |
401 | return mdp->reg_offset == sh_eth_offset_gigabit; | 404 | return mdp->reg_offset == sh_eth_offset_gigabit; |
@@ -473,6 +476,7 @@ static struct sh_eth_cpu_data r8a777x_data = { | |||
473 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | | 476 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | |
474 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | | 477 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | |
475 | EESR_ECI, | 478 | EESR_ECI, |
479 | .fdr_value = 0x00000f0f, | ||
476 | 480 | ||
477 | .apr = 1, | 481 | .apr = 1, |
478 | .mpr = 1, | 482 | .mpr = 1, |
@@ -495,6 +499,9 @@ static struct sh_eth_cpu_data r8a779x_data = { | |||
495 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | | 499 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | |
496 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | | 500 | EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | |
497 | EESR_ECI, | 501 | EESR_ECI, |
502 | .fdr_value = 0x00000f0f, | ||
503 | |||
504 | .trscer_err_mask = DESC_I_RINT8, | ||
498 | 505 | ||
499 | .apr = 1, | 506 | .apr = 1, |
500 | .mpr = 1, | 507 | .mpr = 1, |
@@ -856,6 +863,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) | |||
856 | 863 | ||
857 | if (!cd->eesr_err_check) | 864 | if (!cd->eesr_err_check) |
858 | cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK; | 865 | cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK; |
866 | |||
867 | if (!cd->trscer_err_mask) | ||
868 | cd->trscer_err_mask = DEFAULT_TRSCER_ERR_MASK; | ||
859 | } | 869 | } |
860 | 870 | ||
861 | static int sh_eth_check_reset(struct net_device *ndev) | 871 | static int sh_eth_check_reset(struct net_device *ndev) |
@@ -1113,6 +1123,7 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1113 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; | 1123 | int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; |
1114 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; | 1124 | int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; |
1115 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | 1125 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
1126 | dma_addr_t dma_addr; | ||
1116 | 1127 | ||
1117 | mdp->cur_rx = 0; | 1128 | mdp->cur_rx = 0; |
1118 | mdp->cur_tx = 0; | 1129 | mdp->cur_tx = 0; |
@@ -1126,7 +1137,6 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1126 | /* skb */ | 1137 | /* skb */ |
1127 | mdp->rx_skbuff[i] = NULL; | 1138 | mdp->rx_skbuff[i] = NULL; |
1128 | skb = netdev_alloc_skb(ndev, skbuff_size); | 1139 | skb = netdev_alloc_skb(ndev, skbuff_size); |
1129 | mdp->rx_skbuff[i] = skb; | ||
1130 | if (skb == NULL) | 1140 | if (skb == NULL) |
1131 | break; | 1141 | break; |
1132 | sh_eth_set_receive_align(skb); | 1142 | sh_eth_set_receive_align(skb); |
@@ -1135,9 +1145,15 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1135 | rxdesc = &mdp->rx_ring[i]; | 1145 | rxdesc = &mdp->rx_ring[i]; |
1136 | /* The size of the buffer is a multiple of 16 bytes. */ | 1146 | /* The size of the buffer is a multiple of 16 bytes. */ |
1137 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); | 1147 | rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); |
1138 | dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, | 1148 | dma_addr = dma_map_single(&ndev->dev, skb->data, |
1139 | DMA_FROM_DEVICE); | 1149 | rxdesc->buffer_length, |
1140 | rxdesc->addr = virt_to_phys(skb->data); | 1150 | DMA_FROM_DEVICE); |
1151 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | ||
1152 | kfree_skb(skb); | ||
1153 | break; | ||
1154 | } | ||
1155 | mdp->rx_skbuff[i] = skb; | ||
1156 | rxdesc->addr = dma_addr; | ||
1141 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); | 1157 | rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); |
1142 | 1158 | ||
1143 | /* Rx descriptor address set */ | 1159 | /* Rx descriptor address set */ |
@@ -1294,7 +1310,7 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) | |||
1294 | /* Frame recv control (enable multiple-packets per rx irq) */ | 1310 | /* Frame recv control (enable multiple-packets per rx irq) */ |
1295 | sh_eth_write(ndev, RMCR_RNC, RMCR); | 1311 | sh_eth_write(ndev, RMCR_RNC, RMCR); |
1296 | 1312 | ||
1297 | sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); | 1313 | sh_eth_write(ndev, mdp->cd->trscer_err_mask, TRSCER); |
1298 | 1314 | ||
1299 | if (mdp->cd->bculr) | 1315 | if (mdp->cd->bculr) |
1300 | sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ | 1316 | sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ |
@@ -1309,8 +1325,10 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) | |||
1309 | RFLR); | 1325 | RFLR); |
1310 | 1326 | ||
1311 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); | 1327 | sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); |
1312 | if (start) | 1328 | if (start) { |
1329 | mdp->irq_enabled = true; | ||
1313 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 1330 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
1331 | } | ||
1314 | 1332 | ||
1315 | /* PAUSE Prohibition */ | 1333 | /* PAUSE Prohibition */ |
1316 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | | 1334 | val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | |
@@ -1349,6 +1367,33 @@ static int sh_eth_dev_init(struct net_device *ndev, bool start) | |||
1349 | return ret; | 1367 | return ret; |
1350 | } | 1368 | } |
1351 | 1369 | ||
1370 | static void sh_eth_dev_exit(struct net_device *ndev) | ||
1371 | { | ||
1372 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
1373 | int i; | ||
1374 | |||
1375 | /* Deactivate all TX descriptors, so DMA should stop at next | ||
1376 | * packet boundary if it's currently running | ||
1377 | */ | ||
1378 | for (i = 0; i < mdp->num_tx_ring; i++) | ||
1379 | mdp->tx_ring[i].status &= ~cpu_to_edmac(mdp, TD_TACT); | ||
1380 | |||
1381 | /* Disable TX FIFO egress to MAC */ | ||
1382 | sh_eth_rcv_snd_disable(ndev); | ||
1383 | |||
1384 | /* Stop RX DMA at next packet boundary */ | ||
1385 | sh_eth_write(ndev, 0, EDRRR); | ||
1386 | |||
1387 | /* Aside from TX DMA, we can't tell when the hardware is | ||
1388 | * really stopped, so we need to reset to make sure. | ||
1389 | * Before doing that, wait for long enough to *probably* | ||
1390 | * finish transmitting the last packet and poll stats. | ||
1391 | */ | ||
1392 | msleep(2); /* max frame time at 10 Mbps < 1250 us */ | ||
1393 | sh_eth_get_stats(ndev); | ||
1394 | sh_eth_reset(ndev); | ||
1395 | } | ||
1396 | |||
1352 | /* free Tx skb function */ | 1397 | /* free Tx skb function */ |
1353 | static int sh_eth_txfree(struct net_device *ndev) | 1398 | static int sh_eth_txfree(struct net_device *ndev) |
1354 | { | 1399 | { |
@@ -1393,6 +1438,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1393 | u16 pkt_len = 0; | 1438 | u16 pkt_len = 0; |
1394 | u32 desc_status; | 1439 | u32 desc_status; |
1395 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; | 1440 | int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; |
1441 | dma_addr_t dma_addr; | ||
1396 | 1442 | ||
1397 | boguscnt = min(boguscnt, *quota); | 1443 | boguscnt = min(boguscnt, *quota); |
1398 | limit = boguscnt; | 1444 | limit = boguscnt; |
@@ -1440,9 +1486,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1440 | mdp->rx_skbuff[entry] = NULL; | 1486 | mdp->rx_skbuff[entry] = NULL; |
1441 | if (mdp->cd->rpadir) | 1487 | if (mdp->cd->rpadir) |
1442 | skb_reserve(skb, NET_IP_ALIGN); | 1488 | skb_reserve(skb, NET_IP_ALIGN); |
1443 | dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, | 1489 | dma_unmap_single(&ndev->dev, rxdesc->addr, |
1444 | ALIGN(mdp->rx_buf_sz, 16), | 1490 | ALIGN(mdp->rx_buf_sz, 16), |
1445 | DMA_FROM_DEVICE); | 1491 | DMA_FROM_DEVICE); |
1446 | skb_put(skb, pkt_len); | 1492 | skb_put(skb, pkt_len); |
1447 | skb->protocol = eth_type_trans(skb, ndev); | 1493 | skb->protocol = eth_type_trans(skb, ndev); |
1448 | netif_receive_skb(skb); | 1494 | netif_receive_skb(skb); |
@@ -1462,15 +1508,20 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1462 | 1508 | ||
1463 | if (mdp->rx_skbuff[entry] == NULL) { | 1509 | if (mdp->rx_skbuff[entry] == NULL) { |
1464 | skb = netdev_alloc_skb(ndev, skbuff_size); | 1510 | skb = netdev_alloc_skb(ndev, skbuff_size); |
1465 | mdp->rx_skbuff[entry] = skb; | ||
1466 | if (skb == NULL) | 1511 | if (skb == NULL) |
1467 | break; /* Better luck next round. */ | 1512 | break; /* Better luck next round. */ |
1468 | sh_eth_set_receive_align(skb); | 1513 | sh_eth_set_receive_align(skb); |
1469 | dma_map_single(&ndev->dev, skb->data, | 1514 | dma_addr = dma_map_single(&ndev->dev, skb->data, |
1470 | rxdesc->buffer_length, DMA_FROM_DEVICE); | 1515 | rxdesc->buffer_length, |
1516 | DMA_FROM_DEVICE); | ||
1517 | if (dma_mapping_error(&ndev->dev, dma_addr)) { | ||
1518 | kfree_skb(skb); | ||
1519 | break; | ||
1520 | } | ||
1521 | mdp->rx_skbuff[entry] = skb; | ||
1471 | 1522 | ||
1472 | skb_checksum_none_assert(skb); | 1523 | skb_checksum_none_assert(skb); |
1473 | rxdesc->addr = virt_to_phys(skb->data); | 1524 | rxdesc->addr = dma_addr; |
1474 | } | 1525 | } |
1475 | if (entry >= mdp->num_rx_ring - 1) | 1526 | if (entry >= mdp->num_rx_ring - 1) |
1476 | rxdesc->status |= | 1527 | rxdesc->status |= |
@@ -1566,7 +1617,6 @@ ignore_link: | |||
1566 | if (intr_status & EESR_RFRMER) { | 1617 | if (intr_status & EESR_RFRMER) { |
1567 | /* Receive Frame Overflow int */ | 1618 | /* Receive Frame Overflow int */ |
1568 | ndev->stats.rx_frame_errors++; | 1619 | ndev->stats.rx_frame_errors++; |
1569 | netif_err(mdp, rx_err, ndev, "Receive Abort\n"); | ||
1570 | } | 1620 | } |
1571 | } | 1621 | } |
1572 | 1622 | ||
@@ -1585,13 +1635,11 @@ ignore_link: | |||
1585 | if (intr_status & EESR_RDE) { | 1635 | if (intr_status & EESR_RDE) { |
1586 | /* Receive Descriptor Empty int */ | 1636 | /* Receive Descriptor Empty int */ |
1587 | ndev->stats.rx_over_errors++; | 1637 | ndev->stats.rx_over_errors++; |
1588 | netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n"); | ||
1589 | } | 1638 | } |
1590 | 1639 | ||
1591 | if (intr_status & EESR_RFE) { | 1640 | if (intr_status & EESR_RFE) { |
1592 | /* Receive FIFO Overflow int */ | 1641 | /* Receive FIFO Overflow int */ |
1593 | ndev->stats.rx_fifo_errors++; | 1642 | ndev->stats.rx_fifo_errors++; |
1594 | netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n"); | ||
1595 | } | 1643 | } |
1596 | 1644 | ||
1597 | if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { | 1645 | if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { |
@@ -1646,7 +1694,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
1646 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) | 1694 | if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) |
1647 | ret = IRQ_HANDLED; | 1695 | ret = IRQ_HANDLED; |
1648 | else | 1696 | else |
1649 | goto other_irq; | 1697 | goto out; |
1698 | |||
1699 | if (!likely(mdp->irq_enabled)) { | ||
1700 | sh_eth_write(ndev, 0, EESIPR); | ||
1701 | goto out; | ||
1702 | } | ||
1650 | 1703 | ||
1651 | if (intr_status & EESR_RX_CHECK) { | 1704 | if (intr_status & EESR_RX_CHECK) { |
1652 | if (napi_schedule_prep(&mdp->napi)) { | 1705 | if (napi_schedule_prep(&mdp->napi)) { |
@@ -1677,7 +1730,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
1677 | sh_eth_error(ndev, intr_status); | 1730 | sh_eth_error(ndev, intr_status); |
1678 | } | 1731 | } |
1679 | 1732 | ||
1680 | other_irq: | 1733 | out: |
1681 | spin_unlock(&mdp->lock); | 1734 | spin_unlock(&mdp->lock); |
1682 | 1735 | ||
1683 | return ret; | 1736 | return ret; |
@@ -1705,7 +1758,8 @@ static int sh_eth_poll(struct napi_struct *napi, int budget) | |||
1705 | napi_complete(napi); | 1758 | napi_complete(napi); |
1706 | 1759 | ||
1707 | /* Reenable Rx interrupts */ | 1760 | /* Reenable Rx interrupts */ |
1708 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 1761 | if (mdp->irq_enabled) |
1762 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | ||
1709 | out: | 1763 | out: |
1710 | return budget - quota; | 1764 | return budget - quota; |
1711 | } | 1765 | } |
@@ -1820,6 +1874,9 @@ static int sh_eth_get_settings(struct net_device *ndev, | |||
1820 | unsigned long flags; | 1874 | unsigned long flags; |
1821 | int ret; | 1875 | int ret; |
1822 | 1876 | ||
1877 | if (!mdp->phydev) | ||
1878 | return -ENODEV; | ||
1879 | |||
1823 | spin_lock_irqsave(&mdp->lock, flags); | 1880 | spin_lock_irqsave(&mdp->lock, flags); |
1824 | ret = phy_ethtool_gset(mdp->phydev, ecmd); | 1881 | ret = phy_ethtool_gset(mdp->phydev, ecmd); |
1825 | spin_unlock_irqrestore(&mdp->lock, flags); | 1882 | spin_unlock_irqrestore(&mdp->lock, flags); |
@@ -1834,6 +1891,9 @@ static int sh_eth_set_settings(struct net_device *ndev, | |||
1834 | unsigned long flags; | 1891 | unsigned long flags; |
1835 | int ret; | 1892 | int ret; |
1836 | 1893 | ||
1894 | if (!mdp->phydev) | ||
1895 | return -ENODEV; | ||
1896 | |||
1837 | spin_lock_irqsave(&mdp->lock, flags); | 1897 | spin_lock_irqsave(&mdp->lock, flags); |
1838 | 1898 | ||
1839 | /* disable tx and rx */ | 1899 | /* disable tx and rx */ |
@@ -1868,6 +1928,9 @@ static int sh_eth_nway_reset(struct net_device *ndev) | |||
1868 | unsigned long flags; | 1928 | unsigned long flags; |
1869 | int ret; | 1929 | int ret; |
1870 | 1930 | ||
1931 | if (!mdp->phydev) | ||
1932 | return -ENODEV; | ||
1933 | |||
1871 | spin_lock_irqsave(&mdp->lock, flags); | 1934 | spin_lock_irqsave(&mdp->lock, flags); |
1872 | ret = phy_start_aneg(mdp->phydev); | 1935 | ret = phy_start_aneg(mdp->phydev); |
1873 | spin_unlock_irqrestore(&mdp->lock, flags); | 1936 | spin_unlock_irqrestore(&mdp->lock, flags); |
@@ -1952,40 +2015,50 @@ static int sh_eth_set_ringparam(struct net_device *ndev, | |||
1952 | return -EINVAL; | 2015 | return -EINVAL; |
1953 | 2016 | ||
1954 | if (netif_running(ndev)) { | 2017 | if (netif_running(ndev)) { |
2018 | netif_device_detach(ndev); | ||
1955 | netif_tx_disable(ndev); | 2019 | netif_tx_disable(ndev); |
1956 | /* Disable interrupts by clearing the interrupt mask. */ | 2020 | |
1957 | sh_eth_write(ndev, 0x0000, EESIPR); | 2021 | /* Serialise with the interrupt handler and NAPI, then |
1958 | /* Stop the chip's Tx and Rx processes. */ | 2022 | * disable interrupts. We have to clear the |
1959 | sh_eth_write(ndev, 0, EDTRR); | 2023 | * irq_enabled flag first to ensure that interrupts |
1960 | sh_eth_write(ndev, 0, EDRRR); | 2024 | * won't be re-enabled. |
2025 | */ | ||
2026 | mdp->irq_enabled = false; | ||
1961 | synchronize_irq(ndev->irq); | 2027 | synchronize_irq(ndev->irq); |
1962 | } | 2028 | napi_synchronize(&mdp->napi); |
2029 | sh_eth_write(ndev, 0x0000, EESIPR); | ||
1963 | 2030 | ||
1964 | /* Free all the skbuffs in the Rx queue. */ | 2031 | sh_eth_dev_exit(ndev); |
1965 | sh_eth_ring_free(ndev); | 2032 | |
1966 | /* Free DMA buffer */ | 2033 | /* Free all the skbuffs in the Rx queue. */ |
1967 | sh_eth_free_dma_buffer(mdp); | 2034 | sh_eth_ring_free(ndev); |
2035 | /* Free DMA buffer */ | ||
2036 | sh_eth_free_dma_buffer(mdp); | ||
2037 | } | ||
1968 | 2038 | ||
1969 | /* Set new parameters */ | 2039 | /* Set new parameters */ |
1970 | mdp->num_rx_ring = ring->rx_pending; | 2040 | mdp->num_rx_ring = ring->rx_pending; |
1971 | mdp->num_tx_ring = ring->tx_pending; | 2041 | mdp->num_tx_ring = ring->tx_pending; |
1972 | 2042 | ||
1973 | ret = sh_eth_ring_init(ndev); | ||
1974 | if (ret < 0) { | ||
1975 | netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); | ||
1976 | return ret; | ||
1977 | } | ||
1978 | ret = sh_eth_dev_init(ndev, false); | ||
1979 | if (ret < 0) { | ||
1980 | netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); | ||
1981 | return ret; | ||
1982 | } | ||
1983 | |||
1984 | if (netif_running(ndev)) { | 2043 | if (netif_running(ndev)) { |
2044 | ret = sh_eth_ring_init(ndev); | ||
2045 | if (ret < 0) { | ||
2046 | netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", | ||
2047 | __func__); | ||
2048 | return ret; | ||
2049 | } | ||
2050 | ret = sh_eth_dev_init(ndev, false); | ||
2051 | if (ret < 0) { | ||
2052 | netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", | ||
2053 | __func__); | ||
2054 | return ret; | ||
2055 | } | ||
2056 | |||
2057 | mdp->irq_enabled = true; | ||
1985 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); | 2058 | sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); |
1986 | /* Setting the Rx mode will start the Rx process. */ | 2059 | /* Setting the Rx mode will start the Rx process. */ |
1987 | sh_eth_write(ndev, EDRRR_R, EDRRR); | 2060 | sh_eth_write(ndev, EDRRR_R, EDRRR); |
1988 | netif_wake_queue(ndev); | 2061 | netif_device_attach(ndev); |
1989 | } | 2062 | } |
1990 | 2063 | ||
1991 | return 0; | 2064 | return 0; |
@@ -2101,6 +2174,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
2101 | } | 2174 | } |
2102 | spin_unlock_irqrestore(&mdp->lock, flags); | 2175 | spin_unlock_irqrestore(&mdp->lock, flags); |
2103 | 2176 | ||
2177 | if (skb_padto(skb, ETH_ZLEN)) | ||
2178 | return NETDEV_TX_OK; | ||
2179 | |||
2104 | entry = mdp->cur_tx % mdp->num_tx_ring; | 2180 | entry = mdp->cur_tx % mdp->num_tx_ring; |
2105 | mdp->tx_skbuff[entry] = skb; | 2181 | mdp->tx_skbuff[entry] = skb; |
2106 | txdesc = &mdp->tx_ring[entry]; | 2182 | txdesc = &mdp->tx_ring[entry]; |
@@ -2110,10 +2186,11 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
2110 | skb->len + 2); | 2186 | skb->len + 2); |
2111 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, | 2187 | txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, |
2112 | DMA_TO_DEVICE); | 2188 | DMA_TO_DEVICE); |
2113 | if (skb->len < ETH_ZLEN) | 2189 | if (dma_mapping_error(&ndev->dev, txdesc->addr)) { |
2114 | txdesc->buffer_length = ETH_ZLEN; | 2190 | kfree_skb(skb); |
2115 | else | 2191 | return NETDEV_TX_OK; |
2116 | txdesc->buffer_length = skb->len; | 2192 | } |
2193 | txdesc->buffer_length = skb->len; | ||
2117 | 2194 | ||
2118 | if (entry >= mdp->num_tx_ring - 1) | 2195 | if (entry >= mdp->num_tx_ring - 1) |
2119 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); | 2196 | txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); |
@@ -2165,24 +2242,26 @@ static int sh_eth_close(struct net_device *ndev) | |||
2165 | 2242 | ||
2166 | netif_stop_queue(ndev); | 2243 | netif_stop_queue(ndev); |
2167 | 2244 | ||
2168 | /* Disable interrupts by clearing the interrupt mask. */ | 2245 | /* Serialise with the interrupt handler and NAPI, then disable |
2246 | * interrupts. We have to clear the irq_enabled flag first to | ||
2247 | * ensure that interrupts won't be re-enabled. | ||
2248 | */ | ||
2249 | mdp->irq_enabled = false; | ||
2250 | synchronize_irq(ndev->irq); | ||
2251 | napi_disable(&mdp->napi); | ||
2169 | sh_eth_write(ndev, 0x0000, EESIPR); | 2252 | sh_eth_write(ndev, 0x0000, EESIPR); |
2170 | 2253 | ||
2171 | /* Stop the chip's Tx and Rx processes. */ | 2254 | sh_eth_dev_exit(ndev); |
2172 | sh_eth_write(ndev, 0, EDTRR); | ||
2173 | sh_eth_write(ndev, 0, EDRRR); | ||
2174 | 2255 | ||
2175 | sh_eth_get_stats(ndev); | ||
2176 | /* PHY Disconnect */ | 2256 | /* PHY Disconnect */ |
2177 | if (mdp->phydev) { | 2257 | if (mdp->phydev) { |
2178 | phy_stop(mdp->phydev); | 2258 | phy_stop(mdp->phydev); |
2179 | phy_disconnect(mdp->phydev); | 2259 | phy_disconnect(mdp->phydev); |
2260 | mdp->phydev = NULL; | ||
2180 | } | 2261 | } |
2181 | 2262 | ||
2182 | free_irq(ndev->irq, ndev); | 2263 | free_irq(ndev->irq, ndev); |
2183 | 2264 | ||
2184 | napi_disable(&mdp->napi); | ||
2185 | |||
2186 | /* Free all the skbuffs in the Rx queue. */ | 2265 | /* Free all the skbuffs in the Rx queue. */ |
2187 | sh_eth_ring_free(ndev); | 2266 | sh_eth_ring_free(ndev); |
2188 | 2267 | ||
@@ -2410,7 +2489,7 @@ static int sh_eth_tsu_purge_all(struct net_device *ndev) | |||
2410 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2489 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2411 | int i, ret; | 2490 | int i, ret; |
2412 | 2491 | ||
2413 | if (unlikely(!mdp->cd->tsu)) | 2492 | if (!mdp->cd->tsu) |
2414 | return 0; | 2493 | return 0; |
2415 | 2494 | ||
2416 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { | 2495 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { |
@@ -2433,7 +2512,7 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2433 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); | 2512 | void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); |
2434 | int i; | 2513 | int i; |
2435 | 2514 | ||
2436 | if (unlikely(!mdp->cd->tsu)) | 2515 | if (!mdp->cd->tsu) |
2437 | return; | 2516 | return; |
2438 | 2517 | ||
2439 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { | 2518 | for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { |
@@ -2443,8 +2522,8 @@ static void sh_eth_tsu_purge_mcast(struct net_device *ndev) | |||
2443 | } | 2522 | } |
2444 | } | 2523 | } |
2445 | 2524 | ||
2446 | /* Multicast reception directions set */ | 2525 | /* Update promiscuous flag and multicast filter */ |
2447 | static void sh_eth_set_multicast_list(struct net_device *ndev) | 2526 | static void sh_eth_set_rx_mode(struct net_device *ndev) |
2448 | { | 2527 | { |
2449 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2528 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2450 | u32 ecmr_bits; | 2529 | u32 ecmr_bits; |
@@ -2455,7 +2534,9 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2455 | /* Initial condition is MCT = 1, PRM = 0. | 2534 | /* Initial condition is MCT = 1, PRM = 0. |
2456 | * Depending on ndev->flags, set PRM or clear MCT | 2535 | * Depending on ndev->flags, set PRM or clear MCT |
2457 | */ | 2536 | */ |
2458 | ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; | 2537 | ecmr_bits = sh_eth_read(ndev, ECMR) & ~ECMR_PRM; |
2538 | if (mdp->cd->tsu) | ||
2539 | ecmr_bits |= ECMR_MCT; | ||
2459 | 2540 | ||
2460 | if (!(ndev->flags & IFF_MULTICAST)) { | 2541 | if (!(ndev->flags & IFF_MULTICAST)) { |
2461 | sh_eth_tsu_purge_mcast(ndev); | 2542 | sh_eth_tsu_purge_mcast(ndev); |
@@ -2484,9 +2565,6 @@ static void sh_eth_set_multicast_list(struct net_device *ndev) | |||
2484 | } | 2565 | } |
2485 | } | 2566 | } |
2486 | } | 2567 | } |
2487 | } else { | ||
2488 | /* Normal, unicast/broadcast-only mode. */ | ||
2489 | ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; | ||
2490 | } | 2568 | } |
2491 | 2569 | ||
2492 | /* update the ethernet mode */ | 2570 | /* update the ethernet mode */ |
@@ -2694,6 +2772,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { | |||
2694 | .ndo_stop = sh_eth_close, | 2772 | .ndo_stop = sh_eth_close, |
2695 | .ndo_start_xmit = sh_eth_start_xmit, | 2773 | .ndo_start_xmit = sh_eth_start_xmit, |
2696 | .ndo_get_stats = sh_eth_get_stats, | 2774 | .ndo_get_stats = sh_eth_get_stats, |
2775 | .ndo_set_rx_mode = sh_eth_set_rx_mode, | ||
2697 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2776 | .ndo_tx_timeout = sh_eth_tx_timeout, |
2698 | .ndo_do_ioctl = sh_eth_do_ioctl, | 2777 | .ndo_do_ioctl = sh_eth_do_ioctl, |
2699 | .ndo_validate_addr = eth_validate_addr, | 2778 | .ndo_validate_addr = eth_validate_addr, |
@@ -2706,7 +2785,7 @@ static const struct net_device_ops sh_eth_netdev_ops_tsu = { | |||
2706 | .ndo_stop = sh_eth_close, | 2785 | .ndo_stop = sh_eth_close, |
2707 | .ndo_start_xmit = sh_eth_start_xmit, | 2786 | .ndo_start_xmit = sh_eth_start_xmit, |
2708 | .ndo_get_stats = sh_eth_get_stats, | 2787 | .ndo_get_stats = sh_eth_get_stats, |
2709 | .ndo_set_rx_mode = sh_eth_set_multicast_list, | 2788 | .ndo_set_rx_mode = sh_eth_set_rx_mode, |
2710 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, | 2789 | .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, |
2711 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, | 2790 | .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, |
2712 | .ndo_tx_timeout = sh_eth_tx_timeout, | 2791 | .ndo_tx_timeout = sh_eth_tx_timeout, |
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 22301bf9c21d..332d3c16d483 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
@@ -369,6 +369,8 @@ enum DESC_I_BIT { | |||
369 | DESC_I_RINT1 = 0x0001, | 369 | DESC_I_RINT1 = 0x0001, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | #define DEFAULT_TRSCER_ERR_MASK (DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2) | ||
373 | |||
372 | /* RPADIR */ | 374 | /* RPADIR */ |
373 | enum RPADIR_BIT { | 375 | enum RPADIR_BIT { |
374 | RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, | 376 | RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, |
@@ -470,6 +472,9 @@ struct sh_eth_cpu_data { | |||
470 | unsigned long tx_check; | 472 | unsigned long tx_check; |
471 | unsigned long eesr_err_check; | 473 | unsigned long eesr_err_check; |
472 | 474 | ||
475 | /* Error mask */ | ||
476 | unsigned long trscer_err_mask; | ||
477 | |||
473 | /* hardware features */ | 478 | /* hardware features */ |
474 | unsigned long irq_flags; /* IRQ configuration flags */ | 479 | unsigned long irq_flags; /* IRQ configuration flags */ |
475 | unsigned no_psr:1; /* EtherC DO NOT have PSR */ | 480 | unsigned no_psr:1; /* EtherC DO NOT have PSR */ |
@@ -508,6 +513,7 @@ struct sh_eth_private { | |||
508 | u32 rx_buf_sz; /* Based on MTU+slack. */ | 513 | u32 rx_buf_sz; /* Based on MTU+slack. */ |
509 | int edmac_endian; | 514 | int edmac_endian; |
510 | struct napi_struct napi; | 515 | struct napi_struct napi; |
516 | bool irq_enabled; | ||
511 | /* MII transceiver section. */ | 517 | /* MII transceiver section. */ |
512 | u32 phy_id; /* PHY ID */ | 518 | u32 phy_id; /* PHY ID */ |
513 | struct mii_bus *mii_bus; /* MDIO bus control */ | 519 | struct mii_bus *mii_bus; /* MDIO bus control */ |
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c deleted file mode 100644 index f537cbea20e5..000000000000 --- a/drivers/net/ethernet/s6gmac.c +++ /dev/null | |||
@@ -1,1058 +0,0 @@ | |||
1 | /* | ||
2 | * Ethernet driver for S6105 on chip network device | ||
3 | * (c)2008 emlix GmbH http://www.emlix.com | ||
4 | * Authors: Oskar Schirmer <oskar@scara.com> | ||
5 | * Daniel Gloeckner <dg@emlix.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | */ | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/netdevice.h> | ||
19 | #include <linux/etherdevice.h> | ||
20 | #include <linux/if.h> | ||
21 | #include <linux/stddef.h> | ||
22 | #include <linux/mii.h> | ||
23 | #include <linux/phy.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <variant/hardware.h> | ||
26 | #include <variant/dmac.h> | ||
27 | |||
28 | #define DRV_NAME "s6gmac" | ||
29 | #define DRV_PRMT DRV_NAME ": " | ||
30 | |||
31 | |||
32 | /* register declarations */ | ||
33 | |||
34 | #define S6_GMAC_MACCONF1 0x000 | ||
35 | #define S6_GMAC_MACCONF1_TXENA 0 | ||
36 | #define S6_GMAC_MACCONF1_SYNCTX 1 | ||
37 | #define S6_GMAC_MACCONF1_RXENA 2 | ||
38 | #define S6_GMAC_MACCONF1_SYNCRX 3 | ||
39 | #define S6_GMAC_MACCONF1_TXFLOWCTRL 4 | ||
40 | #define S6_GMAC_MACCONF1_RXFLOWCTRL 5 | ||
41 | #define S6_GMAC_MACCONF1_LOOPBACK 8 | ||
42 | #define S6_GMAC_MACCONF1_RESTXFUNC 16 | ||
43 | #define S6_GMAC_MACCONF1_RESRXFUNC 17 | ||
44 | #define S6_GMAC_MACCONF1_RESTXMACCTRL 18 | ||
45 | #define S6_GMAC_MACCONF1_RESRXMACCTRL 19 | ||
46 | #define S6_GMAC_MACCONF1_SIMULRES 30 | ||
47 | #define S6_GMAC_MACCONF1_SOFTRES 31 | ||
48 | #define S6_GMAC_MACCONF2 0x004 | ||
49 | #define S6_GMAC_MACCONF2_FULL 0 | ||
50 | #define S6_GMAC_MACCONF2_CRCENA 1 | ||
51 | #define S6_GMAC_MACCONF2_PADCRCENA 2 | ||
52 | #define S6_GMAC_MACCONF2_LENGTHFCHK 4 | ||
53 | #define S6_GMAC_MACCONF2_HUGEFRAMENA 5 | ||
54 | #define S6_GMAC_MACCONF2_IFMODE 8 | ||
55 | #define S6_GMAC_MACCONF2_IFMODE_NIBBLE 1 | ||
56 | #define S6_GMAC_MACCONF2_IFMODE_BYTE 2 | ||
57 | #define S6_GMAC_MACCONF2_IFMODE_MASK 3 | ||
58 | #define S6_GMAC_MACCONF2_PREAMBLELEN 12 | ||
59 | #define S6_GMAC_MACCONF2_PREAMBLELEN_MASK 0x0F | ||
60 | #define S6_GMAC_MACIPGIFG 0x008 | ||
61 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP 0 | ||
62 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP_MASK 0x7F | ||
63 | #define S6_GMAC_MACIPGIFG_MINIFGENFORCE 8 | ||
64 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP2 16 | ||
65 | #define S6_GMAC_MACIPGIFG_B2BINTERPGAP1 24 | ||
66 | #define S6_GMAC_MACHALFDUPLEX 0x00C | ||
67 | #define S6_GMAC_MACHALFDUPLEX_COLLISWIN 0 | ||
68 | #define S6_GMAC_MACHALFDUPLEX_COLLISWIN_MASK 0x3F | ||
69 | #define S6_GMAC_MACHALFDUPLEX_RETXMAX 12 | ||
70 | #define S6_GMAC_MACHALFDUPLEX_RETXMAX_MASK 0x0F | ||
71 | #define S6_GMAC_MACHALFDUPLEX_EXCESSDEF 16 | ||
72 | #define S6_GMAC_MACHALFDUPLEX_NOBACKOFF 17 | ||
73 | #define S6_GMAC_MACHALFDUPLEX_BPNOBCKOF 18 | ||
74 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBENA 19 | ||
75 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBTRN 20 | ||
76 | #define S6_GMAC_MACHALFDUPLEX_ALTBEBTR_MASK 0x0F | ||
77 | #define S6_GMAC_MACMAXFRAMELEN 0x010 | ||
78 | #define S6_GMAC_MACMIICONF 0x020 | ||
79 | #define S6_GMAC_MACMIICONF_CSEL 0 | ||
80 | #define S6_GMAC_MACMIICONF_CSEL_DIV10 0 | ||
81 | #define S6_GMAC_MACMIICONF_CSEL_DIV12 1 | ||
82 | #define S6_GMAC_MACMIICONF_CSEL_DIV14 2 | ||
83 | #define S6_GMAC_MACMIICONF_CSEL_DIV18 3 | ||
84 | #define S6_GMAC_MACMIICONF_CSEL_DIV24 4 | ||
85 | #define S6_GMAC_MACMIICONF_CSEL_DIV34 5 | ||
86 | #define S6_GMAC_MACMIICONF_CSEL_DIV68 6 | ||
87 | #define S6_GMAC_MACMIICONF_CSEL_DIV168 7 | ||
88 | #define S6_GMAC_MACMIICONF_CSEL_MASK 7 | ||
89 | #define S6_GMAC_MACMIICONF_PREAMBLESUPR 4 | ||
90 | #define S6_GMAC_MACMIICONF_SCANAUTOINCR 5 | ||
91 | #define S6_GMAC_MACMIICMD 0x024 | ||
92 | #define S6_GMAC_MACMIICMD_READ 0 | ||
93 | #define S6_GMAC_MACMIICMD_SCAN 1 | ||
94 | #define S6_GMAC_MACMIIADDR 0x028 | ||
95 | #define S6_GMAC_MACMIIADDR_REG 0 | ||
96 | #define S6_GMAC_MACMIIADDR_REG_MASK 0x1F | ||
97 | #define S6_GMAC_MACMIIADDR_PHY 8 | ||
98 | #define S6_GMAC_MACMIIADDR_PHY_MASK 0x1F | ||
99 | #define S6_GMAC_MACMIICTRL 0x02C | ||
100 | #define S6_GMAC_MACMIISTAT 0x030 | ||
101 | #define S6_GMAC_MACMIIINDI 0x034 | ||
102 | #define S6_GMAC_MACMIIINDI_BUSY 0 | ||
103 | #define S6_GMAC_MACMIIINDI_SCAN 1 | ||
104 | #define S6_GMAC_MACMIIINDI_INVAL 2 | ||
105 | #define S6_GMAC_MACINTERFSTAT 0x03C | ||
106 | #define S6_GMAC_MACINTERFSTAT_LINKFAIL 3 | ||
107 | #define S6_GMAC_MACINTERFSTAT_EXCESSDEF 9 | ||
108 | #define S6_GMAC_MACSTATADDR1 0x040 | ||
109 | #define S6_GMAC_MACSTATADDR2 0x044 | ||
110 | |||
111 | #define S6_GMAC_FIFOCONF0 0x048 | ||
112 | #define S6_GMAC_FIFOCONF0_HSTRSTWT 0 | ||
113 | #define S6_GMAC_FIFOCONF0_HSTRSTSR 1 | ||
114 | #define S6_GMAC_FIFOCONF0_HSTRSTFR 2 | ||
115 | #define S6_GMAC_FIFOCONF0_HSTRSTST 3 | ||
116 | #define S6_GMAC_FIFOCONF0_HSTRSTFT 4 | ||
117 | #define S6_GMAC_FIFOCONF0_WTMENREQ 8 | ||
118 | #define S6_GMAC_FIFOCONF0_SRFENREQ 9 | ||
119 | #define S6_GMAC_FIFOCONF0_FRFENREQ 10 | ||
120 | #define S6_GMAC_FIFOCONF0_STFENREQ 11 | ||
121 | #define S6_GMAC_FIFOCONF0_FTFENREQ 12 | ||
122 | #define S6_GMAC_FIFOCONF0_WTMENRPLY 16 | ||
123 | #define S6_GMAC_FIFOCONF0_SRFENRPLY 17 | ||
124 | #define S6_GMAC_FIFOCONF0_FRFENRPLY 18 | ||
125 | #define S6_GMAC_FIFOCONF0_STFENRPLY 19 | ||
126 | #define S6_GMAC_FIFOCONF0_FTFENRPLY 20 | ||
127 | #define S6_GMAC_FIFOCONF1 0x04C | ||
128 | #define S6_GMAC_FIFOCONF2 0x050 | ||
129 | #define S6_GMAC_FIFOCONF2_CFGLWM 0 | ||
130 | #define S6_GMAC_FIFOCONF2_CFGHWM 16 | ||
131 | #define S6_GMAC_FIFOCONF3 0x054 | ||
132 | #define S6_GMAC_FIFOCONF3_CFGFTTH 0 | ||
133 | #define S6_GMAC_FIFOCONF3_CFGHWMFT 16 | ||
134 | #define S6_GMAC_FIFOCONF4 0x058 | ||
135 | #define S6_GMAC_FIFOCONF_RSV_PREVDROP 0 | ||
136 | #define S6_GMAC_FIFOCONF_RSV_RUNT 1 | ||
137 | #define S6_GMAC_FIFOCONF_RSV_FALSECAR 2 | ||
138 | #define S6_GMAC_FIFOCONF_RSV_CODEERR 3 | ||
139 | #define S6_GMAC_FIFOCONF_RSV_CRCERR 4 | ||
140 | #define S6_GMAC_FIFOCONF_RSV_LENGTHERR 5 | ||
141 | #define S6_GMAC_FIFOCONF_RSV_LENRANGE 6 | ||
142 | #define S6_GMAC_FIFOCONF_RSV_OK 7 | ||
143 | #define S6_GMAC_FIFOCONF_RSV_MULTICAST 8 | ||
144 | #define S6_GMAC_FIFOCONF_RSV_BROADCAST 9 | ||
145 | #define S6_GMAC_FIFOCONF_RSV_DRIBBLE 10 | ||
146 | #define S6_GMAC_FIFOCONF_RSV_CTRLFRAME 11 | ||
147 | #define S6_GMAC_FIFOCONF_RSV_PAUSECTRL 12 | ||
148 | #define S6_GMAC_FIFOCONF_RSV_UNOPCODE 13 | ||
149 | #define S6_GMAC_FIFOCONF_RSV_VLANTAG 14 | ||
150 | #define S6_GMAC_FIFOCONF_RSV_LONGEVENT 15 | ||
151 | #define S6_GMAC_FIFOCONF_RSV_TRUNCATED 16 | ||
152 | #define S6_GMAC_FIFOCONF_RSV_MASK 0x3FFFF | ||
153 | #define S6_GMAC_FIFOCONF5 0x05C | ||
154 | #define S6_GMAC_FIFOCONF5_DROPLT64 18 | ||
155 | #define S6_GMAC_FIFOCONF5_CFGBYTM 19 | ||
156 | #define S6_GMAC_FIFOCONF5_RXDROPSIZE 20 | ||
157 | #define S6_GMAC_FIFOCONF5_RXDROPSIZE_MASK 0xF | ||
158 | |||
159 | #define S6_GMAC_STAT_REGS 0x080 | ||
160 | #define S6_GMAC_STAT_SIZE_MIN 12 | ||
161 | #define S6_GMAC_STATTR64 0x080 | ||
162 | #define S6_GMAC_STATTR64_SIZE 18 | ||
163 | #define S6_GMAC_STATTR127 0x084 | ||
164 | #define S6_GMAC_STATTR127_SIZE 18 | ||
165 | #define S6_GMAC_STATTR255 0x088 | ||
166 | #define S6_GMAC_STATTR255_SIZE 18 | ||
167 | #define S6_GMAC_STATTR511 0x08C | ||
168 | #define S6_GMAC_STATTR511_SIZE 18 | ||
169 | #define S6_GMAC_STATTR1K 0x090 | ||
170 | #define S6_GMAC_STATTR1K_SIZE 18 | ||
171 | #define S6_GMAC_STATTRMAX 0x094 | ||
172 | #define S6_GMAC_STATTRMAX_SIZE 18 | ||
173 | #define S6_GMAC_STATTRMGV 0x098 | ||
174 | #define S6_GMAC_STATTRMGV_SIZE 18 | ||
175 | #define S6_GMAC_STATRBYT 0x09C | ||
176 | #define S6_GMAC_STATRBYT_SIZE 24 | ||
177 | #define S6_GMAC_STATRPKT 0x0A0 | ||
178 | #define S6_GMAC_STATRPKT_SIZE 18 | ||
179 | #define S6_GMAC_STATRFCS 0x0A4 | ||
180 | #define S6_GMAC_STATRFCS_SIZE 12 | ||
181 | #define S6_GMAC_STATRMCA 0x0A8 | ||
182 | #define S6_GMAC_STATRMCA_SIZE 18 | ||
183 | #define S6_GMAC_STATRBCA 0x0AC | ||
184 | #define S6_GMAC_STATRBCA_SIZE 22 | ||
185 | #define S6_GMAC_STATRXCF 0x0B0 | ||
186 | #define S6_GMAC_STATRXCF_SIZE 18 | ||
187 | #define S6_GMAC_STATRXPF 0x0B4 | ||
188 | #define S6_GMAC_STATRXPF_SIZE 12 | ||
189 | #define S6_GMAC_STATRXUO 0x0B8 | ||
190 | #define S6_GMAC_STATRXUO_SIZE 12 | ||
191 | #define S6_GMAC_STATRALN 0x0BC | ||
192 | #define S6_GMAC_STATRALN_SIZE 12 | ||
193 | #define S6_GMAC_STATRFLR 0x0C0 | ||
194 | #define S6_GMAC_STATRFLR_SIZE 16 | ||
195 | #define S6_GMAC_STATRCDE 0x0C4 | ||
196 | #define S6_GMAC_STATRCDE_SIZE 12 | ||
197 | #define S6_GMAC_STATRCSE 0x0C8 | ||
198 | #define S6_GMAC_STATRCSE_SIZE 12 | ||
199 | #define S6_GMAC_STATRUND 0x0CC | ||
200 | #define S6_GMAC_STATRUND_SIZE 12 | ||
201 | #define S6_GMAC_STATROVR 0x0D0 | ||
202 | #define S6_GMAC_STATROVR_SIZE 12 | ||
203 | #define S6_GMAC_STATRFRG 0x0D4 | ||
204 | #define S6_GMAC_STATRFRG_SIZE 12 | ||
205 | #define S6_GMAC_STATRJBR 0x0D8 | ||
206 | #define S6_GMAC_STATRJBR_SIZE 12 | ||
207 | #define S6_GMAC_STATRDRP 0x0DC | ||
208 | #define S6_GMAC_STATRDRP_SIZE 12 | ||
209 | #define S6_GMAC_STATTBYT 0x0E0 | ||
210 | #define S6_GMAC_STATTBYT_SIZE 24 | ||
211 | #define S6_GMAC_STATTPKT 0x0E4 | ||
212 | #define S6_GMAC_STATTPKT_SIZE 18 | ||
213 | #define S6_GMAC_STATTMCA 0x0E8 | ||
214 | #define S6_GMAC_STATTMCA_SIZE 18 | ||
215 | #define S6_GMAC_STATTBCA 0x0EC | ||
216 | #define S6_GMAC_STATTBCA_SIZE 18 | ||
217 | #define S6_GMAC_STATTXPF 0x0F0 | ||
218 | #define S6_GMAC_STATTXPF_SIZE 12 | ||
219 | #define S6_GMAC_STATTDFR 0x0F4 | ||
220 | #define S6_GMAC_STATTDFR_SIZE 12 | ||
221 | #define S6_GMAC_STATTEDF 0x0F8 | ||
222 | #define S6_GMAC_STATTEDF_SIZE 12 | ||
223 | #define S6_GMAC_STATTSCL 0x0FC | ||
224 | #define S6_GMAC_STATTSCL_SIZE 12 | ||
225 | #define S6_GMAC_STATTMCL 0x100 | ||
226 | #define S6_GMAC_STATTMCL_SIZE 12 | ||
227 | #define S6_GMAC_STATTLCL 0x104 | ||
228 | #define S6_GMAC_STATTLCL_SIZE 12 | ||
229 | #define S6_GMAC_STATTXCL 0x108 | ||
230 | #define S6_GMAC_STATTXCL_SIZE 12 | ||
231 | #define S6_GMAC_STATTNCL 0x10C | ||
232 | #define S6_GMAC_STATTNCL_SIZE 13 | ||
233 | #define S6_GMAC_STATTPFH 0x110 | ||
234 | #define S6_GMAC_STATTPFH_SIZE 12 | ||
235 | #define S6_GMAC_STATTDRP 0x114 | ||
236 | #define S6_GMAC_STATTDRP_SIZE 12 | ||
237 | #define S6_GMAC_STATTJBR 0x118 | ||
238 | #define S6_GMAC_STATTJBR_SIZE 12 | ||
239 | #define S6_GMAC_STATTFCS 0x11C | ||
240 | #define S6_GMAC_STATTFCS_SIZE 12 | ||
241 | #define S6_GMAC_STATTXCF 0x120 | ||
242 | #define S6_GMAC_STATTXCF_SIZE 12 | ||
243 | #define S6_GMAC_STATTOVR 0x124 | ||
244 | #define S6_GMAC_STATTOVR_SIZE 12 | ||
245 | #define S6_GMAC_STATTUND 0x128 | ||
246 | #define S6_GMAC_STATTUND_SIZE 12 | ||
247 | #define S6_GMAC_STATTFRG 0x12C | ||
248 | #define S6_GMAC_STATTFRG_SIZE 12 | ||
249 | #define S6_GMAC_STATCARRY(n) (0x130 + 4*(n)) | ||
250 | #define S6_GMAC_STATCARRYMSK(n) (0x138 + 4*(n)) | ||
251 | #define S6_GMAC_STATCARRY1_RDRP 0 | ||
252 | #define S6_GMAC_STATCARRY1_RJBR 1 | ||
253 | #define S6_GMAC_STATCARRY1_RFRG 2 | ||
254 | #define S6_GMAC_STATCARRY1_ROVR 3 | ||
255 | #define S6_GMAC_STATCARRY1_RUND 4 | ||
256 | #define S6_GMAC_STATCARRY1_RCSE 5 | ||
257 | #define S6_GMAC_STATCARRY1_RCDE 6 | ||
258 | #define S6_GMAC_STATCARRY1_RFLR 7 | ||
259 | #define S6_GMAC_STATCARRY1_RALN 8 | ||
260 | #define S6_GMAC_STATCARRY1_RXUO 9 | ||
261 | #define S6_GMAC_STATCARRY1_RXPF 10 | ||
262 | #define S6_GMAC_STATCARRY1_RXCF 11 | ||
263 | #define S6_GMAC_STATCARRY1_RBCA 12 | ||
264 | #define S6_GMAC_STATCARRY1_RMCA 13 | ||
265 | #define S6_GMAC_STATCARRY1_RFCS 14 | ||
266 | #define S6_GMAC_STATCARRY1_RPKT 15 | ||
267 | #define S6_GMAC_STATCARRY1_RBYT 16 | ||
268 | #define S6_GMAC_STATCARRY1_TRMGV 25 | ||
269 | #define S6_GMAC_STATCARRY1_TRMAX 26 | ||
270 | #define S6_GMAC_STATCARRY1_TR1K 27 | ||
271 | #define S6_GMAC_STATCARRY1_TR511 28 | ||
272 | #define S6_GMAC_STATCARRY1_TR255 29 | ||
273 | #define S6_GMAC_STATCARRY1_TR127 30 | ||
274 | #define S6_GMAC_STATCARRY1_TR64 31 | ||
275 | #define S6_GMAC_STATCARRY2_TDRP 0 | ||
276 | #define S6_GMAC_STATCARRY2_TPFH 1 | ||
277 | #define S6_GMAC_STATCARRY2_TNCL 2 | ||
278 | #define S6_GMAC_STATCARRY2_TXCL 3 | ||
279 | #define S6_GMAC_STATCARRY2_TLCL 4 | ||
280 | #define S6_GMAC_STATCARRY2_TMCL 5 | ||
281 | #define S6_GMAC_STATCARRY2_TSCL 6 | ||
282 | #define S6_GMAC_STATCARRY2_TEDF 7 | ||
283 | #define S6_GMAC_STATCARRY2_TDFR 8 | ||
284 | #define S6_GMAC_STATCARRY2_TXPF 9 | ||
285 | #define S6_GMAC_STATCARRY2_TBCA 10 | ||
286 | #define S6_GMAC_STATCARRY2_TMCA 11 | ||
287 | #define S6_GMAC_STATCARRY2_TPKT 12 | ||
288 | #define S6_GMAC_STATCARRY2_TBYT 13 | ||
289 | #define S6_GMAC_STATCARRY2_TFRG 14 | ||
290 | #define S6_GMAC_STATCARRY2_TUND 15 | ||
291 | #define S6_GMAC_STATCARRY2_TOVR 16 | ||
292 | #define S6_GMAC_STATCARRY2_TXCF 17 | ||
293 | #define S6_GMAC_STATCARRY2_TFCS 18 | ||
294 | #define S6_GMAC_STATCARRY2_TJBR 19 | ||
295 | |||
296 | #define S6_GMAC_HOST_PBLKCTRL 0x140 | ||
297 | #define S6_GMAC_HOST_PBLKCTRL_TXENA 0 | ||
298 | #define S6_GMAC_HOST_PBLKCTRL_RXENA 1 | ||
299 | #define S6_GMAC_HOST_PBLKCTRL_TXSRES 2 | ||
300 | #define S6_GMAC_HOST_PBLKCTRL_RXSRES 3 | ||
301 | #define S6_GMAC_HOST_PBLKCTRL_TXBSIZ 8 | ||
302 | #define S6_GMAC_HOST_PBLKCTRL_RXBSIZ 12 | ||
303 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_16 4 | ||
304 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_32 5 | ||
305 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_64 6 | ||
306 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_128 7 | ||
307 | #define S6_GMAC_HOST_PBLKCTRL_SIZ_MASK 0xF | ||
308 | #define S6_GMAC_HOST_PBLKCTRL_STATENA 16 | ||
309 | #define S6_GMAC_HOST_PBLKCTRL_STATAUTOZ 17 | ||
310 | #define S6_GMAC_HOST_PBLKCTRL_STATCLEAR 18 | ||
311 | #define S6_GMAC_HOST_PBLKCTRL_RGMII 19 | ||
312 | #define S6_GMAC_HOST_INTMASK 0x144 | ||
313 | #define S6_GMAC_HOST_INTSTAT 0x148 | ||
314 | #define S6_GMAC_HOST_INT_TXBURSTOVER 3 | ||
315 | #define S6_GMAC_HOST_INT_TXPREWOVER 4 | ||
316 | #define S6_GMAC_HOST_INT_RXBURSTUNDER 5 | ||
317 | #define S6_GMAC_HOST_INT_RXPOSTRFULL 6 | ||
318 | #define S6_GMAC_HOST_INT_RXPOSTRUNDER 7 | ||
319 | #define S6_GMAC_HOST_RXFIFOHWM 0x14C | ||
320 | #define S6_GMAC_HOST_CTRLFRAMXP 0x150 | ||
321 | #define S6_GMAC_HOST_DSTADDRLO(n) (0x160 + 8*(n)) | ||
322 | #define S6_GMAC_HOST_DSTADDRHI(n) (0x164 + 8*(n)) | ||
323 | #define S6_GMAC_HOST_DSTMASKLO(n) (0x180 + 8*(n)) | ||
324 | #define S6_GMAC_HOST_DSTMASKHI(n) (0x184 + 8*(n)) | ||
325 | |||
326 | #define S6_GMAC_BURST_PREWR 0x1B0 | ||
327 | #define S6_GMAC_BURST_PREWR_LEN 0 | ||
328 | #define S6_GMAC_BURST_PREWR_LEN_MASK ((1 << 20) - 1) | ||
329 | #define S6_GMAC_BURST_PREWR_CFE 20 | ||
330 | #define S6_GMAC_BURST_PREWR_PPE 21 | ||
331 | #define S6_GMAC_BURST_PREWR_FCS 22 | ||
332 | #define S6_GMAC_BURST_PREWR_PAD 23 | ||
333 | #define S6_GMAC_BURST_POSTRD 0x1D0 | ||
334 | #define S6_GMAC_BURST_POSTRD_LEN 0 | ||
335 | #define S6_GMAC_BURST_POSTRD_LEN_MASK ((1 << 20) - 1) | ||
336 | #define S6_GMAC_BURST_POSTRD_DROP 20 | ||
337 | |||
338 | |||
339 | /* data handling */ | ||
340 | |||
341 | #define S6_NUM_TX_SKB 8 /* must be larger than TX fifo size */ | ||
342 | #define S6_NUM_RX_SKB 16 | ||
343 | #define S6_MAX_FRLEN 1536 | ||
344 | |||
345 | struct s6gmac { | ||
346 | u32 reg; | ||
347 | u32 tx_dma; | ||
348 | u32 rx_dma; | ||
349 | u32 io; | ||
350 | u8 tx_chan; | ||
351 | u8 rx_chan; | ||
352 | spinlock_t lock; | ||
353 | u8 tx_skb_i, tx_skb_o; | ||
354 | u8 rx_skb_i, rx_skb_o; | ||
355 | struct sk_buff *tx_skb[S6_NUM_TX_SKB]; | ||
356 | struct sk_buff *rx_skb[S6_NUM_RX_SKB]; | ||
357 | unsigned long carry[sizeof(struct net_device_stats) / sizeof(long)]; | ||
358 | unsigned long stats[sizeof(struct net_device_stats) / sizeof(long)]; | ||
359 | struct phy_device *phydev; | ||
360 | struct { | ||
361 | struct mii_bus *bus; | ||
362 | int irq[PHY_MAX_ADDR]; | ||
363 | } mii; | ||
364 | struct { | ||
365 | unsigned int mbit; | ||
366 | u8 giga; | ||
367 | u8 isup; | ||
368 | u8 full; | ||
369 | } link; | ||
370 | }; | ||
371 | |||
372 | static void s6gmac_rx_fillfifo(struct net_device *dev) | ||
373 | { | ||
374 | struct s6gmac *pd = netdev_priv(dev); | ||
375 | struct sk_buff *skb; | ||
376 | while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) && | ||
377 | (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) && | ||
378 | (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) { | ||
379 | pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb; | ||
380 | s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan, | ||
381 | pd->io, (u32)skb->data, S6_MAX_FRLEN); | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static void s6gmac_rx_interrupt(struct net_device *dev) | ||
386 | { | ||
387 | struct s6gmac *pd = netdev_priv(dev); | ||
388 | u32 pfx; | ||
389 | struct sk_buff *skb; | ||
390 | while (((u8)(pd->rx_skb_i - pd->rx_skb_o)) > | ||
391 | s6dmac_pending_count(pd->rx_dma, pd->rx_chan)) { | ||
392 | skb = pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]; | ||
393 | pfx = readl(pd->reg + S6_GMAC_BURST_POSTRD); | ||
394 | if (pfx & (1 << S6_GMAC_BURST_POSTRD_DROP)) { | ||
395 | dev_kfree_skb_irq(skb); | ||
396 | } else { | ||
397 | skb_put(skb, (pfx >> S6_GMAC_BURST_POSTRD_LEN) | ||
398 | & S6_GMAC_BURST_POSTRD_LEN_MASK); | ||
399 | skb->protocol = eth_type_trans(skb, dev); | ||
400 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
401 | netif_rx(skb); | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | static void s6gmac_tx_interrupt(struct net_device *dev) | ||
407 | { | ||
408 | struct s6gmac *pd = netdev_priv(dev); | ||
409 | while (((u8)(pd->tx_skb_i - pd->tx_skb_o)) > | ||
410 | s6dmac_pending_count(pd->tx_dma, pd->tx_chan)) { | ||
411 | dev_kfree_skb_irq(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); | ||
412 | } | ||
413 | if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
414 | netif_wake_queue(dev); | ||
415 | } | ||
416 | |||
417 | struct s6gmac_statinf { | ||
418 | unsigned reg_size : 4; /* 0: unused */ | ||
419 | unsigned reg_off : 6; | ||
420 | unsigned net_index : 6; | ||
421 | }; | ||
422 | |||
423 | #define S6_STATS_B (8 * sizeof(u32)) | ||
424 | #define S6_STATS_C(b, r, f) [b] = { \ | ||
425 | BUILD_BUG_ON_ZERO(r##_SIZE < S6_GMAC_STAT_SIZE_MIN) + \ | ||
426 | BUILD_BUG_ON_ZERO((r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1)) \ | ||
427 | >= (1<<4)) + \ | ||
428 | r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1), \ | ||
429 | BUILD_BUG_ON_ZERO(((unsigned)((r - S6_GMAC_STAT_REGS) / sizeof(u32))) \ | ||
430 | >= ((1<<6)-1)) + \ | ||
431 | (r - S6_GMAC_STAT_REGS) / sizeof(u32), \ | ||
432 | BUILD_BUG_ON_ZERO((offsetof(struct net_device_stats, f)) \ | ||
433 | % sizeof(unsigned long)) + \ | ||
434 | BUILD_BUG_ON_ZERO((((unsigned)(offsetof(struct net_device_stats, f)) \ | ||
435 | / sizeof(unsigned long)) >= (1<<6))) + \ | ||
436 | BUILD_BUG_ON_ZERO((sizeof(((struct net_device_stats *)0)->f) \ | ||
437 | != sizeof(unsigned long))) + \ | ||
438 | (offsetof(struct net_device_stats, f)) / sizeof(unsigned long)}, | ||
439 | |||
440 | static const struct s6gmac_statinf statinf[2][S6_STATS_B] = { { | ||
441 | S6_STATS_C(S6_GMAC_STATCARRY1_RBYT, S6_GMAC_STATRBYT, rx_bytes) | ||
442 | S6_STATS_C(S6_GMAC_STATCARRY1_RPKT, S6_GMAC_STATRPKT, rx_packets) | ||
443 | S6_STATS_C(S6_GMAC_STATCARRY1_RFCS, S6_GMAC_STATRFCS, rx_crc_errors) | ||
444 | S6_STATS_C(S6_GMAC_STATCARRY1_RMCA, S6_GMAC_STATRMCA, multicast) | ||
445 | S6_STATS_C(S6_GMAC_STATCARRY1_RALN, S6_GMAC_STATRALN, rx_frame_errors) | ||
446 | S6_STATS_C(S6_GMAC_STATCARRY1_RFLR, S6_GMAC_STATRFLR, rx_length_errors) | ||
447 | S6_STATS_C(S6_GMAC_STATCARRY1_RCDE, S6_GMAC_STATRCDE, rx_missed_errors) | ||
448 | S6_STATS_C(S6_GMAC_STATCARRY1_RUND, S6_GMAC_STATRUND, rx_length_errors) | ||
449 | S6_STATS_C(S6_GMAC_STATCARRY1_ROVR, S6_GMAC_STATROVR, rx_length_errors) | ||
450 | S6_STATS_C(S6_GMAC_STATCARRY1_RFRG, S6_GMAC_STATRFRG, rx_crc_errors) | ||
451 | S6_STATS_C(S6_GMAC_STATCARRY1_RJBR, S6_GMAC_STATRJBR, rx_crc_errors) | ||
452 | S6_STATS_C(S6_GMAC_STATCARRY1_RDRP, S6_GMAC_STATRDRP, rx_dropped) | ||
453 | }, { | ||
454 | S6_STATS_C(S6_GMAC_STATCARRY2_TBYT, S6_GMAC_STATTBYT, tx_bytes) | ||
455 | S6_STATS_C(S6_GMAC_STATCARRY2_TPKT, S6_GMAC_STATTPKT, tx_packets) | ||
456 | S6_STATS_C(S6_GMAC_STATCARRY2_TEDF, S6_GMAC_STATTEDF, tx_aborted_errors) | ||
457 | S6_STATS_C(S6_GMAC_STATCARRY2_TXCL, S6_GMAC_STATTXCL, tx_aborted_errors) | ||
458 | S6_STATS_C(S6_GMAC_STATCARRY2_TNCL, S6_GMAC_STATTNCL, collisions) | ||
459 | S6_STATS_C(S6_GMAC_STATCARRY2_TDRP, S6_GMAC_STATTDRP, tx_dropped) | ||
460 | S6_STATS_C(S6_GMAC_STATCARRY2_TJBR, S6_GMAC_STATTJBR, tx_errors) | ||
461 | S6_STATS_C(S6_GMAC_STATCARRY2_TFCS, S6_GMAC_STATTFCS, tx_errors) | ||
462 | S6_STATS_C(S6_GMAC_STATCARRY2_TOVR, S6_GMAC_STATTOVR, tx_errors) | ||
463 | S6_STATS_C(S6_GMAC_STATCARRY2_TUND, S6_GMAC_STATTUND, tx_errors) | ||
464 | S6_STATS_C(S6_GMAC_STATCARRY2_TFRG, S6_GMAC_STATTFRG, tx_errors) | ||
465 | } }; | ||
466 | |||
467 | static void s6gmac_stats_collect(struct s6gmac *pd, | ||
468 | const struct s6gmac_statinf *inf) | ||
469 | { | ||
470 | int b; | ||
471 | for (b = 0; b < S6_STATS_B; b++) { | ||
472 | if (inf[b].reg_size) { | ||
473 | pd->stats[inf[b].net_index] += | ||
474 | readl(pd->reg + S6_GMAC_STAT_REGS | ||
475 | + sizeof(u32) * inf[b].reg_off); | ||
476 | } | ||
477 | } | ||
478 | } | ||
479 | |||
480 | static void s6gmac_stats_carry(struct s6gmac *pd, | ||
481 | const struct s6gmac_statinf *inf, u32 mask) | ||
482 | { | ||
483 | int b; | ||
484 | while (mask) { | ||
485 | b = fls(mask) - 1; | ||
486 | mask &= ~(1 << b); | ||
487 | pd->carry[inf[b].net_index] += (1 << inf[b].reg_size); | ||
488 | } | ||
489 | } | ||
490 | |||
491 | static inline u32 s6gmac_stats_pending(struct s6gmac *pd, int carry) | ||
492 | { | ||
493 | int r = readl(pd->reg + S6_GMAC_STATCARRY(carry)) & | ||
494 | ~readl(pd->reg + S6_GMAC_STATCARRYMSK(carry)); | ||
495 | return r; | ||
496 | } | ||
497 | |||
498 | static inline void s6gmac_stats_interrupt(struct s6gmac *pd, int carry) | ||
499 | { | ||
500 | u32 mask; | ||
501 | mask = s6gmac_stats_pending(pd, carry); | ||
502 | if (mask) { | ||
503 | writel(mask, pd->reg + S6_GMAC_STATCARRY(carry)); | ||
504 | s6gmac_stats_carry(pd, &statinf[carry][0], mask); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | static irqreturn_t s6gmac_interrupt(int irq, void *dev_id) | ||
509 | { | ||
510 | struct net_device *dev = (struct net_device *)dev_id; | ||
511 | struct s6gmac *pd = netdev_priv(dev); | ||
512 | if (!dev) | ||
513 | return IRQ_NONE; | ||
514 | spin_lock(&pd->lock); | ||
515 | if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan)) | ||
516 | s6gmac_rx_interrupt(dev); | ||
517 | s6gmac_rx_fillfifo(dev); | ||
518 | if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan)) | ||
519 | s6gmac_tx_interrupt(dev); | ||
520 | s6gmac_stats_interrupt(pd, 0); | ||
521 | s6gmac_stats_interrupt(pd, 1); | ||
522 | spin_unlock(&pd->lock); | ||
523 | return IRQ_HANDLED; | ||
524 | } | ||
525 | |||
526 | static inline void s6gmac_set_dstaddr(struct s6gmac *pd, int n, | ||
527 | u32 addrlo, u32 addrhi, u32 masklo, u32 maskhi) | ||
528 | { | ||
529 | writel(addrlo, pd->reg + S6_GMAC_HOST_DSTADDRLO(n)); | ||
530 | writel(addrhi, pd->reg + S6_GMAC_HOST_DSTADDRHI(n)); | ||
531 | writel(masklo, pd->reg + S6_GMAC_HOST_DSTMASKLO(n)); | ||
532 | writel(maskhi, pd->reg + S6_GMAC_HOST_DSTMASKHI(n)); | ||
533 | } | ||
534 | |||
535 | static inline void s6gmac_stop_device(struct net_device *dev) | ||
536 | { | ||
537 | struct s6gmac *pd = netdev_priv(dev); | ||
538 | writel(0, pd->reg + S6_GMAC_MACCONF1); | ||
539 | } | ||
540 | |||
541 | static inline void s6gmac_init_device(struct net_device *dev) | ||
542 | { | ||
543 | struct s6gmac *pd = netdev_priv(dev); | ||
544 | int is_rgmii = !!(pd->phydev->supported | ||
545 | & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)); | ||
546 | #if 0 | ||
547 | writel(1 << S6_GMAC_MACCONF1_SYNCTX | | ||
548 | 1 << S6_GMAC_MACCONF1_SYNCRX | | ||
549 | 1 << S6_GMAC_MACCONF1_TXFLOWCTRL | | ||
550 | 1 << S6_GMAC_MACCONF1_RXFLOWCTRL | | ||
551 | 1 << S6_GMAC_MACCONF1_RESTXFUNC | | ||
552 | 1 << S6_GMAC_MACCONF1_RESRXFUNC | | ||
553 | 1 << S6_GMAC_MACCONF1_RESTXMACCTRL | | ||
554 | 1 << S6_GMAC_MACCONF1_RESRXMACCTRL, | ||
555 | pd->reg + S6_GMAC_MACCONF1); | ||
556 | #endif | ||
557 | writel(1 << S6_GMAC_MACCONF1_SOFTRES, pd->reg + S6_GMAC_MACCONF1); | ||
558 | udelay(1000); | ||
559 | writel(1 << S6_GMAC_MACCONF1_TXENA | 1 << S6_GMAC_MACCONF1_RXENA, | ||
560 | pd->reg + S6_GMAC_MACCONF1); | ||
561 | writel(1 << S6_GMAC_HOST_PBLKCTRL_TXSRES | | ||
562 | 1 << S6_GMAC_HOST_PBLKCTRL_RXSRES, | ||
563 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
564 | writel(S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | | ||
565 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | | ||
566 | 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | | ||
567 | 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | | ||
568 | is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, | ||
569 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
570 | writel(1 << S6_GMAC_MACCONF1_TXENA | | ||
571 | 1 << S6_GMAC_MACCONF1_RXENA | | ||
572 | (dev->flags & IFF_LOOPBACK ? 1 : 0) | ||
573 | << S6_GMAC_MACCONF1_LOOPBACK, | ||
574 | pd->reg + S6_GMAC_MACCONF1); | ||
575 | writel(dev->mtu && (dev->mtu < (S6_MAX_FRLEN - ETH_HLEN-ETH_FCS_LEN)) ? | ||
576 | dev->mtu+ETH_HLEN+ETH_FCS_LEN : S6_MAX_FRLEN, | ||
577 | pd->reg + S6_GMAC_MACMAXFRAMELEN); | ||
578 | writel((pd->link.full ? 1 : 0) << S6_GMAC_MACCONF2_FULL | | ||
579 | 1 << S6_GMAC_MACCONF2_PADCRCENA | | ||
580 | 1 << S6_GMAC_MACCONF2_LENGTHFCHK | | ||
581 | (pd->link.giga ? | ||
582 | S6_GMAC_MACCONF2_IFMODE_BYTE : | ||
583 | S6_GMAC_MACCONF2_IFMODE_NIBBLE) | ||
584 | << S6_GMAC_MACCONF2_IFMODE | | ||
585 | 7 << S6_GMAC_MACCONF2_PREAMBLELEN, | ||
586 | pd->reg + S6_GMAC_MACCONF2); | ||
587 | writel(0, pd->reg + S6_GMAC_MACSTATADDR1); | ||
588 | writel(0, pd->reg + S6_GMAC_MACSTATADDR2); | ||
589 | writel(1 << S6_GMAC_FIFOCONF0_WTMENREQ | | ||
590 | 1 << S6_GMAC_FIFOCONF0_SRFENREQ | | ||
591 | 1 << S6_GMAC_FIFOCONF0_FRFENREQ | | ||
592 | 1 << S6_GMAC_FIFOCONF0_STFENREQ | | ||
593 | 1 << S6_GMAC_FIFOCONF0_FTFENREQ, | ||
594 | pd->reg + S6_GMAC_FIFOCONF0); | ||
595 | writel(128 << S6_GMAC_FIFOCONF3_CFGFTTH | | ||
596 | 128 << S6_GMAC_FIFOCONF3_CFGHWMFT, | ||
597 | pd->reg + S6_GMAC_FIFOCONF3); | ||
598 | writel((S6_GMAC_FIFOCONF_RSV_MASK & ~( | ||
599 | 1 << S6_GMAC_FIFOCONF_RSV_RUNT | | ||
600 | 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | | ||
601 | 1 << S6_GMAC_FIFOCONF_RSV_OK | | ||
602 | 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | | ||
603 | 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | | ||
604 | 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | | ||
605 | 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | | ||
606 | 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED)) | | ||
607 | 1 << S6_GMAC_FIFOCONF5_DROPLT64 | | ||
608 | pd->link.giga << S6_GMAC_FIFOCONF5_CFGBYTM | | ||
609 | 1 << S6_GMAC_FIFOCONF5_RXDROPSIZE, | ||
610 | pd->reg + S6_GMAC_FIFOCONF5); | ||
611 | writel(1 << S6_GMAC_FIFOCONF_RSV_RUNT | | ||
612 | 1 << S6_GMAC_FIFOCONF_RSV_CRCERR | | ||
613 | 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE | | ||
614 | 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME | | ||
615 | 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL | | ||
616 | 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE | | ||
617 | 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED, | ||
618 | pd->reg + S6_GMAC_FIFOCONF4); | ||
619 | s6gmac_set_dstaddr(pd, 0, | ||
620 | 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF); | ||
621 | s6gmac_set_dstaddr(pd, 1, | ||
622 | dev->dev_addr[5] | | ||
623 | dev->dev_addr[4] << 8 | | ||
624 | dev->dev_addr[3] << 16 | | ||
625 | dev->dev_addr[2] << 24, | ||
626 | dev->dev_addr[1] | | ||
627 | dev->dev_addr[0] << 8, | ||
628 | 0xFFFFFFFF, 0x0000FFFF); | ||
629 | s6gmac_set_dstaddr(pd, 2, | ||
630 | 0x00000000, 0x00000100, 0x00000000, 0x00000100); | ||
631 | s6gmac_set_dstaddr(pd, 3, | ||
632 | 0x00000000, 0x00000000, 0x00000000, 0x00000000); | ||
633 | writel(1 << S6_GMAC_HOST_PBLKCTRL_TXENA | | ||
634 | 1 << S6_GMAC_HOST_PBLKCTRL_RXENA | | ||
635 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ | | ||
636 | S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ | | ||
637 | 1 << S6_GMAC_HOST_PBLKCTRL_STATENA | | ||
638 | 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR | | ||
639 | is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII, | ||
640 | pd->reg + S6_GMAC_HOST_PBLKCTRL); | ||
641 | } | ||
642 | |||
643 | static void s6mii_enable(struct s6gmac *pd) | ||
644 | { | ||
645 | writel(readl(pd->reg + S6_GMAC_MACCONF1) & | ||
646 | ~(1 << S6_GMAC_MACCONF1_SOFTRES), | ||
647 | pd->reg + S6_GMAC_MACCONF1); | ||
648 | writel((readl(pd->reg + S6_GMAC_MACMIICONF) | ||
649 | & ~(S6_GMAC_MACMIICONF_CSEL_MASK << S6_GMAC_MACMIICONF_CSEL)) | ||
650 | | (S6_GMAC_MACMIICONF_CSEL_DIV168 << S6_GMAC_MACMIICONF_CSEL), | ||
651 | pd->reg + S6_GMAC_MACMIICONF); | ||
652 | } | ||
653 | |||
654 | static int s6mii_busy(struct s6gmac *pd, int tmo) | ||
655 | { | ||
656 | while (readl(pd->reg + S6_GMAC_MACMIIINDI)) { | ||
657 | if (--tmo == 0) | ||
658 | return -ETIME; | ||
659 | udelay(64); | ||
660 | } | ||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum) | ||
665 | { | ||
666 | struct s6gmac *pd = bus->priv; | ||
667 | s6mii_enable(pd); | ||
668 | if (s6mii_busy(pd, 256)) | ||
669 | return -ETIME; | ||
670 | writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | | ||
671 | regnum << S6_GMAC_MACMIIADDR_REG, | ||
672 | pd->reg + S6_GMAC_MACMIIADDR); | ||
673 | writel(1 << S6_GMAC_MACMIICMD_READ, pd->reg + S6_GMAC_MACMIICMD); | ||
674 | writel(0, pd->reg + S6_GMAC_MACMIICMD); | ||
675 | if (s6mii_busy(pd, 256)) | ||
676 | return -ETIME; | ||
677 | return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT); | ||
678 | } | ||
679 | |||
680 | static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value) | ||
681 | { | ||
682 | struct s6gmac *pd = bus->priv; | ||
683 | s6mii_enable(pd); | ||
684 | if (s6mii_busy(pd, 256)) | ||
685 | return -ETIME; | ||
686 | writel(phy_addr << S6_GMAC_MACMIIADDR_PHY | | ||
687 | regnum << S6_GMAC_MACMIIADDR_REG, | ||
688 | pd->reg + S6_GMAC_MACMIIADDR); | ||
689 | writel(value, pd->reg + S6_GMAC_MACMIICTRL); | ||
690 | if (s6mii_busy(pd, 256)) | ||
691 | return -ETIME; | ||
692 | return 0; | ||
693 | } | ||
694 | |||
695 | static int s6mii_reset(struct mii_bus *bus) | ||
696 | { | ||
697 | struct s6gmac *pd = bus->priv; | ||
698 | s6mii_enable(pd); | ||
699 | if (s6mii_busy(pd, PHY_INIT_TIMEOUT)) | ||
700 | return -ETIME; | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static void s6gmac_set_rgmii_txclock(struct s6gmac *pd) | ||
705 | { | ||
706 | u32 pllsel = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
707 | pllsel &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC); | ||
708 | switch (pd->link.mbit) { | ||
709 | case 10: | ||
710 | pllsel |= S6_GREG1_PLLSEL_GMAC_2500KHZ << S6_GREG1_PLLSEL_GMAC; | ||
711 | break; | ||
712 | case 100: | ||
713 | pllsel |= S6_GREG1_PLLSEL_GMAC_25MHZ << S6_GREG1_PLLSEL_GMAC; | ||
714 | break; | ||
715 | case 1000: | ||
716 | pllsel |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC; | ||
717 | break; | ||
718 | default: | ||
719 | return; | ||
720 | } | ||
721 | writel(pllsel, S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
722 | } | ||
723 | |||
724 | static inline void s6gmac_linkisup(struct net_device *dev, int isup) | ||
725 | { | ||
726 | struct s6gmac *pd = netdev_priv(dev); | ||
727 | struct phy_device *phydev = pd->phydev; | ||
728 | |||
729 | pd->link.full = phydev->duplex; | ||
730 | pd->link.giga = (phydev->speed == 1000); | ||
731 | if (pd->link.mbit != phydev->speed) { | ||
732 | pd->link.mbit = phydev->speed; | ||
733 | s6gmac_set_rgmii_txclock(pd); | ||
734 | } | ||
735 | pd->link.isup = isup; | ||
736 | if (isup) | ||
737 | netif_carrier_on(dev); | ||
738 | phy_print_status(phydev); | ||
739 | } | ||
740 | |||
741 | static void s6gmac_adjust_link(struct net_device *dev) | ||
742 | { | ||
743 | struct s6gmac *pd = netdev_priv(dev); | ||
744 | struct phy_device *phydev = pd->phydev; | ||
745 | if (pd->link.isup && | ||
746 | (!phydev->link || | ||
747 | (pd->link.mbit != phydev->speed) || | ||
748 | (pd->link.full != phydev->duplex))) { | ||
749 | pd->link.isup = 0; | ||
750 | netif_tx_disable(dev); | ||
751 | if (!phydev->link) { | ||
752 | netif_carrier_off(dev); | ||
753 | phy_print_status(phydev); | ||
754 | } | ||
755 | } | ||
756 | if (!pd->link.isup && phydev->link) { | ||
757 | if (pd->link.full != phydev->duplex) { | ||
758 | u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); | ||
759 | if (phydev->duplex) | ||
760 | maccfg |= 1 << S6_GMAC_MACCONF2_FULL; | ||
761 | else | ||
762 | maccfg &= ~(1 << S6_GMAC_MACCONF2_FULL); | ||
763 | writel(maccfg, pd->reg + S6_GMAC_MACCONF2); | ||
764 | } | ||
765 | |||
766 | if (pd->link.giga != (phydev->speed == 1000)) { | ||
767 | u32 fifocfg = readl(pd->reg + S6_GMAC_FIFOCONF5); | ||
768 | u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2); | ||
769 | maccfg &= ~(S6_GMAC_MACCONF2_IFMODE_MASK | ||
770 | << S6_GMAC_MACCONF2_IFMODE); | ||
771 | if (phydev->speed == 1000) { | ||
772 | fifocfg |= 1 << S6_GMAC_FIFOCONF5_CFGBYTM; | ||
773 | maccfg |= S6_GMAC_MACCONF2_IFMODE_BYTE | ||
774 | << S6_GMAC_MACCONF2_IFMODE; | ||
775 | } else { | ||
776 | fifocfg &= ~(1 << S6_GMAC_FIFOCONF5_CFGBYTM); | ||
777 | maccfg |= S6_GMAC_MACCONF2_IFMODE_NIBBLE | ||
778 | << S6_GMAC_MACCONF2_IFMODE; | ||
779 | } | ||
780 | writel(fifocfg, pd->reg + S6_GMAC_FIFOCONF5); | ||
781 | writel(maccfg, pd->reg + S6_GMAC_MACCONF2); | ||
782 | } | ||
783 | |||
784 | if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
785 | netif_wake_queue(dev); | ||
786 | s6gmac_linkisup(dev, 1); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | static inline int s6gmac_phy_start(struct net_device *dev) | ||
791 | { | ||
792 | struct s6gmac *pd = netdev_priv(dev); | ||
793 | int i = 0; | ||
794 | struct phy_device *p = NULL; | ||
795 | while ((i < PHY_MAX_ADDR) && (!(p = pd->mii.bus->phy_map[i]))) | ||
796 | i++; | ||
797 | p = phy_connect(dev, dev_name(&p->dev), &s6gmac_adjust_link, | ||
798 | PHY_INTERFACE_MODE_RGMII); | ||
799 | if (IS_ERR(p)) { | ||
800 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | ||
801 | return PTR_ERR(p); | ||
802 | } | ||
803 | p->supported &= PHY_GBIT_FEATURES; | ||
804 | p->advertising = p->supported; | ||
805 | pd->phydev = p; | ||
806 | return 0; | ||
807 | } | ||
808 | |||
809 | static inline void s6gmac_init_stats(struct net_device *dev) | ||
810 | { | ||
811 | struct s6gmac *pd = netdev_priv(dev); | ||
812 | u32 mask; | ||
813 | mask = 1 << S6_GMAC_STATCARRY1_RDRP | | ||
814 | 1 << S6_GMAC_STATCARRY1_RJBR | | ||
815 | 1 << S6_GMAC_STATCARRY1_RFRG | | ||
816 | 1 << S6_GMAC_STATCARRY1_ROVR | | ||
817 | 1 << S6_GMAC_STATCARRY1_RUND | | ||
818 | 1 << S6_GMAC_STATCARRY1_RCDE | | ||
819 | 1 << S6_GMAC_STATCARRY1_RFLR | | ||
820 | 1 << S6_GMAC_STATCARRY1_RALN | | ||
821 | 1 << S6_GMAC_STATCARRY1_RMCA | | ||
822 | 1 << S6_GMAC_STATCARRY1_RFCS | | ||
823 | 1 << S6_GMAC_STATCARRY1_RPKT | | ||
824 | 1 << S6_GMAC_STATCARRY1_RBYT; | ||
825 | writel(mask, pd->reg + S6_GMAC_STATCARRY(0)); | ||
826 | writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(0)); | ||
827 | mask = 1 << S6_GMAC_STATCARRY2_TDRP | | ||
828 | 1 << S6_GMAC_STATCARRY2_TNCL | | ||
829 | 1 << S6_GMAC_STATCARRY2_TXCL | | ||
830 | 1 << S6_GMAC_STATCARRY2_TEDF | | ||
831 | 1 << S6_GMAC_STATCARRY2_TPKT | | ||
832 | 1 << S6_GMAC_STATCARRY2_TBYT | | ||
833 | 1 << S6_GMAC_STATCARRY2_TFRG | | ||
834 | 1 << S6_GMAC_STATCARRY2_TUND | | ||
835 | 1 << S6_GMAC_STATCARRY2_TOVR | | ||
836 | 1 << S6_GMAC_STATCARRY2_TFCS | | ||
837 | 1 << S6_GMAC_STATCARRY2_TJBR; | ||
838 | writel(mask, pd->reg + S6_GMAC_STATCARRY(1)); | ||
839 | writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(1)); | ||
840 | } | ||
841 | |||
842 | static inline void s6gmac_init_dmac(struct net_device *dev) | ||
843 | { | ||
844 | struct s6gmac *pd = netdev_priv(dev); | ||
845 | s6dmac_disable_chan(pd->tx_dma, pd->tx_chan); | ||
846 | s6dmac_disable_chan(pd->rx_dma, pd->rx_chan); | ||
847 | s6dmac_disable_error_irqs(pd->tx_dma, 1 << S6_HIFDMA_GMACTX); | ||
848 | s6dmac_disable_error_irqs(pd->rx_dma, 1 << S6_HIFDMA_GMACRX); | ||
849 | } | ||
850 | |||
851 | static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev) | ||
852 | { | ||
853 | struct s6gmac *pd = netdev_priv(dev); | ||
854 | unsigned long flags; | ||
855 | |||
856 | spin_lock_irqsave(&pd->lock, flags); | ||
857 | writel(skb->len << S6_GMAC_BURST_PREWR_LEN | | ||
858 | 0 << S6_GMAC_BURST_PREWR_CFE | | ||
859 | 1 << S6_GMAC_BURST_PREWR_PPE | | ||
860 | 1 << S6_GMAC_BURST_PREWR_FCS | | ||
861 | ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD, | ||
862 | pd->reg + S6_GMAC_BURST_PREWR); | ||
863 | s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan, | ||
864 | (u32)skb->data, pd->io, skb->len); | ||
865 | if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan)) | ||
866 | netif_stop_queue(dev); | ||
867 | if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) { | ||
868 | printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n", | ||
869 | pd->tx_skb_o, pd->tx_skb_i); | ||
870 | BUG(); | ||
871 | } | ||
872 | pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb; | ||
873 | spin_unlock_irqrestore(&pd->lock, flags); | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | static void s6gmac_tx_timeout(struct net_device *dev) | ||
878 | { | ||
879 | struct s6gmac *pd = netdev_priv(dev); | ||
880 | unsigned long flags; | ||
881 | spin_lock_irqsave(&pd->lock, flags); | ||
882 | s6gmac_tx_interrupt(dev); | ||
883 | spin_unlock_irqrestore(&pd->lock, flags); | ||
884 | } | ||
885 | |||
886 | static int s6gmac_open(struct net_device *dev) | ||
887 | { | ||
888 | struct s6gmac *pd = netdev_priv(dev); | ||
889 | unsigned long flags; | ||
890 | phy_read_status(pd->phydev); | ||
891 | spin_lock_irqsave(&pd->lock, flags); | ||
892 | pd->link.mbit = 0; | ||
893 | s6gmac_linkisup(dev, pd->phydev->link); | ||
894 | s6gmac_init_device(dev); | ||
895 | s6gmac_init_stats(dev); | ||
896 | s6gmac_init_dmac(dev); | ||
897 | s6gmac_rx_fillfifo(dev); | ||
898 | s6dmac_enable_chan(pd->rx_dma, pd->rx_chan, | ||
899 | 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1); | ||
900 | s6dmac_enable_chan(pd->tx_dma, pd->tx_chan, | ||
901 | 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1); | ||
902 | writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER | | ||
903 | 0 << S6_GMAC_HOST_INT_TXPREWOVER | | ||
904 | 0 << S6_GMAC_HOST_INT_RXBURSTUNDER | | ||
905 | 0 << S6_GMAC_HOST_INT_RXPOSTRFULL | | ||
906 | 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER, | ||
907 | pd->reg + S6_GMAC_HOST_INTMASK); | ||
908 | spin_unlock_irqrestore(&pd->lock, flags); | ||
909 | phy_start(pd->phydev); | ||
910 | netif_start_queue(dev); | ||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static int s6gmac_stop(struct net_device *dev) | ||
915 | { | ||
916 | struct s6gmac *pd = netdev_priv(dev); | ||
917 | unsigned long flags; | ||
918 | netif_stop_queue(dev); | ||
919 | phy_stop(pd->phydev); | ||
920 | spin_lock_irqsave(&pd->lock, flags); | ||
921 | s6gmac_init_dmac(dev); | ||
922 | s6gmac_stop_device(dev); | ||
923 | while (pd->tx_skb_i != pd->tx_skb_o) | ||
924 | dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]); | ||
925 | while (pd->rx_skb_i != pd->rx_skb_o) | ||
926 | dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]); | ||
927 | spin_unlock_irqrestore(&pd->lock, flags); | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | static struct net_device_stats *s6gmac_stats(struct net_device *dev) | ||
932 | { | ||
933 | struct s6gmac *pd = netdev_priv(dev); | ||
934 | struct net_device_stats *st = (struct net_device_stats *)&pd->stats; | ||
935 | int i; | ||
936 | do { | ||
937 | unsigned long flags; | ||
938 | spin_lock_irqsave(&pd->lock, flags); | ||
939 | for (i = 0; i < ARRAY_SIZE(pd->stats); i++) | ||
940 | pd->stats[i] = | ||
941 | pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1); | ||
942 | s6gmac_stats_collect(pd, &statinf[0][0]); | ||
943 | s6gmac_stats_collect(pd, &statinf[1][0]); | ||
944 | i = s6gmac_stats_pending(pd, 0) | | ||
945 | s6gmac_stats_pending(pd, 1); | ||
946 | spin_unlock_irqrestore(&pd->lock, flags); | ||
947 | } while (i); | ||
948 | st->rx_errors = st->rx_crc_errors + | ||
949 | st->rx_frame_errors + | ||
950 | st->rx_length_errors + | ||
951 | st->rx_missed_errors; | ||
952 | st->tx_errors += st->tx_aborted_errors; | ||
953 | return st; | ||
954 | } | ||
955 | |||
956 | static int s6gmac_probe(struct platform_device *pdev) | ||
957 | { | ||
958 | struct net_device *dev; | ||
959 | struct s6gmac *pd; | ||
960 | int res; | ||
961 | unsigned long i; | ||
962 | struct mii_bus *mb; | ||
963 | |||
964 | dev = alloc_etherdev(sizeof(*pd)); | ||
965 | if (!dev) | ||
966 | return -ENOMEM; | ||
967 | |||
968 | dev->open = s6gmac_open; | ||
969 | dev->stop = s6gmac_stop; | ||
970 | dev->hard_start_xmit = s6gmac_tx; | ||
971 | dev->tx_timeout = s6gmac_tx_timeout; | ||
972 | dev->watchdog_timeo = HZ; | ||
973 | dev->get_stats = s6gmac_stats; | ||
974 | dev->irq = platform_get_irq(pdev, 0); | ||
975 | pd = netdev_priv(dev); | ||
976 | memset(pd, 0, sizeof(*pd)); | ||
977 | spin_lock_init(&pd->lock); | ||
978 | pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start; | ||
979 | i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start; | ||
980 | pd->tx_dma = DMA_MASK_DMAC(i); | ||
981 | pd->tx_chan = DMA_INDEX_CHNL(i); | ||
982 | i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start; | ||
983 | pd->rx_dma = DMA_MASK_DMAC(i); | ||
984 | pd->rx_chan = DMA_INDEX_CHNL(i); | ||
985 | pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
986 | res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev); | ||
987 | if (res) { | ||
988 | printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq); | ||
989 | goto errirq; | ||
990 | } | ||
991 | res = register_netdev(dev); | ||
992 | if (res) { | ||
993 | printk(KERN_ERR DRV_PRMT "error registering device %s\n", | ||
994 | dev->name); | ||
995 | goto errdev; | ||
996 | } | ||
997 | mb = mdiobus_alloc(); | ||
998 | if (!mb) { | ||
999 | printk(KERN_ERR DRV_PRMT "error allocating mii bus\n"); | ||
1000 | res = -ENOMEM; | ||
1001 | goto errmii; | ||
1002 | } | ||
1003 | mb->name = "s6gmac_mii"; | ||
1004 | mb->read = s6mii_read; | ||
1005 | mb->write = s6mii_write; | ||
1006 | mb->reset = s6mii_reset; | ||
1007 | mb->priv = pd; | ||
1008 | snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id); | ||
1009 | mb->phy_mask = ~(1 << 0); | ||
1010 | mb->irq = &pd->mii.irq[0]; | ||
1011 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
1012 | int n = platform_get_irq(pdev, i + 1); | ||
1013 | if (n < 0) | ||
1014 | n = PHY_POLL; | ||
1015 | pd->mii.irq[i] = n; | ||
1016 | } | ||
1017 | mdiobus_register(mb); | ||
1018 | pd->mii.bus = mb; | ||
1019 | res = s6gmac_phy_start(dev); | ||
1020 | if (res) | ||
1021 | return res; | ||
1022 | platform_set_drvdata(pdev, dev); | ||
1023 | return 0; | ||
1024 | errmii: | ||
1025 | unregister_netdev(dev); | ||
1026 | errdev: | ||
1027 | free_irq(dev->irq, dev); | ||
1028 | errirq: | ||
1029 | free_netdev(dev); | ||
1030 | return res; | ||
1031 | } | ||
1032 | |||
1033 | static int s6gmac_remove(struct platform_device *pdev) | ||
1034 | { | ||
1035 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1036 | if (dev) { | ||
1037 | struct s6gmac *pd = netdev_priv(dev); | ||
1038 | mdiobus_unregister(pd->mii.bus); | ||
1039 | unregister_netdev(dev); | ||
1040 | free_irq(dev->irq, dev); | ||
1041 | free_netdev(dev); | ||
1042 | } | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1046 | static struct platform_driver s6gmac_driver = { | ||
1047 | .probe = s6gmac_probe, | ||
1048 | .remove = s6gmac_remove, | ||
1049 | .driver = { | ||
1050 | .name = "s6gmac", | ||
1051 | }, | ||
1052 | }; | ||
1053 | |||
1054 | module_platform_driver(s6gmac_driver); | ||
1055 | |||
1056 | MODULE_LICENSE("GPL"); | ||
1057 | MODULE_DESCRIPTION("S6105 on chip Ethernet driver"); | ||
1058 | MODULE_AUTHOR("Oskar Schirmer <oskar@scara.com>"); | ||
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 698494481d18..b1a271853d85 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | |||
@@ -474,13 +474,19 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, | |||
474 | /* allocate memory for RX skbuff array */ | 474 | /* allocate memory for RX skbuff array */ |
475 | rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, | 475 | rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, |
476 | sizeof(dma_addr_t), GFP_KERNEL); | 476 | sizeof(dma_addr_t), GFP_KERNEL); |
477 | if (rx_ring->rx_skbuff_dma == NULL) | 477 | if (!rx_ring->rx_skbuff_dma) { |
478 | goto dmamem_err; | 478 | dma_free_coherent(priv->device, |
479 | rx_rsize * sizeof(struct sxgbe_rx_norm_desc), | ||
480 | rx_ring->dma_rx, rx_ring->dma_rx_phy); | ||
481 | goto error; | ||
482 | } | ||
479 | 483 | ||
480 | rx_ring->rx_skbuff = kmalloc_array(rx_rsize, | 484 | rx_ring->rx_skbuff = kmalloc_array(rx_rsize, |
481 | sizeof(struct sk_buff *), GFP_KERNEL); | 485 | sizeof(struct sk_buff *), GFP_KERNEL); |
482 | if (rx_ring->rx_skbuff == NULL) | 486 | if (!rx_ring->rx_skbuff) { |
483 | goto rxbuff_err; | 487 | kfree(rx_ring->rx_skbuff_dma); |
488 | goto error; | ||
489 | } | ||
484 | 490 | ||
485 | /* initialise the buffers */ | 491 | /* initialise the buffers */ |
486 | for (desc_index = 0; desc_index < rx_rsize; desc_index++) { | 492 | for (desc_index = 0; desc_index < rx_rsize; desc_index++) { |
@@ -502,13 +508,6 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, | |||
502 | err_init_rx_buffers: | 508 | err_init_rx_buffers: |
503 | while (--desc_index >= 0) | 509 | while (--desc_index >= 0) |
504 | free_rx_ring(priv->device, rx_ring, desc_index); | 510 | free_rx_ring(priv->device, rx_ring, desc_index); |
505 | kfree(rx_ring->rx_skbuff); | ||
506 | rxbuff_err: | ||
507 | kfree(rx_ring->rx_skbuff_dma); | ||
508 | dmamem_err: | ||
509 | dma_free_coherent(priv->device, | ||
510 | rx_rsize * sizeof(struct sxgbe_rx_norm_desc), | ||
511 | rx_ring->dma_rx, rx_ring->dma_rx_phy); | ||
512 | error: | 511 | error: |
513 | return -ENOMEM; | 512 | return -ENOMEM; |
514 | } | 513 | } |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index 866560ea9e18..b02eed12bfc5 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c | |||
@@ -108,10 +108,6 @@ static int sxgbe_platform_probe(struct platform_device *pdev) | |||
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | /* Get MAC address if available (DT) */ | ||
112 | if (mac) | ||
113 | ether_addr_copy(priv->dev->dev_addr, mac); | ||
114 | |||
115 | priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr); | 111 | priv = sxgbe_drv_probe(&(pdev->dev), plat_dat, addr); |
116 | if (!priv) { | 112 | if (!priv) { |
117 | pr_err("%s: main driver probe failed\n", __func__); | 113 | pr_err("%s: main driver probe failed\n", __func__); |
@@ -125,6 +121,10 @@ static int sxgbe_platform_probe(struct platform_device *pdev) | |||
125 | goto err_drv_remove; | 121 | goto err_drv_remove; |
126 | } | 122 | } |
127 | 123 | ||
124 | /* Get MAC address if available (DT) */ | ||
125 | if (mac) | ||
126 | ether_addr_copy(priv->dev->dev_addr, mac); | ||
127 | |||
128 | /* Get the TX/RX IRQ numbers */ | 128 | /* Get the TX/RX IRQ numbers */ |
129 | for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) { | 129 | for (i = 0, chan = 1; i < SXGBE_TX_QUEUES; i++) { |
130 | priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++); | 130 | priv->txq[i]->irq_no = irq_of_parse_and_map(node, chan++); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 118a427d1942..cf62ff4c8c56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -1671,7 +1671,7 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv) | |||
1671 | * 0 on success and an appropriate (-)ve integer as defined in errno.h | 1671 | * 0 on success and an appropriate (-)ve integer as defined in errno.h |
1672 | * file on failure. | 1672 | * file on failure. |
1673 | */ | 1673 | */ |
1674 | static int stmmac_hw_setup(struct net_device *dev) | 1674 | static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) |
1675 | { | 1675 | { |
1676 | struct stmmac_priv *priv = netdev_priv(dev); | 1676 | struct stmmac_priv *priv = netdev_priv(dev); |
1677 | int ret; | 1677 | int ret; |
@@ -1708,9 +1708,11 @@ static int stmmac_hw_setup(struct net_device *dev) | |||
1708 | 1708 | ||
1709 | stmmac_mmc_setup(priv); | 1709 | stmmac_mmc_setup(priv); |
1710 | 1710 | ||
1711 | ret = stmmac_init_ptp(priv); | 1711 | if (init_ptp) { |
1712 | if (ret && ret != -EOPNOTSUPP) | 1712 | ret = stmmac_init_ptp(priv); |
1713 | pr_warn("%s: failed PTP initialisation\n", __func__); | 1713 | if (ret && ret != -EOPNOTSUPP) |
1714 | pr_warn("%s: failed PTP initialisation\n", __func__); | ||
1715 | } | ||
1714 | 1716 | ||
1715 | #ifdef CONFIG_DEBUG_FS | 1717 | #ifdef CONFIG_DEBUG_FS |
1716 | ret = stmmac_init_fs(dev); | 1718 | ret = stmmac_init_fs(dev); |
@@ -1787,7 +1789,7 @@ static int stmmac_open(struct net_device *dev) | |||
1787 | goto init_error; | 1789 | goto init_error; |
1788 | } | 1790 | } |
1789 | 1791 | ||
1790 | ret = stmmac_hw_setup(dev); | 1792 | ret = stmmac_hw_setup(dev, true); |
1791 | if (ret < 0) { | 1793 | if (ret < 0) { |
1792 | pr_err("%s: Hw setup failed\n", __func__); | 1794 | pr_err("%s: Hw setup failed\n", __func__); |
1793 | goto init_error; | 1795 | goto init_error; |
@@ -2776,6 +2778,9 @@ static int stmmac_hw_init(struct stmmac_priv *priv) | |||
2776 | * @addr: iobase memory address | 2778 | * @addr: iobase memory address |
2777 | * Description: this is the main probe function used to | 2779 | * Description: this is the main probe function used to |
2778 | * call the alloc_etherdev, allocate the priv structure. | 2780 | * call the alloc_etherdev, allocate the priv structure. |
2781 | * Return: | ||
2782 | * on success the new private structure is returned, otherwise the error | ||
2783 | * pointer. | ||
2779 | */ | 2784 | */ |
2780 | struct stmmac_priv *stmmac_dvr_probe(struct device *device, | 2785 | struct stmmac_priv *stmmac_dvr_probe(struct device *device, |
2781 | struct plat_stmmacenet_data *plat_dat, | 2786 | struct plat_stmmacenet_data *plat_dat, |
@@ -2787,7 +2792,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, | |||
2787 | 2792 | ||
2788 | ndev = alloc_etherdev(sizeof(struct stmmac_priv)); | 2793 | ndev = alloc_etherdev(sizeof(struct stmmac_priv)); |
2789 | if (!ndev) | 2794 | if (!ndev) |
2790 | return NULL; | 2795 | return ERR_PTR(-ENOMEM); |
2791 | 2796 | ||
2792 | SET_NETDEV_DEV(ndev, device); | 2797 | SET_NETDEV_DEV(ndev, device); |
2793 | 2798 | ||
@@ -3036,7 +3041,7 @@ int stmmac_resume(struct net_device *ndev) | |||
3036 | netif_device_attach(ndev); | 3041 | netif_device_attach(ndev); |
3037 | 3042 | ||
3038 | init_dma_desc_rings(ndev, GFP_ATOMIC); | 3043 | init_dma_desc_rings(ndev, GFP_ATOMIC); |
3039 | stmmac_hw_setup(ndev); | 3044 | stmmac_hw_setup(ndev, false); |
3040 | stmmac_init_tx_coalesce(priv); | 3045 | stmmac_init_tx_coalesce(priv); |
3041 | 3046 | ||
3042 | napi_enable(&priv->napi); | 3047 | napi_enable(&priv->napi); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 4032b170fe24..3039de2465ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -430,7 +430,6 @@ static struct platform_driver stmmac_pltfr_driver = { | |||
430 | .remove = stmmac_pltfr_remove, | 430 | .remove = stmmac_pltfr_remove, |
431 | .driver = { | 431 | .driver = { |
432 | .name = STMMAC_RESOURCE_NAME, | 432 | .name = STMMAC_RESOURCE_NAME, |
433 | .owner = THIS_MODULE, | ||
434 | .pm = &stmmac_pltfr_pm_ops, | 433 | .pm = &stmmac_pltfr_pm_ops, |
435 | .of_match_table = of_match_ptr(stmmac_dt_ids), | 434 | .of_match_table = of_match_ptr(stmmac_dt_ids), |
436 | }, | 435 | }, |
diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 45c408ef67d0..d2835bf7b4fb 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c | |||
@@ -1201,6 +1201,7 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb) | |||
1201 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO); | 1201 | segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO); |
1202 | if (IS_ERR(segs)) { | 1202 | if (IS_ERR(segs)) { |
1203 | dev->stats.tx_dropped++; | 1203 | dev->stats.tx_dropped++; |
1204 | dev_kfree_skb_any(skb); | ||
1204 | return NETDEV_TX_OK; | 1205 | return NETDEV_TX_OK; |
1205 | } | 1206 | } |
1206 | 1207 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c560f9aeb55d..a39131f494ec 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -610,7 +610,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
610 | 610 | ||
611 | /* Clear all mcast from ALE */ | 611 | /* Clear all mcast from ALE */ |
612 | cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS << | 612 | cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS << |
613 | priv->host_port); | 613 | priv->host_port, -1); |
614 | 614 | ||
615 | /* Flood All Unicast Packets to Host port */ | 615 | /* Flood All Unicast Packets to Host port */ |
616 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); | 616 | cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); |
@@ -634,6 +634,12 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) | |||
634 | static void cpsw_ndo_set_rx_mode(struct net_device *ndev) | 634 | static void cpsw_ndo_set_rx_mode(struct net_device *ndev) |
635 | { | 635 | { |
636 | struct cpsw_priv *priv = netdev_priv(ndev); | 636 | struct cpsw_priv *priv = netdev_priv(ndev); |
637 | int vid; | ||
638 | |||
639 | if (priv->data.dual_emac) | ||
640 | vid = priv->slaves[priv->emac_port].port_vlan; | ||
641 | else | ||
642 | vid = priv->data.default_vlan; | ||
637 | 643 | ||
638 | if (ndev->flags & IFF_PROMISC) { | 644 | if (ndev->flags & IFF_PROMISC) { |
639 | /* Enable promiscuous mode */ | 645 | /* Enable promiscuous mode */ |
@@ -649,7 +655,8 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) | |||
649 | cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); | 655 | cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); |
650 | 656 | ||
651 | /* Clear all mcast from ALE */ | 657 | /* Clear all mcast from ALE */ |
652 | cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port); | 658 | cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS << priv->host_port, |
659 | vid); | ||
653 | 660 | ||
654 | if (!netdev_mc_empty(ndev)) { | 661 | if (!netdev_mc_empty(ndev)) { |
655 | struct netdev_hw_addr *ha; | 662 | struct netdev_hw_addr *ha; |
@@ -757,6 +764,14 @@ requeue: | |||
757 | static irqreturn_t cpsw_interrupt(int irq, void *dev_id) | 764 | static irqreturn_t cpsw_interrupt(int irq, void *dev_id) |
758 | { | 765 | { |
759 | struct cpsw_priv *priv = dev_id; | 766 | struct cpsw_priv *priv = dev_id; |
767 | int value = irq - priv->irqs_table[0]; | ||
768 | |||
769 | /* NOTICE: Ending IRQ here. The trick with the 'value' variable above | ||
770 | * is to make sure we will always write the correct value to the EOI | ||
771 | * register. Namely 0 for RX_THRESH Interrupt, 1 for RX Interrupt, 2 | ||
772 | * for TX Interrupt and 3 for MISC Interrupt. | ||
773 | */ | ||
774 | cpdma_ctlr_eoi(priv->dma, value); | ||
760 | 775 | ||
761 | cpsw_intr_disable(priv); | 776 | cpsw_intr_disable(priv); |
762 | if (priv->irq_enabled == true) { | 777 | if (priv->irq_enabled == true) { |
@@ -786,8 +801,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) | |||
786 | int num_tx, num_rx; | 801 | int num_tx, num_rx; |
787 | 802 | ||
788 | num_tx = cpdma_chan_process(priv->txch, 128); | 803 | num_tx = cpdma_chan_process(priv->txch, 128); |
789 | if (num_tx) | ||
790 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | ||
791 | 804 | ||
792 | num_rx = cpdma_chan_process(priv->rxch, budget); | 805 | num_rx = cpdma_chan_process(priv->rxch, budget); |
793 | if (num_rx < budget) { | 806 | if (num_rx < budget) { |
@@ -795,7 +808,6 @@ static int cpsw_poll(struct napi_struct *napi, int budget) | |||
795 | 808 | ||
796 | napi_complete(napi); | 809 | napi_complete(napi); |
797 | cpsw_intr_enable(priv); | 810 | cpsw_intr_enable(priv); |
798 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | ||
799 | prim_cpsw = cpsw_get_slave_priv(priv, 0); | 811 | prim_cpsw = cpsw_get_slave_priv(priv, 0); |
800 | if (prim_cpsw->irq_enabled == false) { | 812 | if (prim_cpsw->irq_enabled == false) { |
801 | prim_cpsw->irq_enabled = true; | 813 | prim_cpsw->irq_enabled = true; |
@@ -1310,8 +1322,6 @@ static int cpsw_ndo_open(struct net_device *ndev) | |||
1310 | napi_enable(&priv->napi); | 1322 | napi_enable(&priv->napi); |
1311 | cpdma_ctlr_start(priv->dma); | 1323 | cpdma_ctlr_start(priv->dma); |
1312 | cpsw_intr_enable(priv); | 1324 | cpsw_intr_enable(priv); |
1313 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | ||
1314 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | ||
1315 | 1325 | ||
1316 | prim_cpsw = cpsw_get_slave_priv(priv, 0); | 1326 | prim_cpsw = cpsw_get_slave_priv(priv, 0); |
1317 | if (prim_cpsw->irq_enabled == false) { | 1327 | if (prim_cpsw->irq_enabled == false) { |
@@ -1578,9 +1588,6 @@ static void cpsw_ndo_tx_timeout(struct net_device *ndev) | |||
1578 | cpdma_chan_start(priv->txch); | 1588 | cpdma_chan_start(priv->txch); |
1579 | cpdma_ctlr_int_ctrl(priv->dma, true); | 1589 | cpdma_ctlr_int_ctrl(priv->dma, true); |
1580 | cpsw_intr_enable(priv); | 1590 | cpsw_intr_enable(priv); |
1581 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | ||
1582 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | ||
1583 | |||
1584 | } | 1591 | } |
1585 | 1592 | ||
1586 | static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) | 1593 | static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) |
@@ -1620,9 +1627,6 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev) | |||
1620 | cpsw_interrupt(ndev->irq, priv); | 1627 | cpsw_interrupt(ndev->irq, priv); |
1621 | cpdma_ctlr_int_ctrl(priv->dma, true); | 1628 | cpdma_ctlr_int_ctrl(priv->dma, true); |
1622 | cpsw_intr_enable(priv); | 1629 | cpsw_intr_enable(priv); |
1623 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); | ||
1624 | cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); | ||
1625 | |||
1626 | } | 1630 | } |
1627 | #endif | 1631 | #endif |
1628 | 1632 | ||
@@ -1630,16 +1634,24 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, | |||
1630 | unsigned short vid) | 1634 | unsigned short vid) |
1631 | { | 1635 | { |
1632 | int ret; | 1636 | int ret; |
1633 | int unreg_mcast_mask; | 1637 | int unreg_mcast_mask = 0; |
1638 | u32 port_mask; | ||
1634 | 1639 | ||
1635 | if (priv->ndev->flags & IFF_ALLMULTI) | 1640 | if (priv->data.dual_emac) { |
1636 | unreg_mcast_mask = ALE_ALL_PORTS; | 1641 | port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST; |
1637 | else | 1642 | |
1638 | unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; | 1643 | if (priv->ndev->flags & IFF_ALLMULTI) |
1644 | unreg_mcast_mask = port_mask; | ||
1645 | } else { | ||
1646 | port_mask = ALE_ALL_PORTS; | ||
1639 | 1647 | ||
1640 | ret = cpsw_ale_add_vlan(priv->ale, vid, | 1648 | if (priv->ndev->flags & IFF_ALLMULTI) |
1641 | ALE_ALL_PORTS << priv->host_port, | 1649 | unreg_mcast_mask = ALE_ALL_PORTS; |
1642 | 0, ALE_ALL_PORTS << priv->host_port, | 1650 | else |
1651 | unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; | ||
1652 | } | ||
1653 | |||
1654 | ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask, | ||
1643 | unreg_mcast_mask << priv->host_port); | 1655 | unreg_mcast_mask << priv->host_port); |
1644 | if (ret != 0) | 1656 | if (ret != 0) |
1645 | return ret; | 1657 | return ret; |
@@ -1650,8 +1662,7 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, | |||
1650 | goto clean_vid; | 1662 | goto clean_vid; |
1651 | 1663 | ||
1652 | ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, | 1664 | ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, |
1653 | ALE_ALL_PORTS << priv->host_port, | 1665 | port_mask, ALE_VLAN, vid, 0); |
1654 | ALE_VLAN, vid, 0); | ||
1655 | if (ret != 0) | 1666 | if (ret != 0) |
1656 | goto clean_vlan_ucast; | 1667 | goto clean_vlan_ucast; |
1657 | return 0; | 1668 | return 0; |
@@ -1672,6 +1683,19 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, | |||
1672 | if (vid == priv->data.default_vlan) | 1683 | if (vid == priv->data.default_vlan) |
1673 | return 0; | 1684 | return 0; |
1674 | 1685 | ||
1686 | if (priv->data.dual_emac) { | ||
1687 | /* In dual EMAC, reserved VLAN id should not be used for | ||
1688 | * creating VLAN interfaces as this can break the dual | ||
1689 | * EMAC port separation | ||
1690 | */ | ||
1691 | int i; | ||
1692 | |||
1693 | for (i = 0; i < priv->data.slaves; i++) { | ||
1694 | if (vid == priv->slaves[i].port_vlan) | ||
1695 | return -EINVAL; | ||
1696 | } | ||
1697 | } | ||
1698 | |||
1675 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); | 1699 | dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); |
1676 | return cpsw_add_vlan_ale_entry(priv, vid); | 1700 | return cpsw_add_vlan_ale_entry(priv, vid); |
1677 | } | 1701 | } |
@@ -1685,6 +1709,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, | |||
1685 | if (vid == priv->data.default_vlan) | 1709 | if (vid == priv->data.default_vlan) |
1686 | return 0; | 1710 | return 0; |
1687 | 1711 | ||
1712 | if (priv->data.dual_emac) { | ||
1713 | int i; | ||
1714 | |||
1715 | for (i = 0; i < priv->data.slaves; i++) { | ||
1716 | if (vid == priv->slaves[i].port_vlan) | ||
1717 | return -EINVAL; | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1688 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); | 1721 | dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); |
1689 | ret = cpsw_ale_del_vlan(priv->ale, vid, 0); | 1722 | ret = cpsw_ale_del_vlan(priv->ale, vid, 0); |
1690 | if (ret != 0) | 1723 | if (ret != 0) |
diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index 097ebe7077ac..5246b3a18ff8 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c | |||
@@ -234,7 +234,7 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, | |||
234 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); | 234 | cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); |
235 | } | 235 | } |
236 | 236 | ||
237 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | 237 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) |
238 | { | 238 | { |
239 | u32 ale_entry[ALE_ENTRY_WORDS]; | 239 | u32 ale_entry[ALE_ENTRY_WORDS]; |
240 | int ret, idx; | 240 | int ret, idx; |
@@ -245,6 +245,14 @@ int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask) | |||
245 | if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) | 245 | if (ret != ALE_TYPE_ADDR && ret != ALE_TYPE_VLAN_ADDR) |
246 | continue; | 246 | continue; |
247 | 247 | ||
248 | /* if vid passed is -1 then remove all multicast entry from | ||
249 | * the table irrespective of vlan id, if a valid vlan id is | ||
250 | * passed then remove only multicast added to that vlan id. | ||
251 | * if vlan id doesn't match then move on to next entry. | ||
252 | */ | ||
253 | if (vid != -1 && cpsw_ale_get_vlan_id(ale_entry) != vid) | ||
254 | continue; | ||
255 | |||
248 | if (cpsw_ale_get_mcast(ale_entry)) { | 256 | if (cpsw_ale_get_mcast(ale_entry)) { |
249 | u8 addr[6]; | 257 | u8 addr[6]; |
250 | 258 | ||
diff --git a/drivers/net/ethernet/ti/cpsw_ale.h b/drivers/net/ethernet/ti/cpsw_ale.h index c0d4127aa549..af1e7ecd87c6 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.h +++ b/drivers/net/ethernet/ti/cpsw_ale.h | |||
@@ -92,7 +92,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale); | |||
92 | 92 | ||
93 | int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout); | 93 | int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout); |
94 | int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); | 94 | int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask); |
95 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask); | 95 | int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid); |
96 | int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, | 96 | int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, |
97 | int flags, u16 vid); | 97 | int flags, u16 vid); |
98 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, | 98 | int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port, |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ea712512c7d1..5fae4354722c 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/of.h> | 62 | #include <linux/of.h> |
63 | #include <linux/of_address.h> | 63 | #include <linux/of_address.h> |
64 | #include <linux/of_device.h> | 64 | #include <linux/of_device.h> |
65 | #include <linux/of_mdio.h> | ||
65 | #include <linux/of_irq.h> | 66 | #include <linux/of_irq.h> |
66 | #include <linux/of_net.h> | 67 | #include <linux/of_net.h> |
67 | 68 | ||
@@ -343,9 +344,7 @@ struct emac_priv { | |||
343 | u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; | 344 | u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; |
344 | u32 rx_addr_type; | 345 | u32 rx_addr_type; |
345 | const char *phy_id; | 346 | const char *phy_id; |
346 | #ifdef CONFIG_OF | ||
347 | struct device_node *phy_node; | 347 | struct device_node *phy_node; |
348 | #endif | ||
349 | struct phy_device *phydev; | 348 | struct phy_device *phydev; |
350 | spinlock_t lock; | 349 | spinlock_t lock; |
351 | /*platform specific members*/ | 350 | /*platform specific members*/ |
@@ -922,6 +921,16 @@ static void emac_int_disable(struct emac_priv *priv) | |||
922 | if (priv->int_disable) | 921 | if (priv->int_disable) |
923 | priv->int_disable(); | 922 | priv->int_disable(); |
924 | 923 | ||
924 | /* NOTE: Rx Threshold and Misc interrupts are not enabled */ | ||
925 | |||
926 | /* ack rxen only then a new pulse will be generated */ | ||
927 | emac_write(EMAC_DM646X_MACEOIVECTOR, | ||
928 | EMAC_DM646X_MAC_EOI_C0_RXEN); | ||
929 | |||
930 | /* ack txen- only then a new pulse will be generated */ | ||
931 | emac_write(EMAC_DM646X_MACEOIVECTOR, | ||
932 | EMAC_DM646X_MAC_EOI_C0_TXEN); | ||
933 | |||
925 | local_irq_restore(flags); | 934 | local_irq_restore(flags); |
926 | 935 | ||
927 | } else { | 936 | } else { |
@@ -951,15 +960,6 @@ static void emac_int_enable(struct emac_priv *priv) | |||
951 | * register */ | 960 | * register */ |
952 | 961 | ||
953 | /* NOTE: Rx Threshold and Misc interrupts are not enabled */ | 962 | /* NOTE: Rx Threshold and Misc interrupts are not enabled */ |
954 | |||
955 | /* ack rxen only then a new pulse will be generated */ | ||
956 | emac_write(EMAC_DM646X_MACEOIVECTOR, | ||
957 | EMAC_DM646X_MAC_EOI_C0_RXEN); | ||
958 | |||
959 | /* ack txen- only then a new pulse will be generated */ | ||
960 | emac_write(EMAC_DM646X_MACEOIVECTOR, | ||
961 | EMAC_DM646X_MAC_EOI_C0_TXEN); | ||
962 | |||
963 | } else { | 963 | } else { |
964 | /* Set DM644x control registers for interrupt control */ | 964 | /* Set DM644x control registers for interrupt control */ |
965 | emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1); | 965 | emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1); |
@@ -1537,7 +1537,13 @@ static int emac_dev_open(struct net_device *ndev) | |||
1537 | int i = 0; | 1537 | int i = 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 | ret = pm_runtime_get_sync(&priv->pdev->dev); |
1541 | if (ret < 0) { | ||
1542 | pm_runtime_put_noidle(&priv->pdev->dev); | ||
1543 | dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", | ||
1544 | __func__, ret); | ||
1545 | return ret; | ||
1546 | } | ||
1541 | 1547 | ||
1542 | netif_carrier_off(ndev); | 1548 | netif_carrier_off(ndev); |
1543 | for (cnt = 0; cnt < ETH_ALEN; cnt++) | 1549 | for (cnt = 0; cnt < ETH_ALEN; cnt++) |
@@ -1596,8 +1602,20 @@ static int emac_dev_open(struct net_device *ndev) | |||
1596 | cpdma_ctlr_start(priv->dma); | 1602 | cpdma_ctlr_start(priv->dma); |
1597 | 1603 | ||
1598 | priv->phydev = NULL; | 1604 | priv->phydev = NULL; |
1605 | |||
1606 | if (priv->phy_node) { | ||
1607 | priv->phydev = of_phy_connect(ndev, priv->phy_node, | ||
1608 | &emac_adjust_link, 0, 0); | ||
1609 | if (!priv->phydev) { | ||
1610 | dev_err(emac_dev, "could not connect to phy %s\n", | ||
1611 | priv->phy_node->full_name); | ||
1612 | ret = -ENODEV; | ||
1613 | goto err; | ||
1614 | } | ||
1615 | } | ||
1616 | |||
1599 | /* use the first phy on the bus if pdata did not give us a phy id */ | 1617 | /* use the first phy on the bus if pdata did not give us a phy id */ |
1600 | if (!priv->phy_id) { | 1618 | if (!priv->phydev && !priv->phy_id) { |
1601 | struct device *phy; | 1619 | struct device *phy; |
1602 | 1620 | ||
1603 | phy = bus_find_device(&mdio_bus_type, NULL, NULL, | 1621 | phy = bus_find_device(&mdio_bus_type, NULL, NULL, |
@@ -1606,7 +1624,7 @@ static int emac_dev_open(struct net_device *ndev) | |||
1606 | priv->phy_id = dev_name(phy); | 1624 | priv->phy_id = dev_name(phy); |
1607 | } | 1625 | } |
1608 | 1626 | ||
1609 | if (priv->phy_id && *priv->phy_id) { | 1627 | if (!priv->phydev && priv->phy_id && *priv->phy_id) { |
1610 | priv->phydev = phy_connect(ndev, priv->phy_id, | 1628 | priv->phydev = phy_connect(ndev, priv->phy_id, |
1611 | &emac_adjust_link, | 1629 | &emac_adjust_link, |
1612 | PHY_INTERFACE_MODE_MII); | 1630 | PHY_INTERFACE_MODE_MII); |
@@ -1627,7 +1645,9 @@ static int emac_dev_open(struct net_device *ndev) | |||
1627 | "(mii_bus:phy_addr=%s, id=%x)\n", | 1645 | "(mii_bus:phy_addr=%s, id=%x)\n", |
1628 | priv->phydev->drv->name, dev_name(&priv->phydev->dev), | 1646 | priv->phydev->drv->name, dev_name(&priv->phydev->dev), |
1629 | priv->phydev->phy_id); | 1647 | priv->phydev->phy_id); |
1630 | } else { | 1648 | } |
1649 | |||
1650 | if (!priv->phydev) { | ||
1631 | /* No PHY , fix the link, speed and duplex settings */ | 1651 | /* No PHY , fix the link, speed and duplex settings */ |
1632 | dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); | 1652 | dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); |
1633 | priv->link = 1; | 1653 | priv->link = 1; |
@@ -1724,6 +1744,15 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) | |||
1724 | struct emac_priv *priv = netdev_priv(ndev); | 1744 | struct emac_priv *priv = netdev_priv(ndev); |
1725 | u32 mac_control; | 1745 | u32 mac_control; |
1726 | u32 stats_clear_mask; | 1746 | u32 stats_clear_mask; |
1747 | int err; | ||
1748 | |||
1749 | err = pm_runtime_get_sync(&priv->pdev->dev); | ||
1750 | if (err < 0) { | ||
1751 | pm_runtime_put_noidle(&priv->pdev->dev); | ||
1752 | dev_err(&priv->pdev->dev, "%s: failed to get_sync(%d)\n", | ||
1753 | __func__, err); | ||
1754 | return &ndev->stats; | ||
1755 | } | ||
1727 | 1756 | ||
1728 | /* update emac hardware stats and reset the registers*/ | 1757 | /* update emac hardware stats and reset the registers*/ |
1729 | 1758 | ||
@@ -1766,6 +1795,8 @@ static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) | |||
1766 | ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); | 1795 | ndev->stats.tx_fifo_errors += emac_read(EMAC_TXUNDERRUN); |
1767 | emac_write(EMAC_TXUNDERRUN, stats_clear_mask); | 1796 | emac_write(EMAC_TXUNDERRUN, stats_clear_mask); |
1768 | 1797 | ||
1798 | pm_runtime_put(&priv->pdev->dev); | ||
1799 | |||
1769 | return &ndev->stats; | 1800 | return &ndev->stats; |
1770 | } | 1801 | } |
1771 | 1802 | ||
@@ -1859,7 +1890,7 @@ davinci_emac_of_get_pdata(struct platform_device *pdev, struct emac_priv *priv) | |||
1859 | static int davinci_emac_probe(struct platform_device *pdev) | 1890 | static int davinci_emac_probe(struct platform_device *pdev) |
1860 | { | 1891 | { |
1861 | int rc = 0; | 1892 | int rc = 0; |
1862 | struct resource *res; | 1893 | struct resource *res, *res_ctrl; |
1863 | struct net_device *ndev; | 1894 | struct net_device *ndev; |
1864 | struct emac_priv *priv; | 1895 | struct emac_priv *priv; |
1865 | unsigned long hw_ram_addr; | 1896 | unsigned long hw_ram_addr; |
@@ -1876,6 +1907,7 @@ static int davinci_emac_probe(struct platform_device *pdev) | |||
1876 | return -EBUSY; | 1907 | return -EBUSY; |
1877 | } | 1908 | } |
1878 | emac_bus_frequency = clk_get_rate(emac_clk); | 1909 | emac_bus_frequency = clk_get_rate(emac_clk); |
1910 | devm_clk_put(&pdev->dev, emac_clk); | ||
1879 | 1911 | ||
1880 | /* TODO: Probe PHY here if possible */ | 1912 | /* TODO: Probe PHY here if possible */ |
1881 | 1913 | ||
@@ -1917,11 +1949,20 @@ static int davinci_emac_probe(struct platform_device *pdev) | |||
1917 | rc = PTR_ERR(priv->remap_addr); | 1949 | rc = PTR_ERR(priv->remap_addr); |
1918 | goto no_pdata; | 1950 | goto no_pdata; |
1919 | } | 1951 | } |
1952 | |||
1953 | res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1954 | if (res_ctrl) { | ||
1955 | priv->ctrl_base = | ||
1956 | devm_ioremap_resource(&pdev->dev, res_ctrl); | ||
1957 | if (IS_ERR(priv->ctrl_base)) | ||
1958 | goto no_pdata; | ||
1959 | } else { | ||
1960 | priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; | ||
1961 | } | ||
1962 | |||
1920 | priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset; | 1963 | priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset; |
1921 | ndev->base_addr = (unsigned long)priv->remap_addr; | 1964 | ndev->base_addr = (unsigned long)priv->remap_addr; |
1922 | 1965 | ||
1923 | priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; | ||
1924 | |||
1925 | hw_ram_addr = pdata->hw_ram_addr; | 1966 | hw_ram_addr = pdata->hw_ram_addr; |
1926 | if (!hw_ram_addr) | 1967 | if (!hw_ram_addr) |
1927 | hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset; | 1968 | hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset; |
@@ -1980,12 +2021,22 @@ static int davinci_emac_probe(struct platform_device *pdev) | |||
1980 | ndev->ethtool_ops = ðtool_ops; | 2021 | ndev->ethtool_ops = ðtool_ops; |
1981 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); | 2022 | netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT); |
1982 | 2023 | ||
2024 | pm_runtime_enable(&pdev->dev); | ||
2025 | rc = pm_runtime_get_sync(&pdev->dev); | ||
2026 | if (rc < 0) { | ||
2027 | pm_runtime_put_noidle(&pdev->dev); | ||
2028 | dev_err(&pdev->dev, "%s: failed to get_sync(%d)\n", | ||
2029 | __func__, rc); | ||
2030 | goto no_cpdma_chan; | ||
2031 | } | ||
2032 | |||
1983 | /* register the network device */ | 2033 | /* register the network device */ |
1984 | SET_NETDEV_DEV(ndev, &pdev->dev); | 2034 | SET_NETDEV_DEV(ndev, &pdev->dev); |
1985 | rc = register_netdev(ndev); | 2035 | rc = register_netdev(ndev); |
1986 | if (rc) { | 2036 | if (rc) { |
1987 | dev_err(&pdev->dev, "error in register_netdev\n"); | 2037 | dev_err(&pdev->dev, "error in register_netdev\n"); |
1988 | rc = -ENODEV; | 2038 | rc = -ENODEV; |
2039 | pm_runtime_put(&pdev->dev); | ||
1989 | goto no_cpdma_chan; | 2040 | goto no_cpdma_chan; |
1990 | } | 2041 | } |
1991 | 2042 | ||
@@ -1995,9 +2046,7 @@ static int davinci_emac_probe(struct platform_device *pdev) | |||
1995 | "(regs: %p, irq: %d)\n", | 2046 | "(regs: %p, irq: %d)\n", |
1996 | (void *)priv->emac_base_phys, ndev->irq); | 2047 | (void *)priv->emac_base_phys, ndev->irq); |
1997 | } | 2048 | } |
1998 | 2049 | pm_runtime_put(&pdev->dev); | |
1999 | pm_runtime_enable(&pdev->dev); | ||
2000 | pm_runtime_resume(&pdev->dev); | ||
2001 | 2050 | ||
2002 | return 0; | 2051 | return 0; |
2003 | 2052 | ||
@@ -2071,9 +2120,14 @@ static const struct emac_platform_data am3517_emac_data = { | |||
2071 | .hw_ram_addr = 0x01e20000, | 2120 | .hw_ram_addr = 0x01e20000, |
2072 | }; | 2121 | }; |
2073 | 2122 | ||
2123 | static const struct emac_platform_data dm816_emac_data = { | ||
2124 | .version = EMAC_VERSION_2, | ||
2125 | }; | ||
2126 | |||
2074 | static const struct of_device_id davinci_emac_of_match[] = { | 2127 | static const struct of_device_id davinci_emac_of_match[] = { |
2075 | {.compatible = "ti,davinci-dm6467-emac", }, | 2128 | {.compatible = "ti,davinci-dm6467-emac", }, |
2076 | {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, | 2129 | {.compatible = "ti,am3517-emac", .data = &am3517_emac_data, }, |
2130 | {.compatible = "ti,dm816-emac", .data = &dm816_emac_data, }, | ||
2077 | {}, | 2131 | {}, |
2078 | }; | 2132 | }; |
2079 | MODULE_DEVICE_TABLE(of, davinci_emac_of_match); | 2133 | MODULE_DEVICE_TABLE(of, davinci_emac_of_match); |
diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 9c2d91ea0af4..dbcbf0c5bcfa 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c | |||
@@ -1043,6 +1043,7 @@ static int temac_of_probe(struct platform_device *op) | |||
1043 | lp->regs = of_iomap(op->dev.of_node, 0); | 1043 | lp->regs = of_iomap(op->dev.of_node, 0); |
1044 | if (!lp->regs) { | 1044 | if (!lp->regs) { |
1045 | dev_err(&op->dev, "could not map temac regs.\n"); | 1045 | dev_err(&op->dev, "could not map temac regs.\n"); |
1046 | rc = -ENOMEM; | ||
1046 | goto nodev; | 1047 | goto nodev; |
1047 | } | 1048 | } |
1048 | 1049 | ||
@@ -1062,6 +1063,7 @@ static int temac_of_probe(struct platform_device *op) | |||
1062 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); | 1063 | np = of_parse_phandle(op->dev.of_node, "llink-connected", 0); |
1063 | if (!np) { | 1064 | if (!np) { |
1064 | dev_err(&op->dev, "could not find DMA node\n"); | 1065 | dev_err(&op->dev, "could not find DMA node\n"); |
1066 | rc = -ENODEV; | ||
1065 | goto err_iounmap; | 1067 | goto err_iounmap; |
1066 | } | 1068 | } |
1067 | 1069 | ||
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h index 44b8d2bad8c3..4c9b4fa1d3c1 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h | |||
@@ -388,7 +388,6 @@ struct axidma_bd { | |||
388 | * @dma_err_tasklet: Tasklet structure to process Axi DMA errors | 388 | * @dma_err_tasklet: Tasklet structure to process Axi DMA errors |
389 | * @tx_irq: Axidma TX IRQ number | 389 | * @tx_irq: Axidma TX IRQ number |
390 | * @rx_irq: Axidma RX IRQ number | 390 | * @rx_irq: Axidma RX IRQ number |
391 | * @temac_type: axienet type to identify between soft and hard temac | ||
392 | * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X | 391 | * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X |
393 | * @options: AxiEthernet option word | 392 | * @options: AxiEthernet option word |
394 | * @last_link: Phy link state in which the PHY was negotiated earlier | 393 | * @last_link: Phy link state in which the PHY was negotiated earlier |
@@ -431,7 +430,6 @@ struct axienet_local { | |||
431 | 430 | ||
432 | int tx_irq; | 431 | int tx_irq; |
433 | int rx_irq; | 432 | int rx_irq; |
434 | u32 temac_type; | ||
435 | u32 phy_type; | 433 | u32 phy_type; |
436 | 434 | ||
437 | u32 options; /* Current options word */ | 435 | u32 options; /* Current options word */ |
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 4ea2d4e6f1d1..a6d2860b712c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c | |||
@@ -1501,6 +1501,7 @@ static int axienet_of_probe(struct platform_device *op) | |||
1501 | lp->regs = of_iomap(op->dev.of_node, 0); | 1501 | lp->regs = of_iomap(op->dev.of_node, 0); |
1502 | if (!lp->regs) { | 1502 | if (!lp->regs) { |
1503 | dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); | 1503 | dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); |
1504 | ret = -ENOMEM; | ||
1504 | goto nodev; | 1505 | goto nodev; |
1505 | } | 1506 | } |
1506 | /* Setup checksum offload, but default to off if not specified */ | 1507 | /* Setup checksum offload, but default to off if not specified */ |
@@ -1555,10 +1556,6 @@ static int axienet_of_probe(struct platform_device *op) | |||
1555 | if ((be32_to_cpup(p)) >= 0x4000) | 1556 | if ((be32_to_cpup(p)) >= 0x4000) |
1556 | lp->jumbo_support = 1; | 1557 | lp->jumbo_support = 1; |
1557 | } | 1558 | } |
1558 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type", | ||
1559 | NULL); | ||
1560 | if (p) | ||
1561 | lp->temac_type = be32_to_cpup(p); | ||
1562 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); | 1559 | p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); |
1563 | if (p) | 1560 | if (p) |
1564 | lp->phy_type = be32_to_cpup(p); | 1561 | lp->phy_type = be32_to_cpup(p); |
@@ -1567,6 +1564,7 @@ static int axienet_of_probe(struct platform_device *op) | |||
1567 | np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); | 1564 | np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); |
1568 | if (!np) { | 1565 | if (!np) { |
1569 | dev_err(&op->dev, "could not find DMA node\n"); | 1566 | dev_err(&op->dev, "could not find DMA node\n"); |
1567 | ret = -ENODEV; | ||
1570 | goto err_iounmap; | 1568 | goto err_iounmap; |
1571 | } | 1569 | } |
1572 | lp->dma_regs = of_iomap(np, 0); | 1570 | lp->dma_regs = of_iomap(np, 0); |
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 24858799c204..9d4ce388510a 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c | |||
@@ -1109,6 +1109,7 @@ static int xemaclite_of_probe(struct platform_device *ofdev) | |||
1109 | res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); | 1109 | res = platform_get_resource(ofdev, IORESOURCE_IRQ, 0); |
1110 | if (!res) { | 1110 | if (!res) { |
1111 | dev_err(dev, "no IRQ found\n"); | 1111 | dev_err(dev, "no IRQ found\n"); |
1112 | rc = -ENXIO; | ||
1112 | goto error; | 1113 | goto error; |
1113 | } | 1114 | } |
1114 | 1115 | ||
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 2f48f790c9b4..384ca4f4de4a 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h | |||
@@ -590,6 +590,7 @@ struct nvsp_message { | |||
590 | 590 | ||
591 | 591 | ||
592 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe | 592 | #define NETVSC_RECEIVE_BUFFER_ID 0xcafe |
593 | #define NETVSC_SEND_BUFFER_ID 0 | ||
593 | 594 | ||
594 | #define NETVSC_PACKET_SIZE 4096 | 595 | #define NETVSC_PACKET_SIZE 4096 |
595 | 596 | ||
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index dd867e6cabd6..9f49c0129a78 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -161,8 +161,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
161 | 161 | ||
162 | /* Deal with the send buffer we may have setup. | 162 | /* Deal with the send buffer we may have setup. |
163 | * If we got a send section size, it means we received a | 163 | * If we got a send section size, it means we received a |
164 | * SendsendBufferComplete msg (ie sent | 164 | * NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE msg (ie sent |
165 | * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need | 165 | * NVSP_MSG1_TYPE_SEND_SEND_BUF msg) therefore, we need |
166 | * to send a revoke msg here | 166 | * to send a revoke msg here |
167 | */ | 167 | */ |
168 | if (net_device->send_section_size) { | 168 | if (net_device->send_section_size) { |
@@ -172,7 +172,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
172 | 172 | ||
173 | revoke_packet->hdr.msg_type = | 173 | revoke_packet->hdr.msg_type = |
174 | NVSP_MSG1_TYPE_REVOKE_SEND_BUF; | 174 | NVSP_MSG1_TYPE_REVOKE_SEND_BUF; |
175 | revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0; | 175 | revoke_packet->msg.v1_msg.revoke_send_buf.id = |
176 | NETVSC_SEND_BUFFER_ID; | ||
176 | 177 | ||
177 | ret = vmbus_sendpacket(net_device->dev->channel, | 178 | ret = vmbus_sendpacket(net_device->dev->channel, |
178 | revoke_packet, | 179 | revoke_packet, |
@@ -204,7 +205,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device) | |||
204 | net_device->send_buf_gpadl_handle = 0; | 205 | net_device->send_buf_gpadl_handle = 0; |
205 | } | 206 | } |
206 | if (net_device->send_buf) { | 207 | if (net_device->send_buf) { |
207 | /* Free up the receive buffer */ | 208 | /* Free up the send buffer */ |
208 | vfree(net_device->send_buf); | 209 | vfree(net_device->send_buf); |
209 | net_device->send_buf = NULL; | 210 | net_device->send_buf = NULL; |
210 | } | 211 | } |
@@ -339,9 +340,9 @@ static int netvsc_init_buf(struct hv_device *device) | |||
339 | init_packet = &net_device->channel_init_pkt; | 340 | init_packet = &net_device->channel_init_pkt; |
340 | memset(init_packet, 0, sizeof(struct nvsp_message)); | 341 | memset(init_packet, 0, sizeof(struct nvsp_message)); |
341 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; | 342 | init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; |
342 | init_packet->msg.v1_msg.send_recv_buf.gpadl_handle = | 343 | init_packet->msg.v1_msg.send_send_buf.gpadl_handle = |
343 | net_device->send_buf_gpadl_handle; | 344 | net_device->send_buf_gpadl_handle; |
344 | init_packet->msg.v1_msg.send_recv_buf.id = 0; | 345 | init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID; |
345 | 346 | ||
346 | /* Send the gpadl notification request */ | 347 | /* Send the gpadl notification request */ |
347 | ret = vmbus_sendpacket(device->channel, init_packet, | 348 | ret = vmbus_sendpacket(device->channel, init_packet, |
@@ -364,7 +365,7 @@ static int netvsc_init_buf(struct hv_device *device) | |||
364 | netdev_err(ndev, "Unable to complete send buffer " | 365 | netdev_err(ndev, "Unable to complete send buffer " |
365 | "initialization with NetVsp - status %d\n", | 366 | "initialization with NetVsp - status %d\n", |
366 | init_packet->msg.v1_msg. | 367 | init_packet->msg.v1_msg. |
367 | send_recv_buf_complete.status); | 368 | send_send_buf_complete.status); |
368 | ret = -EINVAL; | 369 | ret = -EINVAL; |
369 | goto cleanup; | 370 | goto cleanup; |
370 | } | 371 | } |
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index a14d87783245..2e195289ddf4 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
@@ -377,9 +377,11 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) | |||
377 | }; | 377 | }; |
378 | 378 | ||
379 | dst = ip6_route_output(dev_net(dev), NULL, &fl6); | 379 | dst = ip6_route_output(dev_net(dev), NULL, &fl6); |
380 | if (IS_ERR(dst)) | 380 | if (dst->error) { |
381 | ret = dst->error; | ||
382 | dst_release(dst); | ||
381 | goto err; | 383 | goto err; |
382 | 384 | } | |
383 | skb_dst_drop(skb); | 385 | skb_dst_drop(skb); |
384 | skb_dst_set(skb, dst); | 386 | skb_dst_set(skb, dst); |
385 | err = ip6_local_out(skb); | 387 | err = ip6_local_out(skb); |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index c530de1e63f5..3ad8ca76196d 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -88,6 +88,7 @@ struct kszphy_priv { | |||
88 | 88 | ||
89 | static const struct kszphy_type ksz8021_type = { | 89 | static const struct kszphy_type ksz8021_type = { |
90 | .led_mode_reg = MII_KSZPHY_CTRL_2, | 90 | .led_mode_reg = MII_KSZPHY_CTRL_2, |
91 | .has_broadcast_disable = true, | ||
91 | .has_rmii_ref_clk_sel = true, | 92 | .has_rmii_ref_clk_sel = true, |
92 | }; | 93 | }; |
93 | 94 | ||
@@ -258,19 +259,6 @@ static int kszphy_config_init(struct phy_device *phydev) | |||
258 | return 0; | 259 | return 0; |
259 | } | 260 | } |
260 | 261 | ||
261 | static int ksz8021_config_init(struct phy_device *phydev) | ||
262 | { | ||
263 | int rc; | ||
264 | |||
265 | rc = kszphy_config_init(phydev); | ||
266 | if (rc) | ||
267 | return rc; | ||
268 | |||
269 | rc = kszphy_broadcast_disable(phydev); | ||
270 | |||
271 | return rc < 0 ? rc : 0; | ||
272 | } | ||
273 | |||
274 | static int ksz9021_load_values_from_of(struct phy_device *phydev, | 262 | static int ksz9021_load_values_from_of(struct phy_device *phydev, |
275 | struct device_node *of_node, u16 reg, | 263 | struct device_node *of_node, u16 reg, |
276 | char *field1, char *field2, | 264 | char *field1, char *field2, |
@@ -584,7 +572,7 @@ static struct phy_driver ksphy_driver[] = { | |||
584 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 572 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
585 | .driver_data = &ksz8021_type, | 573 | .driver_data = &ksz8021_type, |
586 | .probe = kszphy_probe, | 574 | .probe = kszphy_probe, |
587 | .config_init = ksz8021_config_init, | 575 | .config_init = kszphy_config_init, |
588 | .config_aneg = genphy_config_aneg, | 576 | .config_aneg = genphy_config_aneg, |
589 | .read_status = genphy_read_status, | 577 | .read_status = genphy_read_status, |
590 | .ack_interrupt = kszphy_ack_interrupt, | 578 | .ack_interrupt = kszphy_ack_interrupt, |
@@ -601,7 +589,7 @@ static struct phy_driver ksphy_driver[] = { | |||
601 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 589 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
602 | .driver_data = &ksz8021_type, | 590 | .driver_data = &ksz8021_type, |
603 | .probe = kszphy_probe, | 591 | .probe = kszphy_probe, |
604 | .config_init = ksz8021_config_init, | 592 | .config_init = kszphy_config_init, |
605 | .config_aneg = genphy_config_aneg, | 593 | .config_aneg = genphy_config_aneg, |
606 | .read_status = genphy_read_status, | 594 | .read_status = genphy_read_status, |
607 | .ack_interrupt = kszphy_ack_interrupt, | 595 | .ack_interrupt = kszphy_ack_interrupt, |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 93e224217e24..f7ff493f1e73 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -629,6 +629,7 @@ static int team_change_mode(struct team *team, const char *kind) | |||
629 | static void team_notify_peers_work(struct work_struct *work) | 629 | static void team_notify_peers_work(struct work_struct *work) |
630 | { | 630 | { |
631 | struct team *team; | 631 | struct team *team; |
632 | int val; | ||
632 | 633 | ||
633 | team = container_of(work, struct team, notify_peers.dw.work); | 634 | team = container_of(work, struct team, notify_peers.dw.work); |
634 | 635 | ||
@@ -636,9 +637,14 @@ static void team_notify_peers_work(struct work_struct *work) | |||
636 | schedule_delayed_work(&team->notify_peers.dw, 0); | 637 | schedule_delayed_work(&team->notify_peers.dw, 0); |
637 | return; | 638 | return; |
638 | } | 639 | } |
640 | val = atomic_dec_if_positive(&team->notify_peers.count_pending); | ||
641 | if (val < 0) { | ||
642 | rtnl_unlock(); | ||
643 | return; | ||
644 | } | ||
639 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev); | 645 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, team->dev); |
640 | rtnl_unlock(); | 646 | rtnl_unlock(); |
641 | if (!atomic_dec_and_test(&team->notify_peers.count_pending)) | 647 | if (val) |
642 | schedule_delayed_work(&team->notify_peers.dw, | 648 | schedule_delayed_work(&team->notify_peers.dw, |
643 | msecs_to_jiffies(team->notify_peers.interval)); | 649 | msecs_to_jiffies(team->notify_peers.interval)); |
644 | } | 650 | } |
@@ -669,6 +675,7 @@ static void team_notify_peers_fini(struct team *team) | |||
669 | static void team_mcast_rejoin_work(struct work_struct *work) | 675 | static void team_mcast_rejoin_work(struct work_struct *work) |
670 | { | 676 | { |
671 | struct team *team; | 677 | struct team *team; |
678 | int val; | ||
672 | 679 | ||
673 | team = container_of(work, struct team, mcast_rejoin.dw.work); | 680 | team = container_of(work, struct team, mcast_rejoin.dw.work); |
674 | 681 | ||
@@ -676,9 +683,14 @@ static void team_mcast_rejoin_work(struct work_struct *work) | |||
676 | schedule_delayed_work(&team->mcast_rejoin.dw, 0); | 683 | schedule_delayed_work(&team->mcast_rejoin.dw, 0); |
677 | return; | 684 | return; |
678 | } | 685 | } |
686 | val = atomic_dec_if_positive(&team->mcast_rejoin.count_pending); | ||
687 | if (val < 0) { | ||
688 | rtnl_unlock(); | ||
689 | return; | ||
690 | } | ||
679 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev); | 691 | call_netdevice_notifiers(NETDEV_RESEND_IGMP, team->dev); |
680 | rtnl_unlock(); | 692 | rtnl_unlock(); |
681 | if (!atomic_dec_and_test(&team->mcast_rejoin.count_pending)) | 693 | if (val) |
682 | schedule_delayed_work(&team->mcast_rejoin.dw, | 694 | schedule_delayed_work(&team->mcast_rejoin.dw, |
683 | msecs_to_jiffies(team->mcast_rejoin.interval)); | 695 | msecs_to_jiffies(team->mcast_rejoin.interval)); |
684 | } | 696 | } |
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index dcb6d33141e0..1e9cdca37014 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -1276,7 +1276,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length) | |||
1276 | awd.done = 0; | 1276 | awd.done = 0; |
1277 | 1277 | ||
1278 | urb->context = &awd; | 1278 | urb->context = &awd; |
1279 | status = usb_submit_urb(urb, GFP_NOIO); | 1279 | status = usb_submit_urb(urb, GFP_ATOMIC); |
1280 | if (status) { | 1280 | if (status) { |
1281 | // something went wrong | 1281 | // something went wrong |
1282 | usb_free_urb(urb); | 1282 | usb_free_urb(urb); |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index b8a82b86f909..602dc6668c3a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -56,6 +56,8 @@ struct qmi_wwan_state { | |||
56 | /* default ethernet address used by the modem */ | 56 | /* default ethernet address used by the modem */ |
57 | static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; | 57 | static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3}; |
58 | 58 | ||
59 | static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00}; | ||
60 | |||
59 | /* Make up an ethernet header if the packet doesn't have one. | 61 | /* Make up an ethernet header if the packet doesn't have one. |
60 | * | 62 | * |
61 | * A firmware bug common among several devices cause them to send raw | 63 | * A firmware bug common among several devices cause them to send raw |
@@ -332,10 +334,12 @@ next_desc: | |||
332 | usb_driver_release_interface(driver, info->data); | 334 | usb_driver_release_interface(driver, info->data); |
333 | } | 335 | } |
334 | 336 | ||
335 | /* Never use the same address on both ends of the link, even | 337 | /* Never use the same address on both ends of the link, even if the |
336 | * if the buggy firmware told us to. | 338 | * buggy firmware told us to. Or, if device is assigned the well-known |
339 | * buggy firmware MAC address, replace it with a random address, | ||
337 | */ | 340 | */ |
338 | if (ether_addr_equal(dev->net->dev_addr, default_modem_addr)) | 341 | if (ether_addr_equal(dev->net->dev_addr, default_modem_addr) || |
342 | ether_addr_equal(dev->net->dev_addr, buggy_fw_addr)) | ||
339 | eth_hw_addr_random(dev->net); | 343 | eth_hw_addr_random(dev->net); |
340 | 344 | ||
341 | /* make MAC addr easily distinguishable from an IP header */ | 345 | /* make MAC addr easily distinguishable from an IP header */ |
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2d1c77e81836..bf405f134d3a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -833,9 +833,6 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) | |||
833 | index &= ~3; | 833 | index &= ~3; |
834 | } | 834 | } |
835 | 835 | ||
836 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); | ||
837 | |||
838 | data |= __le32_to_cpu(tmp) & ~mask; | ||
839 | tmp = __cpu_to_le32(data); | 836 | tmp = __cpu_to_le32(data); |
840 | 837 | ||
841 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); | 838 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); |
@@ -874,9 +871,6 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) | |||
874 | index &= ~3; | 871 | index &= ~3; |
875 | } | 872 | } |
876 | 873 | ||
877 | generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); | ||
878 | |||
879 | data |= __le32_to_cpu(tmp) & ~mask; | ||
880 | tmp = __cpu_to_le32(data); | 874 | tmp = __cpu_to_le32(data); |
881 | 875 | ||
882 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); | 876 | generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); |
@@ -926,12 +920,6 @@ static void sram_write(struct r8152 *tp, u16 addr, u16 data) | |||
926 | ocp_reg_write(tp, OCP_SRAM_DATA, data); | 920 | ocp_reg_write(tp, OCP_SRAM_DATA, data); |
927 | } | 921 | } |
928 | 922 | ||
929 | static u16 sram_read(struct r8152 *tp, u16 addr) | ||
930 | { | ||
931 | ocp_reg_write(tp, OCP_SRAM_ADDR, addr); | ||
932 | return ocp_reg_read(tp, OCP_SRAM_DATA); | ||
933 | } | ||
934 | |||
935 | static int read_mii_word(struct net_device *netdev, int phy_id, int reg) | 923 | static int read_mii_word(struct net_device *netdev, int phy_id, int reg) |
936 | { | 924 | { |
937 | struct r8152 *tp = netdev_priv(netdev); | 925 | struct r8152 *tp = netdev_priv(netdev); |
@@ -1897,6 +1885,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) | |||
1897 | netif_wake_queue(netdev); | 1885 | netif_wake_queue(netdev); |
1898 | } | 1886 | } |
1899 | 1887 | ||
1888 | static netdev_features_t | ||
1889 | rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, | ||
1890 | netdev_features_t features) | ||
1891 | { | ||
1892 | u32 mss = skb_shinfo(skb)->gso_size; | ||
1893 | int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; | ||
1894 | int offset = skb_transport_offset(skb); | ||
1895 | |||
1896 | if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) | ||
1897 | features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); | ||
1898 | else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) | ||
1899 | features &= ~NETIF_F_GSO_MASK; | ||
1900 | |||
1901 | return features; | ||
1902 | } | ||
1903 | |||
1900 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, | 1904 | static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, |
1901 | struct net_device *netdev) | 1905 | struct net_device *netdev) |
1902 | { | 1906 | { |
@@ -2502,24 +2506,18 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) | |||
2502 | data = ocp_reg_read(tp, OCP_POWER_CFG); | 2506 | data = ocp_reg_read(tp, OCP_POWER_CFG); |
2503 | data |= EN_10M_PLLOFF; | 2507 | data |= EN_10M_PLLOFF; |
2504 | ocp_reg_write(tp, OCP_POWER_CFG, data); | 2508 | ocp_reg_write(tp, OCP_POWER_CFG, data); |
2505 | data = sram_read(tp, SRAM_IMPEDANCE); | 2509 | sram_write(tp, SRAM_IMPEDANCE, 0x0b13); |
2506 | data &= ~RX_DRIVING_MASK; | ||
2507 | sram_write(tp, SRAM_IMPEDANCE, data); | ||
2508 | 2510 | ||
2509 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); | 2511 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); |
2510 | ocp_data |= PFM_PWM_SWITCH; | 2512 | ocp_data |= PFM_PWM_SWITCH; |
2511 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); | 2513 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); |
2512 | 2514 | ||
2513 | data = sram_read(tp, SRAM_LPF_CFG); | 2515 | /* Enable LPF corner auto tune */ |
2514 | data |= LPF_AUTO_TUNE; | 2516 | sram_write(tp, SRAM_LPF_CFG, 0xf70f); |
2515 | sram_write(tp, SRAM_LPF_CFG, data); | ||
2516 | 2517 | ||
2517 | data = sram_read(tp, SRAM_10M_AMP1); | 2518 | /* Adjust 10M Amplitude */ |
2518 | data |= GDAC_IB_UPALL; | 2519 | sram_write(tp, SRAM_10M_AMP1, 0x00af); |
2519 | sram_write(tp, SRAM_10M_AMP1, data); | 2520 | sram_write(tp, SRAM_10M_AMP2, 0x0208); |
2520 | data = sram_read(tp, SRAM_10M_AMP2); | ||
2521 | data |= AMP_DN; | ||
2522 | sram_write(tp, SRAM_10M_AMP2, data); | ||
2523 | 2521 | ||
2524 | set_bit(PHY_RESET, &tp->flags); | 2522 | set_bit(PHY_RESET, &tp->flags); |
2525 | } | 2523 | } |
@@ -3706,6 +3704,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { | |||
3706 | .ndo_set_mac_address = rtl8152_set_mac_address, | 3704 | .ndo_set_mac_address = rtl8152_set_mac_address, |
3707 | .ndo_change_mtu = rtl8152_change_mtu, | 3705 | .ndo_change_mtu = rtl8152_change_mtu, |
3708 | .ndo_validate_addr = eth_validate_addr, | 3706 | .ndo_validate_addr = eth_validate_addr, |
3707 | .ndo_features_check = rtl8152_features_check, | ||
3709 | }; | 3708 | }; |
3710 | 3709 | ||
3711 | static void r8152b_get_version(struct r8152 *tp) | 3710 | static void r8152b_get_version(struct r8152 *tp) |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b8bd7191572d..5ca97713bfb3 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -760,7 +760,6 @@ static int virtnet_poll(struct napi_struct *napi, int budget) | |||
760 | container_of(napi, struct receive_queue, napi); | 760 | container_of(napi, struct receive_queue, napi); |
761 | unsigned int r, received = 0; | 761 | unsigned int r, received = 0; |
762 | 762 | ||
763 | again: | ||
764 | received += virtnet_receive(rq, budget - received); | 763 | received += virtnet_receive(rq, budget - received); |
765 | 764 | ||
766 | /* Out of packets? */ | 765 | /* Out of packets? */ |
@@ -771,7 +770,6 @@ again: | |||
771 | napi_schedule_prep(napi)) { | 770 | napi_schedule_prep(napi)) { |
772 | virtqueue_disable_cb(rq->vq); | 771 | virtqueue_disable_cb(rq->vq); |
773 | __napi_schedule(napi); | 772 | __napi_schedule(napi); |
774 | goto again; | ||
775 | } | 773 | } |
776 | } | 774 | } |
777 | 775 | ||
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 49d9f2291998..7fbd89fbe107 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1579,8 +1579,10 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); | 1579 | bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk); |
1580 | 1580 | ||
1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1581 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
1582 | if (IS_ERR(skb)) | 1582 | if (IS_ERR(skb)) { |
1583 | return -EINVAL; | 1583 | err = -EINVAL; |
1584 | goto err; | ||
1585 | } | ||
1584 | 1586 | ||
1585 | skb_scrub_packet(skb, xnet); | 1587 | skb_scrub_packet(skb, xnet); |
1586 | 1588 | ||
@@ -1590,12 +1592,16 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1590 | 1592 | ||
1591 | /* Need space for new headers (invalidates iph ptr) */ | 1593 | /* Need space for new headers (invalidates iph ptr) */ |
1592 | err = skb_cow_head(skb, min_headroom); | 1594 | err = skb_cow_head(skb, min_headroom); |
1593 | if (unlikely(err)) | 1595 | if (unlikely(err)) { |
1594 | return err; | 1596 | kfree_skb(skb); |
1597 | goto err; | ||
1598 | } | ||
1595 | 1599 | ||
1596 | skb = vlan_hwaccel_push_inside(skb); | 1600 | skb = vlan_hwaccel_push_inside(skb); |
1597 | if (WARN_ON(!skb)) | 1601 | if (WARN_ON(!skb)) { |
1598 | return -ENOMEM; | 1602 | err = -ENOMEM; |
1603 | goto err; | ||
1604 | } | ||
1599 | 1605 | ||
1600 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); | 1606 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); |
1601 | vxh->vx_flags = htonl(VXLAN_FLAGS); | 1607 | vxh->vx_flags = htonl(VXLAN_FLAGS); |
@@ -1606,6 +1612,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1606 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, | 1612 | udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio, |
1607 | ttl, src_port, dst_port); | 1613 | ttl, src_port, dst_port); |
1608 | return 0; | 1614 | return 0; |
1615 | err: | ||
1616 | dst_release(dst); | ||
1617 | return err; | ||
1609 | } | 1618 | } |
1610 | #endif | 1619 | #endif |
1611 | 1620 | ||
@@ -1621,7 +1630,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
1621 | 1630 | ||
1622 | skb = udp_tunnel_handle_offloads(skb, udp_sum); | 1631 | skb = udp_tunnel_handle_offloads(skb, udp_sum); |
1623 | if (IS_ERR(skb)) | 1632 | if (IS_ERR(skb)) |
1624 | return -EINVAL; | 1633 | return PTR_ERR(skb); |
1625 | 1634 | ||
1626 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 1635 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
1627 | + VXLAN_HLEN + sizeof(struct iphdr) | 1636 | + VXLAN_HLEN + sizeof(struct iphdr) |
@@ -1629,8 +1638,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
1629 | 1638 | ||
1630 | /* Need space for new headers (invalidates iph ptr) */ | 1639 | /* Need space for new headers (invalidates iph ptr) */ |
1631 | err = skb_cow_head(skb, min_headroom); | 1640 | err = skb_cow_head(skb, min_headroom); |
1632 | if (unlikely(err)) | 1641 | if (unlikely(err)) { |
1642 | kfree_skb(skb); | ||
1633 | return err; | 1643 | return err; |
1644 | } | ||
1634 | 1645 | ||
1635 | skb = vlan_hwaccel_push_inside(skb); | 1646 | skb = vlan_hwaccel_push_inside(skb); |
1636 | if (WARN_ON(!skb)) | 1647 | if (WARN_ON(!skb)) |
@@ -1776,9 +1787,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1776 | tos, ttl, df, src_port, dst_port, | 1787 | tos, ttl, df, src_port, dst_port, |
1777 | htonl(vni << 8), | 1788 | htonl(vni << 8), |
1778 | !net_eq(vxlan->net, dev_net(vxlan->dev))); | 1789 | !net_eq(vxlan->net, dev_net(vxlan->dev))); |
1779 | 1790 | if (err < 0) { | |
1780 | if (err < 0) | 1791 | /* skb is already freed. */ |
1792 | skb = NULL; | ||
1781 | goto rt_tx_error; | 1793 | goto rt_tx_error; |
1794 | } | ||
1795 | |||
1782 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 1796 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
1783 | #if IS_ENABLED(CONFIG_IPV6) | 1797 | #if IS_ENABLED(CONFIG_IPV6) |
1784 | } else { | 1798 | } else { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 9a72640237cb..62b0bf4fdf6b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
285 | 285 | ||
286 | __ath_cancel_work(sc); | 286 | __ath_cancel_work(sc); |
287 | 287 | ||
288 | disable_irq(sc->irq); | ||
288 | tasklet_disable(&sc->intr_tq); | 289 | tasklet_disable(&sc->intr_tq); |
289 | tasklet_disable(&sc->bcon_tasklet); | 290 | tasklet_disable(&sc->bcon_tasklet); |
290 | spin_lock_bh(&sc->sc_pcu_lock); | 291 | spin_lock_bh(&sc->sc_pcu_lock); |
@@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) | |||
331 | r = -EIO; | 332 | r = -EIO; |
332 | 333 | ||
333 | out: | 334 | out: |
335 | enable_irq(sc->irq); | ||
334 | spin_unlock_bh(&sc->sc_pcu_lock); | 336 | spin_unlock_bh(&sc->sc_pcu_lock); |
335 | tasklet_enable(&sc->bcon_tasklet); | 337 | tasklet_enable(&sc->bcon_tasklet); |
336 | tasklet_enable(&sc->intr_tq); | 338 | tasklet_enable(&sc->intr_tq); |
@@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
512 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) | 514 | if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags)) |
513 | return IRQ_NONE; | 515 | return IRQ_NONE; |
514 | 516 | ||
515 | if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | ||
516 | return IRQ_NONE; | ||
517 | |||
518 | /* shared irq, not for us */ | 517 | /* shared irq, not for us */ |
519 | if (!ath9k_hw_intrpend(ah)) | 518 | if (!ath9k_hw_intrpend(ah)) |
520 | return IRQ_NONE; | 519 | return IRQ_NONE; |
@@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
529 | ath9k_debug_sync_cause(sc, sync_cause); | 528 | ath9k_debug_sync_cause(sc, sync_cause); |
530 | status &= ah->imask; /* discard unasked-for bits */ | 529 | status &= ah->imask; /* discard unasked-for bits */ |
531 | 530 | ||
532 | if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags)) | 531 | if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) |
533 | return IRQ_HANDLED; | 532 | return IRQ_HANDLED; |
534 | 533 | ||
535 | /* | 534 | /* |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3c06e9365949..9880dae2a569 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -1070,7 +1070,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, | |||
1070 | */ | 1070 | */ |
1071 | if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && | 1071 | if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && |
1072 | ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || | 1072 | ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || |
1073 | (sdiodev->pdata->oob_irq_supported))) | 1073 | (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) |
1074 | bus_if->wowl_supported = true; | 1074 | bus_if->wowl_supported = true; |
1075 | #endif | 1075 | #endif |
1076 | 1076 | ||
@@ -1167,7 +1167,7 @@ static int brcmf_ops_sdio_resume(struct device *dev) | |||
1167 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 1167 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
1168 | 1168 | ||
1169 | brcmf_dbg(SDIO, "Enter\n"); | 1169 | brcmf_dbg(SDIO, "Enter\n"); |
1170 | if (sdiodev->pdata->oob_irq_supported) | 1170 | if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) |
1171 | disable_irq_wake(sdiodev->pdata->oob_irq_nr); | 1171 | disable_irq_wake(sdiodev->pdata->oob_irq_nr); |
1172 | brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); | 1172 | brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); |
1173 | atomic_set(&sdiodev->suspend, false); | 1173 | atomic_set(&sdiodev->suspend, false); |
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig index 91c0cb3c368e..21de4fe6cf2d 100644 --- a/drivers/net/wireless/ipw2x00/Kconfig +++ b/drivers/net/wireless/ipw2x00/Kconfig | |||
@@ -65,7 +65,8 @@ config IPW2100_DEBUG | |||
65 | 65 | ||
66 | config IPW2200 | 66 | config IPW2200 |
67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" | 67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" |
68 | depends on PCI && CFG80211 && CFG80211_WEXT | 68 | depends on PCI && CFG80211 |
69 | select CFG80211_WEXT | ||
69 | select WIRELESS_EXT | 70 | select WIRELESS_EXT |
70 | select WEXT_SPY | 71 | select WEXT_SPY |
71 | select WEXT_PRIV | 72 | select WEXT_PRIV |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index e5be2d21868f..a5f9198d5747 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -69,8 +69,8 @@ | |||
69 | #include "iwl-agn-hw.h" | 69 | #include "iwl-agn-hw.h" |
70 | 70 | ||
71 | /* Highest firmware API version supported */ | 71 | /* Highest firmware API version supported */ |
72 | #define IWL7260_UCODE_API_MAX 10 | 72 | #define IWL7260_UCODE_API_MAX 12 |
73 | #define IWL3160_UCODE_API_MAX 10 | 73 | #define IWL3160_UCODE_API_MAX 12 |
74 | 74 | ||
75 | /* Oldest version we won't warn about */ | 75 | /* Oldest version we won't warn about */ |
76 | #define IWL7260_UCODE_API_OK 10 | 76 | #define IWL7260_UCODE_API_OK 10 |
@@ -105,7 +105,7 @@ | |||
105 | #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" | 105 | #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" |
106 | 106 | ||
107 | #define IWL7265D_FW_PRE "iwlwifi-7265D-" | 107 | #define IWL7265D_FW_PRE "iwlwifi-7265D-" |
108 | #define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" | 108 | #define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) ".ucode" |
109 | 109 | ||
110 | #define NVM_HW_SECTION_NUM_FAMILY_7000 0 | 110 | #define NVM_HW_SECTION_NUM_FAMILY_7000 0 |
111 | 111 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index bf0a95cb7153..3668fc57e770 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
@@ -69,7 +69,7 @@ | |||
69 | #include "iwl-agn-hw.h" | 69 | #include "iwl-agn-hw.h" |
70 | 70 | ||
71 | /* Highest firmware API version supported */ | 71 | /* Highest firmware API version supported */ |
72 | #define IWL8000_UCODE_API_MAX 10 | 72 | #define IWL8000_UCODE_API_MAX 12 |
73 | 73 | ||
74 | /* Oldest version we won't warn about */ | 74 | /* Oldest version we won't warn about */ |
75 | #define IWL8000_UCODE_API_OK 10 | 75 | #define IWL8000_UCODE_API_OK 10 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 38de1513e4de..850b85a47806 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1323,10 +1323,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) | |||
1323 | 1323 | ||
1324 | try_again: | 1324 | try_again: |
1325 | /* try next, if any */ | 1325 | /* try next, if any */ |
1326 | kfree(pieces); | ||
1327 | release_firmware(ucode_raw); | 1326 | release_firmware(ucode_raw); |
1328 | if (iwl_request_firmware(drv, false)) | 1327 | if (iwl_request_firmware(drv, false)) |
1329 | goto out_unbind; | 1328 | goto out_unbind; |
1329 | kfree(pieces); | ||
1330 | return; | 1330 | return; |
1331 | 1331 | ||
1332 | out_free_fw: | 1332 | out_free_fw: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 9564ae173d06..1f7f15eb86da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -310,6 +310,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
310 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) | 310 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) |
311 | 311 | ||
312 | #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 | 312 | #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 |
313 | #define FH_MEM_TB_MAX_LENGTH (0x00020000) | ||
313 | 314 | ||
314 | /* TFDB Area - TFDs buffer table */ | 315 | /* TFDB Area - TFDs buffer table */ |
315 | #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) | 316 | #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index f2a047f6bb3e..660ddb1b7d8a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -243,6 +243,10 @@ enum iwl_ucode_tlv_flag { | |||
243 | * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. | 243 | * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. |
244 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time | 244 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time |
245 | * longer than the passive one, which is essential for fragmented scan. | 245 | * longer than the passive one, which is essential for fragmented scan. |
246 | * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, | ||
247 | * regardless of the band or the number of the probes. FW will calculate | ||
248 | * the actual dwell time. | ||
249 | * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. | ||
246 | */ | 250 | */ |
247 | enum iwl_ucode_tlv_api { | 251 | enum iwl_ucode_tlv_api { |
248 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), | 252 | IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), |
@@ -253,6 +257,8 @@ enum iwl_ucode_tlv_api { | |||
253 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), | 257 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), |
254 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), | 258 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), |
255 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | 259 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
260 | IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), | ||
261 | IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), | ||
256 | }; | 262 | }; |
257 | 263 | ||
258 | /** | 264 | /** |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 1f2acf47bfb2..cfc0e65b34a5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | |||
@@ -653,8 +653,11 @@ enum iwl_scan_channel_flags { | |||
653 | }; | 653 | }; |
654 | 654 | ||
655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S | 655 | /* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S |
656 | * @flags: enum iwl_scan_channel_flgs | 656 | * @flags: enum iwl_scan_channel_flags |
657 | * @non_ebs_ratio: how many regular scan iteration before EBS | 657 | * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is |
658 | * involved. | ||
659 | * 1 - EBS is disabled. | ||
660 | * 2 - every second scan will be full scan(and so on). | ||
658 | */ | 661 | */ |
659 | struct iwl_scan_channel_opt { | 662 | struct iwl_scan_channel_opt { |
660 | __le16 flags; | 663 | __le16 flags; |
@@ -672,6 +675,7 @@ struct iwl_scan_channel_opt { | |||
672 | * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented | 675 | * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented |
673 | * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report | 676 | * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report |
674 | * and DS parameter set IEs into probe requests. | 677 | * and DS parameter set IEs into probe requests. |
678 | * @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches | ||
675 | */ | 679 | */ |
676 | enum iwl_mvm_lmac_scan_flags { | 680 | enum iwl_mvm_lmac_scan_flags { |
677 | IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0), | 681 | IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0), |
@@ -681,6 +685,7 @@ enum iwl_mvm_lmac_scan_flags { | |||
681 | IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4), | 685 | IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4), |
682 | IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5), | 686 | IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5), |
683 | IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6), | 687 | IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6), |
688 | IWL_MVM_LMAC_SCAN_FLAG_MATCH = BIT(9), | ||
684 | }; | 689 | }; |
685 | 690 | ||
686 | enum iwl_scan_priority { | 691 | enum iwl_scan_priority { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 31a5b3f4266c..20915587c820 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -1004,8 +1004,13 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) | |||
1004 | { | 1004 | { |
1005 | lockdep_assert_held(&mvm->mutex); | 1005 | lockdep_assert_held(&mvm->mutex); |
1006 | 1006 | ||
1007 | /* disallow low power states when the FW is down */ | 1007 | /* |
1008 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | 1008 | * Disallow low power states when the FW is down by taking |
1009 | * the UCODE_DOWN ref. in case of ongoing hw restart the | ||
1010 | * ref is already taken, so don't take it again. | ||
1011 | */ | ||
1012 | if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) | ||
1013 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | ||
1009 | 1014 | ||
1010 | /* async_handlers_wk is now blocked */ | 1015 | /* async_handlers_wk is now blocked */ |
1011 | 1016 | ||
@@ -1023,6 +1028,12 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) | |||
1023 | /* the fw is stopped, the aux sta is dead: clean up driver state */ | 1028 | /* the fw is stopped, the aux sta is dead: clean up driver state */ |
1024 | iwl_mvm_del_aux_sta(mvm); | 1029 | iwl_mvm_del_aux_sta(mvm); |
1025 | 1030 | ||
1031 | /* | ||
1032 | * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete() | ||
1033 | * won't be called in this case). | ||
1034 | */ | ||
1035 | clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); | ||
1036 | |||
1026 | mvm->ucode_loaded = false; | 1037 | mvm->ucode_loaded = false; |
1027 | } | 1038 | } |
1028 | 1039 | ||
@@ -3332,18 +3343,16 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, | |||
3332 | msk |= mvmsta->tfd_queue_msk; | 3343 | msk |= mvmsta->tfd_queue_msk; |
3333 | } | 3344 | } |
3334 | 3345 | ||
3335 | if (drop) { | 3346 | msk &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); |
3336 | if (iwl_mvm_flush_tx_path(mvm, msk, true)) | ||
3337 | IWL_ERR(mvm, "flush request fail\n"); | ||
3338 | mutex_unlock(&mvm->mutex); | ||
3339 | } else { | ||
3340 | mutex_unlock(&mvm->mutex); | ||
3341 | 3347 | ||
3342 | /* this can take a while, and we may need/want other operations | 3348 | if (iwl_mvm_flush_tx_path(mvm, msk, true)) |
3343 | * to succeed while doing this, so do it without the mutex held | 3349 | IWL_ERR(mvm, "flush request fail\n"); |
3344 | */ | 3350 | mutex_unlock(&mvm->mutex); |
3345 | iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | 3351 | |
3346 | } | 3352 | /* this can take a while, and we may need/want other operations |
3353 | * to succeed while doing this, so do it without the mutex held | ||
3354 | */ | ||
3355 | iwl_trans_wait_tx_queue_empty(mvm->trans, msk); | ||
3347 | } | 3356 | } |
3348 | 3357 | ||
3349 | const struct ieee80211_ops iwl_mvm_hw_ops = { | 3358 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index e5294d01181e..844bf7c4c8de 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -72,6 +72,8 @@ | |||
72 | 72 | ||
73 | #define IWL_PLCP_QUIET_THRESH 1 | 73 | #define IWL_PLCP_QUIET_THRESH 1 |
74 | #define IWL_ACTIVE_QUIET_TIME 10 | 74 | #define IWL_ACTIVE_QUIET_TIME 10 |
75 | #define IWL_DENSE_EBS_SCAN_RATIO 5 | ||
76 | #define IWL_SPARSE_EBS_SCAN_RATIO 1 | ||
75 | 77 | ||
76 | struct iwl_mvm_scan_params { | 78 | struct iwl_mvm_scan_params { |
77 | u32 max_out_time; | 79 | u32 max_out_time; |
@@ -171,15 +173,21 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid, | |||
171 | * already included in the probe template, so we need to set only | 173 | * already included in the probe template, so we need to set only |
172 | * req->n_ssids - 1 bits in addition to the first bit. | 174 | * req->n_ssids - 1 bits in addition to the first bit. |
173 | */ | 175 | */ |
174 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 176 | static u16 iwl_mvm_get_active_dwell(struct iwl_mvm *mvm, |
177 | enum ieee80211_band band, int n_ssids) | ||
175 | { | 178 | { |
179 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) | ||
180 | return 10; | ||
176 | if (band == IEEE80211_BAND_2GHZ) | 181 | if (band == IEEE80211_BAND_2GHZ) |
177 | return 20 + 3 * (n_ssids + 1); | 182 | return 20 + 3 * (n_ssids + 1); |
178 | return 10 + 2 * (n_ssids + 1); | 183 | return 10 + 2 * (n_ssids + 1); |
179 | } | 184 | } |
180 | 185 | ||
181 | static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) | 186 | static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm, |
187 | enum ieee80211_band band) | ||
182 | { | 188 | { |
189 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BASIC_DWELL) | ||
190 | return 110; | ||
183 | return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; | 191 | return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; |
184 | } | 192 | } |
185 | 193 | ||
@@ -331,7 +339,8 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, | |||
331 | */ | 339 | */ |
332 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 340 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
333 | u32 passive_dwell = | 341 | u32 passive_dwell = |
334 | iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ); | 342 | iwl_mvm_get_passive_dwell(mvm, |
343 | IEEE80211_BAND_2GHZ); | ||
335 | params->max_out_time = passive_dwell; | 344 | params->max_out_time = passive_dwell; |
336 | } else { | 345 | } else { |
337 | params->passive_fragmented = true; | 346 | params->passive_fragmented = true; |
@@ -348,8 +357,8 @@ not_bound: | |||
348 | params->dwell[band].passive = frag_passive_dwell; | 357 | params->dwell[band].passive = frag_passive_dwell; |
349 | else | 358 | else |
350 | params->dwell[band].passive = | 359 | params->dwell[band].passive = |
351 | iwl_mvm_get_passive_dwell(band); | 360 | iwl_mvm_get_passive_dwell(mvm, band); |
352 | params->dwell[band].active = iwl_mvm_get_active_dwell(band, | 361 | params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, |
353 | n_ssids); | 362 | n_ssids); |
354 | } | 363 | } |
355 | } | 364 | } |
@@ -1098,6 +1107,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
1098 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, | 1107 | return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, |
1099 | notify); | 1108 | notify); |
1100 | 1109 | ||
1110 | if (mvm->scan_status == IWL_MVM_SCAN_NONE) | ||
1111 | return 0; | ||
1112 | |||
1113 | if (iwl_mvm_is_radio_killed(mvm)) | ||
1114 | goto out; | ||
1115 | |||
1101 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && | 1116 | if (mvm->scan_status != IWL_MVM_SCAN_SCHED && |
1102 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || | 1117 | (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || |
1103 | mvm->scan_status != IWL_MVM_SCAN_OS)) { | 1118 | mvm->scan_status != IWL_MVM_SCAN_OS)) { |
@@ -1134,6 +1149,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify) | |||
1134 | if (mvm->scan_status == IWL_MVM_SCAN_OS) | 1149 | if (mvm->scan_status == IWL_MVM_SCAN_OS) |
1135 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); | 1150 | iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); |
1136 | 1151 | ||
1152 | out: | ||
1137 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 1153 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
1138 | 1154 | ||
1139 | if (notify) { | 1155 | if (notify) { |
@@ -1290,18 +1306,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm, | |||
1290 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); | 1306 | cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); |
1291 | cmd->iter_num = cpu_to_le32(1); | 1307 | cmd->iter_num = cpu_to_le32(1); |
1292 | 1308 | ||
1293 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | ||
1294 | mvm->last_ebs_successful) { | ||
1295 | cmd->channel_opt[0].flags = | ||
1296 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1297 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1298 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1299 | cmd->channel_opt[1].flags = | ||
1300 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1301 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1302 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1303 | } | ||
1304 | |||
1305 | if (iwl_mvm_rrm_scan_needed(mvm)) | 1309 | if (iwl_mvm_rrm_scan_needed(mvm)) |
1306 | cmd->scan_flags |= | 1310 | cmd->scan_flags |= |
1307 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); | 1311 | cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); |
@@ -1376,6 +1380,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm, | |||
1376 | cmd->schedule[1].iterations = 0; | 1380 | cmd->schedule[1].iterations = 0; |
1377 | cmd->schedule[1].full_scan_mul = 0; | 1381 | cmd->schedule[1].full_scan_mul = 0; |
1378 | 1382 | ||
1383 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS && | ||
1384 | mvm->last_ebs_successful) { | ||
1385 | cmd->channel_opt[0].flags = | ||
1386 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1387 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1388 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1389 | cmd->channel_opt[0].non_ebs_ratio = | ||
1390 | cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | ||
1391 | cmd->channel_opt[1].flags = | ||
1392 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1393 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1394 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1395 | cmd->channel_opt[1].non_ebs_ratio = | ||
1396 | cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | ||
1397 | } | ||
1398 | |||
1379 | for (i = 1; i <= req->req.n_ssids; i++) | 1399 | for (i = 1; i <= req->req.n_ssids; i++) |
1380 | ssid_bitmap |= BIT(i); | 1400 | ssid_bitmap |= BIT(i); |
1381 | 1401 | ||
@@ -1448,6 +1468,8 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
1448 | 1468 | ||
1449 | if (iwl_mvm_scan_pass_all(mvm, req)) | 1469 | if (iwl_mvm_scan_pass_all(mvm, req)) |
1450 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; | 1470 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL; |
1471 | else | ||
1472 | flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH; | ||
1451 | 1473 | ||
1452 | if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) | 1474 | if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0) |
1453 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; | 1475 | flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION; |
@@ -1474,6 +1496,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, | |||
1474 | cmd->schedule[1].iterations = 0xff; | 1496 | cmd->schedule[1].iterations = 0xff; |
1475 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; | 1497 | cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; |
1476 | 1498 | ||
1499 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT && | ||
1500 | mvm->last_ebs_successful) { | ||
1501 | cmd->channel_opt[0].flags = | ||
1502 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1503 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1504 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1505 | cmd->channel_opt[0].non_ebs_ratio = | ||
1506 | cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO); | ||
1507 | cmd->channel_opt[1].flags = | ||
1508 | cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS | | ||
1509 | IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE | | ||
1510 | IWL_SCAN_CHANNEL_FLAG_CACHE_ADD); | ||
1511 | cmd->channel_opt[1].non_ebs_ratio = | ||
1512 | cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO); | ||
1513 | } | ||
1514 | |||
1477 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, | 1515 | iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, |
1478 | ssid_bitmap, cmd); | 1516 | ssid_bitmap, cmd); |
1479 | 1517 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 4f15d9decc81..c59d07567d90 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -90,8 +90,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
90 | 90 | ||
91 | if (ieee80211_is_probe_resp(fc)) | 91 | if (ieee80211_is_probe_resp(fc)) |
92 | tx_flags |= TX_CMD_FLG_TSF; | 92 | tx_flags |= TX_CMD_FLG_TSF; |
93 | else if (ieee80211_is_back_req(fc)) | ||
94 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | ||
95 | 93 | ||
96 | if (ieee80211_has_morefrags(fc)) | 94 | if (ieee80211_has_morefrags(fc)) |
97 | tx_flags |= TX_CMD_FLG_MORE_FRAG; | 95 | tx_flags |= TX_CMD_FLG_MORE_FRAG; |
@@ -100,6 +98,15 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
100 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 98 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
101 | tx_cmd->tid_tspec = qc[0] & 0xf; | 99 | tx_cmd->tid_tspec = qc[0] & 0xf; |
102 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; | 100 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
101 | } else if (ieee80211_is_back_req(fc)) { | ||
102 | struct ieee80211_bar *bar = (void *)skb->data; | ||
103 | u16 control = le16_to_cpu(bar->control); | ||
104 | |||
105 | tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR; | ||
106 | tx_cmd->tid_tspec = (control & | ||
107 | IEEE80211_BAR_CTRL_TID_INFO_MASK) >> | ||
108 | IEEE80211_BAR_CTRL_TID_INFO_SHIFT; | ||
109 | WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT); | ||
103 | } else { | 110 | } else { |
104 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; | 111 | tx_cmd->tid_tspec = IWL_TID_NON_QOS; |
105 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) | 112 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) |
@@ -108,8 +115,12 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
108 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; | 115 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL; |
109 | } | 116 | } |
110 | 117 | ||
111 | /* tid_tspec will default to 0 = BE when QOS isn't enabled */ | 118 | /* Default to 0 (BE) when tid_spec is set to IWL_TID_NON_QOS */ |
112 | ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; | 119 | if (tx_cmd->tid_tspec < IWL_MAX_TID_COUNT) |
120 | ac = tid_to_mac80211_ac[tx_cmd->tid_tspec]; | ||
121 | else | ||
122 | ac = tid_to_mac80211_ac[0]; | ||
123 | |||
113 | tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) << | 124 | tx_flags |= iwl_mvm_bt_coex_tx_prio(mvm, hdr, info, ac) << |
114 | TX_CMD_FLG_BT_PRIO_POS; | 125 | TX_CMD_FLG_BT_PRIO_POS; |
115 | 126 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index e56e77ef5d2e..917431e30f74 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c | |||
@@ -665,7 +665,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm) | |||
665 | if (num_of_ant(mvm->fw->valid_rx_ant) == 1) | 665 | if (num_of_ant(mvm->fw->valid_rx_ant) == 1) |
666 | return false; | 666 | return false; |
667 | 667 | ||
668 | if (!mvm->cfg->rx_with_siso_diversity) | 668 | if (mvm->cfg->rx_with_siso_diversity) |
669 | return false; | 669 | return false; |
670 | 670 | ||
671 | ieee80211_iterate_active_interfaces_atomic( | 671 | ieee80211_iterate_active_interfaces_atomic( |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 3ee8e3848876..d5aadb00dd9e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -367,7 +367,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
367 | 367 | ||
368 | /* 3165 Series */ | 368 | /* 3165 Series */ |
369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, | 369 | {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)}, |
370 | {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)}, | ||
371 | {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)}, | ||
370 | {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)}, | 372 | {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)}, |
373 | {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)}, | ||
374 | {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)}, | ||
371 | 375 | ||
372 | /* 7265 Series */ | 376 | /* 7265 Series */ |
373 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, | 377 | {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, |
@@ -523,8 +527,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
523 | else if (cfg == &iwl7265_n_cfg) | 527 | else if (cfg == &iwl7265_n_cfg) |
524 | cfg_7265d = &iwl7265d_n_cfg; | 528 | cfg_7265d = &iwl7265d_n_cfg; |
525 | if (cfg_7265d && | 529 | if (cfg_7265d && |
526 | (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) | 530 | (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) { |
527 | cfg = cfg_7265d; | 531 | cfg = cfg_7265d; |
532 | iwl_trans->cfg = cfg_7265d; | ||
533 | } | ||
528 | #endif | 534 | #endif |
529 | 535 | ||
530 | pci_set_drvdata(pdev, iwl_trans); | 536 | pci_set_drvdata(pdev, iwl_trans); |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5d79a1f44b8e..523fe0c88dcb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -614,7 +614,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, | |||
614 | { | 614 | { |
615 | u8 *v_addr; | 615 | u8 *v_addr; |
616 | dma_addr_t p_addr; | 616 | dma_addr_t p_addr; |
617 | u32 offset, chunk_sz = section->len; | 617 | u32 offset, chunk_sz = min_t(u32, FH_MEM_TB_MAX_LENGTH, section->len); |
618 | int ret = 0; | 618 | int ret = 0; |
619 | 619 | ||
620 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", | 620 | IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", |
@@ -1012,16 +1012,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1012 | /* Stop the device, and put it in low power state */ | 1012 | /* Stop the device, and put it in low power state */ |
1013 | iwl_pcie_apm_stop(trans); | 1013 | iwl_pcie_apm_stop(trans); |
1014 | 1014 | ||
1015 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | 1015 | /* stop and reset the on-board processor */ |
1016 | * Clean again the interrupt here | 1016 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
1017 | udelay(20); | ||
1018 | |||
1019 | /* | ||
1020 | * Upon stop, the APM issues an interrupt if HW RF kill is set. | ||
1021 | * This is a bug in certain verions of the hardware. | ||
1022 | * Certain devices also keep sending HW RF kill interrupt all | ||
1023 | * the time, unless the interrupt is ACKed even if the interrupt | ||
1024 | * should be masked. Re-ACK all the interrupts here. | ||
1017 | */ | 1025 | */ |
1018 | spin_lock(&trans_pcie->irq_lock); | 1026 | spin_lock(&trans_pcie->irq_lock); |
1019 | iwl_disable_interrupts(trans); | 1027 | iwl_disable_interrupts(trans); |
1020 | spin_unlock(&trans_pcie->irq_lock); | 1028 | spin_unlock(&trans_pcie->irq_lock); |
1021 | 1029 | ||
1022 | /* stop and reset the on-board processor */ | ||
1023 | iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | ||
1024 | udelay(20); | ||
1025 | 1030 | ||
1026 | /* clear all status bits */ | 1031 | /* clear all status bits */ |
1027 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); | 1032 | clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status); |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 846a2e6e34d8..c70efb9a6e78 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -666,7 +666,8 @@ tx_status_ok: | |||
666 | } | 666 | } |
667 | 667 | ||
668 | static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, | 668 | static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, |
669 | u8 *entry, int rxring_idx, int desc_idx) | 669 | struct sk_buff *new_skb, u8 *entry, |
670 | int rxring_idx, int desc_idx) | ||
670 | { | 671 | { |
671 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 672 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
672 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 673 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
@@ -674,11 +675,15 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, | |||
674 | u8 tmp_one = 1; | 675 | u8 tmp_one = 1; |
675 | struct sk_buff *skb; | 676 | struct sk_buff *skb; |
676 | 677 | ||
678 | if (likely(new_skb)) { | ||
679 | skb = new_skb; | ||
680 | goto remap; | ||
681 | } | ||
677 | skb = dev_alloc_skb(rtlpci->rxbuffersize); | 682 | skb = dev_alloc_skb(rtlpci->rxbuffersize); |
678 | if (!skb) | 683 | if (!skb) |
679 | return 0; | 684 | return 0; |
680 | rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; | ||
681 | 685 | ||
686 | remap: | ||
682 | /* just set skb->cb to mapping addr for pci_unmap_single use */ | 687 | /* just set skb->cb to mapping addr for pci_unmap_single use */ |
683 | *((dma_addr_t *)skb->cb) = | 688 | *((dma_addr_t *)skb->cb) = |
684 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), | 689 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), |
@@ -686,6 +691,7 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, | |||
686 | bufferaddress = *((dma_addr_t *)skb->cb); | 691 | bufferaddress = *((dma_addr_t *)skb->cb); |
687 | if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) | 692 | if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) |
688 | return 0; | 693 | return 0; |
694 | rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb; | ||
689 | if (rtlpriv->use_new_trx_flow) { | 695 | if (rtlpriv->use_new_trx_flow) { |
690 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, | 696 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false, |
691 | HW_DESC_RX_PREPARE, | 697 | HW_DESC_RX_PREPARE, |
@@ -781,6 +787,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
781 | /*rx pkt */ | 787 | /*rx pkt */ |
782 | struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ | 788 | struct sk_buff *skb = rtlpci->rx_ring[rxring_idx].rx_buf[ |
783 | rtlpci->rx_ring[rxring_idx].idx]; | 789 | rtlpci->rx_ring[rxring_idx].idx]; |
790 | struct sk_buff *new_skb; | ||
784 | 791 | ||
785 | if (rtlpriv->use_new_trx_flow) { | 792 | if (rtlpriv->use_new_trx_flow) { |
786 | rx_remained_cnt = | 793 | rx_remained_cnt = |
@@ -807,6 +814,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
807 | pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb), | 814 | pci_unmap_single(rtlpci->pdev, *((dma_addr_t *)skb->cb), |
808 | rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); | 815 | rtlpci->rxbuffersize, PCI_DMA_FROMDEVICE); |
809 | 816 | ||
817 | /* get a new skb - if fail, old one will be reused */ | ||
818 | new_skb = dev_alloc_skb(rtlpci->rxbuffersize); | ||
819 | if (unlikely(!new_skb)) { | ||
820 | pr_err("Allocation of new skb failed in %s\n", | ||
821 | __func__); | ||
822 | goto no_new; | ||
823 | } | ||
810 | if (rtlpriv->use_new_trx_flow) { | 824 | if (rtlpriv->use_new_trx_flow) { |
811 | buffer_desc = | 825 | buffer_desc = |
812 | &rtlpci->rx_ring[rxring_idx].buffer_desc | 826 | &rtlpci->rx_ring[rxring_idx].buffer_desc |
@@ -911,14 +925,16 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
911 | schedule_work(&rtlpriv->works.lps_change_work); | 925 | schedule_work(&rtlpriv->works.lps_change_work); |
912 | } | 926 | } |
913 | end: | 927 | end: |
928 | skb = new_skb; | ||
929 | no_new: | ||
914 | if (rtlpriv->use_new_trx_flow) { | 930 | if (rtlpriv->use_new_trx_flow) { |
915 | _rtl_pci_init_one_rxdesc(hw, (u8 *)buffer_desc, | 931 | _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)buffer_desc, |
916 | rxring_idx, | 932 | rxring_idx, |
917 | rtlpci->rx_ring[rxring_idx].idx); | 933 | rtlpci->rx_ring[rxring_idx].idx); |
918 | } else { | 934 | } else { |
919 | _rtl_pci_init_one_rxdesc(hw, (u8 *)pdesc, rxring_idx, | 935 | _rtl_pci_init_one_rxdesc(hw, skb, (u8 *)pdesc, |
936 | rxring_idx, | ||
920 | rtlpci->rx_ring[rxring_idx].idx); | 937 | rtlpci->rx_ring[rxring_idx].idx); |
921 | |||
922 | if (rtlpci->rx_ring[rxring_idx].idx == | 938 | if (rtlpci->rx_ring[rxring_idx].idx == |
923 | rtlpci->rxringcount - 1) | 939 | rtlpci->rxringcount - 1) |
924 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, | 940 | rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, |
@@ -1307,7 +1323,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) | |||
1307 | rtlpci->rx_ring[rxring_idx].idx = 0; | 1323 | rtlpci->rx_ring[rxring_idx].idx = 0; |
1308 | for (i = 0; i < rtlpci->rxringcount; i++) { | 1324 | for (i = 0; i < rtlpci->rxringcount; i++) { |
1309 | entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; | 1325 | entry = &rtlpci->rx_ring[rxring_idx].buffer_desc[i]; |
1310 | if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, | 1326 | if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, |
1311 | rxring_idx, i)) | 1327 | rxring_idx, i)) |
1312 | return -ENOMEM; | 1328 | return -ENOMEM; |
1313 | } | 1329 | } |
@@ -1332,7 +1348,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) | |||
1332 | 1348 | ||
1333 | for (i = 0; i < rtlpci->rxringcount; i++) { | 1349 | for (i = 0; i < rtlpci->rxringcount; i++) { |
1334 | entry = &rtlpci->rx_ring[rxring_idx].desc[i]; | 1350 | entry = &rtlpci->rx_ring[rxring_idx].desc[i]; |
1335 | if (!_rtl_pci_init_one_rxdesc(hw, (u8 *)entry, | 1351 | if (!_rtl_pci_init_one_rxdesc(hw, NULL, (u8 *)entry, |
1336 | rxring_idx, i)) | 1352 | rxring_idx, i)) |
1337 | return -ENOMEM; | 1353 | return -ENOMEM; |
1338 | } | 1354 | } |
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index efbaf2ae1999..794204e34fba 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c | |||
@@ -737,6 +737,7 @@ static void connect(struct backend_info *be) | |||
737 | } | 737 | } |
738 | 738 | ||
739 | queue->remaining_credit = credit_bytes; | 739 | queue->remaining_credit = credit_bytes; |
740 | queue->credit_usec = credit_usec; | ||
740 | 741 | ||
741 | err = connect_rings(be, queue); | 742 | err = connect_rings(be, queue); |
742 | if (err) { | 743 | if (err) { |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 22bcb4e12e2a..d8c10764f130 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -88,10 +88,8 @@ struct netfront_cb { | |||
88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) | 88 | #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3) |
89 | 89 | ||
90 | struct netfront_stats { | 90 | struct netfront_stats { |
91 | u64 rx_packets; | 91 | u64 packets; |
92 | u64 tx_packets; | 92 | u64 bytes; |
93 | u64 rx_bytes; | ||
94 | u64 tx_bytes; | ||
95 | struct u64_stats_sync syncp; | 93 | struct u64_stats_sync syncp; |
96 | }; | 94 | }; |
97 | 95 | ||
@@ -160,7 +158,8 @@ struct netfront_info { | |||
160 | struct netfront_queue *queues; | 158 | struct netfront_queue *queues; |
161 | 159 | ||
162 | /* Statistics */ | 160 | /* Statistics */ |
163 | struct netfront_stats __percpu *stats; | 161 | struct netfront_stats __percpu *rx_stats; |
162 | struct netfront_stats __percpu *tx_stats; | ||
164 | 163 | ||
165 | atomic_t rx_gso_checksum_fixup; | 164 | atomic_t rx_gso_checksum_fixup; |
166 | }; | 165 | }; |
@@ -565,7 +564,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
565 | { | 564 | { |
566 | unsigned short id; | 565 | unsigned short id; |
567 | struct netfront_info *np = netdev_priv(dev); | 566 | struct netfront_info *np = netdev_priv(dev); |
568 | struct netfront_stats *stats = this_cpu_ptr(np->stats); | 567 | struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); |
569 | struct xen_netif_tx_request *tx; | 568 | struct xen_netif_tx_request *tx; |
570 | char *data = skb->data; | 569 | char *data = skb->data; |
571 | RING_IDX i; | 570 | RING_IDX i; |
@@ -672,10 +671,10 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
672 | if (notify) | 671 | if (notify) |
673 | notify_remote_via_irq(queue->tx_irq); | 672 | notify_remote_via_irq(queue->tx_irq); |
674 | 673 | ||
675 | u64_stats_update_begin(&stats->syncp); | 674 | u64_stats_update_begin(&tx_stats->syncp); |
676 | stats->tx_bytes += skb->len; | 675 | tx_stats->bytes += skb->len; |
677 | stats->tx_packets++; | 676 | tx_stats->packets++; |
678 | u64_stats_update_end(&stats->syncp); | 677 | u64_stats_update_end(&tx_stats->syncp); |
679 | 678 | ||
680 | /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ | 679 | /* Note: It is not safe to access skb after xennet_tx_buf_gc()! */ |
681 | xennet_tx_buf_gc(queue); | 680 | xennet_tx_buf_gc(queue); |
@@ -931,7 +930,7 @@ static int checksum_setup(struct net_device *dev, struct sk_buff *skb) | |||
931 | static int handle_incoming_queue(struct netfront_queue *queue, | 930 | static int handle_incoming_queue(struct netfront_queue *queue, |
932 | struct sk_buff_head *rxq) | 931 | struct sk_buff_head *rxq) |
933 | { | 932 | { |
934 | struct netfront_stats *stats = this_cpu_ptr(queue->info->stats); | 933 | struct netfront_stats *rx_stats = this_cpu_ptr(queue->info->rx_stats); |
935 | int packets_dropped = 0; | 934 | int packets_dropped = 0; |
936 | struct sk_buff *skb; | 935 | struct sk_buff *skb; |
937 | 936 | ||
@@ -952,10 +951,10 @@ static int handle_incoming_queue(struct netfront_queue *queue, | |||
952 | continue; | 951 | continue; |
953 | } | 952 | } |
954 | 953 | ||
955 | u64_stats_update_begin(&stats->syncp); | 954 | u64_stats_update_begin(&rx_stats->syncp); |
956 | stats->rx_packets++; | 955 | rx_stats->packets++; |
957 | stats->rx_bytes += skb->len; | 956 | rx_stats->bytes += skb->len; |
958 | u64_stats_update_end(&stats->syncp); | 957 | u64_stats_update_end(&rx_stats->syncp); |
959 | 958 | ||
960 | /* Pass it up. */ | 959 | /* Pass it up. */ |
961 | napi_gro_receive(&queue->napi, skb); | 960 | napi_gro_receive(&queue->napi, skb); |
@@ -1079,18 +1078,22 @@ static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, | |||
1079 | int cpu; | 1078 | int cpu; |
1080 | 1079 | ||
1081 | for_each_possible_cpu(cpu) { | 1080 | for_each_possible_cpu(cpu) { |
1082 | struct netfront_stats *stats = per_cpu_ptr(np->stats, cpu); | 1081 | struct netfront_stats *rx_stats = per_cpu_ptr(np->rx_stats, cpu); |
1082 | struct netfront_stats *tx_stats = per_cpu_ptr(np->tx_stats, cpu); | ||
1083 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | 1083 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; |
1084 | unsigned int start; | 1084 | unsigned int start; |
1085 | 1085 | ||
1086 | do { | 1086 | do { |
1087 | start = u64_stats_fetch_begin_irq(&stats->syncp); | 1087 | start = u64_stats_fetch_begin_irq(&tx_stats->syncp); |
1088 | tx_packets = tx_stats->packets; | ||
1089 | tx_bytes = tx_stats->bytes; | ||
1090 | } while (u64_stats_fetch_retry_irq(&tx_stats->syncp, start)); | ||
1088 | 1091 | ||
1089 | rx_packets = stats->rx_packets; | 1092 | do { |
1090 | tx_packets = stats->tx_packets; | 1093 | start = u64_stats_fetch_begin_irq(&rx_stats->syncp); |
1091 | rx_bytes = stats->rx_bytes; | 1094 | rx_packets = rx_stats->packets; |
1092 | tx_bytes = stats->tx_bytes; | 1095 | rx_bytes = rx_stats->bytes; |
1093 | } while (u64_stats_fetch_retry_irq(&stats->syncp, start)); | 1096 | } while (u64_stats_fetch_retry_irq(&rx_stats->syncp, start)); |
1094 | 1097 | ||
1095 | tot->rx_packets += rx_packets; | 1098 | tot->rx_packets += rx_packets; |
1096 | tot->tx_packets += tx_packets; | 1099 | tot->tx_packets += tx_packets; |
@@ -1275,6 +1278,15 @@ static const struct net_device_ops xennet_netdev_ops = { | |||
1275 | #endif | 1278 | #endif |
1276 | }; | 1279 | }; |
1277 | 1280 | ||
1281 | static void xennet_free_netdev(struct net_device *netdev) | ||
1282 | { | ||
1283 | struct netfront_info *np = netdev_priv(netdev); | ||
1284 | |||
1285 | free_percpu(np->rx_stats); | ||
1286 | free_percpu(np->tx_stats); | ||
1287 | free_netdev(netdev); | ||
1288 | } | ||
1289 | |||
1278 | static struct net_device *xennet_create_dev(struct xenbus_device *dev) | 1290 | static struct net_device *xennet_create_dev(struct xenbus_device *dev) |
1279 | { | 1291 | { |
1280 | int err; | 1292 | int err; |
@@ -1295,8 +1307,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1295 | np->queues = NULL; | 1307 | np->queues = NULL; |
1296 | 1308 | ||
1297 | err = -ENOMEM; | 1309 | err = -ENOMEM; |
1298 | np->stats = netdev_alloc_pcpu_stats(struct netfront_stats); | 1310 | np->rx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); |
1299 | if (np->stats == NULL) | 1311 | if (np->rx_stats == NULL) |
1312 | goto exit; | ||
1313 | np->tx_stats = netdev_alloc_pcpu_stats(struct netfront_stats); | ||
1314 | if (np->tx_stats == NULL) | ||
1300 | goto exit; | 1315 | goto exit; |
1301 | 1316 | ||
1302 | netdev->netdev_ops = &xennet_netdev_ops; | 1317 | netdev->netdev_ops = &xennet_netdev_ops; |
@@ -1327,7 +1342,7 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) | |||
1327 | return netdev; | 1342 | return netdev; |
1328 | 1343 | ||
1329 | exit: | 1344 | exit: |
1330 | free_netdev(netdev); | 1345 | xennet_free_netdev(netdev); |
1331 | return ERR_PTR(err); | 1346 | return ERR_PTR(err); |
1332 | } | 1347 | } |
1333 | 1348 | ||
@@ -1369,7 +1384,7 @@ static int netfront_probe(struct xenbus_device *dev, | |||
1369 | return 0; | 1384 | return 0; |
1370 | 1385 | ||
1371 | fail: | 1386 | fail: |
1372 | free_netdev(netdev); | 1387 | xennet_free_netdev(netdev); |
1373 | dev_set_drvdata(&dev->dev, NULL); | 1388 | dev_set_drvdata(&dev->dev, NULL); |
1374 | return err; | 1389 | return err; |
1375 | } | 1390 | } |
@@ -2189,9 +2204,7 @@ static int xennet_remove(struct xenbus_device *dev) | |||
2189 | info->queues = NULL; | 2204 | info->queues = NULL; |
2190 | } | 2205 | } |
2191 | 2206 | ||
2192 | free_percpu(info->stats); | 2207 | xennet_free_netdev(info->netdev); |
2193 | |||
2194 | free_netdev(info->netdev); | ||
2195 | 2208 | ||
2196 | return 0; | 2209 | return 0; |
2197 | } | 2210 | } |
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index ea63fbd228ed..352b4f28f82c 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c | |||
@@ -114,17 +114,6 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, | |||
114 | ret = of_overlay_apply_one(ov, tchild, child); | 114 | ret = of_overlay_apply_one(ov, tchild, child); |
115 | if (ret) | 115 | if (ret) |
116 | return ret; | 116 | return ret; |
117 | |||
118 | /* The properties are already copied, now do the child nodes */ | ||
119 | for_each_child_of_node(child, grandchild) { | ||
120 | ret = of_overlay_apply_single_device_node(ov, tchild, grandchild); | ||
121 | if (ret) { | ||
122 | pr_err("%s: Failed to apply single node @%s/%s\n", | ||
123 | __func__, tchild->full_name, | ||
124 | grandchild->name); | ||
125 | return ret; | ||
126 | } | ||
127 | } | ||
128 | } | 117 | } |
129 | 118 | ||
130 | return ret; | 119 | return ret; |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 5b33c6a21807..b0d50d70a8a1 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -188,7 +188,7 @@ static void of_dma_configure(struct device *dev) | |||
188 | size = dev->coherent_dma_mask; | 188 | size = dev->coherent_dma_mask; |
189 | } else { | 189 | } else { |
190 | offset = PFN_DOWN(paddr - dma_addr); | 190 | offset = PFN_DOWN(paddr - dma_addr); |
191 | dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", dev->dma_pfn_offset); | 191 | dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset); |
192 | } | 192 | } |
193 | dev->dma_pfn_offset = offset; | 193 | dev->dma_pfn_offset = offset; |
194 | 194 | ||
@@ -566,6 +566,10 @@ static int of_platform_notify(struct notifier_block *nb, | |||
566 | if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) | 566 | if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) |
567 | return NOTIFY_OK; /* not for us */ | 567 | return NOTIFY_OK; /* not for us */ |
568 | 568 | ||
569 | /* already populated? (driver using of_populate manually) */ | ||
570 | if (of_node_check_flag(rd->dn, OF_POPULATED)) | ||
571 | return NOTIFY_OK; | ||
572 | |||
569 | /* pdev_parent may be NULL when no bus platform device */ | 573 | /* pdev_parent may be NULL when no bus platform device */ |
570 | pdev_parent = of_find_device_by_node(rd->dn->parent); | 574 | pdev_parent = of_find_device_by_node(rd->dn->parent); |
571 | pdev = of_platform_device_create(rd->dn, NULL, | 575 | pdev = of_platform_device_create(rd->dn, NULL, |
@@ -581,6 +585,11 @@ static int of_platform_notify(struct notifier_block *nb, | |||
581 | break; | 585 | break; |
582 | 586 | ||
583 | case OF_RECONFIG_CHANGE_REMOVE: | 587 | case OF_RECONFIG_CHANGE_REMOVE: |
588 | |||
589 | /* already depopulated? */ | ||
590 | if (!of_node_check_flag(rd->dn, OF_POPULATED)) | ||
591 | return NOTIFY_OK; | ||
592 | |||
584 | /* find our device by node */ | 593 | /* find our device by node */ |
585 | pdev = of_find_device_by_node(rd->dn); | 594 | pdev = of_find_device_by_node(rd->dn); |
586 | if (pdev == NULL) | 595 | if (pdev == NULL) |
diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi index 75976da22b2e..a2b687d5f324 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi | |||
@@ -176,5 +176,60 @@ | |||
176 | }; | 176 | }; |
177 | }; | 177 | }; |
178 | 178 | ||
179 | overlay10 { | ||
180 | fragment@0 { | ||
181 | target-path = "/testcase-data/overlay-node/test-bus"; | ||
182 | __overlay__ { | ||
183 | |||
184 | /* suppress DTC warning */ | ||
185 | #address-cells = <1>; | ||
186 | #size-cells = <0>; | ||
187 | |||
188 | test-selftest10 { | ||
189 | compatible = "selftest"; | ||
190 | status = "okay"; | ||
191 | reg = <10>; | ||
192 | |||
193 | #address-cells = <1>; | ||
194 | #size-cells = <0>; | ||
195 | |||
196 | test-selftest101 { | ||
197 | compatible = "selftest"; | ||
198 | status = "okay"; | ||
199 | reg = <1>; | ||
200 | }; | ||
201 | |||
202 | }; | ||
203 | }; | ||
204 | }; | ||
205 | }; | ||
206 | |||
207 | overlay11 { | ||
208 | fragment@0 { | ||
209 | target-path = "/testcase-data/overlay-node/test-bus"; | ||
210 | __overlay__ { | ||
211 | |||
212 | /* suppress DTC warning */ | ||
213 | #address-cells = <1>; | ||
214 | #size-cells = <0>; | ||
215 | |||
216 | test-selftest11 { | ||
217 | compatible = "selftest"; | ||
218 | status = "okay"; | ||
219 | reg = <11>; | ||
220 | |||
221 | #address-cells = <1>; | ||
222 | #size-cells = <0>; | ||
223 | |||
224 | test-selftest111 { | ||
225 | compatible = "selftest"; | ||
226 | status = "okay"; | ||
227 | reg = <1>; | ||
228 | }; | ||
229 | |||
230 | }; | ||
231 | }; | ||
232 | }; | ||
233 | }; | ||
179 | }; | 234 | }; |
180 | }; | 235 | }; |
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 844838e11ef1..41a4a138f53b 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c | |||
@@ -978,6 +978,9 @@ static int selftest_probe(struct platform_device *pdev) | |||
978 | } | 978 | } |
979 | 979 | ||
980 | dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); | 980 | dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); |
981 | |||
982 | of_platform_populate(np, NULL, NULL, &pdev->dev); | ||
983 | |||
981 | return 0; | 984 | return 0; |
982 | } | 985 | } |
983 | 986 | ||
@@ -1385,6 +1388,39 @@ static void of_selftest_overlay_8(void) | |||
1385 | selftest(1, "overlay test %d passed\n", 8); | 1388 | selftest(1, "overlay test %d passed\n", 8); |
1386 | } | 1389 | } |
1387 | 1390 | ||
1391 | /* test insertion of a bus with parent devices */ | ||
1392 | static void of_selftest_overlay_10(void) | ||
1393 | { | ||
1394 | int ret; | ||
1395 | char *child_path; | ||
1396 | |||
1397 | /* device should disable */ | ||
1398 | ret = of_selftest_apply_overlay_check(10, 10, 0, 1); | ||
1399 | if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 10)) | ||
1400 | return; | ||
1401 | |||
1402 | child_path = kasprintf(GFP_KERNEL, "%s/test-selftest101", | ||
1403 | selftest_path(10)); | ||
1404 | if (selftest(child_path, "overlay test %d failed; kasprintf\n", 10)) | ||
1405 | return; | ||
1406 | |||
1407 | ret = of_path_platform_device_exists(child_path); | ||
1408 | kfree(child_path); | ||
1409 | if (selftest(ret, "overlay test %d failed; no child device\n", 10)) | ||
1410 | return; | ||
1411 | } | ||
1412 | |||
1413 | /* test insertion of a bus with parent devices (and revert) */ | ||
1414 | static void of_selftest_overlay_11(void) | ||
1415 | { | ||
1416 | int ret; | ||
1417 | |||
1418 | /* device should disable */ | ||
1419 | ret = of_selftest_apply_revert_overlay_check(11, 11, 0, 1); | ||
1420 | if (selftest(ret == 0, "overlay test %d failed; overlay application\n", 11)) | ||
1421 | return; | ||
1422 | } | ||
1423 | |||
1388 | static void __init of_selftest_overlay(void) | 1424 | static void __init of_selftest_overlay(void) |
1389 | { | 1425 | { |
1390 | struct device_node *bus_np = NULL; | 1426 | struct device_node *bus_np = NULL; |
@@ -1433,6 +1469,9 @@ static void __init of_selftest_overlay(void) | |||
1433 | of_selftest_overlay_6(); | 1469 | of_selftest_overlay_6(); |
1434 | of_selftest_overlay_8(); | 1470 | of_selftest_overlay_8(); |
1435 | 1471 | ||
1472 | of_selftest_overlay_10(); | ||
1473 | of_selftest_overlay_11(); | ||
1474 | |||
1436 | out: | 1475 | out: |
1437 | of_node_put(bus_np); | 1476 | of_node_put(bus_np); |
1438 | } | 1477 | } |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 37e71ff6408d..dceb9ddfd99a 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -694,9 +694,8 @@ lba_fixup_bus(struct pci_bus *bus) | |||
694 | int i; | 694 | int i; |
695 | /* PCI-PCI Bridge */ | 695 | /* PCI-PCI Bridge */ |
696 | pci_read_bridge_bases(bus); | 696 | pci_read_bridge_bases(bus); |
697 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | 697 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) |
698 | pci_claim_resource(bus->self, i); | 698 | pci_claim_bridge_resource(bus->self, i); |
699 | } | ||
700 | } else { | 699 | } else { |
701 | /* Host-PCI Bridge */ | 700 | /* Host-PCI Bridge */ |
702 | int err; | 701 | int err; |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 73aef51a28f0..8fb16188cd82 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
228 | } | 228 | } |
229 | EXPORT_SYMBOL(pci_bus_alloc_resource); | 229 | EXPORT_SYMBOL(pci_bus_alloc_resource); |
230 | 230 | ||
231 | /* | ||
232 | * The @idx resource of @dev should be a PCI-PCI bridge window. If this | ||
233 | * resource fits inside a window of an upstream bridge, do nothing. If it | ||
234 | * overlaps an upstream window but extends outside it, clip the resource so | ||
235 | * it fits completely inside. | ||
236 | */ | ||
237 | bool pci_bus_clip_resource(struct pci_dev *dev, int idx) | ||
238 | { | ||
239 | struct pci_bus *bus = dev->bus; | ||
240 | struct resource *res = &dev->resource[idx]; | ||
241 | struct resource orig_res = *res; | ||
242 | struct resource *r; | ||
243 | int i; | ||
244 | |||
245 | pci_bus_for_each_resource(bus, r, i) { | ||
246 | resource_size_t start, end; | ||
247 | |||
248 | if (!r) | ||
249 | continue; | ||
250 | |||
251 | if (resource_type(res) != resource_type(r)) | ||
252 | continue; | ||
253 | |||
254 | start = max(r->start, res->start); | ||
255 | end = min(r->end, res->end); | ||
256 | |||
257 | if (start > end) | ||
258 | continue; /* no overlap */ | ||
259 | |||
260 | if (res->start == start && res->end == end) | ||
261 | return false; /* no change */ | ||
262 | |||
263 | res->start = start; | ||
264 | res->end = end; | ||
265 | dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", | ||
266 | &orig_res, res); | ||
267 | |||
268 | return true; | ||
269 | } | ||
270 | |||
271 | return false; | ||
272 | } | ||
273 | |||
231 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } | 274 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } |
232 | 275 | ||
233 | /** | 276 | /** |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cab05f31223f..e9d4fd861ba1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3271,7 +3271,8 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe) | |||
3271 | { | 3271 | { |
3272 | struct pci_dev *pdev; | 3272 | struct pci_dev *pdev; |
3273 | 3273 | ||
3274 | if (pci_is_root_bus(dev->bus) || dev->subordinate || !dev->bus->self) | 3274 | if (pci_is_root_bus(dev->bus) || dev->subordinate || |
3275 | !dev->bus->self || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) | ||
3275 | return -ENOTTY; | 3276 | return -ENOTTY; |
3276 | 3277 | ||
3277 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) | 3278 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) |
@@ -3305,7 +3306,8 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) | |||
3305 | { | 3306 | { |
3306 | struct pci_dev *pdev; | 3307 | struct pci_dev *pdev; |
3307 | 3308 | ||
3308 | if (dev->subordinate || !dev->slot) | 3309 | if (dev->subordinate || !dev->slot || |
3310 | dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) | ||
3309 | return -ENOTTY; | 3311 | return -ENOTTY; |
3310 | 3312 | ||
3311 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) | 3313 | list_for_each_entry(pdev, &dev->bus->devices, bus_list) |
@@ -3557,6 +3559,20 @@ int pci_try_reset_function(struct pci_dev *dev) | |||
3557 | } | 3559 | } |
3558 | EXPORT_SYMBOL_GPL(pci_try_reset_function); | 3560 | EXPORT_SYMBOL_GPL(pci_try_reset_function); |
3559 | 3561 | ||
3562 | /* Do any devices on or below this bus prevent a bus reset? */ | ||
3563 | static bool pci_bus_resetable(struct pci_bus *bus) | ||
3564 | { | ||
3565 | struct pci_dev *dev; | ||
3566 | |||
3567 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
3568 | if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || | ||
3569 | (dev->subordinate && !pci_bus_resetable(dev->subordinate))) | ||
3570 | return false; | ||
3571 | } | ||
3572 | |||
3573 | return true; | ||
3574 | } | ||
3575 | |||
3560 | /* Lock devices from the top of the tree down */ | 3576 | /* Lock devices from the top of the tree down */ |
3561 | static void pci_bus_lock(struct pci_bus *bus) | 3577 | static void pci_bus_lock(struct pci_bus *bus) |
3562 | { | 3578 | { |
@@ -3607,6 +3623,22 @@ unlock: | |||
3607 | return 0; | 3623 | return 0; |
3608 | } | 3624 | } |
3609 | 3625 | ||
3626 | /* Do any devices on or below this slot prevent a bus reset? */ | ||
3627 | static bool pci_slot_resetable(struct pci_slot *slot) | ||
3628 | { | ||
3629 | struct pci_dev *dev; | ||
3630 | |||
3631 | list_for_each_entry(dev, &slot->bus->devices, bus_list) { | ||
3632 | if (!dev->slot || dev->slot != slot) | ||
3633 | continue; | ||
3634 | if (dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET || | ||
3635 | (dev->subordinate && !pci_bus_resetable(dev->subordinate))) | ||
3636 | return false; | ||
3637 | } | ||
3638 | |||
3639 | return true; | ||
3640 | } | ||
3641 | |||
3610 | /* Lock devices from the top of the tree down */ | 3642 | /* Lock devices from the top of the tree down */ |
3611 | static void pci_slot_lock(struct pci_slot *slot) | 3643 | static void pci_slot_lock(struct pci_slot *slot) |
3612 | { | 3644 | { |
@@ -3728,7 +3760,7 @@ static int pci_slot_reset(struct pci_slot *slot, int probe) | |||
3728 | { | 3760 | { |
3729 | int rc; | 3761 | int rc; |
3730 | 3762 | ||
3731 | if (!slot) | 3763 | if (!slot || !pci_slot_resetable(slot)) |
3732 | return -ENOTTY; | 3764 | return -ENOTTY; |
3733 | 3765 | ||
3734 | if (!probe) | 3766 | if (!probe) |
@@ -3820,7 +3852,7 @@ EXPORT_SYMBOL_GPL(pci_try_reset_slot); | |||
3820 | 3852 | ||
3821 | static int pci_bus_reset(struct pci_bus *bus, int probe) | 3853 | static int pci_bus_reset(struct pci_bus *bus, int probe) |
3822 | { | 3854 | { |
3823 | if (!bus->self) | 3855 | if (!bus->self || !pci_bus_resetable(bus)) |
3824 | return -ENOTTY; | 3856 | return -ENOTTY; |
3825 | 3857 | ||
3826 | if (probe) | 3858 | if (probe) |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 8aff29a804ff..d54632a1db43 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -208,6 +208,7 @@ void __pci_bus_size_bridges(struct pci_bus *bus, | |||
208 | void __pci_bus_assign_resources(const struct pci_bus *bus, | 208 | void __pci_bus_assign_resources(const struct pci_bus *bus, |
209 | struct list_head *realloc_head, | 209 | struct list_head *realloc_head, |
210 | struct list_head *fail_head); | 210 | struct list_head *fail_head); |
211 | bool pci_bus_clip_resource(struct pci_dev *dev, int idx); | ||
211 | 212 | ||
212 | /** | 213 | /** |
213 | * pci_ari_enabled - query ARI forwarding status | 214 | * pci_ari_enabled - query ARI forwarding status |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ed6f89b6efe5..e52356aa09b8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -3028,6 +3028,20 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_REALTEK, 0x8169, | |||
3028 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, | 3028 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, PCI_ANY_ID, |
3029 | quirk_broken_intx_masking); | 3029 | quirk_broken_intx_masking); |
3030 | 3030 | ||
3031 | static void quirk_no_bus_reset(struct pci_dev *dev) | ||
3032 | { | ||
3033 | dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; | ||
3034 | } | ||
3035 | |||
3036 | /* | ||
3037 | * Atheros AR93xx chips do not behave after a bus reset. The device will | ||
3038 | * throw a Link Down error on AER-capable systems and regardless of AER, | ||
3039 | * config space of the device is never accessible again and typically | ||
3040 | * causes the system to hang or reset when access is attempted. | ||
3041 | * http://www.spinics.net/lists/linux-pci/msg34797.html | ||
3042 | */ | ||
3043 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset); | ||
3044 | |||
3031 | #ifdef CONFIG_ACPI | 3045 | #ifdef CONFIG_ACPI |
3032 | /* | 3046 | /* |
3033 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. | 3047 | * Apple: Shutdown Cactus Ridge Thunderbolt controller. |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 0482235eee92..e3e17f3c0f0f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -530,9 +530,8 @@ EXPORT_SYMBOL(pci_setup_cardbus); | |||
530 | config space writes, so it's quite possible that an I/O window of | 530 | config space writes, so it's quite possible that an I/O window of |
531 | the bridge will have some undesirable address (e.g. 0) after the | 531 | the bridge will have some undesirable address (e.g. 0) after the |
532 | first write. Ditto 64-bit prefetchable MMIO. */ | 532 | first write. Ditto 64-bit prefetchable MMIO. */ |
533 | static void pci_setup_bridge_io(struct pci_bus *bus) | 533 | static void pci_setup_bridge_io(struct pci_dev *bridge) |
534 | { | 534 | { |
535 | struct pci_dev *bridge = bus->self; | ||
536 | struct resource *res; | 535 | struct resource *res; |
537 | struct pci_bus_region region; | 536 | struct pci_bus_region region; |
538 | unsigned long io_mask; | 537 | unsigned long io_mask; |
@@ -545,7 +544,7 @@ static void pci_setup_bridge_io(struct pci_bus *bus) | |||
545 | io_mask = PCI_IO_1K_RANGE_MASK; | 544 | io_mask = PCI_IO_1K_RANGE_MASK; |
546 | 545 | ||
547 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 546 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
548 | res = bus->resource[0]; | 547 | res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0]; |
549 | pcibios_resource_to_bus(bridge->bus, ®ion, res); | 548 | pcibios_resource_to_bus(bridge->bus, ®ion, res); |
550 | if (res->flags & IORESOURCE_IO) { | 549 | if (res->flags & IORESOURCE_IO) { |
551 | pci_read_config_word(bridge, PCI_IO_BASE, &l); | 550 | pci_read_config_word(bridge, PCI_IO_BASE, &l); |
@@ -568,15 +567,14 @@ static void pci_setup_bridge_io(struct pci_bus *bus) | |||
568 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); | 567 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); |
569 | } | 568 | } |
570 | 569 | ||
571 | static void pci_setup_bridge_mmio(struct pci_bus *bus) | 570 | static void pci_setup_bridge_mmio(struct pci_dev *bridge) |
572 | { | 571 | { |
573 | struct pci_dev *bridge = bus->self; | ||
574 | struct resource *res; | 572 | struct resource *res; |
575 | struct pci_bus_region region; | 573 | struct pci_bus_region region; |
576 | u32 l; | 574 | u32 l; |
577 | 575 | ||
578 | /* Set up the top and bottom of the PCI Memory segment for this bus. */ | 576 | /* Set up the top and bottom of the PCI Memory segment for this bus. */ |
579 | res = bus->resource[1]; | 577 | res = &bridge->resource[PCI_BRIDGE_RESOURCES + 1]; |
580 | pcibios_resource_to_bus(bridge->bus, ®ion, res); | 578 | pcibios_resource_to_bus(bridge->bus, ®ion, res); |
581 | if (res->flags & IORESOURCE_MEM) { | 579 | if (res->flags & IORESOURCE_MEM) { |
582 | l = (region.start >> 16) & 0xfff0; | 580 | l = (region.start >> 16) & 0xfff0; |
@@ -588,9 +586,8 @@ static void pci_setup_bridge_mmio(struct pci_bus *bus) | |||
588 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 586 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
589 | } | 587 | } |
590 | 588 | ||
591 | static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) | 589 | static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge) |
592 | { | 590 | { |
593 | struct pci_dev *bridge = bus->self; | ||
594 | struct resource *res; | 591 | struct resource *res; |
595 | struct pci_bus_region region; | 592 | struct pci_bus_region region; |
596 | u32 l, bu, lu; | 593 | u32 l, bu, lu; |
@@ -602,7 +599,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_bus *bus) | |||
602 | 599 | ||
603 | /* Set up PREF base/limit. */ | 600 | /* Set up PREF base/limit. */ |
604 | bu = lu = 0; | 601 | bu = lu = 0; |
605 | res = bus->resource[2]; | 602 | res = &bridge->resource[PCI_BRIDGE_RESOURCES + 2]; |
606 | pcibios_resource_to_bus(bridge->bus, ®ion, res); | 603 | pcibios_resource_to_bus(bridge->bus, ®ion, res); |
607 | if (res->flags & IORESOURCE_PREFETCH) { | 604 | if (res->flags & IORESOURCE_PREFETCH) { |
608 | l = (region.start >> 16) & 0xfff0; | 605 | l = (region.start >> 16) & 0xfff0; |
@@ -630,13 +627,13 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type) | |||
630 | &bus->busn_res); | 627 | &bus->busn_res); |
631 | 628 | ||
632 | if (type & IORESOURCE_IO) | 629 | if (type & IORESOURCE_IO) |
633 | pci_setup_bridge_io(bus); | 630 | pci_setup_bridge_io(bridge); |
634 | 631 | ||
635 | if (type & IORESOURCE_MEM) | 632 | if (type & IORESOURCE_MEM) |
636 | pci_setup_bridge_mmio(bus); | 633 | pci_setup_bridge_mmio(bridge); |
637 | 634 | ||
638 | if (type & IORESOURCE_PREFETCH) | 635 | if (type & IORESOURCE_PREFETCH) |
639 | pci_setup_bridge_mmio_pref(bus); | 636 | pci_setup_bridge_mmio_pref(bridge); |
640 | 637 | ||
641 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 638 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
642 | } | 639 | } |
@@ -649,6 +646,41 @@ void pci_setup_bridge(struct pci_bus *bus) | |||
649 | __pci_setup_bridge(bus, type); | 646 | __pci_setup_bridge(bus, type); |
650 | } | 647 | } |
651 | 648 | ||
649 | |||
650 | int pci_claim_bridge_resource(struct pci_dev *bridge, int i) | ||
651 | { | ||
652 | if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END) | ||
653 | return 0; | ||
654 | |||
655 | if (pci_claim_resource(bridge, i) == 0) | ||
656 | return 0; /* claimed the window */ | ||
657 | |||
658 | if ((bridge->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
659 | return 0; | ||
660 | |||
661 | if (!pci_bus_clip_resource(bridge, i)) | ||
662 | return -EINVAL; /* clipping didn't change anything */ | ||
663 | |||
664 | switch (i - PCI_BRIDGE_RESOURCES) { | ||
665 | case 0: | ||
666 | pci_setup_bridge_io(bridge); | ||
667 | break; | ||
668 | case 1: | ||
669 | pci_setup_bridge_mmio(bridge); | ||
670 | break; | ||
671 | case 2: | ||
672 | pci_setup_bridge_mmio_pref(bridge); | ||
673 | break; | ||
674 | default: | ||
675 | return -EINVAL; | ||
676 | } | ||
677 | |||
678 | if (pci_claim_resource(bridge, i) == 0) | ||
679 | return 0; /* claimed a smaller window */ | ||
680 | |||
681 | return -EINVAL; | ||
682 | } | ||
683 | |||
652 | /* Check whether the bridge supports optional I/O and | 684 | /* Check whether the bridge supports optional I/O and |
653 | prefetchable memory ranges. If not, the respective | 685 | prefetchable memory ranges. If not, the respective |
654 | base/limit registers must be read-only and read as 0. */ | 686 | base/limit registers must be read-only and read as 0. */ |
diff --git a/drivers/phy/phy-miphy28lp.c b/drivers/phy/phy-miphy28lp.c index e34da13885e8..27fa62ce6136 100644 --- a/drivers/phy/phy-miphy28lp.c +++ b/drivers/phy/phy-miphy28lp.c | |||
@@ -1050,7 +1050,8 @@ static int miphy28lp_init(struct phy *phy) | |||
1050 | ret = miphy28lp_init_usb3(miphy_phy); | 1050 | ret = miphy28lp_init_usb3(miphy_phy); |
1051 | break; | 1051 | break; |
1052 | default: | 1052 | default: |
1053 | return -EINVAL; | 1053 | ret = -EINVAL; |
1054 | break; | ||
1054 | } | 1055 | } |
1055 | 1056 | ||
1056 | mutex_unlock(&miphy_dev->miphy_mutex); | 1057 | mutex_unlock(&miphy_dev->miphy_mutex); |
diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index c96e8183a8ff..efe724f97e02 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c | |||
@@ -29,10 +29,9 @@ | |||
29 | /** | 29 | /** |
30 | * omap_control_pcie_pcs - set the PCS delay count | 30 | * omap_control_pcie_pcs - set the PCS delay count |
31 | * @dev: the control module device | 31 | * @dev: the control module device |
32 | * @id: index of the pcie PHY (should be 1 or 2) | ||
33 | * @delay: 8 bit delay value | 32 | * @delay: 8 bit delay value |
34 | */ | 33 | */ |
35 | void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) | 34 | void omap_control_pcie_pcs(struct device *dev, u8 delay) |
36 | { | 35 | { |
37 | u32 val; | 36 | u32 val; |
38 | struct omap_control_phy *control_phy; | 37 | struct omap_control_phy *control_phy; |
@@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) | |||
55 | 54 | ||
56 | val = readl(control_phy->pcie_pcs); | 55 | val = readl(control_phy->pcie_pcs); |
57 | val &= ~(OMAP_CTRL_PCIE_PCS_MASK << | 56 | val &= ~(OMAP_CTRL_PCIE_PCS_MASK << |
58 | (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); | 57 | OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); |
59 | val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); | 58 | val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); |
60 | writel(val, control_phy->pcie_pcs); | 59 | writel(val, control_phy->pcie_pcs); |
61 | } | 60 | } |
62 | EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); | 61 | EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); |
diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index fb02a67c9181..a2b08f3ccb03 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c | |||
@@ -244,7 +244,8 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) | |||
244 | else | 244 | else |
245 | data->num_phys = 3; | 245 | data->num_phys = 3; |
246 | 246 | ||
247 | if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy")) | 247 | if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy") || |
248 | of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy")) | ||
248 | data->disc_thresh = 3; | 249 | data->disc_thresh = 3; |
249 | else | 250 | else |
250 | data->disc_thresh = 2; | 251 | data->disc_thresh = 2; |
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index 1387b4d4afe3..465de2c800f2 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c | |||
@@ -82,7 +82,6 @@ struct ti_pipe3 { | |||
82 | struct clk *refclk; | 82 | struct clk *refclk; |
83 | struct clk *div_clk; | 83 | struct clk *div_clk; |
84 | struct pipe3_dpll_map *dpll_map; | 84 | struct pipe3_dpll_map *dpll_map; |
85 | u8 id; | ||
86 | }; | 85 | }; |
87 | 86 | ||
88 | static struct pipe3_dpll_map dpll_map_usb[] = { | 87 | static struct pipe3_dpll_map dpll_map_usb[] = { |
@@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x) | |||
217 | u32 val; | 216 | u32 val; |
218 | int ret = 0; | 217 | int ret = 0; |
219 | 218 | ||
219 | /* | ||
220 | * Set pcie_pcs register to 0x96 for proper functioning of phy | ||
221 | * as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table | ||
222 | * 18-1804. | ||
223 | */ | ||
220 | if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { | 224 | if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { |
221 | omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); | 225 | omap_control_pcie_pcs(phy->control_dev, 0x96); |
222 | return 0; | 226 | return 0; |
223 | } | 227 | } |
224 | 228 | ||
@@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) | |||
347 | } | 351 | } |
348 | 352 | ||
349 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { | 353 | if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { |
350 | if (of_property_read_u8(node, "id", &phy->id) < 0) | ||
351 | phy->id = 1; | ||
352 | 354 | ||
353 | clk = devm_clk_get(phy->dev, "dpll_ref"); | 355 | clk = devm_clk_get(phy->dev, "dpll_ref"); |
354 | if (IS_ERR(clk)) { | 356 | if (IS_ERR(clk)) { |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e4f65510c87e..89dca77ca038 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -1801,14 +1801,15 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) | |||
1801 | if (pctldev == NULL) | 1801 | if (pctldev == NULL) |
1802 | return; | 1802 | return; |
1803 | 1803 | ||
1804 | mutex_lock(&pinctrldev_list_mutex); | ||
1805 | mutex_lock(&pctldev->mutex); | 1804 | mutex_lock(&pctldev->mutex); |
1806 | |||
1807 | pinctrl_remove_device_debugfs(pctldev); | 1805 | pinctrl_remove_device_debugfs(pctldev); |
1806 | mutex_unlock(&pctldev->mutex); | ||
1808 | 1807 | ||
1809 | if (!IS_ERR(pctldev->p)) | 1808 | if (!IS_ERR(pctldev->p)) |
1810 | pinctrl_put(pctldev->p); | 1809 | pinctrl_put(pctldev->p); |
1811 | 1810 | ||
1811 | mutex_lock(&pinctrldev_list_mutex); | ||
1812 | mutex_lock(&pctldev->mutex); | ||
1812 | /* TODO: check that no pinmuxes are still active? */ | 1813 | /* TODO: check that no pinmuxes are still active? */ |
1813 | list_del(&pctldev->node); | 1814 | list_del(&pctldev->node); |
1814 | /* Destroy descriptor tree */ | 1815 | /* Destroy descriptor tree */ |
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index dfd021e8268f..f4cd0b9b2438 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c | |||
@@ -177,7 +177,7 @@ struct at91_pinctrl { | |||
177 | struct device *dev; | 177 | struct device *dev; |
178 | struct pinctrl_dev *pctl; | 178 | struct pinctrl_dev *pctl; |
179 | 179 | ||
180 | int nbanks; | 180 | int nactive_banks; |
181 | 181 | ||
182 | uint32_t *mux_mask; | 182 | uint32_t *mux_mask; |
183 | int nmux; | 183 | int nmux; |
@@ -653,12 +653,18 @@ static int pin_check_config(struct at91_pinctrl *info, const char *name, | |||
653 | int mux; | 653 | int mux; |
654 | 654 | ||
655 | /* check if it's a valid config */ | 655 | /* check if it's a valid config */ |
656 | if (pin->bank >= info->nbanks) { | 656 | if (pin->bank >= gpio_banks) { |
657 | dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", | 657 | dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", |
658 | name, index, pin->bank, info->nbanks); | 658 | name, index, pin->bank, gpio_banks); |
659 | return -EINVAL; | 659 | return -EINVAL; |
660 | } | 660 | } |
661 | 661 | ||
662 | if (!gpio_chips[pin->bank]) { | ||
663 | dev_err(info->dev, "%s: pin conf %d bank_id %d not enabled\n", | ||
664 | name, index, pin->bank); | ||
665 | return -ENXIO; | ||
666 | } | ||
667 | |||
662 | if (pin->pin >= MAX_NB_GPIO_PER_BANK) { | 668 | if (pin->pin >= MAX_NB_GPIO_PER_BANK) { |
663 | dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", | 669 | dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", |
664 | name, index, pin->pin, MAX_NB_GPIO_PER_BANK); | 670 | name, index, pin->pin, MAX_NB_GPIO_PER_BANK); |
@@ -981,7 +987,8 @@ static void at91_pinctrl_child_count(struct at91_pinctrl *info, | |||
981 | 987 | ||
982 | for_each_child_of_node(np, child) { | 988 | for_each_child_of_node(np, child) { |
983 | if (of_device_is_compatible(child, gpio_compat)) { | 989 | if (of_device_is_compatible(child, gpio_compat)) { |
984 | info->nbanks++; | 990 | if (of_device_is_available(child)) |
991 | info->nactive_banks++; | ||
985 | } else { | 992 | } else { |
986 | info->nfunctions++; | 993 | info->nfunctions++; |
987 | info->ngroups += of_get_child_count(child); | 994 | info->ngroups += of_get_child_count(child); |
@@ -1003,11 +1010,11 @@ static int at91_pinctrl_mux_mask(struct at91_pinctrl *info, | |||
1003 | } | 1010 | } |
1004 | 1011 | ||
1005 | size /= sizeof(*list); | 1012 | size /= sizeof(*list); |
1006 | if (!size || size % info->nbanks) { | 1013 | if (!size || size % gpio_banks) { |
1007 | dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks); | 1014 | dev_err(info->dev, "wrong mux mask array should be by %d\n", gpio_banks); |
1008 | return -EINVAL; | 1015 | return -EINVAL; |
1009 | } | 1016 | } |
1010 | info->nmux = size / info->nbanks; | 1017 | info->nmux = size / gpio_banks; |
1011 | 1018 | ||
1012 | info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); | 1019 | info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); |
1013 | if (!info->mux_mask) { | 1020 | if (!info->mux_mask) { |
@@ -1131,7 +1138,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, | |||
1131 | of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; | 1138 | of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; |
1132 | at91_pinctrl_child_count(info, np); | 1139 | at91_pinctrl_child_count(info, np); |
1133 | 1140 | ||
1134 | if (info->nbanks < 1) { | 1141 | if (gpio_banks < 1) { |
1135 | dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n"); | 1142 | dev_err(&pdev->dev, "you need to specify at least one gpio-controller\n"); |
1136 | return -EINVAL; | 1143 | return -EINVAL; |
1137 | } | 1144 | } |
@@ -1144,7 +1151,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, | |||
1144 | 1151 | ||
1145 | dev_dbg(&pdev->dev, "mux-mask\n"); | 1152 | dev_dbg(&pdev->dev, "mux-mask\n"); |
1146 | tmp = info->mux_mask; | 1153 | tmp = info->mux_mask; |
1147 | for (i = 0; i < info->nbanks; i++) { | 1154 | for (i = 0; i < gpio_banks; i++) { |
1148 | for (j = 0; j < info->nmux; j++, tmp++) { | 1155 | for (j = 0; j < info->nmux; j++, tmp++) { |
1149 | dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); | 1156 | dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); |
1150 | } | 1157 | } |
@@ -1162,7 +1169,7 @@ static int at91_pinctrl_probe_dt(struct platform_device *pdev, | |||
1162 | if (!info->groups) | 1169 | if (!info->groups) |
1163 | return -ENOMEM; | 1170 | return -ENOMEM; |
1164 | 1171 | ||
1165 | dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks); | 1172 | dev_dbg(&pdev->dev, "nbanks = %d\n", gpio_banks); |
1166 | dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); | 1173 | dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); |
1167 | dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); | 1174 | dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); |
1168 | 1175 | ||
@@ -1185,7 +1192,7 @@ static int at91_pinctrl_probe(struct platform_device *pdev) | |||
1185 | { | 1192 | { |
1186 | struct at91_pinctrl *info; | 1193 | struct at91_pinctrl *info; |
1187 | struct pinctrl_pin_desc *pdesc; | 1194 | struct pinctrl_pin_desc *pdesc; |
1188 | int ret, i, j, k; | 1195 | int ret, i, j, k, ngpio_chips_enabled = 0; |
1189 | 1196 | ||
1190 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 1197 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
1191 | if (!info) | 1198 | if (!info) |
@@ -1200,23 +1207,27 @@ static int at91_pinctrl_probe(struct platform_device *pdev) | |||
1200 | * to obtain references to the struct gpio_chip * for them, and we | 1207 | * to obtain references to the struct gpio_chip * for them, and we |
1201 | * need this to proceed. | 1208 | * need this to proceed. |
1202 | */ | 1209 | */ |
1203 | for (i = 0; i < info->nbanks; i++) { | 1210 | for (i = 0; i < gpio_banks; i++) |
1204 | if (!gpio_chips[i]) { | 1211 | if (gpio_chips[i]) |
1205 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | 1212 | ngpio_chips_enabled++; |
1206 | devm_kfree(&pdev->dev, info); | 1213 | |
1207 | return -EPROBE_DEFER; | 1214 | if (ngpio_chips_enabled < info->nactive_banks) { |
1208 | } | 1215 | dev_warn(&pdev->dev, |
1216 | "All GPIO chips are not registered yet (%d/%d)\n", | ||
1217 | ngpio_chips_enabled, info->nactive_banks); | ||
1218 | devm_kfree(&pdev->dev, info); | ||
1219 | return -EPROBE_DEFER; | ||
1209 | } | 1220 | } |
1210 | 1221 | ||
1211 | at91_pinctrl_desc.name = dev_name(&pdev->dev); | 1222 | at91_pinctrl_desc.name = dev_name(&pdev->dev); |
1212 | at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK; | 1223 | at91_pinctrl_desc.npins = gpio_banks * MAX_NB_GPIO_PER_BANK; |
1213 | at91_pinctrl_desc.pins = pdesc = | 1224 | at91_pinctrl_desc.pins = pdesc = |
1214 | devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); | 1225 | devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); |
1215 | 1226 | ||
1216 | if (!at91_pinctrl_desc.pins) | 1227 | if (!at91_pinctrl_desc.pins) |
1217 | return -ENOMEM; | 1228 | return -ENOMEM; |
1218 | 1229 | ||
1219 | for (i = 0 , k = 0; i < info->nbanks; i++) { | 1230 | for (i = 0, k = 0; i < gpio_banks; i++) { |
1220 | for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { | 1231 | for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { |
1221 | pdesc->number = k; | 1232 | pdesc->number = k; |
1222 | pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); | 1233 | pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); |
@@ -1234,8 +1245,9 @@ static int at91_pinctrl_probe(struct platform_device *pdev) | |||
1234 | } | 1245 | } |
1235 | 1246 | ||
1236 | /* We will handle a range of GPIO pins */ | 1247 | /* We will handle a range of GPIO pins */ |
1237 | for (i = 0; i < info->nbanks; i++) | 1248 | for (i = 0; i < gpio_banks; i++) |
1238 | pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); | 1249 | if (gpio_chips[i]) |
1250 | pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); | ||
1239 | 1251 | ||
1240 | dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); | 1252 | dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); |
1241 | 1253 | ||
@@ -1613,9 +1625,10 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
1613 | static int at91_gpio_of_irq_setup(struct platform_device *pdev, | 1625 | static int at91_gpio_of_irq_setup(struct platform_device *pdev, |
1614 | struct at91_gpio_chip *at91_gpio) | 1626 | struct at91_gpio_chip *at91_gpio) |
1615 | { | 1627 | { |
1628 | struct gpio_chip *gpiochip_prev = NULL; | ||
1616 | struct at91_gpio_chip *prev = NULL; | 1629 | struct at91_gpio_chip *prev = NULL; |
1617 | struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); | 1630 | struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); |
1618 | int ret; | 1631 | int ret, i; |
1619 | 1632 | ||
1620 | at91_gpio->pioc_hwirq = irqd_to_hwirq(d); | 1633 | at91_gpio->pioc_hwirq = irqd_to_hwirq(d); |
1621 | 1634 | ||
@@ -1641,24 +1654,33 @@ static int at91_gpio_of_irq_setup(struct platform_device *pdev, | |||
1641 | return ret; | 1654 | return ret; |
1642 | } | 1655 | } |
1643 | 1656 | ||
1644 | /* Setup chained handler */ | ||
1645 | if (at91_gpio->pioc_idx) | ||
1646 | prev = gpio_chips[at91_gpio->pioc_idx - 1]; | ||
1647 | |||
1648 | /* The top level handler handles one bank of GPIOs, except | 1657 | /* The top level handler handles one bank of GPIOs, except |
1649 | * on some SoC it can handle up to three... | 1658 | * on some SoC it can handle up to three... |
1650 | * We only set up the handler for the first of the list. | 1659 | * We only set up the handler for the first of the list. |
1651 | */ | 1660 | */ |
1652 | if (prev && prev->next == at91_gpio) | 1661 | gpiochip_prev = irq_get_handler_data(at91_gpio->pioc_virq); |
1662 | if (!gpiochip_prev) { | ||
1663 | /* Then register the chain on the parent IRQ */ | ||
1664 | gpiochip_set_chained_irqchip(&at91_gpio->chip, | ||
1665 | &gpio_irqchip, | ||
1666 | at91_gpio->pioc_virq, | ||
1667 | gpio_irq_handler); | ||
1653 | return 0; | 1668 | return 0; |
1669 | } | ||
1654 | 1670 | ||
1655 | /* Then register the chain on the parent IRQ */ | 1671 | prev = container_of(gpiochip_prev, struct at91_gpio_chip, chip); |
1656 | gpiochip_set_chained_irqchip(&at91_gpio->chip, | ||
1657 | &gpio_irqchip, | ||
1658 | at91_gpio->pioc_virq, | ||
1659 | gpio_irq_handler); | ||
1660 | 1672 | ||
1661 | return 0; | 1673 | /* we can only have 2 banks before */ |
1674 | for (i = 0; i < 2; i++) { | ||
1675 | if (prev->next) { | ||
1676 | prev = prev->next; | ||
1677 | } else { | ||
1678 | prev->next = at91_gpio; | ||
1679 | return 0; | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1683 | return -EINVAL; | ||
1662 | } | 1684 | } |
1663 | 1685 | ||
1664 | /* This structure is replicated for each GPIO block allocated at probe time */ | 1686 | /* This structure is replicated for each GPIO block allocated at probe time */ |
@@ -1675,24 +1697,6 @@ static struct gpio_chip at91_gpio_template = { | |||
1675 | .ngpio = MAX_NB_GPIO_PER_BANK, | 1697 | .ngpio = MAX_NB_GPIO_PER_BANK, |
1676 | }; | 1698 | }; |
1677 | 1699 | ||
1678 | static void at91_gpio_probe_fixup(void) | ||
1679 | { | ||
1680 | unsigned i; | ||
1681 | struct at91_gpio_chip *at91_gpio, *last = NULL; | ||
1682 | |||
1683 | for (i = 0; i < gpio_banks; i++) { | ||
1684 | at91_gpio = gpio_chips[i]; | ||
1685 | |||
1686 | /* | ||
1687 | * GPIO controller are grouped on some SoC: | ||
1688 | * PIOC, PIOD and PIOE can share the same IRQ line | ||
1689 | */ | ||
1690 | if (last && last->pioc_virq == at91_gpio->pioc_virq) | ||
1691 | last->next = at91_gpio; | ||
1692 | last = at91_gpio; | ||
1693 | } | ||
1694 | } | ||
1695 | |||
1696 | static struct of_device_id at91_gpio_of_match[] = { | 1700 | static struct of_device_id at91_gpio_of_match[] = { |
1697 | { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, | 1701 | { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, |
1698 | { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, | 1702 | { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, |
@@ -1805,8 +1809,6 @@ static int at91_gpio_probe(struct platform_device *pdev) | |||
1805 | gpio_chips[alias_idx] = at91_chip; | 1809 | gpio_chips[alias_idx] = at91_chip; |
1806 | gpio_banks = max(gpio_banks, alias_idx + 1); | 1810 | gpio_banks = max(gpio_banks, alias_idx + 1); |
1807 | 1811 | ||
1808 | at91_gpio_probe_fixup(); | ||
1809 | |||
1810 | ret = at91_gpio_of_irq_setup(pdev, at91_chip); | 1812 | ret = at91_gpio_of_irq_setup(pdev, at91_chip); |
1811 | if (ret) | 1813 | if (ret) |
1812 | goto irq_setup_err; | 1814 | goto irq_setup_err; |
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index ba74f0aa60c7..43eacc924b7e 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c | |||
@@ -89,6 +89,7 @@ struct rockchip_iomux { | |||
89 | * @reg_pull: optional separate register for additional pull settings | 89 | * @reg_pull: optional separate register for additional pull settings |
90 | * @clk: clock of the gpio bank | 90 | * @clk: clock of the gpio bank |
91 | * @irq: interrupt of the gpio bank | 91 | * @irq: interrupt of the gpio bank |
92 | * @saved_enables: Saved content of GPIO_INTEN at suspend time. | ||
92 | * @pin_base: first pin number | 93 | * @pin_base: first pin number |
93 | * @nr_pins: number of pins in this bank | 94 | * @nr_pins: number of pins in this bank |
94 | * @name: name of the bank | 95 | * @name: name of the bank |
@@ -107,6 +108,7 @@ struct rockchip_pin_bank { | |||
107 | struct regmap *regmap_pull; | 108 | struct regmap *regmap_pull; |
108 | struct clk *clk; | 109 | struct clk *clk; |
109 | int irq; | 110 | int irq; |
111 | u32 saved_enables; | ||
110 | u32 pin_base; | 112 | u32 pin_base; |
111 | u8 nr_pins; | 113 | u8 nr_pins; |
112 | char *name; | 114 | char *name; |
@@ -1396,10 +1398,7 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1396 | { | 1398 | { |
1397 | struct irq_chip *chip = irq_get_chip(irq); | 1399 | struct irq_chip *chip = irq_get_chip(irq); |
1398 | struct rockchip_pin_bank *bank = irq_get_handler_data(irq); | 1400 | struct rockchip_pin_bank *bank = irq_get_handler_data(irq); |
1399 | u32 polarity = 0, data = 0; | ||
1400 | u32 pend; | 1401 | u32 pend; |
1401 | bool edge_changed = false; | ||
1402 | unsigned long flags; | ||
1403 | 1402 | ||
1404 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); | 1403 | dev_dbg(bank->drvdata->dev, "got irq for bank %s\n", bank->name); |
1405 | 1404 | ||
@@ -1407,12 +1406,6 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1407 | 1406 | ||
1408 | pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); | 1407 | pend = readl_relaxed(bank->reg_base + GPIO_INT_STATUS); |
1409 | 1408 | ||
1410 | if (bank->toggle_edge_mode) { | ||
1411 | polarity = readl_relaxed(bank->reg_base + | ||
1412 | GPIO_INT_POLARITY); | ||
1413 | data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); | ||
1414 | } | ||
1415 | |||
1416 | while (pend) { | 1409 | while (pend) { |
1417 | unsigned int virq; | 1410 | unsigned int virq; |
1418 | 1411 | ||
@@ -1432,27 +1425,31 @@ static void rockchip_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
1432 | * needs manual intervention. | 1425 | * needs manual intervention. |
1433 | */ | 1426 | */ |
1434 | if (bank->toggle_edge_mode & BIT(irq)) { | 1427 | if (bank->toggle_edge_mode & BIT(irq)) { |
1435 | if (data & BIT(irq)) | 1428 | u32 data, data_old, polarity; |
1436 | polarity &= ~BIT(irq); | 1429 | unsigned long flags; |
1437 | else | ||
1438 | polarity |= BIT(irq); | ||
1439 | 1430 | ||
1440 | edge_changed = true; | 1431 | data = readl_relaxed(bank->reg_base + GPIO_EXT_PORT); |
1441 | } | 1432 | do { |
1433 | spin_lock_irqsave(&bank->slock, flags); | ||
1442 | 1434 | ||
1443 | generic_handle_irq(virq); | 1435 | polarity = readl_relaxed(bank->reg_base + |
1444 | } | 1436 | GPIO_INT_POLARITY); |
1437 | if (data & BIT(irq)) | ||
1438 | polarity &= ~BIT(irq); | ||
1439 | else | ||
1440 | polarity |= BIT(irq); | ||
1441 | writel(polarity, | ||
1442 | bank->reg_base + GPIO_INT_POLARITY); | ||
1445 | 1443 | ||
1446 | if (bank->toggle_edge_mode && edge_changed) { | 1444 | spin_unlock_irqrestore(&bank->slock, flags); |
1447 | /* Interrupt params should only be set with ints disabled */ | ||
1448 | spin_lock_irqsave(&bank->slock, flags); | ||
1449 | 1445 | ||
1450 | data = readl_relaxed(bank->reg_base + GPIO_INTEN); | 1446 | data_old = data; |
1451 | writel_relaxed(0, bank->reg_base + GPIO_INTEN); | 1447 | data = readl_relaxed(bank->reg_base + |
1452 | writel(polarity, bank->reg_base + GPIO_INT_POLARITY); | 1448 | GPIO_EXT_PORT); |
1453 | writel(data, bank->reg_base + GPIO_INTEN); | 1449 | } while ((data & BIT(irq)) != (data_old & BIT(irq))); |
1450 | } | ||
1454 | 1451 | ||
1455 | spin_unlock_irqrestore(&bank->slock, flags); | 1452 | generic_handle_irq(virq); |
1456 | } | 1453 | } |
1457 | 1454 | ||
1458 | chained_irq_exit(chip, desc); | 1455 | chained_irq_exit(chip, desc); |
@@ -1543,6 +1540,51 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) | |||
1543 | return 0; | 1540 | return 0; |
1544 | } | 1541 | } |
1545 | 1542 | ||
1543 | static void rockchip_irq_suspend(struct irq_data *d) | ||
1544 | { | ||
1545 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
1546 | struct rockchip_pin_bank *bank = gc->private; | ||
1547 | |||
1548 | bank->saved_enables = irq_reg_readl(gc, GPIO_INTEN); | ||
1549 | irq_reg_writel(gc, gc->wake_active, GPIO_INTEN); | ||
1550 | } | ||
1551 | |||
1552 | static void rockchip_irq_resume(struct irq_data *d) | ||
1553 | { | ||
1554 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
1555 | struct rockchip_pin_bank *bank = gc->private; | ||
1556 | |||
1557 | irq_reg_writel(gc, bank->saved_enables, GPIO_INTEN); | ||
1558 | } | ||
1559 | |||
1560 | static void rockchip_irq_disable(struct irq_data *d) | ||
1561 | { | ||
1562 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
1563 | u32 val; | ||
1564 | |||
1565 | irq_gc_lock(gc); | ||
1566 | |||
1567 | val = irq_reg_readl(gc, GPIO_INTEN); | ||
1568 | val &= ~d->mask; | ||
1569 | irq_reg_writel(gc, val, GPIO_INTEN); | ||
1570 | |||
1571 | irq_gc_unlock(gc); | ||
1572 | } | ||
1573 | |||
1574 | static void rockchip_irq_enable(struct irq_data *d) | ||
1575 | { | ||
1576 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
1577 | u32 val; | ||
1578 | |||
1579 | irq_gc_lock(gc); | ||
1580 | |||
1581 | val = irq_reg_readl(gc, GPIO_INTEN); | ||
1582 | val |= d->mask; | ||
1583 | irq_reg_writel(gc, val, GPIO_INTEN); | ||
1584 | |||
1585 | irq_gc_unlock(gc); | ||
1586 | } | ||
1587 | |||
1546 | static int rockchip_interrupts_register(struct platform_device *pdev, | 1588 | static int rockchip_interrupts_register(struct platform_device *pdev, |
1547 | struct rockchip_pinctrl *info) | 1589 | struct rockchip_pinctrl *info) |
1548 | { | 1590 | { |
@@ -1581,12 +1623,16 @@ static int rockchip_interrupts_register(struct platform_device *pdev, | |||
1581 | gc = irq_get_domain_generic_chip(bank->domain, 0); | 1623 | gc = irq_get_domain_generic_chip(bank->domain, 0); |
1582 | gc->reg_base = bank->reg_base; | 1624 | gc->reg_base = bank->reg_base; |
1583 | gc->private = bank; | 1625 | gc->private = bank; |
1584 | gc->chip_types[0].regs.mask = GPIO_INTEN; | 1626 | gc->chip_types[0].regs.mask = GPIO_INTMASK; |
1585 | gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; | 1627 | gc->chip_types[0].regs.ack = GPIO_PORTS_EOI; |
1586 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; | 1628 | gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit; |
1587 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit; | 1629 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; |
1588 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; | 1630 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; |
1631 | gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; | ||
1632 | gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; | ||
1589 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; | 1633 | gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; |
1634 | gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; | ||
1635 | gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; | ||
1590 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; | 1636 | gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; |
1591 | gc->wake_enabled = IRQ_MSK(bank->nr_pins); | 1637 | gc->wake_enabled = IRQ_MSK(bank->nr_pins); |
1592 | 1638 | ||
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index 7c9d51382248..9e5ec00084bb 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c | |||
@@ -1012,8 +1012,10 @@ static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, | |||
1012 | struct seq_file *s, unsigned pin_id) | 1012 | struct seq_file *s, unsigned pin_id) |
1013 | { | 1013 | { |
1014 | unsigned long config; | 1014 | unsigned long config; |
1015 | st_pinconf_get(pctldev, pin_id, &config); | ||
1016 | 1015 | ||
1016 | mutex_unlock(&pctldev->mutex); | ||
1017 | st_pinconf_get(pctldev, pin_id, &config); | ||
1018 | mutex_lock(&pctldev->mutex); | ||
1017 | seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" | 1019 | seq_printf(s, "[OE:%ld,PU:%ld,OD:%ld]\n" |
1018 | "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," | 1020 | "\t\t[retime:%ld,invclk:%ld,clknotdat:%ld," |
1019 | "de:%ld,rt-clk:%ld,rt-delay:%ld]", | 1021 | "de:%ld,rt-clk:%ld,rt-delay:%ld]", |
@@ -1443,6 +1445,7 @@ static struct gpio_chip st_gpio_template = { | |||
1443 | 1445 | ||
1444 | static struct irq_chip st_gpio_irqchip = { | 1446 | static struct irq_chip st_gpio_irqchip = { |
1445 | .name = "GPIO", | 1447 | .name = "GPIO", |
1448 | .irq_disable = st_gpio_irq_mask, | ||
1446 | .irq_mask = st_gpio_irq_mask, | 1449 | .irq_mask = st_gpio_irq_mask, |
1447 | .irq_unmask = st_gpio_irq_unmask, | 1450 | .irq_unmask = st_gpio_irq_unmask, |
1448 | .irq_set_type = st_gpio_irq_set_type, | 1451 | .irq_set_type = st_gpio_irq_set_type, |
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index c5cef59f5965..779950c62e53 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c | |||
@@ -798,10 +798,8 @@ static int pinmux_xway_probe(struct platform_device *pdev) | |||
798 | 798 | ||
799 | /* load the gpio chip */ | 799 | /* load the gpio chip */ |
800 | xway_chip.dev = &pdev->dev; | 800 | xway_chip.dev = &pdev->dev; |
801 | of_gpiochip_add(&xway_chip); | ||
802 | ret = gpiochip_add(&xway_chip); | 801 | ret = gpiochip_add(&xway_chip); |
803 | if (ret) { | 802 | if (ret) { |
804 | of_gpiochip_remove(&xway_chip); | ||
805 | dev_err(&pdev->dev, "Failed to register gpio chip\n"); | 803 | dev_err(&pdev->dev, "Failed to register gpio chip\n"); |
806 | return ret; | 804 | return ret; |
807 | } | 805 | } |
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index e730935fa457..ed7017df065d 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -865,10 +865,10 @@ static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, | |||
865 | 865 | ||
866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) | 866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) |
867 | { | 867 | { |
868 | int i = 0; | 868 | int i; |
869 | const struct msm_function *func = pctrl->soc->functions; | 869 | const struct msm_function *func = pctrl->soc->functions; |
870 | 870 | ||
871 | for (; i <= pctrl->soc->nfunctions; i++) | 871 | for (i = 0; i < pctrl->soc->nfunctions; i++) |
872 | if (!strcmp(func[i].name, "ps_hold")) { | 872 | if (!strcmp(func[i].name, "ps_hold")) { |
873 | pctrl->restart_nb.notifier_call = msm_ps_hold_restart; | 873 | pctrl->restart_nb.notifier_call = msm_ps_hold_restart; |
874 | pctrl->restart_nb.priority = 128; | 874 | pctrl->restart_nb.priority = 128; |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 9411eae39a4e..3d21efe11d7b 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -2,11 +2,9 @@ | |||
2 | * Driver for Dell laptop extras | 2 | * Driver for Dell laptop extras |
3 | * | 3 | * |
4 | * Copyright (c) Red Hat <mjg@redhat.com> | 4 | * Copyright (c) Red Hat <mjg@redhat.com> |
5 | * Copyright (c) 2014 Gabriele Mazzotta <gabriele.mzt@gmail.com> | ||
6 | * Copyright (c) 2014 Pali Rohár <pali.rohar@gmail.com> | ||
7 | * | 5 | * |
8 | * Based on documentation in the libsmbios package: | 6 | * Based on documentation in the libsmbios package, Copyright (C) 2005 Dell |
9 | * Copyright (C) 2005-2014 Dell Inc. | 7 | * Inc. |
10 | * | 8 | * |
11 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -34,13 +32,6 @@ | |||
34 | #include "../../firmware/dcdbas.h" | 32 | #include "../../firmware/dcdbas.h" |
35 | 33 | ||
36 | #define BRIGHTNESS_TOKEN 0x7d | 34 | #define BRIGHTNESS_TOKEN 0x7d |
37 | #define KBD_LED_OFF_TOKEN 0x01E1 | ||
38 | #define KBD_LED_ON_TOKEN 0x01E2 | ||
39 | #define KBD_LED_AUTO_TOKEN 0x01E3 | ||
40 | #define KBD_LED_AUTO_25_TOKEN 0x02EA | ||
41 | #define KBD_LED_AUTO_50_TOKEN 0x02EB | ||
42 | #define KBD_LED_AUTO_75_TOKEN 0x02EC | ||
43 | #define KBD_LED_AUTO_100_TOKEN 0x02F6 | ||
44 | 35 | ||
45 | /* This structure will be modified by the firmware when we enter | 36 | /* This structure will be modified by the firmware when we enter |
46 | * system management mode, hence the volatiles */ | 37 | * system management mode, hence the volatiles */ |
@@ -71,13 +62,6 @@ struct calling_interface_structure { | |||
71 | 62 | ||
72 | struct quirk_entry { | 63 | struct quirk_entry { |
73 | u8 touchpad_led; | 64 | u8 touchpad_led; |
74 | |||
75 | int needs_kbd_timeouts; | ||
76 | /* | ||
77 | * Ordered list of timeouts expressed in seconds. | ||
78 | * The list must end with -1 | ||
79 | */ | ||
80 | int kbd_timeouts[]; | ||
81 | }; | 65 | }; |
82 | 66 | ||
83 | static struct quirk_entry *quirks; | 67 | static struct quirk_entry *quirks; |
@@ -92,15 +76,6 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) | |||
92 | return 1; | 76 | return 1; |
93 | } | 77 | } |
94 | 78 | ||
95 | /* | ||
96 | * These values come from Windows utility provided by Dell. If any other value | ||
97 | * is used then BIOS silently set timeout to 0 without any error message. | ||
98 | */ | ||
99 | static struct quirk_entry quirk_dell_xps13_9333 = { | ||
100 | .needs_kbd_timeouts = 1, | ||
101 | .kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 }, | ||
102 | }; | ||
103 | |||
104 | static int da_command_address; | 79 | static int da_command_address; |
105 | static int da_command_code; | 80 | static int da_command_code; |
106 | static int da_num_tokens; | 81 | static int da_num_tokens; |
@@ -292,15 +267,6 @@ static const struct dmi_system_id dell_quirks[] __initconst = { | |||
292 | }, | 267 | }, |
293 | .driver_data = &quirk_dell_vostro_v130, | 268 | .driver_data = &quirk_dell_vostro_v130, |
294 | }, | 269 | }, |
295 | { | ||
296 | .callback = dmi_matched, | ||
297 | .ident = "Dell XPS13 9333", | ||
298 | .matches = { | ||
299 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
300 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS13 9333"), | ||
301 | }, | ||
302 | .driver_data = &quirk_dell_xps13_9333, | ||
303 | }, | ||
304 | { } | 270 | { } |
305 | }; | 271 | }; |
306 | 272 | ||
@@ -365,29 +331,17 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) | |||
365 | } | 331 | } |
366 | } | 332 | } |
367 | 333 | ||
368 | static int find_token_id(int tokenid) | 334 | static int find_token_location(int tokenid) |
369 | { | 335 | { |
370 | int i; | 336 | int i; |
371 | |||
372 | for (i = 0; i < da_num_tokens; i++) { | 337 | for (i = 0; i < da_num_tokens; i++) { |
373 | if (da_tokens[i].tokenID == tokenid) | 338 | if (da_tokens[i].tokenID == tokenid) |
374 | return i; | 339 | return da_tokens[i].location; |
375 | } | 340 | } |
376 | 341 | ||
377 | return -1; | 342 | return -1; |
378 | } | 343 | } |
379 | 344 | ||
380 | static int find_token_location(int tokenid) | ||
381 | { | ||
382 | int id; | ||
383 | |||
384 | id = find_token_id(tokenid); | ||
385 | if (id == -1) | ||
386 | return -1; | ||
387 | |||
388 | return da_tokens[id].location; | ||
389 | } | ||
390 | |||
391 | static struct calling_interface_buffer * | 345 | static struct calling_interface_buffer * |
392 | dell_send_request(struct calling_interface_buffer *buffer, int class, | 346 | dell_send_request(struct calling_interface_buffer *buffer, int class, |
393 | int select) | 347 | int select) |
@@ -408,20 +362,6 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
408 | return buffer; | 362 | return buffer; |
409 | } | 363 | } |
410 | 364 | ||
411 | static inline int dell_smi_error(int value) | ||
412 | { | ||
413 | switch (value) { | ||
414 | case 0: /* Completed successfully */ | ||
415 | return 0; | ||
416 | case -1: /* Completed with error */ | ||
417 | return -EIO; | ||
418 | case -2: /* Function not supported */ | ||
419 | return -ENXIO; | ||
420 | default: /* Unknown error */ | ||
421 | return -EINVAL; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /* Derived from information in DellWirelessCtl.cpp: | 365 | /* Derived from information in DellWirelessCtl.cpp: |
426 | Class 17, select 11 is radio control. It returns an array of 32-bit values. | 366 | Class 17, select 11 is radio control. It returns an array of 32-bit values. |
427 | 367 | ||
@@ -776,7 +716,7 @@ static int dell_send_intensity(struct backlight_device *bd) | |||
776 | else | 716 | else |
777 | dell_send_request(buffer, 1, 1); | 717 | dell_send_request(buffer, 1, 1); |
778 | 718 | ||
779 | out: | 719 | out: |
780 | release_buffer(); | 720 | release_buffer(); |
781 | return ret; | 721 | return ret; |
782 | } | 722 | } |
@@ -800,7 +740,7 @@ static int dell_get_intensity(struct backlight_device *bd) | |||
800 | 740 | ||
801 | ret = buffer->output[1]; | 741 | ret = buffer->output[1]; |
802 | 742 | ||
803 | out: | 743 | out: |
804 | release_buffer(); | 744 | release_buffer(); |
805 | return ret; | 745 | return ret; |
806 | } | 746 | } |
@@ -849,984 +789,6 @@ static void touchpad_led_exit(void) | |||
849 | led_classdev_unregister(&touchpad_led); | 789 | led_classdev_unregister(&touchpad_led); |
850 | } | 790 | } |
851 | 791 | ||
852 | /* | ||
853 | * Derived from information in smbios-keyboard-ctl: | ||
854 | * | ||
855 | * cbClass 4 | ||
856 | * cbSelect 11 | ||
857 | * Keyboard illumination | ||
858 | * cbArg1 determines the function to be performed | ||
859 | * | ||
860 | * cbArg1 0x0 = Get Feature Information | ||
861 | * cbRES1 Standard return codes (0, -1, -2) | ||
862 | * cbRES2, word0 Bitmap of user-selectable modes | ||
863 | * bit 0 Always off (All systems) | ||
864 | * bit 1 Always on (Travis ATG, Siberia) | ||
865 | * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) | ||
866 | * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off | ||
867 | * bit 4 Auto: Input-activity-based On; input-activity based Off | ||
868 | * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off | ||
869 | * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off | ||
870 | * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off | ||
871 | * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off | ||
872 | * bits 9-15 Reserved for future use | ||
873 | * cbRES2, byte2 Reserved for future use | ||
874 | * cbRES2, byte3 Keyboard illumination type | ||
875 | * 0 Reserved | ||
876 | * 1 Tasklight | ||
877 | * 2 Backlight | ||
878 | * 3-255 Reserved for future use | ||
879 | * cbRES3, byte0 Supported auto keyboard illumination trigger bitmap. | ||
880 | * bit 0 Any keystroke | ||
881 | * bit 1 Touchpad activity | ||
882 | * bit 2 Pointing stick | ||
883 | * bit 3 Any mouse | ||
884 | * bits 4-7 Reserved for future use | ||
885 | * cbRES3, byte1 Supported timeout unit bitmap | ||
886 | * bit 0 Seconds | ||
887 | * bit 1 Minutes | ||
888 | * bit 2 Hours | ||
889 | * bit 3 Days | ||
890 | * bits 4-7 Reserved for future use | ||
891 | * cbRES3, byte2 Number of keyboard light brightness levels | ||
892 | * cbRES4, byte0 Maximum acceptable seconds value (0 if seconds not supported). | ||
893 | * cbRES4, byte1 Maximum acceptable minutes value (0 if minutes not supported). | ||
894 | * cbRES4, byte2 Maximum acceptable hours value (0 if hours not supported). | ||
895 | * cbRES4, byte3 Maximum acceptable days value (0 if days not supported) | ||
896 | * | ||
897 | * cbArg1 0x1 = Get Current State | ||
898 | * cbRES1 Standard return codes (0, -1, -2) | ||
899 | * cbRES2, word0 Bitmap of current mode state | ||
900 | * bit 0 Always off (All systems) | ||
901 | * bit 1 Always on (Travis ATG, Siberia) | ||
902 | * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) | ||
903 | * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off | ||
904 | * bit 4 Auto: Input-activity-based On; input-activity based Off | ||
905 | * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off | ||
906 | * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off | ||
907 | * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off | ||
908 | * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off | ||
909 | * bits 9-15 Reserved for future use | ||
910 | * Note: Only One bit can be set | ||
911 | * cbRES2, byte2 Currently active auto keyboard illumination triggers. | ||
912 | * bit 0 Any keystroke | ||
913 | * bit 1 Touchpad activity | ||
914 | * bit 2 Pointing stick | ||
915 | * bit 3 Any mouse | ||
916 | * bits 4-7 Reserved for future use | ||
917 | * cbRES2, byte3 Current Timeout | ||
918 | * bits 7:6 Timeout units indicator: | ||
919 | * 00b Seconds | ||
920 | * 01b Minutes | ||
921 | * 10b Hours | ||
922 | * 11b Days | ||
923 | * bits 5:0 Timeout value (0-63) in sec/min/hr/day | ||
924 | * NOTE: A value of 0 means always on (no timeout) if any bits of RES3 byte | ||
925 | * are set upon return from the [Get feature information] call. | ||
926 | * cbRES3, byte0 Current setting of ALS value that turns the light on or off. | ||
927 | * cbRES3, byte1 Current ALS reading | ||
928 | * cbRES3, byte2 Current keyboard light level. | ||
929 | * | ||
930 | * cbArg1 0x2 = Set New State | ||
931 | * cbRES1 Standard return codes (0, -1, -2) | ||
932 | * cbArg2, word0 Bitmap of current mode state | ||
933 | * bit 0 Always off (All systems) | ||
934 | * bit 1 Always on (Travis ATG, Siberia) | ||
935 | * bit 2 Auto: ALS-based On; ALS-based Off (Travis ATG) | ||
936 | * bit 3 Auto: ALS- and input-activity-based On; input-activity based Off | ||
937 | * bit 4 Auto: Input-activity-based On; input-activity based Off | ||
938 | * bit 5 Auto: Input-activity-based On (illumination level 25%); input-activity based Off | ||
939 | * bit 6 Auto: Input-activity-based On (illumination level 50%); input-activity based Off | ||
940 | * bit 7 Auto: Input-activity-based On (illumination level 75%); input-activity based Off | ||
941 | * bit 8 Auto: Input-activity-based On (illumination level 100%); input-activity based Off | ||
942 | * bits 9-15 Reserved for future use | ||
943 | * Note: Only One bit can be set | ||
944 | * cbArg2, byte2 Desired auto keyboard illumination triggers. Must remain inactive to allow | ||
945 | * keyboard to turn off automatically. | ||
946 | * bit 0 Any keystroke | ||
947 | * bit 1 Touchpad activity | ||
948 | * bit 2 Pointing stick | ||
949 | * bit 3 Any mouse | ||
950 | * bits 4-7 Reserved for future use | ||
951 | * cbArg2, byte3 Desired Timeout | ||
952 | * bits 7:6 Timeout units indicator: | ||
953 | * 00b Seconds | ||
954 | * 01b Minutes | ||
955 | * 10b Hours | ||
956 | * 11b Days | ||
957 | * bits 5:0 Timeout value (0-63) in sec/min/hr/day | ||
958 | * cbArg3, byte0 Desired setting of ALS value that turns the light on or off. | ||
959 | * cbArg3, byte2 Desired keyboard light level. | ||
960 | */ | ||
961 | |||
962 | |||
963 | enum kbd_timeout_unit { | ||
964 | KBD_TIMEOUT_SECONDS = 0, | ||
965 | KBD_TIMEOUT_MINUTES, | ||
966 | KBD_TIMEOUT_HOURS, | ||
967 | KBD_TIMEOUT_DAYS, | ||
968 | }; | ||
969 | |||
970 | enum kbd_mode_bit { | ||
971 | KBD_MODE_BIT_OFF = 0, | ||
972 | KBD_MODE_BIT_ON, | ||
973 | KBD_MODE_BIT_ALS, | ||
974 | KBD_MODE_BIT_TRIGGER_ALS, | ||
975 | KBD_MODE_BIT_TRIGGER, | ||
976 | KBD_MODE_BIT_TRIGGER_25, | ||
977 | KBD_MODE_BIT_TRIGGER_50, | ||
978 | KBD_MODE_BIT_TRIGGER_75, | ||
979 | KBD_MODE_BIT_TRIGGER_100, | ||
980 | }; | ||
981 | |||
982 | #define kbd_is_als_mode_bit(bit) \ | ||
983 | ((bit) == KBD_MODE_BIT_ALS || (bit) == KBD_MODE_BIT_TRIGGER_ALS) | ||
984 | #define kbd_is_trigger_mode_bit(bit) \ | ||
985 | ((bit) >= KBD_MODE_BIT_TRIGGER_ALS && (bit) <= KBD_MODE_BIT_TRIGGER_100) | ||
986 | #define kbd_is_level_mode_bit(bit) \ | ||
987 | ((bit) >= KBD_MODE_BIT_TRIGGER_25 && (bit) <= KBD_MODE_BIT_TRIGGER_100) | ||
988 | |||
989 | struct kbd_info { | ||
990 | u16 modes; | ||
991 | u8 type; | ||
992 | u8 triggers; | ||
993 | u8 levels; | ||
994 | u8 seconds; | ||
995 | u8 minutes; | ||
996 | u8 hours; | ||
997 | u8 days; | ||
998 | }; | ||
999 | |||
1000 | struct kbd_state { | ||
1001 | u8 mode_bit; | ||
1002 | u8 triggers; | ||
1003 | u8 timeout_value; | ||
1004 | u8 timeout_unit; | ||
1005 | u8 als_setting; | ||
1006 | u8 als_value; | ||
1007 | u8 level; | ||
1008 | }; | ||
1009 | |||
1010 | static const int kbd_tokens[] = { | ||
1011 | KBD_LED_OFF_TOKEN, | ||
1012 | KBD_LED_AUTO_25_TOKEN, | ||
1013 | KBD_LED_AUTO_50_TOKEN, | ||
1014 | KBD_LED_AUTO_75_TOKEN, | ||
1015 | KBD_LED_AUTO_100_TOKEN, | ||
1016 | KBD_LED_ON_TOKEN, | ||
1017 | }; | ||
1018 | |||
1019 | static u16 kbd_token_bits; | ||
1020 | |||
1021 | static struct kbd_info kbd_info; | ||
1022 | static bool kbd_als_supported; | ||
1023 | static bool kbd_triggers_supported; | ||
1024 | |||
1025 | static u8 kbd_mode_levels[16]; | ||
1026 | static int kbd_mode_levels_count; | ||
1027 | |||
1028 | static u8 kbd_previous_level; | ||
1029 | static u8 kbd_previous_mode_bit; | ||
1030 | |||
1031 | static bool kbd_led_present; | ||
1032 | |||
1033 | /* | ||
1034 | * NOTE: there are three ways to set the keyboard backlight level. | ||
1035 | * First, via kbd_state.mode_bit (assigning KBD_MODE_BIT_TRIGGER_* value). | ||
1036 | * Second, via kbd_state.level (assigning numerical value <= kbd_info.levels). | ||
1037 | * Third, via SMBIOS tokens (KBD_LED_* in kbd_tokens) | ||
1038 | * | ||
1039 | * There are laptops which support only one of these methods. If we want to | ||
1040 | * support as many machines as possible we need to implement all three methods. | ||
1041 | * The first two methods use the kbd_state structure. The third uses SMBIOS | ||
1042 | * tokens. If kbd_info.levels == 0, the machine does not support setting the | ||
1043 | * keyboard backlight level via kbd_state.level. | ||
1044 | */ | ||
1045 | |||
1046 | static int kbd_get_info(struct kbd_info *info) | ||
1047 | { | ||
1048 | u8 units; | ||
1049 | int ret; | ||
1050 | |||
1051 | get_buffer(); | ||
1052 | |||
1053 | buffer->input[0] = 0x0; | ||
1054 | dell_send_request(buffer, 4, 11); | ||
1055 | ret = buffer->output[0]; | ||
1056 | |||
1057 | if (ret) { | ||
1058 | ret = dell_smi_error(ret); | ||
1059 | goto out; | ||
1060 | } | ||
1061 | |||
1062 | info->modes = buffer->output[1] & 0xFFFF; | ||
1063 | info->type = (buffer->output[1] >> 24) & 0xFF; | ||
1064 | info->triggers = buffer->output[2] & 0xFF; | ||
1065 | units = (buffer->output[2] >> 8) & 0xFF; | ||
1066 | info->levels = (buffer->output[2] >> 16) & 0xFF; | ||
1067 | |||
1068 | if (units & BIT(0)) | ||
1069 | info->seconds = (buffer->output[3] >> 0) & 0xFF; | ||
1070 | if (units & BIT(1)) | ||
1071 | info->minutes = (buffer->output[3] >> 8) & 0xFF; | ||
1072 | if (units & BIT(2)) | ||
1073 | info->hours = (buffer->output[3] >> 16) & 0xFF; | ||
1074 | if (units & BIT(3)) | ||
1075 | info->days = (buffer->output[3] >> 24) & 0xFF; | ||
1076 | |||
1077 | out: | ||
1078 | release_buffer(); | ||
1079 | return ret; | ||
1080 | } | ||
1081 | |||
1082 | static unsigned int kbd_get_max_level(void) | ||
1083 | { | ||
1084 | if (kbd_info.levels != 0) | ||
1085 | return kbd_info.levels; | ||
1086 | if (kbd_mode_levels_count > 0) | ||
1087 | return kbd_mode_levels_count - 1; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | static int kbd_get_level(struct kbd_state *state) | ||
1092 | { | ||
1093 | int i; | ||
1094 | |||
1095 | if (kbd_info.levels != 0) | ||
1096 | return state->level; | ||
1097 | |||
1098 | if (kbd_mode_levels_count > 0) { | ||
1099 | for (i = 0; i < kbd_mode_levels_count; ++i) | ||
1100 | if (kbd_mode_levels[i] == state->mode_bit) | ||
1101 | return i; | ||
1102 | return 0; | ||
1103 | } | ||
1104 | |||
1105 | return -EINVAL; | ||
1106 | } | ||
1107 | |||
1108 | static int kbd_set_level(struct kbd_state *state, u8 level) | ||
1109 | { | ||
1110 | if (kbd_info.levels != 0) { | ||
1111 | if (level != 0) | ||
1112 | kbd_previous_level = level; | ||
1113 | if (state->level == level) | ||
1114 | return 0; | ||
1115 | state->level = level; | ||
1116 | if (level != 0 && state->mode_bit == KBD_MODE_BIT_OFF) | ||
1117 | state->mode_bit = kbd_previous_mode_bit; | ||
1118 | else if (level == 0 && state->mode_bit != KBD_MODE_BIT_OFF) { | ||
1119 | kbd_previous_mode_bit = state->mode_bit; | ||
1120 | state->mode_bit = KBD_MODE_BIT_OFF; | ||
1121 | } | ||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1125 | if (kbd_mode_levels_count > 0 && level < kbd_mode_levels_count) { | ||
1126 | if (level != 0) | ||
1127 | kbd_previous_level = level; | ||
1128 | state->mode_bit = kbd_mode_levels[level]; | ||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | return -EINVAL; | ||
1133 | } | ||
1134 | |||
1135 | static int kbd_get_state(struct kbd_state *state) | ||
1136 | { | ||
1137 | int ret; | ||
1138 | |||
1139 | get_buffer(); | ||
1140 | |||
1141 | buffer->input[0] = 0x1; | ||
1142 | dell_send_request(buffer, 4, 11); | ||
1143 | ret = buffer->output[0]; | ||
1144 | |||
1145 | if (ret) { | ||
1146 | ret = dell_smi_error(ret); | ||
1147 | goto out; | ||
1148 | } | ||
1149 | |||
1150 | state->mode_bit = ffs(buffer->output[1] & 0xFFFF); | ||
1151 | if (state->mode_bit != 0) | ||
1152 | state->mode_bit--; | ||
1153 | |||
1154 | state->triggers = (buffer->output[1] >> 16) & 0xFF; | ||
1155 | state->timeout_value = (buffer->output[1] >> 24) & 0x3F; | ||
1156 | state->timeout_unit = (buffer->output[1] >> 30) & 0x3; | ||
1157 | state->als_setting = buffer->output[2] & 0xFF; | ||
1158 | state->als_value = (buffer->output[2] >> 8) & 0xFF; | ||
1159 | state->level = (buffer->output[2] >> 16) & 0xFF; | ||
1160 | |||
1161 | out: | ||
1162 | release_buffer(); | ||
1163 | return ret; | ||
1164 | } | ||
1165 | |||
1166 | static int kbd_set_state(struct kbd_state *state) | ||
1167 | { | ||
1168 | int ret; | ||
1169 | |||
1170 | get_buffer(); | ||
1171 | buffer->input[0] = 0x2; | ||
1172 | buffer->input[1] = BIT(state->mode_bit) & 0xFFFF; | ||
1173 | buffer->input[1] |= (state->triggers & 0xFF) << 16; | ||
1174 | buffer->input[1] |= (state->timeout_value & 0x3F) << 24; | ||
1175 | buffer->input[1] |= (state->timeout_unit & 0x3) << 30; | ||
1176 | buffer->input[2] = state->als_setting & 0xFF; | ||
1177 | buffer->input[2] |= (state->level & 0xFF) << 16; | ||
1178 | dell_send_request(buffer, 4, 11); | ||
1179 | ret = buffer->output[0]; | ||
1180 | release_buffer(); | ||
1181 | |||
1182 | return dell_smi_error(ret); | ||
1183 | } | ||
1184 | |||
1185 | static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old) | ||
1186 | { | ||
1187 | int ret; | ||
1188 | |||
1189 | ret = kbd_set_state(state); | ||
1190 | if (ret == 0) | ||
1191 | return 0; | ||
1192 | |||
1193 | /* | ||
1194 | * When setting the new state fails,try to restore the previous one. | ||
1195 | * This is needed on some machines where BIOS sets a default state when | ||
1196 | * setting a new state fails. This default state could be all off. | ||
1197 | */ | ||
1198 | |||
1199 | if (kbd_set_state(old)) | ||
1200 | pr_err("Setting old previous keyboard state failed\n"); | ||
1201 | |||
1202 | return ret; | ||
1203 | } | ||
1204 | |||
1205 | static int kbd_set_token_bit(u8 bit) | ||
1206 | { | ||
1207 | int id; | ||
1208 | int ret; | ||
1209 | |||
1210 | if (bit >= ARRAY_SIZE(kbd_tokens)) | ||
1211 | return -EINVAL; | ||
1212 | |||
1213 | id = find_token_id(kbd_tokens[bit]); | ||
1214 | if (id == -1) | ||
1215 | return -EINVAL; | ||
1216 | |||
1217 | get_buffer(); | ||
1218 | buffer->input[0] = da_tokens[id].location; | ||
1219 | buffer->input[1] = da_tokens[id].value; | ||
1220 | dell_send_request(buffer, 1, 0); | ||
1221 | ret = buffer->output[0]; | ||
1222 | release_buffer(); | ||
1223 | |||
1224 | return dell_smi_error(ret); | ||
1225 | } | ||
1226 | |||
1227 | static int kbd_get_token_bit(u8 bit) | ||
1228 | { | ||
1229 | int id; | ||
1230 | int ret; | ||
1231 | int val; | ||
1232 | |||
1233 | if (bit >= ARRAY_SIZE(kbd_tokens)) | ||
1234 | return -EINVAL; | ||
1235 | |||
1236 | id = find_token_id(kbd_tokens[bit]); | ||
1237 | if (id == -1) | ||
1238 | return -EINVAL; | ||
1239 | |||
1240 | get_buffer(); | ||
1241 | buffer->input[0] = da_tokens[id].location; | ||
1242 | dell_send_request(buffer, 0, 0); | ||
1243 | ret = buffer->output[0]; | ||
1244 | val = buffer->output[1]; | ||
1245 | release_buffer(); | ||
1246 | |||
1247 | if (ret) | ||
1248 | return dell_smi_error(ret); | ||
1249 | |||
1250 | return (val == da_tokens[id].value); | ||
1251 | } | ||
1252 | |||
1253 | static int kbd_get_first_active_token_bit(void) | ||
1254 | { | ||
1255 | int i; | ||
1256 | int ret; | ||
1257 | |||
1258 | for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) { | ||
1259 | ret = kbd_get_token_bit(i); | ||
1260 | if (ret == 1) | ||
1261 | return i; | ||
1262 | } | ||
1263 | |||
1264 | return ret; | ||
1265 | } | ||
1266 | |||
1267 | static int kbd_get_valid_token_counts(void) | ||
1268 | { | ||
1269 | return hweight16(kbd_token_bits); | ||
1270 | } | ||
1271 | |||
1272 | static inline int kbd_init_info(void) | ||
1273 | { | ||
1274 | struct kbd_state state; | ||
1275 | int ret; | ||
1276 | int i; | ||
1277 | |||
1278 | ret = kbd_get_info(&kbd_info); | ||
1279 | if (ret) | ||
1280 | return ret; | ||
1281 | |||
1282 | kbd_get_state(&state); | ||
1283 | |||
1284 | /* NOTE: timeout value is stored in 6 bits so max value is 63 */ | ||
1285 | if (kbd_info.seconds > 63) | ||
1286 | kbd_info.seconds = 63; | ||
1287 | if (kbd_info.minutes > 63) | ||
1288 | kbd_info.minutes = 63; | ||
1289 | if (kbd_info.hours > 63) | ||
1290 | kbd_info.hours = 63; | ||
1291 | if (kbd_info.days > 63) | ||
1292 | kbd_info.days = 63; | ||
1293 | |||
1294 | /* NOTE: On tested machines ON mode did not work and caused | ||
1295 | * problems (turned backlight off) so do not use it | ||
1296 | */ | ||
1297 | kbd_info.modes &= ~BIT(KBD_MODE_BIT_ON); | ||
1298 | |||
1299 | kbd_previous_level = kbd_get_level(&state); | ||
1300 | kbd_previous_mode_bit = state.mode_bit; | ||
1301 | |||
1302 | if (kbd_previous_level == 0 && kbd_get_max_level() != 0) | ||
1303 | kbd_previous_level = 1; | ||
1304 | |||
1305 | if (kbd_previous_mode_bit == KBD_MODE_BIT_OFF) { | ||
1306 | kbd_previous_mode_bit = | ||
1307 | ffs(kbd_info.modes & ~BIT(KBD_MODE_BIT_OFF)); | ||
1308 | if (kbd_previous_mode_bit != 0) | ||
1309 | kbd_previous_mode_bit--; | ||
1310 | } | ||
1311 | |||
1312 | if (kbd_info.modes & (BIT(KBD_MODE_BIT_ALS) | | ||
1313 | BIT(KBD_MODE_BIT_TRIGGER_ALS))) | ||
1314 | kbd_als_supported = true; | ||
1315 | |||
1316 | if (kbd_info.modes & ( | ||
1317 | BIT(KBD_MODE_BIT_TRIGGER_ALS) | BIT(KBD_MODE_BIT_TRIGGER) | | ||
1318 | BIT(KBD_MODE_BIT_TRIGGER_25) | BIT(KBD_MODE_BIT_TRIGGER_50) | | ||
1319 | BIT(KBD_MODE_BIT_TRIGGER_75) | BIT(KBD_MODE_BIT_TRIGGER_100) | ||
1320 | )) | ||
1321 | kbd_triggers_supported = true; | ||
1322 | |||
1323 | /* kbd_mode_levels[0] is reserved, see below */ | ||
1324 | for (i = 0; i < 16; ++i) | ||
1325 | if (kbd_is_level_mode_bit(i) && (BIT(i) & kbd_info.modes)) | ||
1326 | kbd_mode_levels[1 + kbd_mode_levels_count++] = i; | ||
1327 | |||
1328 | /* | ||
1329 | * Find the first supported mode and assign to kbd_mode_levels[0]. | ||
1330 | * This should be 0 (off), but we cannot depend on the BIOS to | ||
1331 | * support 0. | ||
1332 | */ | ||
1333 | if (kbd_mode_levels_count > 0) { | ||
1334 | for (i = 0; i < 16; ++i) { | ||
1335 | if (BIT(i) & kbd_info.modes) { | ||
1336 | kbd_mode_levels[0] = i; | ||
1337 | break; | ||
1338 | } | ||
1339 | } | ||
1340 | kbd_mode_levels_count++; | ||
1341 | } | ||
1342 | |||
1343 | return 0; | ||
1344 | |||
1345 | } | ||
1346 | |||
1347 | static inline void kbd_init_tokens(void) | ||
1348 | { | ||
1349 | int i; | ||
1350 | |||
1351 | for (i = 0; i < ARRAY_SIZE(kbd_tokens); ++i) | ||
1352 | if (find_token_id(kbd_tokens[i]) != -1) | ||
1353 | kbd_token_bits |= BIT(i); | ||
1354 | } | ||
1355 | |||
1356 | static void kbd_init(void) | ||
1357 | { | ||
1358 | int ret; | ||
1359 | |||
1360 | ret = kbd_init_info(); | ||
1361 | kbd_init_tokens(); | ||
1362 | |||
1363 | if (kbd_token_bits != 0 || ret == 0) | ||
1364 | kbd_led_present = true; | ||
1365 | } | ||
1366 | |||
1367 | static ssize_t kbd_led_timeout_store(struct device *dev, | ||
1368 | struct device_attribute *attr, | ||
1369 | const char *buf, size_t count) | ||
1370 | { | ||
1371 | struct kbd_state new_state; | ||
1372 | struct kbd_state state; | ||
1373 | bool convert; | ||
1374 | int value; | ||
1375 | int ret; | ||
1376 | char ch; | ||
1377 | u8 unit; | ||
1378 | int i; | ||
1379 | |||
1380 | ret = sscanf(buf, "%d %c", &value, &ch); | ||
1381 | if (ret < 1) | ||
1382 | return -EINVAL; | ||
1383 | else if (ret == 1) | ||
1384 | ch = 's'; | ||
1385 | |||
1386 | if (value < 0) | ||
1387 | return -EINVAL; | ||
1388 | |||
1389 | convert = false; | ||
1390 | |||
1391 | switch (ch) { | ||
1392 | case 's': | ||
1393 | if (value > kbd_info.seconds) | ||
1394 | convert = true; | ||
1395 | unit = KBD_TIMEOUT_SECONDS; | ||
1396 | break; | ||
1397 | case 'm': | ||
1398 | if (value > kbd_info.minutes) | ||
1399 | convert = true; | ||
1400 | unit = KBD_TIMEOUT_MINUTES; | ||
1401 | break; | ||
1402 | case 'h': | ||
1403 | if (value > kbd_info.hours) | ||
1404 | convert = true; | ||
1405 | unit = KBD_TIMEOUT_HOURS; | ||
1406 | break; | ||
1407 | case 'd': | ||
1408 | if (value > kbd_info.days) | ||
1409 | convert = true; | ||
1410 | unit = KBD_TIMEOUT_DAYS; | ||
1411 | break; | ||
1412 | default: | ||
1413 | return -EINVAL; | ||
1414 | } | ||
1415 | |||
1416 | if (quirks && quirks->needs_kbd_timeouts) | ||
1417 | convert = true; | ||
1418 | |||
1419 | if (convert) { | ||
1420 | /* Convert value from current units to seconds */ | ||
1421 | switch (unit) { | ||
1422 | case KBD_TIMEOUT_DAYS: | ||
1423 | value *= 24; | ||
1424 | case KBD_TIMEOUT_HOURS: | ||
1425 | value *= 60; | ||
1426 | case KBD_TIMEOUT_MINUTES: | ||
1427 | value *= 60; | ||
1428 | unit = KBD_TIMEOUT_SECONDS; | ||
1429 | } | ||
1430 | |||
1431 | if (quirks && quirks->needs_kbd_timeouts) { | ||
1432 | for (i = 0; quirks->kbd_timeouts[i] != -1; i++) { | ||
1433 | if (value <= quirks->kbd_timeouts[i]) { | ||
1434 | value = quirks->kbd_timeouts[i]; | ||
1435 | break; | ||
1436 | } | ||
1437 | } | ||
1438 | } | ||
1439 | |||
1440 | if (value <= kbd_info.seconds && kbd_info.seconds) { | ||
1441 | unit = KBD_TIMEOUT_SECONDS; | ||
1442 | } else if (value / 60 <= kbd_info.minutes && kbd_info.minutes) { | ||
1443 | value /= 60; | ||
1444 | unit = KBD_TIMEOUT_MINUTES; | ||
1445 | } else if (value / (60 * 60) <= kbd_info.hours && kbd_info.hours) { | ||
1446 | value /= (60 * 60); | ||
1447 | unit = KBD_TIMEOUT_HOURS; | ||
1448 | } else if (value / (60 * 60 * 24) <= kbd_info.days && kbd_info.days) { | ||
1449 | value /= (60 * 60 * 24); | ||
1450 | unit = KBD_TIMEOUT_DAYS; | ||
1451 | } else { | ||
1452 | return -EINVAL; | ||
1453 | } | ||
1454 | } | ||
1455 | |||
1456 | ret = kbd_get_state(&state); | ||
1457 | if (ret) | ||
1458 | return ret; | ||
1459 | |||
1460 | new_state = state; | ||
1461 | new_state.timeout_value = value; | ||
1462 | new_state.timeout_unit = unit; | ||
1463 | |||
1464 | ret = kbd_set_state_safe(&new_state, &state); | ||
1465 | if (ret) | ||
1466 | return ret; | ||
1467 | |||
1468 | return count; | ||
1469 | } | ||
1470 | |||
1471 | static ssize_t kbd_led_timeout_show(struct device *dev, | ||
1472 | struct device_attribute *attr, char *buf) | ||
1473 | { | ||
1474 | struct kbd_state state; | ||
1475 | int ret; | ||
1476 | int len; | ||
1477 | |||
1478 | ret = kbd_get_state(&state); | ||
1479 | if (ret) | ||
1480 | return ret; | ||
1481 | |||
1482 | len = sprintf(buf, "%d", state.timeout_value); | ||
1483 | |||
1484 | switch (state.timeout_unit) { | ||
1485 | case KBD_TIMEOUT_SECONDS: | ||
1486 | return len + sprintf(buf+len, "s\n"); | ||
1487 | case KBD_TIMEOUT_MINUTES: | ||
1488 | return len + sprintf(buf+len, "m\n"); | ||
1489 | case KBD_TIMEOUT_HOURS: | ||
1490 | return len + sprintf(buf+len, "h\n"); | ||
1491 | case KBD_TIMEOUT_DAYS: | ||
1492 | return len + sprintf(buf+len, "d\n"); | ||
1493 | default: | ||
1494 | return -EINVAL; | ||
1495 | } | ||
1496 | |||
1497 | return len; | ||
1498 | } | ||
1499 | |||
1500 | static DEVICE_ATTR(stop_timeout, S_IRUGO | S_IWUSR, | ||
1501 | kbd_led_timeout_show, kbd_led_timeout_store); | ||
1502 | |||
1503 | static const char * const kbd_led_triggers[] = { | ||
1504 | "keyboard", | ||
1505 | "touchpad", | ||
1506 | /*"trackstick"*/ NULL, /* NOTE: trackstick is just alias for touchpad */ | ||
1507 | "mouse", | ||
1508 | }; | ||
1509 | |||
1510 | static ssize_t kbd_led_triggers_store(struct device *dev, | ||
1511 | struct device_attribute *attr, | ||
1512 | const char *buf, size_t count) | ||
1513 | { | ||
1514 | struct kbd_state new_state; | ||
1515 | struct kbd_state state; | ||
1516 | bool triggers_enabled = false; | ||
1517 | bool als_enabled = false; | ||
1518 | bool disable_als = false; | ||
1519 | bool enable_als = false; | ||
1520 | int trigger_bit = -1; | ||
1521 | char trigger[21]; | ||
1522 | int i, ret; | ||
1523 | |||
1524 | ret = sscanf(buf, "%20s", trigger); | ||
1525 | if (ret != 1) | ||
1526 | return -EINVAL; | ||
1527 | |||
1528 | if (trigger[0] != '+' && trigger[0] != '-') | ||
1529 | return -EINVAL; | ||
1530 | |||
1531 | ret = kbd_get_state(&state); | ||
1532 | if (ret) | ||
1533 | return ret; | ||
1534 | |||
1535 | if (kbd_als_supported) | ||
1536 | als_enabled = kbd_is_als_mode_bit(state.mode_bit); | ||
1537 | |||
1538 | if (kbd_triggers_supported) | ||
1539 | triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); | ||
1540 | |||
1541 | if (kbd_als_supported) { | ||
1542 | if (strcmp(trigger, "+als") == 0) { | ||
1543 | if (als_enabled) | ||
1544 | return count; | ||
1545 | enable_als = true; | ||
1546 | } else if (strcmp(trigger, "-als") == 0) { | ||
1547 | if (!als_enabled) | ||
1548 | return count; | ||
1549 | disable_als = true; | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | if (enable_als || disable_als) { | ||
1554 | new_state = state; | ||
1555 | if (enable_als) { | ||
1556 | if (triggers_enabled) | ||
1557 | new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS; | ||
1558 | else | ||
1559 | new_state.mode_bit = KBD_MODE_BIT_ALS; | ||
1560 | } else { | ||
1561 | if (triggers_enabled) { | ||
1562 | new_state.mode_bit = KBD_MODE_BIT_TRIGGER; | ||
1563 | kbd_set_level(&new_state, kbd_previous_level); | ||
1564 | } else { | ||
1565 | new_state.mode_bit = KBD_MODE_BIT_ON; | ||
1566 | } | ||
1567 | } | ||
1568 | if (!(kbd_info.modes & BIT(new_state.mode_bit))) | ||
1569 | return -EINVAL; | ||
1570 | ret = kbd_set_state_safe(&new_state, &state); | ||
1571 | if (ret) | ||
1572 | return ret; | ||
1573 | kbd_previous_mode_bit = new_state.mode_bit; | ||
1574 | return count; | ||
1575 | } | ||
1576 | |||
1577 | if (kbd_triggers_supported) { | ||
1578 | for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { | ||
1579 | if (!(kbd_info.triggers & BIT(i))) | ||
1580 | continue; | ||
1581 | if (!kbd_led_triggers[i]) | ||
1582 | continue; | ||
1583 | if (strcmp(trigger+1, kbd_led_triggers[i]) != 0) | ||
1584 | continue; | ||
1585 | if (trigger[0] == '+' && | ||
1586 | triggers_enabled && (state.triggers & BIT(i))) | ||
1587 | return count; | ||
1588 | if (trigger[0] == '-' && | ||
1589 | (!triggers_enabled || !(state.triggers & BIT(i)))) | ||
1590 | return count; | ||
1591 | trigger_bit = i; | ||
1592 | break; | ||
1593 | } | ||
1594 | } | ||
1595 | |||
1596 | if (trigger_bit != -1) { | ||
1597 | new_state = state; | ||
1598 | if (trigger[0] == '+') | ||
1599 | new_state.triggers |= BIT(trigger_bit); | ||
1600 | else { | ||
1601 | new_state.triggers &= ~BIT(trigger_bit); | ||
1602 | /* NOTE: trackstick bit (2) must be disabled when | ||
1603 | * disabling touchpad bit (1), otherwise touchpad | ||
1604 | * bit (1) will not be disabled */ | ||
1605 | if (trigger_bit == 1) | ||
1606 | new_state.triggers &= ~BIT(2); | ||
1607 | } | ||
1608 | if ((kbd_info.triggers & new_state.triggers) != | ||
1609 | new_state.triggers) | ||
1610 | return -EINVAL; | ||
1611 | if (new_state.triggers && !triggers_enabled) { | ||
1612 | if (als_enabled) | ||
1613 | new_state.mode_bit = KBD_MODE_BIT_TRIGGER_ALS; | ||
1614 | else { | ||
1615 | new_state.mode_bit = KBD_MODE_BIT_TRIGGER; | ||
1616 | kbd_set_level(&new_state, kbd_previous_level); | ||
1617 | } | ||
1618 | } else if (new_state.triggers == 0) { | ||
1619 | if (als_enabled) | ||
1620 | new_state.mode_bit = KBD_MODE_BIT_ALS; | ||
1621 | else | ||
1622 | kbd_set_level(&new_state, 0); | ||
1623 | } | ||
1624 | if (!(kbd_info.modes & BIT(new_state.mode_bit))) | ||
1625 | return -EINVAL; | ||
1626 | ret = kbd_set_state_safe(&new_state, &state); | ||
1627 | if (ret) | ||
1628 | return ret; | ||
1629 | if (new_state.mode_bit != KBD_MODE_BIT_OFF) | ||
1630 | kbd_previous_mode_bit = new_state.mode_bit; | ||
1631 | return count; | ||
1632 | } | ||
1633 | |||
1634 | return -EINVAL; | ||
1635 | } | ||
1636 | |||
1637 | static ssize_t kbd_led_triggers_show(struct device *dev, | ||
1638 | struct device_attribute *attr, char *buf) | ||
1639 | { | ||
1640 | struct kbd_state state; | ||
1641 | bool triggers_enabled; | ||
1642 | int level, i, ret; | ||
1643 | int len = 0; | ||
1644 | |||
1645 | ret = kbd_get_state(&state); | ||
1646 | if (ret) | ||
1647 | return ret; | ||
1648 | |||
1649 | len = 0; | ||
1650 | |||
1651 | if (kbd_triggers_supported) { | ||
1652 | triggers_enabled = kbd_is_trigger_mode_bit(state.mode_bit); | ||
1653 | level = kbd_get_level(&state); | ||
1654 | for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); ++i) { | ||
1655 | if (!(kbd_info.triggers & BIT(i))) | ||
1656 | continue; | ||
1657 | if (!kbd_led_triggers[i]) | ||
1658 | continue; | ||
1659 | if ((triggers_enabled || level <= 0) && | ||
1660 | (state.triggers & BIT(i))) | ||
1661 | buf[len++] = '+'; | ||
1662 | else | ||
1663 | buf[len++] = '-'; | ||
1664 | len += sprintf(buf+len, "%s ", kbd_led_triggers[i]); | ||
1665 | } | ||
1666 | } | ||
1667 | |||
1668 | if (kbd_als_supported) { | ||
1669 | if (kbd_is_als_mode_bit(state.mode_bit)) | ||
1670 | len += sprintf(buf+len, "+als "); | ||
1671 | else | ||
1672 | len += sprintf(buf+len, "-als "); | ||
1673 | } | ||
1674 | |||
1675 | if (len) | ||
1676 | buf[len - 1] = '\n'; | ||
1677 | |||
1678 | return len; | ||
1679 | } | ||
1680 | |||
1681 | static DEVICE_ATTR(start_triggers, S_IRUGO | S_IWUSR, | ||
1682 | kbd_led_triggers_show, kbd_led_triggers_store); | ||
1683 | |||
1684 | static ssize_t kbd_led_als_store(struct device *dev, | ||
1685 | struct device_attribute *attr, | ||
1686 | const char *buf, size_t count) | ||
1687 | { | ||
1688 | struct kbd_state state; | ||
1689 | struct kbd_state new_state; | ||
1690 | u8 setting; | ||
1691 | int ret; | ||
1692 | |||
1693 | ret = kstrtou8(buf, 10, &setting); | ||
1694 | if (ret) | ||
1695 | return ret; | ||
1696 | |||
1697 | ret = kbd_get_state(&state); | ||
1698 | if (ret) | ||
1699 | return ret; | ||
1700 | |||
1701 | new_state = state; | ||
1702 | new_state.als_setting = setting; | ||
1703 | |||
1704 | ret = kbd_set_state_safe(&new_state, &state); | ||
1705 | if (ret) | ||
1706 | return ret; | ||
1707 | |||
1708 | return count; | ||
1709 | } | ||
1710 | |||
1711 | static ssize_t kbd_led_als_show(struct device *dev, | ||
1712 | struct device_attribute *attr, char *buf) | ||
1713 | { | ||
1714 | struct kbd_state state; | ||
1715 | int ret; | ||
1716 | |||
1717 | ret = kbd_get_state(&state); | ||
1718 | if (ret) | ||
1719 | return ret; | ||
1720 | |||
1721 | return sprintf(buf, "%d\n", state.als_setting); | ||
1722 | } | ||
1723 | |||
1724 | static DEVICE_ATTR(als_setting, S_IRUGO | S_IWUSR, | ||
1725 | kbd_led_als_show, kbd_led_als_store); | ||
1726 | |||
1727 | static struct attribute *kbd_led_attrs[] = { | ||
1728 | &dev_attr_stop_timeout.attr, | ||
1729 | &dev_attr_start_triggers.attr, | ||
1730 | &dev_attr_als_setting.attr, | ||
1731 | NULL, | ||
1732 | }; | ||
1733 | ATTRIBUTE_GROUPS(kbd_led); | ||
1734 | |||
1735 | static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev) | ||
1736 | { | ||
1737 | int ret; | ||
1738 | u16 num; | ||
1739 | struct kbd_state state; | ||
1740 | |||
1741 | if (kbd_get_max_level()) { | ||
1742 | ret = kbd_get_state(&state); | ||
1743 | if (ret) | ||
1744 | return 0; | ||
1745 | ret = kbd_get_level(&state); | ||
1746 | if (ret < 0) | ||
1747 | return 0; | ||
1748 | return ret; | ||
1749 | } | ||
1750 | |||
1751 | if (kbd_get_valid_token_counts()) { | ||
1752 | ret = kbd_get_first_active_token_bit(); | ||
1753 | if (ret < 0) | ||
1754 | return 0; | ||
1755 | for (num = kbd_token_bits; num != 0 && ret > 0; --ret) | ||
1756 | num &= num - 1; /* clear the first bit set */ | ||
1757 | if (num == 0) | ||
1758 | return 0; | ||
1759 | return ffs(num) - 1; | ||
1760 | } | ||
1761 | |||
1762 | pr_warn("Keyboard brightness level control not supported\n"); | ||
1763 | return 0; | ||
1764 | } | ||
1765 | |||
1766 | static void kbd_led_level_set(struct led_classdev *led_cdev, | ||
1767 | enum led_brightness value) | ||
1768 | { | ||
1769 | struct kbd_state state; | ||
1770 | struct kbd_state new_state; | ||
1771 | u16 num; | ||
1772 | |||
1773 | if (kbd_get_max_level()) { | ||
1774 | if (kbd_get_state(&state)) | ||
1775 | return; | ||
1776 | new_state = state; | ||
1777 | if (kbd_set_level(&new_state, value)) | ||
1778 | return; | ||
1779 | kbd_set_state_safe(&new_state, &state); | ||
1780 | return; | ||
1781 | } | ||
1782 | |||
1783 | if (kbd_get_valid_token_counts()) { | ||
1784 | for (num = kbd_token_bits; num != 0 && value > 0; --value) | ||
1785 | num &= num - 1; /* clear the first bit set */ | ||
1786 | if (num == 0) | ||
1787 | return; | ||
1788 | kbd_set_token_bit(ffs(num) - 1); | ||
1789 | return; | ||
1790 | } | ||
1791 | |||
1792 | pr_warn("Keyboard brightness level control not supported\n"); | ||
1793 | } | ||
1794 | |||
1795 | static struct led_classdev kbd_led = { | ||
1796 | .name = "dell::kbd_backlight", | ||
1797 | .brightness_set = kbd_led_level_set, | ||
1798 | .brightness_get = kbd_led_level_get, | ||
1799 | .groups = kbd_led_groups, | ||
1800 | }; | ||
1801 | |||
1802 | static int __init kbd_led_init(struct device *dev) | ||
1803 | { | ||
1804 | kbd_init(); | ||
1805 | if (!kbd_led_present) | ||
1806 | return -ENODEV; | ||
1807 | kbd_led.max_brightness = kbd_get_max_level(); | ||
1808 | if (!kbd_led.max_brightness) { | ||
1809 | kbd_led.max_brightness = kbd_get_valid_token_counts(); | ||
1810 | if (kbd_led.max_brightness) | ||
1811 | kbd_led.max_brightness--; | ||
1812 | } | ||
1813 | return led_classdev_register(dev, &kbd_led); | ||
1814 | } | ||
1815 | |||
1816 | static void brightness_set_exit(struct led_classdev *led_cdev, | ||
1817 | enum led_brightness value) | ||
1818 | { | ||
1819 | /* Don't change backlight level on exit */ | ||
1820 | }; | ||
1821 | |||
1822 | static void kbd_led_exit(void) | ||
1823 | { | ||
1824 | if (!kbd_led_present) | ||
1825 | return; | ||
1826 | kbd_led.brightness_set = brightness_set_exit; | ||
1827 | led_classdev_unregister(&kbd_led); | ||
1828 | } | ||
1829 | |||
1830 | static int __init dell_init(void) | 792 | static int __init dell_init(void) |
1831 | { | 793 | { |
1832 | int max_intensity = 0; | 794 | int max_intensity = 0; |
@@ -1879,8 +841,6 @@ static int __init dell_init(void) | |||
1879 | if (quirks && quirks->touchpad_led) | 841 | if (quirks && quirks->touchpad_led) |
1880 | touchpad_led_init(&platform_device->dev); | 842 | touchpad_led_init(&platform_device->dev); |
1881 | 843 | ||
1882 | kbd_led_init(&platform_device->dev); | ||
1883 | |||
1884 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); | 844 | dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); |
1885 | if (dell_laptop_dir != NULL) | 845 | if (dell_laptop_dir != NULL) |
1886 | debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, | 846 | debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, |
@@ -1948,7 +908,6 @@ static void __exit dell_exit(void) | |||
1948 | debugfs_remove_recursive(dell_laptop_dir); | 908 | debugfs_remove_recursive(dell_laptop_dir); |
1949 | if (quirks && quirks->touchpad_led) | 909 | if (quirks && quirks->touchpad_led) |
1950 | touchpad_led_exit(); | 910 | touchpad_led_exit(); |
1951 | kbd_led_exit(); | ||
1952 | i8042_remove_filter(dell_laptop_i8042_filter); | 911 | i8042_remove_filter(dell_laptop_i8042_filter); |
1953 | cancel_delayed_work_sync(&dell_rfkill_work); | 912 | cancel_delayed_work_sync(&dell_rfkill_work); |
1954 | backlight_device_unregister(dell_backlight_device); | 913 | backlight_device_unregister(dell_backlight_device); |
@@ -1965,7 +924,5 @@ module_init(dell_init); | |||
1965 | module_exit(dell_exit); | 924 | module_exit(dell_exit); |
1966 | 925 | ||
1967 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); | 926 | MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>"); |
1968 | MODULE_AUTHOR("Gabriele Mazzotta <gabriele.mzt@gmail.com>"); | ||
1969 | MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); | ||
1970 | MODULE_DESCRIPTION("Dell laptop driver"); | 927 | MODULE_DESCRIPTION("Dell laptop driver"); |
1971 | MODULE_LICENSE("GPL"); | 928 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index c71443c4f265..97b5e4ee1ca4 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -1041,6 +1041,7 @@ static const struct x86_cpu_id rapl_ids[] = { | |||
1041 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ | 1041 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ |
1042 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ | 1042 | RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */ |
1043 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ | 1043 | RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */ |
1044 | RAPL_CPU(0x56, rapl_defaults_core),/* Future Xeon */ | ||
1044 | RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */ | 1045 | RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */ |
1045 | {} | 1046 | {} |
1046 | }; | 1047 | }; |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index f622d0613d27..a6f116aa5235 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -414,6 +414,14 @@ config REGULATOR_MAX77802 | |||
414 | Exynos5420/Exynos5800 SoCs to control various voltages. | 414 | Exynos5420/Exynos5800 SoCs to control various voltages. |
415 | It includes support for control of voltage and ramp speed. | 415 | It includes support for control of voltage and ramp speed. |
416 | 416 | ||
417 | config REGULATOR_MAX77843 | ||
418 | tristate "Maxim 77843 regulator" | ||
419 | depends on MFD_MAX77843 | ||
420 | help | ||
421 | This driver controls a Maxim 77843 regulator. | ||
422 | The regulator include two 'SAFEOUT' for USB(Universal Serial Bus) | ||
423 | This is suitable for Exynos5433 SoC chips. | ||
424 | |||
417 | config REGULATOR_MC13XXX_CORE | 425 | config REGULATOR_MC13XXX_CORE |
418 | tristate | 426 | tristate |
419 | 427 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1a0fbc397de1..2c4da15e1545 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o | |||
55 | obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o | 55 | obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o |
56 | obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o | 56 | obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o |
57 | obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o | 57 | obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o |
58 | obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o | ||
58 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o | 59 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o |
59 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o | 60 | obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o |
60 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o | 61 | obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o |
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index f23d7e1f2ee7..e4331f5e5d7d 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c | |||
@@ -32,11 +32,13 @@ | |||
32 | 32 | ||
33 | #define AXP20X_FREQ_DCDC_MASK 0x0f | 33 | #define AXP20X_FREQ_DCDC_MASK 0x0f |
34 | 34 | ||
35 | #define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ | 35 | #define AXP20X_DESC_IO(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ |
36 | _emask, _enable_val, _disable_val) \ | 36 | _ereg, _emask, _enable_val, _disable_val) \ |
37 | [AXP20X_##_id] = { \ | 37 | [AXP20X_##_id] = { \ |
38 | .name = #_id, \ | 38 | .name = #_id, \ |
39 | .supply_name = (_supply), \ | 39 | .supply_name = (_supply), \ |
40 | .of_match = of_match_ptr(_match), \ | ||
41 | .regulators_node = of_match_ptr("regulators"), \ | ||
40 | .type = REGULATOR_VOLTAGE, \ | 42 | .type = REGULATOR_VOLTAGE, \ |
41 | .id = AXP20X_##_id, \ | 43 | .id = AXP20X_##_id, \ |
42 | .n_voltages = (((_max) - (_min)) / (_step) + 1), \ | 44 | .n_voltages = (((_max) - (_min)) / (_step) + 1), \ |
@@ -52,11 +54,13 @@ | |||
52 | .ops = &axp20x_ops, \ | 54 | .ops = &axp20x_ops, \ |
53 | } | 55 | } |
54 | 56 | ||
55 | #define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \ | 57 | #define AXP20X_DESC(_id, _match, _supply, _min, _max, _step, _vreg, _vmask, \ |
56 | _emask) \ | 58 | _ereg, _emask) \ |
57 | [AXP20X_##_id] = { \ | 59 | [AXP20X_##_id] = { \ |
58 | .name = #_id, \ | 60 | .name = #_id, \ |
59 | .supply_name = (_supply), \ | 61 | .supply_name = (_supply), \ |
62 | .of_match = of_match_ptr(_match), \ | ||
63 | .regulators_node = of_match_ptr("regulators"), \ | ||
60 | .type = REGULATOR_VOLTAGE, \ | 64 | .type = REGULATOR_VOLTAGE, \ |
61 | .id = AXP20X_##_id, \ | 65 | .id = AXP20X_##_id, \ |
62 | .n_voltages = (((_max) - (_min)) / (_step) + 1), \ | 66 | .n_voltages = (((_max) - (_min)) / (_step) + 1), \ |
@@ -70,10 +74,12 @@ | |||
70 | .ops = &axp20x_ops, \ | 74 | .ops = &axp20x_ops, \ |
71 | } | 75 | } |
72 | 76 | ||
73 | #define AXP20X_DESC_FIXED(_id, _supply, _volt) \ | 77 | #define AXP20X_DESC_FIXED(_id, _match, _supply, _volt) \ |
74 | [AXP20X_##_id] = { \ | 78 | [AXP20X_##_id] = { \ |
75 | .name = #_id, \ | 79 | .name = #_id, \ |
76 | .supply_name = (_supply), \ | 80 | .supply_name = (_supply), \ |
81 | .of_match = of_match_ptr(_match), \ | ||
82 | .regulators_node = of_match_ptr("regulators"), \ | ||
77 | .type = REGULATOR_VOLTAGE, \ | 83 | .type = REGULATOR_VOLTAGE, \ |
78 | .id = AXP20X_##_id, \ | 84 | .id = AXP20X_##_id, \ |
79 | .n_voltages = 1, \ | 85 | .n_voltages = 1, \ |
@@ -82,10 +88,13 @@ | |||
82 | .ops = &axp20x_ops_fixed \ | 88 | .ops = &axp20x_ops_fixed \ |
83 | } | 89 | } |
84 | 90 | ||
85 | #define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \ | 91 | #define AXP20X_DESC_TABLE(_id, _match, _supply, _table, _vreg, _vmask, _ereg, \ |
92 | _emask) \ | ||
86 | [AXP20X_##_id] = { \ | 93 | [AXP20X_##_id] = { \ |
87 | .name = #_id, \ | 94 | .name = #_id, \ |
88 | .supply_name = (_supply), \ | 95 | .supply_name = (_supply), \ |
96 | .of_match = of_match_ptr(_match), \ | ||
97 | .regulators_node = of_match_ptr("regulators"), \ | ||
89 | .type = REGULATOR_VOLTAGE, \ | 98 | .type = REGULATOR_VOLTAGE, \ |
90 | .id = AXP20X_##_id, \ | 99 | .id = AXP20X_##_id, \ |
91 | .n_voltages = ARRAY_SIZE(_table), \ | 100 | .n_voltages = ARRAY_SIZE(_table), \ |
@@ -127,36 +136,20 @@ static struct regulator_ops axp20x_ops = { | |||
127 | }; | 136 | }; |
128 | 137 | ||
129 | static const struct regulator_desc axp20x_regulators[] = { | 138 | static const struct regulator_desc axp20x_regulators[] = { |
130 | AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f, | 139 | AXP20X_DESC(DCDC2, "dcdc2", "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, |
131 | AXP20X_PWR_OUT_CTRL, 0x10), | 140 | 0x3f, AXP20X_PWR_OUT_CTRL, 0x10), |
132 | AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f, | 141 | AXP20X_DESC(DCDC3, "dcdc3", "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, |
133 | AXP20X_PWR_OUT_CTRL, 0x02), | 142 | 0x7f, AXP20X_PWR_OUT_CTRL, 0x02), |
134 | AXP20X_DESC_FIXED(LDO1, "acin", 1300), | 143 | AXP20X_DESC_FIXED(LDO1, "ldo1", "acin", 1300), |
135 | AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0, | 144 | AXP20X_DESC(LDO2, "ldo2", "ldo24in", 1800, 3300, 100, |
136 | AXP20X_PWR_OUT_CTRL, 0x04), | 145 | AXP20X_LDO24_V_OUT, 0xf0, AXP20X_PWR_OUT_CTRL, 0x04), |
137 | AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f, | 146 | AXP20X_DESC(LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, |
138 | AXP20X_PWR_OUT_CTRL, 0x40), | 147 | 0x7f, AXP20X_PWR_OUT_CTRL, 0x40), |
139 | AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f, | 148 | AXP20X_DESC_TABLE(LDO4, "ldo4", "ldo24in", axp20x_ldo4_data, |
140 | AXP20X_PWR_OUT_CTRL, 0x08), | 149 | AXP20X_LDO24_V_OUT, 0x0f, AXP20X_PWR_OUT_CTRL, 0x08), |
141 | AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0, | 150 | AXP20X_DESC_IO(LDO5, "ldo5", "ldo5in", 1800, 3300, 100, |
142 | AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED, | 151 | AXP20X_LDO5_V_OUT, 0xf0, AXP20X_GPIO0_CTRL, 0x07, |
143 | AXP20X_IO_DISABLED), | 152 | AXP20X_IO_ENABLED, AXP20X_IO_DISABLED), |
144 | }; | ||
145 | |||
146 | #define AXP_MATCH(_name, _id) \ | ||
147 | [AXP20X_##_id] = { \ | ||
148 | .name = #_name, \ | ||
149 | .driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \ | ||
150 | } | ||
151 | |||
152 | static struct of_regulator_match axp20x_matches[] = { | ||
153 | AXP_MATCH(dcdc2, DCDC2), | ||
154 | AXP_MATCH(dcdc3, DCDC3), | ||
155 | AXP_MATCH(ldo1, LDO1), | ||
156 | AXP_MATCH(ldo2, LDO2), | ||
157 | AXP_MATCH(ldo3, LDO3), | ||
158 | AXP_MATCH(ldo4, LDO4), | ||
159 | AXP_MATCH(ldo5, LDO5), | ||
160 | }; | 153 | }; |
161 | 154 | ||
162 | static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) | 155 | static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) |
@@ -193,13 +186,6 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev) | |||
193 | if (!regulators) { | 186 | if (!regulators) { |
194 | dev_warn(&pdev->dev, "regulators node not found\n"); | 187 | dev_warn(&pdev->dev, "regulators node not found\n"); |
195 | } else { | 188 | } else { |
196 | ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches, | ||
197 | ARRAY_SIZE(axp20x_matches)); | ||
198 | if (ret < 0) { | ||
199 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); | ||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | dcdcfreq = 1500; | 189 | dcdcfreq = 1500; |
204 | of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq); | 190 | of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq); |
205 | ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); | 191 | ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); |
@@ -233,23 +219,17 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
233 | { | 219 | { |
234 | struct regulator_dev *rdev; | 220 | struct regulator_dev *rdev; |
235 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); | 221 | struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); |
236 | struct regulator_config config = { }; | 222 | struct regulator_config config = { |
237 | struct regulator_init_data *init_data; | 223 | .dev = pdev->dev.parent, |
224 | .regmap = axp20x->regmap, | ||
225 | }; | ||
238 | int ret, i; | 226 | int ret, i; |
239 | u32 workmode; | 227 | u32 workmode; |
240 | 228 | ||
241 | ret = axp20x_regulator_parse_dt(pdev); | 229 | /* This only sets the dcdc freq. Ignore any errors */ |
242 | if (ret) | 230 | axp20x_regulator_parse_dt(pdev); |
243 | return ret; | ||
244 | 231 | ||
245 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { | 232 | for (i = 0; i < AXP20X_REG_ID_MAX; i++) { |
246 | init_data = axp20x_matches[i].init_data; | ||
247 | |||
248 | config.dev = pdev->dev.parent; | ||
249 | config.init_data = init_data; | ||
250 | config.regmap = axp20x->regmap; | ||
251 | config.of_node = axp20x_matches[i].of_node; | ||
252 | |||
253 | rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i], | 233 | rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i], |
254 | &config); | 234 | &config); |
255 | if (IS_ERR(rdev)) { | 235 | if (IS_ERR(rdev)) { |
@@ -259,7 +239,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev) | |||
259 | return PTR_ERR(rdev); | 239 | return PTR_ERR(rdev); |
260 | } | 240 | } |
261 | 241 | ||
262 | ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode", | 242 | ret = of_property_read_u32(rdev->dev.of_node, |
243 | "x-powers,dcdc-workmode", | ||
263 | &workmode); | 244 | &workmode); |
264 | if (!ret) { | 245 | if (!ret) { |
265 | if (axp20x_set_dcdc_workmode(rdev, i, workmode)) | 246 | if (axp20x_set_dcdc_workmode(rdev, i, workmode)) |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e225711bb8bc..b899947d839d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -632,49 +632,34 @@ static ssize_t regulator_bypass_show(struct device *dev, | |||
632 | static DEVICE_ATTR(bypass, 0444, | 632 | static DEVICE_ATTR(bypass, 0444, |
633 | regulator_bypass_show, NULL); | 633 | regulator_bypass_show, NULL); |
634 | 634 | ||
635 | /* | ||
636 | * These are the only attributes are present for all regulators. | ||
637 | * Other attributes are a function of regulator functionality. | ||
638 | */ | ||
639 | static struct attribute *regulator_dev_attrs[] = { | ||
640 | &dev_attr_name.attr, | ||
641 | &dev_attr_num_users.attr, | ||
642 | &dev_attr_type.attr, | ||
643 | NULL, | ||
644 | }; | ||
645 | ATTRIBUTE_GROUPS(regulator_dev); | ||
646 | |||
647 | static void regulator_dev_release(struct device *dev) | ||
648 | { | ||
649 | struct regulator_dev *rdev = dev_get_drvdata(dev); | ||
650 | kfree(rdev); | ||
651 | } | ||
652 | |||
653 | static struct class regulator_class = { | ||
654 | .name = "regulator", | ||
655 | .dev_release = regulator_dev_release, | ||
656 | .dev_groups = regulator_dev_groups, | ||
657 | }; | ||
658 | |||
659 | /* Calculate the new optimum regulator operating mode based on the new total | 635 | /* Calculate the new optimum regulator operating mode based on the new total |
660 | * consumer load. All locks held by caller */ | 636 | * consumer load. All locks held by caller */ |
661 | static void drms_uA_update(struct regulator_dev *rdev) | 637 | static int drms_uA_update(struct regulator_dev *rdev) |
662 | { | 638 | { |
663 | struct regulator *sibling; | 639 | struct regulator *sibling; |
664 | int current_uA = 0, output_uV, input_uV, err; | 640 | int current_uA = 0, output_uV, input_uV, err; |
665 | unsigned int mode; | 641 | unsigned int mode; |
666 | 642 | ||
643 | /* | ||
644 | * first check to see if we can set modes at all, otherwise just | ||
645 | * tell the consumer everything is OK. | ||
646 | */ | ||
667 | err = regulator_check_drms(rdev); | 647 | err = regulator_check_drms(rdev); |
668 | if (err < 0 || !rdev->desc->ops->get_optimum_mode || | 648 | if (err < 0) |
669 | (!rdev->desc->ops->get_voltage && | 649 | return 0; |
670 | !rdev->desc->ops->get_voltage_sel) || | 650 | |
671 | !rdev->desc->ops->set_mode) | 651 | if (!rdev->desc->ops->get_optimum_mode) |
672 | return; | 652 | return 0; |
653 | |||
654 | if (!rdev->desc->ops->set_mode) | ||
655 | return -EINVAL; | ||
673 | 656 | ||
674 | /* get output voltage */ | 657 | /* get output voltage */ |
675 | output_uV = _regulator_get_voltage(rdev); | 658 | output_uV = _regulator_get_voltage(rdev); |
676 | if (output_uV <= 0) | 659 | if (output_uV <= 0) { |
677 | return; | 660 | rdev_err(rdev, "invalid output voltage found\n"); |
661 | return -EINVAL; | ||
662 | } | ||
678 | 663 | ||
679 | /* get input voltage */ | 664 | /* get input voltage */ |
680 | input_uV = 0; | 665 | input_uV = 0; |
@@ -682,8 +667,10 @@ static void drms_uA_update(struct regulator_dev *rdev) | |||
682 | input_uV = regulator_get_voltage(rdev->supply); | 667 | input_uV = regulator_get_voltage(rdev->supply); |
683 | if (input_uV <= 0) | 668 | if (input_uV <= 0) |
684 | input_uV = rdev->constraints->input_uV; | 669 | input_uV = rdev->constraints->input_uV; |
685 | if (input_uV <= 0) | 670 | if (input_uV <= 0) { |
686 | return; | 671 | rdev_err(rdev, "invalid input voltage found\n"); |
672 | return -EINVAL; | ||
673 | } | ||
687 | 674 | ||
688 | /* calc total requested load */ | 675 | /* calc total requested load */ |
689 | list_for_each_entry(sibling, &rdev->consumer_list, list) | 676 | list_for_each_entry(sibling, &rdev->consumer_list, list) |
@@ -695,8 +682,17 @@ static void drms_uA_update(struct regulator_dev *rdev) | |||
695 | 682 | ||
696 | /* check the new mode is allowed */ | 683 | /* check the new mode is allowed */ |
697 | err = regulator_mode_constrain(rdev, &mode); | 684 | err = regulator_mode_constrain(rdev, &mode); |
698 | if (err == 0) | 685 | if (err < 0) { |
699 | rdev->desc->ops->set_mode(rdev, mode); | 686 | rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", |
687 | current_uA, input_uV, output_uV); | ||
688 | return err; | ||
689 | } | ||
690 | |||
691 | err = rdev->desc->ops->set_mode(rdev, mode); | ||
692 | if (err < 0) | ||
693 | rdev_err(rdev, "failed to set optimum mode %x\n", mode); | ||
694 | |||
695 | return err; | ||
700 | } | 696 | } |
701 | 697 | ||
702 | static int suspend_set_state(struct regulator_dev *rdev, | 698 | static int suspend_set_state(struct regulator_dev *rdev, |
@@ -1488,7 +1484,7 @@ struct regulator *regulator_get_optional(struct device *dev, const char *id) | |||
1488 | } | 1484 | } |
1489 | EXPORT_SYMBOL_GPL(regulator_get_optional); | 1485 | EXPORT_SYMBOL_GPL(regulator_get_optional); |
1490 | 1486 | ||
1491 | /* Locks held by regulator_put() */ | 1487 | /* regulator_list_mutex lock held by regulator_put() */ |
1492 | static void _regulator_put(struct regulator *regulator) | 1488 | static void _regulator_put(struct regulator *regulator) |
1493 | { | 1489 | { |
1494 | struct regulator_dev *rdev; | 1490 | struct regulator_dev *rdev; |
@@ -1503,12 +1499,14 @@ static void _regulator_put(struct regulator *regulator) | |||
1503 | /* remove any sysfs entries */ | 1499 | /* remove any sysfs entries */ |
1504 | if (regulator->dev) | 1500 | if (regulator->dev) |
1505 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); | 1501 | sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name); |
1502 | mutex_lock(&rdev->mutex); | ||
1506 | kfree(regulator->supply_name); | 1503 | kfree(regulator->supply_name); |
1507 | list_del(®ulator->list); | 1504 | list_del(®ulator->list); |
1508 | kfree(regulator); | 1505 | kfree(regulator); |
1509 | 1506 | ||
1510 | rdev->open_count--; | 1507 | rdev->open_count--; |
1511 | rdev->exclusive = 0; | 1508 | rdev->exclusive = 0; |
1509 | mutex_unlock(&rdev->mutex); | ||
1512 | 1510 | ||
1513 | module_put(rdev->owner); | 1511 | module_put(rdev->owner); |
1514 | } | 1512 | } |
@@ -3024,75 +3022,13 @@ EXPORT_SYMBOL_GPL(regulator_get_mode); | |||
3024 | int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) | 3022 | int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) |
3025 | { | 3023 | { |
3026 | struct regulator_dev *rdev = regulator->rdev; | 3024 | struct regulator_dev *rdev = regulator->rdev; |
3027 | struct regulator *consumer; | 3025 | int ret; |
3028 | int ret, output_uV, input_uV = 0, total_uA_load = 0; | ||
3029 | unsigned int mode; | ||
3030 | |||
3031 | if (rdev->supply) | ||
3032 | input_uV = regulator_get_voltage(rdev->supply); | ||
3033 | 3026 | ||
3034 | mutex_lock(&rdev->mutex); | 3027 | mutex_lock(&rdev->mutex); |
3035 | |||
3036 | /* | ||
3037 | * first check to see if we can set modes at all, otherwise just | ||
3038 | * tell the consumer everything is OK. | ||
3039 | */ | ||
3040 | regulator->uA_load = uA_load; | 3028 | regulator->uA_load = uA_load; |
3041 | ret = regulator_check_drms(rdev); | 3029 | ret = drms_uA_update(rdev); |
3042 | if (ret < 0) { | ||
3043 | ret = 0; | ||
3044 | goto out; | ||
3045 | } | ||
3046 | |||
3047 | if (!rdev->desc->ops->get_optimum_mode) | ||
3048 | goto out; | ||
3049 | |||
3050 | /* | ||
3051 | * we can actually do this so any errors are indicators of | ||
3052 | * potential real failure. | ||
3053 | */ | ||
3054 | ret = -EINVAL; | ||
3055 | |||
3056 | if (!rdev->desc->ops->set_mode) | ||
3057 | goto out; | ||
3058 | |||
3059 | /* get output voltage */ | ||
3060 | output_uV = _regulator_get_voltage(rdev); | ||
3061 | if (output_uV <= 0) { | ||
3062 | rdev_err(rdev, "invalid output voltage found\n"); | ||
3063 | goto out; | ||
3064 | } | ||
3065 | |||
3066 | /* No supply? Use constraint voltage */ | ||
3067 | if (input_uV <= 0) | ||
3068 | input_uV = rdev->constraints->input_uV; | ||
3069 | if (input_uV <= 0) { | ||
3070 | rdev_err(rdev, "invalid input voltage found\n"); | ||
3071 | goto out; | ||
3072 | } | ||
3073 | |||
3074 | /* calc total requested load for this regulator */ | ||
3075 | list_for_each_entry(consumer, &rdev->consumer_list, list) | ||
3076 | total_uA_load += consumer->uA_load; | ||
3077 | |||
3078 | mode = rdev->desc->ops->get_optimum_mode(rdev, | ||
3079 | input_uV, output_uV, | ||
3080 | total_uA_load); | ||
3081 | ret = regulator_mode_constrain(rdev, &mode); | ||
3082 | if (ret < 0) { | ||
3083 | rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", | ||
3084 | total_uA_load, input_uV, output_uV); | ||
3085 | goto out; | ||
3086 | } | ||
3087 | |||
3088 | ret = rdev->desc->ops->set_mode(rdev, mode); | ||
3089 | if (ret < 0) { | ||
3090 | rdev_err(rdev, "failed to set optimum mode %x\n", mode); | ||
3091 | goto out; | ||
3092 | } | ||
3093 | ret = mode; | ||
3094 | out: | ||
3095 | mutex_unlock(&rdev->mutex); | 3030 | mutex_unlock(&rdev->mutex); |
3031 | |||
3096 | return ret; | 3032 | return ret; |
3097 | } | 3033 | } |
3098 | EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); | 3034 | EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); |
@@ -3434,126 +3370,136 @@ int regulator_mode_to_status(unsigned int mode) | |||
3434 | } | 3370 | } |
3435 | EXPORT_SYMBOL_GPL(regulator_mode_to_status); | 3371 | EXPORT_SYMBOL_GPL(regulator_mode_to_status); |
3436 | 3372 | ||
3373 | static struct attribute *regulator_dev_attrs[] = { | ||
3374 | &dev_attr_name.attr, | ||
3375 | &dev_attr_num_users.attr, | ||
3376 | &dev_attr_type.attr, | ||
3377 | &dev_attr_microvolts.attr, | ||
3378 | &dev_attr_microamps.attr, | ||
3379 | &dev_attr_opmode.attr, | ||
3380 | &dev_attr_state.attr, | ||
3381 | &dev_attr_status.attr, | ||
3382 | &dev_attr_bypass.attr, | ||
3383 | &dev_attr_requested_microamps.attr, | ||
3384 | &dev_attr_min_microvolts.attr, | ||
3385 | &dev_attr_max_microvolts.attr, | ||
3386 | &dev_attr_min_microamps.attr, | ||
3387 | &dev_attr_max_microamps.attr, | ||
3388 | &dev_attr_suspend_standby_state.attr, | ||
3389 | &dev_attr_suspend_mem_state.attr, | ||
3390 | &dev_attr_suspend_disk_state.attr, | ||
3391 | &dev_attr_suspend_standby_microvolts.attr, | ||
3392 | &dev_attr_suspend_mem_microvolts.attr, | ||
3393 | &dev_attr_suspend_disk_microvolts.attr, | ||
3394 | &dev_attr_suspend_standby_mode.attr, | ||
3395 | &dev_attr_suspend_mem_mode.attr, | ||
3396 | &dev_attr_suspend_disk_mode.attr, | ||
3397 | NULL | ||
3398 | }; | ||
3399 | |||
3437 | /* | 3400 | /* |
3438 | * To avoid cluttering sysfs (and memory) with useless state, only | 3401 | * To avoid cluttering sysfs (and memory) with useless state, only |
3439 | * create attributes that can be meaningfully displayed. | 3402 | * create attributes that can be meaningfully displayed. |
3440 | */ | 3403 | */ |
3441 | static int add_regulator_attributes(struct regulator_dev *rdev) | 3404 | static umode_t regulator_attr_is_visible(struct kobject *kobj, |
3405 | struct attribute *attr, int idx) | ||
3442 | { | 3406 | { |
3443 | struct device *dev = &rdev->dev; | 3407 | struct device *dev = kobj_to_dev(kobj); |
3408 | struct regulator_dev *rdev = container_of(dev, struct regulator_dev, dev); | ||
3444 | const struct regulator_ops *ops = rdev->desc->ops; | 3409 | const struct regulator_ops *ops = rdev->desc->ops; |
3445 | int status = 0; | 3410 | umode_t mode = attr->mode; |
3411 | |||
3412 | /* these three are always present */ | ||
3413 | if (attr == &dev_attr_name.attr || | ||
3414 | attr == &dev_attr_num_users.attr || | ||
3415 | attr == &dev_attr_type.attr) | ||
3416 | return mode; | ||
3446 | 3417 | ||
3447 | /* some attributes need specific methods to be displayed */ | 3418 | /* some attributes need specific methods to be displayed */ |
3448 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || | 3419 | if (attr == &dev_attr_microvolts.attr) { |
3449 | (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || | 3420 | if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || |
3450 | (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || | 3421 | (ops->get_voltage_sel && ops->get_voltage_sel(rdev) >= 0) || |
3451 | (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1))) { | 3422 | (ops->list_voltage && ops->list_voltage(rdev, 0) >= 0) || |
3452 | status = device_create_file(dev, &dev_attr_microvolts); | 3423 | (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1)) |
3453 | if (status < 0) | 3424 | return mode; |
3454 | return status; | 3425 | return 0; |
3455 | } | ||
3456 | if (ops->get_current_limit) { | ||
3457 | status = device_create_file(dev, &dev_attr_microamps); | ||
3458 | if (status < 0) | ||
3459 | return status; | ||
3460 | } | ||
3461 | if (ops->get_mode) { | ||
3462 | status = device_create_file(dev, &dev_attr_opmode); | ||
3463 | if (status < 0) | ||
3464 | return status; | ||
3465 | } | ||
3466 | if (rdev->ena_pin || ops->is_enabled) { | ||
3467 | status = device_create_file(dev, &dev_attr_state); | ||
3468 | if (status < 0) | ||
3469 | return status; | ||
3470 | } | ||
3471 | if (ops->get_status) { | ||
3472 | status = device_create_file(dev, &dev_attr_status); | ||
3473 | if (status < 0) | ||
3474 | return status; | ||
3475 | } | ||
3476 | if (ops->get_bypass) { | ||
3477 | status = device_create_file(dev, &dev_attr_bypass); | ||
3478 | if (status < 0) | ||
3479 | return status; | ||
3480 | } | 3426 | } |
3481 | 3427 | ||
3428 | if (attr == &dev_attr_microamps.attr) | ||
3429 | return ops->get_current_limit ? mode : 0; | ||
3430 | |||
3431 | if (attr == &dev_attr_opmode.attr) | ||
3432 | return ops->get_mode ? mode : 0; | ||
3433 | |||
3434 | if (attr == &dev_attr_state.attr) | ||
3435 | return (rdev->ena_pin || ops->is_enabled) ? mode : 0; | ||
3436 | |||
3437 | if (attr == &dev_attr_status.attr) | ||
3438 | return ops->get_status ? mode : 0; | ||
3439 | |||
3440 | if (attr == &dev_attr_bypass.attr) | ||
3441 | return ops->get_bypass ? mode : 0; | ||
3442 | |||
3482 | /* some attributes are type-specific */ | 3443 | /* some attributes are type-specific */ |
3483 | if (rdev->desc->type == REGULATOR_CURRENT) { | 3444 | if (attr == &dev_attr_requested_microamps.attr) |
3484 | status = device_create_file(dev, &dev_attr_requested_microamps); | 3445 | return rdev->desc->type == REGULATOR_CURRENT ? mode : 0; |
3485 | if (status < 0) | ||
3486 | return status; | ||
3487 | } | ||
3488 | 3446 | ||
3489 | /* all the other attributes exist to support constraints; | 3447 | /* all the other attributes exist to support constraints; |
3490 | * don't show them if there are no constraints, or if the | 3448 | * don't show them if there are no constraints, or if the |
3491 | * relevant supporting methods are missing. | 3449 | * relevant supporting methods are missing. |
3492 | */ | 3450 | */ |
3493 | if (!rdev->constraints) | 3451 | if (!rdev->constraints) |
3494 | return status; | 3452 | return 0; |
3495 | 3453 | ||
3496 | /* constraints need specific supporting methods */ | 3454 | /* constraints need specific supporting methods */ |
3497 | if (ops->set_voltage || ops->set_voltage_sel) { | 3455 | if (attr == &dev_attr_min_microvolts.attr || |
3498 | status = device_create_file(dev, &dev_attr_min_microvolts); | 3456 | attr == &dev_attr_max_microvolts.attr) |
3499 | if (status < 0) | 3457 | return (ops->set_voltage || ops->set_voltage_sel) ? mode : 0; |
3500 | return status; | 3458 | |
3501 | status = device_create_file(dev, &dev_attr_max_microvolts); | 3459 | if (attr == &dev_attr_min_microamps.attr || |
3502 | if (status < 0) | 3460 | attr == &dev_attr_max_microamps.attr) |
3503 | return status; | 3461 | return ops->set_current_limit ? mode : 0; |
3504 | } | 3462 | |
3505 | if (ops->set_current_limit) { | 3463 | if (attr == &dev_attr_suspend_standby_state.attr || |
3506 | status = device_create_file(dev, &dev_attr_min_microamps); | 3464 | attr == &dev_attr_suspend_mem_state.attr || |
3507 | if (status < 0) | 3465 | attr == &dev_attr_suspend_disk_state.attr) |
3508 | return status; | 3466 | return mode; |
3509 | status = device_create_file(dev, &dev_attr_max_microamps); | 3467 | |
3510 | if (status < 0) | 3468 | if (attr == &dev_attr_suspend_standby_microvolts.attr || |
3511 | return status; | 3469 | attr == &dev_attr_suspend_mem_microvolts.attr || |
3512 | } | 3470 | attr == &dev_attr_suspend_disk_microvolts.attr) |
3513 | 3471 | return ops->set_suspend_voltage ? mode : 0; | |
3514 | status = device_create_file(dev, &dev_attr_suspend_standby_state); | 3472 | |
3515 | if (status < 0) | 3473 | if (attr == &dev_attr_suspend_standby_mode.attr || |
3516 | return status; | 3474 | attr == &dev_attr_suspend_mem_mode.attr || |
3517 | status = device_create_file(dev, &dev_attr_suspend_mem_state); | 3475 | attr == &dev_attr_suspend_disk_mode.attr) |
3518 | if (status < 0) | 3476 | return ops->set_suspend_mode ? mode : 0; |
3519 | return status; | 3477 | |
3520 | status = device_create_file(dev, &dev_attr_suspend_disk_state); | 3478 | return mode; |
3521 | if (status < 0) | 3479 | } |
3522 | return status; | 3480 | |
3481 | static const struct attribute_group regulator_dev_group = { | ||
3482 | .attrs = regulator_dev_attrs, | ||
3483 | .is_visible = regulator_attr_is_visible, | ||
3484 | }; | ||
3485 | |||
3486 | static const struct attribute_group *regulator_dev_groups[] = { | ||
3487 | ®ulator_dev_group, | ||
3488 | NULL | ||
3489 | }; | ||
3523 | 3490 | ||
3524 | if (ops->set_suspend_voltage) { | 3491 | static void regulator_dev_release(struct device *dev) |
3525 | status = device_create_file(dev, | 3492 | { |
3526 | &dev_attr_suspend_standby_microvolts); | 3493 | struct regulator_dev *rdev = dev_get_drvdata(dev); |
3527 | if (status < 0) | 3494 | kfree(rdev); |
3528 | return status; | ||
3529 | status = device_create_file(dev, | ||
3530 | &dev_attr_suspend_mem_microvolts); | ||
3531 | if (status < 0) | ||
3532 | return status; | ||
3533 | status = device_create_file(dev, | ||
3534 | &dev_attr_suspend_disk_microvolts); | ||
3535 | if (status < 0) | ||
3536 | return status; | ||
3537 | } | ||
3538 | |||
3539 | if (ops->set_suspend_mode) { | ||
3540 | status = device_create_file(dev, | ||
3541 | &dev_attr_suspend_standby_mode); | ||
3542 | if (status < 0) | ||
3543 | return status; | ||
3544 | status = device_create_file(dev, | ||
3545 | &dev_attr_suspend_mem_mode); | ||
3546 | if (status < 0) | ||
3547 | return status; | ||
3548 | status = device_create_file(dev, | ||
3549 | &dev_attr_suspend_disk_mode); | ||
3550 | if (status < 0) | ||
3551 | return status; | ||
3552 | } | ||
3553 | |||
3554 | return status; | ||
3555 | } | 3495 | } |
3556 | 3496 | ||
3497 | static struct class regulator_class = { | ||
3498 | .name = "regulator", | ||
3499 | .dev_release = regulator_dev_release, | ||
3500 | .dev_groups = regulator_dev_groups, | ||
3501 | }; | ||
3502 | |||
3557 | static void rdev_init_debugfs(struct regulator_dev *rdev) | 3503 | static void rdev_init_debugfs(struct regulator_dev *rdev) |
3558 | { | 3504 | { |
3559 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); | 3505 | rdev->debugfs = debugfs_create_dir(rdev_get_name(rdev), debugfs_root); |
@@ -3573,7 +3519,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) | |||
3573 | /** | 3519 | /** |
3574 | * regulator_register - register regulator | 3520 | * regulator_register - register regulator |
3575 | * @regulator_desc: regulator to register | 3521 | * @regulator_desc: regulator to register |
3576 | * @config: runtime configuration for regulator | 3522 | * @cfg: runtime configuration for regulator |
3577 | * | 3523 | * |
3578 | * Called by regulator drivers to register a regulator. | 3524 | * Called by regulator drivers to register a regulator. |
3579 | * Returns a valid pointer to struct regulator_dev on success | 3525 | * Returns a valid pointer to struct regulator_dev on success |
@@ -3581,20 +3527,21 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) | |||
3581 | */ | 3527 | */ |
3582 | struct regulator_dev * | 3528 | struct regulator_dev * |
3583 | regulator_register(const struct regulator_desc *regulator_desc, | 3529 | regulator_register(const struct regulator_desc *regulator_desc, |
3584 | const struct regulator_config *config) | 3530 | const struct regulator_config *cfg) |
3585 | { | 3531 | { |
3586 | const struct regulation_constraints *constraints = NULL; | 3532 | const struct regulation_constraints *constraints = NULL; |
3587 | const struct regulator_init_data *init_data; | 3533 | const struct regulator_init_data *init_data; |
3588 | static atomic_t regulator_no = ATOMIC_INIT(0); | 3534 | struct regulator_config *config = NULL; |
3535 | static atomic_t regulator_no = ATOMIC_INIT(-1); | ||
3589 | struct regulator_dev *rdev; | 3536 | struct regulator_dev *rdev; |
3590 | struct device *dev; | 3537 | struct device *dev; |
3591 | int ret, i; | 3538 | int ret, i; |
3592 | const char *supply = NULL; | 3539 | const char *supply = NULL; |
3593 | 3540 | ||
3594 | if (regulator_desc == NULL || config == NULL) | 3541 | if (regulator_desc == NULL || cfg == NULL) |
3595 | return ERR_PTR(-EINVAL); | 3542 | return ERR_PTR(-EINVAL); |
3596 | 3543 | ||
3597 | dev = config->dev; | 3544 | dev = cfg->dev; |
3598 | WARN_ON(!dev); | 3545 | WARN_ON(!dev); |
3599 | 3546 | ||
3600 | if (regulator_desc->name == NULL || regulator_desc->ops == NULL) | 3547 | if (regulator_desc->name == NULL || regulator_desc->ops == NULL) |
@@ -3624,7 +3571,17 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3624 | if (rdev == NULL) | 3571 | if (rdev == NULL) |
3625 | return ERR_PTR(-ENOMEM); | 3572 | return ERR_PTR(-ENOMEM); |
3626 | 3573 | ||
3627 | init_data = regulator_of_get_init_data(dev, regulator_desc, | 3574 | /* |
3575 | * Duplicate the config so the driver could override it after | ||
3576 | * parsing init data. | ||
3577 | */ | ||
3578 | config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); | ||
3579 | if (config == NULL) { | ||
3580 | kfree(rdev); | ||
3581 | return ERR_PTR(-ENOMEM); | ||
3582 | } | ||
3583 | |||
3584 | init_data = regulator_of_get_init_data(dev, regulator_desc, config, | ||
3628 | &rdev->dev.of_node); | 3585 | &rdev->dev.of_node); |
3629 | if (!init_data) { | 3586 | if (!init_data) { |
3630 | init_data = config->init_data; | 3587 | init_data = config->init_data; |
@@ -3658,8 +3615,8 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3658 | /* register with sysfs */ | 3615 | /* register with sysfs */ |
3659 | rdev->dev.class = ®ulator_class; | 3616 | rdev->dev.class = ®ulator_class; |
3660 | rdev->dev.parent = dev; | 3617 | rdev->dev.parent = dev; |
3661 | dev_set_name(&rdev->dev, "regulator.%d", | 3618 | dev_set_name(&rdev->dev, "regulator.%lu", |
3662 | atomic_inc_return(®ulator_no) - 1); | 3619 | (unsigned long) atomic_inc_return(®ulator_no)); |
3663 | ret = device_register(&rdev->dev); | 3620 | ret = device_register(&rdev->dev); |
3664 | if (ret != 0) { | 3621 | if (ret != 0) { |
3665 | put_device(&rdev->dev); | 3622 | put_device(&rdev->dev); |
@@ -3692,11 +3649,6 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3692 | if (ret < 0) | 3649 | if (ret < 0) |
3693 | goto scrub; | 3650 | goto scrub; |
3694 | 3651 | ||
3695 | /* add attributes supported by this regulator */ | ||
3696 | ret = add_regulator_attributes(rdev); | ||
3697 | if (ret < 0) | ||
3698 | goto scrub; | ||
3699 | |||
3700 | if (init_data && init_data->supply_regulator) | 3652 | if (init_data && init_data->supply_regulator) |
3701 | supply = init_data->supply_regulator; | 3653 | supply = init_data->supply_regulator; |
3702 | else if (regulator_desc->supply_name) | 3654 | else if (regulator_desc->supply_name) |
@@ -3752,6 +3704,7 @@ add_dev: | |||
3752 | rdev_init_debugfs(rdev); | 3704 | rdev_init_debugfs(rdev); |
3753 | out: | 3705 | out: |
3754 | mutex_unlock(®ulator_list_mutex); | 3706 | mutex_unlock(®ulator_list_mutex); |
3707 | kfree(config); | ||
3755 | return rdev; | 3708 | return rdev; |
3756 | 3709 | ||
3757 | unset_supplies: | 3710 | unset_supplies: |
diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index c78d2106d6cb..01343419555e 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/of_gpio.h> | ||
27 | #include <linux/regulator/of_regulator.h> | 28 | #include <linux/regulator/of_regulator.h> |
28 | #include <linux/regulator/da9211.h> | 29 | #include <linux/regulator/da9211.h> |
29 | #include "da9211-regulator.h" | 30 | #include "da9211-regulator.h" |
@@ -276,7 +277,10 @@ static struct da9211_pdata *da9211_parse_regulators_dt( | |||
276 | continue; | 277 | continue; |
277 | 278 | ||
278 | pdata->init_data[n] = da9211_matches[i].init_data; | 279 | pdata->init_data[n] = da9211_matches[i].init_data; |
279 | 280 | pdata->reg_node[n] = da9211_matches[i].of_node; | |
281 | pdata->gpio_ren[n] = | ||
282 | of_get_named_gpio(da9211_matches[i].of_node, | ||
283 | "enable-gpios", 0); | ||
280 | n++; | 284 | n++; |
281 | } | 285 | } |
282 | 286 | ||
@@ -364,7 +368,15 @@ static int da9211_regulator_init(struct da9211 *chip) | |||
364 | config.dev = chip->dev; | 368 | config.dev = chip->dev; |
365 | config.driver_data = chip; | 369 | config.driver_data = chip; |
366 | config.regmap = chip->regmap; | 370 | config.regmap = chip->regmap; |
367 | config.of_node = chip->dev->of_node; | 371 | config.of_node = chip->pdata->reg_node[i]; |
372 | |||
373 | if (gpio_is_valid(chip->pdata->gpio_ren[i])) { | ||
374 | config.ena_gpio = chip->pdata->gpio_ren[i]; | ||
375 | config.ena_gpio_initialized = true; | ||
376 | } else { | ||
377 | config.ena_gpio = -EINVAL; | ||
378 | config.ena_gpio_initialized = false; | ||
379 | } | ||
368 | 380 | ||
369 | chip->rdev[i] = devm_regulator_register(chip->dev, | 381 | chip->rdev[i] = devm_regulator_register(chip->dev, |
370 | &da9211_regulators[i], &config); | 382 | &da9211_regulators[i], &config); |
diff --git a/drivers/regulator/fan53555.c b/drivers/regulator/fan53555.c index 6c43ab2d5121..3c25db89a021 100644 --- a/drivers/regulator/fan53555.c +++ b/drivers/regulator/fan53555.c | |||
@@ -147,7 +147,7 @@ static unsigned int fan53555_get_mode(struct regulator_dev *rdev) | |||
147 | return REGULATOR_MODE_NORMAL; | 147 | return REGULATOR_MODE_NORMAL; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int slew_rates[] = { | 150 | static const int slew_rates[] = { |
151 | 64000, | 151 | 64000, |
152 | 32000, | 152 | 32000, |
153 | 16000, | 153 | 16000, |
@@ -296,7 +296,7 @@ static int fan53555_regulator_register(struct fan53555_device_info *di, | |||
296 | return PTR_ERR_OR_ZERO(di->rdev); | 296 | return PTR_ERR_OR_ZERO(di->rdev); |
297 | } | 297 | } |
298 | 298 | ||
299 | static struct regmap_config fan53555_regmap_config = { | 299 | static const struct regmap_config fan53555_regmap_config = { |
300 | .reg_bits = 8, | 300 | .reg_bits = 8, |
301 | .val_bits = 8, | 301 | .val_bits = 8, |
302 | }; | 302 | }; |
diff --git a/drivers/regulator/internal.h b/drivers/regulator/internal.h index 80ba2a35a04b..c74ac8734023 100644 --- a/drivers/regulator/internal.h +++ b/drivers/regulator/internal.h | |||
@@ -38,11 +38,13 @@ struct regulator { | |||
38 | #ifdef CONFIG_OF | 38 | #ifdef CONFIG_OF |
39 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | 39 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, |
40 | const struct regulator_desc *desc, | 40 | const struct regulator_desc *desc, |
41 | struct regulator_config *config, | ||
41 | struct device_node **node); | 42 | struct device_node **node); |
42 | #else | 43 | #else |
43 | static inline struct regulator_init_data * | 44 | static inline struct regulator_init_data * |
44 | regulator_of_get_init_data(struct device *dev, | 45 | regulator_of_get_init_data(struct device *dev, |
45 | const struct regulator_desc *desc, | 46 | const struct regulator_desc *desc, |
47 | struct regulator_config *config, | ||
46 | struct device_node **node) | 48 | struct device_node **node) |
47 | { | 49 | { |
48 | return NULL; | 50 | return NULL; |
diff --git a/drivers/regulator/isl9305.c b/drivers/regulator/isl9305.c index 92fefd98da58..6e3a15fe00f1 100644 --- a/drivers/regulator/isl9305.c +++ b/drivers/regulator/isl9305.c | |||
@@ -177,8 +177,10 @@ static int isl9305_i2c_probe(struct i2c_client *i2c, | |||
177 | 177 | ||
178 | #ifdef CONFIG_OF | 178 | #ifdef CONFIG_OF |
179 | static const struct of_device_id isl9305_dt_ids[] = { | 179 | static const struct of_device_id isl9305_dt_ids[] = { |
180 | { .compatible = "isl,isl9305" }, | 180 | { .compatible = "isl,isl9305" }, /* for backward compat., don't use */ |
181 | { .compatible = "isl,isl9305h" }, | 181 | { .compatible = "isil,isl9305" }, |
182 | { .compatible = "isl,isl9305h" }, /* for backward compat., don't use */ | ||
183 | { .compatible = "isil,isl9305h" }, | ||
182 | {}, | 184 | {}, |
183 | }; | 185 | }; |
184 | #endif | 186 | #endif |
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 021d64d856bb..3de328ab41f3 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c | |||
@@ -106,7 +106,6 @@ struct lp872x { | |||
106 | struct device *dev; | 106 | struct device *dev; |
107 | enum lp872x_id chipid; | 107 | enum lp872x_id chipid; |
108 | struct lp872x_platform_data *pdata; | 108 | struct lp872x_platform_data *pdata; |
109 | struct regulator_dev **regulators; | ||
110 | int num_regulators; | 109 | int num_regulators; |
111 | enum lp872x_dvs_state dvs_pin; | 110 | enum lp872x_dvs_state dvs_pin; |
112 | int dvs_gpio; | 111 | int dvs_gpio; |
@@ -801,8 +800,6 @@ static int lp872x_regulator_register(struct lp872x *lp) | |||
801 | dev_err(lp->dev, "regulator register err"); | 800 | dev_err(lp->dev, "regulator register err"); |
802 | return PTR_ERR(rdev); | 801 | return PTR_ERR(rdev); |
803 | } | 802 | } |
804 | |||
805 | *(lp->regulators + i) = rdev; | ||
806 | } | 803 | } |
807 | 804 | ||
808 | return 0; | 805 | return 0; |
@@ -906,7 +903,7 @@ static struct lp872x_platform_data | |||
906 | static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) | 903 | static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
907 | { | 904 | { |
908 | struct lp872x *lp; | 905 | struct lp872x *lp; |
909 | int ret, size, num_regulators; | 906 | int ret; |
910 | const int lp872x_num_regulators[] = { | 907 | const int lp872x_num_regulators[] = { |
911 | [LP8720] = LP8720_NUM_REGULATORS, | 908 | [LP8720] = LP8720_NUM_REGULATORS, |
912 | [LP8725] = LP8725_NUM_REGULATORS, | 909 | [LP8725] = LP8725_NUM_REGULATORS, |
@@ -918,38 +915,27 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) | |||
918 | 915 | ||
919 | lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); | 916 | lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); |
920 | if (!lp) | 917 | if (!lp) |
921 | goto err_mem; | 918 | return -ENOMEM; |
922 | |||
923 | num_regulators = lp872x_num_regulators[id->driver_data]; | ||
924 | size = sizeof(struct regulator_dev *) * num_regulators; | ||
925 | 919 | ||
926 | lp->regulators = devm_kzalloc(&cl->dev, size, GFP_KERNEL); | 920 | lp->num_regulators = lp872x_num_regulators[id->driver_data]; |
927 | if (!lp->regulators) | ||
928 | goto err_mem; | ||
929 | 921 | ||
930 | lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); | 922 | lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); |
931 | if (IS_ERR(lp->regmap)) { | 923 | if (IS_ERR(lp->regmap)) { |
932 | ret = PTR_ERR(lp->regmap); | 924 | ret = PTR_ERR(lp->regmap); |
933 | dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); | 925 | dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); |
934 | goto err_dev; | 926 | return ret; |
935 | } | 927 | } |
936 | 928 | ||
937 | lp->dev = &cl->dev; | 929 | lp->dev = &cl->dev; |
938 | lp->pdata = dev_get_platdata(&cl->dev); | 930 | lp->pdata = dev_get_platdata(&cl->dev); |
939 | lp->chipid = id->driver_data; | 931 | lp->chipid = id->driver_data; |
940 | lp->num_regulators = num_regulators; | ||
941 | i2c_set_clientdata(cl, lp); | 932 | i2c_set_clientdata(cl, lp); |
942 | 933 | ||
943 | ret = lp872x_config(lp); | 934 | ret = lp872x_config(lp); |
944 | if (ret) | 935 | if (ret) |
945 | goto err_dev; | 936 | return ret; |
946 | 937 | ||
947 | return lp872x_regulator_register(lp); | 938 | return lp872x_regulator_register(lp); |
948 | |||
949 | err_mem: | ||
950 | return -ENOMEM; | ||
951 | err_dev: | ||
952 | return ret; | ||
953 | } | 939 | } |
954 | 940 | ||
955 | static const struct of_device_id lp872x_dt_ids[] = { | 941 | static const struct of_device_id lp872x_dt_ids[] = { |
diff --git a/drivers/regulator/max14577.c b/drivers/regulator/max14577.c index bf9a44c5fdd2..b3678d289619 100644 --- a/drivers/regulator/max14577.c +++ b/drivers/regulator/max14577.c | |||
@@ -103,6 +103,8 @@ static struct regulator_ops max14577_charger_ops = { | |||
103 | static const struct regulator_desc max14577_supported_regulators[] = { | 103 | static const struct regulator_desc max14577_supported_regulators[] = { |
104 | [MAX14577_SAFEOUT] = { | 104 | [MAX14577_SAFEOUT] = { |
105 | .name = "SAFEOUT", | 105 | .name = "SAFEOUT", |
106 | .of_match = of_match_ptr("SAFEOUT"), | ||
107 | .regulators_node = of_match_ptr("regulators"), | ||
106 | .id = MAX14577_SAFEOUT, | 108 | .id = MAX14577_SAFEOUT, |
107 | .ops = &max14577_safeout_ops, | 109 | .ops = &max14577_safeout_ops, |
108 | .type = REGULATOR_VOLTAGE, | 110 | .type = REGULATOR_VOLTAGE, |
@@ -114,6 +116,8 @@ static const struct regulator_desc max14577_supported_regulators[] = { | |||
114 | }, | 116 | }, |
115 | [MAX14577_CHARGER] = { | 117 | [MAX14577_CHARGER] = { |
116 | .name = "CHARGER", | 118 | .name = "CHARGER", |
119 | .of_match = of_match_ptr("CHARGER"), | ||
120 | .regulators_node = of_match_ptr("regulators"), | ||
117 | .id = MAX14577_CHARGER, | 121 | .id = MAX14577_CHARGER, |
118 | .ops = &max14577_charger_ops, | 122 | .ops = &max14577_charger_ops, |
119 | .type = REGULATOR_CURRENT, | 123 | .type = REGULATOR_CURRENT, |
@@ -137,6 +141,8 @@ static struct regulator_ops max77836_ldo_ops = { | |||
137 | static const struct regulator_desc max77836_supported_regulators[] = { | 141 | static const struct regulator_desc max77836_supported_regulators[] = { |
138 | [MAX14577_SAFEOUT] = { | 142 | [MAX14577_SAFEOUT] = { |
139 | .name = "SAFEOUT", | 143 | .name = "SAFEOUT", |
144 | .of_match = of_match_ptr("SAFEOUT"), | ||
145 | .regulators_node = of_match_ptr("regulators"), | ||
140 | .id = MAX14577_SAFEOUT, | 146 | .id = MAX14577_SAFEOUT, |
141 | .ops = &max14577_safeout_ops, | 147 | .ops = &max14577_safeout_ops, |
142 | .type = REGULATOR_VOLTAGE, | 148 | .type = REGULATOR_VOLTAGE, |
@@ -148,6 +154,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { | |||
148 | }, | 154 | }, |
149 | [MAX14577_CHARGER] = { | 155 | [MAX14577_CHARGER] = { |
150 | .name = "CHARGER", | 156 | .name = "CHARGER", |
157 | .of_match = of_match_ptr("CHARGER"), | ||
158 | .regulators_node = of_match_ptr("regulators"), | ||
151 | .id = MAX14577_CHARGER, | 159 | .id = MAX14577_CHARGER, |
152 | .ops = &max14577_charger_ops, | 160 | .ops = &max14577_charger_ops, |
153 | .type = REGULATOR_CURRENT, | 161 | .type = REGULATOR_CURRENT, |
@@ -157,6 +165,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { | |||
157 | }, | 165 | }, |
158 | [MAX77836_LDO1] = { | 166 | [MAX77836_LDO1] = { |
159 | .name = "LDO1", | 167 | .name = "LDO1", |
168 | .of_match = of_match_ptr("LDO1"), | ||
169 | .regulators_node = of_match_ptr("regulators"), | ||
160 | .id = MAX77836_LDO1, | 170 | .id = MAX77836_LDO1, |
161 | .ops = &max77836_ldo_ops, | 171 | .ops = &max77836_ldo_ops, |
162 | .type = REGULATOR_VOLTAGE, | 172 | .type = REGULATOR_VOLTAGE, |
@@ -171,6 +181,8 @@ static const struct regulator_desc max77836_supported_regulators[] = { | |||
171 | }, | 181 | }, |
172 | [MAX77836_LDO2] = { | 182 | [MAX77836_LDO2] = { |
173 | .name = "LDO2", | 183 | .name = "LDO2", |
184 | .of_match = of_match_ptr("LDO2"), | ||
185 | .regulators_node = of_match_ptr("regulators"), | ||
174 | .id = MAX77836_LDO2, | 186 | .id = MAX77836_LDO2, |
175 | .ops = &max77836_ldo_ops, | 187 | .ops = &max77836_ldo_ops, |
176 | .type = REGULATOR_VOLTAGE, | 188 | .type = REGULATOR_VOLTAGE, |
@@ -198,43 +210,6 @@ static struct of_regulator_match max77836_regulator_matches[] = { | |||
198 | { .name = "LDO2", }, | 210 | { .name = "LDO2", }, |
199 | }; | 211 | }; |
200 | 212 | ||
201 | static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev, | ||
202 | enum maxim_device_type dev_type) | ||
203 | { | ||
204 | int ret; | ||
205 | struct device_node *np; | ||
206 | struct of_regulator_match *regulator_matches; | ||
207 | unsigned int regulator_matches_size; | ||
208 | |||
209 | np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); | ||
210 | if (!np) { | ||
211 | dev_err(&pdev->dev, "Failed to get child OF node for regulators\n"); | ||
212 | return -EINVAL; | ||
213 | } | ||
214 | |||
215 | switch (dev_type) { | ||
216 | case MAXIM_DEVICE_TYPE_MAX77836: | ||
217 | regulator_matches = max77836_regulator_matches; | ||
218 | regulator_matches_size = ARRAY_SIZE(max77836_regulator_matches); | ||
219 | break; | ||
220 | case MAXIM_DEVICE_TYPE_MAX14577: | ||
221 | default: | ||
222 | regulator_matches = max14577_regulator_matches; | ||
223 | regulator_matches_size = ARRAY_SIZE(max14577_regulator_matches); | ||
224 | } | ||
225 | |||
226 | ret = of_regulator_match(&pdev->dev, np, regulator_matches, | ||
227 | regulator_matches_size); | ||
228 | if (ret < 0) | ||
229 | dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret); | ||
230 | else | ||
231 | ret = 0; | ||
232 | |||
233 | of_node_put(np); | ||
234 | |||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | static inline struct regulator_init_data *match_init_data(int index, | 213 | static inline struct regulator_init_data *match_init_data(int index, |
239 | enum maxim_device_type dev_type) | 214 | enum maxim_device_type dev_type) |
240 | { | 215 | { |
@@ -261,11 +236,6 @@ static inline struct device_node *match_of_node(int index, | |||
261 | } | 236 | } |
262 | } | 237 | } |
263 | #else /* CONFIG_OF */ | 238 | #else /* CONFIG_OF */ |
264 | static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev, | ||
265 | enum maxim_device_type dev_type) | ||
266 | { | ||
267 | return 0; | ||
268 | } | ||
269 | static inline struct regulator_init_data *match_init_data(int index, | 239 | static inline struct regulator_init_data *match_init_data(int index, |
270 | enum maxim_device_type dev_type) | 240 | enum maxim_device_type dev_type) |
271 | { | 241 | { |
@@ -308,16 +278,12 @@ static int max14577_regulator_probe(struct platform_device *pdev) | |||
308 | { | 278 | { |
309 | struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent); | 279 | struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent); |
310 | struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev); | 280 | struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev); |
311 | int i, ret; | 281 | int i, ret = 0; |
312 | struct regulator_config config = {}; | 282 | struct regulator_config config = {}; |
313 | const struct regulator_desc *supported_regulators; | 283 | const struct regulator_desc *supported_regulators; |
314 | unsigned int supported_regulators_size; | 284 | unsigned int supported_regulators_size; |
315 | enum maxim_device_type dev_type = max14577->dev_type; | 285 | enum maxim_device_type dev_type = max14577->dev_type; |
316 | 286 | ||
317 | ret = max14577_regulator_dt_parse_pdata(pdev, dev_type); | ||
318 | if (ret) | ||
319 | return ret; | ||
320 | |||
321 | switch (dev_type) { | 287 | switch (dev_type) { |
322 | case MAXIM_DEVICE_TYPE_MAX77836: | 288 | case MAXIM_DEVICE_TYPE_MAX77836: |
323 | supported_regulators = max77836_supported_regulators; | 289 | supported_regulators = max77836_supported_regulators; |
@@ -329,7 +295,7 @@ static int max14577_regulator_probe(struct platform_device *pdev) | |||
329 | supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators); | 295 | supported_regulators_size = ARRAY_SIZE(max14577_supported_regulators); |
330 | } | 296 | } |
331 | 297 | ||
332 | config.dev = &pdev->dev; | 298 | config.dev = max14577->dev; |
333 | config.driver_data = max14577; | 299 | config.driver_data = max14577; |
334 | 300 | ||
335 | for (i = 0; i < supported_regulators_size; i++) { | 301 | for (i = 0; i < supported_regulators_size; i++) { |
diff --git a/drivers/regulator/max77686.c b/drivers/regulator/max77686.c index 10d206266ac2..15fb1416bfbd 100644 --- a/drivers/regulator/max77686.c +++ b/drivers/regulator/max77686.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/bug.h> | 26 | #include <linux/bug.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/of_gpio.h> | ||
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
30 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
31 | #include <linux/regulator/driver.h> | 32 | #include <linux/regulator/driver.h> |
@@ -46,6 +47,11 @@ | |||
46 | #define MAX77686_DVS_UVSTEP 12500 | 47 | #define MAX77686_DVS_UVSTEP 12500 |
47 | 48 | ||
48 | /* | 49 | /* |
50 | * Value for configuring buck[89] and LDO{20,21,22} as GPIO control. | ||
51 | * It is the same as 'off' for other regulators. | ||
52 | */ | ||
53 | #define MAX77686_GPIO_CONTROL 0x0 | ||
54 | /* | ||
49 | * Values used for configuring LDOs and bucks. | 55 | * Values used for configuring LDOs and bucks. |
50 | * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26 | 56 | * Forcing low power mode: LDO1, 3-5, 9, 13, 17-26 |
51 | */ | 57 | */ |
@@ -82,6 +88,8 @@ enum max77686_ramp_rate { | |||
82 | }; | 88 | }; |
83 | 89 | ||
84 | struct max77686_data { | 90 | struct max77686_data { |
91 | u64 gpio_enabled:MAX77686_REGULATORS; | ||
92 | |||
85 | /* Array indexed by regulator id */ | 93 | /* Array indexed by regulator id */ |
86 | unsigned int opmode[MAX77686_REGULATORS]; | 94 | unsigned int opmode[MAX77686_REGULATORS]; |
87 | }; | 95 | }; |
@@ -100,6 +108,26 @@ static unsigned int max77686_get_opmode_shift(int id) | |||
100 | } | 108 | } |
101 | } | 109 | } |
102 | 110 | ||
111 | /* | ||
112 | * When regulator is configured for GPIO control then it | ||
113 | * replaces "normal" mode. Any change from low power mode to normal | ||
114 | * should actually change to GPIO control. | ||
115 | * Map normal mode to proper value for such regulators. | ||
116 | */ | ||
117 | static unsigned int max77686_map_normal_mode(struct max77686_data *max77686, | ||
118 | int id) | ||
119 | { | ||
120 | switch (id) { | ||
121 | case MAX77686_BUCK8: | ||
122 | case MAX77686_BUCK9: | ||
123 | case MAX77686_LDO20 ... MAX77686_LDO22: | ||
124 | if (max77686->gpio_enabled & (1 << id)) | ||
125 | return MAX77686_GPIO_CONTROL; | ||
126 | } | ||
127 | |||
128 | return MAX77686_NORMAL; | ||
129 | } | ||
130 | |||
103 | /* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */ | 131 | /* Some BUCKs and LDOs supports Normal[ON/OFF] mode during suspend */ |
104 | static int max77686_set_suspend_disable(struct regulator_dev *rdev) | 132 | static int max77686_set_suspend_disable(struct regulator_dev *rdev) |
105 | { | 133 | { |
@@ -136,7 +164,7 @@ static int max77686_set_suspend_mode(struct regulator_dev *rdev, | |||
136 | val = MAX77686_LDO_LOWPOWER_PWRREQ; | 164 | val = MAX77686_LDO_LOWPOWER_PWRREQ; |
137 | break; | 165 | break; |
138 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 166 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ |
139 | val = MAX77686_NORMAL; | 167 | val = max77686_map_normal_mode(max77686, id); |
140 | break; | 168 | break; |
141 | default: | 169 | default: |
142 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | 170 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", |
@@ -160,7 +188,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
160 | { | 188 | { |
161 | unsigned int val; | 189 | unsigned int val; |
162 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); | 190 | struct max77686_data *max77686 = rdev_get_drvdata(rdev); |
163 | int ret; | 191 | int ret, id = rdev_get_id(rdev); |
164 | 192 | ||
165 | switch (mode) { | 193 | switch (mode) { |
166 | case REGULATOR_MODE_STANDBY: /* switch off */ | 194 | case REGULATOR_MODE_STANDBY: /* switch off */ |
@@ -170,7 +198,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
170 | val = MAX77686_LDO_LOWPOWER_PWRREQ; | 198 | val = MAX77686_LDO_LOWPOWER_PWRREQ; |
171 | break; | 199 | break; |
172 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ | 200 | case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ |
173 | val = MAX77686_NORMAL; | 201 | val = max77686_map_normal_mode(max77686, id); |
174 | break; | 202 | break; |
175 | default: | 203 | default: |
176 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", | 204 | pr_warn("%s: regulator_suspend_mode : 0x%x not supported\n", |
@@ -184,7 +212,7 @@ static int max77686_ldo_set_suspend_mode(struct regulator_dev *rdev, | |||
184 | if (ret) | 212 | if (ret) |
185 | return ret; | 213 | return ret; |
186 | 214 | ||
187 | max77686->opmode[rdev_get_id(rdev)] = val; | 215 | max77686->opmode[id] = val; |
188 | return 0; | 216 | return 0; |
189 | } | 217 | } |
190 | 218 | ||
@@ -197,7 +225,7 @@ static int max77686_enable(struct regulator_dev *rdev) | |||
197 | shift = max77686_get_opmode_shift(id); | 225 | shift = max77686_get_opmode_shift(id); |
198 | 226 | ||
199 | if (max77686->opmode[id] == MAX77686_OFF_PWRREQ) | 227 | if (max77686->opmode[id] == MAX77686_OFF_PWRREQ) |
200 | max77686->opmode[id] = MAX77686_NORMAL; | 228 | max77686->opmode[id] = max77686_map_normal_mode(max77686, id); |
201 | 229 | ||
202 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 230 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
203 | rdev->desc->enable_mask, | 231 | rdev->desc->enable_mask, |
@@ -229,6 +257,36 @@ static int max77686_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | |||
229 | MAX77686_RAMP_RATE_MASK, ramp_value << 6); | 257 | MAX77686_RAMP_RATE_MASK, ramp_value << 6); |
230 | } | 258 | } |
231 | 259 | ||
260 | static int max77686_of_parse_cb(struct device_node *np, | ||
261 | const struct regulator_desc *desc, | ||
262 | struct regulator_config *config) | ||
263 | { | ||
264 | struct max77686_data *max77686 = config->driver_data; | ||
265 | |||
266 | switch (desc->id) { | ||
267 | case MAX77686_BUCK8: | ||
268 | case MAX77686_BUCK9: | ||
269 | case MAX77686_LDO20 ... MAX77686_LDO22: | ||
270 | config->ena_gpio = of_get_named_gpio(np, | ||
271 | "maxim,ena-gpios", 0); | ||
272 | config->ena_gpio_flags = GPIOF_OUT_INIT_HIGH; | ||
273 | config->ena_gpio_initialized = true; | ||
274 | break; | ||
275 | default: | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | if (gpio_is_valid(config->ena_gpio)) { | ||
280 | max77686->gpio_enabled |= (1 << desc->id); | ||
281 | |||
282 | return regmap_update_bits(config->regmap, desc->enable_reg, | ||
283 | desc->enable_mask, | ||
284 | MAX77686_GPIO_CONTROL); | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
232 | static struct regulator_ops max77686_ops = { | 290 | static struct regulator_ops max77686_ops = { |
233 | .list_voltage = regulator_list_voltage_linear, | 291 | .list_voltage = regulator_list_voltage_linear, |
234 | .map_voltage = regulator_map_voltage_linear, | 292 | .map_voltage = regulator_map_voltage_linear, |
@@ -283,6 +341,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
283 | .name = "LDO"#num, \ | 341 | .name = "LDO"#num, \ |
284 | .of_match = of_match_ptr("LDO"#num), \ | 342 | .of_match = of_match_ptr("LDO"#num), \ |
285 | .regulators_node = of_match_ptr("voltage-regulators"), \ | 343 | .regulators_node = of_match_ptr("voltage-regulators"), \ |
344 | .of_parse_cb = max77686_of_parse_cb, \ | ||
286 | .id = MAX77686_LDO##num, \ | 345 | .id = MAX77686_LDO##num, \ |
287 | .ops = &max77686_ops, \ | 346 | .ops = &max77686_ops, \ |
288 | .type = REGULATOR_VOLTAGE, \ | 347 | .type = REGULATOR_VOLTAGE, \ |
@@ -355,6 +414,7 @@ static struct regulator_ops max77686_buck_dvs_ops = { | |||
355 | .name = "BUCK"#num, \ | 414 | .name = "BUCK"#num, \ |
356 | .of_match = of_match_ptr("BUCK"#num), \ | 415 | .of_match = of_match_ptr("BUCK"#num), \ |
357 | .regulators_node = of_match_ptr("voltage-regulators"), \ | 416 | .regulators_node = of_match_ptr("voltage-regulators"), \ |
417 | .of_parse_cb = max77686_of_parse_cb, \ | ||
358 | .id = MAX77686_BUCK##num, \ | 418 | .id = MAX77686_BUCK##num, \ |
359 | .ops = &max77686_ops, \ | 419 | .ops = &max77686_ops, \ |
360 | .type = REGULATOR_VOLTAGE, \ | 420 | .type = REGULATOR_VOLTAGE, \ |
diff --git a/drivers/regulator/max77843.c b/drivers/regulator/max77843.c new file mode 100644 index 000000000000..c132ef527cdd --- /dev/null +++ b/drivers/regulator/max77843.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * max77843.c - Regulator driver for the Maxim MAX77843 | ||
3 | * | ||
4 | * Copyright (C) 2015 Samsung Electronics | ||
5 | * Author: Jaewon Kim <jaewon02.kim@samsung.com> | ||
6 | * Author: Beomho Seo <beomho.seo@samsung.com> | ||
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/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/regulator/driver.h> | ||
17 | #include <linux/regulator/machine.h> | ||
18 | #include <linux/mfd/max77843-private.h> | ||
19 | #include <linux/regulator/of_regulator.h> | ||
20 | |||
21 | enum max77843_regulator_type { | ||
22 | MAX77843_SAFEOUT1 = 0, | ||
23 | MAX77843_SAFEOUT2, | ||
24 | MAX77843_CHARGER, | ||
25 | |||
26 | MAX77843_NUM, | ||
27 | }; | ||
28 | |||
29 | static const unsigned int max77843_safeout_voltage_table[] = { | ||
30 | 4850000, | ||
31 | 4900000, | ||
32 | 4950000, | ||
33 | 3300000, | ||
34 | }; | ||
35 | |||
36 | static int max77843_reg_is_enabled(struct regulator_dev *rdev) | ||
37 | { | ||
38 | struct regmap *regmap = rdev->regmap; | ||
39 | int ret; | ||
40 | unsigned int reg; | ||
41 | |||
42 | ret = regmap_read(regmap, rdev->desc->enable_reg, ®); | ||
43 | if (ret) { | ||
44 | dev_err(&rdev->dev, "Fialed to read charger register\n"); | ||
45 | return ret; | ||
46 | } | ||
47 | |||
48 | return (reg & rdev->desc->enable_mask) == rdev->desc->enable_mask; | ||
49 | } | ||
50 | |||
51 | static int max77843_reg_get_current_limit(struct regulator_dev *rdev) | ||
52 | { | ||
53 | struct regmap *regmap = rdev->regmap; | ||
54 | unsigned int chg_min_uA = rdev->constraints->min_uA; | ||
55 | unsigned int chg_max_uA = rdev->constraints->max_uA; | ||
56 | unsigned int val; | ||
57 | int ret; | ||
58 | unsigned int reg, sel; | ||
59 | |||
60 | ret = regmap_read(regmap, MAX77843_CHG_REG_CHG_CNFG_02, ®); | ||
61 | if (ret) { | ||
62 | dev_err(&rdev->dev, "Failed to read charger register\n"); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | sel = reg & MAX77843_CHG_FAST_CHG_CURRENT_MASK; | ||
67 | |||
68 | if (sel < 0x03) | ||
69 | sel = 0; | ||
70 | else | ||
71 | sel -= 2; | ||
72 | |||
73 | val = chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel; | ||
74 | if (val > chg_max_uA) | ||
75 | return -EINVAL; | ||
76 | |||
77 | return val; | ||
78 | } | ||
79 | |||
80 | static int max77843_reg_set_current_limit(struct regulator_dev *rdev, | ||
81 | int min_uA, int max_uA) | ||
82 | { | ||
83 | struct regmap *regmap = rdev->regmap; | ||
84 | unsigned int chg_min_uA = rdev->constraints->min_uA; | ||
85 | int sel = 0; | ||
86 | |||
87 | while (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel < min_uA) | ||
88 | sel++; | ||
89 | |||
90 | if (chg_min_uA + MAX77843_CHG_FAST_CHG_CURRENT_STEP * sel > max_uA) | ||
91 | return -EINVAL; | ||
92 | |||
93 | sel += 2; | ||
94 | |||
95 | return regmap_write(regmap, MAX77843_CHG_REG_CHG_CNFG_02, sel); | ||
96 | } | ||
97 | |||
98 | static struct regulator_ops max77843_charger_ops = { | ||
99 | .is_enabled = max77843_reg_is_enabled, | ||
100 | .enable = regulator_enable_regmap, | ||
101 | .disable = regulator_disable_regmap, | ||
102 | .get_current_limit = max77843_reg_get_current_limit, | ||
103 | .set_current_limit = max77843_reg_set_current_limit, | ||
104 | }; | ||
105 | |||
106 | static struct regulator_ops max77843_regulator_ops = { | ||
107 | .is_enabled = regulator_is_enabled_regmap, | ||
108 | .enable = regulator_enable_regmap, | ||
109 | .disable = regulator_disable_regmap, | ||
110 | .list_voltage = regulator_list_voltage_table, | ||
111 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
112 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
113 | }; | ||
114 | |||
115 | static const struct regulator_desc max77843_supported_regulators[] = { | ||
116 | [MAX77843_SAFEOUT1] = { | ||
117 | .name = "SAFEOUT1", | ||
118 | .id = MAX77843_SAFEOUT1, | ||
119 | .ops = &max77843_regulator_ops, | ||
120 | .of_match = of_match_ptr("SAFEOUT1"), | ||
121 | .regulators_node = of_match_ptr("regulators"), | ||
122 | .type = REGULATOR_VOLTAGE, | ||
123 | .owner = THIS_MODULE, | ||
124 | .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table), | ||
125 | .volt_table = max77843_safeout_voltage_table, | ||
126 | .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, | ||
127 | .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT1, | ||
128 | .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, | ||
129 | .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT1_MASK, | ||
130 | }, | ||
131 | [MAX77843_SAFEOUT2] = { | ||
132 | .name = "SAFEOUT2", | ||
133 | .id = MAX77843_SAFEOUT2, | ||
134 | .ops = &max77843_regulator_ops, | ||
135 | .of_match = of_match_ptr("SAFEOUT2"), | ||
136 | .regulators_node = of_match_ptr("regulators"), | ||
137 | .type = REGULATOR_VOLTAGE, | ||
138 | .owner = THIS_MODULE, | ||
139 | .n_voltages = ARRAY_SIZE(max77843_safeout_voltage_table), | ||
140 | .volt_table = max77843_safeout_voltage_table, | ||
141 | .enable_reg = MAX77843_SYS_REG_SAFEOUTCTRL, | ||
142 | .enable_mask = MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT2, | ||
143 | .vsel_reg = MAX77843_SYS_REG_SAFEOUTCTRL, | ||
144 | .vsel_mask = MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK, | ||
145 | }, | ||
146 | [MAX77843_CHARGER] = { | ||
147 | .name = "CHARGER", | ||
148 | .id = MAX77843_CHARGER, | ||
149 | .ops = &max77843_charger_ops, | ||
150 | .of_match = of_match_ptr("CHARGER"), | ||
151 | .regulators_node = of_match_ptr("regulators"), | ||
152 | .type = REGULATOR_CURRENT, | ||
153 | .owner = THIS_MODULE, | ||
154 | .enable_reg = MAX77843_CHG_REG_CHG_CNFG_00, | ||
155 | .enable_mask = MAX77843_CHG_MASK, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | static struct regmap *max77843_get_regmap(struct max77843 *max77843, int reg_id) | ||
160 | { | ||
161 | switch (reg_id) { | ||
162 | case MAX77843_SAFEOUT1: | ||
163 | case MAX77843_SAFEOUT2: | ||
164 | return max77843->regmap; | ||
165 | case MAX77843_CHARGER: | ||
166 | return max77843->regmap_chg; | ||
167 | default: | ||
168 | return max77843->regmap; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | static int max77843_regulator_probe(struct platform_device *pdev) | ||
173 | { | ||
174 | struct max77843 *max77843 = dev_get_drvdata(pdev->dev.parent); | ||
175 | struct regulator_config config = {}; | ||
176 | int i; | ||
177 | |||
178 | config.dev = max77843->dev; | ||
179 | config.driver_data = max77843; | ||
180 | |||
181 | for (i = 0; i < ARRAY_SIZE(max77843_supported_regulators); i++) { | ||
182 | struct regulator_dev *regulator; | ||
183 | |||
184 | config.regmap = max77843_get_regmap(max77843, | ||
185 | max77843_supported_regulators[i].id); | ||
186 | |||
187 | regulator = devm_regulator_register(&pdev->dev, | ||
188 | &max77843_supported_regulators[i], &config); | ||
189 | if (IS_ERR(regulator)) { | ||
190 | dev_err(&pdev->dev, | ||
191 | "Failed to regiser regulator-%d\n", i); | ||
192 | return PTR_ERR(regulator); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static const struct platform_device_id max77843_regulator_id[] = { | ||
200 | { "max77843-regulator", }, | ||
201 | { /* sentinel */ }, | ||
202 | }; | ||
203 | |||
204 | static struct platform_driver max77843_regulator_driver = { | ||
205 | .driver = { | ||
206 | .name = "max77843-regulator", | ||
207 | }, | ||
208 | .probe = max77843_regulator_probe, | ||
209 | .id_table = max77843_regulator_id, | ||
210 | }; | ||
211 | |||
212 | static int __init max77843_regulator_init(void) | ||
213 | { | ||
214 | return platform_driver_register(&max77843_regulator_driver); | ||
215 | } | ||
216 | subsys_initcall(max77843_regulator_init); | ||
217 | |||
218 | static void __exit max77843_regulator_exit(void) | ||
219 | { | ||
220 | platform_driver_unregister(&max77843_regulator_driver); | ||
221 | } | ||
222 | module_exit(max77843_regulator_exit); | ||
223 | |||
224 | MODULE_AUTHOR("Jaewon Kim <jaewon02.kim@samsung.com>"); | ||
225 | MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>"); | ||
226 | MODULE_DESCRIPTION("Maxim MAX77843 regulator driver"); | ||
227 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index c8bddcc8f911..81229579ece9 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c | |||
@@ -115,7 +115,7 @@ static unsigned int max8649_get_mode(struct regulator_dev *rdev) | |||
115 | return REGULATOR_MODE_NORMAL; | 115 | return REGULATOR_MODE_NORMAL; |
116 | } | 116 | } |
117 | 117 | ||
118 | static struct regulator_ops max8649_dcdc_ops = { | 118 | static const struct regulator_ops max8649_dcdc_ops = { |
119 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | 119 | .set_voltage_sel = regulator_set_voltage_sel_regmap, |
120 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | 120 | .get_voltage_sel = regulator_get_voltage_sel_regmap, |
121 | .list_voltage = regulator_list_voltage_linear, | 121 | .list_voltage = regulator_list_voltage_linear, |
@@ -143,7 +143,7 @@ static struct regulator_desc dcdc_desc = { | |||
143 | .enable_is_inverted = true, | 143 | .enable_is_inverted = true, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static struct regmap_config max8649_regmap_config = { | 146 | static const struct regmap_config max8649_regmap_config = { |
147 | .reg_bits = 8, | 147 | .reg_bits = 8, |
148 | .val_bits = 8, | 148 | .val_bits = 8, |
149 | }; | 149 | }; |
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 91eaaf010524..24e812c48d93 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c | |||
@@ -270,6 +270,7 @@ EXPORT_SYMBOL_GPL(of_regulator_match); | |||
270 | 270 | ||
271 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | 271 | struct regulator_init_data *regulator_of_get_init_data(struct device *dev, |
272 | const struct regulator_desc *desc, | 272 | const struct regulator_desc *desc, |
273 | struct regulator_config *config, | ||
273 | struct device_node **node) | 274 | struct device_node **node) |
274 | { | 275 | { |
275 | struct device_node *search, *child; | 276 | struct device_node *search, *child; |
@@ -307,6 +308,16 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev, | |||
307 | break; | 308 | break; |
308 | } | 309 | } |
309 | 310 | ||
311 | if (desc->of_parse_cb) { | ||
312 | if (desc->of_parse_cb(child, desc, config)) { | ||
313 | dev_err(dev, | ||
314 | "driver callback failed to parse DT for regulator %s\n", | ||
315 | child->name); | ||
316 | init_data = NULL; | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
310 | of_node_get(child); | 321 | of_node_get(child); |
311 | *node = child; | 322 | *node = child; |
312 | break; | 323 | break; |
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index c879dff597ee..8cc8d1877c44 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #define PFUZE100_VGEN5VOL 0x70 | 56 | #define PFUZE100_VGEN5VOL 0x70 |
57 | #define PFUZE100_VGEN6VOL 0x71 | 57 | #define PFUZE100_VGEN6VOL 0x71 |
58 | 58 | ||
59 | enum chips { PFUZE100, PFUZE200 }; | 59 | enum chips { PFUZE100, PFUZE200, PFUZE3000 = 3 }; |
60 | 60 | ||
61 | struct pfuze_regulator { | 61 | struct pfuze_regulator { |
62 | struct regulator_desc desc; | 62 | struct regulator_desc desc; |
@@ -80,9 +80,18 @@ static const int pfuze100_vsnvs[] = { | |||
80 | 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, | 80 | 1000000, 1100000, 1200000, 1300000, 1500000, 1800000, 3000000, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static const int pfuze3000_sw2lo[] = { | ||
84 | 1500000, 1550000, 1600000, 1650000, 1700000, 1750000, 1800000, 1850000, | ||
85 | }; | ||
86 | |||
87 | static const int pfuze3000_sw2hi[] = { | ||
88 | 2500000, 2800000, 2850000, 3000000, 3100000, 3150000, 3200000, 3300000, | ||
89 | }; | ||
90 | |||
83 | static const struct i2c_device_id pfuze_device_id[] = { | 91 | static const struct i2c_device_id pfuze_device_id[] = { |
84 | {.name = "pfuze100", .driver_data = PFUZE100}, | 92 | {.name = "pfuze100", .driver_data = PFUZE100}, |
85 | {.name = "pfuze200", .driver_data = PFUZE200}, | 93 | {.name = "pfuze200", .driver_data = PFUZE200}, |
94 | {.name = "pfuze3000", .driver_data = PFUZE3000}, | ||
86 | { } | 95 | { } |
87 | }; | 96 | }; |
88 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | 97 | MODULE_DEVICE_TABLE(i2c, pfuze_device_id); |
@@ -90,6 +99,7 @@ MODULE_DEVICE_TABLE(i2c, pfuze_device_id); | |||
90 | static const struct of_device_id pfuze_dt_ids[] = { | 99 | static const struct of_device_id pfuze_dt_ids[] = { |
91 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, | 100 | { .compatible = "fsl,pfuze100", .data = (void *)PFUZE100}, |
92 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, | 101 | { .compatible = "fsl,pfuze200", .data = (void *)PFUZE200}, |
102 | { .compatible = "fsl,pfuze3000", .data = (void *)PFUZE3000}, | ||
93 | { } | 103 | { } |
94 | }; | 104 | }; |
95 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); | 105 | MODULE_DEVICE_TABLE(of, pfuze_dt_ids); |
@@ -219,6 +229,60 @@ static struct regulator_ops pfuze100_swb_regulator_ops = { | |||
219 | .stby_mask = 0x20, \ | 229 | .stby_mask = 0x20, \ |
220 | } | 230 | } |
221 | 231 | ||
232 | #define PFUZE3000_VCC_REG(_chip, _name, base, min, max, step) { \ | ||
233 | .desc = { \ | ||
234 | .name = #_name, \ | ||
235 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
236 | .ops = &pfuze100_ldo_regulator_ops, \ | ||
237 | .type = REGULATOR_VOLTAGE, \ | ||
238 | .id = _chip ## _ ## _name, \ | ||
239 | .owner = THIS_MODULE, \ | ||
240 | .min_uV = (min), \ | ||
241 | .uV_step = (step), \ | ||
242 | .vsel_reg = (base), \ | ||
243 | .vsel_mask = 0x3, \ | ||
244 | .enable_reg = (base), \ | ||
245 | .enable_mask = 0x10, \ | ||
246 | }, \ | ||
247 | .stby_reg = (base), \ | ||
248 | .stby_mask = 0x20, \ | ||
249 | } | ||
250 | |||
251 | |||
252 | #define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \ | ||
253 | .desc = { \ | ||
254 | .name = #_name,\ | ||
255 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
256 | .ops = &pfuze100_sw_regulator_ops, \ | ||
257 | .type = REGULATOR_VOLTAGE, \ | ||
258 | .id = _chip ## _ ## _name, \ | ||
259 | .owner = THIS_MODULE, \ | ||
260 | .min_uV = (min), \ | ||
261 | .uV_step = (step), \ | ||
262 | .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | ||
263 | .vsel_mask = 0x7, \ | ||
264 | }, \ | ||
265 | .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | ||
266 | .stby_mask = 0x7, \ | ||
267 | } | ||
268 | |||
269 | #define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \ | ||
270 | .desc = { \ | ||
271 | .name = #_name,\ | ||
272 | .n_voltages = ((max) - (min)) / (step) + 1, \ | ||
273 | .ops = &pfuze100_sw_regulator_ops, \ | ||
274 | .type = REGULATOR_VOLTAGE, \ | ||
275 | .id = _chip ## _ ## _name, \ | ||
276 | .owner = THIS_MODULE, \ | ||
277 | .min_uV = (min), \ | ||
278 | .uV_step = (step), \ | ||
279 | .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ | ||
280 | .vsel_mask = 0xf, \ | ||
281 | }, \ | ||
282 | .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ | ||
283 | .stby_mask = 0xf, \ | ||
284 | } | ||
285 | |||
222 | /* PFUZE100 */ | 286 | /* PFUZE100 */ |
223 | static struct pfuze_regulator pfuze100_regulators[] = { | 287 | static struct pfuze_regulator pfuze100_regulators[] = { |
224 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), | 288 | PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), |
@@ -254,6 +318,22 @@ static struct pfuze_regulator pfuze200_regulators[] = { | |||
254 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | 318 | PFUZE100_VGEN_REG(PFUZE200, VGEN6, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), |
255 | }; | 319 | }; |
256 | 320 | ||
321 | static struct pfuze_regulator pfuze3000_regulators[] = { | ||
322 | PFUZE100_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 700000, 1475000, 25000), | ||
323 | PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), | ||
324 | PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), | ||
325 | PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), | ||
326 | PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst), | ||
327 | PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), | ||
328 | PFUZE100_FIXED_REG(PFUZE3000, VREFDDR, PFUZE100_VREFDDRCON, 750000), | ||
329 | PFUZE100_VGEN_REG(PFUZE3000, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), | ||
330 | PFUZE100_VGEN_REG(PFUZE3000, VLDO2, PFUZE100_VGEN2VOL, 800000, 1550000, 50000), | ||
331 | PFUZE3000_VCC_REG(PFUZE3000, VCCSD, PFUZE100_VGEN3VOL, 2850000, 3300000, 150000), | ||
332 | PFUZE3000_VCC_REG(PFUZE3000, V33, PFUZE100_VGEN4VOL, 2850000, 3300000, 150000), | ||
333 | PFUZE100_VGEN_REG(PFUZE3000, VLDO3, PFUZE100_VGEN5VOL, 1800000, 3300000, 100000), | ||
334 | PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), | ||
335 | }; | ||
336 | |||
257 | static struct pfuze_regulator *pfuze_regulators; | 337 | static struct pfuze_regulator *pfuze_regulators; |
258 | 338 | ||
259 | #ifdef CONFIG_OF | 339 | #ifdef CONFIG_OF |
@@ -294,6 +374,24 @@ static struct of_regulator_match pfuze200_matches[] = { | |||
294 | { .name = "vgen6", }, | 374 | { .name = "vgen6", }, |
295 | }; | 375 | }; |
296 | 376 | ||
377 | /* PFUZE3000 */ | ||
378 | static struct of_regulator_match pfuze3000_matches[] = { | ||
379 | |||
380 | { .name = "sw1a", }, | ||
381 | { .name = "sw1b", }, | ||
382 | { .name = "sw2", }, | ||
383 | { .name = "sw3", }, | ||
384 | { .name = "swbst", }, | ||
385 | { .name = "vsnvs", }, | ||
386 | { .name = "vrefddr", }, | ||
387 | { .name = "vldo1", }, | ||
388 | { .name = "vldo2", }, | ||
389 | { .name = "vccsd", }, | ||
390 | { .name = "v33", }, | ||
391 | { .name = "vldo3", }, | ||
392 | { .name = "vldo4", }, | ||
393 | }; | ||
394 | |||
297 | static struct of_regulator_match *pfuze_matches; | 395 | static struct of_regulator_match *pfuze_matches; |
298 | 396 | ||
299 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | 397 | static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) |
@@ -313,6 +411,11 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) | |||
313 | } | 411 | } |
314 | 412 | ||
315 | switch (chip->chip_id) { | 413 | switch (chip->chip_id) { |
414 | case PFUZE3000: | ||
415 | pfuze_matches = pfuze3000_matches; | ||
416 | ret = of_regulator_match(dev, parent, pfuze3000_matches, | ||
417 | ARRAY_SIZE(pfuze3000_matches)); | ||
418 | break; | ||
316 | case PFUZE200: | 419 | case PFUZE200: |
317 | pfuze_matches = pfuze200_matches; | 420 | pfuze_matches = pfuze200_matches; |
318 | ret = of_regulator_match(dev, parent, pfuze200_matches, | 421 | ret = of_regulator_match(dev, parent, pfuze200_matches, |
@@ -378,7 +481,8 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip) | |||
378 | * as ID=8 in PFUZE100 | 481 | * as ID=8 in PFUZE100 |
379 | */ | 482 | */ |
380 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); | 483 | dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); |
381 | } else if ((value & 0x0f) != pfuze_chip->chip_id) { | 484 | } else if ((value & 0x0f) != pfuze_chip->chip_id && |
485 | (value & 0xf0) >> 4 != pfuze_chip->chip_id) { | ||
382 | /* device id NOT match with your setting */ | 486 | /* device id NOT match with your setting */ |
383 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); | 487 | dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); |
384 | return -ENODEV; | 488 | return -ENODEV; |
@@ -417,7 +521,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
417 | int i, ret; | 521 | int i, ret; |
418 | const struct of_device_id *match; | 522 | const struct of_device_id *match; |
419 | u32 regulator_num; | 523 | u32 regulator_num; |
420 | u32 sw_check_start, sw_check_end; | 524 | u32 sw_check_start, sw_check_end, sw_hi = 0x40; |
421 | 525 | ||
422 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), | 526 | pfuze_chip = devm_kzalloc(&client->dev, sizeof(*pfuze_chip), |
423 | GFP_KERNEL); | 527 | GFP_KERNEL); |
@@ -458,13 +562,19 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
458 | 562 | ||
459 | /* use the right regulators after identify the right device */ | 563 | /* use the right regulators after identify the right device */ |
460 | switch (pfuze_chip->chip_id) { | 564 | switch (pfuze_chip->chip_id) { |
565 | case PFUZE3000: | ||
566 | pfuze_regulators = pfuze3000_regulators; | ||
567 | regulator_num = ARRAY_SIZE(pfuze3000_regulators); | ||
568 | sw_check_start = PFUZE3000_SW2; | ||
569 | sw_check_end = PFUZE3000_SW2; | ||
570 | sw_hi = 1 << 3; | ||
571 | break; | ||
461 | case PFUZE200: | 572 | case PFUZE200: |
462 | pfuze_regulators = pfuze200_regulators; | 573 | pfuze_regulators = pfuze200_regulators; |
463 | regulator_num = ARRAY_SIZE(pfuze200_regulators); | 574 | regulator_num = ARRAY_SIZE(pfuze200_regulators); |
464 | sw_check_start = PFUZE200_SW2; | 575 | sw_check_start = PFUZE200_SW2; |
465 | sw_check_end = PFUZE200_SW3B; | 576 | sw_check_end = PFUZE200_SW3B; |
466 | break; | 577 | break; |
467 | |||
468 | case PFUZE100: | 578 | case PFUZE100: |
469 | default: | 579 | default: |
470 | pfuze_regulators = pfuze100_regulators; | 580 | pfuze_regulators = pfuze100_regulators; |
@@ -474,7 +584,8 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
474 | break; | 584 | break; |
475 | } | 585 | } |
476 | dev_info(&client->dev, "pfuze%s found.\n", | 586 | dev_info(&client->dev, "pfuze%s found.\n", |
477 | (pfuze_chip->chip_id == PFUZE100) ? "100" : "200"); | 587 | (pfuze_chip->chip_id == PFUZE100) ? "100" : |
588 | ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000")); | ||
478 | 589 | ||
479 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, | 590 | memcpy(pfuze_chip->regulator_descs, pfuze_regulators, |
480 | sizeof(pfuze_chip->regulator_descs)); | 591 | sizeof(pfuze_chip->regulator_descs)); |
@@ -498,10 +609,15 @@ static int pfuze100_regulator_probe(struct i2c_client *client, | |||
498 | /* SW2~SW4 high bit check and modify the voltage value table */ | 609 | /* SW2~SW4 high bit check and modify the voltage value table */ |
499 | if (i >= sw_check_start && i <= sw_check_end) { | 610 | if (i >= sw_check_start && i <= sw_check_end) { |
500 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); | 611 | regmap_read(pfuze_chip->regmap, desc->vsel_reg, &val); |
501 | if (val & 0x40) { | 612 | if (val & sw_hi) { |
502 | desc->min_uV = 800000; | 613 | if (pfuze_chip->chip_id == PFUZE3000) { |
503 | desc->uV_step = 50000; | 614 | desc->volt_table = pfuze3000_sw2hi; |
504 | desc->n_voltages = 51; | 615 | desc->n_voltages = ARRAY_SIZE(pfuze3000_sw2hi); |
616 | } else { | ||
617 | desc->min_uV = 800000; | ||
618 | desc->uV_step = 50000; | ||
619 | desc->n_voltages = 51; | ||
620 | } | ||
505 | } | 621 | } |
506 | } | 622 | } |
507 | 623 | ||
diff --git a/drivers/regulator/qcom_rpm-regulator.c b/drivers/regulator/qcom_rpm-regulator.c index 8364ff331a81..7678944f83f6 100644 --- a/drivers/regulator/qcom_rpm-regulator.c +++ b/drivers/regulator/qcom_rpm-regulator.c | |||
@@ -674,6 +674,7 @@ static int rpm_reg_probe(struct platform_device *pdev) | |||
674 | vreg->desc.owner = THIS_MODULE; | 674 | vreg->desc.owner = THIS_MODULE; |
675 | vreg->desc.type = REGULATOR_VOLTAGE; | 675 | vreg->desc.type = REGULATOR_VOLTAGE; |
676 | vreg->desc.name = pdev->dev.of_node->name; | 676 | vreg->desc.name = pdev->dev.of_node->name; |
677 | vreg->desc.supply_name = "vin"; | ||
677 | 678 | ||
678 | vreg->rpm = dev_get_drvdata(pdev->dev.parent); | 679 | vreg->rpm = dev_get_drvdata(pdev->dev.parent); |
679 | if (!vreg->rpm) { | 680 | if (!vreg->rpm) { |
@@ -768,7 +769,7 @@ static int rpm_reg_probe(struct platform_device *pdev) | |||
768 | break; | 769 | break; |
769 | } | 770 | } |
770 | 771 | ||
771 | if (force_mode < 0) { | 772 | if (force_mode == -1) { |
772 | dev_err(&pdev->dev, "invalid force mode\n"); | 773 | dev_err(&pdev->dev, "invalid force mode\n"); |
773 | return -EINVAL; | 774 | return -EINVAL; |
774 | } | 775 | } |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index c1444c3d84c2..ff828117798f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -405,6 +405,40 @@ static struct regulator_ops s2mps14_reg_ops; | |||
405 | .enable_mask = S2MPS14_ENABLE_MASK \ | 405 | .enable_mask = S2MPS14_ENABLE_MASK \ |
406 | } | 406 | } |
407 | 407 | ||
408 | #define regulator_desc_s2mps13_buck7(num, min, step, min_sel) { \ | ||
409 | .name = "BUCK"#num, \ | ||
410 | .id = S2MPS13_BUCK##num, \ | ||
411 | .ops = &s2mps14_reg_ops, \ | ||
412 | .type = REGULATOR_VOLTAGE, \ | ||
413 | .owner = THIS_MODULE, \ | ||
414 | .min_uV = min, \ | ||
415 | .uV_step = step, \ | ||
416 | .linear_min_sel = min_sel, \ | ||
417 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
418 | .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ | ||
419 | .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ | ||
420 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
421 | .enable_reg = S2MPS13_REG_B1CTRL + (num - 1) * 2, \ | ||
422 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
423 | } | ||
424 | |||
425 | #define regulator_desc_s2mps13_buck8_10(num, min, step, min_sel) { \ | ||
426 | .name = "BUCK"#num, \ | ||
427 | .id = S2MPS13_BUCK##num, \ | ||
428 | .ops = &s2mps14_reg_ops, \ | ||
429 | .type = REGULATOR_VOLTAGE, \ | ||
430 | .owner = THIS_MODULE, \ | ||
431 | .min_uV = min, \ | ||
432 | .uV_step = step, \ | ||
433 | .linear_min_sel = min_sel, \ | ||
434 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | ||
435 | .ramp_delay = S2MPS13_BUCK_RAMP_DELAY, \ | ||
436 | .vsel_reg = S2MPS13_REG_B1OUT + (num) * 2 - 1, \ | ||
437 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | ||
438 | .enable_reg = S2MPS13_REG_B1CTRL + (num) * 2 - 1, \ | ||
439 | .enable_mask = S2MPS14_ENABLE_MASK \ | ||
440 | } | ||
441 | |||
408 | static const struct regulator_desc s2mps13_regulators[] = { | 442 | static const struct regulator_desc s2mps13_regulators[] = { |
409 | regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), | 443 | regulator_desc_s2mps13_ldo(1, MIN_800_MV, STEP_12_5_MV, 0x00), |
410 | regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), | 444 | regulator_desc_s2mps13_ldo(2, MIN_1400_MV, STEP_50_MV, 0x0C), |
@@ -452,10 +486,10 @@ static const struct regulator_desc s2mps13_regulators[] = { | |||
452 | regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), | 486 | regulator_desc_s2mps13_buck(4, MIN_500_MV, STEP_6_25_MV, 0x10), |
453 | regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), | 487 | regulator_desc_s2mps13_buck(5, MIN_500_MV, STEP_6_25_MV, 0x10), |
454 | regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), | 488 | regulator_desc_s2mps13_buck(6, MIN_500_MV, STEP_6_25_MV, 0x10), |
455 | regulator_desc_s2mps13_buck(7, MIN_500_MV, STEP_6_25_MV, 0x10), | 489 | regulator_desc_s2mps13_buck7(7, MIN_500_MV, STEP_6_25_MV, 0x10), |
456 | regulator_desc_s2mps13_buck(8, MIN_1000_MV, STEP_12_5_MV, 0x20), | 490 | regulator_desc_s2mps13_buck8_10(8, MIN_1000_MV, STEP_12_5_MV, 0x20), |
457 | regulator_desc_s2mps13_buck(9, MIN_1000_MV, STEP_12_5_MV, 0x20), | 491 | regulator_desc_s2mps13_buck8_10(9, MIN_1000_MV, STEP_12_5_MV, 0x20), |
458 | regulator_desc_s2mps13_buck(10, MIN_500_MV, STEP_6_25_MV, 0x10), | 492 | regulator_desc_s2mps13_buck8_10(10, MIN_500_MV, STEP_6_25_MV, 0x10), |
459 | }; | 493 | }; |
460 | 494 | ||
461 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) | 495 | static int s2mps14_regulator_enable(struct regulator_dev *rdev) |
@@ -570,7 +604,7 @@ static struct regulator_ops s2mps14_reg_ops = { | |||
570 | .enable_mask = S2MPS14_ENABLE_MASK \ | 604 | .enable_mask = S2MPS14_ENABLE_MASK \ |
571 | } | 605 | } |
572 | 606 | ||
573 | #define regulator_desc_s2mps14_buck(num, min, step) { \ | 607 | #define regulator_desc_s2mps14_buck(num, min, step, min_sel) { \ |
574 | .name = "BUCK"#num, \ | 608 | .name = "BUCK"#num, \ |
575 | .id = S2MPS14_BUCK##num, \ | 609 | .id = S2MPS14_BUCK##num, \ |
576 | .ops = &s2mps14_reg_ops, \ | 610 | .ops = &s2mps14_reg_ops, \ |
@@ -579,7 +613,7 @@ static struct regulator_ops s2mps14_reg_ops = { | |||
579 | .min_uV = min, \ | 613 | .min_uV = min, \ |
580 | .uV_step = step, \ | 614 | .uV_step = step, \ |
581 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ | 615 | .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ |
582 | .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ | 616 | .linear_min_sel = min_sel, \ |
583 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ | 617 | .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ |
584 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ | 618 | .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ |
585 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ | 619 | .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ |
@@ -613,11 +647,16 @@ static const struct regulator_desc s2mps14_regulators[] = { | |||
613 | regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), | 647 | regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), |
614 | regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), | 648 | regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), |
615 | regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), | 649 | regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), |
616 | regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV), | 650 | regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV, |
617 | regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV), | 651 | S2MPS14_BUCK1235_START_SEL), |
618 | regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV), | 652 | regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV, |
619 | regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV), | 653 | S2MPS14_BUCK1235_START_SEL), |
620 | regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV), | 654 | regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV, |
655 | S2MPS14_BUCK1235_START_SEL), | ||
656 | regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV, | ||
657 | S2MPS14_BUCK4_START_SEL), | ||
658 | regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV, | ||
659 | S2MPS14_BUCK1235_START_SEL), | ||
621 | }; | 660 | }; |
622 | 661 | ||
623 | static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, | 662 | static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, |
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index eebc52cb6984..3d95c87160b3 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c | |||
@@ -102,6 +102,8 @@ static int sunxi_reset_init(struct device_node *np) | |||
102 | goto err_alloc; | 102 | goto err_alloc; |
103 | } | 103 | } |
104 | 104 | ||
105 | spin_lock_init(&data->lock); | ||
106 | |||
105 | data->rcdev.owner = THIS_MODULE; | 107 | data->rcdev.owner = THIS_MODULE; |
106 | data->rcdev.nr_resets = size * 32; | 108 | data->rcdev.nr_resets = size * 32; |
107 | data->rcdev.ops = &sunxi_reset_ops; | 109 | data->rcdev.ops = &sunxi_reset_ops; |
@@ -157,6 +159,8 @@ static int sunxi_reset_probe(struct platform_device *pdev) | |||
157 | if (IS_ERR(data->membase)) | 159 | if (IS_ERR(data->membase)) |
158 | return PTR_ERR(data->membase); | 160 | return PTR_ERR(data->membase); |
159 | 161 | ||
162 | spin_lock_init(&data->lock); | ||
163 | |||
160 | data->rcdev.owner = THIS_MODULE; | 164 | data->rcdev.owner = THIS_MODULE; |
161 | data->rcdev.nr_resets = resource_size(res) * 32; | 165 | data->rcdev.nr_resets = resource_size(res) * 32; |
162 | data->rcdev.ops = &sunxi_reset_ops; | 166 | data->rcdev.ops = &sunxi_reset_ops; |
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index b5e7c4670205..89ac1d5083c6 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c | |||
@@ -832,6 +832,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); | |||
832 | static const struct platform_device_id s5m_rtc_id[] = { | 832 | static const struct platform_device_id s5m_rtc_id[] = { |
833 | { "s5m-rtc", S5M8767X }, | 833 | { "s5m-rtc", S5M8767X }, |
834 | { "s2mps14-rtc", S2MPS14X }, | 834 | { "s2mps14-rtc", S2MPS14X }, |
835 | { }, | ||
835 | }; | 836 | }; |
836 | 837 | ||
837 | static struct platform_driver s5m_rtc_driver = { | 838 | static struct platform_driver s5m_rtc_driver = { |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 91e97ec01418..4d41bf75c233 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -1163,9 +1163,13 @@ static inline int ap_test_config_card_id(unsigned int id) | |||
1163 | */ | 1163 | */ |
1164 | static inline int ap_test_config_domain(unsigned int domain) | 1164 | static inline int ap_test_config_domain(unsigned int domain) |
1165 | { | 1165 | { |
1166 | if (!ap_configuration) | 1166 | if (!ap_configuration) /* QCI not supported */ |
1167 | return 1; | 1167 | if (domain < 16) |
1168 | return ap_test_config(ap_configuration->aqm, domain); | 1168 | return 1; /* then domains 0...15 are configured */ |
1169 | else | ||
1170 | return 0; | ||
1171 | else | ||
1172 | return ap_test_config(ap_configuration->aqm, domain); | ||
1169 | } | 1173 | } |
1170 | 1174 | ||
1171 | /** | 1175 | /** |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index f407e3763432..642c77c76b84 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1784,6 +1784,8 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, | |||
1784 | QETH_DBF_TEXT(SETUP, 2, "idxanswr"); | 1784 | QETH_DBF_TEXT(SETUP, 2, "idxanswr"); |
1785 | card = CARD_FROM_CDEV(channel->ccwdev); | 1785 | card = CARD_FROM_CDEV(channel->ccwdev); |
1786 | iob = qeth_get_buffer(channel); | 1786 | iob = qeth_get_buffer(channel); |
1787 | if (!iob) | ||
1788 | return -ENOMEM; | ||
1787 | iob->callback = idx_reply_cb; | 1789 | iob->callback = idx_reply_cb; |
1788 | memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); | 1790 | memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1)); |
1789 | channel->ccw.count = QETH_BUFSIZE; | 1791 | channel->ccw.count = QETH_BUFSIZE; |
@@ -1834,6 +1836,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, | |||
1834 | QETH_DBF_TEXT(SETUP, 2, "idxactch"); | 1836 | QETH_DBF_TEXT(SETUP, 2, "idxactch"); |
1835 | 1837 | ||
1836 | iob = qeth_get_buffer(channel); | 1838 | iob = qeth_get_buffer(channel); |
1839 | if (!iob) | ||
1840 | return -ENOMEM; | ||
1837 | iob->callback = idx_reply_cb; | 1841 | iob->callback = idx_reply_cb; |
1838 | memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); | 1842 | memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1)); |
1839 | channel->ccw.count = IDX_ACTIVATE_SIZE; | 1843 | channel->ccw.count = IDX_ACTIVATE_SIZE; |
@@ -2021,10 +2025,36 @@ void qeth_prepare_control_data(struct qeth_card *card, int len, | |||
2021 | } | 2025 | } |
2022 | EXPORT_SYMBOL_GPL(qeth_prepare_control_data); | 2026 | EXPORT_SYMBOL_GPL(qeth_prepare_control_data); |
2023 | 2027 | ||
2028 | /** | ||
2029 | * qeth_send_control_data() - send control command to the card | ||
2030 | * @card: qeth_card structure pointer | ||
2031 | * @len: size of the command buffer | ||
2032 | * @iob: qeth_cmd_buffer pointer | ||
2033 | * @reply_cb: callback function pointer | ||
2034 | * @cb_card: pointer to the qeth_card structure | ||
2035 | * @cb_reply: pointer to the qeth_reply structure | ||
2036 | * @cb_cmd: pointer to the original iob for non-IPA | ||
2037 | * commands, or to the qeth_ipa_cmd structure | ||
2038 | * for the IPA commands. | ||
2039 | * @reply_param: private pointer passed to the callback | ||
2040 | * | ||
2041 | * Returns the value of the `return_code' field of the response | ||
2042 | * block returned from the hardware, or other error indication. | ||
2043 | * Value of zero indicates successful execution of the command. | ||
2044 | * | ||
2045 | * Callback function gets called one or more times, with cb_cmd | ||
2046 | * pointing to the response returned by the hardware. Callback | ||
2047 | * function must return non-zero if more reply blocks are expected, | ||
2048 | * and zero if the last or only reply block is received. Callback | ||
2049 | * function can get the value of the reply_param pointer from the | ||
2050 | * field 'param' of the structure qeth_reply. | ||
2051 | */ | ||
2052 | |||
2024 | int qeth_send_control_data(struct qeth_card *card, int len, | 2053 | int qeth_send_control_data(struct qeth_card *card, int len, |
2025 | struct qeth_cmd_buffer *iob, | 2054 | struct qeth_cmd_buffer *iob, |
2026 | int (*reply_cb)(struct qeth_card *, struct qeth_reply *, | 2055 | int (*reply_cb)(struct qeth_card *cb_card, |
2027 | unsigned long), | 2056 | struct qeth_reply *cb_reply, |
2057 | unsigned long cb_cmd), | ||
2028 | void *reply_param) | 2058 | void *reply_param) |
2029 | { | 2059 | { |
2030 | int rc; | 2060 | int rc; |
@@ -2914,9 +2944,16 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, | |||
2914 | struct qeth_cmd_buffer *iob; | 2944 | struct qeth_cmd_buffer *iob; |
2915 | struct qeth_ipa_cmd *cmd; | 2945 | struct qeth_ipa_cmd *cmd; |
2916 | 2946 | ||
2917 | iob = qeth_wait_for_buffer(&card->write); | 2947 | iob = qeth_get_buffer(&card->write); |
2918 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 2948 | if (iob) { |
2919 | qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | 2949 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
2950 | qeth_fill_ipacmd_header(card, cmd, ipacmd, prot); | ||
2951 | } else { | ||
2952 | dev_warn(&card->gdev->dev, | ||
2953 | "The qeth driver ran out of channel command buffers\n"); | ||
2954 | QETH_DBF_MESSAGE(1, "%s The qeth driver ran out of channel command buffers", | ||
2955 | dev_name(&card->gdev->dev)); | ||
2956 | } | ||
2920 | 2957 | ||
2921 | return iob; | 2958 | return iob; |
2922 | } | 2959 | } |
@@ -2932,6 +2969,12 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | |||
2932 | } | 2969 | } |
2933 | EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); | 2970 | EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); |
2934 | 2971 | ||
2972 | /** | ||
2973 | * qeth_send_ipa_cmd() - send an IPA command | ||
2974 | * | ||
2975 | * See qeth_send_control_data() for explanation of the arguments. | ||
2976 | */ | ||
2977 | |||
2935 | int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, | 2978 | int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, |
2936 | int (*reply_cb)(struct qeth_card *, struct qeth_reply*, | 2979 | int (*reply_cb)(struct qeth_card *, struct qeth_reply*, |
2937 | unsigned long), | 2980 | unsigned long), |
@@ -2968,6 +3011,8 @@ int qeth_send_startlan(struct qeth_card *card) | |||
2968 | QETH_DBF_TEXT(SETUP, 2, "strtlan"); | 3011 | QETH_DBF_TEXT(SETUP, 2, "strtlan"); |
2969 | 3012 | ||
2970 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); | 3013 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); |
3014 | if (!iob) | ||
3015 | return -ENOMEM; | ||
2971 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 3016 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
2972 | return rc; | 3017 | return rc; |
2973 | } | 3018 | } |
@@ -3013,11 +3058,13 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, | |||
3013 | 3058 | ||
3014 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, | 3059 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, |
3015 | QETH_PROT_IPV4); | 3060 | QETH_PROT_IPV4); |
3016 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3061 | if (iob) { |
3017 | cmd->data.setadapterparms.hdr.cmdlength = cmdlen; | 3062 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
3018 | cmd->data.setadapterparms.hdr.command_code = command; | 3063 | cmd->data.setadapterparms.hdr.cmdlength = cmdlen; |
3019 | cmd->data.setadapterparms.hdr.used_total = 1; | 3064 | cmd->data.setadapterparms.hdr.command_code = command; |
3020 | cmd->data.setadapterparms.hdr.seq_no = 1; | 3065 | cmd->data.setadapterparms.hdr.used_total = 1; |
3066 | cmd->data.setadapterparms.hdr.seq_no = 1; | ||
3067 | } | ||
3021 | 3068 | ||
3022 | return iob; | 3069 | return iob; |
3023 | } | 3070 | } |
@@ -3030,6 +3077,8 @@ int qeth_query_setadapterparms(struct qeth_card *card) | |||
3030 | QETH_CARD_TEXT(card, 3, "queryadp"); | 3077 | QETH_CARD_TEXT(card, 3, "queryadp"); |
3031 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, | 3078 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, |
3032 | sizeof(struct qeth_ipacmd_setadpparms)); | 3079 | sizeof(struct qeth_ipacmd_setadpparms)); |
3080 | if (!iob) | ||
3081 | return -ENOMEM; | ||
3033 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); | 3082 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); |
3034 | return rc; | 3083 | return rc; |
3035 | } | 3084 | } |
@@ -3080,6 +3129,8 @@ int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot) | |||
3080 | 3129 | ||
3081 | QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); | 3130 | QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); |
3082 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); | 3131 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); |
3132 | if (!iob) | ||
3133 | return -ENOMEM; | ||
3083 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); | 3134 | rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); |
3084 | return rc; | 3135 | return rc; |
3085 | } | 3136 | } |
@@ -3119,6 +3170,8 @@ int qeth_query_switch_attributes(struct qeth_card *card, | |||
3119 | return -ENOMEDIUM; | 3170 | return -ENOMEDIUM; |
3120 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, | 3171 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, |
3121 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); | 3172 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
3173 | if (!iob) | ||
3174 | return -ENOMEM; | ||
3122 | return qeth_send_ipa_cmd(card, iob, | 3175 | return qeth_send_ipa_cmd(card, iob, |
3123 | qeth_query_switch_attributes_cb, sw_info); | 3176 | qeth_query_switch_attributes_cb, sw_info); |
3124 | } | 3177 | } |
@@ -3146,6 +3199,8 @@ static int qeth_query_setdiagass(struct qeth_card *card) | |||
3146 | 3199 | ||
3147 | QETH_DBF_TEXT(SETUP, 2, "qdiagass"); | 3200 | QETH_DBF_TEXT(SETUP, 2, "qdiagass"); |
3148 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 3201 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
3202 | if (!iob) | ||
3203 | return -ENOMEM; | ||
3149 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3204 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
3150 | cmd->data.diagass.subcmd_len = 16; | 3205 | cmd->data.diagass.subcmd_len = 16; |
3151 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; | 3206 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; |
@@ -3197,6 +3252,8 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) | |||
3197 | 3252 | ||
3198 | QETH_DBF_TEXT(SETUP, 2, "diagtrap"); | 3253 | QETH_DBF_TEXT(SETUP, 2, "diagtrap"); |
3199 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 3254 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
3255 | if (!iob) | ||
3256 | return -ENOMEM; | ||
3200 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 3257 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
3201 | cmd->data.diagass.subcmd_len = 80; | 3258 | cmd->data.diagass.subcmd_len = 80; |
3202 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; | 3259 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; |
@@ -4162,6 +4219,8 @@ void qeth_setadp_promisc_mode(struct qeth_card *card) | |||
4162 | 4219 | ||
4163 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, | 4220 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, |
4164 | sizeof(struct qeth_ipacmd_setadpparms)); | 4221 | sizeof(struct qeth_ipacmd_setadpparms)); |
4222 | if (!iob) | ||
4223 | return; | ||
4165 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); | 4224 | cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); |
4166 | cmd->data.setadapterparms.data.mode = mode; | 4225 | cmd->data.setadapterparms.data.mode = mode; |
4167 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); | 4226 | qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL); |
@@ -4232,6 +4291,8 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) | |||
4232 | 4291 | ||
4233 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, | 4292 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, |
4234 | sizeof(struct qeth_ipacmd_setadpparms)); | 4293 | sizeof(struct qeth_ipacmd_setadpparms)); |
4294 | if (!iob) | ||
4295 | return -ENOMEM; | ||
4235 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4296 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
4236 | cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; | 4297 | cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; |
4237 | cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; | 4298 | cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; |
@@ -4345,6 +4406,8 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, | |||
4345 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, | 4406 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, |
4346 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + | 4407 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
4347 | sizeof(struct qeth_set_access_ctrl)); | 4408 | sizeof(struct qeth_set_access_ctrl)); |
4409 | if (!iob) | ||
4410 | return -ENOMEM; | ||
4348 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4411 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
4349 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; | 4412 | access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; |
4350 | access_ctrl_req->subcmd_code = isolation; | 4413 | access_ctrl_req->subcmd_code = isolation; |
@@ -4588,6 +4651,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
4588 | 4651 | ||
4589 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, | 4652 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, |
4590 | QETH_SNMP_SETADP_CMDLENGTH + req_len); | 4653 | QETH_SNMP_SETADP_CMDLENGTH + req_len); |
4654 | if (!iob) { | ||
4655 | rc = -ENOMEM; | ||
4656 | goto out; | ||
4657 | } | ||
4591 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4658 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
4592 | memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); | 4659 | memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); |
4593 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, | 4660 | rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, |
@@ -4599,7 +4666,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) | |||
4599 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) | 4666 | if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) |
4600 | rc = -EFAULT; | 4667 | rc = -EFAULT; |
4601 | } | 4668 | } |
4602 | 4669 | out: | |
4603 | kfree(ureq); | 4670 | kfree(ureq); |
4604 | kfree(qinfo.udata); | 4671 | kfree(qinfo.udata); |
4605 | return rc; | 4672 | return rc; |
@@ -4670,6 +4737,10 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata) | |||
4670 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, | 4737 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, |
4671 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + | 4738 | sizeof(struct qeth_ipacmd_setadpparms_hdr) + |
4672 | sizeof(struct qeth_query_oat)); | 4739 | sizeof(struct qeth_query_oat)); |
4740 | if (!iob) { | ||
4741 | rc = -ENOMEM; | ||
4742 | goto out_free; | ||
4743 | } | ||
4673 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 4744 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
4674 | oat_req = &cmd->data.setadapterparms.data.query_oat; | 4745 | oat_req = &cmd->data.setadapterparms.data.query_oat; |
4675 | oat_req->subcmd_code = oat_data.command; | 4746 | oat_req->subcmd_code = oat_data.command; |
@@ -4735,6 +4806,8 @@ static int qeth_query_card_info(struct qeth_card *card, | |||
4735 | return -EOPNOTSUPP; | 4806 | return -EOPNOTSUPP; |
4736 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, | 4807 | iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, |
4737 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); | 4808 | sizeof(struct qeth_ipacmd_setadpparms_hdr)); |
4809 | if (!iob) | ||
4810 | return -ENOMEM; | ||
4738 | return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, | 4811 | return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, |
4739 | (void *)carrier_info); | 4812 | (void *)carrier_info); |
4740 | } | 4813 | } |
@@ -5060,11 +5133,23 @@ retriable: | |||
5060 | card->options.adp.supported_funcs = 0; | 5133 | card->options.adp.supported_funcs = 0; |
5061 | card->options.sbp.supported_funcs = 0; | 5134 | card->options.sbp.supported_funcs = 0; |
5062 | card->info.diagass_support = 0; | 5135 | card->info.diagass_support = 0; |
5063 | qeth_query_ipassists(card, QETH_PROT_IPV4); | 5136 | rc = qeth_query_ipassists(card, QETH_PROT_IPV4); |
5064 | if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) | 5137 | if (rc == -ENOMEM) |
5065 | qeth_query_setadapterparms(card); | 5138 | goto out; |
5066 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) | 5139 | if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { |
5067 | qeth_query_setdiagass(card); | 5140 | rc = qeth_query_setadapterparms(card); |
5141 | if (rc < 0) { | ||
5142 | QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); | ||
5143 | goto out; | ||
5144 | } | ||
5145 | } | ||
5146 | if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { | ||
5147 | rc = qeth_query_setdiagass(card); | ||
5148 | if (rc < 0) { | ||
5149 | QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); | ||
5150 | goto out; | ||
5151 | } | ||
5152 | } | ||
5068 | return 0; | 5153 | return 0; |
5069 | out: | 5154 | out: |
5070 | dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " | 5155 | dev_warn(&card->gdev->dev, "The qeth device driver failed to recover " |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index d02cd1a67943..ce87ae72edbd 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -27,10 +27,7 @@ static int qeth_l2_set_offline(struct ccwgroup_device *); | |||
27 | static int qeth_l2_stop(struct net_device *); | 27 | static int qeth_l2_stop(struct net_device *); |
28 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); | 28 | static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); |
29 | static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, | 29 | static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *, |
30 | enum qeth_ipa_cmds, | 30 | enum qeth_ipa_cmds); |
31 | int (*reply_cb) (struct qeth_card *, | ||
32 | struct qeth_reply*, | ||
33 | unsigned long)); | ||
34 | static void qeth_l2_set_multicast_list(struct net_device *); | 31 | static void qeth_l2_set_multicast_list(struct net_device *); |
35 | static int qeth_l2_recover(void *); | 32 | static int qeth_l2_recover(void *); |
36 | static void qeth_bridgeport_query_support(struct qeth_card *card); | 33 | static void qeth_bridgeport_query_support(struct qeth_card *card); |
@@ -130,56 +127,71 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) | |||
130 | return ndev; | 127 | return ndev; |
131 | } | 128 | } |
132 | 129 | ||
133 | static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, | 130 | static int qeth_setdel_makerc(struct qeth_card *card, int retcode) |
134 | struct qeth_reply *reply, | ||
135 | unsigned long data) | ||
136 | { | 131 | { |
137 | struct qeth_ipa_cmd *cmd; | 132 | int rc; |
138 | __u8 *mac; | ||
139 | 133 | ||
140 | QETH_CARD_TEXT(card, 2, "L2Sgmacb"); | 134 | if (retcode) |
141 | cmd = (struct qeth_ipa_cmd *) data; | 135 | QETH_CARD_TEXT_(card, 2, "err%04x", retcode); |
142 | mac = &cmd->data.setdelmac.mac[0]; | 136 | switch (retcode) { |
143 | /* MAC already registered, needed in couple/uncouple case */ | 137 | case IPA_RC_SUCCESS: |
144 | if (cmd->hdr.return_code == IPA_RC_L2_DUP_MAC) { | 138 | rc = 0; |
145 | QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n", | 139 | break; |
146 | mac, QETH_CARD_IFNAME(card)); | 140 | case IPA_RC_L2_UNSUPPORTED_CMD: |
147 | cmd->hdr.return_code = 0; | 141 | rc = -ENOSYS; |
142 | break; | ||
143 | case IPA_RC_L2_ADDR_TABLE_FULL: | ||
144 | rc = -ENOSPC; | ||
145 | break; | ||
146 | case IPA_RC_L2_DUP_MAC: | ||
147 | case IPA_RC_L2_DUP_LAYER3_MAC: | ||
148 | rc = -EEXIST; | ||
149 | break; | ||
150 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | ||
151 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | ||
152 | rc = -EPERM; | ||
153 | break; | ||
154 | case IPA_RC_L2_MAC_NOT_FOUND: | ||
155 | rc = -ENOENT; | ||
156 | break; | ||
157 | case -ENOMEM: | ||
158 | rc = -ENOMEM; | ||
159 | break; | ||
160 | default: | ||
161 | rc = -EIO; | ||
162 | break; | ||
148 | } | 163 | } |
149 | if (cmd->hdr.return_code) | 164 | return rc; |
150 | QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %x\n", | ||
151 | mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | ||
152 | return 0; | ||
153 | } | 165 | } |
154 | 166 | ||
155 | static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) | 167 | static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) |
156 | { | 168 | { |
157 | QETH_CARD_TEXT(card, 2, "L2Sgmac"); | 169 | int rc; |
158 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC, | ||
159 | qeth_l2_send_setgroupmac_cb); | ||
160 | } | ||
161 | |||
162 | static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, | ||
163 | struct qeth_reply *reply, | ||
164 | unsigned long data) | ||
165 | { | ||
166 | struct qeth_ipa_cmd *cmd; | ||
167 | __u8 *mac; | ||
168 | 170 | ||
169 | QETH_CARD_TEXT(card, 2, "L2Dgmacb"); | 171 | QETH_CARD_TEXT(card, 2, "L2Sgmac"); |
170 | cmd = (struct qeth_ipa_cmd *) data; | 172 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
171 | mac = &cmd->data.setdelmac.mac[0]; | 173 | IPA_CMD_SETGMAC)); |
172 | if (cmd->hdr.return_code) | 174 | if (rc == -EEXIST) |
173 | QETH_DBF_MESSAGE(2, "Could not delete group MAC %pM on %s: %x\n", | 175 | QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", |
174 | mac, QETH_CARD_IFNAME(card), cmd->hdr.return_code); | 176 | mac, QETH_CARD_IFNAME(card)); |
175 | return 0; | 177 | else if (rc) |
178 | QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", | ||
179 | mac, QETH_CARD_IFNAME(card), rc); | ||
180 | return rc; | ||
176 | } | 181 | } |
177 | 182 | ||
178 | static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) | 183 | static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) |
179 | { | 184 | { |
185 | int rc; | ||
186 | |||
180 | QETH_CARD_TEXT(card, 2, "L2Dgmac"); | 187 | QETH_CARD_TEXT(card, 2, "L2Dgmac"); |
181 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC, | 188 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
182 | qeth_l2_send_delgroupmac_cb); | 189 | IPA_CMD_DELGMAC)); |
190 | if (rc) | ||
191 | QETH_DBF_MESSAGE(2, | ||
192 | "Could not delete group MAC %pM on %s: %d\n", | ||
193 | mac, QETH_CARD_IFNAME(card), rc); | ||
194 | return rc; | ||
183 | } | 195 | } |
184 | 196 | ||
185 | static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) | 197 | static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) |
@@ -197,10 +209,11 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac) | |||
197 | mc->is_vmac = vmac; | 209 | mc->is_vmac = vmac; |
198 | 210 | ||
199 | if (vmac) { | 211 | if (vmac) { |
200 | rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | 212 | rc = qeth_setdel_makerc(card, |
201 | NULL); | 213 | qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC)); |
202 | } else { | 214 | } else { |
203 | rc = qeth_l2_send_setgroupmac(card, mac); | 215 | rc = qeth_setdel_makerc(card, |
216 | qeth_l2_send_setgroupmac(card, mac)); | ||
204 | } | 217 | } |
205 | 218 | ||
206 | if (!rc) | 219 | if (!rc) |
@@ -218,7 +231,7 @@ static void qeth_l2_del_all_mc(struct qeth_card *card, int del) | |||
218 | if (del) { | 231 | if (del) { |
219 | if (mc->is_vmac) | 232 | if (mc->is_vmac) |
220 | qeth_l2_send_setdelmac(card, mc->mc_addr, | 233 | qeth_l2_send_setdelmac(card, mc->mc_addr, |
221 | IPA_CMD_DELVMAC, NULL); | 234 | IPA_CMD_DELVMAC); |
222 | else | 235 | else |
223 | qeth_l2_send_delgroupmac(card, mc->mc_addr); | 236 | qeth_l2_send_delgroupmac(card, mc->mc_addr); |
224 | } | 237 | } |
@@ -291,6 +304,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, | |||
291 | 304 | ||
292 | QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); | 305 | QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); |
293 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 306 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
307 | if (!iob) | ||
308 | return -ENOMEM; | ||
294 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 309 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
295 | cmd->data.setdelvlan.vlan_id = i; | 310 | cmd->data.setdelvlan.vlan_id = i; |
296 | return qeth_send_ipa_cmd(card, iob, | 311 | return qeth_send_ipa_cmd(card, iob, |
@@ -313,6 +328,7 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, | |||
313 | { | 328 | { |
314 | struct qeth_card *card = dev->ml_priv; | 329 | struct qeth_card *card = dev->ml_priv; |
315 | struct qeth_vlan_vid *id; | 330 | struct qeth_vlan_vid *id; |
331 | int rc; | ||
316 | 332 | ||
317 | QETH_CARD_TEXT_(card, 4, "aid:%d", vid); | 333 | QETH_CARD_TEXT_(card, 4, "aid:%d", vid); |
318 | if (!vid) | 334 | if (!vid) |
@@ -328,7 +344,11 @@ static int qeth_l2_vlan_rx_add_vid(struct net_device *dev, | |||
328 | id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); | 344 | id = kmalloc(sizeof(struct qeth_vlan_vid), GFP_ATOMIC); |
329 | if (id) { | 345 | if (id) { |
330 | id->vid = vid; | 346 | id->vid = vid; |
331 | qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); | 347 | rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN); |
348 | if (rc) { | ||
349 | kfree(id); | ||
350 | return rc; | ||
351 | } | ||
332 | spin_lock_bh(&card->vlanlock); | 352 | spin_lock_bh(&card->vlanlock); |
333 | list_add_tail(&id->list, &card->vid_list); | 353 | list_add_tail(&id->list, &card->vid_list); |
334 | spin_unlock_bh(&card->vlanlock); | 354 | spin_unlock_bh(&card->vlanlock); |
@@ -343,6 +363,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, | |||
343 | { | 363 | { |
344 | struct qeth_vlan_vid *id, *tmpid = NULL; | 364 | struct qeth_vlan_vid *id, *tmpid = NULL; |
345 | struct qeth_card *card = dev->ml_priv; | 365 | struct qeth_card *card = dev->ml_priv; |
366 | int rc = 0; | ||
346 | 367 | ||
347 | QETH_CARD_TEXT_(card, 4, "kid:%d", vid); | 368 | QETH_CARD_TEXT_(card, 4, "kid:%d", vid); |
348 | if (card->info.type == QETH_CARD_TYPE_OSM) { | 369 | if (card->info.type == QETH_CARD_TYPE_OSM) { |
@@ -363,11 +384,11 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, | |||
363 | } | 384 | } |
364 | spin_unlock_bh(&card->vlanlock); | 385 | spin_unlock_bh(&card->vlanlock); |
365 | if (tmpid) { | 386 | if (tmpid) { |
366 | qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); | 387 | rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); |
367 | kfree(tmpid); | 388 | kfree(tmpid); |
368 | } | 389 | } |
369 | qeth_l2_set_multicast_list(card->dev); | 390 | qeth_l2_set_multicast_list(card->dev); |
370 | return 0; | 391 | return rc; |
371 | } | 392 | } |
372 | 393 | ||
373 | static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) | 394 | static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) |
@@ -539,91 +560,62 @@ out: | |||
539 | } | 560 | } |
540 | 561 | ||
541 | static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, | 562 | static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, |
542 | enum qeth_ipa_cmds ipacmd, | 563 | enum qeth_ipa_cmds ipacmd) |
543 | int (*reply_cb) (struct qeth_card *, | ||
544 | struct qeth_reply*, | ||
545 | unsigned long)) | ||
546 | { | 564 | { |
547 | struct qeth_ipa_cmd *cmd; | 565 | struct qeth_ipa_cmd *cmd; |
548 | struct qeth_cmd_buffer *iob; | 566 | struct qeth_cmd_buffer *iob; |
549 | 567 | ||
550 | QETH_CARD_TEXT(card, 2, "L2sdmac"); | 568 | QETH_CARD_TEXT(card, 2, "L2sdmac"); |
551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); | 569 | iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); |
570 | if (!iob) | ||
571 | return -ENOMEM; | ||
552 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 572 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
553 | cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; | 573 | cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; |
554 | memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); | 574 | memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); |
555 | return qeth_send_ipa_cmd(card, iob, reply_cb, NULL); | 575 | return qeth_send_ipa_cmd(card, iob, NULL, NULL); |
556 | } | 576 | } |
557 | 577 | ||
558 | static int qeth_l2_send_setmac_cb(struct qeth_card *card, | 578 | static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) |
559 | struct qeth_reply *reply, | ||
560 | unsigned long data) | ||
561 | { | 579 | { |
562 | struct qeth_ipa_cmd *cmd; | 580 | int rc; |
563 | 581 | ||
564 | QETH_CARD_TEXT(card, 2, "L2Smaccb"); | 582 | QETH_CARD_TEXT(card, 2, "L2Setmac"); |
565 | cmd = (struct qeth_ipa_cmd *) data; | 583 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
566 | if (cmd->hdr.return_code) { | 584 | IPA_CMD_SETVMAC)); |
567 | QETH_CARD_TEXT_(card, 2, "L2er%x", cmd->hdr.return_code); | 585 | if (rc == 0) { |
586 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | ||
587 | memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); | ||
588 | dev_info(&card->gdev->dev, | ||
589 | "MAC address %pM successfully registered on device %s\n", | ||
590 | card->dev->dev_addr, card->dev->name); | ||
591 | } else { | ||
568 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | 592 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; |
569 | switch (cmd->hdr.return_code) { | 593 | switch (rc) { |
570 | case IPA_RC_L2_DUP_MAC: | 594 | case -EEXIST: |
571 | case IPA_RC_L2_DUP_LAYER3_MAC: | ||
572 | dev_warn(&card->gdev->dev, | 595 | dev_warn(&card->gdev->dev, |
573 | "MAC address %pM already exists\n", | 596 | "MAC address %pM already exists\n", mac); |
574 | cmd->data.setdelmac.mac); | ||
575 | break; | 597 | break; |
576 | case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP: | 598 | case -EPERM: |
577 | case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP: | ||
578 | dev_warn(&card->gdev->dev, | 599 | dev_warn(&card->gdev->dev, |
579 | "MAC address %pM is not authorized\n", | 600 | "MAC address %pM is not authorized\n", mac); |
580 | cmd->data.setdelmac.mac); | ||
581 | break; | ||
582 | default: | ||
583 | break; | 601 | break; |
584 | } | 602 | } |
585 | } else { | ||
586 | card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; | ||
587 | memcpy(card->dev->dev_addr, cmd->data.setdelmac.mac, | ||
588 | OSA_ADDR_LEN); | ||
589 | dev_info(&card->gdev->dev, | ||
590 | "MAC address %pM successfully registered on device %s\n", | ||
591 | card->dev->dev_addr, card->dev->name); | ||
592 | } | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) | ||
597 | { | ||
598 | QETH_CARD_TEXT(card, 2, "L2Setmac"); | ||
599 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC, | ||
600 | qeth_l2_send_setmac_cb); | ||
601 | } | ||
602 | |||
603 | static int qeth_l2_send_delmac_cb(struct qeth_card *card, | ||
604 | struct qeth_reply *reply, | ||
605 | unsigned long data) | ||
606 | { | ||
607 | struct qeth_ipa_cmd *cmd; | ||
608 | |||
609 | QETH_CARD_TEXT(card, 2, "L2Dmaccb"); | ||
610 | cmd = (struct qeth_ipa_cmd *) data; | ||
611 | if (cmd->hdr.return_code) { | ||
612 | QETH_CARD_TEXT_(card, 2, "err%d", cmd->hdr.return_code); | ||
613 | return 0; | ||
614 | } | 603 | } |
615 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | 604 | return rc; |
616 | |||
617 | return 0; | ||
618 | } | 605 | } |
619 | 606 | ||
620 | static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) | 607 | static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) |
621 | { | 608 | { |
609 | int rc; | ||
610 | |||
622 | QETH_CARD_TEXT(card, 2, "L2Delmac"); | 611 | QETH_CARD_TEXT(card, 2, "L2Delmac"); |
623 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) | 612 | if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)) |
624 | return 0; | 613 | return 0; |
625 | return qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC, | 614 | rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac, |
626 | qeth_l2_send_delmac_cb); | 615 | IPA_CMD_DELVMAC)); |
616 | if (rc == 0) | ||
617 | card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; | ||
618 | return rc; | ||
627 | } | 619 | } |
628 | 620 | ||
629 | static int qeth_l2_request_initial_mac(struct qeth_card *card) | 621 | static int qeth_l2_request_initial_mac(struct qeth_card *card) |
@@ -651,7 +643,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) | |||
651 | if (rc) { | 643 | if (rc) { |
652 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " | 644 | QETH_DBF_MESSAGE(2, "couldn't get MAC address on " |
653 | "device %s: x%x\n", CARD_BUS_ID(card), rc); | 645 | "device %s: x%x\n", CARD_BUS_ID(card), rc); |
654 | QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); | 646 | QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc); |
655 | return rc; | 647 | return rc; |
656 | } | 648 | } |
657 | QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); | 649 | QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, OSA_ADDR_LEN); |
@@ -687,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) | |||
687 | return -ERESTARTSYS; | 679 | return -ERESTARTSYS; |
688 | } | 680 | } |
689 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); | 681 | rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); |
690 | if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) | 682 | if (!rc || (rc == -ENOENT)) |
691 | rc = qeth_l2_send_setmac(card, addr->sa_data); | 683 | rc = qeth_l2_send_setmac(card, addr->sa_data); |
692 | return rc ? -EINVAL : 0; | 684 | return rc ? -EINVAL : 0; |
693 | } | 685 | } |
@@ -996,7 +988,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
996 | recover_flag = card->state; | 988 | recover_flag = card->state; |
997 | rc = qeth_core_hardsetup_card(card); | 989 | rc = qeth_core_hardsetup_card(card); |
998 | if (rc) { | 990 | if (rc) { |
999 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 991 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
1000 | rc = -ENODEV; | 992 | rc = -ENODEV; |
1001 | goto out_remove; | 993 | goto out_remove; |
1002 | } | 994 | } |
@@ -1730,6 +1722,8 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) | |||
1730 | 1722 | ||
1731 | QETH_CARD_TEXT(card, 2, "brqsuppo"); | 1723 | QETH_CARD_TEXT(card, 2, "brqsuppo"); |
1732 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1724 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
1725 | if (!iob) | ||
1726 | return; | ||
1733 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1727 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1734 | cmd->data.sbp.hdr.cmdlength = | 1728 | cmd->data.sbp.hdr.cmdlength = |
1735 | sizeof(struct qeth_ipacmd_sbp_hdr) + | 1729 | sizeof(struct qeth_ipacmd_sbp_hdr) + |
@@ -1805,6 +1799,8 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, | |||
1805 | if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) | 1799 | if (!(card->options.sbp.supported_funcs & IPA_SBP_QUERY_BRIDGE_PORTS)) |
1806 | return -EOPNOTSUPP; | 1800 | return -EOPNOTSUPP; |
1807 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1801 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
1802 | if (!iob) | ||
1803 | return -ENOMEM; | ||
1808 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1804 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1809 | cmd->data.sbp.hdr.cmdlength = | 1805 | cmd->data.sbp.hdr.cmdlength = |
1810 | sizeof(struct qeth_ipacmd_sbp_hdr); | 1806 | sizeof(struct qeth_ipacmd_sbp_hdr); |
@@ -1817,9 +1813,7 @@ int qeth_bridgeport_query_ports(struct qeth_card *card, | |||
1817 | if (rc) | 1813 | if (rc) |
1818 | return rc; | 1814 | return rc; |
1819 | rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); | 1815 | rc = qeth_bridgeport_makerc(card, &cbctl, IPA_SBP_QUERY_BRIDGE_PORTS); |
1820 | if (rc) | 1816 | return rc; |
1821 | return rc; | ||
1822 | return 0; | ||
1823 | } | 1817 | } |
1824 | EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); | 1818 | EXPORT_SYMBOL_GPL(qeth_bridgeport_query_ports); |
1825 | 1819 | ||
@@ -1873,6 +1867,8 @@ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) | |||
1873 | if (!(card->options.sbp.supported_funcs & setcmd)) | 1867 | if (!(card->options.sbp.supported_funcs & setcmd)) |
1874 | return -EOPNOTSUPP; | 1868 | return -EOPNOTSUPP; |
1875 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); | 1869 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETBRIDGEPORT, 0); |
1870 | if (!iob) | ||
1871 | return -ENOMEM; | ||
1876 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1872 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1877 | cmd->data.sbp.hdr.cmdlength = cmdlength; | 1873 | cmd->data.sbp.hdr.cmdlength = cmdlength; |
1878 | cmd->data.sbp.hdr.command_code = setcmd; | 1874 | cmd->data.sbp.hdr.command_code = setcmd; |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 625227ad16ee..e2a0ee845399 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -549,6 +549,8 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, | |||
549 | QETH_CARD_TEXT(card, 4, "setdelmc"); | 549 | QETH_CARD_TEXT(card, 4, "setdelmc"); |
550 | 550 | ||
551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); | 551 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
552 | if (!iob) | ||
553 | return -ENOMEM; | ||
552 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 554 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
553 | memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); | 555 | memcpy(&cmd->data.setdelipm.mac, addr->mac, OSA_ADDR_LEN); |
554 | if (addr->proto == QETH_PROT_IPV6) | 556 | if (addr->proto == QETH_PROT_IPV6) |
@@ -588,6 +590,8 @@ static int qeth_l3_send_setdelip(struct qeth_card *card, | |||
588 | QETH_CARD_TEXT_(card, 4, "flags%02X", flags); | 590 | QETH_CARD_TEXT_(card, 4, "flags%02X", flags); |
589 | 591 | ||
590 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); | 592 | iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); |
593 | if (!iob) | ||
594 | return -ENOMEM; | ||
591 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 595 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
592 | if (addr->proto == QETH_PROT_IPV6) { | 596 | if (addr->proto == QETH_PROT_IPV6) { |
593 | memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, | 597 | memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr, |
@@ -616,6 +620,8 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, | |||
616 | 620 | ||
617 | QETH_CARD_TEXT(card, 4, "setroutg"); | 621 | QETH_CARD_TEXT(card, 4, "setroutg"); |
618 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); | 622 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); |
623 | if (!iob) | ||
624 | return -ENOMEM; | ||
619 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 625 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
620 | cmd->data.setrtg.type = (type); | 626 | cmd->data.setrtg.type = (type); |
621 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); | 627 | rc = qeth_send_ipa_cmd(card, iob, NULL, NULL); |
@@ -1049,12 +1055,14 @@ static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd( | |||
1049 | QETH_CARD_TEXT(card, 4, "getasscm"); | 1055 | QETH_CARD_TEXT(card, 4, "getasscm"); |
1050 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); | 1056 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); |
1051 | 1057 | ||
1052 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1058 | if (iob) { |
1053 | cmd->data.setassparms.hdr.assist_no = ipa_func; | 1059 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1054 | cmd->data.setassparms.hdr.length = 8 + len; | 1060 | cmd->data.setassparms.hdr.assist_no = ipa_func; |
1055 | cmd->data.setassparms.hdr.command_code = cmd_code; | 1061 | cmd->data.setassparms.hdr.length = 8 + len; |
1056 | cmd->data.setassparms.hdr.return_code = 0; | 1062 | cmd->data.setassparms.hdr.command_code = cmd_code; |
1057 | cmd->data.setassparms.hdr.seq_no = 0; | 1063 | cmd->data.setassparms.hdr.return_code = 0; |
1064 | cmd->data.setassparms.hdr.seq_no = 0; | ||
1065 | } | ||
1058 | 1066 | ||
1059 | return iob; | 1067 | return iob; |
1060 | } | 1068 | } |
@@ -1090,6 +1098,8 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, | |||
1090 | QETH_CARD_TEXT(card, 4, "simassp6"); | 1098 | QETH_CARD_TEXT(card, 4, "simassp6"); |
1091 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, | 1099 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
1092 | 0, QETH_PROT_IPV6); | 1100 | 0, QETH_PROT_IPV6); |
1101 | if (!iob) | ||
1102 | return -ENOMEM; | ||
1093 | rc = qeth_l3_send_setassparms(card, iob, 0, 0, | 1103 | rc = qeth_l3_send_setassparms(card, iob, 0, 0, |
1094 | qeth_l3_default_setassparms_cb, NULL); | 1104 | qeth_l3_default_setassparms_cb, NULL); |
1095 | return rc; | 1105 | return rc; |
@@ -1108,6 +1118,8 @@ static int qeth_l3_send_simple_setassparms(struct qeth_card *card, | |||
1108 | length = sizeof(__u32); | 1118 | length = sizeof(__u32); |
1109 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, | 1119 | iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, |
1110 | length, QETH_PROT_IPV4); | 1120 | length, QETH_PROT_IPV4); |
1121 | if (!iob) | ||
1122 | return -ENOMEM; | ||
1111 | rc = qeth_l3_send_setassparms(card, iob, length, data, | 1123 | rc = qeth_l3_send_setassparms(card, iob, length, data, |
1112 | qeth_l3_default_setassparms_cb, NULL); | 1124 | qeth_l3_default_setassparms_cb, NULL); |
1113 | return rc; | 1125 | return rc; |
@@ -1494,6 +1506,8 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) | |||
1494 | 1506 | ||
1495 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, | 1507 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
1496 | QETH_PROT_IPV6); | 1508 | QETH_PROT_IPV6); |
1509 | if (!iob) | ||
1510 | return -ENOMEM; | ||
1497 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1511 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1498 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = | 1512 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
1499 | card->info.unique_id; | 1513 | card->info.unique_id; |
@@ -1537,6 +1551,8 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) | |||
1537 | 1551 | ||
1538 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, | 1552 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, |
1539 | QETH_PROT_IPV6); | 1553 | QETH_PROT_IPV6); |
1554 | if (!iob) | ||
1555 | return -ENOMEM; | ||
1540 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1556 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1541 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = | 1557 | *((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) = |
1542 | card->info.unique_id; | 1558 | card->info.unique_id; |
@@ -1611,6 +1627,8 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) | |||
1611 | QETH_DBF_TEXT(SETUP, 2, "diagtrac"); | 1627 | QETH_DBF_TEXT(SETUP, 2, "diagtrac"); |
1612 | 1628 | ||
1613 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); | 1629 | iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); |
1630 | if (!iob) | ||
1631 | return -ENOMEM; | ||
1614 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 1632 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
1615 | cmd->data.diagass.subcmd_len = 16; | 1633 | cmd->data.diagass.subcmd_len = 16; |
1616 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; | 1634 | cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; |
@@ -2442,6 +2460,8 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card, | |||
2442 | IPA_CMD_ASS_ARP_QUERY_INFO, | 2460 | IPA_CMD_ASS_ARP_QUERY_INFO, |
2443 | sizeof(struct qeth_arp_query_data) - sizeof(char), | 2461 | sizeof(struct qeth_arp_query_data) - sizeof(char), |
2444 | prot); | 2462 | prot); |
2463 | if (!iob) | ||
2464 | return -ENOMEM; | ||
2445 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); | 2465 | cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); |
2446 | cmd->data.setassparms.data.query_arp.request_bits = 0x000F; | 2466 | cmd->data.setassparms.data.query_arp.request_bits = 0x000F; |
2447 | cmd->data.setassparms.data.query_arp.reply_bits = 0; | 2467 | cmd->data.setassparms.data.query_arp.reply_bits = 0; |
@@ -2535,6 +2555,8 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, | |||
2535 | IPA_CMD_ASS_ARP_ADD_ENTRY, | 2555 | IPA_CMD_ASS_ARP_ADD_ENTRY, |
2536 | sizeof(struct qeth_arp_cache_entry), | 2556 | sizeof(struct qeth_arp_cache_entry), |
2537 | QETH_PROT_IPV4); | 2557 | QETH_PROT_IPV4); |
2558 | if (!iob) | ||
2559 | return -ENOMEM; | ||
2538 | rc = qeth_l3_send_setassparms(card, iob, | 2560 | rc = qeth_l3_send_setassparms(card, iob, |
2539 | sizeof(struct qeth_arp_cache_entry), | 2561 | sizeof(struct qeth_arp_cache_entry), |
2540 | (unsigned long) entry, | 2562 | (unsigned long) entry, |
@@ -2574,6 +2596,8 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, | |||
2574 | IPA_CMD_ASS_ARP_REMOVE_ENTRY, | 2596 | IPA_CMD_ASS_ARP_REMOVE_ENTRY, |
2575 | 12, | 2597 | 12, |
2576 | QETH_PROT_IPV4); | 2598 | QETH_PROT_IPV4); |
2599 | if (!iob) | ||
2600 | return -ENOMEM; | ||
2577 | rc = qeth_l3_send_setassparms(card, iob, | 2601 | rc = qeth_l3_send_setassparms(card, iob, |
2578 | 12, (unsigned long)buf, | 2602 | 12, (unsigned long)buf, |
2579 | qeth_l3_default_setassparms_cb, NULL); | 2603 | qeth_l3_default_setassparms_cb, NULL); |
@@ -3262,6 +3286,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { | |||
3262 | 3286 | ||
3263 | static int qeth_l3_setup_netdev(struct qeth_card *card) | 3287 | static int qeth_l3_setup_netdev(struct qeth_card *card) |
3264 | { | 3288 | { |
3289 | int rc; | ||
3290 | |||
3265 | if (card->info.type == QETH_CARD_TYPE_OSD || | 3291 | if (card->info.type == QETH_CARD_TYPE_OSD || |
3266 | card->info.type == QETH_CARD_TYPE_OSX) { | 3292 | card->info.type == QETH_CARD_TYPE_OSX) { |
3267 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || | 3293 | if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) || |
@@ -3293,7 +3319,9 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3293 | return -ENODEV; | 3319 | return -ENODEV; |
3294 | card->dev->flags |= IFF_NOARP; | 3320 | card->dev->flags |= IFF_NOARP; |
3295 | card->dev->netdev_ops = &qeth_l3_netdev_ops; | 3321 | card->dev->netdev_ops = &qeth_l3_netdev_ops; |
3296 | qeth_l3_iqd_read_initial_mac(card); | 3322 | rc = qeth_l3_iqd_read_initial_mac(card); |
3323 | if (rc) | ||
3324 | return rc; | ||
3297 | if (card->options.hsuid[0]) | 3325 | if (card->options.hsuid[0]) |
3298 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); | 3326 | memcpy(card->dev->perm_addr, card->options.hsuid, 9); |
3299 | } else | 3327 | } else |
@@ -3360,7 +3388,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3360 | recover_flag = card->state; | 3388 | recover_flag = card->state; |
3361 | rc = qeth_core_hardsetup_card(card); | 3389 | rc = qeth_core_hardsetup_card(card); |
3362 | if (rc) { | 3390 | if (rc) { |
3363 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 3391 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
3364 | rc = -ENODEV; | 3392 | rc = -ENODEV; |
3365 | goto out_remove; | 3393 | goto out_remove; |
3366 | } | 3394 | } |
@@ -3401,7 +3429,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3401 | contin: | 3429 | contin: |
3402 | rc = qeth_l3_setadapter_parms(card); | 3430 | rc = qeth_l3_setadapter_parms(card); |
3403 | if (rc) | 3431 | if (rc) |
3404 | QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); | 3432 | QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); |
3405 | if (!card->options.sniffer) { | 3433 | if (!card->options.sniffer) { |
3406 | rc = qeth_l3_start_ipassists(card); | 3434 | rc = qeth_l3_start_ipassists(card); |
3407 | if (rc) { | 3435 | if (rc) { |
@@ -3410,10 +3438,10 @@ contin: | |||
3410 | } | 3438 | } |
3411 | rc = qeth_l3_setrouting_v4(card); | 3439 | rc = qeth_l3_setrouting_v4(card); |
3412 | if (rc) | 3440 | if (rc) |
3413 | QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); | 3441 | QETH_DBF_TEXT_(SETUP, 2, "4err%04x", rc); |
3414 | rc = qeth_l3_setrouting_v6(card); | 3442 | rc = qeth_l3_setrouting_v6(card); |
3415 | if (rc) | 3443 | if (rc) |
3416 | QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); | 3444 | QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc); |
3417 | } | 3445 | } |
3418 | netif_tx_disable(card->dev); | 3446 | netif_tx_disable(card->dev); |
3419 | 3447 | ||
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 3b73b96619e2..26270c351624 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | #define DRV_NAME "fnic" | 40 | #define DRV_NAME "fnic" |
41 | #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" | 41 | #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" |
42 | #define DRV_VERSION "1.6.0.16" | 42 | #define DRV_VERSION "1.6.0.17" |
43 | #define PFX DRV_NAME ": " | 43 | #define PFX DRV_NAME ": " |
44 | #define DFX DRV_NAME "%d: " | 44 | #define DFX DRV_NAME "%d: " |
45 | 45 | ||
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 2097de42a147..155b286f1a9d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c | |||
@@ -1892,6 +1892,21 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) | |||
1892 | goto fnic_abort_cmd_end; | 1892 | goto fnic_abort_cmd_end; |
1893 | } | 1893 | } |
1894 | 1894 | ||
1895 | /* IO out of order */ | ||
1896 | |||
1897 | if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) { | ||
1898 | spin_unlock_irqrestore(io_lock, flags); | ||
1899 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1900 | "Issuing Host reset due to out of order IO\n"); | ||
1901 | |||
1902 | if (fnic_host_reset(sc) == FAILED) { | ||
1903 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
1904 | "fnic_host_reset failed.\n"); | ||
1905 | } | ||
1906 | ret = FAILED; | ||
1907 | goto fnic_abort_cmd_end; | ||
1908 | } | ||
1909 | |||
1895 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; | 1910 | CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; |
1896 | 1911 | ||
1897 | /* | 1912 | /* |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index df4e27cd996a..9219953ee949 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -683,6 +683,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd, | |||
683 | ipr_reinit_ipr_cmnd(ipr_cmd); | 683 | ipr_reinit_ipr_cmnd(ipr_cmd); |
684 | ipr_cmd->u.scratch = 0; | 684 | ipr_cmd->u.scratch = 0; |
685 | ipr_cmd->sibling = NULL; | 685 | ipr_cmd->sibling = NULL; |
686 | ipr_cmd->eh_comp = NULL; | ||
686 | ipr_cmd->fast_done = fast_done; | 687 | ipr_cmd->fast_done = fast_done; |
687 | init_timer(&ipr_cmd->timer); | 688 | init_timer(&ipr_cmd->timer); |
688 | } | 689 | } |
@@ -848,6 +849,8 @@ static void ipr_scsi_eh_done(struct ipr_cmnd *ipr_cmd) | |||
848 | 849 | ||
849 | scsi_dma_unmap(ipr_cmd->scsi_cmd); | 850 | scsi_dma_unmap(ipr_cmd->scsi_cmd); |
850 | scsi_cmd->scsi_done(scsi_cmd); | 851 | scsi_cmd->scsi_done(scsi_cmd); |
852 | if (ipr_cmd->eh_comp) | ||
853 | complete(ipr_cmd->eh_comp); | ||
851 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); | 854 | list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); |
852 | } | 855 | } |
853 | 856 | ||
@@ -4811,6 +4814,84 @@ static int ipr_slave_alloc(struct scsi_device *sdev) | |||
4811 | return rc; | 4814 | return rc; |
4812 | } | 4815 | } |
4813 | 4816 | ||
4817 | /** | ||
4818 | * ipr_match_lun - Match function for specified LUN | ||
4819 | * @ipr_cmd: ipr command struct | ||
4820 | * @device: device to match (sdev) | ||
4821 | * | ||
4822 | * Returns: | ||
4823 | * 1 if command matches sdev / 0 if command does not match sdev | ||
4824 | **/ | ||
4825 | static int ipr_match_lun(struct ipr_cmnd *ipr_cmd, void *device) | ||
4826 | { | ||
4827 | if (ipr_cmd->scsi_cmd && ipr_cmd->scsi_cmd->device == device) | ||
4828 | return 1; | ||
4829 | return 0; | ||
4830 | } | ||
4831 | |||
4832 | /** | ||
4833 | * ipr_wait_for_ops - Wait for matching commands to complete | ||
4834 | * @ipr_cmd: ipr command struct | ||
4835 | * @device: device to match (sdev) | ||
4836 | * @match: match function to use | ||
4837 | * | ||
4838 | * Returns: | ||
4839 | * SUCCESS / FAILED | ||
4840 | **/ | ||
4841 | static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device, | ||
4842 | int (*match)(struct ipr_cmnd *, void *)) | ||
4843 | { | ||
4844 | struct ipr_cmnd *ipr_cmd; | ||
4845 | int wait; | ||
4846 | unsigned long flags; | ||
4847 | struct ipr_hrr_queue *hrrq; | ||
4848 | signed long timeout = IPR_ABORT_TASK_TIMEOUT; | ||
4849 | DECLARE_COMPLETION_ONSTACK(comp); | ||
4850 | |||
4851 | ENTER; | ||
4852 | do { | ||
4853 | wait = 0; | ||
4854 | |||
4855 | for_each_hrrq(hrrq, ioa_cfg) { | ||
4856 | spin_lock_irqsave(hrrq->lock, flags); | ||
4857 | list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { | ||
4858 | if (match(ipr_cmd, device)) { | ||
4859 | ipr_cmd->eh_comp = ∁ | ||
4860 | wait++; | ||
4861 | } | ||
4862 | } | ||
4863 | spin_unlock_irqrestore(hrrq->lock, flags); | ||
4864 | } | ||
4865 | |||
4866 | if (wait) { | ||
4867 | timeout = wait_for_completion_timeout(&comp, timeout); | ||
4868 | |||
4869 | if (!timeout) { | ||
4870 | wait = 0; | ||
4871 | |||
4872 | for_each_hrrq(hrrq, ioa_cfg) { | ||
4873 | spin_lock_irqsave(hrrq->lock, flags); | ||
4874 | list_for_each_entry(ipr_cmd, &hrrq->hrrq_pending_q, queue) { | ||
4875 | if (match(ipr_cmd, device)) { | ||
4876 | ipr_cmd->eh_comp = NULL; | ||
4877 | wait++; | ||
4878 | } | ||
4879 | } | ||
4880 | spin_unlock_irqrestore(hrrq->lock, flags); | ||
4881 | } | ||
4882 | |||
4883 | if (wait) | ||
4884 | dev_err(&ioa_cfg->pdev->dev, "Timed out waiting for aborted commands\n"); | ||
4885 | LEAVE; | ||
4886 | return wait ? FAILED : SUCCESS; | ||
4887 | } | ||
4888 | } | ||
4889 | } while (wait); | ||
4890 | |||
4891 | LEAVE; | ||
4892 | return SUCCESS; | ||
4893 | } | ||
4894 | |||
4814 | static int ipr_eh_host_reset(struct scsi_cmnd *cmd) | 4895 | static int ipr_eh_host_reset(struct scsi_cmnd *cmd) |
4815 | { | 4896 | { |
4816 | struct ipr_ioa_cfg *ioa_cfg; | 4897 | struct ipr_ioa_cfg *ioa_cfg; |
@@ -5030,11 +5111,17 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) | |||
5030 | static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) | 5111 | static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) |
5031 | { | 5112 | { |
5032 | int rc; | 5113 | int rc; |
5114 | struct ipr_ioa_cfg *ioa_cfg; | ||
5115 | |||
5116 | ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; | ||
5033 | 5117 | ||
5034 | spin_lock_irq(cmd->device->host->host_lock); | 5118 | spin_lock_irq(cmd->device->host->host_lock); |
5035 | rc = __ipr_eh_dev_reset(cmd); | 5119 | rc = __ipr_eh_dev_reset(cmd); |
5036 | spin_unlock_irq(cmd->device->host->host_lock); | 5120 | spin_unlock_irq(cmd->device->host->host_lock); |
5037 | 5121 | ||
5122 | if (rc == SUCCESS) | ||
5123 | rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); | ||
5124 | |||
5038 | return rc; | 5125 | return rc; |
5039 | } | 5126 | } |
5040 | 5127 | ||
@@ -5234,13 +5321,18 @@ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) | |||
5234 | { | 5321 | { |
5235 | unsigned long flags; | 5322 | unsigned long flags; |
5236 | int rc; | 5323 | int rc; |
5324 | struct ipr_ioa_cfg *ioa_cfg; | ||
5237 | 5325 | ||
5238 | ENTER; | 5326 | ENTER; |
5239 | 5327 | ||
5328 | ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; | ||
5329 | |||
5240 | spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); | 5330 | spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); |
5241 | rc = ipr_cancel_op(scsi_cmd); | 5331 | rc = ipr_cancel_op(scsi_cmd); |
5242 | spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); | 5332 | spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); |
5243 | 5333 | ||
5334 | if (rc == SUCCESS) | ||
5335 | rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); | ||
5244 | LEAVE; | 5336 | LEAVE; |
5245 | return rc; | 5337 | return rc; |
5246 | } | 5338 | } |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b4f3eec51bc9..ec03b42fa2b9 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -1606,6 +1606,7 @@ struct ipr_cmnd { | |||
1606 | struct scsi_device *sdev; | 1606 | struct scsi_device *sdev; |
1607 | } u; | 1607 | } u; |
1608 | 1608 | ||
1609 | struct completion *eh_comp; | ||
1609 | struct ipr_hrr_queue *hrrq; | 1610 | struct ipr_hrr_queue *hrrq; |
1610 | struct ipr_ioa_cfg *ioa_cfg; | 1611 | struct ipr_ioa_cfg *ioa_cfg; |
1611 | }; | 1612 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 12ca291c1380..cce1cbc1a927 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -734,7 +734,9 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) | |||
734 | * Return target busy if we've received a non-zero retry_delay_timer | 734 | * Return target busy if we've received a non-zero retry_delay_timer |
735 | * in a FCP_RSP. | 735 | * in a FCP_RSP. |
736 | */ | 736 | */ |
737 | if (time_after(jiffies, fcport->retry_delay_timestamp)) | 737 | if (fcport->retry_delay_timestamp == 0) { |
738 | /* retry delay not set */ | ||
739 | } else if (time_after(jiffies, fcport->retry_delay_timestamp)) | ||
738 | fcport->retry_delay_timestamp = 0; | 740 | fcport->retry_delay_timestamp = 0; |
739 | else | 741 | else |
740 | goto qc24_target_busy; | 742 | goto qc24_target_busy; |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index e02885451425..9b3829931f40 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -986,9 +986,9 @@ int scsi_device_get(struct scsi_device *sdev) | |||
986 | return -ENXIO; | 986 | return -ENXIO; |
987 | if (!get_device(&sdev->sdev_gendev)) | 987 | if (!get_device(&sdev->sdev_gendev)) |
988 | return -ENXIO; | 988 | return -ENXIO; |
989 | /* We can fail this if we're doing SCSI operations | 989 | /* We can fail try_module_get if we're doing SCSI operations |
990 | * from module exit (like cache flush) */ | 990 | * from module exit (like cache flush) */ |
991 | try_module_get(sdev->host->hostt->module); | 991 | __module_get(sdev->host->hostt->module); |
992 | 992 | ||
993 | return 0; | 993 | return 0; |
994 | } | 994 | } |
@@ -1004,14 +1004,7 @@ EXPORT_SYMBOL(scsi_device_get); | |||
1004 | */ | 1004 | */ |
1005 | void scsi_device_put(struct scsi_device *sdev) | 1005 | void scsi_device_put(struct scsi_device *sdev) |
1006 | { | 1006 | { |
1007 | #ifdef CONFIG_MODULE_UNLOAD | 1007 | module_put(sdev->host->hostt->module); |
1008 | struct module *module = sdev->host->hostt->module; | ||
1009 | |||
1010 | /* The module refcount will be zero if scsi_device_get() | ||
1011 | * was called from a module removal routine */ | ||
1012 | if (module && module_refcount(module) != 0) | ||
1013 | module_put(module); | ||
1014 | #endif | ||
1015 | put_device(&sdev->sdev_gendev); | 1008 | put_device(&sdev->sdev_gendev); |
1016 | } | 1009 | } |
1017 | EXPORT_SYMBOL(scsi_device_put); | 1010 | EXPORT_SYMBOL(scsi_device_put); |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 7b8b51bc29b4..4aca1b0378c2 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -1623,7 +1623,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
1623 | req_opcode = cmd[3]; | 1623 | req_opcode = cmd[3]; |
1624 | req_sa = get_unaligned_be16(cmd + 4); | 1624 | req_sa = get_unaligned_be16(cmd + 4); |
1625 | alloc_len = get_unaligned_be32(cmd + 6); | 1625 | alloc_len = get_unaligned_be32(cmd + 6); |
1626 | if (alloc_len < 4 && alloc_len > 0xffff) { | 1626 | if (alloc_len < 4 || alloc_len > 0xffff) { |
1627 | mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); | 1627 | mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1); |
1628 | return check_condition_result; | 1628 | return check_condition_result; |
1629 | } | 1629 | } |
@@ -1631,7 +1631,7 @@ resp_rsup_opcodes(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
1631 | a_len = 8192; | 1631 | a_len = 8192; |
1632 | else | 1632 | else |
1633 | a_len = alloc_len; | 1633 | a_len = alloc_len; |
1634 | arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL); | 1634 | arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC); |
1635 | if (NULL == arr) { | 1635 | if (NULL == arr) { |
1636 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, | 1636 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, |
1637 | INSUFF_RES_ASCQ); | 1637 | INSUFF_RES_ASCQ); |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index e42fff6e8c10..8afb01604d51 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1041,7 +1041,7 @@ retry: | |||
1041 | } | 1041 | } |
1042 | /* signal not to enter either branch of the if () below */ | 1042 | /* signal not to enter either branch of the if () below */ |
1043 | timeleft = 0; | 1043 | timeleft = 0; |
1044 | rtn = NEEDS_RETRY; | 1044 | rtn = FAILED; |
1045 | } else { | 1045 | } else { |
1046 | timeleft = wait_for_completion_timeout(&done, timeout); | 1046 | timeleft = wait_for_completion_timeout(&done, timeout); |
1047 | rtn = SUCCESS; | 1047 | rtn = SUCCESS; |
@@ -1081,7 +1081,7 @@ retry: | |||
1081 | rtn = FAILED; | 1081 | rtn = FAILED; |
1082 | break; | 1082 | break; |
1083 | } | 1083 | } |
1084 | } else if (!rtn) { | 1084 | } else if (rtn != FAILED) { |
1085 | scsi_abort_eh_cmnd(scmd); | 1085 | scsi_abort_eh_cmnd(scmd); |
1086 | rtn = FAILED; | 1086 | rtn = FAILED; |
1087 | } | 1087 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9ea95dd3e260..17bb541f7cc2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -591,7 +591,6 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq) | |||
591 | static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) | 591 | static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) |
592 | { | 592 | { |
593 | struct scatterlist *first_chunk = NULL; | 593 | struct scatterlist *first_chunk = NULL; |
594 | gfp_t gfp_mask = mq ? GFP_NOIO : GFP_ATOMIC; | ||
595 | int ret; | 594 | int ret; |
596 | 595 | ||
597 | BUG_ON(!nents); | 596 | BUG_ON(!nents); |
@@ -606,7 +605,7 @@ static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq) | |||
606 | } | 605 | } |
607 | 606 | ||
608 | ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS, | 607 | ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS, |
609 | first_chunk, gfp_mask, scsi_sg_alloc); | 608 | first_chunk, GFP_ATOMIC, scsi_sg_alloc); |
610 | if (unlikely(ret)) | 609 | if (unlikely(ret)) |
611 | scsi_free_sgtable(sdb, mq); | 610 | scsi_free_sgtable(sdb, mq); |
612 | return ret; | 611 | return ret; |
@@ -1144,7 +1143,17 @@ int scsi_init_io(struct scsi_cmnd *cmd) | |||
1144 | struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; | 1143 | struct scsi_data_buffer *prot_sdb = cmd->prot_sdb; |
1145 | int ivecs, count; | 1144 | int ivecs, count; |
1146 | 1145 | ||
1147 | BUG_ON(prot_sdb == NULL); | 1146 | if (prot_sdb == NULL) { |
1147 | /* | ||
1148 | * This can happen if someone (e.g. multipath) | ||
1149 | * queues a command to a device on an adapter | ||
1150 | * that does not support DIX. | ||
1151 | */ | ||
1152 | WARN_ON_ONCE(1); | ||
1153 | error = BLKPREP_KILL; | ||
1154 | goto err_exit; | ||
1155 | } | ||
1156 | |||
1148 | ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); | 1157 | ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio); |
1149 | 1158 | ||
1150 | if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { | 1159 | if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) { |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index fedab3c21ddf..399516925d80 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -2623,8 +2623,9 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
2623 | sd_config_discard(sdkp, SD_LBP_WS16); | 2623 | sd_config_discard(sdkp, SD_LBP_WS16); |
2624 | 2624 | ||
2625 | } else { /* LBP VPD page tells us what to use */ | 2625 | } else { /* LBP VPD page tells us what to use */ |
2626 | 2626 | if (sdkp->lbpu && sdkp->max_unmap_blocks && !sdkp->lbprz) | |
2627 | if (sdkp->lbpws) | 2627 | sd_config_discard(sdkp, SD_LBP_UNMAP); |
2628 | else if (sdkp->lbpws) | ||
2628 | sd_config_discard(sdkp, SD_LBP_WS16); | 2629 | sd_config_discard(sdkp, SD_LBP_WS16); |
2629 | else if (sdkp->lbpws10) | 2630 | else if (sdkp->lbpws10) |
2630 | sd_config_discard(sdkp, SD_LBP_WS10); | 2631 | sd_config_discard(sdkp, SD_LBP_WS10); |
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 7281316a5ecb..a67d37c7e3c0 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c | |||
@@ -271,7 +271,6 @@ int dw_spi_mid_init(struct dw_spi *dws) | |||
271 | iounmap(clk_reg); | 271 | iounmap(clk_reg); |
272 | 272 | ||
273 | dws->num_cs = 16; | 273 | dws->num_cs = 16; |
274 | dws->fifo_len = 40; /* FIFO has 40 words buffer */ | ||
275 | 274 | ||
276 | #ifdef CONFIG_SPI_DW_MID_DMA | 275 | #ifdef CONFIG_SPI_DW_MID_DMA |
277 | dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); | 276 | dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index d0d5542efc06..8edcd1b84562 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
@@ -621,13 +621,13 @@ static void spi_hw_init(struct dw_spi *dws) | |||
621 | if (!dws->fifo_len) { | 621 | if (!dws->fifo_len) { |
622 | u32 fifo; | 622 | u32 fifo; |
623 | 623 | ||
624 | for (fifo = 2; fifo <= 257; fifo++) { | 624 | for (fifo = 2; fifo <= 256; fifo++) { |
625 | dw_writew(dws, DW_SPI_TXFLTR, fifo); | 625 | dw_writew(dws, DW_SPI_TXFLTR, fifo); |
626 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) | 626 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) |
627 | break; | 627 | break; |
628 | } | 628 | } |
629 | 629 | ||
630 | dws->fifo_len = (fifo == 257) ? 0 : fifo; | 630 | dws->fifo_len = (fifo == 2) ? 0 : fifo - 1; |
631 | dw_writew(dws, DW_SPI_TXFLTR, 0); | 631 | dw_writew(dws, DW_SPI_TXFLTR, 0); |
632 | } | 632 | } |
633 | } | 633 | } |
@@ -673,7 +673,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
673 | if (dws->dma_ops && dws->dma_ops->dma_init) { | 673 | if (dws->dma_ops && dws->dma_ops->dma_init) { |
674 | ret = dws->dma_ops->dma_init(dws); | 674 | ret = dws->dma_ops->dma_init(dws); |
675 | if (ret) { | 675 | if (ret) { |
676 | dev_warn(&master->dev, "DMA init failed\n"); | 676 | dev_warn(dev, "DMA init failed\n"); |
677 | dws->dma_inited = 0; | 677 | dws->dma_inited = 0; |
678 | } | 678 | } |
679 | } | 679 | } |
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index b410499cddca..aad6683db81b 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c | |||
@@ -341,7 +341,7 @@ static int img_spfi_start_dma(struct spi_master *master, | |||
341 | default: | 341 | default: |
342 | rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; | 342 | rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; |
343 | rxconf.src_addr_width = 1; | 343 | rxconf.src_addr_width = 1; |
344 | rxconf.src_maxburst = 1; | 344 | rxconf.src_maxburst = 4; |
345 | } | 345 | } |
346 | dmaengine_slave_config(spfi->rx_ch, &rxconf); | 346 | dmaengine_slave_config(spfi->rx_ch, &rxconf); |
347 | 347 | ||
@@ -368,7 +368,7 @@ static int img_spfi_start_dma(struct spi_master *master, | |||
368 | default: | 368 | default: |
369 | txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; | 369 | txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; |
370 | txconf.dst_addr_width = 1; | 370 | txconf.dst_addr_width = 1; |
371 | txconf.dst_maxburst = 1; | 371 | txconf.dst_maxburst = 4; |
372 | break; | 372 | break; |
373 | } | 373 | } |
374 | dmaengine_slave_config(spfi->tx_ch, &txconf); | 374 | dmaengine_slave_config(spfi->tx_ch, &txconf); |
@@ -390,14 +390,14 @@ static int img_spfi_start_dma(struct spi_master *master, | |||
390 | dma_async_issue_pending(spfi->rx_ch); | 390 | dma_async_issue_pending(spfi->rx_ch); |
391 | } | 391 | } |
392 | 392 | ||
393 | spfi_start(spfi); | ||
394 | |||
393 | if (xfer->tx_buf) { | 395 | if (xfer->tx_buf) { |
394 | spfi->tx_dma_busy = true; | 396 | spfi->tx_dma_busy = true; |
395 | dmaengine_submit(txdesc); | 397 | dmaengine_submit(txdesc); |
396 | dma_async_issue_pending(spfi->tx_ch); | 398 | dma_async_issue_pending(spfi->tx_ch); |
397 | } | 399 | } |
398 | 400 | ||
399 | spfi_start(spfi); | ||
400 | |||
401 | return 1; | 401 | return 1; |
402 | 402 | ||
403 | stop_dma: | 403 | stop_dma: |
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 05c623cfb078..23822e7df6c1 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c | |||
@@ -546,8 +546,8 @@ static void giveback(struct driver_data *drv_data) | |||
546 | cs_deassert(drv_data); | 546 | cs_deassert(drv_data); |
547 | } | 547 | } |
548 | 548 | ||
549 | spi_finalize_current_message(drv_data->master); | ||
550 | drv_data->cur_chip = NULL; | 549 | drv_data->cur_chip = NULL; |
550 | spi_finalize_current_message(drv_data->master); | ||
551 | } | 551 | } |
552 | 552 | ||
553 | static void reset_sccr1(struct driver_data *drv_data) | 553 | static void reset_sccr1(struct driver_data *drv_data) |
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 239be7cbe5a8..3ab7a21445fc 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
@@ -82,7 +82,7 @@ struct sh_msiof_spi_priv { | |||
82 | #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ | 82 | #define MDR1_SYNCMD_LR 0x30000000 /* L/R mode */ |
83 | #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ | 83 | #define MDR1_SYNCAC_SHIFT 25 /* Sync Polarity (1 = Active-low) */ |
84 | #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ | 84 | #define MDR1_BITLSB_SHIFT 24 /* MSB/LSB First (1 = LSB first) */ |
85 | #define MDR1_FLD_MASK 0x000000c0 /* Frame Sync Signal Interval (0-3) */ | 85 | #define MDR1_FLD_MASK 0x0000000c /* Frame Sync Signal Interval (0-3) */ |
86 | #define MDR1_FLD_SHIFT 2 | 86 | #define MDR1_FLD_SHIFT 2 |
87 | #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ | 87 | #define MDR1_XXSTP 0x00000001 /* Transmission/Reception Stop on FIFO */ |
88 | /* TMDR1 */ | 88 | /* TMDR1 */ |
@@ -480,6 +480,8 @@ static int sh_msiof_spi_setup(struct spi_device *spi) | |||
480 | struct device_node *np = spi->master->dev.of_node; | 480 | struct device_node *np = spi->master->dev.of_node; |
481 | struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); | 481 | struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master); |
482 | 482 | ||
483 | pm_runtime_get_sync(&p->pdev->dev); | ||
484 | |||
483 | if (!np) { | 485 | if (!np) { |
484 | /* | 486 | /* |
485 | * Use spi->controller_data for CS (same strategy as spi_gpio), | 487 | * Use spi->controller_data for CS (same strategy as spi_gpio), |
@@ -498,6 +500,9 @@ static int sh_msiof_spi_setup(struct spi_device *spi) | |||
498 | if (spi->cs_gpio >= 0) | 500 | if (spi->cs_gpio >= 0) |
499 | gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); | 501 | gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); |
500 | 502 | ||
503 | |||
504 | pm_runtime_put_sync(&p->pdev->dev); | ||
505 | |||
501 | return 0; | 506 | return 0; |
502 | } | 507 | } |
503 | 508 | ||
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index 1bf891bd321a..4f361b77c749 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c | |||
@@ -264,7 +264,7 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, | |||
264 | 264 | ||
265 | if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) && | 265 | if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) && |
266 | inode->i_sb->s_root != NULL && | 266 | inode->i_sb->s_root != NULL && |
267 | is_root_inode(inode)) | 267 | !is_root_inode(inode)) |
268 | ll_invalidate_aliases(inode); | 268 | ll_invalidate_aliases(inode); |
269 | 269 | ||
270 | iput(inode); | 270 | iput(inode); |
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index 930f6010203e..65d610abe06e 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c | |||
@@ -632,7 +632,7 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) | |||
632 | return 0; | 632 | return 0; |
633 | } | 633 | } |
634 | 634 | ||
635 | if (cfio->fault.ft_flags & VM_FAULT_SIGBUS) { | 635 | if (cfio->fault.ft_flags & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) { |
636 | CDEBUG(D_PAGE, "got addr %p - SIGBUS\n", vmf->virtual_address); | 636 | CDEBUG(D_PAGE, "got addr %p - SIGBUS\n", vmf->virtual_address); |
637 | return -EFAULT; | 637 | return -EFAULT; |
638 | } | 638 | } |
diff --git a/drivers/staging/media/tlg2300/Kconfig b/drivers/staging/media/tlg2300/Kconfig index 81784c6f7b88..77d8753f6ba4 100644 --- a/drivers/staging/media/tlg2300/Kconfig +++ b/drivers/staging/media/tlg2300/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config VIDEO_TLG2300 | 1 | config VIDEO_TLG2300 |
2 | tristate "Telegent TLG2300 USB video capture support (Deprecated)" | 2 | tristate "Telegent TLG2300 USB video capture support (Deprecated)" |
3 | depends on VIDEO_DEV && I2C && SND && DVB_CORE | 3 | depends on VIDEO_DEV && I2C && SND && DVB_CORE |
4 | depends on MEDIA_USB_SUPPORT | ||
4 | select VIDEO_TUNER | 5 | select VIDEO_TUNER |
5 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
6 | depends on RC_CORE | 7 | depends on RC_CORE |
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 093535c6217b..120b70d72d79 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -85,23 +85,20 @@ static struct nvec_chip *nvec_power_handle; | |||
85 | static const struct mfd_cell nvec_devices[] = { | 85 | static const struct mfd_cell nvec_devices[] = { |
86 | { | 86 | { |
87 | .name = "nvec-kbd", | 87 | .name = "nvec-kbd", |
88 | .id = 1, | ||
89 | }, | 88 | }, |
90 | { | 89 | { |
91 | .name = "nvec-mouse", | 90 | .name = "nvec-mouse", |
92 | .id = 1, | ||
93 | }, | 91 | }, |
94 | { | 92 | { |
95 | .name = "nvec-power", | 93 | .name = "nvec-power", |
96 | .id = 1, | 94 | .id = 0, |
97 | }, | 95 | }, |
98 | { | 96 | { |
99 | .name = "nvec-power", | 97 | .name = "nvec-power", |
100 | .id = 2, | 98 | .id = 1, |
101 | }, | 99 | }, |
102 | { | 100 | { |
103 | .name = "nvec-paz00", | 101 | .name = "nvec-paz00", |
104 | .id = 1, | ||
105 | }, | 102 | }, |
106 | }; | 103 | }; |
107 | 104 | ||
@@ -891,7 +888,7 @@ static int tegra_nvec_probe(struct platform_device *pdev) | |||
891 | nvec_msg_free(nvec, msg); | 888 | nvec_msg_free(nvec, msg); |
892 | } | 889 | } |
893 | 890 | ||
894 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, | 891 | ret = mfd_add_devices(nvec->dev, 0, nvec_devices, |
895 | ARRAY_SIZE(nvec_devices), NULL, 0, NULL); | 892 | ARRAY_SIZE(nvec_devices), NULL, 0, NULL); |
896 | if (ret) | 893 | if (ret) |
897 | dev_err(nvec->dev, "error adding subdevices\n"); | 894 | dev_err(nvec->dev, "error adding subdevices\n"); |
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 86c72ba0a0cd..f8c5fc371c4c 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c | |||
@@ -2177,7 +2177,7 @@ bool BBbVT3253Init(struct vnt_private *priv) | |||
2177 | /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ | 2177 | /* Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted) */ |
2178 | /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ | 2178 | /*bResult &= BBbWriteEmbedded(dwIoBase,0x0a,0x28);*/ |
2179 | /* Select VC1/VC2, CR215 = 0x02->0x06 */ | 2179 | /* Select VC1/VC2, CR215 = 0x02->0x06 */ |
2180 | bResult &= BBbWriteEmbedded(dwIoBase, 0xd7, 0x06); | 2180 | bResult &= BBbWriteEmbedded(priv, 0xd7, 0x06); |
2181 | /* }} */ | 2181 | /* }} */ |
2182 | 2182 | ||
2183 | for (ii = 0; ii < CB_VT3253B0_AGC; ii++) | 2183 | for (ii = 0; ii < CB_VT3253B0_AGC; ii++) |
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index c8f739dd346e..70f870541f92 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c | |||
@@ -182,6 +182,14 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) | |||
182 | if (pDevice->byCurrentCh == uConnectionChannel) | 182 | if (pDevice->byCurrentCh == uConnectionChannel) |
183 | return bResult; | 183 | return bResult; |
184 | 184 | ||
185 | /* Set VGA to max sensitivity */ | ||
186 | if (pDevice->bUpdateBBVGA && | ||
187 | pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) { | ||
188 | pDevice->byBBVGACurrent = pDevice->abyBBVGA[0]; | ||
189 | |||
190 | BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); | ||
191 | } | ||
192 | |||
185 | /* clear NAV */ | 193 | /* clear NAV */ |
186 | MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); | 194 | MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MACCR, MACCR_CLRNAV); |
187 | 195 | ||
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 83e4162c0094..cd1a277d853b 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
@@ -1232,7 +1232,7 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) | |||
1232 | 1232 | ||
1233 | head_td = priv->apCurrTD[dma_idx]; | 1233 | head_td = priv->apCurrTD[dma_idx]; |
1234 | 1234 | ||
1235 | head_td->m_td1TD1.byTCR = (TCR_EDP|TCR_STP); | 1235 | head_td->m_td1TD1.byTCR = 0; |
1236 | 1236 | ||
1237 | head_td->pTDInfo->skb = skb; | 1237 | head_td->pTDInfo->skb = skb; |
1238 | 1238 | ||
@@ -1257,6 +1257,11 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) | |||
1257 | 1257 | ||
1258 | priv->bPWBitOn = false; | 1258 | priv->bPWBitOn = false; |
1259 | 1259 | ||
1260 | /* Set TSR1 & ReqCount in TxDescHead */ | ||
1261 | head_td->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); | ||
1262 | head_td->m_td1TD1.wReqCount = | ||
1263 | cpu_to_le16((u16)head_td->pTDInfo->dwReqCount); | ||
1264 | |||
1260 | head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; | 1265 | head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB; |
1261 | 1266 | ||
1262 | if (dma_idx == TYPE_AC0DMA) | 1267 | if (dma_idx == TYPE_AC0DMA) |
@@ -1500,9 +1505,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw, | |||
1500 | if (conf->enable_beacon) { | 1505 | if (conf->enable_beacon) { |
1501 | vnt_beacon_enable(priv, vif, conf); | 1506 | vnt_beacon_enable(priv, vif, conf); |
1502 | 1507 | ||
1503 | MACvRegBitsOn(priv, MAC_REG_TCR, TCR_AUTOBCNTX); | 1508 | MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, |
1509 | TCR_AUTOBCNTX); | ||
1504 | } else { | 1510 | } else { |
1505 | MACvRegBitsOff(priv, MAC_REG_TCR, TCR_AUTOBCNTX); | 1511 | MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, |
1512 | TCR_AUTOBCNTX); | ||
1506 | } | 1513 | } |
1507 | } | 1514 | } |
1508 | 1515 | ||
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 61c39dd7ad01..b5b0155961f2 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c | |||
@@ -1204,13 +1204,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, | |||
1204 | 1204 | ||
1205 | ptdCurr = (PSTxDesc)pHeadTD; | 1205 | ptdCurr = (PSTxDesc)pHeadTD; |
1206 | 1206 | ||
1207 | ptdCurr->pTDInfo->dwReqCount = cbReqCount - uPadding; | 1207 | ptdCurr->pTDInfo->dwReqCount = cbReqCount; |
1208 | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; | 1208 | ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength; |
1209 | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; | 1209 | ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma; |
1210 | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); | 1210 | ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma); |
1211 | /* Set TSR1 & ReqCount in TxDescHead */ | ||
1212 | ptdCurr->m_td1TD1.byTCR |= (TCR_STP | TCR_EDP | EDMSDU); | ||
1213 | ptdCurr->m_td1TD1.wReqCount = cpu_to_le16((unsigned short)(cbReqCount)); | ||
1214 | 1211 | ||
1215 | return cbHeaderLength; | 1212 | return cbHeaderLength; |
1216 | } | 1213 | } |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 55f6774f706f..aebde3289c50 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -2027,10 +2027,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2027 | goto reject; | 2027 | goto reject; |
2028 | } | 2028 | } |
2029 | if (!strncmp("=All", text_ptr, 4)) { | 2029 | if (!strncmp("=All", text_ptr, 4)) { |
2030 | cmd->cmd_flags |= IFC_SENDTARGETS_ALL; | 2030 | cmd->cmd_flags |= ICF_SENDTARGETS_ALL; |
2031 | } else if (!strncmp("=iqn.", text_ptr, 5) || | 2031 | } else if (!strncmp("=iqn.", text_ptr, 5) || |
2032 | !strncmp("=eui.", text_ptr, 5)) { | 2032 | !strncmp("=eui.", text_ptr, 5)) { |
2033 | cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; | 2033 | cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE; |
2034 | } else { | 2034 | } else { |
2035 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); | 2035 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); |
2036 | goto reject; | 2036 | goto reject; |
@@ -3415,10 +3415,10 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3415 | return -ENOMEM; | 3415 | return -ENOMEM; |
3416 | } | 3416 | } |
3417 | /* | 3417 | /* |
3418 | * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE | 3418 | * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE |
3419 | * explicit case.. | 3419 | * explicit case.. |
3420 | */ | 3420 | */ |
3421 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { | 3421 | if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) { |
3422 | text_ptr = strchr(text_in, '='); | 3422 | text_ptr = strchr(text_in, '='); |
3423 | if (!text_ptr) { | 3423 | if (!text_ptr) { |
3424 | pr_err("Unable to locate '=' string in text_in:" | 3424 | pr_err("Unable to locate '=' string in text_in:" |
@@ -3434,7 +3434,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3434 | 3434 | ||
3435 | spin_lock(&tiqn_lock); | 3435 | spin_lock(&tiqn_lock); |
3436 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { | 3436 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { |
3437 | if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && | 3437 | if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) && |
3438 | strcmp(tiqn->tiqn, text_ptr)) { | 3438 | strcmp(tiqn->tiqn, text_ptr)) { |
3439 | continue; | 3439 | continue; |
3440 | } | 3440 | } |
@@ -3512,7 +3512,7 @@ eob: | |||
3512 | if (end_of_buf) | 3512 | if (end_of_buf) |
3513 | break; | 3513 | break; |
3514 | 3514 | ||
3515 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) | 3515 | if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) |
3516 | break; | 3516 | break; |
3517 | } | 3517 | } |
3518 | spin_unlock(&tiqn_lock); | 3518 | spin_unlock(&tiqn_lock); |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 09a522bae222..cbcff38ac9b7 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -135,8 +135,8 @@ enum cmd_flags_table { | |||
135 | ICF_CONTIG_MEMORY = 0x00000020, | 135 | ICF_CONTIG_MEMORY = 0x00000020, |
136 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, | 136 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, |
137 | ICF_OOO_CMDSN = 0x00000080, | 137 | ICF_OOO_CMDSN = 0x00000080, |
138 | IFC_SENDTARGETS_ALL = 0x00000100, | 138 | ICF_SENDTARGETS_ALL = 0x00000100, |
139 | IFC_SENDTARGETS_SINGLE = 0x00000200, | 139 | ICF_SENDTARGETS_SINGLE = 0x00000200, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | /* struct iscsi_cmd->i_state */ | 142 | /* struct iscsi_cmd->i_state */ |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7653cfb027a2..58f49ff69b14 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1103,51 +1103,6 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | |||
1103 | } | 1103 | } |
1104 | EXPORT_SYMBOL(se_dev_set_queue_depth); | 1104 | EXPORT_SYMBOL(se_dev_set_queue_depth); |
1105 | 1105 | ||
1106 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | ||
1107 | { | ||
1108 | int block_size = dev->dev_attrib.block_size; | ||
1109 | |||
1110 | if (dev->export_count) { | ||
1111 | pr_err("dev[%p]: Unable to change SE Device" | ||
1112 | " fabric_max_sectors while export_count is %d\n", | ||
1113 | dev, dev->export_count); | ||
1114 | return -EINVAL; | ||
1115 | } | ||
1116 | if (!fabric_max_sectors) { | ||
1117 | pr_err("dev[%p]: Illegal ZERO value for" | ||
1118 | " fabric_max_sectors\n", dev); | ||
1119 | return -EINVAL; | ||
1120 | } | ||
1121 | if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { | ||
1122 | pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" | ||
1123 | " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, | ||
1124 | DA_STATUS_MAX_SECTORS_MIN); | ||
1125 | return -EINVAL; | ||
1126 | } | ||
1127 | if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { | ||
1128 | pr_err("dev[%p]: Passed fabric_max_sectors: %u" | ||
1129 | " greater than DA_STATUS_MAX_SECTORS_MAX:" | ||
1130 | " %u\n", dev, fabric_max_sectors, | ||
1131 | DA_STATUS_MAX_SECTORS_MAX); | ||
1132 | return -EINVAL; | ||
1133 | } | ||
1134 | /* | ||
1135 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() | ||
1136 | */ | ||
1137 | if (!block_size) { | ||
1138 | block_size = 512; | ||
1139 | pr_warn("Defaulting to 512 for zero block_size\n"); | ||
1140 | } | ||
1141 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, | ||
1142 | block_size); | ||
1143 | |||
1144 | dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; | ||
1145 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", | ||
1146 | dev, fabric_max_sectors); | ||
1147 | return 0; | ||
1148 | } | ||
1149 | EXPORT_SYMBOL(se_dev_set_fabric_max_sectors); | ||
1150 | |||
1151 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | 1106 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) |
1152 | { | 1107 | { |
1153 | if (dev->export_count) { | 1108 | if (dev->export_count) { |
@@ -1156,10 +1111,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | |||
1156 | dev, dev->export_count); | 1111 | dev, dev->export_count); |
1157 | return -EINVAL; | 1112 | return -EINVAL; |
1158 | } | 1113 | } |
1159 | if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { | 1114 | if (optimal_sectors > dev->dev_attrib.hw_max_sectors) { |
1160 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" | 1115 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" |
1161 | " greater than fabric_max_sectors: %u\n", dev, | 1116 | " greater than hw_max_sectors: %u\n", dev, |
1162 | optimal_sectors, dev->dev_attrib.fabric_max_sectors); | 1117 | optimal_sectors, dev->dev_attrib.hw_max_sectors); |
1163 | return -EINVAL; | 1118 | return -EINVAL; |
1164 | } | 1119 | } |
1165 | 1120 | ||
@@ -1553,8 +1508,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1553 | dev->dev_attrib.unmap_granularity_alignment = | 1508 | dev->dev_attrib.unmap_granularity_alignment = |
1554 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; | 1509 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; |
1555 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; | 1510 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; |
1556 | dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; | ||
1557 | dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; | ||
1558 | 1511 | ||
1559 | xcopy_lun = &dev->xcopy_lun; | 1512 | xcopy_lun = &dev->xcopy_lun; |
1560 | xcopy_lun->lun_se_dev = dev; | 1513 | xcopy_lun->lun_se_dev = dev; |
@@ -1595,6 +1548,7 @@ int target_configure_device(struct se_device *dev) | |||
1595 | dev->dev_attrib.hw_max_sectors = | 1548 | dev->dev_attrib.hw_max_sectors = |
1596 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, | 1549 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, |
1597 | dev->dev_attrib.hw_block_size); | 1550 | dev->dev_attrib.hw_block_size); |
1551 | dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; | ||
1598 | 1552 | ||
1599 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); | 1553 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); |
1600 | dev->creation_time = get_jiffies_64(); | 1554 | dev->creation_time = get_jiffies_64(); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index c2aea099ea4a..d836de200a03 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -621,7 +621,16 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, | |||
621 | struct fd_prot fd_prot; | 621 | struct fd_prot fd_prot; |
622 | sense_reason_t rc; | 622 | sense_reason_t rc; |
623 | int ret = 0; | 623 | int ret = 0; |
624 | 624 | /* | |
625 | * We are currently limited by the number of iovecs (2048) per | ||
626 | * single vfs_[writev,readv] call. | ||
627 | */ | ||
628 | if (cmd->data_length > FD_MAX_BYTES) { | ||
629 | pr_err("FILEIO: Not able to process I/O of %u bytes due to" | ||
630 | "FD_MAX_BYTES: %u iovec count limitiation\n", | ||
631 | cmd->data_length, FD_MAX_BYTES); | ||
632 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
633 | } | ||
625 | /* | 634 | /* |
626 | * Call vectorized fileio functions to map struct scatterlist | 635 | * Call vectorized fileio functions to map struct scatterlist |
627 | * physical memory addresses to struct iovec virtual memory. | 636 | * physical memory addresses to struct iovec virtual memory. |
@@ -959,7 +968,6 @@ static struct configfs_attribute *fileio_backend_dev_attrs[] = { | |||
959 | &fileio_dev_attrib_hw_block_size.attr, | 968 | &fileio_dev_attrib_hw_block_size.attr, |
960 | &fileio_dev_attrib_block_size.attr, | 969 | &fileio_dev_attrib_block_size.attr, |
961 | &fileio_dev_attrib_hw_max_sectors.attr, | 970 | &fileio_dev_attrib_hw_max_sectors.attr, |
962 | &fileio_dev_attrib_fabric_max_sectors.attr, | ||
963 | &fileio_dev_attrib_optimal_sectors.attr, | 971 | &fileio_dev_attrib_optimal_sectors.attr, |
964 | &fileio_dev_attrib_hw_queue_depth.attr, | 972 | &fileio_dev_attrib_hw_queue_depth.attr, |
965 | &fileio_dev_attrib_queue_depth.attr, | 973 | &fileio_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 3efff94fbd97..78346b850968 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -124,7 +124,7 @@ static int iblock_configure_device(struct se_device *dev) | |||
124 | q = bdev_get_queue(bd); | 124 | q = bdev_get_queue(bd); |
125 | 125 | ||
126 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); | 126 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); |
127 | dev->dev_attrib.hw_max_sectors = UINT_MAX; | 127 | dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); |
128 | dev->dev_attrib.hw_queue_depth = q->nr_requests; | 128 | dev->dev_attrib.hw_queue_depth = q->nr_requests; |
129 | 129 | ||
130 | /* | 130 | /* |
@@ -883,7 +883,6 @@ static struct configfs_attribute *iblock_backend_dev_attrs[] = { | |||
883 | &iblock_dev_attrib_hw_block_size.attr, | 883 | &iblock_dev_attrib_hw_block_size.attr, |
884 | &iblock_dev_attrib_block_size.attr, | 884 | &iblock_dev_attrib_block_size.attr, |
885 | &iblock_dev_attrib_hw_max_sectors.attr, | 885 | &iblock_dev_attrib_hw_max_sectors.attr, |
886 | &iblock_dev_attrib_fabric_max_sectors.attr, | ||
887 | &iblock_dev_attrib_optimal_sectors.attr, | 886 | &iblock_dev_attrib_optimal_sectors.attr, |
888 | &iblock_dev_attrib_hw_queue_depth.attr, | 887 | &iblock_dev_attrib_hw_queue_depth.attr, |
889 | &iblock_dev_attrib_queue_depth.attr, | 888 | &iblock_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d56f2aaba9af..283cf786ef98 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder( | |||
528 | 528 | ||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | } else if (we && registered_nexus) { | ||
532 | /* | ||
533 | * Reads are allowed for Write Exclusive locks | ||
534 | * from all registrants. | ||
535 | */ | ||
536 | if (cmd->data_direction == DMA_FROM_DEVICE) { | ||
537 | pr_debug("Allowing READ CDB: 0x%02x for %s" | ||
538 | " reservation\n", cdb[0], | ||
539 | core_scsi3_pr_dump_type(pr_reg_type)); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
531 | } | 543 | } |
532 | pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" | 544 | pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" |
533 | " for %s reservation\n", transport_dump_cmd_direction(cmd), | 545 | " for %s reservation\n", transport_dump_cmd_direction(cmd), |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 60ebd170a561..98e83ac5661b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -657,7 +657,6 @@ static struct configfs_attribute *rd_mcp_backend_dev_attrs[] = { | |||
657 | &rd_mcp_dev_attrib_hw_block_size.attr, | 657 | &rd_mcp_dev_attrib_hw_block_size.attr, |
658 | &rd_mcp_dev_attrib_block_size.attr, | 658 | &rd_mcp_dev_attrib_block_size.attr, |
659 | &rd_mcp_dev_attrib_hw_max_sectors.attr, | 659 | &rd_mcp_dev_attrib_hw_max_sectors.attr, |
660 | &rd_mcp_dev_attrib_fabric_max_sectors.attr, | ||
661 | &rd_mcp_dev_attrib_optimal_sectors.attr, | 660 | &rd_mcp_dev_attrib_optimal_sectors.attr, |
662 | &rd_mcp_dev_attrib_hw_queue_depth.attr, | 661 | &rd_mcp_dev_attrib_hw_queue_depth.attr, |
663 | &rd_mcp_dev_attrib_queue_depth.attr, | 662 | &rd_mcp_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 11bea1952435..cd4bed7b2757 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -953,21 +953,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
953 | 953 | ||
954 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { | 954 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
955 | unsigned long long end_lba; | 955 | unsigned long long end_lba; |
956 | |||
957 | if (sectors > dev->dev_attrib.fabric_max_sectors) { | ||
958 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | ||
959 | " big sectors %u exceeds fabric_max_sectors:" | ||
960 | " %u\n", cdb[0], sectors, | ||
961 | dev->dev_attrib.fabric_max_sectors); | ||
962 | return TCM_INVALID_CDB_FIELD; | ||
963 | } | ||
964 | if (sectors > dev->dev_attrib.hw_max_sectors) { | ||
965 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | ||
966 | " big sectors %u exceeds backend hw_max_sectors:" | ||
967 | " %u\n", cdb[0], sectors, | ||
968 | dev->dev_attrib.hw_max_sectors); | ||
969 | return TCM_INVALID_CDB_FIELD; | ||
970 | } | ||
971 | check_lba: | 956 | check_lba: |
972 | end_lba = dev->transport->get_blocks(dev) + 1; | 957 | end_lba = dev->transport->get_blocks(dev) + 1; |
973 | if (cmd->t_task_lba + sectors > end_lba) { | 958 | if (cmd->t_task_lba + sectors > end_lba) { |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 1307600fe726..4c71657da56a 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -505,7 +505,6 @@ static sense_reason_t | |||
505 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | 505 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) |
506 | { | 506 | { |
507 | struct se_device *dev = cmd->se_dev; | 507 | struct se_device *dev = cmd->se_dev; |
508 | u32 max_sectors; | ||
509 | int have_tp = 0; | 508 | int have_tp = 0; |
510 | int opt, min; | 509 | int opt, min; |
511 | 510 | ||
@@ -539,9 +538,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
539 | /* | 538 | /* |
540 | * Set MAXIMUM TRANSFER LENGTH | 539 | * Set MAXIMUM TRANSFER LENGTH |
541 | */ | 540 | */ |
542 | max_sectors = min(dev->dev_attrib.fabric_max_sectors, | 541 | put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); |
543 | dev->dev_attrib.hw_max_sectors); | ||
544 | put_unaligned_be32(max_sectors, &buf[8]); | ||
545 | 542 | ||
546 | /* | 543 | /* |
547 | * Set OPTIMAL TRANSFER LENGTH | 544 | * Set OPTIMAL TRANSFER LENGTH |
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 8bfa61c9693d..1157b559683b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -1118,7 +1118,6 @@ static struct configfs_attribute *tcmu_backend_dev_attrs[] = { | |||
1118 | &tcmu_dev_attrib_hw_block_size.attr, | 1118 | &tcmu_dev_attrib_hw_block_size.attr, |
1119 | &tcmu_dev_attrib_block_size.attr, | 1119 | &tcmu_dev_attrib_block_size.attr, |
1120 | &tcmu_dev_attrib_hw_max_sectors.attr, | 1120 | &tcmu_dev_attrib_hw_max_sectors.attr, |
1121 | &tcmu_dev_attrib_fabric_max_sectors.attr, | ||
1122 | &tcmu_dev_attrib_optimal_sectors.attr, | 1121 | &tcmu_dev_attrib_optimal_sectors.attr, |
1123 | &tcmu_dev_attrib_hw_queue_depth.attr, | 1122 | &tcmu_dev_attrib_hw_queue_depth.attr, |
1124 | &tcmu_dev_attrib_queue_depth.attr, | 1123 | &tcmu_dev_attrib_queue_depth.attr, |
diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index ad09e51ffae4..f65f0d109fc8 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) | 4 | * Copyright (C) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com) |
5 | * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org> | 5 | * Copyright (C) 2012 Amit Daniel <amit.kachhap@linaro.org> |
6 | * | 6 | * |
7 | * Copyright (C) 2014 Viresh Kumar <viresh.kumar@linaro.org> | ||
8 | * | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8 | * This program is free software; you can redistribute it and/or modify | 10 | * 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 | 11 | * it under the terms of the GNU General Public License as published by |
@@ -28,6 +30,20 @@ | |||
28 | #include <linux/cpu.h> | 30 | #include <linux/cpu.h> |
29 | #include <linux/cpu_cooling.h> | 31 | #include <linux/cpu_cooling.h> |
30 | 32 | ||
33 | /* | ||
34 | * Cooling state <-> CPUFreq frequency | ||
35 | * | ||
36 | * Cooling states are translated to frequencies throughout this driver and this | ||
37 | * is the relation between them. | ||
38 | * | ||
39 | * Highest cooling state corresponds to lowest possible frequency. | ||
40 | * | ||
41 | * i.e. | ||
42 | * level 0 --> 1st Max Freq | ||
43 | * level 1 --> 2nd Max Freq | ||
44 | * ... | ||
45 | */ | ||
46 | |||
31 | /** | 47 | /** |
32 | * struct cpufreq_cooling_device - data for cooling device with cpufreq | 48 | * struct cpufreq_cooling_device - data for cooling device with cpufreq |
33 | * @id: unique integer value corresponding to each cpufreq_cooling_device | 49 | * @id: unique integer value corresponding to each cpufreq_cooling_device |
@@ -38,25 +54,27 @@ | |||
38 | * cooling devices. | 54 | * cooling devices. |
39 | * @cpufreq_val: integer value representing the absolute value of the clipped | 55 | * @cpufreq_val: integer value representing the absolute value of the clipped |
40 | * frequency. | 56 | * frequency. |
57 | * @max_level: maximum cooling level. One less than total number of valid | ||
58 | * cpufreq frequencies. | ||
41 | * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. | 59 | * @allowed_cpus: all the cpus involved for this cpufreq_cooling_device. |
60 | * @node: list_head to link all cpufreq_cooling_device together. | ||
42 | * | 61 | * |
43 | * This structure is required for keeping information of each | 62 | * This structure is required for keeping information of each registered |
44 | * cpufreq_cooling_device registered. In order to prevent corruption of this a | 63 | * cpufreq_cooling_device. |
45 | * mutex lock cooling_cpufreq_lock is used. | ||
46 | */ | 64 | */ |
47 | struct cpufreq_cooling_device { | 65 | struct cpufreq_cooling_device { |
48 | int id; | 66 | int id; |
49 | struct thermal_cooling_device *cool_dev; | 67 | struct thermal_cooling_device *cool_dev; |
50 | unsigned int cpufreq_state; | 68 | unsigned int cpufreq_state; |
51 | unsigned int cpufreq_val; | 69 | unsigned int cpufreq_val; |
70 | unsigned int max_level; | ||
71 | unsigned int *freq_table; /* In descending order */ | ||
52 | struct cpumask allowed_cpus; | 72 | struct cpumask allowed_cpus; |
53 | struct list_head node; | 73 | struct list_head node; |
54 | }; | 74 | }; |
55 | static DEFINE_IDR(cpufreq_idr); | 75 | static DEFINE_IDR(cpufreq_idr); |
56 | static DEFINE_MUTEX(cooling_cpufreq_lock); | 76 | static DEFINE_MUTEX(cooling_cpufreq_lock); |
57 | 77 | ||
58 | static unsigned int cpufreq_dev_count; | ||
59 | |||
60 | static LIST_HEAD(cpufreq_dev_list); | 78 | static LIST_HEAD(cpufreq_dev_list); |
61 | 79 | ||
62 | /** | 80 | /** |
@@ -98,120 +116,30 @@ static void release_idr(struct idr *idr, int id) | |||
98 | /* Below code defines functions to be used for cpufreq as cooling device */ | 116 | /* Below code defines functions to be used for cpufreq as cooling device */ |
99 | 117 | ||
100 | /** | 118 | /** |
101 | * is_cpufreq_valid - function to check frequency transitioning capability. | 119 | * get_level: Find the level for a particular frequency |
102 | * @cpu: cpu for which check is needed. | 120 | * @cpufreq_dev: cpufreq_dev for which the property is required |
121 | * @freq: Frequency | ||
103 | * | 122 | * |
104 | * This function will check the current state of the system if | 123 | * Return: level on success, THERMAL_CSTATE_INVALID on error. |
105 | * it is capable of changing the frequency for a given @cpu. | ||
106 | * | ||
107 | * Return: 0 if the system is not currently capable of changing | ||
108 | * the frequency of given cpu. !0 in case the frequency is changeable. | ||
109 | */ | 124 | */ |
110 | static int is_cpufreq_valid(int cpu) | 125 | static unsigned long get_level(struct cpufreq_cooling_device *cpufreq_dev, |
126 | unsigned int freq) | ||
111 | { | 127 | { |
112 | struct cpufreq_policy policy; | 128 | unsigned long level; |
113 | |||
114 | return !cpufreq_get_policy(&policy, cpu); | ||
115 | } | ||
116 | |||
117 | enum cpufreq_cooling_property { | ||
118 | GET_LEVEL, | ||
119 | GET_FREQ, | ||
120 | GET_MAXL, | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * get_property - fetch a property of interest for a give cpu. | ||
125 | * @cpu: cpu for which the property is required | ||
126 | * @input: query parameter | ||
127 | * @output: query return | ||
128 | * @property: type of query (frequency, level, max level) | ||
129 | * | ||
130 | * This is the common function to | ||
131 | * 1. get maximum cpu cooling states | ||
132 | * 2. translate frequency to cooling state | ||
133 | * 3. translate cooling state to frequency | ||
134 | * Note that the code may be not in good shape | ||
135 | * but it is written in this way in order to: | ||
136 | * a) reduce duplicate code as most of the code can be shared. | ||
137 | * b) make sure the logic is consistent when translating between | ||
138 | * cooling states and frequencies. | ||
139 | * | ||
140 | * Return: 0 on success, -EINVAL when invalid parameters are passed. | ||
141 | */ | ||
142 | static int get_property(unsigned int cpu, unsigned long input, | ||
143 | unsigned int *output, | ||
144 | enum cpufreq_cooling_property property) | ||
145 | { | ||
146 | int i; | ||
147 | unsigned long max_level = 0, level = 0; | ||
148 | unsigned int freq = CPUFREQ_ENTRY_INVALID; | ||
149 | int descend = -1; | ||
150 | struct cpufreq_frequency_table *pos, *table = | ||
151 | cpufreq_frequency_get_table(cpu); | ||
152 | |||
153 | if (!output) | ||
154 | return -EINVAL; | ||
155 | |||
156 | if (!table) | ||
157 | return -EINVAL; | ||
158 | |||
159 | cpufreq_for_each_valid_entry(pos, table) { | ||
160 | /* ignore duplicate entry */ | ||
161 | if (freq == pos->frequency) | ||
162 | continue; | ||
163 | |||
164 | /* get the frequency order */ | ||
165 | if (freq != CPUFREQ_ENTRY_INVALID && descend == -1) | ||
166 | descend = freq > pos->frequency; | ||
167 | |||
168 | freq = pos->frequency; | ||
169 | max_level++; | ||
170 | } | ||
171 | |||
172 | /* No valid cpu frequency entry */ | ||
173 | if (max_level == 0) | ||
174 | return -EINVAL; | ||
175 | 129 | ||
176 | /* max_level is an index, not a counter */ | 130 | for (level = 0; level <= cpufreq_dev->max_level; level++) { |
177 | max_level--; | 131 | if (freq == cpufreq_dev->freq_table[level]) |
132 | return level; | ||
178 | 133 | ||
179 | /* get max level */ | 134 | if (freq > cpufreq_dev->freq_table[level]) |
180 | if (property == GET_MAXL) { | 135 | break; |
181 | *output = (unsigned int)max_level; | ||
182 | return 0; | ||
183 | } | 136 | } |
184 | 137 | ||
185 | if (property == GET_FREQ) | 138 | return THERMAL_CSTATE_INVALID; |
186 | level = descend ? input : (max_level - input); | ||
187 | |||
188 | i = 0; | ||
189 | cpufreq_for_each_valid_entry(pos, table) { | ||
190 | /* ignore duplicate entry */ | ||
191 | if (freq == pos->frequency) | ||
192 | continue; | ||
193 | |||
194 | /* now we have a valid frequency entry */ | ||
195 | freq = pos->frequency; | ||
196 | |||
197 | if (property == GET_LEVEL && (unsigned int)input == freq) { | ||
198 | /* get level by frequency */ | ||
199 | *output = descend ? i : (max_level - i); | ||
200 | return 0; | ||
201 | } | ||
202 | if (property == GET_FREQ && level == i) { | ||
203 | /* get frequency by level */ | ||
204 | *output = freq; | ||
205 | return 0; | ||
206 | } | ||
207 | i++; | ||
208 | } | ||
209 | |||
210 | return -EINVAL; | ||
211 | } | 139 | } |
212 | 140 | ||
213 | /** | 141 | /** |
214 | * cpufreq_cooling_get_level - for a give cpu, return the cooling level. | 142 | * cpufreq_cooling_get_level - for a given cpu, return the cooling level. |
215 | * @cpu: cpu for which the level is required | 143 | * @cpu: cpu for which the level is required |
216 | * @freq: the frequency of interest | 144 | * @freq: the frequency of interest |
217 | * | 145 | * |
@@ -223,77 +151,21 @@ static int get_property(unsigned int cpu, unsigned long input, | |||
223 | */ | 151 | */ |
224 | unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) | 152 | unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq) |
225 | { | 153 | { |
226 | unsigned int val; | 154 | struct cpufreq_cooling_device *cpufreq_dev; |
227 | |||
228 | if (get_property(cpu, (unsigned long)freq, &val, GET_LEVEL)) | ||
229 | return THERMAL_CSTATE_INVALID; | ||
230 | |||
231 | return (unsigned long)val; | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level); | ||
234 | |||
235 | /** | ||
236 | * get_cpu_frequency - get the absolute value of frequency from level. | ||
237 | * @cpu: cpu for which frequency is fetched. | ||
238 | * @level: cooling level | ||
239 | * | ||
240 | * This function matches cooling level with frequency. Based on a cooling level | ||
241 | * of frequency, equals cooling state of cpu cooling device, it will return | ||
242 | * the corresponding frequency. | ||
243 | * e.g level=0 --> 1st MAX FREQ, level=1 ---> 2nd MAX FREQ, .... etc | ||
244 | * | ||
245 | * Return: 0 on error, the corresponding frequency otherwise. | ||
246 | */ | ||
247 | static unsigned int get_cpu_frequency(unsigned int cpu, unsigned long level) | ||
248 | { | ||
249 | int ret = 0; | ||
250 | unsigned int freq; | ||
251 | |||
252 | ret = get_property(cpu, level, &freq, GET_FREQ); | ||
253 | if (ret) | ||
254 | return 0; | ||
255 | |||
256 | return freq; | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * cpufreq_apply_cooling - function to apply frequency clipping. | ||
261 | * @cpufreq_device: cpufreq_cooling_device pointer containing frequency | ||
262 | * clipping data. | ||
263 | * @cooling_state: value of the cooling state. | ||
264 | * | ||
265 | * Function used to make sure the cpufreq layer is aware of current thermal | ||
266 | * limits. The limits are applied by updating the cpufreq policy. | ||
267 | * | ||
268 | * Return: 0 on success, an error code otherwise (-EINVAL in case wrong | ||
269 | * cooling state). | ||
270 | */ | ||
271 | static int cpufreq_apply_cooling(struct cpufreq_cooling_device *cpufreq_device, | ||
272 | unsigned long cooling_state) | ||
273 | { | ||
274 | unsigned int cpuid, clip_freq; | ||
275 | struct cpumask *mask = &cpufreq_device->allowed_cpus; | ||
276 | unsigned int cpu = cpumask_any(mask); | ||
277 | |||
278 | |||
279 | /* Check if the old cooling action is same as new cooling action */ | ||
280 | if (cpufreq_device->cpufreq_state == cooling_state) | ||
281 | return 0; | ||
282 | |||
283 | clip_freq = get_cpu_frequency(cpu, cooling_state); | ||
284 | if (!clip_freq) | ||
285 | return -EINVAL; | ||
286 | |||
287 | cpufreq_device->cpufreq_state = cooling_state; | ||
288 | cpufreq_device->cpufreq_val = clip_freq; | ||
289 | 155 | ||
290 | for_each_cpu(cpuid, mask) { | 156 | mutex_lock(&cooling_cpufreq_lock); |
291 | if (is_cpufreq_valid(cpuid)) | 157 | list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) { |
292 | cpufreq_update_policy(cpuid); | 158 | if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) { |
159 | mutex_unlock(&cooling_cpufreq_lock); | ||
160 | return get_level(cpufreq_dev, freq); | ||
161 | } | ||
293 | } | 162 | } |
163 | mutex_unlock(&cooling_cpufreq_lock); | ||
294 | 164 | ||
295 | return 0; | 165 | pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu); |
166 | return THERMAL_CSTATE_INVALID; | ||
296 | } | 167 | } |
168 | EXPORT_SYMBOL_GPL(cpufreq_cooling_get_level); | ||
297 | 169 | ||
298 | /** | 170 | /** |
299 | * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. | 171 | * cpufreq_thermal_notifier - notifier callback for cpufreq policy change. |
@@ -323,11 +195,6 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, | |||
323 | &cpufreq_dev->allowed_cpus)) | 195 | &cpufreq_dev->allowed_cpus)) |
324 | continue; | 196 | continue; |
325 | 197 | ||
326 | if (!cpufreq_dev->cpufreq_val) | ||
327 | cpufreq_dev->cpufreq_val = get_cpu_frequency( | ||
328 | cpumask_any(&cpufreq_dev->allowed_cpus), | ||
329 | cpufreq_dev->cpufreq_state); | ||
330 | |||
331 | max_freq = cpufreq_dev->cpufreq_val; | 198 | max_freq = cpufreq_dev->cpufreq_val; |
332 | 199 | ||
333 | if (policy->max != max_freq) | 200 | if (policy->max != max_freq) |
@@ -354,19 +221,9 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, | |||
354 | unsigned long *state) | 221 | unsigned long *state) |
355 | { | 222 | { |
356 | struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; | 223 | struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; |
357 | struct cpumask *mask = &cpufreq_device->allowed_cpus; | ||
358 | unsigned int cpu; | ||
359 | unsigned int count = 0; | ||
360 | int ret; | ||
361 | |||
362 | cpu = cpumask_any(mask); | ||
363 | |||
364 | ret = get_property(cpu, 0, &count, GET_MAXL); | ||
365 | 224 | ||
366 | if (count > 0) | 225 | *state = cpufreq_device->max_level; |
367 | *state = count; | 226 | return 0; |
368 | |||
369 | return ret; | ||
370 | } | 227 | } |
371 | 228 | ||
372 | /** | 229 | /** |
@@ -403,8 +260,24 @@ static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, | |||
403 | unsigned long state) | 260 | unsigned long state) |
404 | { | 261 | { |
405 | struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; | 262 | struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; |
263 | unsigned int cpu = cpumask_any(&cpufreq_device->allowed_cpus); | ||
264 | unsigned int clip_freq; | ||
265 | |||
266 | /* Request state should be less than max_level */ | ||
267 | if (WARN_ON(state > cpufreq_device->max_level)) | ||
268 | return -EINVAL; | ||
269 | |||
270 | /* Check if the old cooling action is same as new cooling action */ | ||
271 | if (cpufreq_device->cpufreq_state == state) | ||
272 | return 0; | ||
406 | 273 | ||
407 | return cpufreq_apply_cooling(cpufreq_device, state); | 274 | clip_freq = cpufreq_device->freq_table[state]; |
275 | cpufreq_device->cpufreq_state = state; | ||
276 | cpufreq_device->cpufreq_val = clip_freq; | ||
277 | |||
278 | cpufreq_update_policy(cpu); | ||
279 | |||
280 | return 0; | ||
408 | } | 281 | } |
409 | 282 | ||
410 | /* Bind cpufreq callbacks to thermal cooling device ops */ | 283 | /* Bind cpufreq callbacks to thermal cooling device ops */ |
@@ -419,10 +292,25 @@ static struct notifier_block thermal_cpufreq_notifier_block = { | |||
419 | .notifier_call = cpufreq_thermal_notifier, | 292 | .notifier_call = cpufreq_thermal_notifier, |
420 | }; | 293 | }; |
421 | 294 | ||
295 | static unsigned int find_next_max(struct cpufreq_frequency_table *table, | ||
296 | unsigned int prev_max) | ||
297 | { | ||
298 | struct cpufreq_frequency_table *pos; | ||
299 | unsigned int max = 0; | ||
300 | |||
301 | cpufreq_for_each_valid_entry(pos, table) { | ||
302 | if (pos->frequency > max && pos->frequency < prev_max) | ||
303 | max = pos->frequency; | ||
304 | } | ||
305 | |||
306 | return max; | ||
307 | } | ||
308 | |||
422 | /** | 309 | /** |
423 | * __cpufreq_cooling_register - helper function to create cpufreq cooling device | 310 | * __cpufreq_cooling_register - helper function to create cpufreq cooling device |
424 | * @np: a valid struct device_node to the cooling device device tree node | 311 | * @np: a valid struct device_node to the cooling device device tree node |
425 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. | 312 | * @clip_cpus: cpumask of cpus where the frequency constraints will happen. |
313 | * Normally this should be same as cpufreq policy->related_cpus. | ||
426 | * | 314 | * |
427 | * This interface function registers the cpufreq cooling device with the name | 315 | * This interface function registers the cpufreq cooling device with the name |
428 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq | 316 | * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq |
@@ -437,37 +325,42 @@ __cpufreq_cooling_register(struct device_node *np, | |||
437 | const struct cpumask *clip_cpus) | 325 | const struct cpumask *clip_cpus) |
438 | { | 326 | { |
439 | struct thermal_cooling_device *cool_dev; | 327 | struct thermal_cooling_device *cool_dev; |
440 | struct cpufreq_cooling_device *cpufreq_dev = NULL; | 328 | struct cpufreq_cooling_device *cpufreq_dev; |
441 | unsigned int min = 0, max = 0; | ||
442 | char dev_name[THERMAL_NAME_LENGTH]; | 329 | char dev_name[THERMAL_NAME_LENGTH]; |
443 | int ret = 0, i; | 330 | struct cpufreq_frequency_table *pos, *table; |
444 | struct cpufreq_policy policy; | 331 | unsigned int freq, i; |
332 | int ret; | ||
445 | 333 | ||
446 | /* Verify that all the clip cpus have same freq_min, freq_max limit */ | 334 | table = cpufreq_frequency_get_table(cpumask_first(clip_cpus)); |
447 | for_each_cpu(i, clip_cpus) { | 335 | if (!table) { |
448 | /* continue if cpufreq policy not found and not return error */ | 336 | pr_debug("%s: CPUFreq table not found\n", __func__); |
449 | if (!cpufreq_get_policy(&policy, i)) | 337 | return ERR_PTR(-EPROBE_DEFER); |
450 | continue; | ||
451 | if (min == 0 && max == 0) { | ||
452 | min = policy.cpuinfo.min_freq; | ||
453 | max = policy.cpuinfo.max_freq; | ||
454 | } else { | ||
455 | if (min != policy.cpuinfo.min_freq || | ||
456 | max != policy.cpuinfo.max_freq) | ||
457 | return ERR_PTR(-EINVAL); | ||
458 | } | ||
459 | } | 338 | } |
460 | cpufreq_dev = kzalloc(sizeof(struct cpufreq_cooling_device), | 339 | |
461 | GFP_KERNEL); | 340 | cpufreq_dev = kzalloc(sizeof(*cpufreq_dev), GFP_KERNEL); |
462 | if (!cpufreq_dev) | 341 | if (!cpufreq_dev) |
463 | return ERR_PTR(-ENOMEM); | 342 | return ERR_PTR(-ENOMEM); |
464 | 343 | ||
344 | /* Find max levels */ | ||
345 | cpufreq_for_each_valid_entry(pos, table) | ||
346 | cpufreq_dev->max_level++; | ||
347 | |||
348 | cpufreq_dev->freq_table = kmalloc(sizeof(*cpufreq_dev->freq_table) * | ||
349 | cpufreq_dev->max_level, GFP_KERNEL); | ||
350 | if (!cpufreq_dev->freq_table) { | ||
351 | cool_dev = ERR_PTR(-ENOMEM); | ||
352 | goto free_cdev; | ||
353 | } | ||
354 | |||
355 | /* max_level is an index, not a counter */ | ||
356 | cpufreq_dev->max_level--; | ||
357 | |||
465 | cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); | 358 | cpumask_copy(&cpufreq_dev->allowed_cpus, clip_cpus); |
466 | 359 | ||
467 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); | 360 | ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); |
468 | if (ret) { | 361 | if (ret) { |
469 | kfree(cpufreq_dev); | 362 | cool_dev = ERR_PTR(ret); |
470 | return ERR_PTR(-EINVAL); | 363 | goto free_table; |
471 | } | 364 | } |
472 | 365 | ||
473 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", | 366 | snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", |
@@ -475,25 +368,44 @@ __cpufreq_cooling_register(struct device_node *np, | |||
475 | 368 | ||
476 | cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, | 369 | cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, |
477 | &cpufreq_cooling_ops); | 370 | &cpufreq_cooling_ops); |
478 | if (IS_ERR(cool_dev)) { | 371 | if (IS_ERR(cool_dev)) |
479 | release_idr(&cpufreq_idr, cpufreq_dev->id); | 372 | goto remove_idr; |
480 | kfree(cpufreq_dev); | 373 | |
481 | return cool_dev; | 374 | /* Fill freq-table in descending order of frequencies */ |
375 | for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) { | ||
376 | freq = find_next_max(table, freq); | ||
377 | cpufreq_dev->freq_table[i] = freq; | ||
378 | |||
379 | /* Warn for duplicate entries */ | ||
380 | if (!freq) | ||
381 | pr_warn("%s: table has duplicate entries\n", __func__); | ||
382 | else | ||
383 | pr_debug("%s: freq:%u KHz\n", __func__, freq); | ||
482 | } | 384 | } |
385 | |||
386 | cpufreq_dev->cpufreq_val = cpufreq_dev->freq_table[0]; | ||
483 | cpufreq_dev->cool_dev = cool_dev; | 387 | cpufreq_dev->cool_dev = cool_dev; |
484 | cpufreq_dev->cpufreq_state = 0; | 388 | |
485 | mutex_lock(&cooling_cpufreq_lock); | 389 | mutex_lock(&cooling_cpufreq_lock); |
486 | 390 | ||
487 | /* Register the notifier for first cpufreq cooling device */ | 391 | /* Register the notifier for first cpufreq cooling device */ |
488 | if (cpufreq_dev_count == 0) | 392 | if (list_empty(&cpufreq_dev_list)) |
489 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, | 393 | cpufreq_register_notifier(&thermal_cpufreq_notifier_block, |
490 | CPUFREQ_POLICY_NOTIFIER); | 394 | CPUFREQ_POLICY_NOTIFIER); |
491 | cpufreq_dev_count++; | ||
492 | list_add(&cpufreq_dev->node, &cpufreq_dev_list); | 395 | list_add(&cpufreq_dev->node, &cpufreq_dev_list); |
493 | 396 | ||
494 | mutex_unlock(&cooling_cpufreq_lock); | 397 | mutex_unlock(&cooling_cpufreq_lock); |
495 | 398 | ||
496 | return cool_dev; | 399 | return cool_dev; |
400 | |||
401 | remove_idr: | ||
402 | release_idr(&cpufreq_idr, cpufreq_dev->id); | ||
403 | free_table: | ||
404 | kfree(cpufreq_dev->freq_table); | ||
405 | free_cdev: | ||
406 | kfree(cpufreq_dev); | ||
407 | |||
408 | return cool_dev; | ||
497 | } | 409 | } |
498 | 410 | ||
499 | /** | 411 | /** |
@@ -554,16 +466,16 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) | |||
554 | cpufreq_dev = cdev->devdata; | 466 | cpufreq_dev = cdev->devdata; |
555 | mutex_lock(&cooling_cpufreq_lock); | 467 | mutex_lock(&cooling_cpufreq_lock); |
556 | list_del(&cpufreq_dev->node); | 468 | list_del(&cpufreq_dev->node); |
557 | cpufreq_dev_count--; | ||
558 | 469 | ||
559 | /* Unregister the notifier for the last cpufreq cooling device */ | 470 | /* Unregister the notifier for the last cpufreq cooling device */ |
560 | if (cpufreq_dev_count == 0) | 471 | if (list_empty(&cpufreq_dev_list)) |
561 | cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, | 472 | cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, |
562 | CPUFREQ_POLICY_NOTIFIER); | 473 | CPUFREQ_POLICY_NOTIFIER); |
563 | mutex_unlock(&cooling_cpufreq_lock); | 474 | mutex_unlock(&cooling_cpufreq_lock); |
564 | 475 | ||
565 | thermal_cooling_device_unregister(cpufreq_dev->cool_dev); | 476 | thermal_cooling_device_unregister(cpufreq_dev->cool_dev); |
566 | release_idr(&cpufreq_idr, cpufreq_dev->id); | 477 | release_idr(&cpufreq_idr, cpufreq_dev->id); |
478 | kfree(cpufreq_dev->freq_table); | ||
567 | kfree(cpufreq_dev); | 479 | kfree(cpufreq_dev); |
568 | } | 480 | } |
569 | EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); | 481 | EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister); |
diff --git a/drivers/thermal/db8500_cpufreq_cooling.c b/drivers/thermal/db8500_cpufreq_cooling.c index 000d53e934a0..607b62c7e611 100644 --- a/drivers/thermal/db8500_cpufreq_cooling.c +++ b/drivers/thermal/db8500_cpufreq_cooling.c | |||
@@ -18,7 +18,6 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/cpu_cooling.h> | 20 | #include <linux/cpu_cooling.h> |
21 | #include <linux/cpufreq.h> | ||
22 | #include <linux/err.h> | 21 | #include <linux/err.h> |
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/of.h> | 23 | #include <linux/of.h> |
@@ -28,18 +27,17 @@ | |||
28 | static int db8500_cpufreq_cooling_probe(struct platform_device *pdev) | 27 | static int db8500_cpufreq_cooling_probe(struct platform_device *pdev) |
29 | { | 28 | { |
30 | struct thermal_cooling_device *cdev; | 29 | struct thermal_cooling_device *cdev; |
31 | struct cpumask mask_val; | ||
32 | |||
33 | /* make sure cpufreq driver has been initialized */ | ||
34 | if (!cpufreq_frequency_get_table(0)) | ||
35 | return -EPROBE_DEFER; | ||
36 | |||
37 | cpumask_set_cpu(0, &mask_val); | ||
38 | cdev = cpufreq_cooling_register(&mask_val); | ||
39 | 30 | ||
31 | cdev = cpufreq_cooling_register(cpu_present_mask); | ||
40 | if (IS_ERR(cdev)) { | 32 | if (IS_ERR(cdev)) { |
41 | dev_err(&pdev->dev, "Failed to register cooling device\n"); | 33 | int ret = PTR_ERR(cdev); |
42 | return PTR_ERR(cdev); | 34 | |
35 | if (ret != -EPROBE_DEFER) | ||
36 | dev_err(&pdev->dev, | ||
37 | "Failed to register cooling device %d\n", | ||
38 | ret); | ||
39 | |||
40 | return ret; | ||
43 | } | 41 | } |
44 | 42 | ||
45 | platform_set_drvdata(pdev, cdev); | 43 | platform_set_drvdata(pdev, cdev); |
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c index 88b32f942dcf..2ccbc0788353 100644 --- a/drivers/thermal/imx_thermal.c +++ b/drivers/thermal/imx_thermal.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/cpu_cooling.h> | 11 | #include <linux/cpu_cooling.h> |
12 | #include <linux/cpufreq.h> | ||
13 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
14 | #include <linux/device.h> | 13 | #include <linux/device.h> |
15 | #include <linux/init.h> | 14 | #include <linux/init.h> |
@@ -454,15 +453,10 @@ static int imx_thermal_probe(struct platform_device *pdev) | |||
454 | const struct of_device_id *of_id = | 453 | const struct of_device_id *of_id = |
455 | of_match_device(of_imx_thermal_match, &pdev->dev); | 454 | of_match_device(of_imx_thermal_match, &pdev->dev); |
456 | struct imx_thermal_data *data; | 455 | struct imx_thermal_data *data; |
457 | struct cpumask clip_cpus; | ||
458 | struct regmap *map; | 456 | struct regmap *map; |
459 | int measure_freq; | 457 | int measure_freq; |
460 | int ret; | 458 | int ret; |
461 | 459 | ||
462 | if (!cpufreq_get_current_driver()) { | ||
463 | dev_dbg(&pdev->dev, "no cpufreq driver!"); | ||
464 | return -EPROBE_DEFER; | ||
465 | } | ||
466 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 460 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
467 | if (!data) | 461 | if (!data) |
468 | return -ENOMEM; | 462 | return -ENOMEM; |
@@ -516,12 +510,13 @@ static int imx_thermal_probe(struct platform_device *pdev) | |||
516 | regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); | 510 | regmap_write(map, MISC0 + REG_SET, MISC0_REFTOP_SELBIASOFF); |
517 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); | 511 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); |
518 | 512 | ||
519 | cpumask_set_cpu(0, &clip_cpus); | 513 | data->cdev = cpufreq_cooling_register(cpu_present_mask); |
520 | data->cdev = cpufreq_cooling_register(&clip_cpus); | ||
521 | if (IS_ERR(data->cdev)) { | 514 | if (IS_ERR(data->cdev)) { |
522 | ret = PTR_ERR(data->cdev); | 515 | ret = PTR_ERR(data->cdev); |
523 | dev_err(&pdev->dev, | 516 | if (ret != -EPROBE_DEFER) |
524 | "failed to register cpufreq cooling device: %d\n", ret); | 517 | dev_err(&pdev->dev, |
518 | "failed to register cpufreq cooling device: %d\n", | ||
519 | ret); | ||
525 | return ret; | 520 | return ret; |
526 | } | 521 | } |
527 | 522 | ||
@@ -613,6 +608,7 @@ static int imx_thermal_suspend(struct device *dev) | |||
613 | regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); | 608 | regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_MEASURE_TEMP); |
614 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); | 609 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_POWER_DOWN); |
615 | data->mode = THERMAL_DEVICE_DISABLED; | 610 | data->mode = THERMAL_DEVICE_DISABLED; |
611 | clk_disable_unprepare(data->thermal_clk); | ||
616 | 612 | ||
617 | return 0; | 613 | return 0; |
618 | } | 614 | } |
@@ -622,6 +618,7 @@ static int imx_thermal_resume(struct device *dev) | |||
622 | struct imx_thermal_data *data = dev_get_drvdata(dev); | 618 | struct imx_thermal_data *data = dev_get_drvdata(dev); |
623 | struct regmap *map = data->tempmon; | 619 | struct regmap *map = data->tempmon; |
624 | 620 | ||
621 | clk_prepare_enable(data->thermal_clk); | ||
625 | /* Enabled thermal sensor after resume */ | 622 | /* Enabled thermal sensor after resume */ |
626 | regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); | 623 | regmap_write(map, TEMPSENSE0 + REG_CLR, TEMPSENSE0_POWER_DOWN); |
627 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); | 624 | regmap_write(map, TEMPSENSE0 + REG_SET, TEMPSENSE0_MEASURE_TEMP); |
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile index ffe40bffaf1a..d4413698a85f 100644 --- a/drivers/thermal/int340x_thermal/Makefile +++ b/drivers/thermal/int340x_thermal/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o | 1 | obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o |
2 | obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o | 2 | obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o |
3 | obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o | 3 | obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o |
4 | obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o | ||
4 | obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o | 5 | obj-$(CONFIG_ACPI_THERMAL_REL) += acpi_thermal_rel.o |
diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index e4e61b3fb11e..2c2ec7666eb1 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c | |||
@@ -82,7 +82,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, | |||
82 | struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; | 82 | struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" }; |
83 | 83 | ||
84 | if (!acpi_has_method(handle, "_TRT")) | 84 | if (!acpi_has_method(handle, "_TRT")) |
85 | return 0; | 85 | return -ENODEV; |
86 | 86 | ||
87 | status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); | 87 | status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer); |
88 | if (ACPI_FAILURE(status)) | 88 | if (ACPI_FAILURE(status)) |
@@ -119,15 +119,11 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, | |||
119 | continue; | 119 | continue; |
120 | 120 | ||
121 | result = acpi_bus_get_device(trt->source, &adev); | 121 | result = acpi_bus_get_device(trt->source, &adev); |
122 | if (!result) | 122 | if (result) |
123 | acpi_create_platform_device(adev); | ||
124 | else | ||
125 | pr_warn("Failed to get source ACPI device\n"); | 123 | pr_warn("Failed to get source ACPI device\n"); |
126 | 124 | ||
127 | result = acpi_bus_get_device(trt->target, &adev); | 125 | result = acpi_bus_get_device(trt->target, &adev); |
128 | if (!result) | 126 | if (result) |
129 | acpi_create_platform_device(adev); | ||
130 | else | ||
131 | pr_warn("Failed to get target ACPI device\n"); | 127 | pr_warn("Failed to get target ACPI device\n"); |
132 | } | 128 | } |
133 | 129 | ||
@@ -167,7 +163,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, | |||
167 | sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; | 163 | sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" }; |
168 | 164 | ||
169 | if (!acpi_has_method(handle, "_ART")) | 165 | if (!acpi_has_method(handle, "_ART")) |
170 | return 0; | 166 | return -ENODEV; |
171 | 167 | ||
172 | status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); | 168 | status = acpi_evaluate_object(handle, "_ART", NULL, &buffer); |
173 | if (ACPI_FAILURE(status)) | 169 | if (ACPI_FAILURE(status)) |
@@ -206,16 +202,12 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, | |||
206 | 202 | ||
207 | if (art->source) { | 203 | if (art->source) { |
208 | result = acpi_bus_get_device(art->source, &adev); | 204 | result = acpi_bus_get_device(art->source, &adev); |
209 | if (!result) | 205 | if (result) |
210 | acpi_create_platform_device(adev); | ||
211 | else | ||
212 | pr_warn("Failed to get source ACPI device\n"); | 206 | pr_warn("Failed to get source ACPI device\n"); |
213 | } | 207 | } |
214 | if (art->target) { | 208 | if (art->target) { |
215 | result = acpi_bus_get_device(art->target, &adev); | 209 | result = acpi_bus_get_device(art->target, &adev); |
216 | if (!result) | 210 | if (result) |
217 | acpi_create_platform_device(adev); | ||
218 | else | ||
219 | pr_warn("Failed to get source ACPI device\n"); | 211 | pr_warn("Failed to get source ACPI device\n"); |
220 | } | 212 | } |
221 | } | 213 | } |
@@ -321,8 +313,8 @@ static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd, | |||
321 | unsigned long length = 0; | 313 | unsigned long length = 0; |
322 | int count = 0; | 314 | int count = 0; |
323 | char __user *arg = (void __user *)__arg; | 315 | char __user *arg = (void __user *)__arg; |
324 | struct trt *trts; | 316 | struct trt *trts = NULL; |
325 | struct art *arts; | 317 | struct art *arts = NULL; |
326 | 318 | ||
327 | switch (cmd) { | 319 | switch (cmd) { |
328 | case ACPI_THERMAL_GET_TRT_COUNT: | 320 | case ACPI_THERMAL_GET_TRT_COUNT: |
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c index dcb306ea14a4..65a98a97df07 100644 --- a/drivers/thermal/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/int340x_thermal/int3400_thermal.c | |||
@@ -335,7 +335,6 @@ static struct platform_driver int3400_thermal_driver = { | |||
335 | .remove = int3400_thermal_remove, | 335 | .remove = int3400_thermal_remove, |
336 | .driver = { | 336 | .driver = { |
337 | .name = "int3400 thermal", | 337 | .name = "int3400 thermal", |
338 | .owner = THIS_MODULE, | ||
339 | .acpi_match_table = ACPI_PTR(int3400_thermal_match), | 338 | .acpi_match_table = ACPI_PTR(int3400_thermal_match), |
340 | }, | 339 | }, |
341 | }; | 340 | }; |
diff --git a/drivers/thermal/int340x_thermal/int3402_thermal.c b/drivers/thermal/int340x_thermal/int3402_thermal.c index a5d08c14ba24..c5cbc3af3a05 100644 --- a/drivers/thermal/int340x_thermal/int3402_thermal.c +++ b/drivers/thermal/int340x_thermal/int3402_thermal.c | |||
@@ -231,7 +231,6 @@ static struct platform_driver int3402_thermal_driver = { | |||
231 | .remove = int3402_thermal_remove, | 231 | .remove = int3402_thermal_remove, |
232 | .driver = { | 232 | .driver = { |
233 | .name = "int3402 thermal", | 233 | .name = "int3402 thermal", |
234 | .owner = THIS_MODULE, | ||
235 | .acpi_match_table = int3402_thermal_match, | 234 | .acpi_match_table = int3402_thermal_match, |
236 | }, | 235 | }, |
237 | }; | 236 | }; |
diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c index 1bfa6a69e77a..0faf500d8a77 100644 --- a/drivers/thermal/int340x_thermal/int3403_thermal.c +++ b/drivers/thermal/int340x_thermal/int3403_thermal.c | |||
@@ -301,6 +301,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv) | |||
301 | { | 301 | { |
302 | struct int3403_sensor *obj = priv->priv; | 302 | struct int3403_sensor *obj = priv->priv; |
303 | 303 | ||
304 | acpi_remove_notify_handler(priv->adev->handle, | ||
305 | ACPI_DEVICE_NOTIFY, int3403_notify); | ||
304 | thermal_zone_device_unregister(obj->tzone); | 306 | thermal_zone_device_unregister(obj->tzone); |
305 | return 0; | 307 | return 0; |
306 | } | 308 | } |
@@ -369,6 +371,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) | |||
369 | p = buf.pointer; | 371 | p = buf.pointer; |
370 | if (!p || (p->type != ACPI_TYPE_PACKAGE)) { | 372 | if (!p || (p->type != ACPI_TYPE_PACKAGE)) { |
371 | printk(KERN_WARNING "Invalid PPSS data\n"); | 373 | printk(KERN_WARNING "Invalid PPSS data\n"); |
374 | kfree(buf.pointer); | ||
372 | return -EFAULT; | 375 | return -EFAULT; |
373 | } | 376 | } |
374 | 377 | ||
@@ -381,6 +384,7 @@ static int int3403_cdev_add(struct int3403_priv *priv) | |||
381 | 384 | ||
382 | priv->priv = obj; | 385 | priv->priv = obj; |
383 | 386 | ||
387 | kfree(buf.pointer); | ||
384 | /* TODO: add ACPI notification support */ | 388 | /* TODO: add ACPI notification support */ |
385 | 389 | ||
386 | return result; | 390 | return result; |
diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c new file mode 100644 index 000000000000..0fe5dbbea968 --- /dev/null +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c | |||
@@ -0,0 +1,311 @@ | |||
1 | /* | ||
2 | * processor_thermal_device.c | ||
3 | * Copyright (c) 2014, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/acpi.h> | ||
21 | |||
22 | /* Broadwell-U/HSB thermal reporting device */ | ||
23 | #define PCI_DEVICE_ID_PROC_BDW_THERMAL 0x1603 | ||
24 | #define PCI_DEVICE_ID_PROC_HSB_THERMAL 0x0A03 | ||
25 | |||
26 | /* Braswell thermal reporting device */ | ||
27 | #define PCI_DEVICE_ID_PROC_BSW_THERMAL 0x22DC | ||
28 | |||
29 | struct power_config { | ||
30 | u32 index; | ||
31 | u32 min_uw; | ||
32 | u32 max_uw; | ||
33 | u32 tmin_us; | ||
34 | u32 tmax_us; | ||
35 | u32 step_uw; | ||
36 | }; | ||
37 | |||
38 | struct proc_thermal_device { | ||
39 | struct device *dev; | ||
40 | struct acpi_device *adev; | ||
41 | struct power_config power_limits[2]; | ||
42 | }; | ||
43 | |||
44 | enum proc_thermal_emum_mode_type { | ||
45 | PROC_THERMAL_NONE, | ||
46 | PROC_THERMAL_PCI, | ||
47 | PROC_THERMAL_PLATFORM_DEV | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * We can have only one type of enumeration, PCI or Platform, | ||
52 | * not both. So we don't need instance specific data. | ||
53 | */ | ||
54 | static enum proc_thermal_emum_mode_type proc_thermal_emum_mode = | ||
55 | PROC_THERMAL_NONE; | ||
56 | |||
57 | #define POWER_LIMIT_SHOW(index, suffix) \ | ||
58 | static ssize_t power_limit_##index##_##suffix##_show(struct device *dev, \ | ||
59 | struct device_attribute *attr, \ | ||
60 | char *buf) \ | ||
61 | { \ | ||
62 | struct pci_dev *pci_dev; \ | ||
63 | struct platform_device *pdev; \ | ||
64 | struct proc_thermal_device *proc_dev; \ | ||
65 | \ | ||
66 | if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { \ | ||
67 | pdev = to_platform_device(dev); \ | ||
68 | proc_dev = platform_get_drvdata(pdev); \ | ||
69 | } else { \ | ||
70 | pci_dev = to_pci_dev(dev); \ | ||
71 | proc_dev = pci_get_drvdata(pci_dev); \ | ||
72 | } \ | ||
73 | return sprintf(buf, "%lu\n",\ | ||
74 | (unsigned long)proc_dev->power_limits[index].suffix * 1000); \ | ||
75 | } | ||
76 | |||
77 | POWER_LIMIT_SHOW(0, min_uw) | ||
78 | POWER_LIMIT_SHOW(0, max_uw) | ||
79 | POWER_LIMIT_SHOW(0, step_uw) | ||
80 | POWER_LIMIT_SHOW(0, tmin_us) | ||
81 | POWER_LIMIT_SHOW(0, tmax_us) | ||
82 | |||
83 | POWER_LIMIT_SHOW(1, min_uw) | ||
84 | POWER_LIMIT_SHOW(1, max_uw) | ||
85 | POWER_LIMIT_SHOW(1, step_uw) | ||
86 | POWER_LIMIT_SHOW(1, tmin_us) | ||
87 | POWER_LIMIT_SHOW(1, tmax_us) | ||
88 | |||
89 | static DEVICE_ATTR_RO(power_limit_0_min_uw); | ||
90 | static DEVICE_ATTR_RO(power_limit_0_max_uw); | ||
91 | static DEVICE_ATTR_RO(power_limit_0_step_uw); | ||
92 | static DEVICE_ATTR_RO(power_limit_0_tmin_us); | ||
93 | static DEVICE_ATTR_RO(power_limit_0_tmax_us); | ||
94 | |||
95 | static DEVICE_ATTR_RO(power_limit_1_min_uw); | ||
96 | static DEVICE_ATTR_RO(power_limit_1_max_uw); | ||
97 | static DEVICE_ATTR_RO(power_limit_1_step_uw); | ||
98 | static DEVICE_ATTR_RO(power_limit_1_tmin_us); | ||
99 | static DEVICE_ATTR_RO(power_limit_1_tmax_us); | ||
100 | |||
101 | static struct attribute *power_limit_attrs[] = { | ||
102 | &dev_attr_power_limit_0_min_uw.attr, | ||
103 | &dev_attr_power_limit_1_min_uw.attr, | ||
104 | &dev_attr_power_limit_0_max_uw.attr, | ||
105 | &dev_attr_power_limit_1_max_uw.attr, | ||
106 | &dev_attr_power_limit_0_step_uw.attr, | ||
107 | &dev_attr_power_limit_1_step_uw.attr, | ||
108 | &dev_attr_power_limit_0_tmin_us.attr, | ||
109 | &dev_attr_power_limit_1_tmin_us.attr, | ||
110 | &dev_attr_power_limit_0_tmax_us.attr, | ||
111 | &dev_attr_power_limit_1_tmax_us.attr, | ||
112 | NULL | ||
113 | }; | ||
114 | |||
115 | static struct attribute_group power_limit_attribute_group = { | ||
116 | .attrs = power_limit_attrs, | ||
117 | .name = "power_limits" | ||
118 | }; | ||
119 | |||
120 | static int proc_thermal_add(struct device *dev, | ||
121 | struct proc_thermal_device **priv) | ||
122 | { | ||
123 | struct proc_thermal_device *proc_priv; | ||
124 | struct acpi_device *adev; | ||
125 | acpi_status status; | ||
126 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
127 | union acpi_object *elements, *ppcc; | ||
128 | union acpi_object *p; | ||
129 | int i; | ||
130 | int ret; | ||
131 | |||
132 | adev = ACPI_COMPANION(dev); | ||
133 | if (!adev) | ||
134 | return -ENODEV; | ||
135 | |||
136 | status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf); | ||
137 | if (ACPI_FAILURE(status)) | ||
138 | return -ENODEV; | ||
139 | |||
140 | p = buf.pointer; | ||
141 | if (!p || (p->type != ACPI_TYPE_PACKAGE)) { | ||
142 | dev_err(dev, "Invalid PPCC data\n"); | ||
143 | ret = -EFAULT; | ||
144 | goto free_buffer; | ||
145 | } | ||
146 | if (!p->package.count) { | ||
147 | dev_err(dev, "Invalid PPCC package size\n"); | ||
148 | ret = -EFAULT; | ||
149 | goto free_buffer; | ||
150 | } | ||
151 | |||
152 | proc_priv = devm_kzalloc(dev, sizeof(*proc_priv), GFP_KERNEL); | ||
153 | if (!proc_priv) { | ||
154 | ret = -ENOMEM; | ||
155 | goto free_buffer; | ||
156 | } | ||
157 | |||
158 | proc_priv->dev = dev; | ||
159 | proc_priv->adev = adev; | ||
160 | |||
161 | for (i = 0; i < min((int)p->package.count - 1, 2); ++i) { | ||
162 | elements = &(p->package.elements[i+1]); | ||
163 | if (elements->type != ACPI_TYPE_PACKAGE || | ||
164 | elements->package.count != 6) { | ||
165 | ret = -EFAULT; | ||
166 | goto free_buffer; | ||
167 | } | ||
168 | ppcc = elements->package.elements; | ||
169 | proc_priv->power_limits[i].index = ppcc[0].integer.value; | ||
170 | proc_priv->power_limits[i].min_uw = ppcc[1].integer.value; | ||
171 | proc_priv->power_limits[i].max_uw = ppcc[2].integer.value; | ||
172 | proc_priv->power_limits[i].tmin_us = ppcc[3].integer.value; | ||
173 | proc_priv->power_limits[i].tmax_us = ppcc[4].integer.value; | ||
174 | proc_priv->power_limits[i].step_uw = ppcc[5].integer.value; | ||
175 | } | ||
176 | |||
177 | *priv = proc_priv; | ||
178 | |||
179 | ret = sysfs_create_group(&dev->kobj, | ||
180 | &power_limit_attribute_group); | ||
181 | |||
182 | free_buffer: | ||
183 | kfree(buf.pointer); | ||
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | void proc_thermal_remove(struct proc_thermal_device *proc_priv) | ||
189 | { | ||
190 | sysfs_remove_group(&proc_priv->dev->kobj, | ||
191 | &power_limit_attribute_group); | ||
192 | } | ||
193 | |||
194 | static int int3401_add(struct platform_device *pdev) | ||
195 | { | ||
196 | struct proc_thermal_device *proc_priv; | ||
197 | int ret; | ||
198 | |||
199 | if (proc_thermal_emum_mode == PROC_THERMAL_PCI) { | ||
200 | dev_err(&pdev->dev, "error: enumerated as PCI dev\n"); | ||
201 | return -ENODEV; | ||
202 | } | ||
203 | |||
204 | ret = proc_thermal_add(&pdev->dev, &proc_priv); | ||
205 | if (ret) | ||
206 | return ret; | ||
207 | |||
208 | platform_set_drvdata(pdev, proc_priv); | ||
209 | proc_thermal_emum_mode = PROC_THERMAL_PLATFORM_DEV; | ||
210 | |||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static int int3401_remove(struct platform_device *pdev) | ||
215 | { | ||
216 | proc_thermal_remove(platform_get_drvdata(pdev)); | ||
217 | |||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int proc_thermal_pci_probe(struct pci_dev *pdev, | ||
222 | const struct pci_device_id *unused) | ||
223 | { | ||
224 | struct proc_thermal_device *proc_priv; | ||
225 | int ret; | ||
226 | |||
227 | if (proc_thermal_emum_mode == PROC_THERMAL_PLATFORM_DEV) { | ||
228 | dev_err(&pdev->dev, "error: enumerated as platform dev\n"); | ||
229 | return -ENODEV; | ||
230 | } | ||
231 | |||
232 | ret = pci_enable_device(pdev); | ||
233 | if (ret < 0) { | ||
234 | dev_err(&pdev->dev, "error: could not enable device\n"); | ||
235 | return ret; | ||
236 | } | ||
237 | |||
238 | ret = proc_thermal_add(&pdev->dev, &proc_priv); | ||
239 | if (ret) { | ||
240 | pci_disable_device(pdev); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | pci_set_drvdata(pdev, proc_priv); | ||
245 | proc_thermal_emum_mode = PROC_THERMAL_PCI; | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static void proc_thermal_pci_remove(struct pci_dev *pdev) | ||
251 | { | ||
252 | proc_thermal_remove(pci_get_drvdata(pdev)); | ||
253 | pci_disable_device(pdev); | ||
254 | } | ||
255 | |||
256 | static const struct pci_device_id proc_thermal_pci_ids[] = { | ||
257 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BDW_THERMAL)}, | ||
258 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_HSB_THERMAL)}, | ||
259 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_BSW_THERMAL)}, | ||
260 | { 0, }, | ||
261 | }; | ||
262 | |||
263 | MODULE_DEVICE_TABLE(pci, proc_thermal_pci_ids); | ||
264 | |||
265 | static struct pci_driver proc_thermal_pci_driver = { | ||
266 | .name = "proc_thermal", | ||
267 | .probe = proc_thermal_pci_probe, | ||
268 | .remove = proc_thermal_pci_remove, | ||
269 | .id_table = proc_thermal_pci_ids, | ||
270 | }; | ||
271 | |||
272 | static const struct acpi_device_id int3401_device_ids[] = { | ||
273 | {"INT3401", 0}, | ||
274 | {"", 0}, | ||
275 | }; | ||
276 | MODULE_DEVICE_TABLE(acpi, int3401_device_ids); | ||
277 | |||
278 | static struct platform_driver int3401_driver = { | ||
279 | .probe = int3401_add, | ||
280 | .remove = int3401_remove, | ||
281 | .driver = { | ||
282 | .name = "int3401 thermal", | ||
283 | .acpi_match_table = int3401_device_ids, | ||
284 | }, | ||
285 | }; | ||
286 | |||
287 | static int __init proc_thermal_init(void) | ||
288 | { | ||
289 | int ret; | ||
290 | |||
291 | ret = platform_driver_register(&int3401_driver); | ||
292 | if (ret) | ||
293 | return ret; | ||
294 | |||
295 | ret = pci_register_driver(&proc_thermal_pci_driver); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | static void __exit proc_thermal_exit(void) | ||
301 | { | ||
302 | platform_driver_unregister(&int3401_driver); | ||
303 | pci_unregister_driver(&proc_thermal_pci_driver); | ||
304 | } | ||
305 | |||
306 | module_init(proc_thermal_init); | ||
307 | module_exit(proc_thermal_exit); | ||
308 | |||
309 | MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>"); | ||
310 | MODULE_DESCRIPTION("Processor Thermal Reporting Device Driver"); | ||
311 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c index e98b4249187c..6ceebd659dd4 100644 --- a/drivers/thermal/intel_powerclamp.c +++ b/drivers/thermal/intel_powerclamp.c | |||
@@ -688,6 +688,7 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = { | |||
688 | { X86_VENDOR_INTEL, 6, 0x45}, | 688 | { X86_VENDOR_INTEL, 6, 0x45}, |
689 | { X86_VENDOR_INTEL, 6, 0x46}, | 689 | { X86_VENDOR_INTEL, 6, 0x46}, |
690 | { X86_VENDOR_INTEL, 6, 0x4c}, | 690 | { X86_VENDOR_INTEL, 6, 0x4c}, |
691 | { X86_VENDOR_INTEL, 6, 0x56}, | ||
691 | {} | 692 | {} |
692 | }; | 693 | }; |
693 | MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); | 694 | MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids); |
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c index e145b66df444..d717f3dab6f1 100644 --- a/drivers/thermal/of-thermal.c +++ b/drivers/thermal/of-thermal.c | |||
@@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(of_thermal_is_trip_valid); | |||
149 | * | 149 | * |
150 | * Return: pointer to trip points table, NULL otherwise | 150 | * Return: pointer to trip points table, NULL otherwise |
151 | */ | 151 | */ |
152 | const struct thermal_trip * const | 152 | const struct thermal_trip * |
153 | of_thermal_get_trip_points(struct thermal_zone_device *tz) | 153 | of_thermal_get_trip_points(struct thermal_zone_device *tz) |
154 | { | 154 | { |
155 | struct __thermal_zone *data = tz->devdata; | 155 | struct __thermal_zone *data = tz->devdata; |
diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 8803e693fe68..2580a4872f90 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c | |||
@@ -63,7 +63,7 @@ struct rcar_thermal_priv { | |||
63 | struct mutex lock; | 63 | struct mutex lock; |
64 | struct list_head list; | 64 | struct list_head list; |
65 | int id; | 65 | int id; |
66 | int ctemp; | 66 | u32 ctemp; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | #define rcar_thermal_for_each_priv(pos, common) \ | 69 | #define rcar_thermal_for_each_priv(pos, common) \ |
@@ -145,7 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) | |||
145 | { | 145 | { |
146 | struct device *dev = rcar_priv_to_dev(priv); | 146 | struct device *dev = rcar_priv_to_dev(priv); |
147 | int i; | 147 | int i; |
148 | int ctemp, old, new; | 148 | u32 ctemp, old, new; |
149 | int ret = -EINVAL; | 149 | int ret = -EINVAL; |
150 | 150 | ||
151 | mutex_lock(&priv->lock); | 151 | mutex_lock(&priv->lock); |
@@ -372,6 +372,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
372 | int i; | 372 | int i; |
373 | int ret = -ENODEV; | 373 | int ret = -ENODEV; |
374 | int idle = IDLE_INTERVAL; | 374 | int idle = IDLE_INTERVAL; |
375 | u32 enr_bits = 0; | ||
375 | 376 | ||
376 | common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); | 377 | common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); |
377 | if (!common) | 378 | if (!common) |
@@ -390,7 +391,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
390 | 391 | ||
391 | /* | 392 | /* |
392 | * platform has IRQ support. | 393 | * platform has IRQ support. |
393 | * Then, drier use common register | 394 | * Then, driver uses common registers |
394 | */ | 395 | */ |
395 | 396 | ||
396 | ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0, | 397 | ret = devm_request_irq(dev, irq->start, rcar_thermal_irq, 0, |
@@ -408,9 +409,6 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
408 | if (IS_ERR(common->base)) | 409 | if (IS_ERR(common->base)) |
409 | return PTR_ERR(common->base); | 410 | return PTR_ERR(common->base); |
410 | 411 | ||
411 | /* enable temperature comparation */ | ||
412 | rcar_thermal_common_write(common, ENR, 0x00030303); | ||
413 | |||
414 | idle = 0; /* polling delay is not needed */ | 412 | idle = 0; /* polling delay is not needed */ |
415 | } | 413 | } |
416 | 414 | ||
@@ -452,8 +450,15 @@ static int rcar_thermal_probe(struct platform_device *pdev) | |||
452 | rcar_thermal_irq_enable(priv); | 450 | rcar_thermal_irq_enable(priv); |
453 | 451 | ||
454 | list_move_tail(&priv->list, &common->head); | 452 | list_move_tail(&priv->list, &common->head); |
453 | |||
454 | /* update ENR bits */ | ||
455 | enr_bits |= 3 << (i * 8); | ||
455 | } | 456 | } |
456 | 457 | ||
458 | /* enable temperature comparation */ | ||
459 | if (irq) | ||
460 | rcar_thermal_common_write(common, ENR, enr_bits); | ||
461 | |||
457 | platform_set_drvdata(pdev, common); | 462 | platform_set_drvdata(pdev, common); |
458 | 463 | ||
459 | dev_info(dev, "%d sensor probed\n", i); | 464 | dev_info(dev, "%d sensor probed\n", i); |
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index 1bcddfc60e91..9c6ce548e363 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c | |||
@@ -677,7 +677,6 @@ static SIMPLE_DEV_PM_OPS(rockchip_thermal_pm_ops, | |||
677 | static struct platform_driver rockchip_thermal_driver = { | 677 | static struct platform_driver rockchip_thermal_driver = { |
678 | .driver = { | 678 | .driver = { |
679 | .name = "rockchip-thermal", | 679 | .name = "rockchip-thermal", |
680 | .owner = THIS_MODULE, | ||
681 | .pm = &rockchip_thermal_pm_ops, | 680 | .pm = &rockchip_thermal_pm_ops, |
682 | .of_match_table = of_rockchip_thermal_match, | 681 | .of_match_table = of_rockchip_thermal_match, |
683 | }, | 682 | }, |
diff --git a/drivers/thermal/samsung/Kconfig b/drivers/thermal/samsung/Kconfig index f760389a204c..c43306ecc0ab 100644 --- a/drivers/thermal/samsung/Kconfig +++ b/drivers/thermal/samsung/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config EXYNOS_THERMAL | 1 | config EXYNOS_THERMAL |
2 | tristate "Exynos thermal management unit driver" | 2 | tristate "Exynos thermal management unit driver" |
3 | depends on ARCH_HAS_BANDGAP && OF | 3 | depends on OF |
4 | help | 4 | help |
5 | If you say yes here you get support for the TMU (Thermal Management | 5 | If you say yes here you get support for the TMU (Thermal Management |
6 | Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises | 6 | Unit) driver for SAMSUNG EXYNOS series of SoCs. This driver initialises |
diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index b6be572704a4..6dc3815cc73f 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c | |||
@@ -347,7 +347,6 @@ void exynos_report_trigger(struct thermal_sensor_conf *conf) | |||
347 | int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) | 347 | int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) |
348 | { | 348 | { |
349 | int ret; | 349 | int ret; |
350 | struct cpumask mask_val; | ||
351 | struct exynos_thermal_zone *th_zone; | 350 | struct exynos_thermal_zone *th_zone; |
352 | 351 | ||
353 | if (!sensor_conf || !sensor_conf->read_temperature) { | 352 | if (!sensor_conf || !sensor_conf->read_temperature) { |
@@ -367,13 +366,14 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) | |||
367 | * sensor | 366 | * sensor |
368 | */ | 367 | */ |
369 | if (sensor_conf->cooling_data.freq_clip_count > 0) { | 368 | if (sensor_conf->cooling_data.freq_clip_count > 0) { |
370 | cpumask_set_cpu(0, &mask_val); | ||
371 | th_zone->cool_dev[th_zone->cool_dev_size] = | 369 | th_zone->cool_dev[th_zone->cool_dev_size] = |
372 | cpufreq_cooling_register(&mask_val); | 370 | cpufreq_cooling_register(cpu_present_mask); |
373 | if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) { | 371 | if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) { |
374 | dev_err(sensor_conf->dev, | 372 | ret = PTR_ERR(th_zone->cool_dev[th_zone->cool_dev_size]); |
375 | "Failed to register cpufreq cooling device\n"); | 373 | if (ret != -EPROBE_DEFER) |
376 | ret = -EINVAL; | 374 | dev_err(sensor_conf->dev, |
375 | "Failed to register cpufreq cooling device: %d\n", | ||
376 | ret); | ||
377 | goto err_unregister; | 377 | goto err_unregister; |
378 | } | 378 | } |
379 | th_zone->cool_dev_size++; | 379 | th_zone->cool_dev_size++; |
diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index d44d91d681d4..d2f1e62a4232 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c | |||
@@ -927,7 +927,10 @@ static int exynos_tmu_probe(struct platform_device *pdev) | |||
927 | /* Register the sensor with thermal management interface */ | 927 | /* Register the sensor with thermal management interface */ |
928 | ret = exynos_register_thermal(sensor_conf); | 928 | ret = exynos_register_thermal(sensor_conf); |
929 | if (ret) { | 929 | if (ret) { |
930 | dev_err(&pdev->dev, "Failed to register thermal interface\n"); | 930 | if (ret != -EPROBE_DEFER) |
931 | dev_err(&pdev->dev, | ||
932 | "Failed to register thermal interface: %d\n", | ||
933 | ret); | ||
931 | goto err_clk; | 934 | goto err_clk; |
932 | } | 935 | } |
933 | data->reg_conf = sensor_conf; | 936 | data->reg_conf = sensor_conf; |
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 84fdf0792e27..87e0b0782023 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c | |||
@@ -930,7 +930,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, | |||
930 | struct thermal_zone_device *pos1; | 930 | struct thermal_zone_device *pos1; |
931 | struct thermal_cooling_device *pos2; | 931 | struct thermal_cooling_device *pos2; |
932 | unsigned long max_state; | 932 | unsigned long max_state; |
933 | int result; | 933 | int result, ret; |
934 | 934 | ||
935 | if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) | 935 | if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE)) |
936 | return -EINVAL; | 936 | return -EINVAL; |
@@ -947,7 +947,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, | |||
947 | if (tz != pos1 || cdev != pos2) | 947 | if (tz != pos1 || cdev != pos2) |
948 | return -EINVAL; | 948 | return -EINVAL; |
949 | 949 | ||
950 | cdev->ops->get_max_state(cdev, &max_state); | 950 | ret = cdev->ops->get_max_state(cdev, &max_state); |
951 | if (ret) | ||
952 | return ret; | ||
951 | 953 | ||
952 | /* lower default 0, upper default max_state */ | 954 | /* lower default 0, upper default max_state */ |
953 | lower = lower == THERMAL_NO_LIMIT ? 0 : lower; | 955 | lower = lower == THERMAL_NO_LIMIT ? 0 : lower; |
diff --git a/drivers/thermal/thermal_core.h b/drivers/thermal/thermal_core.h index 9083e7520623..0531c752fbbb 100644 --- a/drivers/thermal/thermal_core.h +++ b/drivers/thermal/thermal_core.h | |||
@@ -91,7 +91,7 @@ int of_parse_thermal_zones(void); | |||
91 | void of_thermal_destroy_zones(void); | 91 | void of_thermal_destroy_zones(void); |
92 | int of_thermal_get_ntrips(struct thermal_zone_device *); | 92 | int of_thermal_get_ntrips(struct thermal_zone_device *); |
93 | bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); | 93 | bool of_thermal_is_trip_valid(struct thermal_zone_device *, int); |
94 | const struct thermal_trip * const | 94 | const struct thermal_trip * |
95 | of_thermal_get_trip_points(struct thermal_zone_device *); | 95 | of_thermal_get_trip_points(struct thermal_zone_device *); |
96 | #else | 96 | #else |
97 | static inline int of_parse_thermal_zones(void) { return 0; } | 97 | static inline int of_parse_thermal_zones(void) { return 0; } |
@@ -105,7 +105,7 @@ static inline bool of_thermal_is_trip_valid(struct thermal_zone_device *tz, | |||
105 | { | 105 | { |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | static inline const struct thermal_trip * const | 108 | static inline const struct thermal_trip * |
109 | of_thermal_get_trip_points(struct thermal_zone_device *tz) | 109 | of_thermal_get_trip_points(struct thermal_zone_device *tz) |
110 | { | 110 | { |
111 | return NULL; | 111 | return NULL; |
diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 5fd03865e396..3fb054a10f6a 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
30 | #include <linux/thermal.h> | 30 | #include <linux/thermal.h> |
31 | #include <linux/cpufreq.h> | ||
32 | #include <linux/cpumask.h> | 31 | #include <linux/cpumask.h> |
33 | #include <linux/cpu_cooling.h> | 32 | #include <linux/cpu_cooling.h> |
34 | #include <linux/of.h> | 33 | #include <linux/of.h> |
@@ -407,17 +406,17 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) | |||
407 | if (!data) | 406 | if (!data) |
408 | return -EINVAL; | 407 | return -EINVAL; |
409 | 408 | ||
410 | if (!cpufreq_get_current_driver()) { | ||
411 | dev_dbg(bgp->dev, "no cpufreq driver yet\n"); | ||
412 | return -EPROBE_DEFER; | ||
413 | } | ||
414 | |||
415 | /* Register cooling device */ | 409 | /* Register cooling device */ |
416 | data->cool_dev = cpufreq_cooling_register(cpu_present_mask); | 410 | data->cool_dev = cpufreq_cooling_register(cpu_present_mask); |
417 | if (IS_ERR(data->cool_dev)) { | 411 | if (IS_ERR(data->cool_dev)) { |
418 | dev_err(bgp->dev, | 412 | int ret = PTR_ERR(data->cool_dev); |
419 | "Failed to register cpufreq cooling device\n"); | 413 | |
420 | return PTR_ERR(data->cool_dev); | 414 | if (ret != -EPROBE_DEFER) |
415 | dev_err(bgp->dev, | ||
416 | "Failed to register cpu cooling device %d\n", | ||
417 | ret); | ||
418 | |||
419 | return ret; | ||
421 | } | 420 | } |
422 | ti_bandgap_set_sensor_data(bgp, id, data); | 421 | ti_bandgap_set_sensor_data(bgp, id, data); |
423 | 422 | ||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d2b496750d59..4ddfa60c9222 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -2399,17 +2399,12 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, | |||
2399 | 2399 | ||
2400 | poll_wait(file, &tty->read_wait, wait); | 2400 | poll_wait(file, &tty->read_wait, wait); |
2401 | poll_wait(file, &tty->write_wait, wait); | 2401 | poll_wait(file, &tty->write_wait, wait); |
2402 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | ||
2403 | mask |= POLLHUP; | ||
2404 | if (input_available_p(tty, 1)) | 2402 | if (input_available_p(tty, 1)) |
2405 | mask |= POLLIN | POLLRDNORM; | 2403 | mask |= POLLIN | POLLRDNORM; |
2406 | else if (mask & POLLHUP) { | ||
2407 | tty_flush_to_ldisc(tty); | ||
2408 | if (input_available_p(tty, 1)) | ||
2409 | mask |= POLLIN | POLLRDNORM; | ||
2410 | } | ||
2411 | if (tty->packet && tty->link->ctrl_status) | 2404 | if (tty->packet && tty->link->ctrl_status) |
2412 | mask |= POLLPRI | POLLIN | POLLRDNORM; | 2405 | mask |= POLLPRI | POLLIN | POLLRDNORM; |
2406 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | ||
2407 | mask |= POLLHUP; | ||
2413 | if (tty_hung_up_p(file)) | 2408 | if (tty_hung_up_p(file)) |
2414 | mask |= POLLHUP; | 2409 | mask |= POLLHUP; |
2415 | if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { | 2410 | if (!(mask & (POLLHUP | POLLIN | POLLRDNORM))) { |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 31feeb2d0a66..d1f8dc6aabcb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1815,7 +1815,7 @@ pci_wch_ch353_setup(struct serial_private *priv, | |||
1815 | } | 1815 | } |
1816 | 1816 | ||
1817 | static int | 1817 | static int |
1818 | pci_wch_ch382_setup(struct serial_private *priv, | 1818 | pci_wch_ch38x_setup(struct serial_private *priv, |
1819 | const struct pciserial_board *board, | 1819 | const struct pciserial_board *board, |
1820 | struct uart_8250_port *port, int idx) | 1820 | struct uart_8250_port *port, int idx) |
1821 | { | 1821 | { |
@@ -1880,6 +1880,7 @@ pci_wch_ch382_setup(struct serial_private *priv, | |||
1880 | 1880 | ||
1881 | #define PCIE_VENDOR_ID_WCH 0x1c00 | 1881 | #define PCIE_VENDOR_ID_WCH 0x1c00 |
1882 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 | 1882 | #define PCIE_DEVICE_ID_WCH_CH382_2S1P 0x3250 |
1883 | #define PCIE_DEVICE_ID_WCH_CH384_4S 0x3470 | ||
1883 | 1884 | ||
1884 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1885 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1885 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1886 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -2571,13 +2572,21 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
2571 | .subdevice = PCI_ANY_ID, | 2572 | .subdevice = PCI_ANY_ID, |
2572 | .setup = pci_wch_ch353_setup, | 2573 | .setup = pci_wch_ch353_setup, |
2573 | }, | 2574 | }, |
2574 | /* WCH CH382 2S1P card (16750 clone) */ | 2575 | /* WCH CH382 2S1P card (16850 clone) */ |
2575 | { | 2576 | { |
2576 | .vendor = PCIE_VENDOR_ID_WCH, | 2577 | .vendor = PCIE_VENDOR_ID_WCH, |
2577 | .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, | 2578 | .device = PCIE_DEVICE_ID_WCH_CH382_2S1P, |
2578 | .subvendor = PCI_ANY_ID, | 2579 | .subvendor = PCI_ANY_ID, |
2579 | .subdevice = PCI_ANY_ID, | 2580 | .subdevice = PCI_ANY_ID, |
2580 | .setup = pci_wch_ch382_setup, | 2581 | .setup = pci_wch_ch38x_setup, |
2582 | }, | ||
2583 | /* WCH CH384 4S card (16850 clone) */ | ||
2584 | { | ||
2585 | .vendor = PCIE_VENDOR_ID_WCH, | ||
2586 | .device = PCIE_DEVICE_ID_WCH_CH384_4S, | ||
2587 | .subvendor = PCI_ANY_ID, | ||
2588 | .subdevice = PCI_ANY_ID, | ||
2589 | .setup = pci_wch_ch38x_setup, | ||
2581 | }, | 2590 | }, |
2582 | /* | 2591 | /* |
2583 | * ASIX devices with FIFO bug | 2592 | * ASIX devices with FIFO bug |
@@ -2876,6 +2885,7 @@ enum pci_board_num_t { | |||
2876 | pbn_fintek_4, | 2885 | pbn_fintek_4, |
2877 | pbn_fintek_8, | 2886 | pbn_fintek_8, |
2878 | pbn_fintek_12, | 2887 | pbn_fintek_12, |
2888 | pbn_wch384_4, | ||
2879 | }; | 2889 | }; |
2880 | 2890 | ||
2881 | /* | 2891 | /* |
@@ -3675,6 +3685,14 @@ static struct pciserial_board pci_boards[] = { | |||
3675 | .base_baud = 115200, | 3685 | .base_baud = 115200, |
3676 | .first_offset = 0x40, | 3686 | .first_offset = 0x40, |
3677 | }, | 3687 | }, |
3688 | |||
3689 | [pbn_wch384_4] = { | ||
3690 | .flags = FL_BASE0, | ||
3691 | .num_ports = 4, | ||
3692 | .base_baud = 115200, | ||
3693 | .uart_offset = 8, | ||
3694 | .first_offset = 0xC0, | ||
3695 | }, | ||
3678 | }; | 3696 | }; |
3679 | 3697 | ||
3680 | static const struct pci_device_id blacklist[] = { | 3698 | static const struct pci_device_id blacklist[] = { |
@@ -3687,6 +3705,7 @@ static const struct pci_device_id blacklist[] = { | |||
3687 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ | 3705 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ |
3688 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ | 3706 | { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ |
3689 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ | 3707 | { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ |
3708 | { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ | ||
3690 | }; | 3709 | }; |
3691 | 3710 | ||
3692 | /* | 3711 | /* |
@@ -5400,6 +5419,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
5400 | PCI_ANY_ID, PCI_ANY_ID, | 5419 | PCI_ANY_ID, PCI_ANY_ID, |
5401 | 0, 0, pbn_b0_bt_2_115200 }, | 5420 | 0, 0, pbn_b0_bt_2_115200 }, |
5402 | 5421 | ||
5422 | { PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S, | ||
5423 | PCI_ANY_ID, PCI_ANY_ID, | ||
5424 | 0, 0, pbn_wch384_4 }, | ||
5425 | |||
5403 | /* | 5426 | /* |
5404 | * Commtech, Inc. Fastcom adapters | 5427 | * Commtech, Inc. Fastcom adapters |
5405 | */ | 5428 | */ |
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 19273e31d224..107e80722575 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -1757,32 +1757,43 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { | |||
1757 | #endif | 1757 | #endif |
1758 | 1758 | ||
1759 | #if defined(CONFIG_ARCH_EXYNOS) | 1759 | #if defined(CONFIG_ARCH_EXYNOS) |
1760 | #define EXYNOS_COMMON_SERIAL_DRV_DATA \ | ||
1761 | .info = &(struct s3c24xx_uart_info) { \ | ||
1762 | .name = "Samsung Exynos UART", \ | ||
1763 | .type = PORT_S3C6400, \ | ||
1764 | .has_divslot = 1, \ | ||
1765 | .rx_fifomask = S5PV210_UFSTAT_RXMASK, \ | ||
1766 | .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \ | ||
1767 | .rx_fifofull = S5PV210_UFSTAT_RXFULL, \ | ||
1768 | .tx_fifofull = S5PV210_UFSTAT_TXFULL, \ | ||
1769 | .tx_fifomask = S5PV210_UFSTAT_TXMASK, \ | ||
1770 | .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \ | ||
1771 | .def_clk_sel = S3C2410_UCON_CLKSEL0, \ | ||
1772 | .num_clks = 1, \ | ||
1773 | .clksel_mask = 0, \ | ||
1774 | .clksel_shift = 0, \ | ||
1775 | }, \ | ||
1776 | .def_cfg = &(struct s3c2410_uartcfg) { \ | ||
1777 | .ucon = S5PV210_UCON_DEFAULT, \ | ||
1778 | .ufcon = S5PV210_UFCON_DEFAULT, \ | ||
1779 | .has_fracval = 1, \ | ||
1780 | } \ | ||
1781 | |||
1760 | static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { | 1782 | static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { |
1761 | .info = &(struct s3c24xx_uart_info) { | 1783 | EXYNOS_COMMON_SERIAL_DRV_DATA, |
1762 | .name = "Samsung Exynos4 UART", | ||
1763 | .type = PORT_S3C6400, | ||
1764 | .has_divslot = 1, | ||
1765 | .rx_fifomask = S5PV210_UFSTAT_RXMASK, | ||
1766 | .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, | ||
1767 | .rx_fifofull = S5PV210_UFSTAT_RXFULL, | ||
1768 | .tx_fifofull = S5PV210_UFSTAT_TXFULL, | ||
1769 | .tx_fifomask = S5PV210_UFSTAT_TXMASK, | ||
1770 | .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, | ||
1771 | .def_clk_sel = S3C2410_UCON_CLKSEL0, | ||
1772 | .num_clks = 1, | ||
1773 | .clksel_mask = 0, | ||
1774 | .clksel_shift = 0, | ||
1775 | }, | ||
1776 | .def_cfg = &(struct s3c2410_uartcfg) { | ||
1777 | .ucon = S5PV210_UCON_DEFAULT, | ||
1778 | .ufcon = S5PV210_UFCON_DEFAULT, | ||
1779 | .has_fracval = 1, | ||
1780 | }, | ||
1781 | .fifosize = { 256, 64, 16, 16 }, | 1784 | .fifosize = { 256, 64, 16, 16 }, |
1782 | }; | 1785 | }; |
1786 | |||
1787 | static struct s3c24xx_serial_drv_data exynos5433_serial_drv_data = { | ||
1788 | EXYNOS_COMMON_SERIAL_DRV_DATA, | ||
1789 | .fifosize = { 64, 256, 16, 256 }, | ||
1790 | }; | ||
1791 | |||
1783 | #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) | 1792 | #define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data) |
1793 | #define EXYNOS5433_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos5433_serial_drv_data) | ||
1784 | #else | 1794 | #else |
1785 | #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL | 1795 | #define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL |
1796 | #define EXYNOS5433_SERIAL_DRV_DATA (kernel_ulong_t)NULL | ||
1786 | #endif | 1797 | #endif |
1787 | 1798 | ||
1788 | static struct platform_device_id s3c24xx_serial_driver_ids[] = { | 1799 | static struct platform_device_id s3c24xx_serial_driver_ids[] = { |
@@ -1804,6 +1815,9 @@ static struct platform_device_id s3c24xx_serial_driver_ids[] = { | |||
1804 | }, { | 1815 | }, { |
1805 | .name = "exynos4210-uart", | 1816 | .name = "exynos4210-uart", |
1806 | .driver_data = EXYNOS4210_SERIAL_DRV_DATA, | 1817 | .driver_data = EXYNOS4210_SERIAL_DRV_DATA, |
1818 | }, { | ||
1819 | .name = "exynos5433-uart", | ||
1820 | .driver_data = EXYNOS5433_SERIAL_DRV_DATA, | ||
1807 | }, | 1821 | }, |
1808 | { }, | 1822 | { }, |
1809 | }; | 1823 | }; |
@@ -1823,6 +1837,8 @@ static const struct of_device_id s3c24xx_uart_dt_match[] = { | |||
1823 | .data = (void *)S5PV210_SERIAL_DRV_DATA }, | 1837 | .data = (void *)S5PV210_SERIAL_DRV_DATA }, |
1824 | { .compatible = "samsung,exynos4210-uart", | 1838 | { .compatible = "samsung,exynos4210-uart", |
1825 | .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, | 1839 | .data = (void *)EXYNOS4210_SERIAL_DRV_DATA }, |
1840 | { .compatible = "samsung,exynos5433-uart", | ||
1841 | .data = (void *)EXYNOS5433_SERIAL_DRV_DATA }, | ||
1826 | {}, | 1842 | {}, |
1827 | }; | 1843 | }; |
1828 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); | 1844 | MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match); |
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 57ca61b14670..984605bb5bf1 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -2164,7 +2164,9 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) | |||
2164 | break; | 2164 | break; |
2165 | } | 2165 | } |
2166 | 2166 | ||
2167 | dev_info(port->dev, "%s%d at %s (irq = %d, base_baud = %d) is a %s\n", | 2167 | printk(KERN_INFO "%s%s%s%d at %s (irq = %d, base_baud = %d) is a %s\n", |
2168 | port->dev ? dev_name(port->dev) : "", | ||
2169 | port->dev ? ": " : "", | ||
2168 | drv->dev_name, | 2170 | drv->dev_name, |
2169 | drv->tty_driver->name_base + port->line, | 2171 | drv->tty_driver->name_base + port->line, |
2170 | address, port->irq, port->uartclk / 16, uart_type(port)); | 2172 | address, port->irq, port->uartclk / 16, uart_type(port)); |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 4f35b43e2475..51f066aa375e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -1464,6 +1464,9 @@ static int tty_reopen(struct tty_struct *tty) | |||
1464 | driver->subtype == PTY_TYPE_MASTER) | 1464 | driver->subtype == PTY_TYPE_MASTER) |
1465 | return -EIO; | 1465 | return -EIO; |
1466 | 1466 | ||
1467 | if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) | ||
1468 | return -EBUSY; | ||
1469 | |||
1467 | tty->count++; | 1470 | tty->count++; |
1468 | 1471 | ||
1469 | WARN_ON(!tty->ldisc); | 1472 | WARN_ON(!tty->ldisc); |
@@ -2106,10 +2109,6 @@ retry_open: | |||
2106 | retval = -ENODEV; | 2109 | retval = -ENODEV; |
2107 | filp->f_flags = saved_flags; | 2110 | filp->f_flags = saved_flags; |
2108 | 2111 | ||
2109 | if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && | ||
2110 | !capable(CAP_SYS_ADMIN)) | ||
2111 | retval = -EBUSY; | ||
2112 | |||
2113 | if (retval) { | 2112 | if (retval) { |
2114 | #ifdef TTY_DEBUG_HANGUP | 2113 | #ifdef TTY_DEBUG_HANGUP |
2115 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 2114 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 5b9825a4538a..a57dc8866fc5 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c | |||
@@ -669,7 +669,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
669 | if (!ci) | 669 | if (!ci) |
670 | return -ENOMEM; | 670 | return -ENOMEM; |
671 | 671 | ||
672 | platform_set_drvdata(pdev, ci); | ||
673 | ci->dev = dev; | 672 | ci->dev = dev; |
674 | ci->platdata = dev_get_platdata(dev); | 673 | ci->platdata = dev_get_platdata(dev); |
675 | ci->imx28_write_fix = !!(ci->platdata->flags & | 674 | ci->imx28_write_fix = !!(ci->platdata->flags & |
@@ -783,6 +782,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) | |||
783 | } | 782 | } |
784 | } | 783 | } |
785 | 784 | ||
785 | platform_set_drvdata(pdev, ci); | ||
786 | ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, | 786 | ret = devm_request_irq(dev, ci->irq, ci_irq, IRQF_SHARED, |
787 | ci->platdata->name, ci); | 787 | ci->platdata->name, ci); |
788 | if (ret) | 788 | if (ret) |
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index c1694cff1eaf..48731d0bab35 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c | |||
@@ -91,6 +91,7 @@ static int host_start(struct ci_hdrc *ci) | |||
91 | if (!hcd) | 91 | if (!hcd) |
92 | return -ENOMEM; | 92 | return -ENOMEM; |
93 | 93 | ||
94 | dev_set_drvdata(ci->dev, ci); | ||
94 | hcd->rsrc_start = ci->hw_bank.phys; | 95 | hcd->rsrc_start = ci->hw_bank.phys; |
95 | hcd->rsrc_len = ci->hw_bank.size; | 96 | hcd->rsrc_len = ci->hw_bank.size; |
96 | hcd->regs = ci->hw_bank.abs; | 97 | hcd->regs = ci->hw_bank.abs; |
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h index de0c9c9d7091..a6315abe7b7c 100644 --- a/drivers/usb/core/otg_whitelist.h +++ b/drivers/usb/core/otg_whitelist.h | |||
@@ -55,6 +55,11 @@ static int is_targeted(struct usb_device *dev) | |||
55 | le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) | 55 | le16_to_cpu(dev->descriptor.idProduct) == 0xbadd)) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | /* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */ | ||
59 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a && | ||
60 | le16_to_cpu(dev->descriptor.idProduct) == 0x0200)) | ||
61 | return 1; | ||
62 | |||
58 | /* NOTE: can't use usb_match_id() since interface caches | 63 | /* NOTE: can't use usb_match_id() since interface caches |
59 | * aren't set up yet. this is cut/paste from that code. | 64 | * aren't set up yet. this is cut/paste from that code. |
60 | */ | 65 | */ |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 0ffb4ed0a945..41e510ae8c83 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -179,6 +179,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
179 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = | 179 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = |
180 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, | 180 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, |
181 | 181 | ||
182 | /* Protocol and OTG Electrical Test Device */ | ||
183 | { USB_DEVICE(0x1a0a, 0x0200), .driver_info = | ||
184 | USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, | ||
185 | |||
182 | { } /* terminating entry must be last */ | 186 | { } /* terminating entry must be last */ |
183 | }; | 187 | }; |
184 | 188 | ||
diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c index ad43c5bc1ef1..02e3e2d4ea56 100644 --- a/drivers/usb/dwc2/core_intr.c +++ b/drivers/usb/dwc2/core_intr.c | |||
@@ -476,13 +476,13 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |||
476 | u32 gintsts; | 476 | u32 gintsts; |
477 | irqreturn_t retval = IRQ_NONE; | 477 | irqreturn_t retval = IRQ_NONE; |
478 | 478 | ||
479 | spin_lock(&hsotg->lock); | ||
480 | |||
479 | if (!dwc2_is_controller_alive(hsotg)) { | 481 | if (!dwc2_is_controller_alive(hsotg)) { |
480 | dev_warn(hsotg->dev, "Controller is dead\n"); | 482 | dev_warn(hsotg->dev, "Controller is dead\n"); |
481 | goto out; | 483 | goto out; |
482 | } | 484 | } |
483 | 485 | ||
484 | spin_lock(&hsotg->lock); | ||
485 | |||
486 | gintsts = dwc2_read_common_intr(hsotg); | 486 | gintsts = dwc2_read_common_intr(hsotg); |
487 | if (gintsts & ~GINTSTS_PRTINT) | 487 | if (gintsts & ~GINTSTS_PRTINT) |
488 | retval = IRQ_HANDLED; | 488 | retval = IRQ_HANDLED; |
@@ -515,8 +515,8 @@ irqreturn_t dwc2_handle_common_intr(int irq, void *dev) | |||
515 | } | 515 | } |
516 | } | 516 | } |
517 | 517 | ||
518 | spin_unlock(&hsotg->lock); | ||
519 | out: | 518 | out: |
519 | spin_unlock(&hsotg->lock); | ||
520 | return retval; | 520 | return retval; |
521 | } | 521 | } |
522 | EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); | 522 | EXPORT_SYMBOL_GPL(dwc2_handle_common_intr); |
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 200168ec2d75..79242008085b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c | |||
@@ -2567,7 +2567,7 @@ error: | |||
2567 | * s3c_hsotg_ep_disable - disable given endpoint | 2567 | * s3c_hsotg_ep_disable - disable given endpoint |
2568 | * @ep: The endpoint to disable. | 2568 | * @ep: The endpoint to disable. |
2569 | */ | 2569 | */ |
2570 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) | 2570 | static int s3c_hsotg_ep_disable_force(struct usb_ep *ep, bool force) |
2571 | { | 2571 | { |
2572 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2572 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2573 | struct dwc2_hsotg *hsotg = hs_ep->parent; | 2573 | struct dwc2_hsotg *hsotg = hs_ep->parent; |
@@ -2588,7 +2588,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2588 | 2588 | ||
2589 | spin_lock_irqsave(&hsotg->lock, flags); | 2589 | spin_lock_irqsave(&hsotg->lock, flags); |
2590 | /* terminate all requests with shutdown */ | 2590 | /* terminate all requests with shutdown */ |
2591 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); | 2591 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, force); |
2592 | 2592 | ||
2593 | hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); | 2593 | hsotg->fifo_map &= ~(1<<hs_ep->fifo_index); |
2594 | hs_ep->fifo_index = 0; | 2594 | hs_ep->fifo_index = 0; |
@@ -2609,6 +2609,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2609 | return 0; | 2609 | return 0; |
2610 | } | 2610 | } |
2611 | 2611 | ||
2612 | static int s3c_hsotg_ep_disable(struct usb_ep *ep) | ||
2613 | { | ||
2614 | return s3c_hsotg_ep_disable_force(ep, false); | ||
2615 | } | ||
2612 | /** | 2616 | /** |
2613 | * on_list - check request is on the given endpoint | 2617 | * on_list - check request is on the given endpoint |
2614 | * @ep: The endpoint to check. | 2618 | * @ep: The endpoint to check. |
@@ -2924,7 +2928,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget) | |||
2924 | 2928 | ||
2925 | /* all endpoints should be shutdown */ | 2929 | /* all endpoints should be shutdown */ |
2926 | for (ep = 1; ep < hsotg->num_of_eps; ep++) | 2930 | for (ep = 1; ep < hsotg->num_of_eps; ep++) |
2927 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 2931 | s3c_hsotg_ep_disable_force(&hsotg->eps[ep].ep, true); |
2928 | 2932 | ||
2929 | spin_lock_irqsave(&hsotg->lock, flags); | 2933 | spin_lock_irqsave(&hsotg->lock, flags); |
2930 | 2934 | ||
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7c4faf738747..b642a2f998f9 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 | 33 | #define PCI_DEVICE_ID_INTEL_BYT 0x0f37 |
34 | #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e | 34 | #define PCI_DEVICE_ID_INTEL_MRFLD 0x119e |
35 | #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 | 35 | #define PCI_DEVICE_ID_INTEL_BSW 0x22B7 |
36 | #define PCI_DEVICE_ID_INTEL_SPTLP 0x9d30 | ||
37 | #define PCI_DEVICE_ID_INTEL_SPTH 0xa130 | ||
36 | 38 | ||
37 | struct dwc3_pci { | 39 | struct dwc3_pci { |
38 | struct device *dev; | 40 | struct device *dev; |
@@ -219,6 +221,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = { | |||
219 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, | 221 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW), }, |
220 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, | 222 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT), }, |
221 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, | 223 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MRFLD), }, |
224 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), }, | ||
225 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), }, | ||
222 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, | 226 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), }, |
223 | { } /* Terminating Entry */ | 227 | { } /* Terminating Entry */ |
224 | }; | 228 | }; |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f03b136ecfce..8f65ab3a3b92 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -882,8 +882,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
882 | 882 | ||
883 | if (i == (request->num_mapped_sgs - 1) || | 883 | if (i == (request->num_mapped_sgs - 1) || |
884 | sg_is_last(s)) { | 884 | sg_is_last(s)) { |
885 | if (list_is_last(&req->list, | 885 | if (list_empty(&dep->request_list)) |
886 | &dep->request_list)) | ||
887 | last_one = true; | 886 | last_one = true; |
888 | chain = false; | 887 | chain = false; |
889 | } | 888 | } |
@@ -901,6 +900,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) | |||
901 | if (last_one) | 900 | if (last_one) |
902 | break; | 901 | break; |
903 | } | 902 | } |
903 | |||
904 | if (last_one) | ||
905 | break; | ||
904 | } else { | 906 | } else { |
905 | dma = req->request.dma; | 907 | dma = req->request.dma; |
906 | length = req->request.length; | 908 | length = req->request.length; |
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6e04e302dc3a..a1bc3e3a0b09 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c | |||
@@ -399,8 +399,9 @@ static int hidg_setup(struct usb_function *f, | |||
399 | value = __le16_to_cpu(ctrl->wValue); | 399 | value = __le16_to_cpu(ctrl->wValue); |
400 | length = __le16_to_cpu(ctrl->wLength); | 400 | length = __le16_to_cpu(ctrl->wLength); |
401 | 401 | ||
402 | VDBG(cdev, "hid_setup crtl_request : bRequestType:0x%x bRequest:0x%x " | 402 | VDBG(cdev, |
403 | "Value:0x%x\n", ctrl->bRequestType, ctrl->bRequest, value); | 403 | "%s crtl_request : bRequestType:0x%x bRequest:0x%x Value:0x%x\n", |
404 | __func__, ctrl->bRequestType, ctrl->bRequest, value); | ||
404 | 405 | ||
405 | switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { | 406 | switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { |
406 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 | 407 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 |
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a90440300735..259b656c0b3e 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c | |||
@@ -520,7 +520,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) | |||
520 | req = midi_alloc_ep_req(ep, midi->buflen); | 520 | req = midi_alloc_ep_req(ep, midi->buflen); |
521 | 521 | ||
522 | if (!req) { | 522 | if (!req) { |
523 | ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n"); | 523 | ERROR(midi, "%s: alloc_ep_request failed\n", __func__); |
524 | return; | 524 | return; |
525 | } | 525 | } |
526 | req->length = 0; | 526 | req->length = 0; |
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index f7b203293205..e9715845f82e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c | |||
@@ -897,7 +897,6 @@ static void f_audio_free_inst(struct usb_function_instance *f) | |||
897 | struct f_uac1_opts *opts; | 897 | struct f_uac1_opts *opts; |
898 | 898 | ||
899 | opts = container_of(f, struct f_uac1_opts, func_inst); | 899 | opts = container_of(f, struct f_uac1_opts, func_inst); |
900 | gaudio_cleanup(opts->card); | ||
901 | if (opts->fn_play_alloc) | 900 | if (opts->fn_play_alloc) |
902 | kfree(opts->fn_play); | 901 | kfree(opts->fn_play); |
903 | if (opts->fn_cap_alloc) | 902 | if (opts->fn_cap_alloc) |
@@ -935,6 +934,7 @@ static void f_audio_free(struct usb_function *f) | |||
935 | struct f_audio *audio = func_to_audio(f); | 934 | struct f_audio *audio = func_to_audio(f); |
936 | struct f_uac1_opts *opts; | 935 | struct f_uac1_opts *opts; |
937 | 936 | ||
937 | gaudio_cleanup(&audio->card); | ||
938 | opts = container_of(f->fi, struct f_uac1_opts, func_inst); | 938 | opts = container_of(f->fi, struct f_uac1_opts, func_inst); |
939 | kfree(audio); | 939 | kfree(audio); |
940 | mutex_lock(&opts->lock); | 940 | mutex_lock(&opts->lock); |
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c744e4975d74..db49ec4c748e 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -441,6 +441,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
441 | kbuf = memdup_user(buf, len); | 441 | kbuf = memdup_user(buf, len); |
442 | if (IS_ERR(kbuf)) { | 442 | if (IS_ERR(kbuf)) { |
443 | value = PTR_ERR(kbuf); | 443 | value = PTR_ERR(kbuf); |
444 | kbuf = NULL; | ||
444 | goto free1; | 445 | goto free1; |
445 | } | 446 | } |
446 | 447 | ||
@@ -449,6 +450,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
449 | data->name, len, (int) value); | 450 | data->name, len, (int) value); |
450 | free1: | 451 | free1: |
451 | mutex_unlock(&data->lock); | 452 | mutex_unlock(&data->lock); |
453 | kfree (kbuf); | ||
452 | return value; | 454 | return value; |
453 | } | 455 | } |
454 | 456 | ||
diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index ce882371786b..9f93bed42052 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c | |||
@@ -716,10 +716,10 @@ static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, | |||
716 | req->using_dma = 1; | 716 | req->using_dma = 1; |
717 | req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | 717 | req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) |
718 | | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE | 718 | | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE |
719 | | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; | 719 | | USBA_DMA_END_BUF_EN; |
720 | 720 | ||
721 | if (ep->is_in) | 721 | if (!ep->is_in) |
722 | req->ctrl |= USBA_DMA_END_BUF_EN; | 722 | req->ctrl |= USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; |
723 | 723 | ||
724 | /* | 724 | /* |
725 | * Add this request to the queue and submit for DMA if | 725 | * Add this request to the queue and submit for DMA if |
@@ -828,7 +828,7 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
828 | { | 828 | { |
829 | struct usba_ep *ep = to_usba_ep(_ep); | 829 | struct usba_ep *ep = to_usba_ep(_ep); |
830 | struct usba_udc *udc = ep->udc; | 830 | struct usba_udc *udc = ep->udc; |
831 | struct usba_request *req = to_usba_req(_req); | 831 | struct usba_request *req; |
832 | unsigned long flags; | 832 | unsigned long flags; |
833 | u32 status; | 833 | u32 status; |
834 | 834 | ||
@@ -837,6 +837,16 @@ static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
837 | 837 | ||
838 | spin_lock_irqsave(&udc->lock, flags); | 838 | spin_lock_irqsave(&udc->lock, flags); |
839 | 839 | ||
840 | list_for_each_entry(req, &ep->queue, queue) { | ||
841 | if (&req->req == _req) | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | if (&req->req != _req) { | ||
846 | spin_unlock_irqrestore(&udc->lock, flags); | ||
847 | return -EINVAL; | ||
848 | } | ||
849 | |||
840 | if (req->using_dma) { | 850 | if (req->using_dma) { |
841 | /* | 851 | /* |
842 | * If this request is currently being transferred, | 852 | * If this request is currently being transferred, |
@@ -1563,7 +1573,6 @@ static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep) | |||
1563 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { | 1573 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { |
1564 | DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); | 1574 | DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); |
1565 | receive_data(ep); | 1575 | receive_data(ep); |
1566 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1567 | } | 1576 | } |
1568 | } | 1577 | } |
1569 | 1578 | ||
diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index ff67ceac77c4..d4fe8d769bd6 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c | |||
@@ -718,10 +718,11 @@ static int ep_queue(struct bdc_ep *ep, struct bdc_req *req) | |||
718 | struct bdc *bdc; | 718 | struct bdc *bdc; |
719 | int ret = 0; | 719 | int ret = 0; |
720 | 720 | ||
721 | bdc = ep->bdc; | ||
722 | if (!req || !ep || !ep->usb_ep.desc) | 721 | if (!req || !ep || !ep->usb_ep.desc) |
723 | return -EINVAL; | 722 | return -EINVAL; |
724 | 723 | ||
724 | bdc = ep->bdc; | ||
725 | |||
725 | req->usb_req.actual = 0; | 726 | req->usb_req.actual = 0; |
726 | req->usb_req.status = -EINPROGRESS; | 727 | req->usb_req.status = -EINPROGRESS; |
727 | req->epnum = ep->ep_num; | 728 | req->epnum = ep->ep_num; |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e113fd73aeae..f9a332775c47 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1581,6 +1581,10 @@ iso_stream_schedule ( | |||
1581 | else | 1581 | else |
1582 | next = (now + 2 + 7) & ~0x07; /* full frame cache */ | 1582 | next = (now + 2 + 7) & ~0x07; /* full frame cache */ |
1583 | 1583 | ||
1584 | /* If needed, initialize last_iso_frame so that this URB will be seen */ | ||
1585 | if (ehci->isoc_count == 0) | ||
1586 | ehci->last_iso_frame = now >> 3; | ||
1587 | |||
1584 | /* | 1588 | /* |
1585 | * Use ehci->last_iso_frame as the base. There can't be any | 1589 | * Use ehci->last_iso_frame as the base. There can't be any |
1586 | * TDs scheduled for earlier than that. | 1590 | * TDs scheduled for earlier than that. |
@@ -1600,11 +1604,11 @@ iso_stream_schedule ( | |||
1600 | */ | 1604 | */ |
1601 | now2 = (now - base) & (mod - 1); | 1605 | now2 = (now - base) & (mod - 1); |
1602 | 1606 | ||
1603 | /* Is the schedule already full? */ | 1607 | /* Is the schedule about to wrap around? */ |
1604 | if (unlikely(!empty && start < period)) { | 1608 | if (unlikely(!empty && start < period)) { |
1605 | ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", | 1609 | ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n", |
1606 | urb, stream->next_uframe, base, period, mod); | 1610 | urb, stream->next_uframe, base, period, mod); |
1607 | status = -ENOSPC; | 1611 | status = -EFBIG; |
1608 | goto fail; | 1612 | goto fail; |
1609 | } | 1613 | } |
1610 | 1614 | ||
@@ -1671,10 +1675,6 @@ iso_stream_schedule ( | |||
1671 | urb->start_frame = start & (mod - 1); | 1675 | urb->start_frame = start & (mod - 1); |
1672 | if (!stream->highspeed) | 1676 | if (!stream->highspeed) |
1673 | urb->start_frame >>= 3; | 1677 | urb->start_frame >>= 3; |
1674 | |||
1675 | /* Make sure scan_isoc() sees these */ | ||
1676 | if (ehci->isoc_count == 0) | ||
1677 | ehci->last_iso_frame = now >> 3; | ||
1678 | return status; | 1678 | return status; |
1679 | 1679 | ||
1680 | fail: | 1680 | fail: |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 19a9af1b4d74..ff9af29b4e9f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
451 | 451 | ||
452 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); | 452 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); |
453 | if (IS_ERR(u_phy)) { | 453 | if (IS_ERR(u_phy)) { |
454 | err = PTR_ERR(u_phy); | 454 | err = -EPROBE_DEFER; |
455 | goto cleanup_clk_en; | 455 | goto cleanup_clk_en; |
456 | } | 456 | } |
457 | hcd->usb_phy = u_phy; | 457 | hcd->usb_phy = u_phy; |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dd483c13565b..ce636466edb7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
567 | { | 567 | { |
568 | void __iomem *base; | 568 | void __iomem *base; |
569 | u32 control; | 569 | u32 control; |
570 | u32 fminterval; | 570 | u32 fminterval = 0; |
571 | bool no_fminterval = false; | ||
571 | int cnt; | 572 | int cnt; |
572 | 573 | ||
573 | if (!mmio_resource_enabled(pdev, 0)) | 574 | if (!mmio_resource_enabled(pdev, 0)) |
@@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
577 | if (base == NULL) | 578 | if (base == NULL) |
578 | return; | 579 | return; |
579 | 580 | ||
581 | /* | ||
582 | * ULi M5237 OHCI controller locks the whole system when accessing | ||
583 | * the OHCI_FMINTERVAL offset. | ||
584 | */ | ||
585 | if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237) | ||
586 | no_fminterval = true; | ||
587 | |||
580 | control = readl(base + OHCI_CONTROL); | 588 | control = readl(base + OHCI_CONTROL); |
581 | 589 | ||
582 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | 590 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ |
@@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
615 | } | 623 | } |
616 | 624 | ||
617 | /* software reset of the controller, preserving HcFmInterval */ | 625 | /* software reset of the controller, preserving HcFmInterval */ |
618 | fminterval = readl(base + OHCI_FMINTERVAL); | 626 | if (!no_fminterval) |
627 | fminterval = readl(base + OHCI_FMINTERVAL); | ||
628 | |||
619 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); | 629 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); |
620 | 630 | ||
621 | /* reset requires max 10 us delay */ | 631 | /* reset requires max 10 us delay */ |
@@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
624 | break; | 634 | break; |
625 | udelay(1); | 635 | udelay(1); |
626 | } | 636 | } |
627 | writel(fminterval, base + OHCI_FMINTERVAL); | 637 | |
638 | if (!no_fminterval) | ||
639 | writel(fminterval, base + OHCI_FMINTERVAL); | ||
628 | 640 | ||
629 | /* Now the controller is safely in SUSPEND and nothing can wake it up */ | 641 | /* Now the controller is safely in SUSPEND and nothing can wake it up */ |
630 | iounmap(base); | 642 | iounmap(base); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 142b601f9563..7f76c8a12f89 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
82 | "must be suspended extra slowly", | 82 | "must be suspended extra slowly", |
83 | pdev->revision); | 83 | pdev->revision); |
84 | } | 84 | } |
85 | if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) | ||
86 | xhci->quirks |= XHCI_BROKEN_STREAMS; | ||
85 | /* Fresco Logic confirms: all revisions of this chip do not | 87 | /* Fresco Logic confirms: all revisions of this chip do not |
86 | * support MSI, even though some of them claim to in their PCI | 88 | * support MSI, even though some of them claim to in their PCI |
87 | * capabilities. | 89 | * capabilities. |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01fcbb5eb06e..c50d8d202618 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
3803 | return -EINVAL; | 3803 | return -EINVAL; |
3804 | } | 3804 | } |
3805 | 3805 | ||
3806 | if (setup == SETUP_CONTEXT_ONLY) { | ||
3807 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | ||
3808 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == | ||
3809 | SLOT_STATE_DEFAULT) { | ||
3810 | xhci_dbg(xhci, "Slot already in default state\n"); | ||
3811 | return 0; | ||
3812 | } | ||
3813 | } | ||
3814 | |||
3806 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); | 3815 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
3807 | if (!command) | 3816 | if (!command) |
3808 | return -ENOMEM; | 3817 | return -ENOMEM; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9d68372dd9aa..b005010240e5 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -72,6 +72,8 @@ config USB_MUSB_DA8XX | |||
72 | 72 | ||
73 | config USB_MUSB_TUSB6010 | 73 | config USB_MUSB_TUSB6010 |
74 | tristate "TUSB6010" | 74 | tristate "TUSB6010" |
75 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
76 | depends on NOP_USB_XCEIV = USB_MUSB_HDRC # both built-in or both modules | ||
75 | 77 | ||
76 | config USB_MUSB_OMAP2PLUS | 78 | config USB_MUSB_OMAP2PLUS |
77 | tristate "OMAP2430 and onwards" | 79 | tristate "OMAP2430 and onwards" |
@@ -85,6 +87,7 @@ config USB_MUSB_AM35X | |||
85 | config USB_MUSB_DSPS | 87 | config USB_MUSB_DSPS |
86 | tristate "TI DSPS platforms" | 88 | tristate "TI DSPS platforms" |
87 | select USB_MUSB_AM335X_CHILD | 89 | select USB_MUSB_AM335X_CHILD |
90 | depends on ARCH_OMAP2PLUS || COMPILE_TEST | ||
88 | depends on OF_IRQ | 91 | depends on OF_IRQ |
89 | 92 | ||
90 | config USB_MUSB_BLACKFIN | 93 | config USB_MUSB_BLACKFIN |
@@ -93,6 +96,7 @@ config USB_MUSB_BLACKFIN | |||
93 | 96 | ||
94 | config USB_MUSB_UX500 | 97 | config USB_MUSB_UX500 |
95 | tristate "Ux500 platforms" | 98 | tristate "Ux500 platforms" |
99 | depends on ARCH_U8500 || COMPILE_TEST | ||
96 | 100 | ||
97 | config USB_MUSB_JZ4740 | 101 | config USB_MUSB_JZ4740 |
98 | tristate "JZ4740" | 102 | tristate "JZ4740" |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index a441a2de8619..178250145613 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -63,7 +63,7 @@ static void bfin_writew(void __iomem *addr, unsigned offset, u16 data) | |||
63 | bfin_write16(addr + offset, data); | 63 | bfin_write16(addr + offset, data); |
64 | } | 64 | } |
65 | 65 | ||
66 | static void binf_writel(void __iomem *addr, unsigned offset, u32 data) | 66 | static void bfin_writel(void __iomem *addr, unsigned offset, u32 data) |
67 | { | 67 | { |
68 | bfin_write16(addr + offset, (u16)data); | 68 | bfin_write16(addr + offset, (u16)data); |
69 | } | 69 | } |
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index f64fd964dc6d..c39a16ad7832 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -628,9 +628,9 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) | |||
628 | ret = of_property_read_string_index(np, "dma-names", i, &str); | 628 | ret = of_property_read_string_index(np, "dma-names", i, &str); |
629 | if (ret) | 629 | if (ret) |
630 | goto err; | 630 | goto err; |
631 | if (!strncmp(str, "tx", 2)) | 631 | if (strstarts(str, "tx")) |
632 | is_tx = 1; | 632 | is_tx = 1; |
633 | else if (!strncmp(str, "rx", 2)) | 633 | else if (strstarts(str, "rx")) |
634 | is_tx = 0; | 634 | is_tx = 0; |
635 | else { | 635 | else { |
636 | dev_err(dev, "Wrong dmatype %s\n", str); | 636 | dev_err(dev, "Wrong dmatype %s\n", str); |
diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index ad3701a97389..48131aa8472c 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c | |||
@@ -59,20 +59,12 @@ static const struct musb_register_map musb_regmap[] = { | |||
59 | { "RxMaxPp", MUSB_RXMAXP, 16 }, | 59 | { "RxMaxPp", MUSB_RXMAXP, 16 }, |
60 | { "RxCSR", MUSB_RXCSR, 16 }, | 60 | { "RxCSR", MUSB_RXCSR, 16 }, |
61 | { "RxCount", MUSB_RXCOUNT, 16 }, | 61 | { "RxCount", MUSB_RXCOUNT, 16 }, |
62 | { "ConfigData", MUSB_CONFIGDATA,8 }, | ||
63 | { "IntrRxE", MUSB_INTRRXE, 16 }, | 62 | { "IntrRxE", MUSB_INTRRXE, 16 }, |
64 | { "IntrTxE", MUSB_INTRTXE, 16 }, | 63 | { "IntrTxE", MUSB_INTRTXE, 16 }, |
65 | { "IntrUsbE", MUSB_INTRUSBE, 8 }, | 64 | { "IntrUsbE", MUSB_INTRUSBE, 8 }, |
66 | { "DevCtl", MUSB_DEVCTL, 8 }, | 65 | { "DevCtl", MUSB_DEVCTL, 8 }, |
67 | { "BabbleCtl", MUSB_BABBLE_CTL,8 }, | ||
68 | { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, | ||
69 | { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, | ||
70 | { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, | ||
71 | { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, | ||
72 | { "VControl", 0x68, 32 }, | 66 | { "VControl", 0x68, 32 }, |
73 | { "HWVers", 0x69, 16 }, | 67 | { "HWVers", 0x69, 16 }, |
74 | { "EPInfo", MUSB_EPINFO, 8 }, | ||
75 | { "RAMInfo", MUSB_RAMINFO, 8 }, | ||
76 | { "LinkInfo", MUSB_LINKINFO, 8 }, | 68 | { "LinkInfo", MUSB_LINKINFO, 8 }, |
77 | { "VPLen", MUSB_VPLEN, 8 }, | 69 | { "VPLen", MUSB_VPLEN, 8 }, |
78 | { "HS_EOF1", MUSB_HS_EOF1, 8 }, | 70 | { "HS_EOF1", MUSB_HS_EOF1, 8 }, |
@@ -103,6 +95,16 @@ static const struct musb_register_map musb_regmap[] = { | |||
103 | { "DMA_CNTLch7", 0x274, 16 }, | 95 | { "DMA_CNTLch7", 0x274, 16 }, |
104 | { "DMA_ADDRch7", 0x278, 32 }, | 96 | { "DMA_ADDRch7", 0x278, 32 }, |
105 | { "DMA_COUNTch7", 0x27C, 32 }, | 97 | { "DMA_COUNTch7", 0x27C, 32 }, |
98 | #ifndef CONFIG_BLACKFIN | ||
99 | { "ConfigData", MUSB_CONFIGDATA,8 }, | ||
100 | { "BabbleCtl", MUSB_BABBLE_CTL,8 }, | ||
101 | { "TxFIFOsz", MUSB_TXFIFOSZ, 8 }, | ||
102 | { "RxFIFOsz", MUSB_RXFIFOSZ, 8 }, | ||
103 | { "TxFIFOadd", MUSB_TXFIFOADD, 16 }, | ||
104 | { "RxFIFOadd", MUSB_RXFIFOADD, 16 }, | ||
105 | { "EPInfo", MUSB_EPINFO, 8 }, | ||
106 | { "RAMInfo", MUSB_RAMINFO, 8 }, | ||
107 | #endif | ||
106 | { } /* Terminating Entry */ | 108 | { } /* Terminating Entry */ |
107 | }; | 109 | }; |
108 | 110 | ||
@@ -197,30 +199,30 @@ static ssize_t musb_test_mode_write(struct file *file, | |||
197 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | 199 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) |
198 | return -EFAULT; | 200 | return -EFAULT; |
199 | 201 | ||
200 | if (!strncmp(buf, "force host", 9)) | 202 | if (strstarts(buf, "force host")) |
201 | test = MUSB_TEST_FORCE_HOST; | 203 | test = MUSB_TEST_FORCE_HOST; |
202 | 204 | ||
203 | if (!strncmp(buf, "fifo access", 11)) | 205 | if (strstarts(buf, "fifo access")) |
204 | test = MUSB_TEST_FIFO_ACCESS; | 206 | test = MUSB_TEST_FIFO_ACCESS; |
205 | 207 | ||
206 | if (!strncmp(buf, "force full-speed", 15)) | 208 | if (strstarts(buf, "force full-speed")) |
207 | test = MUSB_TEST_FORCE_FS; | 209 | test = MUSB_TEST_FORCE_FS; |
208 | 210 | ||
209 | if (!strncmp(buf, "force high-speed", 15)) | 211 | if (strstarts(buf, "force high-speed")) |
210 | test = MUSB_TEST_FORCE_HS; | 212 | test = MUSB_TEST_FORCE_HS; |
211 | 213 | ||
212 | if (!strncmp(buf, "test packet", 10)) { | 214 | if (strstarts(buf, "test packet")) { |
213 | test = MUSB_TEST_PACKET; | 215 | test = MUSB_TEST_PACKET; |
214 | musb_load_testpacket(musb); | 216 | musb_load_testpacket(musb); |
215 | } | 217 | } |
216 | 218 | ||
217 | if (!strncmp(buf, "test K", 6)) | 219 | if (strstarts(buf, "test K")) |
218 | test = MUSB_TEST_K; | 220 | test = MUSB_TEST_K; |
219 | 221 | ||
220 | if (!strncmp(buf, "test J", 6)) | 222 | if (strstarts(buf, "test J")) |
221 | test = MUSB_TEST_J; | 223 | test = MUSB_TEST_J; |
222 | 224 | ||
223 | if (!strncmp(buf, "test SE0 NAK", 12)) | 225 | if (strstarts(buf, "test SE0 NAK")) |
224 | test = MUSB_TEST_SE0_NAK; | 226 | test = MUSB_TEST_SE0_NAK; |
225 | 227 | ||
226 | musb_writeb(musb->mregs, MUSB_TESTMODE, test); | 228 | musb_writeb(musb->mregs, MUSB_TESTMODE, test); |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 23d474d3d7f4..883a9adfdfff 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -2663,7 +2663,6 @@ void musb_host_cleanup(struct musb *musb) | |||
2663 | if (musb->port_mode == MUSB_PORT_MODE_GADGET) | 2663 | if (musb->port_mode == MUSB_PORT_MODE_GADGET) |
2664 | return; | 2664 | return; |
2665 | usb_remove_hcd(musb->hcd); | 2665 | usb_remove_hcd(musb->hcd); |
2666 | musb->hcd = NULL; | ||
2667 | } | 2666 | } |
2668 | 2667 | ||
2669 | void musb_host_free(struct musb *musb) | 2668 | void musb_host_free(struct musb *musb) |
diff --git a/drivers/usb/phy/phy-mv-usb.c b/drivers/usb/phy/phy-mv-usb.c index 699e38c73d82..697a741a0cb1 100644 --- a/drivers/usb/phy/phy-mv-usb.c +++ b/drivers/usb/phy/phy-mv-usb.c | |||
@@ -338,7 +338,6 @@ static void mv_otg_update_inputs(struct mv_otg *mvotg) | |||
338 | static void mv_otg_update_state(struct mv_otg *mvotg) | 338 | static void mv_otg_update_state(struct mv_otg *mvotg) |
339 | { | 339 | { |
340 | struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; | 340 | struct mv_otg_ctrl *otg_ctrl = &mvotg->otg_ctrl; |
341 | struct usb_phy *phy = &mvotg->phy; | ||
342 | int old_state = mvotg->phy.otg->state; | 341 | int old_state = mvotg->phy.otg->state; |
343 | 342 | ||
344 | switch (old_state) { | 343 | switch (old_state) { |
@@ -858,10 +857,10 @@ static int mv_otg_suspend(struct platform_device *pdev, pm_message_t state) | |||
858 | { | 857 | { |
859 | struct mv_otg *mvotg = platform_get_drvdata(pdev); | 858 | struct mv_otg *mvotg = platform_get_drvdata(pdev); |
860 | 859 | ||
861 | if (mvotg->phy.state != OTG_STATE_B_IDLE) { | 860 | if (mvotg->phy.otg->state != OTG_STATE_B_IDLE) { |
862 | dev_info(&pdev->dev, | 861 | dev_info(&pdev->dev, |
863 | "OTG state is not B_IDLE, it is %d!\n", | 862 | "OTG state is not B_IDLE, it is %d!\n", |
864 | mvotg->phy.state); | 863 | mvotg->phy.otg->state); |
865 | return -EAGAIN; | 864 | return -EAGAIN; |
866 | } | 865 | } |
867 | 866 | ||
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index b4066a001ba0..2f9735b35338 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c | |||
@@ -59,6 +59,9 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) | |||
59 | { | 59 | { |
60 | struct usb_phy *phy; | 60 | struct usb_phy *phy; |
61 | 61 | ||
62 | if (!of_device_is_available(node)) | ||
63 | return ERR_PTR(-ENODEV); | ||
64 | |||
62 | list_for_each_entry(phy, &phy_list, head) { | 65 | list_for_each_entry(phy, &phy_list, head) { |
63 | if (node != phy->dev->of_node) | 66 | if (node != phy->dev->of_node) |
64 | continue; | 67 | continue; |
@@ -66,7 +69,7 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) | |||
66 | return phy; | 69 | return phy; |
67 | } | 70 | } |
68 | 71 | ||
69 | return ERR_PTR(-ENODEV); | 72 | return ERR_PTR(-EPROBE_DEFER); |
70 | } | 73 | } |
71 | 74 | ||
72 | static void devm_usb_phy_release(struct device *dev, void *res) | 75 | static void devm_usb_phy_release(struct device *dev, void *res) |
@@ -190,10 +193,13 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, | |||
190 | spin_lock_irqsave(&phy_lock, flags); | 193 | spin_lock_irqsave(&phy_lock, flags); |
191 | 194 | ||
192 | phy = __of_usb_find_phy(node); | 195 | phy = __of_usb_find_phy(node); |
193 | if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { | 196 | if (IS_ERR(phy)) { |
194 | if (!IS_ERR(phy)) | 197 | devres_free(ptr); |
195 | phy = ERR_PTR(-EPROBE_DEFER); | 198 | goto err1; |
199 | } | ||
196 | 200 | ||
201 | if (!try_module_get(phy->dev->driver->owner)) { | ||
202 | phy = ERR_PTR(-ENODEV); | ||
197 | devres_free(ptr); | 203 | devres_free(ptr); |
198 | goto err1; | 204 | goto err1; |
199 | } | 205 | } |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 8d7fc48b1f30..29fa1c3d0089 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -46,6 +46,8 @@ static struct console usbcons; | |||
46 | * ------------------------------------------------------------ | 46 | * ------------------------------------------------------------ |
47 | */ | 47 | */ |
48 | 48 | ||
49 | static const struct tty_operations usb_console_fake_tty_ops = { | ||
50 | }; | ||
49 | 51 | ||
50 | /* | 52 | /* |
51 | * The parsing of the command line works exactly like the | 53 | * The parsing of the command line works exactly like the |
@@ -137,13 +139,17 @@ static int usb_console_setup(struct console *co, char *options) | |||
137 | goto reset_open_count; | 139 | goto reset_open_count; |
138 | } | 140 | } |
139 | kref_init(&tty->kref); | 141 | kref_init(&tty->kref); |
140 | tty_port_tty_set(&port->port, tty); | ||
141 | tty->driver = usb_serial_tty_driver; | 142 | tty->driver = usb_serial_tty_driver; |
142 | tty->index = co->index; | 143 | tty->index = co->index; |
144 | init_ldsem(&tty->ldisc_sem); | ||
145 | INIT_LIST_HEAD(&tty->tty_files); | ||
146 | kref_get(&tty->driver->kref); | ||
147 | tty->ops = &usb_console_fake_tty_ops; | ||
143 | if (tty_init_termios(tty)) { | 148 | if (tty_init_termios(tty)) { |
144 | retval = -ENOMEM; | 149 | retval = -ENOMEM; |
145 | goto free_tty; | 150 | goto put_tty; |
146 | } | 151 | } |
152 | tty_port_tty_set(&port->port, tty); | ||
147 | } | 153 | } |
148 | 154 | ||
149 | /* only call the device specific open if this | 155 | /* only call the device specific open if this |
@@ -161,7 +167,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
161 | serial->type->set_termios(tty, port, &dummy); | 167 | serial->type->set_termios(tty, port, &dummy); |
162 | 168 | ||
163 | tty_port_tty_set(&port->port, NULL); | 169 | tty_port_tty_set(&port->port, NULL); |
164 | kfree(tty); | 170 | tty_kref_put(tty); |
165 | } | 171 | } |
166 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); | 172 | set_bit(ASYNCB_INITIALIZED, &port->port.flags); |
167 | } | 173 | } |
@@ -177,8 +183,8 @@ static int usb_console_setup(struct console *co, char *options) | |||
177 | 183 | ||
178 | fail: | 184 | fail: |
179 | tty_port_tty_set(&port->port, NULL); | 185 | tty_port_tty_set(&port->port, NULL); |
180 | free_tty: | 186 | put_tty: |
181 | kfree(tty); | 187 | tty_kref_put(tty); |
182 | reset_open_count: | 188 | reset_open_count: |
183 | port->port.count = 0; | 189 | port->port.count = 0; |
184 | usb_autopm_put_interface(serial->interface); | 190 | usb_autopm_put_interface(serial->interface); |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 6c4eb3cf5efd..f4c56fc1a9f6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -120,10 +120,12 @@ static const struct usb_device_id id_table[] = { | |||
120 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ | 120 | { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ |
121 | { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ | 121 | { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ |
122 | { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ | 122 | { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ |
123 | { USB_DEVICE(0x10C4, 0x8875) }, /* CEL MeshConnect USB Stick */ | 123 | { USB_DEVICE(0x10C4, 0x8856) }, /* CEL EM357 ZigBee USB Stick - LR */ |
124 | { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ | ||
124 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ | 125 | { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ |
125 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ | 126 | { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ |
126 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ | 127 | { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ |
128 | { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ | ||
127 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 129 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
128 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 130 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
129 | { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ | 131 | { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 1bd192290b08..ccf1df7c4b80 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -286,7 +286,7 @@ static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, | |||
286 | 286 | ||
287 | res = usb_submit_urb(port->read_urbs[index], mem_flags); | 287 | res = usb_submit_urb(port->read_urbs[index], mem_flags); |
288 | if (res) { | 288 | if (res) { |
289 | if (res != -EPERM) { | 289 | if (res != -EPERM && res != -ENODEV) { |
290 | dev_err(&port->dev, | 290 | dev_err(&port->dev, |
291 | "%s - usb_submit_urb failed: %d\n", | 291 | "%s - usb_submit_urb failed: %d\n", |
292 | __func__, res); | 292 | __func__, res); |
@@ -373,7 +373,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) | |||
373 | __func__, urb->status); | 373 | __func__, urb->status); |
374 | return; | 374 | return; |
375 | default: | 375 | default: |
376 | dev_err(&port->dev, "%s - nonzero urb status: %d\n", | 376 | dev_dbg(&port->dev, "%s - nonzero urb status: %d\n", |
377 | __func__, urb->status); | 377 | __func__, urb->status); |
378 | goto resubmit; | 378 | goto resubmit; |
379 | } | 379 | } |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 077c714f1285..e07b15ed5814 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -410,6 +410,8 @@ static void usa26_instat_callback(struct urb *urb) | |||
410 | } | 410 | } |
411 | port = serial->port[msg->port]; | 411 | port = serial->port[msg->port]; |
412 | p_priv = usb_get_serial_port_data(port); | 412 | p_priv = usb_get_serial_port_data(port); |
413 | if (!p_priv) | ||
414 | goto resubmit; | ||
413 | 415 | ||
414 | /* Update handshaking pin state information */ | 416 | /* Update handshaking pin state information */ |
415 | old_dcd_state = p_priv->dcd_state; | 417 | old_dcd_state = p_priv->dcd_state; |
@@ -420,7 +422,7 @@ static void usa26_instat_callback(struct urb *urb) | |||
420 | 422 | ||
421 | if (old_dcd_state != p_priv->dcd_state) | 423 | if (old_dcd_state != p_priv->dcd_state) |
422 | tty_port_tty_hangup(&port->port, true); | 424 | tty_port_tty_hangup(&port->port, true); |
423 | 425 | resubmit: | |
424 | /* Resubmit urb so we continue receiving */ | 426 | /* Resubmit urb so we continue receiving */ |
425 | err = usb_submit_urb(urb, GFP_ATOMIC); | 427 | err = usb_submit_urb(urb, GFP_ATOMIC); |
426 | if (err != 0) | 428 | if (err != 0) |
@@ -527,6 +529,8 @@ static void usa28_instat_callback(struct urb *urb) | |||
527 | } | 529 | } |
528 | port = serial->port[msg->port]; | 530 | port = serial->port[msg->port]; |
529 | p_priv = usb_get_serial_port_data(port); | 531 | p_priv = usb_get_serial_port_data(port); |
532 | if (!p_priv) | ||
533 | goto resubmit; | ||
530 | 534 | ||
531 | /* Update handshaking pin state information */ | 535 | /* Update handshaking pin state information */ |
532 | old_dcd_state = p_priv->dcd_state; | 536 | old_dcd_state = p_priv->dcd_state; |
@@ -537,7 +541,7 @@ static void usa28_instat_callback(struct urb *urb) | |||
537 | 541 | ||
538 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) | 542 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
539 | tty_port_tty_hangup(&port->port, true); | 543 | tty_port_tty_hangup(&port->port, true); |
540 | 544 | resubmit: | |
541 | /* Resubmit urb so we continue receiving */ | 545 | /* Resubmit urb so we continue receiving */ |
542 | err = usb_submit_urb(urb, GFP_ATOMIC); | 546 | err = usb_submit_urb(urb, GFP_ATOMIC); |
543 | if (err != 0) | 547 | if (err != 0) |
@@ -607,6 +611,8 @@ static void usa49_instat_callback(struct urb *urb) | |||
607 | } | 611 | } |
608 | port = serial->port[msg->portNumber]; | 612 | port = serial->port[msg->portNumber]; |
609 | p_priv = usb_get_serial_port_data(port); | 613 | p_priv = usb_get_serial_port_data(port); |
614 | if (!p_priv) | ||
615 | goto resubmit; | ||
610 | 616 | ||
611 | /* Update handshaking pin state information */ | 617 | /* Update handshaking pin state information */ |
612 | old_dcd_state = p_priv->dcd_state; | 618 | old_dcd_state = p_priv->dcd_state; |
@@ -617,7 +623,7 @@ static void usa49_instat_callback(struct urb *urb) | |||
617 | 623 | ||
618 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) | 624 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
619 | tty_port_tty_hangup(&port->port, true); | 625 | tty_port_tty_hangup(&port->port, true); |
620 | 626 | resubmit: | |
621 | /* Resubmit urb so we continue receiving */ | 627 | /* Resubmit urb so we continue receiving */ |
622 | err = usb_submit_urb(urb, GFP_ATOMIC); | 628 | err = usb_submit_urb(urb, GFP_ATOMIC); |
623 | if (err != 0) | 629 | if (err != 0) |
@@ -855,6 +861,8 @@ static void usa90_instat_callback(struct urb *urb) | |||
855 | 861 | ||
856 | port = serial->port[0]; | 862 | port = serial->port[0]; |
857 | p_priv = usb_get_serial_port_data(port); | 863 | p_priv = usb_get_serial_port_data(port); |
864 | if (!p_priv) | ||
865 | goto resubmit; | ||
858 | 866 | ||
859 | /* Update handshaking pin state information */ | 867 | /* Update handshaking pin state information */ |
860 | old_dcd_state = p_priv->dcd_state; | 868 | old_dcd_state = p_priv->dcd_state; |
@@ -865,7 +873,7 @@ static void usa90_instat_callback(struct urb *urb) | |||
865 | 873 | ||
866 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) | 874 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
867 | tty_port_tty_hangup(&port->port, true); | 875 | tty_port_tty_hangup(&port->port, true); |
868 | 876 | resubmit: | |
869 | /* Resubmit urb so we continue receiving */ | 877 | /* Resubmit urb so we continue receiving */ |
870 | err = usb_submit_urb(urb, GFP_ATOMIC); | 878 | err = usb_submit_urb(urb, GFP_ATOMIC); |
871 | if (err != 0) | 879 | if (err != 0) |
@@ -926,6 +934,8 @@ static void usa67_instat_callback(struct urb *urb) | |||
926 | 934 | ||
927 | port = serial->port[msg->port]; | 935 | port = serial->port[msg->port]; |
928 | p_priv = usb_get_serial_port_data(port); | 936 | p_priv = usb_get_serial_port_data(port); |
937 | if (!p_priv) | ||
938 | goto resubmit; | ||
929 | 939 | ||
930 | /* Update handshaking pin state information */ | 940 | /* Update handshaking pin state information */ |
931 | old_dcd_state = p_priv->dcd_state; | 941 | old_dcd_state = p_priv->dcd_state; |
@@ -934,7 +944,7 @@ static void usa67_instat_callback(struct urb *urb) | |||
934 | 944 | ||
935 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) | 945 | if (old_dcd_state != p_priv->dcd_state && old_dcd_state) |
936 | tty_port_tty_hangup(&port->port, true); | 946 | tty_port_tty_hangup(&port->port, true); |
937 | 947 | resubmit: | |
938 | /* Resubmit urb so we continue receiving */ | 948 | /* Resubmit urb so we continue receiving */ |
939 | err = usb_submit_urb(urb, GFP_ATOMIC); | 949 | err = usb_submit_urb(urb, GFP_ATOMIC); |
940 | if (err != 0) | 950 | if (err != 0) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7a4c21b4f676..efdcee15b520 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -234,6 +234,8 @@ static void option_instat_callback(struct urb *urb); | |||
234 | 234 | ||
235 | #define QUALCOMM_VENDOR_ID 0x05C6 | 235 | #define QUALCOMM_VENDOR_ID 0x05C6 |
236 | 236 | ||
237 | #define SIERRA_VENDOR_ID 0x1199 | ||
238 | |||
237 | #define CMOTECH_VENDOR_ID 0x16d8 | 239 | #define CMOTECH_VENDOR_ID 0x16d8 |
238 | #define CMOTECH_PRODUCT_6001 0x6001 | 240 | #define CMOTECH_PRODUCT_6001 0x6001 |
239 | #define CMOTECH_PRODUCT_CMU_300 0x6002 | 241 | #define CMOTECH_PRODUCT_CMU_300 0x6002 |
@@ -512,7 +514,7 @@ enum option_blacklist_reason { | |||
512 | OPTION_BLACKLIST_RESERVED_IF = 2 | 514 | OPTION_BLACKLIST_RESERVED_IF = 2 |
513 | }; | 515 | }; |
514 | 516 | ||
515 | #define MAX_BL_NUM 8 | 517 | #define MAX_BL_NUM 11 |
516 | struct option_blacklist_info { | 518 | struct option_blacklist_info { |
517 | /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ | 519 | /* bitfield of interface numbers for OPTION_BLACKLIST_SENDSETUP */ |
518 | const unsigned long sendsetup; | 520 | const unsigned long sendsetup; |
@@ -601,6 +603,11 @@ static const struct option_blacklist_info telit_le920_blacklist = { | |||
601 | .reserved = BIT(1) | BIT(5), | 603 | .reserved = BIT(1) | BIT(5), |
602 | }; | 604 | }; |
603 | 605 | ||
606 | static const struct option_blacklist_info sierra_mc73xx_blacklist = { | ||
607 | .sendsetup = BIT(0) | BIT(2), | ||
608 | .reserved = BIT(8) | BIT(10) | BIT(11), | ||
609 | }; | ||
610 | |||
604 | static const struct usb_device_id option_ids[] = { | 611 | static const struct usb_device_id option_ids[] = { |
605 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 612 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
606 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 613 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -1098,6 +1105,8 @@ static const struct usb_device_id option_ids[] = { | |||
1098 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 1105 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
1099 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ | 1106 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ |
1100 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | 1107 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ |
1108 | { USB_DEVICE_INTERFACE_CLASS(SIERRA_VENDOR_ID, 0x68c0, 0xff), | ||
1109 | .driver_info = (kernel_ulong_t)&sierra_mc73xx_blacklist }, /* MC73xx */ | ||
1101 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, | 1110 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, |
1102 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, | 1111 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, |
1103 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), | 1112 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index cb3e14780a7e..9c63897b3a56 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -142,7 +142,6 @@ static const struct usb_device_id id_table[] = { | |||
142 | {DEVICE_SWI(0x0f3d, 0x68a2)}, /* Sierra Wireless MC7700 */ | 142 | {DEVICE_SWI(0x0f3d, 0x68a2)}, /* Sierra Wireless MC7700 */ |
143 | {DEVICE_SWI(0x114f, 0x68a2)}, /* Sierra Wireless MC7750 */ | 143 | {DEVICE_SWI(0x114f, 0x68a2)}, /* Sierra Wireless MC7750 */ |
144 | {DEVICE_SWI(0x1199, 0x68a2)}, /* Sierra Wireless MC7710 */ | 144 | {DEVICE_SWI(0x1199, 0x68a2)}, /* Sierra Wireless MC7710 */ |
145 | {DEVICE_SWI(0x1199, 0x68c0)}, /* Sierra Wireless MC73xx */ | ||
146 | {DEVICE_SWI(0x1199, 0x901c)}, /* Sierra Wireless EM7700 */ | 145 | {DEVICE_SWI(0x1199, 0x901c)}, /* Sierra Wireless EM7700 */ |
147 | {DEVICE_SWI(0x1199, 0x901f)}, /* Sierra Wireless EM7355 */ | 146 | {DEVICE_SWI(0x1199, 0x901f)}, /* Sierra Wireless EM7355 */ |
148 | {DEVICE_SWI(0x1199, 0x9040)}, /* Sierra Wireless Modem */ | 147 | {DEVICE_SWI(0x1199, 0x9040)}, /* Sierra Wireless Modem */ |
diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 8a6f371ed6e7..9893d696fc97 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h | |||
@@ -69,16 +69,39 @@ static int uas_use_uas_driver(struct usb_interface *intf, | |||
69 | return 0; | 69 | return 0; |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * ASM1051 and older ASM1053 devices have the same usb-id, and UAS is | 72 | * ASMedia has a number of usb3 to sata bridge chips, at the time of |
73 | * broken on the ASM1051, use the number of streams to differentiate. | 73 | * this writing the following versions exist: |
74 | * New ASM1053-s also support 32 streams, but have a different prod-id. | 74 | * ASM1051 - no uas support version |
75 | * ASM1051 - with broken (*) uas support | ||
76 | * ASM1053 - with working uas support | ||
77 | * ASM1153 - with working uas support | ||
78 | * | ||
79 | * Devices with these chips re-use a number of device-ids over the | ||
80 | * entire line, so the device-id is useless to determine if we're | ||
81 | * dealing with an ASM1051 (which we want to avoid). | ||
82 | * | ||
83 | * The ASM1153 can be identified by config.MaxPower == 0, | ||
84 | * where as the ASM105x models have config.MaxPower == 36. | ||
85 | * | ||
86 | * Differentiating between the ASM1053 and ASM1051 is trickier, when | ||
87 | * connected over USB-3 we can look at the number of streams supported, | ||
88 | * ASM1051 supports 32 streams, where as early ASM1053 versions support | ||
89 | * 16 streams, newer ASM1053-s also support 32 streams, but have a | ||
90 | * different prod-id. | ||
91 | * | ||
92 | * (*) ASM1051 chips do work with UAS with some disks (with the | ||
93 | * US_FL_NO_REPORT_OPCODES quirk), but are broken with other disks | ||
75 | */ | 94 | */ |
76 | if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && | 95 | if (le16_to_cpu(udev->descriptor.idVendor) == 0x174c && |
77 | le16_to_cpu(udev->descriptor.idProduct) == 0x55aa) { | 96 | (le16_to_cpu(udev->descriptor.idProduct) == 0x5106 || |
78 | if (udev->speed < USB_SPEED_SUPER) { | 97 | le16_to_cpu(udev->descriptor.idProduct) == 0x55aa)) { |
98 | if (udev->actconfig->desc.bMaxPower == 0) { | ||
99 | /* ASM1153, do nothing */ | ||
100 | } else if (udev->speed < USB_SPEED_SUPER) { | ||
79 | /* No streams info, assume ASM1051 */ | 101 | /* No streams info, assume ASM1051 */ |
80 | flags |= US_FL_IGNORE_UAS; | 102 | flags |= US_FL_IGNORE_UAS; |
81 | } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { | 103 | } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { |
104 | /* Possibly an ASM1051, disable uas */ | ||
82 | flags |= US_FL_IGNORE_UAS; | 105 | flags |= US_FL_IGNORE_UAS; |
83 | } | 106 | } |
84 | } | 107 | } |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 11c7a9676441..d684b4b8108f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -507,7 +507,7 @@ UNUSUAL_DEV( 0x04e6, 0x000c, 0x0100, 0x0100, | |||
507 | UNUSUAL_DEV( 0x04e6, 0x000f, 0x0000, 0x9999, | 507 | UNUSUAL_DEV( 0x04e6, 0x000f, 0x0000, 0x9999, |
508 | "SCM Microsystems", | 508 | "SCM Microsystems", |
509 | "eUSB SCSI Adapter (Bus Powered)", | 509 | "eUSB SCSI Adapter (Bus Powered)", |
510 | USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, | 510 | USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, |
511 | US_FL_SCM_MULT_TARG ), | 511 | US_FL_SCM_MULT_TARG ), |
512 | 512 | ||
513 | UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, | 513 | UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, |
@@ -1995,6 +1995,13 @@ UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100, | |||
1995 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1995 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
1996 | US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), | 1996 | US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), |
1997 | 1997 | ||
1998 | /* Reported by Dmitry Nezhevenko <dion@dion.org.ua> */ | ||
1999 | UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114, | ||
2000 | "JMicron", | ||
2001 | "USB to ATA/ATAPI Bridge", | ||
2002 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
2003 | US_FL_BROKEN_FUA ), | ||
2004 | |||
1998 | /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) | 2005 | /* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI) |
1999 | * and Mac USB Dock USB-SCSI */ | 2006 | * and Mac USB Dock USB-SCSI */ |
2000 | UNUSUAL_DEV( 0x1645, 0x0007, 0x0100, 0x0133, | 2007 | UNUSUAL_DEV( 0x1645, 0x0007, 0x0100, 0x0133, |
diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 18a283d6de1c..dbc00e56c7f5 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h | |||
@@ -40,6 +40,16 @@ | |||
40 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> | 40 | * and don't forget to CC: the USB development list <linux-usb@vger.kernel.org> |
41 | */ | 41 | */ |
42 | 42 | ||
43 | /* | ||
44 | * Apricorn USB3 dongle sometimes returns "USBSUSBSUSBS" in response to SCSI | ||
45 | * commands in UAS mode. Observed with the 1.28 firmware; are there others? | ||
46 | */ | ||
47 | UNUSUAL_DEV(0x0984, 0x0301, 0x0128, 0x0128, | ||
48 | "Apricorn", | ||
49 | "", | ||
50 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
51 | US_FL_IGNORE_UAS), | ||
52 | |||
43 | /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ | 53 | /* https://bugzilla.kernel.org/show_bug.cgi?id=79511 */ |
44 | UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999, | 54 | UNUSUAL_DEV(0x0bc2, 0x2312, 0x0000, 0x9999, |
45 | "Seagate", | 55 | "Seagate", |
@@ -68,6 +78,20 @@ UNUSUAL_DEV(0x0bc2, 0xa003, 0x0000, 0x9999, | |||
68 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 78 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
69 | US_FL_NO_ATA_1X), | 79 | US_FL_NO_ATA_1X), |
70 | 80 | ||
81 | /* Reported-by: Marcin ZajÄ…czkowski <mszpak@wp.pl> */ | ||
82 | UNUSUAL_DEV(0x0bc2, 0xa013, 0x0000, 0x9999, | ||
83 | "Seagate", | ||
84 | "Backup Plus", | ||
85 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
86 | US_FL_NO_ATA_1X), | ||
87 | |||
88 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | ||
89 | UNUSUAL_DEV(0x0bc2, 0xa0a4, 0x0000, 0x9999, | ||
90 | "Seagate", | ||
91 | "Backup Plus Desk", | ||
92 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
93 | US_FL_NO_ATA_1X), | ||
94 | |||
71 | /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ | 95 | /* https://bbs.archlinux.org/viewtopic.php?id=183190 */ |
72 | UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999, | 96 | UNUSUAL_DEV(0x0bc2, 0xab20, 0x0000, 0x9999, |
73 | "Seagate", | 97 | "Seagate", |
@@ -82,6 +106,13 @@ UNUSUAL_DEV(0x0bc2, 0xab21, 0x0000, 0x9999, | |||
82 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 106 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
83 | US_FL_NO_ATA_1X), | 107 | US_FL_NO_ATA_1X), |
84 | 108 | ||
109 | /* Reported-by: G. Richard Bellamy <rbellamy@pteradigm.com> */ | ||
110 | UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, | ||
111 | "Seagate", | ||
112 | "BUP Fast HDD", | ||
113 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
114 | US_FL_NO_ATA_1X), | ||
115 | |||
85 | /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */ | 116 | /* Reported-by: Claudio Bizzarri <claudio.bizzarri@gmail.com> */ |
86 | UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, | 117 | UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, |
87 | "JMicron", | 118 | "JMicron", |
@@ -89,14 +120,6 @@ UNUSUAL_DEV(0x152d, 0x0567, 0x0000, 0x9999, | |||
89 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 120 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
90 | US_FL_NO_REPORT_OPCODES), | 121 | US_FL_NO_REPORT_OPCODES), |
91 | 122 | ||
92 | /* Most ASM1051 based devices have issues with uas, blacklist them all */ | ||
93 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | ||
94 | UNUSUAL_DEV(0x174c, 0x5106, 0x0000, 0x9999, | ||
95 | "ASMedia", | ||
96 | "ASM1051", | ||
97 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
98 | US_FL_IGNORE_UAS), | ||
99 | |||
100 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | 123 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ |
101 | UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, | 124 | UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, |
102 | "VIA", | 125 | "VIA", |
@@ -104,9 +127,23 @@ UNUSUAL_DEV(0x2109, 0x0711, 0x0000, 0x9999, | |||
104 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 127 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
105 | US_FL_NO_ATA_1X), | 128 | US_FL_NO_ATA_1X), |
106 | 129 | ||
130 | /* Reported-by: Takeo Nakayama <javhera@gmx.com> */ | ||
131 | UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999, | ||
132 | "JMicron", | ||
133 | "JMS566", | ||
134 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
135 | US_FL_NO_REPORT_OPCODES), | ||
136 | |||
107 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ | 137 | /* Reported-by: Hans de Goede <hdegoede@redhat.com> */ |
108 | UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, | 138 | UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999, |
109 | "Hitachi", | 139 | "Hitachi", |
110 | "External HDD", | 140 | "External HDD", |
111 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 141 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
112 | US_FL_IGNORE_UAS), | 142 | US_FL_IGNORE_UAS), |
143 | |||
144 | /* Reported-by: Richard Henderson <rth@redhat.com> */ | ||
145 | UNUSUAL_DEV(0x4971, 0x8017, 0x0000, 0x9999, | ||
146 | "SimpleTech", | ||
147 | "External HDD", | ||
148 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
149 | US_FL_NO_REPORT_OPCODES), | ||
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index 255201f22126..7cc0122a18ce 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c | |||
@@ -840,13 +840,11 @@ static const struct vfio_device_ops vfio_pci_ops = { | |||
840 | 840 | ||
841 | static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 841 | static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
842 | { | 842 | { |
843 | u8 type; | ||
844 | struct vfio_pci_device *vdev; | 843 | struct vfio_pci_device *vdev; |
845 | struct iommu_group *group; | 844 | struct iommu_group *group; |
846 | int ret; | 845 | int ret; |
847 | 846 | ||
848 | pci_read_config_byte(pdev, PCI_HEADER_TYPE, &type); | 847 | if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL) |
849 | if ((type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) | ||
850 | return -EINVAL; | 848 | return -EINVAL; |
851 | 849 | ||
852 | group = iommu_group_get(&pdev->dev); | 850 | group = iommu_group_get(&pdev->dev); |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 14419a8ccbb6..d415d69dc237 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -538,7 +538,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, | |||
538 | ++headcount; | 538 | ++headcount; |
539 | seg += in; | 539 | seg += in; |
540 | } | 540 | } |
541 | heads[headcount - 1].len = cpu_to_vhost32(vq, len - datalen); | 541 | heads[headcount - 1].len = cpu_to_vhost32(vq, len + datalen); |
542 | *iovcount = seg; | 542 | *iovcount = seg; |
543 | if (unlikely(log)) | 543 | if (unlikely(log)) |
544 | *log_num = nlogs; | 544 | *log_num = nlogs; |
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 01c01cb3933f..d695b1673ae5 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c | |||
@@ -911,6 +911,23 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd, | |||
911 | return 0; | 911 | return 0; |
912 | } | 912 | } |
913 | 913 | ||
914 | static int vhost_scsi_to_tcm_attr(int attr) | ||
915 | { | ||
916 | switch (attr) { | ||
917 | case VIRTIO_SCSI_S_SIMPLE: | ||
918 | return TCM_SIMPLE_TAG; | ||
919 | case VIRTIO_SCSI_S_ORDERED: | ||
920 | return TCM_ORDERED_TAG; | ||
921 | case VIRTIO_SCSI_S_HEAD: | ||
922 | return TCM_HEAD_TAG; | ||
923 | case VIRTIO_SCSI_S_ACA: | ||
924 | return TCM_ACA_TAG; | ||
925 | default: | ||
926 | break; | ||
927 | } | ||
928 | return TCM_SIMPLE_TAG; | ||
929 | } | ||
930 | |||
914 | static void tcm_vhost_submission_work(struct work_struct *work) | 931 | static void tcm_vhost_submission_work(struct work_struct *work) |
915 | { | 932 | { |
916 | struct tcm_vhost_cmd *cmd = | 933 | struct tcm_vhost_cmd *cmd = |
@@ -936,9 +953,10 @@ static void tcm_vhost_submission_work(struct work_struct *work) | |||
936 | rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, | 953 | rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, |
937 | cmd->tvc_cdb, &cmd->tvc_sense_buf[0], | 954 | cmd->tvc_cdb, &cmd->tvc_sense_buf[0], |
938 | cmd->tvc_lun, cmd->tvc_exp_data_len, | 955 | cmd->tvc_lun, cmd->tvc_exp_data_len, |
939 | cmd->tvc_task_attr, cmd->tvc_data_direction, | 956 | vhost_scsi_to_tcm_attr(cmd->tvc_task_attr), |
940 | TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count, | 957 | cmd->tvc_data_direction, TARGET_SCF_ACK_KREF, |
941 | NULL, 0, sg_prot_ptr, cmd->tvc_prot_sgl_count); | 958 | sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, |
959 | cmd->tvc_prot_sgl_count); | ||
942 | if (rc < 0) { | 960 | if (rc < 0) { |
943 | transport_send_check_condition_and_sense(se_cmd, | 961 | transport_send_check_condition_and_sense(se_cmd, |
944 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | 962 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ed71b5347a76..cb807d0ea498 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -713,9 +713,13 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) | |||
713 | r = -EFAULT; | 713 | r = -EFAULT; |
714 | break; | 714 | break; |
715 | } | 715 | } |
716 | if ((a.avail_user_addr & (sizeof *vq->avail->ring - 1)) || | 716 | |
717 | (a.used_user_addr & (sizeof *vq->used->ring - 1)) || | 717 | /* Make sure it's safe to cast pointers to vring types. */ |
718 | (a.log_guest_addr & (sizeof *vq->used->ring - 1))) { | 718 | BUILD_BUG_ON(__alignof__ *vq->avail > VRING_AVAIL_ALIGN_SIZE); |
719 | BUILD_BUG_ON(__alignof__ *vq->used > VRING_USED_ALIGN_SIZE); | ||
720 | if ((a.avail_user_addr & (VRING_AVAIL_ALIGN_SIZE - 1)) || | ||
721 | (a.used_user_addr & (VRING_USED_ALIGN_SIZE - 1)) || | ||
722 | (a.log_guest_addr & (sizeof(u64) - 1))) { | ||
719 | r = -EINVAL; | 723 | r = -EINVAL; |
720 | break; | 724 | break; |
721 | } | 725 | } |
diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index 1c29bd19e3d5..0e5fde1d3ffb 100644 --- a/drivers/video/fbdev/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c | |||
@@ -636,7 +636,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, | |||
636 | err = broadsheet_spiflash_read_range(par, start_sector_addr, | 636 | err = broadsheet_spiflash_read_range(par, start_sector_addr, |
637 | data_start_addr, sector_buffer); | 637 | data_start_addr, sector_buffer); |
638 | if (err) | 638 | if (err) |
639 | return err; | 639 | goto out; |
640 | } | 640 | } |
641 | 641 | ||
642 | /* now we copy our data into the right place in the sector buffer */ | 642 | /* now we copy our data into the right place in the sector buffer */ |
@@ -657,7 +657,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, | |||
657 | err = broadsheet_spiflash_read_range(par, tail_start_addr, | 657 | err = broadsheet_spiflash_read_range(par, tail_start_addr, |
658 | tail_len, sector_buffer + tail_start_addr); | 658 | tail_len, sector_buffer + tail_start_addr); |
659 | if (err) | 659 | if (err) |
660 | return err; | 660 | goto out; |
661 | } | 661 | } |
662 | 662 | ||
663 | /* if we got here we have the full sector that we want to rewrite. */ | 663 | /* if we got here we have the full sector that we want to rewrite. */ |
@@ -665,11 +665,13 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par, | |||
665 | /* first erase the sector */ | 665 | /* first erase the sector */ |
666 | err = broadsheet_spiflash_erase_sector(par, start_sector_addr); | 666 | err = broadsheet_spiflash_erase_sector(par, start_sector_addr); |
667 | if (err) | 667 | if (err) |
668 | return err; | 668 | goto out; |
669 | 669 | ||
670 | /* now write it */ | 670 | /* now write it */ |
671 | err = broadsheet_spiflash_write_sector(par, start_sector_addr, | 671 | err = broadsheet_spiflash_write_sector(par, start_sector_addr, |
672 | sector_buffer, sector_size); | 672 | sector_buffer, sector_size); |
673 | out: | ||
674 | kfree(sector_buffer); | ||
673 | return err; | 675 | return err; |
674 | } | 676 | } |
675 | 677 | ||
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 900aa4ecd617..d6cab1fd9a47 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c | |||
@@ -83,9 +83,10 @@ int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasy | |||
83 | cancel_delayed_work_sync(&info->deferred_work); | 83 | cancel_delayed_work_sync(&info->deferred_work); |
84 | 84 | ||
85 | /* Run it immediately */ | 85 | /* Run it immediately */ |
86 | err = schedule_delayed_work(&info->deferred_work, 0); | 86 | schedule_delayed_work(&info->deferred_work, 0); |
87 | mutex_unlock(&inode->i_mutex); | 87 | mutex_unlock(&inode->i_mutex); |
88 | return err; | 88 | |
89 | return 0; | ||
89 | } | 90 | } |
90 | EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); | 91 | EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); |
91 | 92 | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c index 87accdb59c81..ac83ef5cfd7d 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c | |||
@@ -132,7 +132,6 @@ static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { | |||
132 | .mX_max = 127, | 132 | .mX_max = 127, |
133 | .fint_min = 500000, | 133 | .fint_min = 500000, |
134 | .fint_max = 2500000, | 134 | .fint_max = 2500000, |
135 | .clkdco_max = 1800000000, | ||
136 | 135 | ||
137 | .clkdco_min = 500000000, | 136 | .clkdco_min = 500000000, |
138 | .clkdco_low = 1000000000, | 137 | .clkdco_low = 1000000000, |
@@ -156,7 +155,6 @@ static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { | |||
156 | .mX_max = 127, | 155 | .mX_max = 127, |
157 | .fint_min = 620000, | 156 | .fint_min = 620000, |
158 | .fint_max = 2500000, | 157 | .fint_max = 2500000, |
159 | .clkdco_max = 1800000000, | ||
160 | 158 | ||
161 | .clkdco_min = 750000000, | 159 | .clkdco_min = 750000000, |
162 | .clkdco_low = 1500000000, | 160 | .clkdco_low = 1500000000, |
diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c index 50bc62c5d367..335ffac224b9 100644 --- a/drivers/video/fbdev/omap2/dss/pll.c +++ b/drivers/video/fbdev/omap2/dss/pll.c | |||
@@ -97,7 +97,8 @@ int dss_pll_enable(struct dss_pll *pll) | |||
97 | return 0; | 97 | return 0; |
98 | 98 | ||
99 | err_enable: | 99 | err_enable: |
100 | regulator_disable(pll->regulator); | 100 | if (pll->regulator) |
101 | regulator_disable(pll->regulator); | ||
101 | err_reg: | 102 | err_reg: |
102 | clk_disable_unprepare(pll->clkin); | 103 | clk_disable_unprepare(pll->clkin); |
103 | return r; | 104 | return r; |
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index d51a983075bc..5c2ccab5a958 100644 --- a/drivers/video/fbdev/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c | |||
@@ -342,6 +342,8 @@ static void sdi_init_output(struct platform_device *pdev) | |||
342 | out->output_type = OMAP_DISPLAY_TYPE_SDI; | 342 | out->output_type = OMAP_DISPLAY_TYPE_SDI; |
343 | out->name = "sdi.0"; | 343 | out->name = "sdi.0"; |
344 | out->dispc_channel = OMAP_DSS_CHANNEL_LCD; | 344 | out->dispc_channel = OMAP_DSS_CHANNEL_LCD; |
345 | /* We have SDI only on OMAP3, where it's on port 1 */ | ||
346 | out->port_num = 1; | ||
345 | out->ops.sdi = &sdi_ops; | 347 | out->ops.sdi = &sdi_ops; |
346 | out->owner = THIS_MODULE; | 348 | out->owner = THIS_MODULE; |
347 | 349 | ||
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 92cac803dee3..1085c0432158 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c | |||
@@ -402,7 +402,7 @@ static int __init simplefb_init(void) | |||
402 | if (ret) | 402 | if (ret) |
403 | return ret; | 403 | return ret; |
404 | 404 | ||
405 | if (IS_ENABLED(CONFIG_OF) && of_chosen) { | 405 | if (IS_ENABLED(CONFIG_OF_ADDRESS) && of_chosen) { |
406 | for_each_child_of_node(of_chosen, np) { | 406 | for_each_child_of_node(of_chosen, np) { |
407 | if (of_device_is_compatible(np, "simple-framebuffer")) | 407 | if (of_device_is_compatible(np, "simple-framebuffer")) |
408 | of_platform_device_create(np, NULL, NULL); | 408 | of_platform_device_create(np, NULL, NULL); |
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 940cd196eef5..10fbfd8ab963 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c | |||
@@ -21,6 +21,21 @@ static bool nologo; | |||
21 | module_param(nologo, bool, 0); | 21 | module_param(nologo, bool, 0); |
22 | MODULE_PARM_DESC(nologo, "Disables startup logo"); | 22 | MODULE_PARM_DESC(nologo, "Disables startup logo"); |
23 | 23 | ||
24 | /* | ||
25 | * Logos are located in the initdata, and will be freed in kernel_init. | ||
26 | * Use late_init to mark the logos as freed to prevent any further use. | ||
27 | */ | ||
28 | |||
29 | static bool logos_freed; | ||
30 | |||
31 | static int __init fb_logo_late_init(void) | ||
32 | { | ||
33 | logos_freed = true; | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | late_initcall(fb_logo_late_init); | ||
38 | |||
24 | /* logo's are marked __initdata. Use __init_refok to tell | 39 | /* logo's are marked __initdata. Use __init_refok to tell |
25 | * modpost that it is intended that this function uses data | 40 | * modpost that it is intended that this function uses data |
26 | * marked __initdata. | 41 | * marked __initdata. |
@@ -29,7 +44,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) | |||
29 | { | 44 | { |
30 | const struct linux_logo *logo = NULL; | 45 | const struct linux_logo *logo = NULL; |
31 | 46 | ||
32 | if (nologo) | 47 | if (nologo || logos_freed) |
33 | return NULL; | 48 | return NULL; |
34 | 49 | ||
35 | if (depth >= 1) { | 50 | if (depth >= 1) { |
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 2ef9529809d8..9756f21b809e 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c | |||
@@ -282,6 +282,7 @@ void vp_del_vqs(struct virtio_device *vdev) | |||
282 | 282 | ||
283 | vp_free_vectors(vdev); | 283 | vp_free_vectors(vdev); |
284 | kfree(vp_dev->vqs); | 284 | kfree(vp_dev->vqs); |
285 | vp_dev->vqs = NULL; | ||
285 | } | 286 | } |
286 | 287 | ||
287 | static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, | 288 | static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs, |
@@ -421,15 +422,6 @@ int vp_set_vq_affinity(struct virtqueue *vq, int cpu) | |||
421 | return 0; | 422 | return 0; |
422 | } | 423 | } |
423 | 424 | ||
424 | void virtio_pci_release_dev(struct device *_d) | ||
425 | { | ||
426 | /* | ||
427 | * No need for a release method as we allocate/free | ||
428 | * all devices together with the pci devices. | ||
429 | * Provide an empty one to avoid getting a warning from core. | ||
430 | */ | ||
431 | } | ||
432 | |||
433 | #ifdef CONFIG_PM_SLEEP | 425 | #ifdef CONFIG_PM_SLEEP |
434 | static int virtio_pci_freeze(struct device *dev) | 426 | static int virtio_pci_freeze(struct device *dev) |
435 | { | 427 | { |
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index adddb647b21d..5a497289b7e9 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h | |||
@@ -126,7 +126,6 @@ const char *vp_bus_name(struct virtio_device *vdev); | |||
126 | * - ignore the affinity request if we're using INTX | 126 | * - ignore the affinity request if we're using INTX |
127 | */ | 127 | */ |
128 | int vp_set_vq_affinity(struct virtqueue *vq, int cpu); | 128 | int vp_set_vq_affinity(struct virtqueue *vq, int cpu); |
129 | void virtio_pci_release_dev(struct device *); | ||
130 | 129 | ||
131 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | 130 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, |
132 | const struct pci_device_id *id); | 131 | const struct pci_device_id *id); |
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 6c76f0f5658c..a5486e65e04b 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c | |||
@@ -211,6 +211,17 @@ static const struct virtio_config_ops virtio_pci_config_ops = { | |||
211 | .set_vq_affinity = vp_set_vq_affinity, | 211 | .set_vq_affinity = vp_set_vq_affinity, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static void virtio_pci_release_dev(struct device *_d) | ||
215 | { | ||
216 | struct virtio_device *vdev = dev_to_virtio(_d); | ||
217 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
218 | |||
219 | /* As struct device is a kobject, it's not safe to | ||
220 | * free the memory (including the reference counter itself) | ||
221 | * until it's release callback. */ | ||
222 | kfree(vp_dev); | ||
223 | } | ||
224 | |||
214 | /* the PCI probing function */ | 225 | /* the PCI probing function */ |
215 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | 226 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, |
216 | const struct pci_device_id *id) | 227 | const struct pci_device_id *id) |
@@ -302,5 +313,4 @@ void virtio_pci_legacy_remove(struct pci_dev *pci_dev) | |||
302 | pci_iounmap(pci_dev, vp_dev->ioaddr); | 313 | pci_iounmap(pci_dev, vp_dev->ioaddr); |
303 | pci_release_regions(pci_dev); | 314 | pci_release_regions(pci_dev); |
304 | pci_disable_device(pci_dev); | 315 | pci_disable_device(pci_dev); |
305 | kfree(vp_dev); | ||
306 | } | 316 | } |
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index 5927c0a98a74..bcfd2a22208f 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c | |||
@@ -503,7 +503,6 @@ static struct platform_driver cdns_wdt_driver = { | |||
503 | .shutdown = cdns_wdt_shutdown, | 503 | .shutdown = cdns_wdt_shutdown, |
504 | .driver = { | 504 | .driver = { |
505 | .name = "cdns-wdt", | 505 | .name = "cdns-wdt", |
506 | .owner = THIS_MODULE, | ||
507 | .of_match_table = cdns_wdt_of_match, | 506 | .of_match_table = cdns_wdt_of_match, |
508 | .pm = &cdns_wdt_pm_ops, | 507 | .pm = &cdns_wdt_pm_ops, |
509 | }, | 508 | }, |
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index d6add516a7a7..5142bbabe027 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ | 52 | #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */ |
53 | #define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ | 53 | #define IMX2_WDT_WRSR_TOUT (1 << 1) /* -> Reset due to Timeout */ |
54 | 54 | ||
55 | #define IMX2_WDT_WMCR 0x08 /* Misc Register */ | ||
56 | |||
55 | #define IMX2_WDT_MAX_TIME 128 | 57 | #define IMX2_WDT_MAX_TIME 128 |
56 | #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ | 58 | #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */ |
57 | 59 | ||
@@ -274,6 +276,13 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) | |||
274 | 276 | ||
275 | imx2_wdt_ping_if_active(wdog); | 277 | imx2_wdt_ping_if_active(wdog); |
276 | 278 | ||
279 | /* | ||
280 | * Disable the watchdog power down counter at boot. Otherwise the power | ||
281 | * down counter will pull down the #WDOG interrupt line for one clock | ||
282 | * cycle. | ||
283 | */ | ||
284 | regmap_write(wdev->regmap, IMX2_WDT_WMCR, 0); | ||
285 | |||
277 | ret = watchdog_register_device(wdog); | 286 | ret = watchdog_register_device(wdog); |
278 | if (ret) { | 287 | if (ret) { |
279 | dev_err(&pdev->dev, "cannot register watchdog device\n"); | 288 | dev_err(&pdev->dev, "cannot register watchdog device\n"); |
@@ -327,18 +336,21 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) | |||
327 | } | 336 | } |
328 | 337 | ||
329 | #ifdef CONFIG_PM_SLEEP | 338 | #ifdef CONFIG_PM_SLEEP |
330 | /* Disable watchdog if it is active during suspend */ | 339 | /* Disable watchdog if it is active or non-active but still running */ |
331 | static int imx2_wdt_suspend(struct device *dev) | 340 | static int imx2_wdt_suspend(struct device *dev) |
332 | { | 341 | { |
333 | struct watchdog_device *wdog = dev_get_drvdata(dev); | 342 | struct watchdog_device *wdog = dev_get_drvdata(dev); |
334 | struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); | 343 | struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog); |
335 | 344 | ||
336 | imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); | 345 | /* The watchdog IP block is running */ |
337 | imx2_wdt_ping(wdog); | 346 | if (imx2_wdt_is_running(wdev)) { |
347 | imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME); | ||
348 | imx2_wdt_ping(wdog); | ||
338 | 349 | ||
339 | /* Watchdog has been stopped but IP block is still running */ | 350 | /* The watchdog is not active */ |
340 | if (!watchdog_active(wdog) && imx2_wdt_is_running(wdev)) | 351 | if (!watchdog_active(wdog)) |
341 | del_timer_sync(&wdev->timer); | 352 | del_timer_sync(&wdev->timer); |
353 | } | ||
342 | 354 | ||
343 | clk_disable_unprepare(wdev->clk); | 355 | clk_disable_unprepare(wdev->clk); |
344 | 356 | ||
@@ -354,15 +366,25 @@ static int imx2_wdt_resume(struct device *dev) | |||
354 | clk_prepare_enable(wdev->clk); | 366 | clk_prepare_enable(wdev->clk); |
355 | 367 | ||
356 | if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) { | 368 | if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) { |
357 | /* Resumes from deep sleep we need restart | 369 | /* |
358 | * the watchdog again. | 370 | * If the watchdog is still active and resumes |
371 | * from deep sleep state, need to restart the | ||
372 | * watchdog again. | ||
359 | */ | 373 | */ |
360 | imx2_wdt_setup(wdog); | 374 | imx2_wdt_setup(wdog); |
361 | imx2_wdt_set_timeout(wdog, wdog->timeout); | 375 | imx2_wdt_set_timeout(wdog, wdog->timeout); |
362 | imx2_wdt_ping(wdog); | 376 | imx2_wdt_ping(wdog); |
363 | } else if (imx2_wdt_is_running(wdev)) { | 377 | } else if (imx2_wdt_is_running(wdev)) { |
378 | /* Resuming from non-deep sleep state. */ | ||
379 | imx2_wdt_set_timeout(wdog, wdog->timeout); | ||
364 | imx2_wdt_ping(wdog); | 380 | imx2_wdt_ping(wdog); |
365 | mod_timer(&wdev->timer, jiffies + wdog->timeout * HZ / 2); | 381 | /* |
382 | * But the watchdog is not active, then start | ||
383 | * the timer again. | ||
384 | */ | ||
385 | if (!watchdog_active(wdog)) | ||
386 | mod_timer(&wdev->timer, | ||
387 | jiffies + wdog->timeout * HZ / 2); | ||
366 | } | 388 | } |
367 | 389 | ||
368 | return 0; | 390 | return 0; |
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index ef6a298e8c45..1f4155ee3404 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c | |||
@@ -215,7 +215,6 @@ static struct platform_driver meson_wdt_driver = { | |||
215 | .remove = meson_wdt_remove, | 215 | .remove = meson_wdt_remove, |
216 | .shutdown = meson_wdt_shutdown, | 216 | .shutdown = meson_wdt_shutdown, |
217 | .driver = { | 217 | .driver = { |
218 | .owner = THIS_MODULE, | ||
219 | .name = DRV_NAME, | 218 | .name = DRV_NAME, |
220 | .of_match_table = meson_wdt_dt_ids, | 219 | .of_match_table = meson_wdt_dt_ids, |
221 | }, | 220 | }, |