diff options
Diffstat (limited to 'drivers')
731 files changed, 8983 insertions, 4026 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ac7034129f3f..d5fdd36190cc 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -69,7 +69,9 @@ static const struct acpi_device_id ac_device_ids[] = { | |||
69 | }; | 69 | }; |
70 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); | 70 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); |
71 | 71 | ||
72 | #ifdef CONFIG_PM_SLEEP | ||
72 | static int acpi_ac_resume(struct device *dev); | 73 | static int acpi_ac_resume(struct device *dev); |
74 | #endif | ||
73 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | 75 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); |
74 | 76 | ||
75 | static struct acpi_driver acpi_ac_driver = { | 77 | static struct acpi_driver acpi_ac_driver = { |
@@ -313,6 +315,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
313 | return result; | 315 | return result; |
314 | } | 316 | } |
315 | 317 | ||
318 | #ifdef CONFIG_PM_SLEEP | ||
316 | static int acpi_ac_resume(struct device *dev) | 319 | static int acpi_ac_resume(struct device *dev) |
317 | { | 320 | { |
318 | struct acpi_ac *ac; | 321 | struct acpi_ac *ac; |
@@ -332,6 +335,7 @@ static int acpi_ac_resume(struct device *dev) | |||
332 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 335 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
333 | return 0; | 336 | return 0; |
334 | } | 337 | } |
338 | #endif | ||
335 | 339 | ||
336 | static int acpi_ac_remove(struct acpi_device *device, int type) | 340 | static int acpi_ac_remove(struct acpi_device *device, int type) |
337 | { | 341 | { |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5ccb99ae3a6f..5de4ec72766d 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -83,22 +83,22 @@ acpi_status acpi_hw_clear_acpi_status(void); | |||
83 | /* | 83 | /* |
84 | * hwsleep - sleep/wake support (Legacy sleep registers) | 84 | * hwsleep - sleep/wake support (Legacy sleep registers) |
85 | */ | 85 | */ |
86 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags); | 86 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state); |
87 | 87 | ||
88 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags); | 88 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state); |
89 | 89 | ||
90 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags); | 90 | acpi_status acpi_hw_legacy_wake(u8 sleep_state); |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) | 93 | * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) |
94 | */ | 94 | */ |
95 | void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); | 95 | void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); |
96 | 96 | ||
97 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags); | 97 | acpi_status acpi_hw_extended_sleep(u8 sleep_state); |
98 | 98 | ||
99 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags); | 99 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state); |
100 | 100 | ||
101 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags); | 101 | acpi_status acpi_hw_extended_wake(u8 sleep_state); |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * hwvalid - Port I/O with validation | 104 | * hwvalid - Port I/O with validation |
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 48518dac5342..94996f9ae3ad 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c | |||
@@ -90,7 +90,6 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) | |||
90 | * FUNCTION: acpi_hw_extended_sleep | 90 | * FUNCTION: acpi_hw_extended_sleep |
91 | * | 91 | * |
92 | * PARAMETERS: sleep_state - Which sleep state to enter | 92 | * PARAMETERS: sleep_state - Which sleep state to enter |
93 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
94 | * | 93 | * |
95 | * RETURN: Status | 94 | * RETURN: Status |
96 | * | 95 | * |
@@ -100,7 +99,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) | |||
100 | * | 99 | * |
101 | ******************************************************************************/ | 100 | ******************************************************************************/ |
102 | 101 | ||
103 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | 102 | acpi_status acpi_hw_extended_sleep(u8 sleep_state) |
104 | { | 103 | { |
105 | acpi_status status; | 104 | acpi_status status; |
106 | u8 sleep_type_value; | 105 | u8 sleep_type_value; |
@@ -125,12 +124,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
125 | 124 | ||
126 | acpi_gbl_system_awake_and_running = FALSE; | 125 | acpi_gbl_system_awake_and_running = FALSE; |
127 | 126 | ||
128 | /* Optionally execute _GTS (Going To Sleep) */ | ||
129 | |||
130 | if (flags & ACPI_EXECUTE_GTS) { | ||
131 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); | ||
132 | } | ||
133 | |||
134 | /* Flush caches, as per ACPI specification */ | 127 | /* Flush caches, as per ACPI specification */ |
135 | 128 | ||
136 | ACPI_FLUSH_CPU_CACHE(); | 129 | ACPI_FLUSH_CPU_CACHE(); |
@@ -172,7 +165,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
172 | * FUNCTION: acpi_hw_extended_wake_prep | 165 | * FUNCTION: acpi_hw_extended_wake_prep |
173 | * | 166 | * |
174 | * PARAMETERS: sleep_state - Which sleep state we just exited | 167 | * PARAMETERS: sleep_state - Which sleep state we just exited |
175 | * flags - ACPI_EXECUTE_BFS to run optional method | ||
176 | * | 168 | * |
177 | * RETURN: Status | 169 | * RETURN: Status |
178 | * | 170 | * |
@@ -181,7 +173,7 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
181 | * | 173 | * |
182 | ******************************************************************************/ | 174 | ******************************************************************************/ |
183 | 175 | ||
184 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | 176 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) |
185 | { | 177 | { |
186 | acpi_status status; | 178 | acpi_status status; |
187 | u8 sleep_type_value; | 179 | u8 sleep_type_value; |
@@ -200,11 +192,6 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | |||
200 | &acpi_gbl_FADT.sleep_control); | 192 | &acpi_gbl_FADT.sleep_control); |
201 | } | 193 | } |
202 | 194 | ||
203 | /* Optionally execute _BFS (Back From Sleep) */ | ||
204 | |||
205 | if (flags & ACPI_EXECUTE_BFS) { | ||
206 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); | ||
207 | } | ||
208 | return_ACPI_STATUS(AE_OK); | 195 | return_ACPI_STATUS(AE_OK); |
209 | } | 196 | } |
210 | 197 | ||
@@ -222,7 +209,7 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | |||
222 | * | 209 | * |
223 | ******************************************************************************/ | 210 | ******************************************************************************/ |
224 | 211 | ||
225 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags) | 212 | acpi_status acpi_hw_extended_wake(u8 sleep_state) |
226 | { | 213 | { |
227 | ACPI_FUNCTION_TRACE(hw_extended_wake); | 214 | ACPI_FUNCTION_TRACE(hw_extended_wake); |
228 | 215 | ||
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 9960fe9ef533..3fddde056a5e 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -56,7 +56,6 @@ ACPI_MODULE_NAME("hwsleep") | |||
56 | * FUNCTION: acpi_hw_legacy_sleep | 56 | * FUNCTION: acpi_hw_legacy_sleep |
57 | * | 57 | * |
58 | * PARAMETERS: sleep_state - Which sleep state to enter | 58 | * PARAMETERS: sleep_state - Which sleep state to enter |
59 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
60 | * | 59 | * |
61 | * RETURN: Status | 60 | * RETURN: Status |
62 | * | 61 | * |
@@ -64,7 +63,7 @@ ACPI_MODULE_NAME("hwsleep") | |||
64 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 63 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
65 | * | 64 | * |
66 | ******************************************************************************/ | 65 | ******************************************************************************/ |
67 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | 66 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state) |
68 | { | 67 | { |
69 | struct acpi_bit_register_info *sleep_type_reg_info; | 68 | struct acpi_bit_register_info *sleep_type_reg_info; |
70 | struct acpi_bit_register_info *sleep_enable_reg_info; | 69 | struct acpi_bit_register_info *sleep_enable_reg_info; |
@@ -110,12 +109,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
110 | return_ACPI_STATUS(status); | 109 | return_ACPI_STATUS(status); |
111 | } | 110 | } |
112 | 111 | ||
113 | /* Optionally execute _GTS (Going To Sleep) */ | ||
114 | |||
115 | if (flags & ACPI_EXECUTE_GTS) { | ||
116 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); | ||
117 | } | ||
118 | |||
119 | /* Get current value of PM1A control */ | 112 | /* Get current value of PM1A control */ |
120 | 113 | ||
121 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, | 114 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
@@ -214,7 +207,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
214 | * FUNCTION: acpi_hw_legacy_wake_prep | 207 | * FUNCTION: acpi_hw_legacy_wake_prep |
215 | * | 208 | * |
216 | * PARAMETERS: sleep_state - Which sleep state we just exited | 209 | * PARAMETERS: sleep_state - Which sleep state we just exited |
217 | * flags - ACPI_EXECUTE_BFS to run optional method | ||
218 | * | 210 | * |
219 | * RETURN: Status | 211 | * RETURN: Status |
220 | * | 212 | * |
@@ -224,7 +216,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
224 | * | 216 | * |
225 | ******************************************************************************/ | 217 | ******************************************************************************/ |
226 | 218 | ||
227 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | 219 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) |
228 | { | 220 | { |
229 | acpi_status status; | 221 | acpi_status status; |
230 | struct acpi_bit_register_info *sleep_type_reg_info; | 222 | struct acpi_bit_register_info *sleep_type_reg_info; |
@@ -275,11 +267,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
275 | } | 267 | } |
276 | } | 268 | } |
277 | 269 | ||
278 | /* Optionally execute _BFS (Back From Sleep) */ | ||
279 | |||
280 | if (flags & ACPI_EXECUTE_BFS) { | ||
281 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); | ||
282 | } | ||
283 | return_ACPI_STATUS(status); | 270 | return_ACPI_STATUS(status); |
284 | } | 271 | } |
285 | 272 | ||
@@ -288,7 +275,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
288 | * FUNCTION: acpi_hw_legacy_wake | 275 | * FUNCTION: acpi_hw_legacy_wake |
289 | * | 276 | * |
290 | * PARAMETERS: sleep_state - Which sleep state we just exited | 277 | * PARAMETERS: sleep_state - Which sleep state we just exited |
291 | * flags - Reserved, set to zero | ||
292 | * | 278 | * |
293 | * RETURN: Status | 279 | * RETURN: Status |
294 | * | 280 | * |
@@ -297,7 +283,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
297 | * | 283 | * |
298 | ******************************************************************************/ | 284 | ******************************************************************************/ |
299 | 285 | ||
300 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) | 286 | acpi_status acpi_hw_legacy_wake(u8 sleep_state) |
301 | { | 287 | { |
302 | acpi_status status; | 288 | acpi_status status; |
303 | 289 | ||
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index f8684bfe7907..1f165a750ae2 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("hwxfsleep") | |||
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status | 52 | static acpi_status |
53 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id); | 53 | acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id); |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Dispatch table used to efficiently branch to the various sleep | 56 | * Dispatch table used to efficiently branch to the various sleep |
@@ -235,7 +235,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | |||
235 | * | 235 | * |
236 | ******************************************************************************/ | 236 | ******************************************************************************/ |
237 | static acpi_status | 237 | static acpi_status |
238 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | 238 | acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) |
239 | { | 239 | { |
240 | acpi_status status; | 240 | acpi_status status; |
241 | struct acpi_sleep_functions *sleep_functions = | 241 | struct acpi_sleep_functions *sleep_functions = |
@@ -248,11 +248,11 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | |||
248 | * use the extended sleep registers | 248 | * use the extended sleep registers |
249 | */ | 249 | */ |
250 | if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { | 250 | if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { |
251 | status = sleep_functions->extended_function(sleep_state, flags); | 251 | status = sleep_functions->extended_function(sleep_state); |
252 | } else { | 252 | } else { |
253 | /* Legacy sleep */ | 253 | /* Legacy sleep */ |
254 | 254 | ||
255 | status = sleep_functions->legacy_function(sleep_state, flags); | 255 | status = sleep_functions->legacy_function(sleep_state); |
256 | } | 256 | } |
257 | 257 | ||
258 | return (status); | 258 | return (status); |
@@ -262,7 +262,7 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | |||
262 | * For the case where reduced-hardware-only code is being generated, | 262 | * For the case where reduced-hardware-only code is being generated, |
263 | * we know that only the extended sleep registers are available | 263 | * we know that only the extended sleep registers are available |
264 | */ | 264 | */ |
265 | status = sleep_functions->extended_function(sleep_state, flags); | 265 | status = sleep_functions->extended_function(sleep_state); |
266 | return (status); | 266 | return (status); |
267 | 267 | ||
268 | #endif /* !ACPI_REDUCED_HARDWARE */ | 268 | #endif /* !ACPI_REDUCED_HARDWARE */ |
@@ -349,7 +349,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
349 | * FUNCTION: acpi_enter_sleep_state | 349 | * FUNCTION: acpi_enter_sleep_state |
350 | * | 350 | * |
351 | * PARAMETERS: sleep_state - Which sleep state to enter | 351 | * PARAMETERS: sleep_state - Which sleep state to enter |
352 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
353 | * | 352 | * |
354 | * RETURN: Status | 353 | * RETURN: Status |
355 | * | 354 | * |
@@ -357,7 +356,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
357 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 356 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
358 | * | 357 | * |
359 | ******************************************************************************/ | 358 | ******************************************************************************/ |
360 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) | 359 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) |
361 | { | 360 | { |
362 | acpi_status status; | 361 | acpi_status status; |
363 | 362 | ||
@@ -371,7 +370,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) | |||
371 | } | 370 | } |
372 | 371 | ||
373 | status = | 372 | status = |
374 | acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID); | 373 | acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID); |
375 | return_ACPI_STATUS(status); | 374 | return_ACPI_STATUS(status); |
376 | } | 375 | } |
377 | 376 | ||
@@ -391,14 +390,14 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | |||
391 | * Called with interrupts DISABLED. | 390 | * Called with interrupts DISABLED. |
392 | * | 391 | * |
393 | ******************************************************************************/ | 392 | ******************************************************************************/ |
394 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags) | 393 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) |
395 | { | 394 | { |
396 | acpi_status status; | 395 | acpi_status status; |
397 | 396 | ||
398 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); | 397 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); |
399 | 398 | ||
400 | status = | 399 | status = |
401 | acpi_hw_sleep_dispatch(sleep_state, flags, | 400 | acpi_hw_sleep_dispatch(sleep_state, |
402 | ACPI_WAKE_PREP_FUNCTION_ID); | 401 | ACPI_WAKE_PREP_FUNCTION_ID); |
403 | return_ACPI_STATUS(status); | 402 | return_ACPI_STATUS(status); |
404 | } | 403 | } |
@@ -423,8 +422,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
423 | 422 | ||
424 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 423 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); |
425 | 424 | ||
426 | 425 | status = acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_FUNCTION_ID); | |
427 | status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID); | ||
428 | return_ACPI_STATUS(status); | 426 | return_ACPI_STATUS(status); |
429 | } | 427 | } |
430 | 428 | ||
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index ea4c6d52605a..29e51bc01383 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature, | |||
387 | 387 | ||
388 | return (AE_NOT_FOUND); | 388 | return (AE_NOT_FOUND); |
389 | } | 389 | } |
390 | ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) | ||
390 | 391 | ||
391 | acpi_status | 392 | acpi_status |
392 | acpi_get_table(char *signature, | 393 | acpi_get_table(char *signature, |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index ff2c876ec412..45e3e1759fb8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -1052,6 +1052,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
1052 | return 0; | 1052 | return 0; |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | #ifdef CONFIG_PM_SLEEP | ||
1055 | /* this is needed to learn about changes made in suspended state */ | 1056 | /* this is needed to learn about changes made in suspended state */ |
1056 | static int acpi_battery_resume(struct device *dev) | 1057 | static int acpi_battery_resume(struct device *dev) |
1057 | { | 1058 | { |
@@ -1068,6 +1069,7 @@ static int acpi_battery_resume(struct device *dev) | |||
1068 | acpi_battery_update(battery); | 1069 | acpi_battery_update(battery); |
1069 | return 0; | 1070 | return 0; |
1070 | } | 1071 | } |
1072 | #endif | ||
1071 | 1073 | ||
1072 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); | 1074 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); |
1073 | 1075 | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9628652e080c..e0596954290b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state) | |||
237 | } else if (result == ACPI_STATE_D3_HOT) { | 237 | } else if (result == ACPI_STATE_D3_HOT) { |
238 | result = ACPI_STATE_D3; | 238 | result = ACPI_STATE_D3; |
239 | } | 239 | } |
240 | |||
241 | /* | ||
242 | * If we were unsure about the device parent's power state up to this | ||
243 | * point, the fact that the device is in D0 implies that the parent has | ||
244 | * to be in D0 too. | ||
245 | */ | ||
246 | if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN | ||
247 | && result == ACPI_STATE_D0) | ||
248 | device->parent->power.state = ACPI_STATE_D0; | ||
249 | |||
240 | *state = result; | 250 | *state = result; |
241 | 251 | ||
242 | out: | 252 | out: |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 79d4c22f7a6d..314a3b84bbc7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -78,7 +78,9 @@ static int acpi_button_add(struct acpi_device *device); | |||
78 | static int acpi_button_remove(struct acpi_device *device, int type); | 78 | static int acpi_button_remove(struct acpi_device *device, int type); |
79 | static void acpi_button_notify(struct acpi_device *device, u32 event); | 79 | static void acpi_button_notify(struct acpi_device *device, u32 event); |
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | ||
81 | static int acpi_button_resume(struct device *dev); | 82 | static int acpi_button_resume(struct device *dev); |
83 | #endif | ||
82 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); | 84 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); |
83 | 85 | ||
84 | static struct acpi_driver acpi_button_driver = { | 86 | static struct acpi_driver acpi_button_driver = { |
@@ -310,6 +312,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
310 | } | 312 | } |
311 | } | 313 | } |
312 | 314 | ||
315 | #ifdef CONFIG_PM_SLEEP | ||
313 | static int acpi_button_resume(struct device *dev) | 316 | static int acpi_button_resume(struct device *dev) |
314 | { | 317 | { |
315 | struct acpi_device *device = to_acpi_device(dev); | 318 | struct acpi_device *device = to_acpi_device(dev); |
@@ -319,6 +322,7 @@ static int acpi_button_resume(struct device *dev) | |||
319 | return acpi_lid_send_state(device); | 322 | return acpi_lid_send_state(device); |
320 | return 0; | 323 | return 0; |
321 | } | 324 | } |
325 | #endif | ||
322 | 326 | ||
323 | static int acpi_button_add(struct acpi_device *device) | 327 | static int acpi_button_add(struct acpi_device *device) |
324 | { | 328 | { |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 669d9ee80d16..bc36a476f1ab 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -53,8 +53,10 @@ static const struct acpi_device_id fan_device_ids[] = { | |||
53 | }; | 53 | }; |
54 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); | 54 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); |
55 | 55 | ||
56 | #ifdef CONFIG_PM_SLEEP | ||
56 | static int acpi_fan_suspend(struct device *dev); | 57 | static int acpi_fan_suspend(struct device *dev); |
57 | static int acpi_fan_resume(struct device *dev); | 58 | static int acpi_fan_resume(struct device *dev); |
59 | #endif | ||
58 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); | 60 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); |
59 | 61 | ||
60 | static struct acpi_driver acpi_fan_driver = { | 62 | static struct acpi_driver acpi_fan_driver = { |
@@ -184,6 +186,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
184 | return 0; | 186 | return 0; |
185 | } | 187 | } |
186 | 188 | ||
189 | #ifdef CONFIG_PM_SLEEP | ||
187 | static int acpi_fan_suspend(struct device *dev) | 190 | static int acpi_fan_suspend(struct device *dev) |
188 | { | 191 | { |
189 | if (!dev) | 192 | if (!dev) |
@@ -207,6 +210,7 @@ static int acpi_fan_resume(struct device *dev) | |||
207 | 210 | ||
208 | return result; | 211 | return result; |
209 | } | 212 | } |
213 | #endif | ||
210 | 214 | ||
211 | static int __init acpi_fan_init(void) | 215 | static int __init acpi_fan_init(void) |
212 | { | 216 | { |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e56f3be7b07d..cb31298ca684 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -237,6 +237,8 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, | |||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int __initdata parsed_numa_memblks; | ||
241 | |||
240 | static int __init | 242 | static int __init |
241 | acpi_parse_memory_affinity(struct acpi_subtable_header * header, | 243 | acpi_parse_memory_affinity(struct acpi_subtable_header * header, |
242 | const unsigned long end) | 244 | const unsigned long end) |
@@ -250,8 +252,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, | |||
250 | acpi_table_print_srat_entry(header); | 252 | acpi_table_print_srat_entry(header); |
251 | 253 | ||
252 | /* let architecture-dependent part to do it */ | 254 | /* let architecture-dependent part to do it */ |
253 | acpi_numa_memory_affinity_init(memory_affinity); | 255 | if (!acpi_numa_memory_affinity_init(memory_affinity)) |
254 | 256 | parsed_numa_memblks++; | |
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
257 | 259 | ||
@@ -304,8 +306,10 @@ int __init acpi_numa_init(void) | |||
304 | 306 | ||
305 | acpi_numa_arch_fixup(); | 307 | acpi_numa_arch_fixup(); |
306 | 308 | ||
307 | if (cnt <= 0) | 309 | if (cnt < 0) |
308 | return cnt ?: -ENOENT; | 310 | return cnt; |
311 | else if (!parsed_numa_memblks) | ||
312 | return -ENOENT; | ||
309 | return 0; | 313 | return 0; |
310 | } | 314 | } |
311 | 315 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ec54014c321c..72a2c98bc429 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -573,8 +573,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
573 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | 573 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; |
574 | if (pci_msi_enabled()) | 574 | if (pci_msi_enabled()) |
575 | flags |= OSC_MSI_SUPPORT; | 575 | flags |= OSC_MSI_SUPPORT; |
576 | if (flags != base_flags) | 576 | if (flags != base_flags) { |
577 | acpi_pci_osc_support(root, flags); | 577 | status = acpi_pci_osc_support(root, flags); |
578 | if (ACPI_FAILURE(status)) { | ||
579 | dev_info(root->bus->bridge, "ACPI _OSC support " | ||
580 | "notification failed, disabling PCIe ASPM\n"); | ||
581 | pcie_no_aspm(); | ||
582 | flags = base_flags; | ||
583 | } | ||
584 | } | ||
578 | 585 | ||
579 | if (!pcie_ports_disabled | 586 | if (!pcie_ports_disabled |
580 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | 587 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 215ecd097408..40e38a06ba85 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -67,7 +67,9 @@ static const struct acpi_device_id power_device_ids[] = { | |||
67 | }; | 67 | }; |
68 | MODULE_DEVICE_TABLE(acpi, power_device_ids); | 68 | MODULE_DEVICE_TABLE(acpi, power_device_ids); |
69 | 69 | ||
70 | #ifdef CONFIG_PM_SLEEP | ||
70 | static int acpi_power_resume(struct device *dev); | 71 | static int acpi_power_resume(struct device *dev); |
72 | #endif | ||
71 | static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); | 73 | static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); |
72 | 74 | ||
73 | static struct acpi_driver acpi_power_driver = { | 75 | static struct acpi_driver acpi_power_driver = { |
@@ -105,6 +107,7 @@ struct acpi_power_resource { | |||
105 | 107 | ||
106 | /* List of devices relying on this power resource */ | 108 | /* List of devices relying on this power resource */ |
107 | struct acpi_power_resource_device *devices; | 109 | struct acpi_power_resource_device *devices; |
110 | struct mutex devices_lock; | ||
108 | }; | 111 | }; |
109 | 112 | ||
110 | static struct list_head acpi_power_resource_list; | 113 | static struct list_head acpi_power_resource_list; |
@@ -223,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device) | |||
223 | 226 | ||
224 | static int __acpi_power_on(struct acpi_power_resource *resource) | 227 | static int __acpi_power_on(struct acpi_power_resource *resource) |
225 | { | 228 | { |
226 | struct acpi_power_resource_device *device_list = resource->devices; | ||
227 | acpi_status status = AE_OK; | 229 | acpi_status status = AE_OK; |
228 | 230 | ||
229 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); | 231 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); |
@@ -236,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource) | |||
236 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", | 238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", |
237 | resource->name)); | 239 | resource->name)); |
238 | 240 | ||
239 | while (device_list) { | ||
240 | acpi_power_on_device(device_list->device); | ||
241 | |||
242 | device_list = device_list->next; | ||
243 | } | ||
244 | |||
245 | return 0; | 241 | return 0; |
246 | } | 242 | } |
247 | 243 | ||
248 | static int acpi_power_on(acpi_handle handle) | 244 | static int acpi_power_on(acpi_handle handle) |
249 | { | 245 | { |
250 | int result = 0; | 246 | int result = 0; |
247 | bool resume_device = false; | ||
251 | struct acpi_power_resource *resource = NULL; | 248 | struct acpi_power_resource *resource = NULL; |
249 | struct acpi_power_resource_device *device_list; | ||
252 | 250 | ||
253 | result = acpi_power_get_context(handle, &resource); | 251 | result = acpi_power_get_context(handle, &resource); |
254 | if (result) | 252 | if (result) |
@@ -264,10 +262,25 @@ static int acpi_power_on(acpi_handle handle) | |||
264 | result = __acpi_power_on(resource); | 262 | result = __acpi_power_on(resource); |
265 | if (result) | 263 | if (result) |
266 | resource->ref_count--; | 264 | resource->ref_count--; |
265 | else | ||
266 | resume_device = true; | ||
267 | } | 267 | } |
268 | 268 | ||
269 | mutex_unlock(&resource->resource_lock); | 269 | mutex_unlock(&resource->resource_lock); |
270 | 270 | ||
271 | if (!resume_device) | ||
272 | return result; | ||
273 | |||
274 | mutex_lock(&resource->devices_lock); | ||
275 | |||
276 | device_list = resource->devices; | ||
277 | while (device_list) { | ||
278 | acpi_power_on_device(device_list->device); | ||
279 | device_list = device_list->next; | ||
280 | } | ||
281 | |||
282 | mutex_unlock(&resource->devices_lock); | ||
283 | |||
271 | return result; | 284 | return result; |
272 | } | 285 | } |
273 | 286 | ||
@@ -353,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
353 | if (acpi_power_get_context(res_handle, &resource)) | 366 | if (acpi_power_get_context(res_handle, &resource)) |
354 | return; | 367 | return; |
355 | 368 | ||
356 | mutex_lock(&resource->resource_lock); | 369 | mutex_lock(&resource->devices_lock); |
357 | prev = NULL; | 370 | prev = NULL; |
358 | curr = resource->devices; | 371 | curr = resource->devices; |
359 | while (curr) { | 372 | while (curr) { |
@@ -370,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
370 | prev = curr; | 383 | prev = curr; |
371 | curr = curr->next; | 384 | curr = curr->next; |
372 | } | 385 | } |
373 | mutex_unlock(&resource->resource_lock); | 386 | mutex_unlock(&resource->devices_lock); |
374 | } | 387 | } |
375 | 388 | ||
376 | /* Unlink dev from all power resources in _PR0 */ | 389 | /* Unlink dev from all power resources in _PR0 */ |
@@ -412,10 +425,10 @@ static int __acpi_power_resource_register_device( | |||
412 | 425 | ||
413 | power_resource_device->device = powered_device; | 426 | power_resource_device->device = powered_device; |
414 | 427 | ||
415 | mutex_lock(&resource->resource_lock); | 428 | mutex_lock(&resource->devices_lock); |
416 | power_resource_device->next = resource->devices; | 429 | power_resource_device->next = resource->devices; |
417 | resource->devices = power_resource_device; | 430 | resource->devices = power_resource_device; |
418 | mutex_unlock(&resource->resource_lock); | 431 | mutex_unlock(&resource->devices_lock); |
419 | 432 | ||
420 | return 0; | 433 | return 0; |
421 | } | 434 | } |
@@ -460,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | |||
460 | return ret; | 473 | return ret; |
461 | 474 | ||
462 | no_power_resource: | 475 | no_power_resource: |
463 | printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); | 476 | printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); |
464 | return -ENODEV; | 477 | return -ENODEV; |
465 | } | 478 | } |
466 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); | 479 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); |
@@ -719,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device) | |||
719 | 732 | ||
720 | resource->device = device; | 733 | resource->device = device; |
721 | mutex_init(&resource->resource_lock); | 734 | mutex_init(&resource->resource_lock); |
735 | mutex_init(&resource->devices_lock); | ||
722 | strcpy(resource->name, device->pnp.bus_id); | 736 | strcpy(resource->name, device->pnp.bus_id); |
723 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 737 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
724 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 738 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
@@ -775,6 +789,7 @@ static int acpi_power_remove(struct acpi_device *device, int type) | |||
775 | return 0; | 789 | return 0; |
776 | } | 790 | } |
777 | 791 | ||
792 | #ifdef CONFIG_PM_SLEEP | ||
778 | static int acpi_power_resume(struct device *dev) | 793 | static int acpi_power_resume(struct device *dev) |
779 | { | 794 | { |
780 | int result = 0, state; | 795 | int result = 0, state; |
@@ -803,6 +818,7 @@ static int acpi_power_resume(struct device *dev) | |||
803 | 818 | ||
804 | return result; | 819 | return result; |
805 | } | 820 | } |
821 | #endif | ||
806 | 822 | ||
807 | int __init acpi_power_init(void) | 823 | int __init acpi_power_init(void) |
808 | { | 824 | { |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index ff8e04f2fab4..bfc31cb0dd3e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -437,7 +437,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
437 | /* Normal CPU soft online event */ | 437 | /* Normal CPU soft online event */ |
438 | } else { | 438 | } else { |
439 | acpi_processor_ppc_has_changed(pr, 0); | 439 | acpi_processor_ppc_has_changed(pr, 0); |
440 | acpi_processor_cst_has_changed(pr); | 440 | acpi_processor_hotplug(pr); |
441 | acpi_processor_reevaluate_tstate(pr, action); | 441 | acpi_processor_reevaluate_tstate(pr, action); |
442 | acpi_processor_tstate_has_changed(pr); | 442 | acpi_processor_tstate_has_changed(pr); |
443 | } | 443 | } |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index c0b9aa5faf4c..ff0740e0a9c2 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -988,6 +988,7 @@ static void acpi_sbs_rmdirs(void) | |||
988 | #endif | 988 | #endif |
989 | } | 989 | } |
990 | 990 | ||
991 | #ifdef CONFIG_PM_SLEEP | ||
991 | static int acpi_sbs_resume(struct device *dev) | 992 | static int acpi_sbs_resume(struct device *dev) |
992 | { | 993 | { |
993 | struct acpi_sbs *sbs; | 994 | struct acpi_sbs *sbs; |
@@ -997,6 +998,7 @@ static int acpi_sbs_resume(struct device *dev) | |||
997 | acpi_sbs_callback(sbs); | 998 | acpi_sbs_callback(sbs); |
998 | return 0; | 999 | return 0; |
999 | } | 1000 | } |
1001 | #endif | ||
1000 | 1002 | ||
1001 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); | 1003 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); |
1002 | 1004 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 7a7a9c929247..fdcdbb652915 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -28,36 +28,7 @@ | |||
28 | #include "internal.h" | 28 | #include "internal.h" |
29 | #include "sleep.h" | 29 | #include "sleep.h" |
30 | 30 | ||
31 | u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS; | ||
32 | static unsigned int gts, bfs; | ||
33 | static int set_param_wake_flag(const char *val, struct kernel_param *kp) | ||
34 | { | ||
35 | int ret = param_set_int(val, kp); | ||
36 | |||
37 | if (ret) | ||
38 | return ret; | ||
39 | |||
40 | if (kp->arg == (const char *)>s) { | ||
41 | if (gts) | ||
42 | wake_sleep_flags |= ACPI_EXECUTE_GTS; | ||
43 | else | ||
44 | wake_sleep_flags &= ~ACPI_EXECUTE_GTS; | ||
45 | } | ||
46 | if (kp->arg == (const char *)&bfs) { | ||
47 | if (bfs) | ||
48 | wake_sleep_flags |= ACPI_EXECUTE_BFS; | ||
49 | else | ||
50 | wake_sleep_flags &= ~ACPI_EXECUTE_BFS; | ||
51 | } | ||
52 | return ret; | ||
53 | } | ||
54 | module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); | ||
55 | module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); | ||
56 | MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); | ||
57 | MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); | ||
58 | |||
59 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 31 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
60 | static bool pwr_btn_event_pending; | ||
61 | 32 | ||
62 | static void acpi_sleep_tts_switch(u32 acpi_state) | 33 | static void acpi_sleep_tts_switch(u32 acpi_state) |
63 | { | 34 | { |
@@ -110,6 +81,7 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
110 | 81 | ||
111 | #ifdef CONFIG_ACPI_SLEEP | 82 | #ifdef CONFIG_ACPI_SLEEP |
112 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 83 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
84 | static bool pwr_btn_event_pending; | ||
113 | 85 | ||
114 | /* | 86 | /* |
115 | * The ACPI specification wants us to save NVS memory regions during hibernation | 87 | * The ACPI specification wants us to save NVS memory regions during hibernation |
@@ -305,7 +277,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
305 | switch (acpi_state) { | 277 | switch (acpi_state) { |
306 | case ACPI_STATE_S1: | 278 | case ACPI_STATE_S1: |
307 | barrier(); | 279 | barrier(); |
308 | status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags); | 280 | status = acpi_enter_sleep_state(acpi_state); |
309 | break; | 281 | break; |
310 | 282 | ||
311 | case ACPI_STATE_S3: | 283 | case ACPI_STATE_S3: |
@@ -319,8 +291,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
319 | /* This violates the spec but is required for bug compatibility. */ | 291 | /* This violates the spec but is required for bug compatibility. */ |
320 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); | 292 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); |
321 | 293 | ||
322 | /* Reprogram control registers and execute _BFS */ | 294 | /* Reprogram control registers */ |
323 | acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags); | 295 | acpi_leave_sleep_state_prep(acpi_state); |
324 | 296 | ||
325 | /* ACPI 3.0 specs (P62) says that it's the responsibility | 297 | /* ACPI 3.0 specs (P62) says that it's the responsibility |
326 | * of the OSPM to clear the status bit [ implying that the | 298 | * of the OSPM to clear the status bit [ implying that the |
@@ -603,9 +575,9 @@ static int acpi_hibernation_enter(void) | |||
603 | ACPI_FLUSH_CPU_CACHE(); | 575 | ACPI_FLUSH_CPU_CACHE(); |
604 | 576 | ||
605 | /* This shouldn't return. If it returns, we have a problem */ | 577 | /* This shouldn't return. If it returns, we have a problem */ |
606 | status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags); | 578 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
607 | /* Reprogram control registers and execute _BFS */ | 579 | /* Reprogram control registers */ |
608 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); | 580 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
609 | 581 | ||
610 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 582 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
611 | } | 583 | } |
@@ -617,8 +589,8 @@ static void acpi_hibernation_leave(void) | |||
617 | * enable it here. | 589 | * enable it here. |
618 | */ | 590 | */ |
619 | acpi_enable(); | 591 | acpi_enable(); |
620 | /* Reprogram control registers and execute _BFS */ | 592 | /* Reprogram control registers */ |
621 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); | 593 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
622 | /* Check the hardware signature */ | 594 | /* Check the hardware signature */ |
623 | if (facs && s4_hardware_signature != facs->hardware_signature) { | 595 | if (facs && s4_hardware_signature != facs->hardware_signature) { |
624 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " | 596 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " |
@@ -892,33 +864,7 @@ static void acpi_power_off(void) | |||
892 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 864 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
893 | printk(KERN_DEBUG "%s called\n", __func__); | 865 | printk(KERN_DEBUG "%s called\n", __func__); |
894 | local_irq_disable(); | 866 | local_irq_disable(); |
895 | acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags); | 867 | acpi_enter_sleep_state(ACPI_STATE_S5); |
896 | } | ||
897 | |||
898 | /* | ||
899 | * ACPI 2.0 created the optional _GTS and _BFS, | ||
900 | * but industry adoption has been neither rapid nor broad. | ||
901 | * | ||
902 | * Linux gets into trouble when it executes poorly validated | ||
903 | * paths through the BIOS, so disable _GTS and _BFS by default, | ||
904 | * but do speak up and offer the option to enable them. | ||
905 | */ | ||
906 | static void __init acpi_gts_bfs_check(void) | ||
907 | { | ||
908 | acpi_handle dummy; | ||
909 | |||
910 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy))) | ||
911 | { | ||
912 | printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); | ||
913 | printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " | ||
914 | "please notify linux-acpi@vger.kernel.org\n"); | ||
915 | } | ||
916 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy))) | ||
917 | { | ||
918 | printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); | ||
919 | printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " | ||
920 | "please notify linux-acpi@vger.kernel.org\n"); | ||
921 | } | ||
922 | } | 868 | } |
923 | 869 | ||
924 | int __init acpi_sleep_init(void) | 870 | int __init acpi_sleep_init(void) |
@@ -979,6 +925,5 @@ int __init acpi_sleep_init(void) | |||
979 | * object can also be evaluated when the system enters S5. | 925 | * object can also be evaluated when the system enters S5. |
980 | */ | 926 | */ |
981 | register_reboot_notifier(&tts_notifier); | 927 | register_reboot_notifier(&tts_notifier); |
982 | acpi_gts_bfs_check(); | ||
983 | return 0; | 928 | return 0; |
984 | } | 929 | } |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 240a24400976..7c3f98ba4afe 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) | |||
173 | { | 173 | { |
174 | int result = 0; | 174 | int result = 0; |
175 | 175 | ||
176 | if (!strncmp(val, "enable", strlen("enable"))) { | 176 | if (!strncmp(val, "enable", sizeof("enable") - 1)) { |
177 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | 177 | result = acpi_debug_trace(trace_method_name, trace_debug_level, |
178 | trace_debug_layer, 0); | 178 | trace_debug_layer, 0); |
179 | if (result) | 179 | if (result) |
@@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) | |||
181 | goto exit; | 181 | goto exit; |
182 | } | 182 | } |
183 | 183 | ||
184 | if (!strncmp(val, "disable", strlen("disable"))) { | 184 | if (!strncmp(val, "disable", sizeof("disable") - 1)) { |
185 | int name = 0; | 185 | int name = 0; |
186 | result = acpi_debug_trace((char *)&name, trace_debug_level, | 186 | result = acpi_debug_trace((char *)&name, trace_debug_level, |
187 | trace_debug_layer, 0); | 187 | trace_debug_layer, 0); |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9fe90e9fecb5..edda74a43406 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -106,7 +106,9 @@ static const struct acpi_device_id thermal_device_ids[] = { | |||
106 | }; | 106 | }; |
107 | MODULE_DEVICE_TABLE(acpi, thermal_device_ids); | 107 | MODULE_DEVICE_TABLE(acpi, thermal_device_ids); |
108 | 108 | ||
109 | #ifdef CONFIG_PM_SLEEP | ||
109 | static int acpi_thermal_resume(struct device *dev); | 110 | static int acpi_thermal_resume(struct device *dev); |
111 | #endif | ||
110 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); | 112 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); |
111 | 113 | ||
112 | static struct acpi_driver acpi_thermal_driver = { | 114 | static struct acpi_driver acpi_thermal_driver = { |
@@ -1041,6 +1043,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1041 | return 0; | 1043 | return 0; |
1042 | } | 1044 | } |
1043 | 1045 | ||
1046 | #ifdef CONFIG_PM_SLEEP | ||
1044 | static int acpi_thermal_resume(struct device *dev) | 1047 | static int acpi_thermal_resume(struct device *dev) |
1045 | { | 1048 | { |
1046 | struct acpi_thermal *tz; | 1049 | struct acpi_thermal *tz; |
@@ -1075,6 +1078,7 @@ static int acpi_thermal_resume(struct device *dev) | |||
1075 | 1078 | ||
1076 | return AE_OK; | 1079 | return AE_OK; |
1077 | } | 1080 | } |
1081 | #endif | ||
1078 | 1082 | ||
1079 | static int thermal_act(const struct dmi_system_id *d) { | 1083 | static int thermal_act(const struct dmi_system_id *d) { |
1080 | 1084 | ||
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2be8ef1d3093..27cecd313e75 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -115,7 +115,7 @@ config SATA_SIL24 | |||
115 | If unsure, say N. | 115 | If unsure, say N. |
116 | 116 | ||
117 | config ATA_SFF | 117 | config ATA_SFF |
118 | bool "ATA SFF support" | 118 | bool "ATA SFF support (for legacy IDE and PATA)" |
119 | default y | 119 | default y |
120 | help | 120 | help |
121 | This option adds support for ATA controllers with SFF | 121 | This option adds support for ATA controllers with SFF |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 062e6a1a248f..7862d17976b7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -256,10 +256,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
256 | { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ | 256 | { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */ |
257 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ | 257 | { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ |
258 | { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ | 258 | { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */ |
259 | { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */ | ||
260 | { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */ | ||
261 | { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */ | ||
262 | { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */ | ||
263 | { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */ | ||
264 | { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */ | ||
265 | { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */ | ||
266 | { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */ | ||
259 | 267 | ||
260 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
261 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
262 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, | 270 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, |
271 | /* JMicron 362B and 362C have an AHCI function with IDE class code */ | ||
272 | { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, | ||
273 | { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr }, | ||
263 | 274 | ||
264 | /* ATI */ | 275 | /* ATI */ |
265 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ | 276 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ |
@@ -385,6 +396,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
385 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ | 396 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ |
386 | { PCI_DEVICE(0x1b4b, 0x917a), | 397 | { PCI_DEVICE(0x1b4b, 0x917a), |
387 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ | 398 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ |
399 | { PCI_DEVICE(0x1b4b, 0x9192), | ||
400 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ | ||
388 | { PCI_DEVICE(0x1b4b, 0x91a3), | 401 | { PCI_DEVICE(0x1b4b, 0x91a3), |
389 | .driver_data = board_ahci_yes_fbs }, | 402 | .driver_data = board_ahci_yes_fbs }, |
390 | 403 | ||
@@ -392,7 +405,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
392 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 405 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
393 | 406 | ||
394 | /* Asmedia */ | 407 | /* Asmedia */ |
395 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */ | 408 | { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ |
409 | { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ | ||
410 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | ||
411 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | ||
396 | 412 | ||
397 | /* Generic, PCI class code for AHCI */ | 413 | /* Generic, PCI class code for AHCI */ |
398 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 414 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index c2594ddf25b0..57eb1c212a4c 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -320,6 +320,7 @@ extern struct device_attribute *ahci_sdev_attrs[]; | |||
320 | extern struct ata_port_operations ahci_ops; | 320 | extern struct ata_port_operations ahci_ops; |
321 | extern struct ata_port_operations ahci_pmp_retry_srst_ops; | 321 | extern struct ata_port_operations ahci_pmp_retry_srst_ops; |
322 | 322 | ||
323 | unsigned int ahci_dev_classify(struct ata_port *ap); | ||
323 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 324 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
324 | u32 opts); | 325 | u32 opts); |
325 | void ahci_save_initial_config(struct device *dev, | 326 | void ahci_save_initial_config(struct device *dev, |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 3c809bfbccf5..ef773e12af79 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -329,6 +329,14 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
329 | { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 329 | { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
330 | /* SATA Controller IDE (Lynx Point) */ | 330 | /* SATA Controller IDE (Lynx Point) */ |
331 | { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 331 | { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
332 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
333 | { 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
334 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
335 | { 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, | ||
336 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
337 | { 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
338 | /* SATA Controller IDE (Lynx Point-LP) */ | ||
339 | { 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
332 | /* SATA Controller IDE (DH89xxCC) */ | 340 | /* SATA Controller IDE (DH89xxCC) */ |
333 | { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 341 | { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
334 | { } /* terminate list */ | 342 | { } /* terminate list */ |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index f9eaa82311a9..555c07afa05b 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -1139,7 +1139,7 @@ static void ahci_dev_config(struct ata_device *dev) | |||
1139 | } | 1139 | } |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | static unsigned int ahci_dev_classify(struct ata_port *ap) | 1142 | unsigned int ahci_dev_classify(struct ata_port *ap) |
1143 | { | 1143 | { |
1144 | void __iomem *port_mmio = ahci_port_base(ap); | 1144 | void __iomem *port_mmio = ahci_port_base(ap); |
1145 | struct ata_taskfile tf; | 1145 | struct ata_taskfile tf; |
@@ -1153,6 +1153,7 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
1153 | 1153 | ||
1154 | return ata_dev_classify(&tf); | 1154 | return ata_dev_classify(&tf); |
1155 | } | 1155 | } |
1156 | EXPORT_SYMBOL_GPL(ahci_dev_classify); | ||
1156 | 1157 | ||
1157 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 1158 | void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
1158 | u32 opts) | 1159 | u32 opts) |
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 902b5a457170..fd9ecf74e631 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
@@ -60,17 +60,7 @@ acpi_handle ata_ap_acpi_handle(struct ata_port *ap) | |||
60 | if (ap->flags & ATA_FLAG_ACPI_SATA) | 60 | if (ap->flags & ATA_FLAG_ACPI_SATA) |
61 | return NULL; | 61 | return NULL; |
62 | 62 | ||
63 | /* | 63 | return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), ap->port_no); |
64 | * If acpi bind operation has already happened, we can get the handle | ||
65 | * for the port by checking the corresponding scsi_host device's | ||
66 | * firmware node, otherwise we will need to find out the handle from | ||
67 | * its parent's acpi node. | ||
68 | */ | ||
69 | if (ap->scsi_host) | ||
70 | return DEVICE_ACPI_HANDLE(&ap->scsi_host->shost_gendev); | ||
71 | else | ||
72 | return acpi_get_child(DEVICE_ACPI_HANDLE(ap->host->dev), | ||
73 | ap->port_no); | ||
74 | } | 64 | } |
75 | EXPORT_SYMBOL(ata_ap_acpi_handle); | 65 | EXPORT_SYMBOL(ata_ap_acpi_handle); |
76 | 66 | ||
@@ -1101,6 +1091,9 @@ static int ata_acpi_bind_host(struct ata_port *ap, acpi_handle *handle) | |||
1101 | if (!*handle) | 1091 | if (!*handle) |
1102 | return -ENODEV; | 1092 | return -ENODEV; |
1103 | 1093 | ||
1094 | if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) | ||
1095 | ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; | ||
1096 | |||
1104 | return 0; | 1097 | return 0; |
1105 | } | 1098 | } |
1106 | 1099 | ||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index fadd5866d40f..8e1039c8e159 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4062,7 +4062,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4062 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, | 4062 | { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA }, |
4063 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, | 4063 | { "SAMSUNG CD-ROM SN-124", "N001", ATA_HORKAGE_NODMA }, |
4064 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, | 4064 | { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA }, |
4065 | { "2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, | 4065 | { " 2GB ATA Flash Disk", "ADMA428M", ATA_HORKAGE_NODMA }, |
4066 | /* Odd clown on sil3726/4726 PMPs */ | 4066 | /* Odd clown on sil3726/4726 PMPs */ |
4067 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, | 4067 | { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, |
4068 | 4068 | ||
@@ -4128,6 +4128,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4128 | 4128 | ||
4129 | /* Devices that do not need bridging limits applied */ | 4129 | /* Devices that do not need bridging limits applied */ |
4130 | { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, | 4130 | { "MTRON MSP-SATA*", NULL, ATA_HORKAGE_BRIDGE_OK, }, |
4131 | { "BUFFALO HD-QSU2/R5", NULL, ATA_HORKAGE_BRIDGE_OK, }, | ||
4131 | 4132 | ||
4132 | /* Devices which aren't very happy with higher link speeds */ | 4133 | /* Devices which aren't very happy with higher link speeds */ |
4133 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, | 4134 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, |
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index 361c75cea57b..24e51056ac26 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <scsi/scsi_host.h> | 21 | #include <scsi/scsi_host.h> |
22 | #include <linux/libata.h> | 22 | #include <linux/libata.h> |
23 | #include <linux/dmi.h> | ||
23 | 24 | ||
24 | #define DRV_NAME "pata_atiixp" | 25 | #define DRV_NAME "pata_atiixp" |
25 | #define DRV_VERSION "0.4.6" | 26 | #define DRV_VERSION "0.4.6" |
@@ -33,11 +34,26 @@ enum { | |||
33 | ATIIXP_IDE_UDMA_MODE = 0x56 | 34 | ATIIXP_IDE_UDMA_MODE = 0x56 |
34 | }; | 35 | }; |
35 | 36 | ||
37 | static const struct dmi_system_id attixp_cable_override_dmi_table[] = { | ||
38 | { | ||
39 | /* Board has onboard PATA<->SATA converters */ | ||
40 | .ident = "MSI E350DM-E33", | ||
41 | .matches = { | ||
42 | DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), | ||
43 | DMI_MATCH(DMI_BOARD_NAME, "E350DM-E33(MS-7720)"), | ||
44 | }, | ||
45 | }, | ||
46 | { } | ||
47 | }; | ||
48 | |||
36 | static int atiixp_cable_detect(struct ata_port *ap) | 49 | static int atiixp_cable_detect(struct ata_port *ap) |
37 | { | 50 | { |
38 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | 51 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); |
39 | u8 udma; | 52 | u8 udma; |
40 | 53 | ||
54 | if (dmi_check_system(attixp_cable_override_dmi_table)) | ||
55 | return ATA_CBL_PATA40_SHORT; | ||
56 | |||
41 | /* Hack from drivers/ide/pci. Really we want to know how to do the | 57 | /* Hack from drivers/ide/pci. Really we want to know how to do the |
42 | raw detection not play follow the bios mode guess */ | 58 | raw detection not play follow the bios mode guess */ |
43 | pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); | 59 | pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma); |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index d4386019af5d..96cce6d53195 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev) | |||
2362 | { | 2362 | { |
2363 | printk(DEV_LABEL " (itf %d): can't set up page mapping\n", | 2363 | printk(DEV_LABEL " (itf %d): can't set up page mapping\n", |
2364 | dev->number); | 2364 | dev->number); |
2365 | return error; | 2365 | return -ENOMEM; |
2366 | } | 2366 | } |
2367 | IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n", | 2367 | IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n", |
2368 | dev->number, iadev->pci->revision, base, iadev->irq);) | 2368 | dev->number, iadev->pci->revision, base, iadev->irq);) |
diff --git a/drivers/base/core.c b/drivers/base/core.c index f338037a4f3d..5e6e00bc1652 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1865,6 +1865,7 @@ int __dev_printk(const char *level, const struct device *dev, | |||
1865 | struct va_format *vaf) | 1865 | struct va_format *vaf) |
1866 | { | 1866 | { |
1867 | char dict[128]; | 1867 | char dict[128]; |
1868 | const char *level_extra = ""; | ||
1868 | size_t dictlen = 0; | 1869 | size_t dictlen = 0; |
1869 | const char *subsys; | 1870 | const char *subsys; |
1870 | 1871 | ||
@@ -1911,10 +1912,14 @@ int __dev_printk(const char *level, const struct device *dev, | |||
1911 | "DEVICE=+%s:%s", subsys, dev_name(dev)); | 1912 | "DEVICE=+%s:%s", subsys, dev_name(dev)); |
1912 | } | 1913 | } |
1913 | skip: | 1914 | skip: |
1915 | if (level[2]) | ||
1916 | level_extra = &level[2]; /* skip past KERN_SOH "L" */ | ||
1917 | |||
1914 | return printk_emit(0, level[1] - '0', | 1918 | return printk_emit(0, level[1] - '0', |
1915 | dictlen ? dict : NULL, dictlen, | 1919 | dictlen ? dict : NULL, dictlen, |
1916 | "%s %s: %pV", | 1920 | "%s %s: %s%pV", |
1917 | dev_driver_string(dev), dev_name(dev), vaf); | 1921 | dev_driver_string(dev), dev_name(dev), |
1922 | level_extra, vaf); | ||
1918 | } | 1923 | } |
1919 | EXPORT_SYMBOL(__dev_printk); | 1924 | EXPORT_SYMBOL(__dev_printk); |
1920 | 1925 | ||
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 78efb0306a44..34d94c762a1e 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -250,7 +250,7 @@ int __init dma_declare_contiguous(struct device *dev, unsigned long size, | |||
250 | return -EINVAL; | 250 | return -EINVAL; |
251 | 251 | ||
252 | /* Sanitise input arguments */ | 252 | /* Sanitise input arguments */ |
253 | alignment = PAGE_SIZE << max(MAX_ORDER, pageblock_order); | 253 | alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); |
254 | base = ALIGN(base, alignment); | 254 | base = ALIGN(base, alignment); |
255 | size = ALIGN(size, alignment); | 255 | size = ALIGN(size, alignment); |
256 | limit &= ~(alignment - 1); | 256 | limit &= ~(alignment - 1); |
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 869d7ff2227f..eb78e9640c4a 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -169,8 +169,7 @@ void pm_clk_init(struct device *dev) | |||
169 | */ | 169 | */ |
170 | int pm_clk_create(struct device *dev) | 170 | int pm_clk_create(struct device *dev) |
171 | { | 171 | { |
172 | int ret = dev_pm_get_subsys_data(dev); | 172 | return dev_pm_get_subsys_data(dev); |
173 | return ret < 0 ? ret : 0; | ||
174 | } | 173 | } |
175 | 174 | ||
176 | /** | 175 | /** |
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index a14085cc613f..39c32529b833 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c | |||
@@ -24,7 +24,6 @@ | |||
24 | int dev_pm_get_subsys_data(struct device *dev) | 24 | int dev_pm_get_subsys_data(struct device *dev) |
25 | { | 25 | { |
26 | struct pm_subsys_data *psd; | 26 | struct pm_subsys_data *psd; |
27 | int ret = 0; | ||
28 | 27 | ||
29 | psd = kzalloc(sizeof(*psd), GFP_KERNEL); | 28 | psd = kzalloc(sizeof(*psd), GFP_KERNEL); |
30 | if (!psd) | 29 | if (!psd) |
@@ -40,7 +39,6 @@ int dev_pm_get_subsys_data(struct device *dev) | |||
40 | dev->power.subsys_data = psd; | 39 | dev->power.subsys_data = psd; |
41 | pm_clk_init(dev); | 40 | pm_clk_init(dev); |
42 | psd = NULL; | 41 | psd = NULL; |
43 | ret = 1; | ||
44 | } | 42 | } |
45 | 43 | ||
46 | spin_unlock_irq(&dev->power.lock); | 44 | spin_unlock_irq(&dev->power.lock); |
@@ -48,7 +46,7 @@ int dev_pm_get_subsys_data(struct device *dev) | |||
48 | /* kfree() verifies that its argument is nonzero. */ | 46 | /* kfree() verifies that its argument is nonzero. */ |
49 | kfree(psd); | 47 | kfree(psd); |
50 | 48 | ||
51 | return ret; | 49 | return 0; |
52 | } | 50 | } |
53 | EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); | 51 | EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); |
54 | 52 | ||
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 59894873a3b3..7d9c1cb1c39a 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
147 | || (dev->power.request_pending | 147 | || (dev->power.request_pending |
148 | && dev->power.request == RPM_REQ_RESUME)) | 148 | && dev->power.request == RPM_REQ_RESUME)) |
149 | retval = -EAGAIN; | 149 | retval = -EAGAIN; |
150 | else if (__dev_pm_qos_read_value(dev) < 0) | ||
151 | retval = -EPERM; | ||
150 | else if (dev->power.runtime_status == RPM_SUSPENDED) | 152 | else if (dev->power.runtime_status == RPM_SUSPENDED) |
151 | retval = 1; | 153 | retval = 1; |
152 | 154 | ||
@@ -388,7 +390,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
388 | goto repeat; | 390 | goto repeat; |
389 | } | 391 | } |
390 | 392 | ||
391 | dev->power.deferred_resume = false; | ||
392 | if (dev->power.no_callbacks) | 393 | if (dev->power.no_callbacks) |
393 | goto no_callback; /* Assume success. */ | 394 | goto no_callback; /* Assume success. */ |
394 | 395 | ||
@@ -403,12 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
403 | goto out; | 404 | goto out; |
404 | } | 405 | } |
405 | 406 | ||
406 | if (__dev_pm_qos_read_value(dev) < 0) { | ||
407 | /* Negative PM QoS constraint means "never suspend". */ | ||
408 | retval = -EPERM; | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | __update_runtime_status(dev, RPM_SUSPENDING); | 407 | __update_runtime_status(dev, RPM_SUSPENDING); |
413 | 408 | ||
414 | if (dev->pm_domain) | 409 | if (dev->pm_domain) |
@@ -440,6 +435,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
440 | wake_up_all(&dev->power.wait_queue); | 435 | wake_up_all(&dev->power.wait_queue); |
441 | 436 | ||
442 | if (dev->power.deferred_resume) { | 437 | if (dev->power.deferred_resume) { |
438 | dev->power.deferred_resume = false; | ||
443 | rpm_resume(dev, 0); | 439 | rpm_resume(dev, 0); |
444 | retval = -EAGAIN; | 440 | retval = -EAGAIN; |
445 | goto out; | 441 | goto out; |
@@ -584,6 +580,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
584 | || dev->parent->power.runtime_status == RPM_ACTIVE) { | 580 | || dev->parent->power.runtime_status == RPM_ACTIVE) { |
585 | atomic_inc(&dev->parent->power.child_count); | 581 | atomic_inc(&dev->parent->power.child_count); |
586 | spin_unlock(&dev->parent->power.lock); | 582 | spin_unlock(&dev->parent->power.lock); |
583 | retval = 1; | ||
587 | goto no_callback; /* Assume success. */ | 584 | goto no_callback; /* Assume success. */ |
588 | } | 585 | } |
589 | spin_unlock(&dev->parent->power.lock); | 586 | spin_unlock(&dev->parent->power.lock); |
@@ -664,7 +661,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
664 | } | 661 | } |
665 | wake_up_all(&dev->power.wait_queue); | 662 | wake_up_all(&dev->power.wait_queue); |
666 | 663 | ||
667 | if (!retval) | 664 | if (retval >= 0) |
668 | rpm_idle(dev, RPM_ASYNC); | 665 | rpm_idle(dev, RPM_ASYNC); |
669 | 666 | ||
670 | out: | 667 | out: |
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 11b32d2642df..a6e5672c67e7 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -272,6 +272,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | |||
272 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, | 272 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, |
273 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, | 273 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, |
274 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, | 274 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, |
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, | ||
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
276 | { 0, }, | 277 | { 0, }, |
277 | }; | 278 | }; |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 26823d97fd9f..9ea4627dc0c2 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -507,7 +507,9 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | |||
507 | /* for these chips OTP is always available */ | 507 | /* for these chips OTP is always available */ |
508 | present = true; | 508 | present = true; |
509 | break; | 509 | break; |
510 | 510 | case BCMA_CHIP_ID_BCM43228: | |
511 | present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT; | ||
512 | break; | ||
511 | default: | 513 | default: |
512 | present = false; | 514 | present = false; |
513 | break; | 515 | break; |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index de0435e63b02..887f68f6d79a 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -35,6 +35,7 @@ new_skb(ulong len) | |||
35 | skb_reset_mac_header(skb); | 35 | skb_reset_mac_header(skb); |
36 | skb_reset_network_header(skb); | 36 | skb_reset_network_header(skb); |
37 | skb->protocol = __constant_htons(ETH_P_AOE); | 37 | skb->protocol = __constant_htons(ETH_P_AOE); |
38 | skb_checksum_none_assert(skb); | ||
38 | } | 39 | } |
39 | return skb; | 40 | return skb; |
40 | } | 41 | } |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index acda773b3720..da3311129a0c 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -763,16 +763,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, | |||
763 | { | 763 | { |
764 | case CMD_TARGET_STATUS: | 764 | case CMD_TARGET_STATUS: |
765 | /* Pass it up to the upper layers... */ | 765 | /* Pass it up to the upper layers... */ |
766 | if( ei->ScsiStatus) | 766 | if (!ei->ScsiStatus) { |
767 | { | ||
768 | #if 0 | ||
769 | printk(KERN_WARNING "cciss: cmd %p " | ||
770 | "has SCSI Status = %x\n", | ||
771 | c, ei->ScsiStatus); | ||
772 | #endif | ||
773 | cmd->result |= (ei->ScsiStatus << 1); | ||
774 | } | ||
775 | else { /* scsi status is zero??? How??? */ | ||
776 | 767 | ||
777 | /* Ordinarily, this case should never happen, but there is a bug | 768 | /* Ordinarily, this case should never happen, but there is a bug |
778 | in some released firmware revisions that allows it to happen | 769 | in some released firmware revisions that allows it to happen |
@@ -804,6 +795,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, | |||
804 | } | 795 | } |
805 | break; | 796 | break; |
806 | case CMD_PROTOCOL_ERR: | 797 | case CMD_PROTOCOL_ERR: |
798 | cmd->result = DID_ERROR << 16; | ||
807 | dev_warn(&h->pdev->dev, | 799 | dev_warn(&h->pdev->dev, |
808 | "%p has protocol error\n", c); | 800 | "%p has protocol error\n", c); |
809 | break; | 801 | break; |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index ba91b408abad..d84566496746 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
@@ -889,6 +889,7 @@ struct bm_aio_ctx { | |||
889 | unsigned int done; | 889 | unsigned int done; |
890 | unsigned flags; | 890 | unsigned flags; |
891 | #define BM_AIO_COPY_PAGES 1 | 891 | #define BM_AIO_COPY_PAGES 1 |
892 | #define BM_WRITE_ALL_PAGES 2 | ||
892 | int error; | 893 | int error; |
893 | struct kref kref; | 894 | struct kref kref; |
894 | }; | 895 | }; |
@@ -1059,7 +1060,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned flags, unsigned lazy_w | |||
1059 | if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) | 1060 | if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx) |
1060 | break; | 1061 | break; |
1061 | if (rw & WRITE) { | 1062 | if (rw & WRITE) { |
1062 | if (bm_test_page_unchanged(b->bm_pages[i])) { | 1063 | if (!(flags & BM_WRITE_ALL_PAGES) && |
1064 | bm_test_page_unchanged(b->bm_pages[i])) { | ||
1063 | dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); | 1065 | dynamic_dev_dbg(DEV, "skipped bm write for idx %u\n", i); |
1064 | continue; | 1066 | continue; |
1065 | } | 1067 | } |
@@ -1141,6 +1143,17 @@ int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) | |||
1141 | } | 1143 | } |
1142 | 1144 | ||
1143 | /** | 1145 | /** |
1146 | * drbd_bm_write_all() - Write the whole bitmap to its on disk location. | ||
1147 | * @mdev: DRBD device. | ||
1148 | * | ||
1149 | * Will write all pages. | ||
1150 | */ | ||
1151 | int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local) | ||
1152 | { | ||
1153 | return bm_rw(mdev, WRITE, BM_WRITE_ALL_PAGES, 0); | ||
1154 | } | ||
1155 | |||
1156 | /** | ||
1144 | * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. | 1157 | * drbd_bm_lazy_write_out() - Write bitmap pages 0 to @upper_idx-1, if they have changed. |
1145 | * @mdev: DRBD device. | 1158 | * @mdev: DRBD device. |
1146 | * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages | 1159 | * @upper_idx: 0: write all changed pages; +ve: page index to stop scanning for changed pages |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index b2ca143d0053..b953cc7c9c00 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -1469,6 +1469,7 @@ extern int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr); | |||
1469 | extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); | 1469 | extern int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local); |
1470 | extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); | 1470 | extern int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local); |
1471 | extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); | 1471 | extern int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local); |
1472 | extern int drbd_bm_write_all(struct drbd_conf *mdev) __must_hold(local); | ||
1472 | extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local); | 1473 | extern int drbd_bm_write_copy_pages(struct drbd_conf *mdev) __must_hold(local); |
1473 | extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, | 1474 | extern unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, |
1474 | unsigned long al_enr); | 1475 | unsigned long al_enr); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 2e0e7fc1dbba..f93a0320e952 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -79,6 +79,7 @@ static int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused); | |||
79 | static void md_sync_timer_fn(unsigned long data); | 79 | static void md_sync_timer_fn(unsigned long data); |
80 | static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused); | 80 | static int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused); |
81 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); | 81 | static int w_go_diskless(struct drbd_conf *mdev, struct drbd_work *w, int unused); |
82 | static void _tl_clear(struct drbd_conf *mdev); | ||
82 | 83 | ||
83 | MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, " | 84 | MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, " |
84 | "Lars Ellenberg <lars@linbit.com>"); | 85 | "Lars Ellenberg <lars@linbit.com>"); |
@@ -432,19 +433,10 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | |||
432 | 433 | ||
433 | /* Actions operating on the disk state, also want to work on | 434 | /* Actions operating on the disk state, also want to work on |
434 | requests that got barrier acked. */ | 435 | requests that got barrier acked. */ |
435 | switch (what) { | ||
436 | case fail_frozen_disk_io: | ||
437 | case restart_frozen_disk_io: | ||
438 | list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { | ||
439 | req = list_entry(le, struct drbd_request, tl_requests); | ||
440 | _req_mod(req, what); | ||
441 | } | ||
442 | 436 | ||
443 | case connection_lost_while_pending: | 437 | list_for_each_safe(le, tle, &mdev->barrier_acked_requests) { |
444 | case resend: | 438 | req = list_entry(le, struct drbd_request, tl_requests); |
445 | break; | 439 | _req_mod(req, what); |
446 | default: | ||
447 | dev_err(DEV, "what = %d in _tl_restart()\n", what); | ||
448 | } | 440 | } |
449 | } | 441 | } |
450 | 442 | ||
@@ -459,11 +451,16 @@ static void _tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | |||
459 | */ | 451 | */ |
460 | void tl_clear(struct drbd_conf *mdev) | 452 | void tl_clear(struct drbd_conf *mdev) |
461 | { | 453 | { |
454 | spin_lock_irq(&mdev->req_lock); | ||
455 | _tl_clear(mdev); | ||
456 | spin_unlock_irq(&mdev->req_lock); | ||
457 | } | ||
458 | |||
459 | static void _tl_clear(struct drbd_conf *mdev) | ||
460 | { | ||
462 | struct list_head *le, *tle; | 461 | struct list_head *le, *tle; |
463 | struct drbd_request *r; | 462 | struct drbd_request *r; |
464 | 463 | ||
465 | spin_lock_irq(&mdev->req_lock); | ||
466 | |||
467 | _tl_restart(mdev, connection_lost_while_pending); | 464 | _tl_restart(mdev, connection_lost_while_pending); |
468 | 465 | ||
469 | /* we expect this list to be empty. */ | 466 | /* we expect this list to be empty. */ |
@@ -482,7 +479,6 @@ void tl_clear(struct drbd_conf *mdev) | |||
482 | 479 | ||
483 | memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); | 480 | memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); |
484 | 481 | ||
485 | spin_unlock_irq(&mdev->req_lock); | ||
486 | } | 482 | } |
487 | 483 | ||
488 | void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) | 484 | void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what) |
@@ -1476,12 +1472,12 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os, | |||
1476 | if (ns.susp_fen) { | 1472 | if (ns.susp_fen) { |
1477 | /* case1: The outdate peer handler is successful: */ | 1473 | /* case1: The outdate peer handler is successful: */ |
1478 | if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) { | 1474 | if (os.pdsk > D_OUTDATED && ns.pdsk <= D_OUTDATED) { |
1479 | tl_clear(mdev); | ||
1480 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { | 1475 | if (test_bit(NEW_CUR_UUID, &mdev->flags)) { |
1481 | drbd_uuid_new_current(mdev); | 1476 | drbd_uuid_new_current(mdev); |
1482 | clear_bit(NEW_CUR_UUID, &mdev->flags); | 1477 | clear_bit(NEW_CUR_UUID, &mdev->flags); |
1483 | } | 1478 | } |
1484 | spin_lock_irq(&mdev->req_lock); | 1479 | spin_lock_irq(&mdev->req_lock); |
1480 | _tl_clear(mdev); | ||
1485 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); | 1481 | _drbd_set_state(_NS(mdev, susp_fen, 0), CS_VERBOSE, NULL); |
1486 | spin_unlock_irq(&mdev->req_lock); | 1482 | spin_unlock_irq(&mdev->req_lock); |
1487 | } | 1483 | } |
@@ -3537,9 +3533,9 @@ static void drbd_cleanup(void) | |||
3537 | } | 3533 | } |
3538 | 3534 | ||
3539 | /** | 3535 | /** |
3540 | * drbd_congested() - Callback for pdflush | 3536 | * drbd_congested() - Callback for the flusher thread |
3541 | * @congested_data: User data | 3537 | * @congested_data: User data |
3542 | * @bdi_bits: Bits pdflush is currently interested in | 3538 | * @bdi_bits: Bits the BDI flusher thread is currently interested in |
3543 | * | 3539 | * |
3544 | * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested. | 3540 | * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested. |
3545 | */ | 3541 | */ |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fb9dce8daa24..edb490aad8b4 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -674,8 +674,8 @@ enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds | |||
674 | la_size_changed && md_moved ? "size changed and md moved" : | 674 | la_size_changed && md_moved ? "size changed and md moved" : |
675 | la_size_changed ? "size changed" : "md moved"); | 675 | la_size_changed ? "size changed" : "md moved"); |
676 | /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ | 676 | /* next line implicitly does drbd_suspend_io()+drbd_resume_io() */ |
677 | err = drbd_bitmap_io(mdev, &drbd_bm_write, | 677 | err = drbd_bitmap_io(mdev, md_moved ? &drbd_bm_write_all : &drbd_bm_write, |
678 | "size changed", BM_LOCKED_MASK); | 678 | "size changed", BM_LOCKED_MASK); |
679 | if (err) { | 679 | if (err) { |
680 | rv = dev_size_error; | 680 | rv = dev_size_error; |
681 | goto out; | 681 | goto out; |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 910335c30927..01b2ac641c7b 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
695 | break; | 695 | break; |
696 | 696 | ||
697 | case resend: | 697 | case resend: |
698 | /* Simply complete (local only) READs. */ | ||
699 | if (!(req->rq_state & RQ_WRITE) && !req->w.cb) { | ||
700 | _req_may_be_done(req, m); | ||
701 | break; | ||
702 | } | ||
703 | |||
698 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK | 704 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK |
699 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. | 705 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. |
700 | Trowing them out of the TL here by pretending we got a BARRIER_ACK | 706 | Trowing them out of the TL here by pretending we got a BARRIER_ACK |
@@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns | |||
834 | req->private_bio = NULL; | 840 | req->private_bio = NULL; |
835 | } | 841 | } |
836 | if (rw == WRITE) { | 842 | if (rw == WRITE) { |
837 | remote = 1; | 843 | /* Need to replicate writes. Unless it is an empty flush, |
844 | * which is better mapped to a DRBD P_BARRIER packet, | ||
845 | * also for drbd wire protocol compatibility reasons. */ | ||
846 | if (unlikely(size == 0)) { | ||
847 | /* The only size==0 bios we expect are empty flushes. */ | ||
848 | D_ASSERT(bio->bi_rw & REQ_FLUSH); | ||
849 | remote = 0; | ||
850 | } else | ||
851 | remote = 1; | ||
838 | } else { | 852 | } else { |
839 | /* READ || READA */ | 853 | /* READ || READA */ |
840 | if (local) { | 854 | if (local) { |
@@ -870,8 +884,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns | |||
870 | * extent. This waits for any resync activity in the corresponding | 884 | * extent. This waits for any resync activity in the corresponding |
871 | * resync extent to finish, and, if necessary, pulls in the target | 885 | * resync extent to finish, and, if necessary, pulls in the target |
872 | * extent into the activity log, which involves further disk io because | 886 | * extent into the activity log, which involves further disk io because |
873 | * of transactional on-disk meta data updates. */ | 887 | * of transactional on-disk meta data updates. |
874 | if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { | 888 | * Empty flushes don't need to go into the activity log, they can only |
889 | * flush data for pending writes which are already in there. */ | ||
890 | if (rw == WRITE && local && size | ||
891 | && !test_bit(AL_SUSPENDED, &mdev->flags)) { | ||
875 | req->rq_state |= RQ_IN_ACT_LOG; | 892 | req->rq_state |= RQ_IN_ACT_LOG; |
876 | drbd_al_begin_io(mdev, sector); | 893 | drbd_al_begin_io(mdev, sector); |
877 | } | 894 | } |
@@ -994,7 +1011,10 @@ allocate_barrier: | |||
994 | if (rw == WRITE && _req_conflicts(req)) | 1011 | if (rw == WRITE && _req_conflicts(req)) |
995 | goto fail_conflicting; | 1012 | goto fail_conflicting; |
996 | 1013 | ||
997 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | 1014 | /* no point in adding empty flushes to the transfer log, |
1015 | * they are mapped to drbd barriers already. */ | ||
1016 | if (likely(size!=0)) | ||
1017 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | ||
998 | 1018 | ||
999 | /* NOTE remote first: to get the concurrent write detection right, | 1019 | /* NOTE remote first: to get the concurrent write detection right, |
1000 | * we must register the request before start of local IO. */ | 1020 | * we must register the request before start of local IO. */ |
@@ -1014,6 +1034,14 @@ allocate_barrier: | |||
1014 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) | 1034 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) |
1015 | maybe_pull_ahead(mdev); | 1035 | maybe_pull_ahead(mdev); |
1016 | 1036 | ||
1037 | /* If this was a flush, queue a drbd barrier/start a new epoch. | ||
1038 | * Unless the current epoch was empty anyways, or we are not currently | ||
1039 | * replicating, in which case there is no point. */ | ||
1040 | if (unlikely(bio->bi_rw & REQ_FLUSH) | ||
1041 | && mdev->newest_tle->n_writes | ||
1042 | && drbd_should_do_remote(mdev->state)) | ||
1043 | queue_barrier(mdev); | ||
1044 | |||
1017 | spin_unlock_irq(&mdev->req_lock); | 1045 | spin_unlock_irq(&mdev->req_lock); |
1018 | kfree(b); /* if someone else has beaten us to it... */ | 1046 | kfree(b); /* if someone else has beaten us to it... */ |
1019 | 1047 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index a8fddeb3d638..f946d31d6917 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -1148,11 +1148,15 @@ static bool mtip_pause_ncq(struct mtip_port *port, | |||
1148 | reply = port->rxfis + RX_FIS_D2H_REG; | 1148 | reply = port->rxfis + RX_FIS_D2H_REG; |
1149 | task_file_data = readl(port->mmio+PORT_TFDATA); | 1149 | task_file_data = readl(port->mmio+PORT_TFDATA); |
1150 | 1150 | ||
1151 | if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT)) | 1151 | if (fis->command == ATA_CMD_SEC_ERASE_UNIT) |
1152 | clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); | ||
1153 | |||
1154 | if ((task_file_data & 1)) | ||
1152 | return false; | 1155 | return false; |
1153 | 1156 | ||
1154 | if (fis->command == ATA_CMD_SEC_ERASE_PREP) { | 1157 | if (fis->command == ATA_CMD_SEC_ERASE_PREP) { |
1155 | set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); | 1158 | set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); |
1159 | set_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); | ||
1156 | port->ic_pause_timer = jiffies; | 1160 | port->ic_pause_timer = jiffies; |
1157 | return true; | 1161 | return true; |
1158 | } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && | 1162 | } else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) && |
@@ -1900,7 +1904,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command, | |||
1900 | int rv = 0, xfer_sz = command[3]; | 1904 | int rv = 0, xfer_sz = command[3]; |
1901 | 1905 | ||
1902 | if (xfer_sz) { | 1906 | if (xfer_sz) { |
1903 | if (user_buffer) | 1907 | if (!user_buffer) |
1904 | return -EFAULT; | 1908 | return -EFAULT; |
1905 | 1909 | ||
1906 | buf = dmam_alloc_coherent(&port->dd->pdev->dev, | 1910 | buf = dmam_alloc_coherent(&port->dd->pdev->dev, |
@@ -2043,7 +2047,7 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) | |||
2043 | *timeout = 240000; /* 4 minutes */ | 2047 | *timeout = 240000; /* 4 minutes */ |
2044 | break; | 2048 | break; |
2045 | case ATA_CMD_STANDBYNOW1: | 2049 | case ATA_CMD_STANDBYNOW1: |
2046 | *timeout = 10000; /* 10 seconds */ | 2050 | *timeout = 120000; /* 2 minutes */ |
2047 | break; | 2051 | break; |
2048 | case 0xF7: | 2052 | case 0xF7: |
2049 | case 0xFA: | 2053 | case 0xFA: |
@@ -2588,9 +2592,6 @@ static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, | |||
2588 | if (!len || size) | 2592 | if (!len || size) |
2589 | return 0; | 2593 | return 0; |
2590 | 2594 | ||
2591 | if (size < 0) | ||
2592 | return -EINVAL; | ||
2593 | |||
2594 | size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); | 2595 | size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); |
2595 | 2596 | ||
2596 | for (n = dd->slot_groups-1; n >= 0; n--) | 2597 | for (n = dd->slot_groups-1; n >= 0; n--) |
@@ -2660,9 +2661,6 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, | |||
2660 | if (!len || size) | 2661 | if (!len || size) |
2661 | return 0; | 2662 | return 0; |
2662 | 2663 | ||
2663 | if (size < 0) | ||
2664 | return -EINVAL; | ||
2665 | |||
2666 | size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", | 2664 | size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", |
2667 | dd->port->flags); | 2665 | dd->port->flags); |
2668 | size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", | 2666 | size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", |
@@ -3214,8 +3212,8 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3214 | "Unable to check write protect progress\n"); | 3212 | "Unable to check write protect progress\n"); |
3215 | else | 3213 | else |
3216 | dev_info(&dd->pdev->dev, | 3214 | dev_info(&dd->pdev->dev, |
3217 | "Write protect progress: %d%% (%d blocks)\n", | 3215 | "Write protect progress: %u%% (%u blocks)\n", |
3218 | attr242.cur, attr242.data); | 3216 | attr242.cur, le32_to_cpu(attr242.data)); |
3219 | return rv; | 3217 | return rv; |
3220 | 3218 | ||
3221 | out3: | 3219 | out3: |
@@ -3619,6 +3617,10 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3619 | bio_endio(bio, -ENODATA); | 3617 | bio_endio(bio, -ENODATA); |
3620 | return; | 3618 | return; |
3621 | } | 3619 | } |
3620 | if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) { | ||
3621 | bio_endio(bio, -ENODATA); | ||
3622 | return; | ||
3623 | } | ||
3622 | } | 3624 | } |
3623 | 3625 | ||
3624 | if (unlikely(!bio_has_data(bio))) { | 3626 | if (unlikely(!bio_has_data(bio))) { |
@@ -4168,7 +4170,13 @@ static void mtip_pci_shutdown(struct pci_dev *pdev) | |||
4168 | 4170 | ||
4169 | /* Table of device ids supported by this driver. */ | 4171 | /* Table of device ids supported by this driver. */ |
4170 | static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = { | 4172 | static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = { |
4171 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) }, | 4173 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320H_DEVICE_ID) }, |
4174 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320M_DEVICE_ID) }, | ||
4175 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320S_DEVICE_ID) }, | ||
4176 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P325M_DEVICE_ID) }, | ||
4177 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420H_DEVICE_ID) }, | ||
4178 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P420M_DEVICE_ID) }, | ||
4179 | { PCI_DEVICE(PCI_VENDOR_ID_MICRON, P425M_DEVICE_ID) }, | ||
4172 | { 0 } | 4180 | { 0 } |
4173 | }; | 4181 | }; |
4174 | 4182 | ||
@@ -4199,12 +4207,12 @@ static int __init mtip_init(void) | |||
4199 | { | 4207 | { |
4200 | int error; | 4208 | int error; |
4201 | 4209 | ||
4202 | printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); | 4210 | pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); |
4203 | 4211 | ||
4204 | /* Allocate a major block device number to use with this driver. */ | 4212 | /* Allocate a major block device number to use with this driver. */ |
4205 | error = register_blkdev(0, MTIP_DRV_NAME); | 4213 | error = register_blkdev(0, MTIP_DRV_NAME); |
4206 | if (error <= 0) { | 4214 | if (error <= 0) { |
4207 | printk(KERN_ERR "Unable to register block device (%d)\n", | 4215 | pr_err("Unable to register block device (%d)\n", |
4208 | error); | 4216 | error); |
4209 | return -EBUSY; | 4217 | return -EBUSY; |
4210 | } | 4218 | } |
@@ -4213,7 +4221,7 @@ static int __init mtip_init(void) | |||
4213 | if (!dfs_parent) { | 4221 | if (!dfs_parent) { |
4214 | dfs_parent = debugfs_create_dir("rssd", NULL); | 4222 | dfs_parent = debugfs_create_dir("rssd", NULL); |
4215 | if (IS_ERR_OR_NULL(dfs_parent)) { | 4223 | if (IS_ERR_OR_NULL(dfs_parent)) { |
4216 | printk(KERN_WARNING "Error creating debugfs parent\n"); | 4224 | pr_warn("Error creating debugfs parent\n"); |
4217 | dfs_parent = NULL; | 4225 | dfs_parent = NULL; |
4218 | } | 4226 | } |
4219 | } | 4227 | } |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index f51fc23d17bb..18627a1d04c5 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -76,7 +76,13 @@ | |||
76 | 76 | ||
77 | /* Micron Vendor ID & P320x SSD Device ID */ | 77 | /* Micron Vendor ID & P320x SSD Device ID */ |
78 | #define PCI_VENDOR_ID_MICRON 0x1344 | 78 | #define PCI_VENDOR_ID_MICRON 0x1344 |
79 | #define P320_DEVICE_ID 0x5150 | 79 | #define P320H_DEVICE_ID 0x5150 |
80 | #define P320M_DEVICE_ID 0x5151 | ||
81 | #define P320S_DEVICE_ID 0x5152 | ||
82 | #define P325M_DEVICE_ID 0x5153 | ||
83 | #define P420H_DEVICE_ID 0x5160 | ||
84 | #define P420M_DEVICE_ID 0x5161 | ||
85 | #define P425M_DEVICE_ID 0x5163 | ||
80 | 86 | ||
81 | /* Driver name and version strings */ | 87 | /* Driver name and version strings */ |
82 | #define MTIP_DRV_NAME "mtip32xx" | 88 | #define MTIP_DRV_NAME "mtip32xx" |
@@ -131,10 +137,12 @@ enum { | |||
131 | MTIP_PF_SVC_THD_STOP_BIT = 8, | 137 | MTIP_PF_SVC_THD_STOP_BIT = 8, |
132 | 138 | ||
133 | /* below are bit numbers in 'dd_flag' defined in driver_data */ | 139 | /* below are bit numbers in 'dd_flag' defined in driver_data */ |
140 | MTIP_DDF_SEC_LOCK_BIT = 0, | ||
134 | MTIP_DDF_REMOVE_PENDING_BIT = 1, | 141 | MTIP_DDF_REMOVE_PENDING_BIT = 1, |
135 | MTIP_DDF_OVER_TEMP_BIT = 2, | 142 | MTIP_DDF_OVER_TEMP_BIT = 2, |
136 | MTIP_DDF_WRITE_PROTECT_BIT = 3, | 143 | MTIP_DDF_WRITE_PROTECT_BIT = 3, |
137 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ | 144 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ |
145 | (1 << MTIP_DDF_SEC_LOCK_BIT) | \ | ||
138 | (1 << MTIP_DDF_OVER_TEMP_BIT) | \ | 146 | (1 << MTIP_DDF_OVER_TEMP_BIT) | \ |
139 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), | 147 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), |
140 | 148 | ||
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index d07c9f7fded6..0c03411c59eb 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -449,6 +449,14 @@ static void nbd_clear_que(struct nbd_device *nbd) | |||
449 | req->errors++; | 449 | req->errors++; |
450 | nbd_end_request(req); | 450 | nbd_end_request(req); |
451 | } | 451 | } |
452 | |||
453 | while (!list_empty(&nbd->waiting_queue)) { | ||
454 | req = list_entry(nbd->waiting_queue.next, struct request, | ||
455 | queuelist); | ||
456 | list_del_init(&req->queuelist); | ||
457 | req->errors++; | ||
458 | nbd_end_request(req); | ||
459 | } | ||
452 | } | 460 | } |
453 | 461 | ||
454 | 462 | ||
@@ -598,6 +606,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, | |||
598 | nbd->file = NULL; | 606 | nbd->file = NULL; |
599 | nbd_clear_que(nbd); | 607 | nbd_clear_que(nbd); |
600 | BUG_ON(!list_empty(&nbd->queue_head)); | 608 | BUG_ON(!list_empty(&nbd->queue_head)); |
609 | BUG_ON(!list_empty(&nbd->waiting_queue)); | ||
601 | if (file) | 610 | if (file) |
602 | fput(file); | 611 | fput(file); |
603 | return 0; | 612 | return 0; |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 9917943a3572..54a55f03115d 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -246,13 +246,12 @@ static int rbd_open(struct block_device *bdev, fmode_t mode) | |||
246 | { | 246 | { |
247 | struct rbd_device *rbd_dev = bdev->bd_disk->private_data; | 247 | struct rbd_device *rbd_dev = bdev->bd_disk->private_data; |
248 | 248 | ||
249 | rbd_get_dev(rbd_dev); | ||
250 | |||
251 | set_device_ro(bdev, rbd_dev->read_only); | ||
252 | |||
253 | if ((mode & FMODE_WRITE) && rbd_dev->read_only) | 249 | if ((mode & FMODE_WRITE) && rbd_dev->read_only) |
254 | return -EROFS; | 250 | return -EROFS; |
255 | 251 | ||
252 | rbd_get_dev(rbd_dev); | ||
253 | set_device_ro(bdev, rbd_dev->read_only); | ||
254 | |||
256 | return 0; | 255 | return 0; |
257 | } | 256 | } |
258 | 257 | ||
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 73f196ca713f..c6decb901e5e 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pending_req *req) | |||
337 | invcount++; | 337 | invcount++; |
338 | } | 338 | } |
339 | 339 | ||
340 | ret = gnttab_unmap_refs(unmap, pages, invcount, false); | 340 | ret = gnttab_unmap_refs(unmap, NULL, pages, invcount); |
341 | BUG_ON(ret); | 341 | BUG_ON(ret); |
342 | } | 342 | } |
343 | 343 | ||
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 10308cd8a7ed..fc2de5528dcc 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -79,12 +79,14 @@ static struct usb_device_id ath3k_table[] = { | |||
79 | { USB_DEVICE(0x13d3, 0x3362) }, | 79 | { USB_DEVICE(0x13d3, 0x3362) }, |
80 | { USB_DEVICE(0x0CF3, 0xE004) }, | 80 | { USB_DEVICE(0x0CF3, 0xE004) }, |
81 | { USB_DEVICE(0x0930, 0x0219) }, | 81 | { USB_DEVICE(0x0930, 0x0219) }, |
82 | { USB_DEVICE(0x0489, 0xe057) }, | ||
82 | 83 | ||
83 | /* Atheros AR5BBU12 with sflash firmware */ | 84 | /* Atheros AR5BBU12 with sflash firmware */ |
84 | { USB_DEVICE(0x0489, 0xE02C) }, | 85 | { USB_DEVICE(0x0489, 0xE02C) }, |
85 | 86 | ||
86 | /* Atheros AR5BBU22 with sflash firmware */ | 87 | /* Atheros AR5BBU22 with sflash firmware */ |
87 | { USB_DEVICE(0x0489, 0xE03C) }, | 88 | { USB_DEVICE(0x0489, 0xE03C) }, |
89 | { USB_DEVICE(0x0489, 0xE036) }, | ||
88 | 90 | ||
89 | { } /* Terminating entry */ | 91 | { } /* Terminating entry */ |
90 | }; | 92 | }; |
@@ -104,9 +106,11 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
104 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 106 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
105 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 107 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
106 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 108 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
109 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | ||
107 | 110 | ||
108 | /* Atheros AR5BBU22 with sflash firmware */ | 111 | /* Atheros AR5BBU22 with sflash firmware */ |
109 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 112 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
113 | { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, | ||
110 | 114 | ||
111 | { } /* Terminating entry */ | 115 | { } /* Terminating entry */ |
112 | }; | 116 | }; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index e27221411036..654e248763ef 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = { | |||
52 | /* Generic Bluetooth USB device */ | 52 | /* Generic Bluetooth USB device */ |
53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
54 | 54 | ||
55 | /* Apple-specific (Broadcom) devices */ | ||
56 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, | ||
57 | |||
55 | /* Broadcom SoftSailing reporting vendor specific */ | 58 | /* Broadcom SoftSailing reporting vendor specific */ |
56 | { USB_DEVICE(0x0a5c, 0x21e1) }, | 59 | { USB_DEVICE(0x0a5c, 0x21e1) }, |
57 | 60 | ||
@@ -94,15 +97,14 @@ static struct usb_device_id btusb_table[] = { | |||
94 | 97 | ||
95 | /* Broadcom BCM20702A0 */ | 98 | /* Broadcom BCM20702A0 */ |
96 | { USB_DEVICE(0x0489, 0xe042) }, | 99 | { USB_DEVICE(0x0489, 0xe042) }, |
97 | { USB_DEVICE(0x0a5c, 0x21e3) }, | ||
98 | { USB_DEVICE(0x0a5c, 0x21e6) }, | ||
99 | { USB_DEVICE(0x0a5c, 0x21e8) }, | ||
100 | { USB_DEVICE(0x0a5c, 0x21f3) }, | ||
101 | { USB_DEVICE(0x413c, 0x8197) }, | 100 | { USB_DEVICE(0x413c, 0x8197) }, |
102 | 101 | ||
103 | /* Foxconn - Hon Hai */ | 102 | /* Foxconn - Hon Hai */ |
104 | { USB_DEVICE(0x0489, 0xe033) }, | 103 | { USB_DEVICE(0x0489, 0xe033) }, |
105 | 104 | ||
105 | /*Broadcom devices with vendor specific id */ | ||
106 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, | ||
107 | |||
106 | { } /* Terminating entry */ | 108 | { } /* Terminating entry */ |
107 | }; | 109 | }; |
108 | 110 | ||
@@ -133,12 +135,14 @@ static struct usb_device_id blacklist_table[] = { | |||
133 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 135 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
134 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 136 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
135 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 137 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
138 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | ||
136 | 139 | ||
137 | /* Atheros AR5BBU12 with sflash firmware */ | 140 | /* Atheros AR5BBU12 with sflash firmware */ |
138 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 141 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
139 | 142 | ||
140 | /* Atheros AR5BBU12 with sflash firmware */ | 143 | /* Atheros AR5BBU12 with sflash firmware */ |
141 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 144 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
145 | { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, | ||
142 | 146 | ||
143 | /* Broadcom BCM2035 */ | 147 | /* Broadcom BCM2035 */ |
144 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 148 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 57226424690c..6ec0fff79bc2 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -64,6 +64,7 @@ | |||
64 | #define I830_PTE_SYSTEM_CACHED 0x00000006 | 64 | #define I830_PTE_SYSTEM_CACHED 0x00000006 |
65 | /* GT PTE cache control fields */ | 65 | /* GT PTE cache control fields */ |
66 | #define GEN6_PTE_UNCACHED 0x00000002 | 66 | #define GEN6_PTE_UNCACHED 0x00000002 |
67 | #define HSW_PTE_UNCACHED 0x00000000 | ||
67 | #define GEN6_PTE_LLC 0x00000004 | 68 | #define GEN6_PTE_LLC 0x00000004 |
68 | #define GEN6_PTE_LLC_MLC 0x00000006 | 69 | #define GEN6_PTE_LLC_MLC 0x00000006 |
69 | #define GEN6_PTE_GFDT 0x00000008 | 70 | #define GEN6_PTE_GFDT 0x00000008 |
@@ -239,16 +240,45 @@ | |||
239 | #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A | 240 | #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A |
240 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB 0x0F00 /* VLV1 */ | 241 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB 0x0F00 /* VLV1 */ |
241 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG 0x0F30 | 242 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG 0x0F30 |
242 | #define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ | 243 | #define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ |
243 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG 0x0402 | 244 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG 0x0402 |
244 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG 0x0412 | 245 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG 0x0412 |
245 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ | 246 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG 0x0422 |
247 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ | ||
246 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG 0x0406 | 248 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG 0x0406 |
247 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG 0x0416 | 249 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG 0x0416 |
248 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ | 250 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG 0x0426 |
251 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ | ||
249 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG 0x040a | 252 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG 0x040a |
250 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG 0x041a | 253 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG 0x041a |
251 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */ | 254 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG 0x042a |
252 | #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 | 255 | #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 |
256 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG 0x0C02 | ||
257 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG 0x0C12 | ||
258 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG 0x0C22 | ||
259 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG 0x0C06 | ||
260 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG 0x0C16 | ||
261 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG 0x0C26 | ||
262 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG 0x0C0A | ||
263 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG 0x0C1A | ||
264 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG 0x0C2A | ||
265 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG 0x0A02 | ||
266 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG 0x0A12 | ||
267 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG 0x0A22 | ||
268 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG 0x0A06 | ||
269 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG 0x0A16 | ||
270 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG 0x0A26 | ||
271 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG 0x0A0A | ||
272 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG 0x0A1A | ||
273 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG 0x0A2A | ||
274 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG 0x0D12 | ||
275 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG 0x0D22 | ||
276 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG 0x0D32 | ||
277 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG 0x0D16 | ||
278 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG 0x0D26 | ||
279 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG 0x0D36 | ||
280 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG 0x0D1A | ||
281 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG 0x0D2A | ||
282 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG 0x0D3A | ||
253 | 283 | ||
254 | #endif | 284 | #endif |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9ed92ef5829b..58e32f7c3229 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -1156,6 +1156,30 @@ static bool gen6_check_flags(unsigned int flags) | |||
1156 | return true; | 1156 | return true; |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | static void haswell_write_entry(dma_addr_t addr, unsigned int entry, | ||
1160 | unsigned int flags) | ||
1161 | { | ||
1162 | unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; | ||
1163 | unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; | ||
1164 | u32 pte_flags; | ||
1165 | |||
1166 | if (type_mask == AGP_USER_MEMORY) | ||
1167 | pte_flags = HSW_PTE_UNCACHED | I810_PTE_VALID; | ||
1168 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { | ||
1169 | pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; | ||
1170 | if (gfdt) | ||
1171 | pte_flags |= GEN6_PTE_GFDT; | ||
1172 | } else { /* set 'normal'/'cached' to LLC by default */ | ||
1173 | pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; | ||
1174 | if (gfdt) | ||
1175 | pte_flags |= GEN6_PTE_GFDT; | ||
1176 | } | ||
1177 | |||
1178 | /* gen6 has bit11-4 for physical addr bit39-32 */ | ||
1179 | addr |= (addr >> 28) & 0xff0; | ||
1180 | writel(addr | pte_flags, intel_private.gtt + entry); | ||
1181 | } | ||
1182 | |||
1159 | static void gen6_write_entry(dma_addr_t addr, unsigned int entry, | 1183 | static void gen6_write_entry(dma_addr_t addr, unsigned int entry, |
1160 | unsigned int flags) | 1184 | unsigned int flags) |
1161 | { | 1185 | { |
@@ -1382,6 +1406,15 @@ static const struct intel_gtt_driver sandybridge_gtt_driver = { | |||
1382 | .check_flags = gen6_check_flags, | 1406 | .check_flags = gen6_check_flags, |
1383 | .chipset_flush = i9xx_chipset_flush, | 1407 | .chipset_flush = i9xx_chipset_flush, |
1384 | }; | 1408 | }; |
1409 | static const struct intel_gtt_driver haswell_gtt_driver = { | ||
1410 | .gen = 6, | ||
1411 | .setup = i9xx_setup, | ||
1412 | .cleanup = gen6_cleanup, | ||
1413 | .write_entry = haswell_write_entry, | ||
1414 | .dma_mask_size = 40, | ||
1415 | .check_flags = gen6_check_flags, | ||
1416 | .chipset_flush = i9xx_chipset_flush, | ||
1417 | }; | ||
1385 | static const struct intel_gtt_driver valleyview_gtt_driver = { | 1418 | static const struct intel_gtt_driver valleyview_gtt_driver = { |
1386 | .gen = 7, | 1419 | .gen = 7, |
1387 | .setup = i9xx_setup, | 1420 | .setup = i9xx_setup, |
@@ -1499,19 +1532,77 @@ static const struct intel_gtt_driver_description { | |||
1499 | { PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG, | 1532 | { PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG, |
1500 | "ValleyView", &valleyview_gtt_driver }, | 1533 | "ValleyView", &valleyview_gtt_driver }, |
1501 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG, | 1534 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG, |
1502 | "Haswell", &sandybridge_gtt_driver }, | 1535 | "Haswell", &haswell_gtt_driver }, |
1503 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, | 1536 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, |
1504 | "Haswell", &sandybridge_gtt_driver }, | 1537 | "Haswell", &haswell_gtt_driver }, |
1538 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, | ||
1539 | "Haswell", &haswell_gtt_driver }, | ||
1505 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, | 1540 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, |
1506 | "Haswell", &sandybridge_gtt_driver }, | 1541 | "Haswell", &haswell_gtt_driver }, |
1507 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, | 1542 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, |
1508 | "Haswell", &sandybridge_gtt_driver }, | 1543 | "Haswell", &haswell_gtt_driver }, |
1544 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, | ||
1545 | "Haswell", &haswell_gtt_driver }, | ||
1509 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, | 1546 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, |
1510 | "Haswell", &sandybridge_gtt_driver }, | 1547 | "Haswell", &haswell_gtt_driver }, |
1511 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, | 1548 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, |
1512 | "Haswell", &sandybridge_gtt_driver }, | 1549 | "Haswell", &haswell_gtt_driver }, |
1513 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV, | 1550 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, |
1514 | "Haswell", &sandybridge_gtt_driver }, | 1551 | "Haswell", &haswell_gtt_driver }, |
1552 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, | ||
1553 | "Haswell", &haswell_gtt_driver }, | ||
1554 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, | ||
1555 | "Haswell", &haswell_gtt_driver }, | ||
1556 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, | ||
1557 | "Haswell", &haswell_gtt_driver }, | ||
1558 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, | ||
1559 | "Haswell", &haswell_gtt_driver }, | ||
1560 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, | ||
1561 | "Haswell", &haswell_gtt_driver }, | ||
1562 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, | ||
1563 | "Haswell", &haswell_gtt_driver }, | ||
1564 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, | ||
1565 | "Haswell", &haswell_gtt_driver }, | ||
1566 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, | ||
1567 | "Haswell", &haswell_gtt_driver }, | ||
1568 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, | ||
1569 | "Haswell", &haswell_gtt_driver }, | ||
1570 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, | ||
1571 | "Haswell", &haswell_gtt_driver }, | ||
1572 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, | ||
1573 | "Haswell", &haswell_gtt_driver }, | ||
1574 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, | ||
1575 | "Haswell", &haswell_gtt_driver }, | ||
1576 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, | ||
1577 | "Haswell", &haswell_gtt_driver }, | ||
1578 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, | ||
1579 | "Haswell", &haswell_gtt_driver }, | ||
1580 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, | ||
1581 | "Haswell", &haswell_gtt_driver }, | ||
1582 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, | ||
1583 | "Haswell", &haswell_gtt_driver }, | ||
1584 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, | ||
1585 | "Haswell", &haswell_gtt_driver }, | ||
1586 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, | ||
1587 | "Haswell", &haswell_gtt_driver }, | ||
1588 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, | ||
1589 | "Haswell", &haswell_gtt_driver }, | ||
1590 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, | ||
1591 | "Haswell", &haswell_gtt_driver }, | ||
1592 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, | ||
1593 | "Haswell", &haswell_gtt_driver }, | ||
1594 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, | ||
1595 | "Haswell", &haswell_gtt_driver }, | ||
1596 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, | ||
1597 | "Haswell", &haswell_gtt_driver }, | ||
1598 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, | ||
1599 | "Haswell", &haswell_gtt_driver }, | ||
1600 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, | ||
1601 | "Haswell", &haswell_gtt_driver }, | ||
1602 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, | ||
1603 | "Haswell", &haswell_gtt_driver }, | ||
1604 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, | ||
1605 | "Haswell", &haswell_gtt_driver }, | ||
1515 | { 0, NULL, NULL } | 1606 | { 0, NULL, NULL } |
1516 | }; | 1607 | }; |
1517 | 1608 | ||
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index d706bd0e9e80..4fbdceb6f773 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -160,7 +160,7 @@ static int __exit omap_rng_remove(struct platform_device *pdev) | |||
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
162 | 162 | ||
163 | #ifdef CONFIG_PM | 163 | #ifdef CONFIG_PM_SLEEP |
164 | 164 | ||
165 | static int omap_rng_suspend(struct device *dev) | 165 | static int omap_rng_suspend(struct device *dev) |
166 | { | 166 | { |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 89682fa8801e..c4be3519a587 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -807,6 +807,7 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | |||
807 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 807 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
808 | #endif | 808 | #endif |
809 | 809 | ||
810 | #ifdef CONFIG_PM_SLEEP | ||
810 | static int tpm_tis_resume(struct device *dev) | 811 | static int tpm_tis_resume(struct device *dev) |
811 | { | 812 | { |
812 | struct tpm_chip *chip = dev_get_drvdata(dev); | 813 | struct tpm_chip *chip = dev_get_drvdata(dev); |
@@ -816,6 +817,7 @@ static int tpm_tis_resume(struct device *dev) | |||
816 | 817 | ||
817 | return tpm_pm_resume(dev); | 818 | return tpm_pm_resume(dev); |
818 | } | 819 | } |
820 | #endif | ||
819 | 821 | ||
820 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); | 822 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); |
821 | 823 | ||
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea387054..72ce247a0e8d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -1,4 +1,5 @@ | |||
1 | # common clock types | 1 | # common clock types |
2 | obj-$(CONFIG_HAVE_CLK) += clk-devres.o | ||
2 | obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o | 3 | obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o |
3 | obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ | 4 | obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ |
4 | clk-mux.o clk-divider.o clk-fixed-factor.o | 5 | clk-mux.o clk-divider.o clk-fixed-factor.o |
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c new file mode 100644 index 000000000000..8f571548870f --- /dev/null +++ b/drivers/clk/clk-devres.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | */ | ||
6 | |||
7 | #include <linux/clk.h> | ||
8 | #include <linux/device.h> | ||
9 | #include <linux/export.h> | ||
10 | #include <linux/gfp.h> | ||
11 | |||
12 | static void devm_clk_release(struct device *dev, void *res) | ||
13 | { | ||
14 | clk_put(*(struct clk **)res); | ||
15 | } | ||
16 | |||
17 | struct clk *devm_clk_get(struct device *dev, const char *id) | ||
18 | { | ||
19 | struct clk **ptr, *clk; | ||
20 | |||
21 | ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); | ||
22 | if (!ptr) | ||
23 | return ERR_PTR(-ENOMEM); | ||
24 | |||
25 | clk = clk_get(dev, id); | ||
26 | if (!IS_ERR(clk)) { | ||
27 | *ptr = clk; | ||
28 | devres_add(dev, ptr); | ||
29 | } else { | ||
30 | devres_free(ptr); | ||
31 | } | ||
32 | |||
33 | return clk; | ||
34 | } | ||
35 | EXPORT_SYMBOL(devm_clk_get); | ||
36 | |||
37 | static int devm_clk_match(struct device *dev, void *res, void *data) | ||
38 | { | ||
39 | struct clk **c = res; | ||
40 | if (!c || !*c) { | ||
41 | WARN_ON(!c || !*c); | ||
42 | return 0; | ||
43 | } | ||
44 | return *c == data; | ||
45 | } | ||
46 | |||
47 | void devm_clk_put(struct device *dev, struct clk *clk) | ||
48 | { | ||
49 | int ret; | ||
50 | |||
51 | ret = devres_release(dev, devm_clk_release, devm_clk_match, clk); | ||
52 | |||
53 | WARN_ON(ret); | ||
54 | } | ||
55 | EXPORT_SYMBOL(devm_clk_put); | ||
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index d423c9bdd71a..442a31363873 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -171,51 +171,6 @@ void clk_put(struct clk *clk) | |||
171 | } | 171 | } |
172 | EXPORT_SYMBOL(clk_put); | 172 | EXPORT_SYMBOL(clk_put); |
173 | 173 | ||
174 | static void devm_clk_release(struct device *dev, void *res) | ||
175 | { | ||
176 | clk_put(*(struct clk **)res); | ||
177 | } | ||
178 | |||
179 | struct clk *devm_clk_get(struct device *dev, const char *id) | ||
180 | { | ||
181 | struct clk **ptr, *clk; | ||
182 | |||
183 | ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); | ||
184 | if (!ptr) | ||
185 | return ERR_PTR(-ENOMEM); | ||
186 | |||
187 | clk = clk_get(dev, id); | ||
188 | if (!IS_ERR(clk)) { | ||
189 | *ptr = clk; | ||
190 | devres_add(dev, ptr); | ||
191 | } else { | ||
192 | devres_free(ptr); | ||
193 | } | ||
194 | |||
195 | return clk; | ||
196 | } | ||
197 | EXPORT_SYMBOL(devm_clk_get); | ||
198 | |||
199 | static int devm_clk_match(struct device *dev, void *res, void *data) | ||
200 | { | ||
201 | struct clk **c = res; | ||
202 | if (!c || !*c) { | ||
203 | WARN_ON(!c || !*c); | ||
204 | return 0; | ||
205 | } | ||
206 | return *c == data; | ||
207 | } | ||
208 | |||
209 | void devm_clk_put(struct device *dev, struct clk *clk) | ||
210 | { | ||
211 | int ret; | ||
212 | |||
213 | ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk); | ||
214 | |||
215 | WARN_ON(ret); | ||
216 | } | ||
217 | EXPORT_SYMBOL(devm_clk_put); | ||
218 | |||
219 | void clkdev_add(struct clk_lookup *cl) | 174 | void clkdev_add(struct clk_lookup *cl) |
220 | { | 175 | { |
221 | mutex_lock(&clocks_mutex); | 176 | mutex_lock(&clocks_mutex); |
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index 540795cd0760..d9279385304d 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c | |||
@@ -53,7 +53,7 @@ static struct cs5535_mfgpt_timer *cs5535_event_clock; | |||
53 | #define MFGPT_PERIODIC (MFGPT_HZ / HZ) | 53 | #define MFGPT_PERIODIC (MFGPT_HZ / HZ) |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * The MFPGT timers on the CS5536 provide us with suitable timers to use | 56 | * The MFGPT timers on the CS5536 provide us with suitable timers to use |
57 | * as clock event sources - not as good as a HPET or APIC, but certainly | 57 | * as clock event sources - not as good as a HPET or APIC, but certainly |
58 | * better than the PIT. This isn't a general purpose MFGPT driver, but | 58 | * better than the PIT. This isn't a general purpose MFGPT driver, but |
59 | * a simplified one designed specifically to act as a clock event source. | 59 | * a simplified one designed specifically to act as a clock event source. |
@@ -144,7 +144,7 @@ static int __init cs5535_mfgpt_init(void) | |||
144 | 144 | ||
145 | timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); | 145 | timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); |
146 | if (!timer) { | 146 | if (!timer) { |
147 | printk(KERN_ERR DRV_NAME ": Could not allocate MFPGT timer\n"); | 147 | printk(KERN_ERR DRV_NAME ": Could not allocate MFGPT timer\n"); |
148 | return -ENODEV; | 148 | return -ENODEV; |
149 | } | 149 | } |
150 | cs5535_event_clock = timer; | 150 | cs5535_event_clock = timer; |
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 17fa04d08be9..b47034e650a5 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
@@ -218,7 +218,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | |||
218 | 218 | ||
219 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); | 219 | policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); |
220 | 220 | ||
221 | if (atomic_inc_return(&freq_table_users) == 1) | 221 | if (!freq_table) |
222 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); | 222 | result = opp_init_cpufreq_table(mpu_dev, &freq_table); |
223 | 223 | ||
224 | if (result) { | 224 | if (result) { |
@@ -227,6 +227,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) | |||
227 | goto fail_ck; | 227 | goto fail_ck; |
228 | } | 228 | } |
229 | 229 | ||
230 | atomic_inc_return(&freq_table_users); | ||
231 | |||
230 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | 232 | result = cpufreq_frequency_table_cpuinfo(policy, freq_table); |
231 | if (result) | 233 | if (result) |
232 | goto fail_table; | 234 | goto fail_table; |
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index cdc02ac8f41a..503996a94a6a 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -454,6 +454,7 @@ static int __init pcc_cpufreq_probe(void) | |||
454 | mem_resource->address_length); | 454 | mem_resource->address_length); |
455 | if (pcch_virt_addr == NULL) { | 455 | if (pcch_virt_addr == NULL) { |
456 | pr_debug("probe: could not map shared mem region\n"); | 456 | pr_debug("probe: could not map shared mem region\n"); |
457 | ret = -ENOMEM; | ||
457 | goto out_free; | 458 | goto out_free; |
458 | } | 459 | } |
459 | pcch_hdr = pcch_virt_addr; | 460 | pcch_hdr = pcch_virt_addr; |
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index c0e816468e30..1a40935c85fd 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/string.h> | 36 | #include <linux/string.h> |
37 | #include <linux/cpumask.h> | 37 | #include <linux/cpumask.h> |
38 | #include <linux/sched.h> /* for current / set_cpus_allowed() */ | ||
39 | #include <linux/io.h> | 38 | #include <linux/io.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | 40 | ||
@@ -1139,16 +1138,23 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, | |||
1139 | return res; | 1138 | return res; |
1140 | } | 1139 | } |
1141 | 1140 | ||
1142 | /* Driver entry point to switch to the target frequency */ | 1141 | struct powernowk8_target_arg { |
1143 | static int powernowk8_target(struct cpufreq_policy *pol, | 1142 | struct cpufreq_policy *pol; |
1144 | unsigned targfreq, unsigned relation) | 1143 | unsigned targfreq; |
1144 | unsigned relation; | ||
1145 | }; | ||
1146 | |||
1147 | static long powernowk8_target_fn(void *arg) | ||
1145 | { | 1148 | { |
1146 | cpumask_var_t oldmask; | 1149 | struct powernowk8_target_arg *pta = arg; |
1150 | struct cpufreq_policy *pol = pta->pol; | ||
1151 | unsigned targfreq = pta->targfreq; | ||
1152 | unsigned relation = pta->relation; | ||
1147 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1153 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1148 | u32 checkfid; | 1154 | u32 checkfid; |
1149 | u32 checkvid; | 1155 | u32 checkvid; |
1150 | unsigned int newstate; | 1156 | unsigned int newstate; |
1151 | int ret = -EIO; | 1157 | int ret; |
1152 | 1158 | ||
1153 | if (!data) | 1159 | if (!data) |
1154 | return -EINVAL; | 1160 | return -EINVAL; |
@@ -1156,29 +1162,16 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
1156 | checkfid = data->currfid; | 1162 | checkfid = data->currfid; |
1157 | checkvid = data->currvid; | 1163 | checkvid = data->currvid; |
1158 | 1164 | ||
1159 | /* only run on specific CPU from here on. */ | ||
1160 | /* This is poor form: use a workqueue or smp_call_function_single */ | ||
1161 | if (!alloc_cpumask_var(&oldmask, GFP_KERNEL)) | ||
1162 | return -ENOMEM; | ||
1163 | |||
1164 | cpumask_copy(oldmask, tsk_cpus_allowed(current)); | ||
1165 | set_cpus_allowed_ptr(current, cpumask_of(pol->cpu)); | ||
1166 | |||
1167 | if (smp_processor_id() != pol->cpu) { | ||
1168 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | ||
1169 | goto err_out; | ||
1170 | } | ||
1171 | |||
1172 | if (pending_bit_stuck()) { | 1165 | if (pending_bit_stuck()) { |
1173 | printk(KERN_ERR PFX "failing targ, change pending bit set\n"); | 1166 | printk(KERN_ERR PFX "failing targ, change pending bit set\n"); |
1174 | goto err_out; | 1167 | return -EIO; |
1175 | } | 1168 | } |
1176 | 1169 | ||
1177 | pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", | 1170 | pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", |
1178 | pol->cpu, targfreq, pol->min, pol->max, relation); | 1171 | pol->cpu, targfreq, pol->min, pol->max, relation); |
1179 | 1172 | ||
1180 | if (query_current_values_with_pending_wait(data)) | 1173 | if (query_current_values_with_pending_wait(data)) |
1181 | goto err_out; | 1174 | return -EIO; |
1182 | 1175 | ||
1183 | if (cpu_family != CPU_HW_PSTATE) { | 1176 | if (cpu_family != CPU_HW_PSTATE) { |
1184 | pr_debug("targ: curr fid 0x%x, vid 0x%x\n", | 1177 | pr_debug("targ: curr fid 0x%x, vid 0x%x\n", |
@@ -1196,7 +1189,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
1196 | 1189 | ||
1197 | if (cpufreq_frequency_table_target(pol, data->powernow_table, | 1190 | if (cpufreq_frequency_table_target(pol, data->powernow_table, |
1198 | targfreq, relation, &newstate)) | 1191 | targfreq, relation, &newstate)) |
1199 | goto err_out; | 1192 | return -EIO; |
1200 | 1193 | ||
1201 | mutex_lock(&fidvid_mutex); | 1194 | mutex_lock(&fidvid_mutex); |
1202 | 1195 | ||
@@ -1209,9 +1202,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
1209 | ret = transition_frequency_fidvid(data, newstate); | 1202 | ret = transition_frequency_fidvid(data, newstate); |
1210 | if (ret) { | 1203 | if (ret) { |
1211 | printk(KERN_ERR PFX "transition frequency failed\n"); | 1204 | printk(KERN_ERR PFX "transition frequency failed\n"); |
1212 | ret = 1; | ||
1213 | mutex_unlock(&fidvid_mutex); | 1205 | mutex_unlock(&fidvid_mutex); |
1214 | goto err_out; | 1206 | return 1; |
1215 | } | 1207 | } |
1216 | mutex_unlock(&fidvid_mutex); | 1208 | mutex_unlock(&fidvid_mutex); |
1217 | 1209 | ||
@@ -1220,12 +1212,25 @@ static int powernowk8_target(struct cpufreq_policy *pol, | |||
1220 | data->powernow_table[newstate].index); | 1212 | data->powernow_table[newstate].index); |
1221 | else | 1213 | else |
1222 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1214 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1223 | ret = 0; | ||
1224 | 1215 | ||
1225 | err_out: | 1216 | return 0; |
1226 | set_cpus_allowed_ptr(current, oldmask); | 1217 | } |
1227 | free_cpumask_var(oldmask); | 1218 | |
1228 | return ret; | 1219 | /* Driver entry point to switch to the target frequency */ |
1220 | static int powernowk8_target(struct cpufreq_policy *pol, | ||
1221 | unsigned targfreq, unsigned relation) | ||
1222 | { | ||
1223 | struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, | ||
1224 | .relation = relation }; | ||
1225 | |||
1226 | /* | ||
1227 | * Must run on @pol->cpu. cpufreq core is responsible for ensuring | ||
1228 | * that we're bound to the current CPU and pol->cpu stays online. | ||
1229 | */ | ||
1230 | if (smp_processor_id() == pol->cpu) | ||
1231 | return powernowk8_target_fn(&pta); | ||
1232 | else | ||
1233 | return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); | ||
1229 | } | 1234 | } |
1230 | 1235 | ||
1231 | /* Driver entry point to verify the policy and range of frequencies */ | 1236 | /* Driver entry point to verify the policy and range of frequencies */ |
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 2c9bf2692232..3265844839bf 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c | |||
@@ -678,10 +678,22 @@ static int cpuidle_coupled_cpu_notify(struct notifier_block *nb, | |||
678 | int cpu = (unsigned long)hcpu; | 678 | int cpu = (unsigned long)hcpu; |
679 | struct cpuidle_device *dev; | 679 | struct cpuidle_device *dev; |
680 | 680 | ||
681 | switch (action & ~CPU_TASKS_FROZEN) { | ||
682 | case CPU_UP_PREPARE: | ||
683 | case CPU_DOWN_PREPARE: | ||
684 | case CPU_ONLINE: | ||
685 | case CPU_DEAD: | ||
686 | case CPU_UP_CANCELED: | ||
687 | case CPU_DOWN_FAILED: | ||
688 | break; | ||
689 | default: | ||
690 | return NOTIFY_OK; | ||
691 | } | ||
692 | |||
681 | mutex_lock(&cpuidle_lock); | 693 | mutex_lock(&cpuidle_lock); |
682 | 694 | ||
683 | dev = per_cpu(cpuidle_devices, cpu); | 695 | dev = per_cpu(cpuidle_devices, cpu); |
684 | if (!dev->coupled) | 696 | if (!dev || !dev->coupled) |
685 | goto out; | 697 | goto out; |
686 | 698 | ||
687 | switch (action & ~CPU_TASKS_FROZEN) { | 699 | switch (action & ~CPU_TASKS_FROZEN) { |
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c index 53c8c51d5881..93d14070141a 100644 --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c | |||
@@ -63,7 +63,7 @@ static void caam_jr_dequeue(unsigned long devarg) | |||
63 | 63 | ||
64 | head = ACCESS_ONCE(jrp->head); | 64 | head = ACCESS_ONCE(jrp->head); |
65 | 65 | ||
66 | spin_lock_bh(&jrp->outlock); | 66 | spin_lock(&jrp->outlock); |
67 | 67 | ||
68 | sw_idx = tail = jrp->tail; | 68 | sw_idx = tail = jrp->tail; |
69 | hw_idx = jrp->out_ring_read_index; | 69 | hw_idx = jrp->out_ring_read_index; |
@@ -115,7 +115,7 @@ static void caam_jr_dequeue(unsigned long devarg) | |||
115 | jrp->tail = tail; | 115 | jrp->tail = tail; |
116 | } | 116 | } |
117 | 117 | ||
118 | spin_unlock_bh(&jrp->outlock); | 118 | spin_unlock(&jrp->outlock); |
119 | 119 | ||
120 | /* Finally, execute user's callback */ | 120 | /* Finally, execute user's callback */ |
121 | usercall(dev, userdesc, userstatus, userarg); | 121 | usercall(dev, userdesc, userstatus, userarg); |
@@ -236,14 +236,14 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, | |||
236 | return -EIO; | 236 | return -EIO; |
237 | } | 237 | } |
238 | 238 | ||
239 | spin_lock(&jrp->inplock); | 239 | spin_lock_bh(&jrp->inplock); |
240 | 240 | ||
241 | head = jrp->head; | 241 | head = jrp->head; |
242 | tail = ACCESS_ONCE(jrp->tail); | 242 | tail = ACCESS_ONCE(jrp->tail); |
243 | 243 | ||
244 | if (!rd_reg32(&jrp->rregs->inpring_avail) || | 244 | if (!rd_reg32(&jrp->rregs->inpring_avail) || |
245 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { | 245 | CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) { |
246 | spin_unlock(&jrp->inplock); | 246 | spin_unlock_bh(&jrp->inplock); |
247 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); | 247 | dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE); |
248 | return -EBUSY; | 248 | return -EBUSY; |
249 | } | 249 | } |
@@ -265,7 +265,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc, | |||
265 | 265 | ||
266 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); | 266 | wr_reg32(&jrp->rregs->inpring_jobadd, 1); |
267 | 267 | ||
268 | spin_unlock(&jrp->inplock); | 268 | spin_unlock_bh(&jrp->inplock); |
269 | 269 | ||
270 | return 0; | 270 | return 0; |
271 | } | 271 | } |
diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index 002888185f17..d216cd3cc569 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c | |||
@@ -120,3 +120,4 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, | |||
120 | 120 | ||
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | EXPORT_SYMBOL(gen_split_key); | ||
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index c9c4befb5a8d..df14358d7fa1 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c | |||
@@ -821,8 +821,8 @@ static int hifn_register_rng(struct hifn_device *dev) | |||
821 | /* | 821 | /* |
822 | * We must wait at least 256 Pk_clk cycles between two reads of the rng. | 822 | * We must wait at least 256 Pk_clk cycles between two reads of the rng. |
823 | */ | 823 | */ |
824 | dev->rng_wait_time = DIV_ROUND_UP(NSEC_PER_SEC, dev->pk_clk_freq) * | 824 | dev->rng_wait_time = DIV_ROUND_UP_ULL(NSEC_PER_SEC, |
825 | 256; | 825 | dev->pk_clk_freq) * 256; |
826 | 826 | ||
827 | dev->rng.name = dev->name; | 827 | dev->rng.name = dev->name; |
828 | dev->rng.data_present = hifn_rng_data_present, | 828 | dev->rng.data_present = hifn_rng_data_present, |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 3934fcc4e00b..7ab6e26664a7 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -661,7 +661,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
661 | flags); | 661 | flags); |
662 | 662 | ||
663 | if (unlikely(!atslave || !sg_len)) { | 663 | if (unlikely(!atslave || !sg_len)) { |
664 | dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); | 664 | dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n"); |
665 | return NULL; | 665 | return NULL; |
666 | } | 666 | } |
667 | 667 | ||
@@ -689,6 +689,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
689 | 689 | ||
690 | mem = sg_dma_address(sg); | 690 | mem = sg_dma_address(sg); |
691 | len = sg_dma_len(sg); | 691 | len = sg_dma_len(sg); |
692 | if (unlikely(!len)) { | ||
693 | dev_dbg(chan2dev(chan), | ||
694 | "prep_slave_sg: sg(%d) data length is zero\n", i); | ||
695 | goto err; | ||
696 | } | ||
692 | mem_width = 2; | 697 | mem_width = 2; |
693 | if (unlikely(mem & 3 || len & 3)) | 698 | if (unlikely(mem & 3 || len & 3)) |
694 | mem_width = 0; | 699 | mem_width = 0; |
@@ -724,6 +729,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
724 | 729 | ||
725 | mem = sg_dma_address(sg); | 730 | mem = sg_dma_address(sg); |
726 | len = sg_dma_len(sg); | 731 | len = sg_dma_len(sg); |
732 | if (unlikely(!len)) { | ||
733 | dev_dbg(chan2dev(chan), | ||
734 | "prep_slave_sg: sg(%d) data length is zero\n", i); | ||
735 | goto err; | ||
736 | } | ||
727 | mem_width = 2; | 737 | mem_width = 2; |
728 | if (unlikely(mem & 3 || len & 3)) | 738 | if (unlikely(mem & 3 || len & 3)) |
729 | mem_width = 0; | 739 | mem_width = 0; |
@@ -757,6 +767,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
757 | 767 | ||
758 | err_desc_get: | 768 | err_desc_get: |
759 | dev_err(chan2dev(chan), "not enough descriptors available\n"); | 769 | dev_err(chan2dev(chan), "not enough descriptors available\n"); |
770 | err: | ||
760 | atc_desc_put(atchan, first); | 771 | atc_desc_put(atchan, first); |
761 | return NULL; | 772 | return NULL; |
762 | } | 773 | } |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index fcfeb3cd8d31..5084975d793c 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -172,7 +172,8 @@ struct imxdma_engine { | |||
172 | struct device_dma_parameters dma_parms; | 172 | struct device_dma_parameters dma_parms; |
173 | struct dma_device dma_device; | 173 | struct dma_device dma_device; |
174 | void __iomem *base; | 174 | void __iomem *base; |
175 | struct clk *dma_clk; | 175 | struct clk *dma_ahb; |
176 | struct clk *dma_ipg; | ||
176 | spinlock_t lock; | 177 | spinlock_t lock; |
177 | struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS]; | 178 | struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS]; |
178 | struct imxdma_channel channel[IMX_DMA_CHANNELS]; | 179 | struct imxdma_channel channel[IMX_DMA_CHANNELS]; |
@@ -976,10 +977,20 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
976 | return 0; | 977 | return 0; |
977 | } | 978 | } |
978 | 979 | ||
979 | imxdma->dma_clk = clk_get(NULL, "dma"); | 980 | imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg"); |
980 | if (IS_ERR(imxdma->dma_clk)) | 981 | if (IS_ERR(imxdma->dma_ipg)) { |
981 | return PTR_ERR(imxdma->dma_clk); | 982 | ret = PTR_ERR(imxdma->dma_ipg); |
982 | clk_enable(imxdma->dma_clk); | 983 | goto err_clk; |
984 | } | ||
985 | |||
986 | imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb"); | ||
987 | if (IS_ERR(imxdma->dma_ahb)) { | ||
988 | ret = PTR_ERR(imxdma->dma_ahb); | ||
989 | goto err_clk; | ||
990 | } | ||
991 | |||
992 | clk_prepare_enable(imxdma->dma_ipg); | ||
993 | clk_prepare_enable(imxdma->dma_ahb); | ||
983 | 994 | ||
984 | /* reset DMA module */ | 995 | /* reset DMA module */ |
985 | imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR); | 996 | imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR); |
@@ -988,16 +999,14 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
988 | ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma); | 999 | ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma); |
989 | if (ret) { | 1000 | if (ret) { |
990 | dev_warn(imxdma->dev, "Can't register IRQ for DMA\n"); | 1001 | dev_warn(imxdma->dev, "Can't register IRQ for DMA\n"); |
991 | kfree(imxdma); | 1002 | goto err_enable; |
992 | return ret; | ||
993 | } | 1003 | } |
994 | 1004 | ||
995 | ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma); | 1005 | ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma); |
996 | if (ret) { | 1006 | if (ret) { |
997 | dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n"); | 1007 | dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n"); |
998 | free_irq(MX1_DMA_INT, NULL); | 1008 | free_irq(MX1_DMA_INT, NULL); |
999 | kfree(imxdma); | 1009 | goto err_enable; |
1000 | return ret; | ||
1001 | } | 1010 | } |
1002 | } | 1011 | } |
1003 | 1012 | ||
@@ -1094,7 +1103,10 @@ err_init: | |||
1094 | free_irq(MX1_DMA_INT, NULL); | 1103 | free_irq(MX1_DMA_INT, NULL); |
1095 | free_irq(MX1_DMA_ERR, NULL); | 1104 | free_irq(MX1_DMA_ERR, NULL); |
1096 | } | 1105 | } |
1097 | 1106 | err_enable: | |
1107 | clk_disable_unprepare(imxdma->dma_ipg); | ||
1108 | clk_disable_unprepare(imxdma->dma_ahb); | ||
1109 | err_clk: | ||
1098 | kfree(imxdma); | 1110 | kfree(imxdma); |
1099 | return ret; | 1111 | return ret; |
1100 | } | 1112 | } |
@@ -1114,7 +1126,9 @@ static int __exit imxdma_remove(struct platform_device *pdev) | |||
1114 | free_irq(MX1_DMA_ERR, NULL); | 1126 | free_irq(MX1_DMA_ERR, NULL); |
1115 | } | 1127 | } |
1116 | 1128 | ||
1117 | kfree(imxdma); | 1129 | clk_disable_unprepare(imxdma->dma_ipg); |
1130 | clk_disable_unprepare(imxdma->dma_ahb); | ||
1131 | kfree(imxdma); | ||
1118 | 1132 | ||
1119 | return 0; | 1133 | return 0; |
1120 | } | 1134 | } |
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index e4feba6b03c0..f5843bc80baa 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c | |||
@@ -1567,17 +1567,19 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r) | |||
1567 | goto xfer_exit; | 1567 | goto xfer_exit; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | /* Prefer Secure Channel */ | ||
1571 | if (!_manager_ns(thrd)) | ||
1572 | r->cfg->nonsecure = 0; | ||
1573 | else | ||
1574 | r->cfg->nonsecure = 1; | ||
1575 | 1570 | ||
1576 | /* Use last settings, if not provided */ | 1571 | /* Use last settings, if not provided */ |
1577 | if (r->cfg) | 1572 | if (r->cfg) { |
1573 | /* Prefer Secure Channel */ | ||
1574 | if (!_manager_ns(thrd)) | ||
1575 | r->cfg->nonsecure = 0; | ||
1576 | else | ||
1577 | r->cfg->nonsecure = 1; | ||
1578 | |||
1578 | ccr = _prepare_ccr(r->cfg); | 1579 | ccr = _prepare_ccr(r->cfg); |
1579 | else | 1580 | } else { |
1580 | ccr = readl(regs + CC(thrd->id)); | 1581 | ccr = readl(regs + CC(thrd->id)); |
1582 | } | ||
1581 | 1583 | ||
1582 | /* If this req doesn't have valid xfer settings */ | 1584 | /* If this req doesn't have valid xfer settings */ |
1583 | if (!_is_valid(ccr)) { | 1585 | if (!_is_valid(ccr)) { |
@@ -2928,6 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) | |||
2928 | num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); | 2930 | num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); |
2929 | 2931 | ||
2930 | pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); | 2932 | pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); |
2933 | if (!pdmac->peripherals) { | ||
2934 | ret = -ENOMEM; | ||
2935 | dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n"); | ||
2936 | goto probe_err5; | ||
2937 | } | ||
2931 | 2938 | ||
2932 | for (i = 0; i < num_chan; i++) { | 2939 | for (i = 0; i < num_chan; i++) { |
2933 | pch = &pdmac->peripherals[i]; | 2940 | pch = &pdmac->peripherals[i]; |
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index d52dbc6c54ab..24acd711e032 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -1119,15 +1119,21 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( | |||
1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) | 1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) |
1120 | { | 1120 | { |
1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1122 | struct tegra_dma *tdma = tdc->tdma; | ||
1123 | int ret; | ||
1122 | 1124 | ||
1123 | dma_cookie_init(&tdc->dma_chan); | 1125 | dma_cookie_init(&tdc->dma_chan); |
1124 | tdc->config_init = false; | 1126 | tdc->config_init = false; |
1125 | return 0; | 1127 | ret = clk_prepare_enable(tdma->dma_clk); |
1128 | if (ret < 0) | ||
1129 | dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); | ||
1130 | return ret; | ||
1126 | } | 1131 | } |
1127 | 1132 | ||
1128 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) | 1133 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) |
1129 | { | 1134 | { |
1130 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1135 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1136 | struct tegra_dma *tdma = tdc->tdma; | ||
1131 | 1137 | ||
1132 | struct tegra_dma_desc *dma_desc; | 1138 | struct tegra_dma_desc *dma_desc; |
1133 | struct tegra_dma_sg_req *sg_req; | 1139 | struct tegra_dma_sg_req *sg_req; |
@@ -1163,6 +1169,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) | |||
1163 | list_del(&sg_req->node); | 1169 | list_del(&sg_req->node); |
1164 | kfree(sg_req); | 1170 | kfree(sg_req); |
1165 | } | 1171 | } |
1172 | clk_disable_unprepare(tdma->dma_clk); | ||
1166 | } | 1173 | } |
1167 | 1174 | ||
1168 | /* Tegra20 specific DMA controller information */ | 1175 | /* Tegra20 specific DMA controller information */ |
@@ -1255,6 +1262,13 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1255 | } | 1262 | } |
1256 | } | 1263 | } |
1257 | 1264 | ||
1265 | /* Enable clock before accessing registers */ | ||
1266 | ret = clk_prepare_enable(tdma->dma_clk); | ||
1267 | if (ret < 0) { | ||
1268 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | ||
1269 | goto err_pm_disable; | ||
1270 | } | ||
1271 | |||
1258 | /* Reset DMA controller */ | 1272 | /* Reset DMA controller */ |
1259 | tegra_periph_reset_assert(tdma->dma_clk); | 1273 | tegra_periph_reset_assert(tdma->dma_clk); |
1260 | udelay(2); | 1274 | udelay(2); |
@@ -1265,6 +1279,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1265 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); | 1279 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); |
1266 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); | 1280 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); |
1267 | 1281 | ||
1282 | clk_disable_unprepare(tdma->dma_clk); | ||
1283 | |||
1268 | INIT_LIST_HEAD(&tdma->dma_dev.channels); | 1284 | INIT_LIST_HEAD(&tdma->dma_dev.channels); |
1269 | for (i = 0; i < cdata->nr_channels; i++) { | 1285 | for (i = 0; i < cdata->nr_channels; i++) { |
1270 | struct tegra_dma_channel *tdc = &tdma->channels[i]; | 1286 | struct tegra_dma_channel *tdc = &tdma->channels[i]; |
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 616d90bcb3a4..d5dc9da7f99f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) | |||
199 | return (void *)(((unsigned long)ptr) + align - r); | 199 | return (void *)(((unsigned long)ptr) + align - r); |
200 | } | 200 | } |
201 | 201 | ||
202 | static void _edac_mc_free(struct mem_ctl_info *mci) | ||
203 | { | ||
204 | int i, chn, row; | ||
205 | struct csrow_info *csr; | ||
206 | const unsigned int tot_dimms = mci->tot_dimms; | ||
207 | const unsigned int tot_channels = mci->num_cschannel; | ||
208 | const unsigned int tot_csrows = mci->nr_csrows; | ||
209 | |||
210 | if (mci->dimms) { | ||
211 | for (i = 0; i < tot_dimms; i++) | ||
212 | kfree(mci->dimms[i]); | ||
213 | kfree(mci->dimms); | ||
214 | } | ||
215 | if (mci->csrows) { | ||
216 | for (row = 0; row < tot_csrows; row++) { | ||
217 | csr = mci->csrows[row]; | ||
218 | if (csr) { | ||
219 | if (csr->channels) { | ||
220 | for (chn = 0; chn < tot_channels; chn++) | ||
221 | kfree(csr->channels[chn]); | ||
222 | kfree(csr->channels); | ||
223 | } | ||
224 | kfree(csr); | ||
225 | } | ||
226 | } | ||
227 | kfree(mci->csrows); | ||
228 | } | ||
229 | kfree(mci); | ||
230 | } | ||
231 | |||
202 | /** | 232 | /** |
203 | * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure | 233 | * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure |
204 | * @mc_num: Memory controller number | 234 | * @mc_num: Memory controller number |
@@ -413,24 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, | |||
413 | return mci; | 443 | return mci; |
414 | 444 | ||
415 | error: | 445 | error: |
416 | if (mci->dimms) { | 446 | _edac_mc_free(mci); |
417 | for (i = 0; i < tot_dimms; i++) | ||
418 | kfree(mci->dimms[i]); | ||
419 | kfree(mci->dimms); | ||
420 | } | ||
421 | if (mci->csrows) { | ||
422 | for (chn = 0; chn < tot_channels; chn++) { | ||
423 | csr = mci->csrows[chn]; | ||
424 | if (csr) { | ||
425 | for (chn = 0; chn < tot_channels; chn++) | ||
426 | kfree(csr->channels[chn]); | ||
427 | kfree(csr); | ||
428 | } | ||
429 | kfree(mci->csrows[i]); | ||
430 | } | ||
431 | kfree(mci->csrows); | ||
432 | } | ||
433 | kfree(mci); | ||
434 | 447 | ||
435 | return NULL; | 448 | return NULL; |
436 | } | 449 | } |
@@ -445,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci) | |||
445 | { | 458 | { |
446 | edac_dbg(1, "\n"); | 459 | edac_dbg(1, "\n"); |
447 | 460 | ||
461 | /* If we're not yet registered with sysfs free only what was allocated | ||
462 | * in edac_mc_alloc(). | ||
463 | */ | ||
464 | if (!device_is_registered(&mci->dev)) { | ||
465 | _edac_mc_free(mci); | ||
466 | return; | ||
467 | } | ||
468 | |||
448 | /* the mci instance is freed here, when the sysfs object is dropped */ | 469 | /* the mci instance is freed here, when the sysfs object is dropped */ |
449 | edac_unregister_sysfs(mci); | 470 | edac_unregister_sysfs(mci); |
450 | } | 471 | } |
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c index 47180a08edad..b6653a6fc5d5 100644 --- a/drivers/edac/i3200_edac.c +++ b/drivers/edac/i3200_edac.c | |||
@@ -391,7 +391,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx) | |||
391 | for (j = 0; j < nr_channels; j++) { | 391 | for (j = 0; j < nr_channels; j++) { |
392 | struct dimm_info *dimm = csrow->channels[j]->dimm; | 392 | struct dimm_info *dimm = csrow->channels[j]->dimm; |
393 | 393 | ||
394 | dimm->nr_pages = nr_pages / nr_channels; | 394 | dimm->nr_pages = nr_pages; |
395 | dimm->grain = nr_pages << PAGE_SHIFT; | 395 | dimm->grain = nr_pages << PAGE_SHIFT; |
396 | dimm->mtype = MEM_DDR2; | 396 | dimm->mtype = MEM_DDR2; |
397 | dimm->dtype = DEV_UNKNOWN; | 397 | dimm->dtype = DEV_UNKNOWN; |
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index 39c63757c2a1..6a49dd00b81b 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c | |||
@@ -1012,6 +1012,10 @@ static void handle_channel(struct i5000_pvt *pvt, int slot, int channel, | |||
1012 | /* add the number of COLUMN bits */ | 1012 | /* add the number of COLUMN bits */ |
1013 | addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr); | 1013 | addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr); |
1014 | 1014 | ||
1015 | /* Dual-rank memories have twice the size */ | ||
1016 | if (dinfo->dual_rank) | ||
1017 | addrBits++; | ||
1018 | |||
1015 | addrBits += 6; /* add 64 bits per DIMM */ | 1019 | addrBits += 6; /* add 64 bits per DIMM */ |
1016 | addrBits -= 20; /* divide by 2^^20 */ | 1020 | addrBits -= 20; /* divide by 2^^20 */ |
1017 | addrBits -= 3; /* 8 bits per bytes */ | 1021 | addrBits -= 3; /* 8 bits per bytes */ |
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index f3b1f9fafa4b..5715b7c2c517 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c | |||
@@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
513 | { | 513 | { |
514 | struct sbridge_pvt *pvt = mci->pvt_info; | 514 | struct sbridge_pvt *pvt = mci->pvt_info; |
515 | struct dimm_info *dimm; | 515 | struct dimm_info *dimm; |
516 | int i, j, banks, ranks, rows, cols, size, npages; | 516 | unsigned i, j, banks, ranks, rows, cols, npages; |
517 | u64 size; | ||
517 | u32 reg; | 518 | u32 reg; |
518 | enum edac_type mode; | 519 | enum edac_type mode; |
519 | enum mem_type mtype; | 520 | enum mem_type mtype; |
@@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci) | |||
585 | cols = numcol(mtr); | 586 | cols = numcol(mtr); |
586 | 587 | ||
587 | /* DDR3 has 8 I/O banks */ | 588 | /* DDR3 has 8 I/O banks */ |
588 | size = (rows * cols * banks * ranks) >> (20 - 3); | 589 | size = ((u64)rows * cols * banks * ranks) >> (20 - 3); |
589 | npages = MiB_TO_PAGES(size); | 590 | npages = MiB_TO_PAGES(size); |
590 | 591 | ||
591 | edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n", | 592 | edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n", |
592 | pvt->sbridge_dev->mc, i, j, | 593 | pvt->sbridge_dev->mc, i, j, |
593 | size, npages, | 594 | size, npages, |
594 | banks, ranks, rows, cols); | 595 | banks, ranks, rows, cols); |
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 920a609b2c35..38f9e52f358b 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c | |||
@@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) | |||
669 | } | 669 | } |
670 | info->dev = &pdev->dev; | 670 | info->dev = &pdev->dev; |
671 | info->max77693 = max77693; | 671 | info->max77693 = max77693; |
672 | info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, | 672 | if (info->max77693->regmap_muic) |
673 | &max77693_muic_regmap_config); | 673 | dev_dbg(&pdev->dev, "allocate register map\n"); |
674 | if (IS_ERR(info->max77693->regmap_muic)) { | 674 | else { |
675 | ret = PTR_ERR(info->max77693->regmap_muic); | 675 | info->max77693->regmap_muic = devm_regmap_init_i2c( |
676 | dev_err(max77693->dev, | 676 | info->max77693->muic, |
677 | "failed to allocate register map: %d\n", ret); | 677 | &max77693_muic_regmap_config); |
678 | goto err_regmap; | 678 | if (IS_ERR(info->max77693->regmap_muic)) { |
679 | ret = PTR_ERR(info->max77693->regmap_muic); | ||
680 | dev_err(max77693->dev, | ||
681 | "failed to allocate register map: %d\n", ret); | ||
682 | goto err_regmap; | ||
683 | } | ||
679 | } | 684 | } |
680 | platform_set_drvdata(pdev, info); | 685 | platform_set_drvdata(pdev, info); |
681 | mutex_init(&info->mutex); | 686 | mutex_init(&info->mutex); |
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe3db45fa83c..3cc152e690b0 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c | |||
@@ -107,7 +107,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) | |||
107 | if (ret < 0) | 107 | if (ret < 0) |
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); | 110 | ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, |
111 | pdev->name); | ||
111 | if (ret < 0) | 112 | if (ret < 0) |
112 | goto err; | 113 | goto err; |
113 | 114 | ||
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b16c8a72a2e2..ba7926f5c099 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -294,7 +294,7 @@ config GPIO_MAX732X_IRQ | |||
294 | 294 | ||
295 | config GPIO_MC9S08DZ60 | 295 | config GPIO_MC9S08DZ60 |
296 | bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" | 296 | bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" |
297 | depends on I2C && MACH_MX35_3DS | 297 | depends on I2C=y && MACH_MX35_3DS |
298 | help | 298 | help |
299 | Select this to enable the MC9S08DZ60 GPIO driver | 299 | Select this to enable the MC9S08DZ60 GPIO driver |
300 | 300 | ||
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 150d9768811d..ec48ed512628 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c | |||
@@ -247,9 +247,9 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | |||
247 | 247 | ||
248 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, | 248 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, |
249 | pdata->number_of_pins, numa_node_id()); | 249 | pdata->number_of_pins, numa_node_id()); |
250 | if (IS_ERR_VALUE(p->irq_base)) { | 250 | if (p->irq_base < 0) { |
251 | dev_err(&pdev->dev, "cannot get irq_desc\n"); | 251 | dev_err(&pdev->dev, "cannot get irq_desc\n"); |
252 | return -ENXIO; | 252 | return p->irq_base; |
253 | } | 253 | } |
254 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", | 254 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", |
255 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); | 255 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); |
@@ -266,7 +266,7 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | |||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p) | 269 | static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) |
270 | { | 270 | { |
271 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; | 271 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; |
272 | 272 | ||
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index a1c8754f52cf..202a99207b7d 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -339,7 +339,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
339 | resource_size_t start, len; | 339 | resource_size_t start, len; |
340 | struct lnw_gpio *lnw; | 340 | struct lnw_gpio *lnw; |
341 | u32 gpio_base; | 341 | u32 gpio_base; |
342 | int retval = 0; | 342 | int retval; |
343 | int ngpio = id->driver_data; | 343 | int ngpio = id->driver_data; |
344 | 344 | ||
345 | retval = pci_enable_device(pdev); | 345 | retval = pci_enable_device(pdev); |
@@ -357,6 +357,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
357 | base = ioremap_nocache(start, len); | 357 | base = ioremap_nocache(start, len); |
358 | if (!base) { | 358 | if (!base) { |
359 | dev_err(&pdev->dev, "error mapping bar1\n"); | 359 | dev_err(&pdev->dev, "error mapping bar1\n"); |
360 | retval = -EFAULT; | ||
360 | goto err3; | 361 | goto err3; |
361 | } | 362 | } |
362 | gpio_base = *((u32 *)base + 1); | 363 | gpio_base = *((u32 *)base + 1); |
@@ -381,8 +382,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
381 | 382 | ||
382 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, | 383 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, |
383 | &lnw_gpio_irq_ops, lnw); | 384 | &lnw_gpio_irq_ops, lnw); |
384 | if (!lnw->domain) | 385 | if (!lnw->domain) { |
386 | retval = -ENOMEM; | ||
385 | goto err3; | 387 | goto err3; |
388 | } | ||
386 | 389 | ||
387 | lnw->reg_base = base; | 390 | lnw->reg_base = base; |
388 | lnw->chip.label = dev_name(&pdev->dev); | 391 | lnw->chip.label = dev_name(&pdev->dev); |
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c index 8a420f13905e..ed94b4ea72e9 100644 --- a/drivers/gpio/gpio-lpc32xx.c +++ b/drivers/gpio/gpio-lpc32xx.c | |||
@@ -308,6 +308,7 @@ static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin, | |||
308 | { | 308 | { |
309 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | 309 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); |
310 | 310 | ||
311 | __set_gpio_level_p012(group, pin, value); | ||
311 | __set_gpio_dir_p012(group, pin, 0); | 312 | __set_gpio_dir_p012(group, pin, 0); |
312 | 313 | ||
313 | return 0; | 314 | return 0; |
@@ -318,6 +319,7 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin, | |||
318 | { | 319 | { |
319 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | 320 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); |
320 | 321 | ||
322 | __set_gpio_level_p3(group, pin, value); | ||
321 | __set_gpio_dir_p3(group, pin, 0); | 323 | __set_gpio_dir_p3(group, pin, 0); |
322 | 324 | ||
323 | return 0; | 325 | return 0; |
@@ -326,6 +328,9 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin, | |||
326 | static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin, | 328 | static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin, |
327 | int value) | 329 | int value) |
328 | { | 330 | { |
331 | struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip); | ||
332 | |||
333 | __set_gpo_level_p3(group, pin, value); | ||
329 | return 0; | 334 | return 0; |
330 | } | 335 | } |
331 | 336 | ||
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index 71a838f44501..b38986285868 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c | |||
@@ -99,7 +99,7 @@ static int msic_gpio_to_oreg(unsigned offset) | |||
99 | if (offset < 20) | 99 | if (offset < 20) |
100 | return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; | 100 | return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; |
101 | 101 | ||
102 | return INTEL_MSIC_GPIO1HV0CTLO + offset + 20; | 102 | return INTEL_MSIC_GPIO1HV0CTLO - offset + 20; |
103 | } | 103 | } |
104 | 104 | ||
105 | static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 105 | static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 4db460b6ecf7..80f44bb64a87 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -465,9 +465,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
465 | goto out_iounmap; | 465 | goto out_iounmap; |
466 | 466 | ||
467 | port->bgc.gc.to_irq = mxc_gpio_to_irq; | 467 | port->bgc.gc.to_irq = mxc_gpio_to_irq; |
468 | port->bgc.gc.base = pdev->id * 32; | 468 | port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : |
469 | port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); | 469 | pdev->id * 32; |
470 | port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); | ||
471 | 470 | ||
472 | err = gpiochip_add(&port->bgc.gc); | 471 | err = gpiochip_add(&port->bgc.gc); |
473 | if (err) | 472 | if (err) |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 58a6a63a6ece..9cac88a65f78 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -62,6 +62,7 @@ int pxa_last_gpio; | |||
62 | 62 | ||
63 | #ifdef CONFIG_OF | 63 | #ifdef CONFIG_OF |
64 | static struct irq_domain *domain; | 64 | static struct irq_domain *domain; |
65 | static struct device_node *pxa_gpio_of_node; | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
67 | struct pxa_gpio_chip { | 68 | struct pxa_gpio_chip { |
@@ -277,6 +278,24 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
277 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 278 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
278 | } | 279 | } |
279 | 280 | ||
281 | #ifdef CONFIG_OF_GPIO | ||
282 | static int pxa_gpio_of_xlate(struct gpio_chip *gc, | ||
283 | const struct of_phandle_args *gpiospec, | ||
284 | u32 *flags) | ||
285 | { | ||
286 | if (gpiospec->args[0] > pxa_last_gpio) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip) | ||
290 | return -EINVAL; | ||
291 | |||
292 | if (flags) | ||
293 | *flags = gpiospec->args[1]; | ||
294 | |||
295 | return gpiospec->args[0] % 32; | ||
296 | } | ||
297 | #endif | ||
298 | |||
280 | static int __devinit pxa_init_gpio_chip(int gpio_end, | 299 | static int __devinit pxa_init_gpio_chip(int gpio_end, |
281 | int (*set_wake)(unsigned int, unsigned int)) | 300 | int (*set_wake)(unsigned int, unsigned int)) |
282 | { | 301 | { |
@@ -304,6 +323,11 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, | |||
304 | c->get = pxa_gpio_get; | 323 | c->get = pxa_gpio_get; |
305 | c->set = pxa_gpio_set; | 324 | c->set = pxa_gpio_set; |
306 | c->to_irq = pxa_gpio_to_irq; | 325 | c->to_irq = pxa_gpio_to_irq; |
326 | #ifdef CONFIG_OF_GPIO | ||
327 | c->of_node = pxa_gpio_of_node; | ||
328 | c->of_xlate = pxa_gpio_of_xlate; | ||
329 | c->of_gpio_n_cells = 2; | ||
330 | #endif | ||
307 | 331 | ||
308 | /* number of GPIOs on last bank may be less than 32 */ | 332 | /* number of GPIOs on last bank may be less than 32 */ |
309 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 333 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
@@ -488,6 +512,7 @@ static int pxa_gpio_nums(void) | |||
488 | return count; | 512 | return count; |
489 | } | 513 | } |
490 | 514 | ||
515 | #ifdef CONFIG_OF | ||
491 | static struct of_device_id pxa_gpio_dt_ids[] = { | 516 | static struct of_device_id pxa_gpio_dt_ids[] = { |
492 | { .compatible = "mrvl,pxa-gpio" }, | 517 | { .compatible = "mrvl,pxa-gpio" }, |
493 | { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, | 518 | { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, |
@@ -505,9 +530,9 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
505 | 530 | ||
506 | const struct irq_domain_ops pxa_irq_domain_ops = { | 531 | const struct irq_domain_ops pxa_irq_domain_ops = { |
507 | .map = pxa_irq_domain_map, | 532 | .map = pxa_irq_domain_map, |
533 | .xlate = irq_domain_xlate_twocell, | ||
508 | }; | 534 | }; |
509 | 535 | ||
510 | #ifdef CONFIG_OF | ||
511 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | 536 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) |
512 | { | 537 | { |
513 | int ret, nr_banks, nr_gpios, irq_base; | 538 | int ret, nr_banks, nr_gpios, irq_base; |
@@ -545,6 +570,7 @@ static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | |||
545 | } | 570 | } |
546 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, | 571 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, |
547 | &pxa_irq_domain_ops, NULL); | 572 | &pxa_irq_domain_ops, NULL); |
573 | pxa_gpio_of_node = np; | ||
548 | return 0; | 574 | return 0; |
549 | err: | 575 | err: |
550 | iounmap(gpio_reg_base); | 576 | iounmap(gpio_reg_base); |
@@ -653,7 +679,7 @@ static struct platform_driver pxa_gpio_driver = { | |||
653 | .probe = pxa_gpio_probe, | 679 | .probe = pxa_gpio_probe, |
654 | .driver = { | 680 | .driver = { |
655 | .name = "pxa-gpio", | 681 | .name = "pxa-gpio", |
656 | .of_match_table = pxa_gpio_dt_ids, | 682 | .of_match_table = of_match_ptr(pxa_gpio_dt_ids), |
657 | }, | 683 | }, |
658 | }; | 684 | }; |
659 | 685 | ||
diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index e97016af6443..b62d443e9a59 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c | |||
@@ -170,6 +170,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) | |||
170 | rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; | 170 | rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; |
171 | 171 | ||
172 | rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; | 172 | rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; |
173 | rdc321x_gpio_dev->chip.owner = THIS_MODULE; | ||
173 | rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; | 174 | rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; |
174 | rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; | 175 | rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; |
175 | rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; | 176 | rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; |
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 92f7b2bb79d4..ba126cc04073 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -2454,12 +2454,6 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
2454 | }, | 2454 | }, |
2455 | }, { | 2455 | }, { |
2456 | .chip = { | 2456 | .chip = { |
2457 | .base = EXYNOS5_GPC4(0), | ||
2458 | .ngpio = EXYNOS5_GPIO_C4_NR, | ||
2459 | .label = "GPC4", | ||
2460 | }, | ||
2461 | }, { | ||
2462 | .chip = { | ||
2463 | .base = EXYNOS5_GPD0(0), | 2457 | .base = EXYNOS5_GPD0(0), |
2464 | .ngpio = EXYNOS5_GPIO_D0_NR, | 2458 | .ngpio = EXYNOS5_GPIO_D0_NR, |
2465 | .label = "GPD0", | 2459 | .label = "GPD0", |
@@ -2513,6 +2507,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
2513 | .label = "GPY6", | 2507 | .label = "GPY6", |
2514 | }, | 2508 | }, |
2515 | }, { | 2509 | }, { |
2510 | .chip = { | ||
2511 | .base = EXYNOS5_GPC4(0), | ||
2512 | .ngpio = EXYNOS5_GPIO_C4_NR, | ||
2513 | .label = "GPC4", | ||
2514 | }, | ||
2515 | }, { | ||
2516 | .config = &samsung_gpio_cfgs[9], | 2516 | .config = &samsung_gpio_cfgs[9], |
2517 | .irq_base = IRQ_EINT(0), | 2517 | .irq_base = IRQ_EINT(0), |
2518 | .chip = { | 2518 | .chip = { |
@@ -2836,7 +2836,7 @@ static __init void exynos5_gpiolib_init(void) | |||
2836 | } | 2836 | } |
2837 | 2837 | ||
2838 | /* need to set base address for gpc4 */ | 2838 | /* need to set base address for gpc4 */ |
2839 | exynos5_gpios_1[11].base = gpio_base1 + 0x2E0; | 2839 | exynos5_gpios_1[20].base = gpio_base1 + 0x2E0; |
2840 | 2840 | ||
2841 | /* need to set base address for gpx */ | 2841 | /* need to set base address for gpx */ |
2842 | chip = &exynos5_gpios_1[21]; | 2842 | chip = &exynos5_gpios_1[21]; |
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 424dce8e3f30..8707d4572a06 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -241,7 +241,8 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) | |||
241 | break; | 241 | break; |
242 | 242 | ||
243 | default: | 243 | default: |
244 | return -ENODEV; | 244 | err = -ENODEV; |
245 | goto err_sch_gpio_core; | ||
245 | } | 246 | } |
246 | 247 | ||
247 | sch_gpio_core.dev = &pdev->dev; | 248 | sch_gpio_core.dev = &pdev->dev; |
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a18c4aa68b1e..f1a45997aea8 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
@@ -82,7 +82,7 @@ int of_get_named_gpio_flags(struct device_node *np, const char *propname, | |||
82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | 82 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); |
83 | 83 | ||
84 | of_node_put(gg_data.gpiospec.np); | 84 | of_node_put(gg_data.gpiospec.np); |
85 | pr_debug("%s exited with status %d\n", __func__, ret); | 85 | pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio); |
86 | return gg_data.out_gpio; | 86 | return gg_data.out_gpio; |
87 | } | 87 | } |
88 | EXPORT_SYMBOL(of_get_named_gpio_flags); | 88 | EXPORT_SYMBOL(of_get_named_gpio_flags); |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 23120c00a881..90e28081712d 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -22,6 +22,7 @@ menuconfig DRM | |||
22 | config DRM_USB | 22 | config DRM_USB |
23 | tristate | 23 | tristate |
24 | depends on DRM | 24 | depends on DRM |
25 | depends on USB_ARCH_HAS_HCD | ||
25 | select USB | 26 | select USB |
26 | 27 | ||
27 | config DRM_KMS_HELPER | 28 | config DRM_KMS_HELPER |
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49c..36164806b9d4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c | |||
@@ -193,6 +193,9 @@ static const struct file_operations ast_fops = { | |||
193 | .mmap = ast_mmap, | 193 | .mmap = ast_mmap, |
194 | .poll = drm_poll, | 194 | .poll = drm_poll, |
195 | .fasync = drm_fasync, | 195 | .fasync = drm_fasync, |
196 | #ifdef CONFIG_COMPAT | ||
197 | .compat_ioctl = drm_compat_ioctl, | ||
198 | #endif | ||
196 | .read = drm_read, | 199 | .read = drm_read, |
197 | }; | 200 | }; |
198 | 201 | ||
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb53..a712cafcfa1d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev) | |||
841 | 841 | ||
842 | ast->cursor_cache = obj; | 842 | ast->cursor_cache = obj; |
843 | ast->cursor_cache_gpu_addr = gpu_addr; | 843 | ast->cursor_cache_gpu_addr = gpu_addr; |
844 | DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); | 844 | DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); |
845 | return 0; | 845 | return 0; |
846 | fail: | 846 | fail: |
847 | return ret; | 847 | return ret; |
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c6596..b83a2d7ddd1a 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = { | |||
74 | .unlocked_ioctl = drm_ioctl, | 74 | .unlocked_ioctl = drm_ioctl, |
75 | .mmap = cirrus_mmap, | 75 | .mmap = cirrus_mmap, |
76 | .poll = drm_poll, | 76 | .poll = drm_poll, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .fasync = drm_fasync, | 80 | .fasync = drm_fasync, |
78 | }; | 81 | }; |
79 | static struct drm_driver driver = { | 82 | static struct drm_driver driver = { |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 08a7aa722d6b..6fbfc244748f 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -1981,7 +1981,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, | |||
1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 1981 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1982 | return -EINVAL; | 1982 | return -EINVAL; |
1983 | 1983 | ||
1984 | if (!req->flags) | 1984 | if (!req->flags || (~DRM_MODE_CURSOR_FLAGS & req->flags)) |
1985 | return -EINVAL; | 1985 | return -EINVAL; |
1986 | 1986 | ||
1987 | mutex_lock(&dev->mode_config.mutex); | 1987 | mutex_lock(&dev->mode_config.mutex); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a8743c399e83..b7ee230572b7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -87,6 +87,9 @@ static struct edid_quirk { | |||
87 | int product_id; | 87 | int product_id; |
88 | u32 quirks; | 88 | u32 quirks; |
89 | } edid_quirk_list[] = { | 89 | } edid_quirk_list[] = { |
90 | /* ASUS VW222S */ | ||
91 | { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, | ||
92 | |||
90 | /* Acer AL1706 */ | 93 | /* Acer AL1706 */ |
91 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, | 94 | { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, |
92 | /* Acer F51 */ | 95 | /* Acer F51 */ |
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 66d4a28ad5a2..0303935d10e2 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c | |||
@@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
119 | { | 119 | { |
120 | const struct firmware *fw; | 120 | const struct firmware *fw; |
121 | struct platform_device *pdev; | 121 | struct platform_device *pdev; |
122 | u8 *fwdata = NULL, *edid; | 122 | u8 *fwdata = NULL, *edid, *new_edid; |
123 | int fwsize, expected; | 123 | int fwsize, expected; |
124 | int builtin = 0, err = 0; | 124 | int builtin = 0, err = 0; |
125 | int i, valid_extensions = 0; | 125 | int i, valid_extensions = 0; |
@@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
195 | "\"%s\" for connector \"%s\"\n", valid_extensions, | 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, |
196 | edid[0x7e], name, connector_name); | 196 | edid[0x7e], name, connector_name); |
197 | edid[0x7e] = valid_extensions; | 197 | edid[0x7e] = valid_extensions; |
198 | edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, | 198 | new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, |
199 | GFP_KERNEL); | 199 | GFP_KERNEL); |
200 | if (edid == NULL) { | 200 | if (new_edid == NULL) { |
201 | err = -ENOMEM; | 201 | err = -ENOMEM; |
202 | kfree(edid); | ||
202 | goto relfw_out; | 203 | goto relfw_out; |
203 | } | 204 | } |
205 | edid = new_edid; | ||
204 | } | 206 | } |
205 | 207 | ||
206 | connector->display_info.raw_edid = edid; | 208 | connector->display_info.raw_edid = edid; |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index b7adb4a967fd..28637c181b15 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -706,9 +706,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) | |||
706 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); | 706 | p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); |
707 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); | 707 | p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); |
708 | p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); | 708 | p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); |
709 | |||
710 | p->crtc_hadjusted = false; | ||
711 | p->crtc_vadjusted = false; | ||
712 | } | 709 | } |
713 | EXPORT_SYMBOL(drm_mode_set_crtcinfo); | 710 | EXPORT_SYMBOL(drm_mode_set_crtcinfo); |
714 | 711 | ||
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index 371c695322d9..da457b18eaaf 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -89,7 +89,7 @@ static const struct file_operations drm_proc_fops = { | |||
89 | * Create a given set of proc files represented by an array of | 89 | * Create a given set of proc files represented by an array of |
90 | * gdm_proc_lists in the given root directory. | 90 | * gdm_proc_lists in the given root directory. |
91 | */ | 91 | */ |
92 | int drm_proc_create_files(struct drm_info_list *files, int count, | 92 | static int drm_proc_create_files(struct drm_info_list *files, int count, |
93 | struct proc_dir_entry *root, struct drm_minor *minor) | 93 | struct proc_dir_entry *root, struct drm_minor *minor) |
94 | { | 94 | { |
95 | struct drm_device *dev = minor->dev; | 95 | struct drm_device *dev = minor->dev; |
@@ -172,7 +172,7 @@ int drm_proc_init(struct drm_minor *minor, int minor_id, | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | int drm_proc_remove_files(struct drm_info_list *files, int count, | 175 | static int drm_proc_remove_files(struct drm_info_list *files, int count, |
176 | struct drm_minor *minor) | 176 | struct drm_minor *minor) |
177 | { | 177 | { |
178 | struct list_head *pos, *q; | 178 | struct list_head *pos, *q; |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7d..59a26e577b57 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI | |||
36 | 36 | ||
37 | config DRM_EXYNOS_G2D | 37 | config DRM_EXYNOS_G2D |
38 | bool "Exynos DRM G2D" | 38 | bool "Exynos DRM G2D" |
39 | depends on DRM_EXYNOS | 39 | depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D |
40 | help | 40 | help |
41 | Choose this option if you want to use Exynos G2D for DRM. | 41 | Choose this option if you want to use Exynos G2D for DRM. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b2..ae13febe0eaa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
@@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, | |||
163 | /* TODO */ | 163 | /* TODO */ |
164 | } | 164 | } |
165 | 165 | ||
166 | static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, | ||
167 | struct vm_area_struct *vma) | ||
168 | { | ||
169 | return -ENOTTY; | ||
170 | } | ||
171 | |||
166 | static struct dma_buf_ops exynos_dmabuf_ops = { | 172 | static struct dma_buf_ops exynos_dmabuf_ops = { |
167 | .map_dma_buf = exynos_gem_map_dma_buf, | 173 | .map_dma_buf = exynos_gem_map_dma_buf, |
168 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, | 174 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, |
@@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = { | |||
170 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, | 176 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, |
171 | .kunmap = exynos_gem_dmabuf_kunmap, | 177 | .kunmap = exynos_gem_dmabuf_kunmap, |
172 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, | 178 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, |
179 | .mmap = exynos_gem_dmabuf_mmap, | ||
173 | .release = exynos_dmabuf_release, | 180 | .release = exynos_dmabuf_release, |
174 | }; | 181 | }; |
175 | 182 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e48..d07071937453 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
160 | if (!file_priv) | 160 | if (!file_priv) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
162 | 162 | ||
163 | drm_prime_init_file_private(&file->prime); | ||
164 | file->driver_priv = file_priv; | 163 | file->driver_priv = file_priv; |
165 | 164 | ||
166 | return exynos_drm_subdrv_open(dev, file); | 165 | return exynos_drm_subdrv_open(dev, file); |
@@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev, | |||
184 | e->base.destroy(&e->base); | 183 | e->base.destroy(&e->base); |
185 | } | 184 | } |
186 | } | 185 | } |
187 | drm_prime_destroy_file_private(&file->prime); | ||
188 | spin_unlock_irqrestore(&dev->event_lock, flags); | 186 | spin_unlock_irqrestore(&dev->event_lock, flags); |
189 | 187 | ||
190 | exynos_drm_subdrv_close(dev, file); | 188 | exynos_drm_subdrv_close(dev, file); |
@@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = { | |||
241 | .poll = drm_poll, | 239 | .poll = drm_poll, |
242 | .read = drm_read, | 240 | .read = drm_read, |
243 | .unlocked_ioctl = drm_ioctl, | 241 | .unlocked_ioctl = drm_ioctl, |
242 | #ifdef CONFIG_COMPAT | ||
243 | .compat_ioctl = drm_compat_ioctl, | ||
244 | #endif | ||
244 | .release = drm_release, | 245 | .release = drm_release, |
245 | }; | 246 | }; |
246 | 247 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f03..b19cd93e7047 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
831 | } | 831 | } |
832 | 832 | ||
833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
834 | if (!res) { | ||
835 | dev_err(dev, "failed to find registers\n"); | ||
836 | ret = -ENOENT; | ||
837 | goto err_clk; | ||
838 | } | ||
839 | 834 | ||
840 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); | 835 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); |
841 | if (!ctx->regs) { | 836 | if (!ctx->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a037..1065e90d0919 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -129,7 +129,6 @@ struct g2d_runqueue_node { | |||
129 | struct g2d_data { | 129 | struct g2d_data { |
130 | struct device *dev; | 130 | struct device *dev; |
131 | struct clk *gate_clk; | 131 | struct clk *gate_clk; |
132 | struct resource *regs_res; | ||
133 | void __iomem *regs; | 132 | void __iomem *regs; |
134 | int irq; | 133 | int irq; |
135 | struct workqueue_struct *g2d_workq; | 134 | struct workqueue_struct *g2d_workq; |
@@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
751 | struct exynos_drm_subdrv *subdrv; | 750 | struct exynos_drm_subdrv *subdrv; |
752 | int ret; | 751 | int ret; |
753 | 752 | ||
754 | g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); | 753 | g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL); |
755 | if (!g2d) { | 754 | if (!g2d) { |
756 | dev_err(dev, "failed to allocate driver data\n"); | 755 | dev_err(dev, "failed to allocate driver data\n"); |
757 | return -ENOMEM; | 756 | return -ENOMEM; |
@@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
759 | 758 | ||
760 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", | 759 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", |
761 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); | 760 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); |
762 | if (!g2d->runqueue_slab) { | 761 | if (!g2d->runqueue_slab) |
763 | ret = -ENOMEM; | 762 | return -ENOMEM; |
764 | goto err_free_mem; | ||
765 | } | ||
766 | 763 | ||
767 | g2d->dev = dev; | 764 | g2d->dev = dev; |
768 | 765 | ||
@@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
794 | pm_runtime_enable(dev); | 791 | pm_runtime_enable(dev); |
795 | 792 | ||
796 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 793 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
797 | if (!res) { | ||
798 | dev_err(dev, "failed to get I/O memory\n"); | ||
799 | ret = -ENOENT; | ||
800 | goto err_put_clk; | ||
801 | } | ||
802 | 794 | ||
803 | g2d->regs_res = request_mem_region(res->start, resource_size(res), | 795 | g2d->regs = devm_request_and_ioremap(&pdev->dev, res); |
804 | dev_name(dev)); | ||
805 | if (!g2d->regs_res) { | ||
806 | dev_err(dev, "failed to request I/O memory\n"); | ||
807 | ret = -ENOENT; | ||
808 | goto err_put_clk; | ||
809 | } | ||
810 | |||
811 | g2d->regs = ioremap(res->start, resource_size(res)); | ||
812 | if (!g2d->regs) { | 796 | if (!g2d->regs) { |
813 | dev_err(dev, "failed to remap I/O memory\n"); | 797 | dev_err(dev, "failed to remap I/O memory\n"); |
814 | ret = -ENXIO; | 798 | ret = -ENXIO; |
815 | goto err_release_res; | 799 | goto err_put_clk; |
816 | } | 800 | } |
817 | 801 | ||
818 | g2d->irq = platform_get_irq(pdev, 0); | 802 | g2d->irq = platform_get_irq(pdev, 0); |
819 | if (g2d->irq < 0) { | 803 | if (g2d->irq < 0) { |
820 | dev_err(dev, "failed to get irq\n"); | 804 | dev_err(dev, "failed to get irq\n"); |
821 | ret = g2d->irq; | 805 | ret = g2d->irq; |
822 | goto err_unmap_base; | 806 | goto err_put_clk; |
823 | } | 807 | } |
824 | 808 | ||
825 | ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); | 809 | ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, |
810 | "drm_g2d", g2d); | ||
826 | if (ret < 0) { | 811 | if (ret < 0) { |
827 | dev_err(dev, "irq request failed\n"); | 812 | dev_err(dev, "irq request failed\n"); |
828 | goto err_unmap_base; | 813 | goto err_put_clk; |
829 | } | 814 | } |
830 | 815 | ||
831 | platform_set_drvdata(pdev, g2d); | 816 | platform_set_drvdata(pdev, g2d); |
@@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
838 | ret = exynos_drm_subdrv_register(subdrv); | 823 | ret = exynos_drm_subdrv_register(subdrv); |
839 | if (ret < 0) { | 824 | if (ret < 0) { |
840 | dev_err(dev, "failed to register drm g2d device\n"); | 825 | dev_err(dev, "failed to register drm g2d device\n"); |
841 | goto err_free_irq; | 826 | goto err_put_clk; |
842 | } | 827 | } |
843 | 828 | ||
844 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", | 829 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", |
@@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
846 | 831 | ||
847 | return 0; | 832 | return 0; |
848 | 833 | ||
849 | err_free_irq: | ||
850 | free_irq(g2d->irq, g2d); | ||
851 | err_unmap_base: | ||
852 | iounmap(g2d->regs); | ||
853 | err_release_res: | ||
854 | release_resource(g2d->regs_res); | ||
855 | kfree(g2d->regs_res); | ||
856 | err_put_clk: | 834 | err_put_clk: |
857 | pm_runtime_disable(dev); | 835 | pm_runtime_disable(dev); |
858 | clk_put(g2d->gate_clk); | 836 | clk_put(g2d->gate_clk); |
@@ -862,8 +840,6 @@ err_destroy_workqueue: | |||
862 | destroy_workqueue(g2d->g2d_workq); | 840 | destroy_workqueue(g2d->g2d_workq); |
863 | err_destroy_slab: | 841 | err_destroy_slab: |
864 | kmem_cache_destroy(g2d->runqueue_slab); | 842 | kmem_cache_destroy(g2d->runqueue_slab); |
865 | err_free_mem: | ||
866 | kfree(g2d); | ||
867 | return ret; | 843 | return ret; |
868 | } | 844 | } |
869 | 845 | ||
@@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev) | |||
873 | 849 | ||
874 | cancel_work_sync(&g2d->runqueue_work); | 850 | cancel_work_sync(&g2d->runqueue_work); |
875 | exynos_drm_subdrv_unregister(&g2d->subdrv); | 851 | exynos_drm_subdrv_unregister(&g2d->subdrv); |
876 | free_irq(g2d->irq, g2d); | ||
877 | 852 | ||
878 | while (g2d->runqueue_node) { | 853 | while (g2d->runqueue_node) { |
879 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); | 854 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); |
880 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); | 855 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); |
881 | } | 856 | } |
882 | 857 | ||
883 | iounmap(g2d->regs); | ||
884 | release_resource(g2d->regs_res); | ||
885 | kfree(g2d->regs_res); | ||
886 | |||
887 | pm_runtime_disable(&pdev->dev); | 858 | pm_runtime_disable(&pdev->dev); |
888 | clk_put(g2d->gate_clk); | 859 | clk_put(g2d->gate_clk); |
889 | 860 | ||
890 | g2d_fini_cmdlist(g2d); | 861 | g2d_fini_cmdlist(g2d); |
891 | destroy_workqueue(g2d->g2d_workq); | 862 | destroy_workqueue(g2d->g2d_workq); |
892 | kmem_cache_destroy(g2d->runqueue_slab); | 863 | kmem_cache_destroy(g2d->runqueue_slab); |
893 | kfree(g2d); | ||
894 | 864 | ||
895 | return 0; | 865 | return 0; |
896 | } | 866 | } |
@@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev) | |||
924 | } | 894 | } |
925 | #endif | 895 | #endif |
926 | 896 | ||
927 | SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); | 897 | static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); |
928 | 898 | ||
929 | struct platform_driver g2d_driver = { | 899 | struct platform_driver g2d_driver = { |
930 | .probe = g2d_probe, | 900 | .probe = g2d_probe, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c097..a38051c95ec4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -122,7 +122,7 @@ fail: | |||
122 | __free_page(pages[i]); | 122 | __free_page(pages[i]); |
123 | 123 | ||
124 | drm_free_large(pages); | 124 | drm_free_large(pages); |
125 | return ERR_PTR(PTR_ERR(p)); | 125 | return ERR_CAST(p); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, | 128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, |
@@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
662 | */ | 662 | */ |
663 | 663 | ||
664 | args->pitch = args->width * ((args->bpp + 7) / 8); | 664 | args->pitch = args->width * ((args->bpp + 7) / 8); |
665 | args->size = PAGE_ALIGN(args->pitch * args->height); | 665 | args->size = args->pitch * args->height; |
666 | 666 | ||
667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); | 667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); |
668 | if (IS_ERR(exynos_gem_obj)) | 668 | if (IS_ERR(exynos_gem_obj)) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e22..3fdf0b65f47e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) | |||
345 | 345 | ||
346 | DRM_DEBUG_KMS("%s\n", __FILE__); | 346 | DRM_DEBUG_KMS("%s\n", __FILE__); |
347 | 347 | ||
348 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 348 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
349 | if (!ctx) { | 349 | if (!ctx) { |
350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); | 350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); |
351 | return -ENOMEM; | 351 | return -ENOMEM; |
@@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) | |||
371 | DRM_DEBUG_KMS("%s\n", __FILE__); | 371 | DRM_DEBUG_KMS("%s\n", __FILE__); |
372 | 372 | ||
373 | exynos_drm_subdrv_unregister(&ctx->subdrv); | 373 | exynos_drm_subdrv_unregister(&ctx->subdrv); |
374 | kfree(ctx); | ||
375 | 374 | ||
376 | return 0; | 375 | return 0; |
377 | } | 376 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043a..e1f94b746bd7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -29,7 +29,6 @@ static const uint32_t formats[] = { | |||
29 | DRM_FORMAT_XRGB8888, | 29 | DRM_FORMAT_XRGB8888, |
30 | DRM_FORMAT_ARGB8888, | 30 | DRM_FORMAT_ARGB8888, |
31 | DRM_FORMAT_NV12, | 31 | DRM_FORMAT_NV12, |
32 | DRM_FORMAT_NV12M, | ||
33 | DRM_FORMAT_NV12MT, | 32 | DRM_FORMAT_NV12MT, |
34 | }; | 33 | }; |
35 | 34 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd57..537027a74fd5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev) | |||
633 | 633 | ||
634 | DRM_DEBUG_KMS("%s\n", __FILE__); | 634 | DRM_DEBUG_KMS("%s\n", __FILE__); |
635 | 635 | ||
636 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 636 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
637 | if (!ctx) | 637 | if (!ctx) |
638 | return -ENOMEM; | 638 | return -ENOMEM; |
639 | 639 | ||
@@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev) | |||
673 | ctx->raw_edid = NULL; | 673 | ctx->raw_edid = NULL; |
674 | } | 674 | } |
675 | 675 | ||
676 | kfree(ctx); | ||
677 | |||
678 | return 0; | 676 | return 0; |
679 | } | 677 | } |
680 | 678 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207c..a6aea6f3ea1a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2172 | 2172 | ||
2173 | DRM_DEBUG_KMS("HDMI resource init\n"); | 2173 | DRM_DEBUG_KMS("HDMI resource init\n"); |
2174 | 2174 | ||
2175 | memset(res, 0, sizeof *res); | 2175 | memset(res, 0, sizeof(*res)); |
2176 | 2176 | ||
2177 | /* get clocks, power */ | 2177 | /* get clocks, power */ |
2178 | res->hdmi = clk_get(dev, "hdmi"); | 2178 | res->hdmi = clk_get(dev, "hdmi"); |
@@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); | 2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); |
2205 | 2205 | ||
2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * | 2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * |
2207 | sizeof res->regul_bulk[0], GFP_KERNEL); | 2207 | sizeof(res->regul_bulk[0]), GFP_KERNEL); |
2208 | if (!res->regul_bulk) { | 2208 | if (!res->regul_bulk) { |
2209 | DRM_ERROR("failed to get memory for regulators\n"); | 2209 | DRM_ERROR("failed to get memory for regulators\n"); |
2210 | goto fail; | 2210 | goto fail; |
@@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata) | |||
2243 | clk_put(res->sclk_hdmi); | 2243 | clk_put(res->sclk_hdmi); |
2244 | if (!IS_ERR_OR_NULL(res->hdmi)) | 2244 | if (!IS_ERR_OR_NULL(res->hdmi)) |
2245 | clk_put(res->hdmi); | 2245 | clk_put(res->hdmi); |
2246 | memset(res, 0, sizeof *res); | 2246 | memset(res, 0, sizeof(*res)); |
2247 | 2247 | ||
2248 | return 0; | 2248 | return 0; |
2249 | } | 2249 | } |
@@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2312 | } | 2312 | } |
2313 | 2313 | ||
2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2315 | if (!res) { | ||
2316 | DRM_ERROR("failed to find registers\n"); | ||
2317 | ret = -ENOENT; | ||
2318 | goto err_resource; | ||
2319 | } | ||
2320 | 2315 | ||
2321 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); | 2316 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); |
2322 | if (!hdata->regs) { | 2317 | if (!hdata->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81dd..25b97d5e5fcb 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res, | |||
236 | static void vp_default_filter(struct mixer_resources *res) | 236 | static void vp_default_filter(struct mixer_resources *res) |
237 | { | 237 | { |
238 | vp_filter_set(res, VP_POLY8_Y0_LL, | 238 | vp_filter_set(res, VP_POLY8_Y0_LL, |
239 | filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); | 239 | filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8)); |
240 | vp_filter_set(res, VP_POLY4_Y0_LL, | 240 | vp_filter_set(res, VP_POLY4_Y0_LL, |
241 | filter_y_vert_tap4, sizeof filter_y_vert_tap4); | 241 | filter_y_vert_tap4, sizeof(filter_y_vert_tap4)); |
242 | vp_filter_set(res, VP_POLY4_C0_LL, | 242 | vp_filter_set(res, VP_POLY4_C0_LL, |
243 | filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); | 243 | filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) | 246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) |
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6b..cf49ba5a54bf 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c | |||
@@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
476 | .pos = DSPAPOS, | 476 | .pos = DSPAPOS, |
477 | .surf = DSPASURF, | 477 | .surf = DSPASURF, |
478 | .addr = MRST_DSPABASE, | 478 | .addr = MRST_DSPABASE, |
479 | .base = MRST_DSPABASE, | ||
479 | .status = PIPEASTAT, | 480 | .status = PIPEASTAT, |
480 | .linoff = DSPALINOFF, | 481 | .linoff = DSPALINOFF, |
481 | .tileoff = DSPATILEOFF, | 482 | .tileoff = DSPATILEOFF, |
@@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
499 | .pos = DSPBPOS, | 500 | .pos = DSPBPOS, |
500 | .surf = DSPBSURF, | 501 | .surf = DSPBSURF, |
501 | .addr = DSPBBASE, | 502 | .addr = DSPBBASE, |
503 | .base = DSPBBASE, | ||
502 | .status = PIPEBSTAT, | 504 | .status = PIPEBSTAT, |
503 | .linoff = DSPBLINOFF, | 505 | .linoff = DSPBLINOFF, |
504 | .tileoff = DSPBTILEOFF, | 506 | .tileoff = DSPBTILEOFF, |
diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 30dc22a7156c..8033526bb53b 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c | |||
@@ -1362,6 +1362,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, | |||
1362 | (struct drm_connector **) (psb_intel_crtc + 1); | 1362 | (struct drm_connector **) (psb_intel_crtc + 1); |
1363 | psb_intel_crtc->mode_set.num_connectors = 0; | 1363 | psb_intel_crtc->mode_set.num_connectors = 0; |
1364 | psb_intel_cursor_init(dev, psb_intel_crtc); | 1364 | psb_intel_cursor_init(dev, psb_intel_crtc); |
1365 | |||
1366 | /* Set to true so that the pipe is forced off on initial config. */ | ||
1367 | psb_intel_crtc->active = true; | ||
1365 | } | 1368 | } |
1366 | 1369 | ||
1367 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 1370 | int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6e..463ec6871fe9 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = { | |||
115 | .unlocked_ioctl = drm_ioctl, | 115 | .unlocked_ioctl = drm_ioctl, |
116 | .mmap = i810_mmap_buffers, | 116 | .mmap = i810_mmap_buffers, |
117 | .fasync = drm_fasync, | 117 | .fasync = drm_fasync, |
118 | #ifdef CONFIG_COMPAT | ||
119 | .compat_ioctl = drm_compat_ioctl, | ||
120 | #endif | ||
118 | .llseek = noop_llseek, | 121 | .llseek = noop_llseek, |
119 | }; | 122 | }; |
120 | 123 | ||
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d09..48cfcca2b350 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = { | |||
51 | .mmap = drm_mmap, | 51 | .mmap = drm_mmap, |
52 | .poll = drm_poll, | 52 | .poll = drm_poll, |
53 | .fasync = drm_fasync, | 53 | .fasync = drm_fasync, |
54 | #ifdef CONFIG_COMPAT | ||
55 | .compat_ioctl = drm_compat_ioctl, | ||
56 | #endif | ||
54 | .llseek = noop_llseek, | 57 | .llseek = noop_llseek, |
55 | }; | 58 | }; |
56 | 59 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b9..914c0dfabe60 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1587 | spin_lock_init(&dev_priv->irq_lock); | 1587 | spin_lock_init(&dev_priv->irq_lock); |
1588 | spin_lock_init(&dev_priv->error_lock); | 1588 | spin_lock_init(&dev_priv->error_lock); |
1589 | spin_lock_init(&dev_priv->rps_lock); | 1589 | spin_lock_init(&dev_priv->rps_lock); |
1590 | spin_lock_init(&dev_priv->dpio_lock); | ||
1590 | 1591 | ||
1591 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 1592 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
1592 | dev_priv->num_pipe = 3; | 1593 | dev_priv->num_pipe = 3; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ed22612bc847..a24ffbe97c01 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ | 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ |
347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ | 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ |
348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ | 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ |
349 | INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ | ||
349 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ | 350 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ |
350 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ | 351 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ |
352 | INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ | ||
351 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ | 353 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ |
352 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ | 354 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ |
353 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ | 355 | INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ |
356 | INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ | ||
357 | INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
358 | INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
359 | INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ | ||
360 | INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
361 | INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
362 | INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ | ||
363 | INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
364 | INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
365 | INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ | ||
366 | INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
367 | INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
368 | INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ | ||
369 | INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
370 | INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
371 | INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ | ||
372 | INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
373 | INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
374 | INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ | ||
375 | INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
376 | INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
377 | INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ | ||
378 | INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
379 | INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
380 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ | ||
381 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
382 | INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
354 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | 383 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), |
355 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | 384 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), |
356 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | 385 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5c4657a54f97..274d25de521e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2365,6 +2365,10 @@ int i915_gpu_idle(struct drm_device *dev) | |||
2365 | 2365 | ||
2366 | /* Flush everything onto the inactive list. */ | 2366 | /* Flush everything onto the inactive list. */ |
2367 | for_each_ring(ring, dev_priv, i) { | 2367 | for_each_ring(ring, dev_priv, i) { |
2368 | ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); | ||
2369 | if (ret) | ||
2370 | return ret; | ||
2371 | |||
2368 | ret = i915_ring_idle(ring); | 2372 | ret = i915_ring_idle(ring); |
2369 | if (ret) | 2373 | if (ret) |
2370 | return ret; | 2374 | return ret; |
@@ -2372,10 +2376,6 @@ int i915_gpu_idle(struct drm_device *dev) | |||
2372 | /* Is the device fubar? */ | 2376 | /* Is the device fubar? */ |
2373 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) | 2377 | if (WARN_ON(!list_empty(&ring->gpu_write_list))) |
2374 | return -EBUSY; | 2378 | return -EBUSY; |
2375 | |||
2376 | ret = i915_switch_context(ring, NULL, DEFAULT_CONTEXT_ID); | ||
2377 | if (ret) | ||
2378 | return ret; | ||
2379 | } | 2379 | } |
2380 | 2380 | ||
2381 | return 0; | 2381 | return 0; |
@@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, | |||
3242 | { | 3242 | { |
3243 | int ret; | 3243 | int ret; |
3244 | 3244 | ||
3245 | BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); | 3245 | if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT)) |
3246 | return -EBUSY; | ||
3246 | 3247 | ||
3247 | if (obj->gtt_space != NULL) { | 3248 | if (obj->gtt_space != NULL) { |
3248 | if ((alignment && obj->gtt_offset & (alignment - 1)) || | 3249 | if ((alignment && obj->gtt_offset & (alignment - 1)) || |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index da8b01fb1bf8..a9d58d72bb4d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -451,7 +451,6 @@ int i915_switch_context(struct intel_ring_buffer *ring, | |||
451 | struct drm_i915_file_private *file_priv = NULL; | 451 | struct drm_i915_file_private *file_priv = NULL; |
452 | struct i915_hw_context *to; | 452 | struct i915_hw_context *to; |
453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; | 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; |
454 | int ret; | ||
455 | 454 | ||
456 | if (dev_priv->hw_contexts_disabled) | 455 | if (dev_priv->hw_contexts_disabled) |
457 | return 0; | 456 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5af631e788c8..ff2819ea0813 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -291,6 +291,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
291 | target_i915_obj = to_intel_bo(target_obj); | 291 | target_i915_obj = to_intel_bo(target_obj); |
292 | target_offset = target_i915_obj->gtt_offset; | 292 | target_offset = target_i915_obj->gtt_offset; |
293 | 293 | ||
294 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
295 | * pipe_control writes because the gpu doesn't properly redirect them | ||
296 | * through the ppgtt for non_secure batchbuffers. */ | ||
297 | if (unlikely(IS_GEN6(dev) && | ||
298 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
299 | !target_i915_obj->has_global_gtt_mapping)) { | ||
300 | i915_gem_gtt_bind_object(target_i915_obj, | ||
301 | target_i915_obj->cache_level); | ||
302 | } | ||
303 | |||
294 | /* The target buffer should have appeared before us in the | 304 | /* The target buffer should have appeared before us in the |
295 | * exec_object list, so it should have a GTT space bound by now. | 305 | * exec_object list, so it should have a GTT space bound by now. |
296 | */ | 306 | */ |
@@ -399,16 +409,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
399 | io_mapping_unmap_atomic(reloc_page); | 409 | io_mapping_unmap_atomic(reloc_page); |
400 | } | 410 | } |
401 | 411 | ||
402 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
403 | * pipe_control writes because the gpu doesn't properly redirect them | ||
404 | * through the ppgtt for non_secure batchbuffers. */ | ||
405 | if (unlikely(IS_GEN6(dev) && | ||
406 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
407 | !target_i915_obj->has_global_gtt_mapping)) { | ||
408 | i915_gem_gtt_bind_object(target_i915_obj, | ||
409 | target_i915_obj->cache_level); | ||
410 | } | ||
411 | |||
412 | /* and update the user's relocation entry */ | 412 | /* and update the user's relocation entry */ |
413 | reloc->presumed_offset = target_offset; | 413 | reloc->presumed_offset = target_offset; |
414 | 414 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9fd25a435536..60815b861ec2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -72,7 +72,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev) | |||
72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 | 72 | /* ppgtt PDEs reside in the global gtt pagetable, which has 512*1024 |
73 | * entries. For aliasing ppgtt support we just steal them at the end for | 73 | * entries. For aliasing ppgtt support we just steal them at the end for |
74 | * now. */ | 74 | * now. */ |
75 | first_pd_entry_in_global_pt = 512*1024 - I915_PPGTT_PD_ENTRIES; | 75 | first_pd_entry_in_global_pt = dev_priv->mm.gtt->gtt_total_entries - I915_PPGTT_PD_ENTRIES; |
76 | 76 | ||
77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); | 77 | ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); |
78 | if (!ppgtt) | 78 | if (!ppgtt) |
@@ -261,7 +261,10 @@ void i915_ppgtt_bind_object(struct i915_hw_ppgtt *ppgtt, | |||
261 | pte_flags |= GEN6_PTE_CACHE_LLC; | 261 | pte_flags |= GEN6_PTE_CACHE_LLC; |
262 | break; | 262 | break; |
263 | case I915_CACHE_NONE: | 263 | case I915_CACHE_NONE: |
264 | pte_flags |= GEN6_PTE_UNCACHED; | 264 | if (IS_HASWELL(dev)) |
265 | pte_flags |= HSW_PTE_UNCACHED; | ||
266 | else | ||
267 | pte_flags |= GEN6_PTE_UNCACHED; | ||
265 | break; | 268 | break; |
266 | default: | 269 | default: |
267 | BUG(); | 270 | BUG(); |
@@ -361,7 +364,8 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | |||
361 | struct drm_device *dev = obj->base.dev; | 364 | struct drm_device *dev = obj->base.dev; |
362 | struct drm_i915_private *dev_priv = dev->dev_private; | 365 | struct drm_i915_private *dev_priv = dev->dev_private; |
363 | 366 | ||
364 | if (dev_priv->mm.gtt->needs_dmar) | 367 | /* don't map imported dma buf objects */ |
368 | if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table) | ||
365 | return intel_gtt_map_memory(obj->pages, | 369 | return intel_gtt_map_memory(obj->pages, |
366 | obj->base.size >> PAGE_SHIFT, | 370 | obj->base.size >> PAGE_SHIFT, |
367 | &obj->sg_list, | 371 | &obj->sg_list, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9d..5249640cce13 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev) | |||
2700 | dev->driver->irq_handler = i8xx_irq_handler; | 2700 | dev->driver->irq_handler = i8xx_irq_handler; |
2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; | 2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; |
2702 | } else if (INTEL_INFO(dev)->gen == 3) { | 2702 | } else if (INTEL_INFO(dev)->gen == 3) { |
2703 | /* IIR "flip pending" means done if this bit is set */ | ||
2704 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
2705 | |||
2706 | dev->driver->irq_preinstall = i915_irq_preinstall; | 2703 | dev->driver->irq_preinstall = i915_irq_preinstall; |
2707 | dev->driver->irq_postinstall = i915_irq_postinstall; | 2704 | dev->driver->irq_postinstall = i915_irq_postinstall; |
2708 | dev->driver->irq_uninstall = i915_irq_uninstall; | 2705 | dev->driver->irq_uninstall = i915_irq_uninstall; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index acc99b21e0b6..28725ce5b82c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -115,6 +115,7 @@ | |||
115 | 115 | ||
116 | #define GEN6_PTE_VALID (1 << 0) | 116 | #define GEN6_PTE_VALID (1 << 0) |
117 | #define GEN6_PTE_UNCACHED (1 << 1) | 117 | #define GEN6_PTE_UNCACHED (1 << 1) |
118 | #define HSW_PTE_UNCACHED (0) | ||
118 | #define GEN6_PTE_CACHE_LLC (2 << 1) | 119 | #define GEN6_PTE_CACHE_LLC (2 << 1) |
119 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) | 120 | #define GEN6_PTE_CACHE_LLC_MLC (3 << 1) |
120 | #define GEN6_PTE_CACHE_BITS (3 << 1) | 121 | #define GEN6_PTE_CACHE_BITS (3 << 1) |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 2f5388af8df9..7631807a2788 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "intel_drv.h" | 32 | #include "intel_drv.h" |
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | 34 | ||
35 | #ifdef CONFIG_PM | ||
35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 36 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
36 | { | 37 | { |
37 | struct drm_i915_private *dev_priv = dev->dev_private; | 38 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -224,3 +225,14 @@ void i915_teardown_sysfs(struct drm_device *dev) | |||
224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | 225 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); |
225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 226 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
226 | } | 227 | } |
228 | #else | ||
229 | void i915_setup_sysfs(struct drm_device *dev) | ||
230 | { | ||
231 | return; | ||
232 | } | ||
233 | |||
234 | void i915_teardown_sysfs(struct drm_device *dev) | ||
235 | { | ||
236 | return; | ||
237 | } | ||
238 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 7ed4a41c3965..23bdc8cd1458 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -326,6 +326,36 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
326 | return ret; | 326 | return ret; |
327 | } | 327 | } |
328 | 328 | ||
329 | static struct edid *intel_crt_get_edid(struct drm_connector *connector, | ||
330 | struct i2c_adapter *i2c) | ||
331 | { | ||
332 | struct edid *edid; | ||
333 | |||
334 | edid = drm_get_edid(connector, i2c); | ||
335 | |||
336 | if (!edid && !intel_gmbus_is_forced_bit(i2c)) { | ||
337 | DRM_DEBUG_KMS("CRT GMBUS EDID read failed, retry using GPIO bit-banging\n"); | ||
338 | intel_gmbus_force_bit(i2c, true); | ||
339 | edid = drm_get_edid(connector, i2c); | ||
340 | intel_gmbus_force_bit(i2c, false); | ||
341 | } | ||
342 | |||
343 | return edid; | ||
344 | } | ||
345 | |||
346 | /* local version of intel_ddc_get_modes() to use intel_crt_get_edid() */ | ||
347 | static int intel_crt_ddc_get_modes(struct drm_connector *connector, | ||
348 | struct i2c_adapter *adapter) | ||
349 | { | ||
350 | struct edid *edid; | ||
351 | |||
352 | edid = intel_crt_get_edid(connector, adapter); | ||
353 | if (!edid) | ||
354 | return 0; | ||
355 | |||
356 | return intel_connector_update_modes(connector, edid); | ||
357 | } | ||
358 | |||
329 | static bool intel_crt_detect_ddc(struct drm_connector *connector) | 359 | static bool intel_crt_detect_ddc(struct drm_connector *connector) |
330 | { | 360 | { |
331 | struct intel_crt *crt = intel_attached_crt(connector); | 361 | struct intel_crt *crt = intel_attached_crt(connector); |
@@ -336,7 +366,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) | |||
336 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); | 366 | BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG); |
337 | 367 | ||
338 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | 368 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
339 | edid = drm_get_edid(connector, i2c); | 369 | edid = intel_crt_get_edid(connector, i2c); |
340 | 370 | ||
341 | if (edid) { | 371 | if (edid) { |
342 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; | 372 | bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; |
@@ -544,13 +574,13 @@ static int intel_crt_get_modes(struct drm_connector *connector) | |||
544 | struct i2c_adapter *i2c; | 574 | struct i2c_adapter *i2c; |
545 | 575 | ||
546 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); | 576 | i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); |
547 | ret = intel_ddc_get_modes(connector, i2c); | 577 | ret = intel_crt_ddc_get_modes(connector, i2c); |
548 | if (ret || !IS_G4X(dev)) | 578 | if (ret || !IS_G4X(dev)) |
549 | return ret; | 579 | return ret; |
550 | 580 | ||
551 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | 581 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ |
552 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); | 582 | i2c = intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPB); |
553 | return intel_ddc_get_modes(connector, i2c); | 583 | return intel_crt_ddc_get_modes(connector, i2c); |
554 | } | 584 | } |
555 | 585 | ||
556 | static int intel_crt_set_property(struct drm_connector *connector, | 586 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6159765f1eb..c040aee1341c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -869,6 +869,7 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
869 | unsigned long bestppm, ppm, absppm; | 869 | unsigned long bestppm, ppm, absppm; |
870 | int dotclk, flag; | 870 | int dotclk, flag; |
871 | 871 | ||
872 | flag = 0; | ||
872 | dotclk = target * 1000; | 873 | dotclk = target * 1000; |
873 | bestppm = 1000000; | 874 | bestppm = 1000000; |
874 | ppm = absppm = 0; | 875 | ppm = absppm = 0; |
@@ -1375,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | |||
1375 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1376 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1376 | reg, pipe_name(pipe)); | 1377 | reg, pipe_name(pipe)); |
1377 | 1378 | ||
1378 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1379 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 |
1380 | && (val & DP_PIPEB_SELECT), | ||
1379 | "IBX PCH dp port still using transcoder B\n"); | 1381 | "IBX PCH dp port still using transcoder B\n"); |
1380 | } | 1382 | } |
1381 | 1383 | ||
@@ -1383,11 +1385,12 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1383 | enum pipe pipe, int reg) | 1385 | enum pipe pipe, int reg) |
1384 | { | 1386 | { |
1385 | u32 val = I915_READ(reg); | 1387 | u32 val = I915_READ(reg); |
1386 | WARN(hdmi_pipe_enabled(dev_priv, val, pipe), | 1388 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
1387 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1389 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1388 | reg, pipe_name(pipe)); | 1390 | reg, pipe_name(pipe)); |
1389 | 1391 | ||
1390 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1392 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 |
1393 | && (val & SDVO_PIPE_B_SELECT), | ||
1391 | "IBX PCH hdmi port still using transcoder B\n"); | 1394 | "IBX PCH hdmi port still using transcoder B\n"); |
1392 | } | 1395 | } |
1393 | 1396 | ||
@@ -1403,13 +1406,13 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | |||
1403 | 1406 | ||
1404 | reg = PCH_ADPA; | 1407 | reg = PCH_ADPA; |
1405 | val = I915_READ(reg); | 1408 | val = I915_READ(reg); |
1406 | WARN(adpa_pipe_enabled(dev_priv, val, pipe), | 1409 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
1407 | "PCH VGA enabled on transcoder %c, should be disabled\n", | 1410 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
1408 | pipe_name(pipe)); | 1411 | pipe_name(pipe)); |
1409 | 1412 | ||
1410 | reg = PCH_LVDS; | 1413 | reg = PCH_LVDS; |
1411 | val = I915_READ(reg); | 1414 | val = I915_READ(reg); |
1412 | WARN(lvds_pipe_enabled(dev_priv, val, pipe), | 1415 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
1413 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | 1416 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1414 | pipe_name(pipe)); | 1417 | pipe_name(pipe)); |
1415 | 1418 | ||
@@ -1871,7 +1874,7 @@ static void disable_pch_hdmi(struct drm_i915_private *dev_priv, | |||
1871 | enum pipe pipe, int reg) | 1874 | enum pipe pipe, int reg) |
1872 | { | 1875 | { |
1873 | u32 val = I915_READ(reg); | 1876 | u32 val = I915_READ(reg); |
1874 | if (hdmi_pipe_enabled(dev_priv, val, pipe)) { | 1877 | if (hdmi_pipe_enabled(dev_priv, pipe, val)) { |
1875 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", | 1878 | DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", |
1876 | reg, pipe); | 1879 | reg, pipe); |
1877 | I915_WRITE(reg, val & ~PORT_ENABLE); | 1880 | I915_WRITE(reg, val & ~PORT_ENABLE); |
@@ -1893,12 +1896,12 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, | |||
1893 | 1896 | ||
1894 | reg = PCH_ADPA; | 1897 | reg = PCH_ADPA; |
1895 | val = I915_READ(reg); | 1898 | val = I915_READ(reg); |
1896 | if (adpa_pipe_enabled(dev_priv, val, pipe)) | 1899 | if (adpa_pipe_enabled(dev_priv, pipe, val)) |
1897 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); | 1900 | I915_WRITE(reg, val & ~ADPA_DAC_ENABLE); |
1898 | 1901 | ||
1899 | reg = PCH_LVDS; | 1902 | reg = PCH_LVDS; |
1900 | val = I915_READ(reg); | 1903 | val = I915_READ(reg); |
1901 | if (lvds_pipe_enabled(dev_priv, val, pipe)) { | 1904 | if (lvds_pipe_enabled(dev_priv, pipe, val)) { |
1902 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); | 1905 | DRM_DEBUG_KMS("disable lvds on pipe %d val 0x%08x\n", pipe, val); |
1903 | I915_WRITE(reg, val & ~LVDS_PORT_EN); | 1906 | I915_WRITE(reg, val & ~LVDS_PORT_EN); |
1904 | POSTING_READ(reg); | 1907 | POSTING_READ(reg); |
@@ -3753,17 +3756,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
3753 | continue; | 3756 | continue; |
3754 | } | 3757 | } |
3755 | 3758 | ||
3756 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
3757 | /* Use VBT settings if we have an eDP panel */ | ||
3758 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
3759 | |||
3760 | if (edp_bpc < display_bpc) { | ||
3761 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
3762 | display_bpc = edp_bpc; | ||
3763 | } | ||
3764 | continue; | ||
3765 | } | ||
3766 | |||
3767 | /* Not one of the known troublemakers, check the EDID */ | 3759 | /* Not one of the known troublemakers, check the EDID */ |
3768 | list_for_each_entry(connector, &dev->mode_config.connector_list, | 3760 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
3769 | head) { | 3761 | head) { |
@@ -4199,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc, | |||
4199 | POSTING_READ(DPLL(pipe)); | 4191 | POSTING_READ(DPLL(pipe)); |
4200 | udelay(150); | 4192 | udelay(150); |
4201 | 4193 | ||
4202 | I915_WRITE(DPLL(pipe), dpll); | ||
4203 | |||
4204 | /* Wait for the clocks to stabilize. */ | ||
4205 | POSTING_READ(DPLL(pipe)); | ||
4206 | udelay(150); | ||
4207 | |||
4208 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 4194 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
4209 | * This is an exception to the general rule that mode_set doesn't turn | 4195 | * This is an exception to the general rule that mode_set doesn't turn |
4210 | * things on. | 4196 | * things on. |
@@ -4212,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc, | |||
4212 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 4198 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
4213 | intel_update_lvds(crtc, clock, adjusted_mode); | 4199 | intel_update_lvds(crtc, clock, adjusted_mode); |
4214 | 4200 | ||
4201 | I915_WRITE(DPLL(pipe), dpll); | ||
4202 | |||
4203 | /* Wait for the clocks to stabilize. */ | ||
4204 | POSTING_READ(DPLL(pipe)); | ||
4205 | udelay(150); | ||
4206 | |||
4215 | /* The pixel multiplier can only be updated once the | 4207 | /* The pixel multiplier can only be updated once the |
4216 | * DPLL is enabled and the clocks are stable. | 4208 | * DPLL is enabled and the clocks are stable. |
4217 | * | 4209 | * |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a56b9ab0f58..ace757af9133 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1174,10 +1174,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); |
1175 | 1175 | ||
1176 | pp = ironlake_get_pp_control(dev_priv); | 1176 | pp = ironlake_get_pp_control(dev_priv); |
1177 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1177 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1178 | * panels get very unhappy and cease to work. */ | ||
1179 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | ||
1178 | I915_WRITE(PCH_PP_CONTROL, pp); | 1180 | I915_WRITE(PCH_PP_CONTROL, pp); |
1179 | POSTING_READ(PCH_PP_CONTROL); | 1181 | POSTING_READ(PCH_PP_CONTROL); |
1180 | 1182 | ||
1183 | intel_dp->want_panel_vdd = false; | ||
1184 | |||
1181 | ironlake_wait_panel_off(intel_dp); | 1185 | ironlake_wait_panel_off(intel_dp); |
1182 | } | 1186 | } |
1183 | 1187 | ||
@@ -1287,11 +1291,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
1287 | * ensure that we have vdd while we switch off the panel. */ | 1291 | * ensure that we have vdd while we switch off the panel. */ |
1288 | ironlake_edp_panel_vdd_on(intel_dp); | 1292 | ironlake_edp_panel_vdd_on(intel_dp); |
1289 | ironlake_edp_backlight_off(intel_dp); | 1293 | ironlake_edp_backlight_off(intel_dp); |
1290 | ironlake_edp_panel_off(intel_dp); | ||
1291 | |||
1292 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1294 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1295 | ironlake_edp_panel_off(intel_dp); | ||
1293 | intel_dp_link_down(intel_dp); | 1296 | intel_dp_link_down(intel_dp); |
1294 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
1295 | } | 1297 | } |
1296 | 1298 | ||
1297 | static void intel_dp_commit(struct drm_encoder *encoder) | 1299 | static void intel_dp_commit(struct drm_encoder *encoder) |
@@ -1326,11 +1328,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1326 | /* Switching the panel off requires vdd. */ | 1328 | /* Switching the panel off requires vdd. */ |
1327 | ironlake_edp_panel_vdd_on(intel_dp); | 1329 | ironlake_edp_panel_vdd_on(intel_dp); |
1328 | ironlake_edp_backlight_off(intel_dp); | 1330 | ironlake_edp_backlight_off(intel_dp); |
1329 | ironlake_edp_panel_off(intel_dp); | ||
1330 | |||
1331 | intel_dp_sink_dpms(intel_dp, mode); | 1331 | intel_dp_sink_dpms(intel_dp, mode); |
1332 | ironlake_edp_panel_off(intel_dp); | ||
1332 | intel_dp_link_down(intel_dp); | 1333 | intel_dp_link_down(intel_dp); |
1333 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
1334 | 1334 | ||
1335 | if (is_cpu_edp(intel_dp)) | 1335 | if (is_cpu_edp(intel_dp)) |
1336 | ironlake_edp_pll_off(encoder); | 1336 | ironlake_edp_pll_off(encoder); |
@@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2533 | break; | 2533 | break; |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2537 | |||
2538 | /* Cache some DPCD data in the eDP case */ | 2536 | /* Cache some DPCD data in the eDP case */ |
2539 | if (is_edp(intel_dp)) { | 2537 | if (is_edp(intel_dp)) { |
2540 | bool ret; | ||
2541 | struct edp_power_seq cur, vbt; | 2538 | struct edp_power_seq cur, vbt; |
2542 | u32 pp_on, pp_off, pp_div; | 2539 | u32 pp_on, pp_off, pp_div; |
2543 | struct edid *edid; | ||
2544 | 2540 | ||
2545 | pp_on = I915_READ(PCH_PP_ON_DELAYS); | 2541 | pp_on = I915_READ(PCH_PP_ON_DELAYS); |
2546 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); | 2542 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); |
@@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2591 | 2587 | ||
2592 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | 2588 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", |
2593 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | 2589 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); |
2590 | } | ||
2591 | |||
2592 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2593 | |||
2594 | if (is_edp(intel_dp)) { | ||
2595 | bool ret; | ||
2596 | struct edid *edid; | ||
2594 | 2597 | ||
2595 | ironlake_edp_panel_vdd_on(intel_dp); | 2598 | ironlake_edp_panel_vdd_on(intel_dp); |
2596 | ret = intel_dp_get_dpcd(intel_dp); | 2599 | ret = intel_dp_get_dpcd(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 84353559441c..cd54cf88a28f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -46,15 +46,16 @@ | |||
46 | }) | 46 | }) |
47 | 47 | ||
48 | #define wait_for_atomic_us(COND, US) ({ \ | 48 | #define wait_for_atomic_us(COND, US) ({ \ |
49 | int i, ret__ = -ETIMEDOUT; \ | 49 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US); \ |
50 | for (i = 0; i < (US); i++) { \ | 50 | int ret__ = 0; \ |
51 | if ((COND)) { \ | 51 | while (!(COND)) { \ |
52 | ret__ = 0; \ | 52 | if (time_after(jiffies, timeout__)) { \ |
53 | break; \ | 53 | ret__ = -ETIMEDOUT; \ |
54 | } \ | 54 | break; \ |
55 | udelay(1); \ | 55 | } \ |
56 | } \ | 56 | cpu_relax(); \ |
57 | ret__; \ | 57 | } \ |
58 | ret__; \ | ||
58 | }) | 59 | }) |
59 | 60 | ||
60 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 61 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
@@ -341,6 +342,8 @@ struct intel_fbc_work { | |||
341 | int interval; | 342 | int interval; |
342 | }; | 343 | }; |
343 | 344 | ||
345 | int intel_connector_update_modes(struct drm_connector *connector, | ||
346 | struct edid *edid); | ||
344 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); | 347 | int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter); |
345 | 348 | ||
346 | extern void intel_attach_force_audio_property(struct drm_connector *connector); | 349 | extern void intel_attach_force_audio_property(struct drm_connector *connector); |
@@ -380,7 +383,6 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
380 | const struct drm_display_mode *mode, | 383 | const struct drm_display_mode *mode, |
381 | struct drm_display_mode *adjusted_mode); | 384 | struct drm_display_mode *adjusted_mode); |
382 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 385 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
383 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | ||
384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 386 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
385 | extern int intel_panel_setup_backlight(struct drm_device *dev); | 387 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
386 | extern void intel_panel_enable_backlight(struct drm_device *dev, | 388 | extern void intel_panel_enable_backlight(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 98f602427eb8..12dc3308ab8c 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
609 | u32 temp; | 609 | u32 temp; |
610 | u32 enable_bits = SDVO_ENABLE; | 610 | u32 enable_bits = SDVO_ENABLE; |
611 | 611 | ||
612 | if (intel_hdmi->has_audio) | 612 | if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON) |
613 | enable_bits |= SDVO_AUDIO_ENABLE; | 613 | enable_bits |= SDVO_AUDIO_ENABLE; |
614 | 614 | ||
615 | temp = I915_READ(intel_hdmi->sdvox_reg); | 615 | temp = I915_READ(intel_hdmi->sdvox_reg); |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 1991a4408cf9..b9755f6378d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -486,9 +486,6 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
486 | bus->dev_priv = dev_priv; | 486 | bus->dev_priv = dev_priv; |
487 | 487 | ||
488 | bus->adapter.algo = &gmbus_algorithm; | 488 | bus->adapter.algo = &gmbus_algorithm; |
489 | ret = i2c_add_adapter(&bus->adapter); | ||
490 | if (ret) | ||
491 | goto err; | ||
492 | 489 | ||
493 | /* By default use a conservative clock rate */ | 490 | /* By default use a conservative clock rate */ |
494 | bus->reg0 = port | GMBUS_RATE_100KHZ; | 491 | bus->reg0 = port | GMBUS_RATE_100KHZ; |
@@ -498,6 +495,10 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
498 | bus->force_bit = true; | 495 | bus->force_bit = true; |
499 | 496 | ||
500 | intel_gpio_setup(bus, port); | 497 | intel_gpio_setup(bus, port); |
498 | |||
499 | ret = i2c_add_adapter(&bus->adapter); | ||
500 | if (ret) | ||
501 | goto err; | ||
501 | } | 502 | } |
502 | 503 | ||
503 | intel_i2c_reset(dev_priv->dev); | 504 | intel_i2c_reset(dev_priv->dev); |
@@ -540,9 +541,6 @@ void intel_teardown_gmbus(struct drm_device *dev) | |||
540 | struct drm_i915_private *dev_priv = dev->dev_private; | 541 | struct drm_i915_private *dev_priv = dev->dev_private; |
541 | int i; | 542 | int i; |
542 | 543 | ||
543 | if (dev_priv->gmbus == NULL) | ||
544 | return; | ||
545 | |||
546 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 544 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
547 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 545 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
548 | i2c_del_adapter(&bus->adapter); | 546 | i2c_del_adapter(&bus->adapter); |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e05c0d3e3440..e9a6f6aaed85 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -780,6 +780,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), | 780 | DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"), |
781 | }, | 781 | }, |
782 | }, | 782 | }, |
783 | { | ||
784 | .callback = intel_no_lvds_dmi_callback, | ||
785 | .ident = "Gigabyte GA-D525TUD", | ||
786 | .matches = { | ||
787 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), | ||
788 | DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), | ||
789 | }, | ||
790 | }, | ||
783 | 791 | ||
784 | { } /* terminating entry */ | 792 | { } /* terminating entry */ |
785 | }; | 793 | }; |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 45848b9b670b..29b72593fbb2 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -33,6 +33,25 @@ | |||
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * intel_connector_update_modes - update connector from edid | ||
37 | * @connector: DRM connector device to use | ||
38 | * @edid: previously read EDID information | ||
39 | */ | ||
40 | int intel_connector_update_modes(struct drm_connector *connector, | ||
41 | struct edid *edid) | ||
42 | { | ||
43 | int ret; | ||
44 | |||
45 | drm_mode_connector_update_edid_property(connector, edid); | ||
46 | ret = drm_add_edid_modes(connector, edid); | ||
47 | drm_edid_to_eld(connector, edid); | ||
48 | connector->display_info.raw_edid = NULL; | ||
49 | kfree(edid); | ||
50 | |||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | /** | ||
36 | * intel_ddc_get_modes - get modelist from monitor | 55 | * intel_ddc_get_modes - get modelist from monitor |
37 | * @connector: DRM connector device to use | 56 | * @connector: DRM connector device to use |
38 | * @adapter: i2c adapter | 57 | * @adapter: i2c adapter |
@@ -43,18 +62,12 @@ int intel_ddc_get_modes(struct drm_connector *connector, | |||
43 | struct i2c_adapter *adapter) | 62 | struct i2c_adapter *adapter) |
44 | { | 63 | { |
45 | struct edid *edid; | 64 | struct edid *edid; |
46 | int ret = 0; | ||
47 | 65 | ||
48 | edid = drm_get_edid(connector, adapter); | 66 | edid = drm_get_edid(connector, adapter); |
49 | if (edid) { | 67 | if (!edid) |
50 | drm_mode_connector_update_edid_property(connector, edid); | 68 | return 0; |
51 | ret = drm_add_edid_modes(connector, edid); | ||
52 | drm_edid_to_eld(connector, edid); | ||
53 | connector->display_info.raw_edid = NULL; | ||
54 | kfree(edid); | ||
55 | } | ||
56 | 69 | ||
57 | return ret; | 70 | return intel_connector_update_modes(connector, edid); |
58 | } | 71 | } |
59 | 72 | ||
60 | static const struct drm_prop_enum_list force_audio_names[] = { | 73 | static const struct drm_prop_enum_list force_audio_names[] = { |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 10c7d39034e1..e019b2369861 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) | |||
162 | return val; | 162 | return val; |
163 | } | 163 | } |
164 | 164 | ||
165 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | 165 | static u32 _intel_panel_get_max_backlight(struct drm_device *dev) |
166 | { | 166 | { |
167 | struct drm_i915_private *dev_priv = dev->dev_private; | 167 | struct drm_i915_private *dev_priv = dev->dev_private; |
168 | u32 max; | 168 | u32 max; |
169 | 169 | ||
170 | max = i915_read_blc_pwm_ctl(dev_priv); | 170 | max = i915_read_blc_pwm_ctl(dev_priv); |
171 | if (max == 0) { | ||
172 | /* XXX add code here to query mode clock or hardware clock | ||
173 | * and program max PWM appropriately. | ||
174 | */ | ||
175 | pr_warn_once("fixme: max PWM is zero\n"); | ||
176 | return 1; | ||
177 | } | ||
178 | 171 | ||
179 | if (HAS_PCH_SPLIT(dev)) { | 172 | if (HAS_PCH_SPLIT(dev)) { |
180 | max >>= 16; | 173 | max >>= 16; |
@@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) | |||
188 | max *= 0xff; | 181 | max *= 0xff; |
189 | } | 182 | } |
190 | 183 | ||
184 | return max; | ||
185 | } | ||
186 | |||
187 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | ||
188 | { | ||
189 | u32 max; | ||
190 | |||
191 | max = _intel_panel_get_max_backlight(dev); | ||
192 | if (max == 0) { | ||
193 | /* XXX add code here to query mode clock or hardware clock | ||
194 | * and program max PWM appropriately. | ||
195 | */ | ||
196 | pr_warn_once("fixme: max PWM is zero\n"); | ||
197 | return 1; | ||
198 | } | ||
199 | |||
191 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); | 200 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); |
192 | return max; | 201 | return max; |
193 | } | 202 | } |
@@ -213,7 +222,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
213 | return val; | 222 | return val; |
214 | } | 223 | } |
215 | 224 | ||
216 | u32 intel_panel_get_backlight(struct drm_device *dev) | 225 | static u32 intel_panel_get_backlight(struct drm_device *dev) |
217 | { | 226 | { |
218 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
219 | u32 val; | 228 | u32 val; |
@@ -311,9 +320,6 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
311 | if (dev_priv->backlight_level == 0) | 320 | if (dev_priv->backlight_level == 0) |
312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | 321 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); |
313 | 322 | ||
314 | dev_priv->backlight_enabled = true; | ||
315 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
316 | |||
317 | if (INTEL_INFO(dev)->gen >= 4) { | 323 | if (INTEL_INFO(dev)->gen >= 4) { |
318 | uint32_t reg, tmp; | 324 | uint32_t reg, tmp; |
319 | 325 | ||
@@ -326,7 +332,7 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
326 | * we don't track the backlight dpms state, hence check whether | 332 | * we don't track the backlight dpms state, hence check whether |
327 | * we have to do anything first. */ | 333 | * we have to do anything first. */ |
328 | if (tmp & BLM_PWM_ENABLE) | 334 | if (tmp & BLM_PWM_ENABLE) |
329 | return; | 335 | goto set_level; |
330 | 336 | ||
331 | if (dev_priv->num_pipe == 3) | 337 | if (dev_priv->num_pipe == 3) |
332 | tmp &= ~BLM_PIPE_SELECT_IVB; | 338 | tmp &= ~BLM_PIPE_SELECT_IVB; |
@@ -347,6 +353,14 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | 353 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); |
348 | } | 354 | } |
349 | } | 355 | } |
356 | |||
357 | set_level: | ||
358 | /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. | ||
359 | * BLC_PWM_CPU_CTL may be cleared to zero automatically when these | ||
360 | * registers are set. | ||
361 | */ | ||
362 | dev_priv->backlight_enabled = true; | ||
363 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
350 | } | 364 | } |
351 | 365 | ||
352 | static void intel_panel_init_backlight(struct drm_device *dev) | 366 | static void intel_panel_init_backlight(struct drm_device *dev) |
@@ -419,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
419 | 433 | ||
420 | memset(&props, 0, sizeof(props)); | 434 | memset(&props, 0, sizeof(props)); |
421 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
422 | props.max_brightness = intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
437 | if (props.max_brightness == 0) { | ||
438 | DRM_ERROR("Failed to get maximum backlight value\n"); | ||
439 | return -ENODEV; | ||
440 | } | ||
423 | dev_priv->backlight = | 441 | dev_priv->backlight = |
424 | backlight_device_register("intel_backlight", | 442 | backlight_device_register("intel_backlight", |
425 | &connector->kdev, dev, | 443 | &connector->kdev, dev, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 94aabcaa3a67..ba8a27b1757a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -2441,17 +2441,10 @@ static void gen6_enable_rps(struct drm_device *dev) | |||
2441 | dev_priv->max_delay << 24 | | 2441 | dev_priv->max_delay << 24 | |
2442 | dev_priv->min_delay << 16); | 2442 | dev_priv->min_delay << 16); |
2443 | 2443 | ||
2444 | if (IS_HASWELL(dev)) { | 2444 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); |
2445 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400); | 2445 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); |
2446 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000); | 2446 | I915_WRITE(GEN6_RP_UP_EI, 66000); |
2447 | I915_WRITE(GEN6_RP_UP_EI, 66000); | 2447 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); |
2448 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); | ||
2449 | } else { | ||
2450 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); | ||
2451 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); | ||
2452 | I915_WRITE(GEN6_RP_UP_EI, 100000); | ||
2453 | I915_WRITE(GEN6_RP_DOWN_EI, 5000000); | ||
2454 | } | ||
2455 | 2448 | ||
2456 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | 2449 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
2457 | I915_WRITE(GEN6_RP_CONTROL, | 2450 | I915_WRITE(GEN6_RP_CONTROL, |
@@ -3679,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) | |||
3679 | 3672 | ||
3680 | if (IS_PINEVIEW(dev)) | 3673 | if (IS_PINEVIEW(dev)) |
3681 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); | 3674 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); |
3675 | |||
3676 | /* IIR "flip pending" means done if this bit is set */ | ||
3677 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
3682 | } | 3678 | } |
3683 | 3679 | ||
3684 | static void i85x_init_clock_gating(struct drm_device *dev) | 3680 | static void i85x_init_clock_gating(struct drm_device *dev) |
@@ -3963,6 +3959,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
3963 | DRM_ERROR("Force wake wait timed out\n"); | 3959 | DRM_ERROR("Force wake wait timed out\n"); |
3964 | 3960 | ||
3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | 3961 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
3962 | POSTING_READ(FORCEWAKE); | ||
3966 | 3963 | ||
3967 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3964 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
3968 | DRM_ERROR("Force wake wait timed out\n"); | 3965 | DRM_ERROR("Force wake wait timed out\n"); |
@@ -3983,6 +3980,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
3983 | DRM_ERROR("Force wake wait timed out\n"); | 3980 | DRM_ERROR("Force wake wait timed out\n"); |
3984 | 3981 | ||
3985 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | 3982 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); |
3983 | POSTING_READ(FORCEWAKE_MT); | ||
3986 | 3984 | ||
3987 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3985 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
3988 | DRM_ERROR("Force wake wait timed out\n"); | 3986 | DRM_ERROR("Force wake wait timed out\n"); |
@@ -4018,14 +4016,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | |||
4018 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 4016 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
4019 | { | 4017 | { |
4020 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 4018 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
4021 | /* The below doubles as a POSTING_READ */ | 4019 | POSTING_READ(FORCEWAKE); |
4022 | gen6_gt_check_fifodbg(dev_priv); | 4020 | gen6_gt_check_fifodbg(dev_priv); |
4023 | } | 4021 | } |
4024 | 4022 | ||
4025 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | 4023 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
4026 | { | 4024 | { |
4027 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | 4025 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); |
4028 | /* The below doubles as a POSTING_READ */ | 4026 | POSTING_READ(FORCEWAKE_MT); |
4029 | gen6_gt_check_fifodbg(dev_priv); | 4027 | gen6_gt_check_fifodbg(dev_priv); |
4030 | } | 4028 | } |
4031 | 4029 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bf0195a96d53..e2a73b38abe9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -227,31 +227,36 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
227 | * number of bits based on the write domains has little performance | 227 | * number of bits based on the write domains has little performance |
228 | * impact. | 228 | * impact. |
229 | */ | 229 | */ |
230 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | 230 | if (flush_domains) { |
231 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | 231 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; |
232 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | 232 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; |
233 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | 233 | /* |
234 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | 234 | * Ensure that any following seqno writes only happen |
235 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 235 | * when the render cache is indeed flushed. |
236 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 236 | */ |
237 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
238 | /* | ||
239 | * Ensure that any following seqno writes only happen when the render | ||
240 | * cache is indeed flushed (but only if the caller actually wants that). | ||
241 | */ | ||
242 | if (flush_domains) | ||
243 | flags |= PIPE_CONTROL_CS_STALL; | 237 | flags |= PIPE_CONTROL_CS_STALL; |
238 | } | ||
239 | if (invalidate_domains) { | ||
240 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
241 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
242 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
243 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
244 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
245 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
246 | /* | ||
247 | * TLB invalidate requires a post-sync write. | ||
248 | */ | ||
249 | flags |= PIPE_CONTROL_QW_WRITE; | ||
250 | } | ||
244 | 251 | ||
245 | ret = intel_ring_begin(ring, 6); | 252 | ret = intel_ring_begin(ring, 4); |
246 | if (ret) | 253 | if (ret) |
247 | return ret; | 254 | return ret; |
248 | 255 | ||
249 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | 256 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); |
250 | intel_ring_emit(ring, flags); | 257 | intel_ring_emit(ring, flags); |
251 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | 258 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); |
252 | intel_ring_emit(ring, 0); /* lower dword */ | 259 | intel_ring_emit(ring, 0); |
253 | intel_ring_emit(ring, 0); /* uppwer dword */ | ||
254 | intel_ring_emit(ring, MI_NOOP); | ||
255 | intel_ring_advance(ring); | 260 | intel_ring_advance(ring); |
256 | 261 | ||
257 | return 0; | 262 | return 0; |
@@ -289,8 +294,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
289 | I915_WRITE_HEAD(ring, 0); | 294 | I915_WRITE_HEAD(ring, 0); |
290 | ring->write_tail(ring, 0); | 295 | ring->write_tail(ring, 0); |
291 | 296 | ||
292 | /* Initialize the ring. */ | ||
293 | I915_WRITE_START(ring, obj->gtt_offset); | ||
294 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 297 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
295 | 298 | ||
296 | /* G45 ring initialization fails to reset head to zero */ | 299 | /* G45 ring initialization fails to reset head to zero */ |
@@ -316,6 +319,11 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
316 | } | 319 | } |
317 | } | 320 | } |
318 | 321 | ||
322 | /* Initialize the ring. This must happen _after_ we've cleared the ring | ||
323 | * registers with the above sequence (the readback of the HEAD registers | ||
324 | * also enforces ordering), otherwise the hw might lose the new ring | ||
325 | * register values. */ | ||
326 | I915_WRITE_START(ring, obj->gtt_offset); | ||
319 | I915_WRITE_CTL(ring, | 327 | I915_WRITE_CTL(ring, |
320 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 328 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
321 | | RING_VALID); | 329 | | RING_VALID); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 26a6a4d0d078..123afd357611 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -444,13 +444,16 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
444 | struct i2c_msg *msgs; | 444 | struct i2c_msg *msgs; |
445 | int i, ret = true; | 445 | int i, ret = true; |
446 | 446 | ||
447 | /* Would be simpler to allocate both in one go ? */ | ||
447 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); | 448 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); |
448 | if (!buf) | 449 | if (!buf) |
449 | return false; | 450 | return false; |
450 | 451 | ||
451 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); | 452 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); |
452 | if (!msgs) | 453 | if (!msgs) { |
454 | kfree(buf); | ||
453 | return false; | 455 | return false; |
456 | } | ||
454 | 457 | ||
455 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 458 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
456 | 459 | ||
@@ -1689,6 +1692,7 @@ static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) | |||
1689 | edid = intel_sdvo_get_edid(connector); | 1692 | edid = intel_sdvo_get_edid(connector); |
1690 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) | 1693 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) |
1691 | has_audio = drm_detect_monitor_audio(edid); | 1694 | has_audio = drm_detect_monitor_audio(edid); |
1695 | kfree(edid); | ||
1692 | 1696 | ||
1693 | return has_audio; | 1697 | return has_audio; |
1694 | } | 1698 | } |
@@ -2569,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2569 | hotplug_mask = intel_sdvo->is_sdvob ? | 2573 | hotplug_mask = intel_sdvo->is_sdvob ? |
2570 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | 2574 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; |
2571 | } | 2575 | } |
2572 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2573 | 2576 | ||
2574 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2577 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2575 | 2578 | ||
@@ -2577,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2577 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) | 2580 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2578 | goto err; | 2581 | goto err; |
2579 | 2582 | ||
2580 | /* Set up hotplug command - note paranoia about contents of reply. | ||
2581 | * We assume that the hardware is in a sane state, and only touch | ||
2582 | * the bits we think we understand. | ||
2583 | */ | ||
2584 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, | ||
2585 | &intel_sdvo->hotplug_active, 2); | ||
2586 | intel_sdvo->hotplug_active[0] &= ~0x3; | ||
2587 | |||
2588 | if (intel_sdvo_output_setup(intel_sdvo, | 2583 | if (intel_sdvo_output_setup(intel_sdvo, |
2589 | intel_sdvo->caps.output_flags) != true) { | 2584 | intel_sdvo->caps.output_flags) != true) { |
2590 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2585 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
@@ -2592,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2592 | goto err; | 2587 | goto err; |
2593 | } | 2588 | } |
2594 | 2589 | ||
2590 | /* Only enable the hotplug irq if we need it, to work around noisy | ||
2591 | * hotplug lines. | ||
2592 | */ | ||
2593 | if (intel_sdvo->hotplug_active[0]) | ||
2594 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2595 | |||
2595 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); | 2596 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2596 | 2597 | ||
2597 | /* Set the input timing to the screen. Assume always input 0. */ | 2598 | /* Set the input timing to the screen. Assume always input 0. */ |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index cc8df4de2d92..7644f31a3778 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -60,11 +60,11 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
60 | 60 | ||
61 | switch (fb->pixel_format) { | 61 | switch (fb->pixel_format) { |
62 | case DRM_FORMAT_XBGR8888: | 62 | case DRM_FORMAT_XBGR8888: |
63 | sprctl |= SPRITE_FORMAT_RGBX888; | 63 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
64 | pixel_size = 4; | 64 | pixel_size = 4; |
65 | break; | 65 | break; |
66 | case DRM_FORMAT_XRGB8888: | 66 | case DRM_FORMAT_XRGB8888: |
67 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; | 67 | sprctl |= SPRITE_FORMAT_RGBX888; |
68 | pixel_size = 4; | 68 | pixel_size = 4; |
69 | break; | 69 | break; |
70 | case DRM_FORMAT_YUYV: | 70 | case DRM_FORMAT_YUYV: |
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d79974..e5f145d2cb3b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c | |||
@@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = { | |||
84 | .mmap = mgag200_mmap, | 84 | .mmap = mgag200_mmap, |
85 | .poll = drm_poll, | 85 | .poll = drm_poll, |
86 | .fasync = drm_fasync, | 86 | .fasync = drm_fasync, |
87 | #ifdef CONFIG_COMPAT | ||
88 | .compat_ioctl = drm_compat_ioctl, | ||
89 | #endif | ||
87 | .read = drm_read, | 90 | .read = drm_read, |
88 | }; | 91 | }; |
89 | 92 | ||
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a4d7c500c97b..b69642d5d850 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
468 | { | 468 | { |
469 | unsigned int vcomax, vcomin, pllreffreq; | 469 | unsigned int vcomax, vcomin, pllreffreq; |
470 | unsigned int delta, tmpdelta; | 470 | unsigned int delta, tmpdelta; |
471 | unsigned int testr, testn, testm, testo; | 471 | int testr, testn, testm, testo; |
472 | unsigned int p, m, n; | 472 | unsigned int p, m, n; |
473 | unsigned int computed; | 473 | unsigned int computed, vco; |
474 | int tmp; | 474 | int tmp; |
475 | const unsigned int m_div_val[] = { 1, 2, 4, 8 }; | ||
475 | 476 | ||
476 | m = n = p = 0; | 477 | m = n = p = 0; |
477 | vcomax = 1488000; | 478 | vcomax = 1488000; |
@@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
490 | if (delta == 0) | 491 | if (delta == 0) |
491 | break; | 492 | break; |
492 | for (testo = 5; testo < 33; testo++) { | 493 | for (testo = 5; testo < 33; testo++) { |
493 | computed = pllreffreq * (testn + 1) / | 494 | vco = pllreffreq * (testn + 1) / |
494 | (testr + 1); | 495 | (testr + 1); |
495 | if (computed < vcomin) | 496 | if (vco < vcomin) |
496 | continue; | 497 | continue; |
497 | if (computed > vcomax) | 498 | if (vco > vcomax) |
498 | continue; | 499 | continue; |
500 | computed = vco / (m_div_val[testm] * (testo + 1)); | ||
499 | if (computed > clock) | 501 | if (computed > clock) |
500 | tmpdelta = computed - clock; | 502 | tmpdelta = computed - clock; |
501 | else | 503 | else |
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index ff23d88880e5..3ca240b4413d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -179,7 +179,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) | |||
179 | return 0; | 179 | return 0; |
180 | } else | 180 | } else |
181 | if (init->class == 0x906e) { | 181 | if (init->class == 0x906e) { |
182 | NV_ERROR(dev, "906e not supported yet\n"); | 182 | NV_DEBUG(dev, "906e not supported yet\n"); |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | } | 184 | } |
185 | 185 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fc841e87b343..26ebffebe710 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -211,11 +211,6 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, | |||
211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); |
212 | } | 212 | } |
213 | 213 | ||
214 | static int nouveau_dsm_init(void) | ||
215 | { | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | 214 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) |
220 | { | 215 | { |
221 | /* easy option one - intel vendor ID means Integrated */ | 216 | /* easy option one - intel vendor ID means Integrated */ |
@@ -232,7 +227,6 @@ static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | |||
232 | static struct vga_switcheroo_handler nouveau_dsm_handler = { | 227 | static struct vga_switcheroo_handler nouveau_dsm_handler = { |
233 | .switchto = nouveau_dsm_switchto, | 228 | .switchto = nouveau_dsm_switchto, |
234 | .power_state = nouveau_dsm_power_state, | 229 | .power_state = nouveau_dsm_power_state, |
235 | .init = nouveau_dsm_init, | ||
236 | .get_client_id = nouveau_dsm_get_client_id, | 230 | .get_client_id = nouveau_dsm_get_client_id, |
237 | }; | 231 | }; |
238 | 232 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf46..7e16dc5e6467 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, | |||
598 | args->size = args->pitch * args->height; | 598 | args->size = args->pitch * args->height; |
599 | args->size = roundup(args->size, PAGE_SIZE); | 599 | args->size = roundup(args->size, PAGE_SIZE); |
600 | 600 | ||
601 | ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); | 601 | ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); |
602 | if (ret) | 602 | if (ret) |
603 | return ret; | 603 | return ret; |
604 | 604 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 77e564667b5c..240cf962c999 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
229 | } | 229 | } |
230 | break; | 230 | break; |
231 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
232 | port->drive = entry[0]; | 232 | port->drive = entry[0] & 0x0f; |
233 | port->sense = port->drive; | 233 | port->sense = port->drive; |
234 | port->adapter.algo = &nouveau_dp_i2c_algo; | 234 | port->adapter.algo = &nouveau_dp_i2c_algo; |
235 | break; | 235 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1cdfd6e757ce..c61014442aa9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -731,15 +731,16 @@ nouveau_card_init(struct drm_device *dev) | |||
731 | case 0xa3: | 731 | case 0xa3: |
732 | case 0xa5: | 732 | case 0xa5: |
733 | case 0xa8: | 733 | case 0xa8: |
734 | case 0xaf: | ||
735 | nva3_copy_create(dev); | 734 | nva3_copy_create(dev); |
736 | break; | 735 | break; |
737 | } | 736 | } |
738 | break; | 737 | break; |
739 | case NV_C0: | 738 | case NV_C0: |
740 | nvc0_copy_create(dev, 1); | 739 | if (!(nv_rd32(dev, 0x022500) & 0x00000200)) |
740 | nvc0_copy_create(dev, 1); | ||
741 | case NV_D0: | 741 | case NV_D0: |
742 | nvc0_copy_create(dev, 0); | 742 | if (!(nv_rd32(dev, 0x022500) & 0x00000100)) |
743 | nvc0_copy_create(dev, 0); | ||
743 | break; | 744 | break; |
744 | default: | 745 | default: |
745 | break; | 746 | break; |
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7a..c399d510b27a 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
@@ -22,6 +22,7 @@ | |||
22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/dmi.h> | ||
25 | #include "drmP.h" | 26 | #include "drmP.h" |
26 | #include "nouveau_drv.h" | 27 | #include "nouveau_drv.h" |
27 | #include "nouveau_hw.h" | 28 | #include "nouveau_hw.h" |
@@ -110,11 +111,26 @@ nv50_gpio_isr(struct drm_device *dev) | |||
110 | nv_wr32(dev, 0xe074, intr1); | 111 | nv_wr32(dev, 0xe074, intr1); |
111 | } | 112 | } |
112 | 113 | ||
114 | static struct dmi_system_id gpio_reset_ids[] = { | ||
115 | { | ||
116 | .ident = "Apple Macbook 10,1", | ||
117 | .matches = { | ||
118 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
119 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"), | ||
120 | } | ||
121 | }, | ||
122 | { } | ||
123 | }; | ||
124 | |||
113 | int | 125 | int |
114 | nv50_gpio_init(struct drm_device *dev) | 126 | nv50_gpio_init(struct drm_device *dev) |
115 | { | 127 | { |
116 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 128 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
117 | 129 | ||
130 | /* initialise gpios and routing to vbios defaults */ | ||
131 | if (dmi_check_system(gpio_reset_ids)) | ||
132 | nouveau_gpio_reset(dev); | ||
133 | |||
118 | /* disable, and ack any pending gpio interrupts */ | 134 | /* disable, and ack any pending gpio interrupts */ |
119 | nv_wr32(dev, 0xe050, 0x00000000); | 135 | nv_wr32(dev, 0xe050, 0x00000000); |
120 | nv_wr32(dev, 0xe054, 0xffffffff); | 136 | nv_wr32(dev, 0xe054, 0xffffffff); |
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c index cc82d799fc3b..c564c5e4c30a 100644 --- a/drivers/gpu/drm/nouveau/nv84_fifo.c +++ b/drivers/gpu/drm/nouveau/nv84_fifo.c | |||
@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine) | |||
117 | struct drm_device *dev = chan->dev; | 117 | struct drm_device *dev = chan->dev; |
118 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
119 | unsigned long flags; | 119 | unsigned long flags; |
120 | u32 save; | ||
120 | 121 | ||
121 | /* remove channel from playlist, will context switch if active */ | 122 | /* remove channel from playlist, will context switch if active */ |
122 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 123 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
123 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); | 124 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); |
124 | nv50_fifo_playlist_update(dev); | 125 | nv50_fifo_playlist_update(dev); |
125 | 126 | ||
127 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
128 | |||
126 | /* tell any engines on this channel to unload their contexts */ | 129 | /* tell any engines on this channel to unload their contexts */ |
127 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); | 130 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); |
128 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) | 131 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) |
129 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); | 132 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); |
130 | 133 | ||
134 | nv_wr32(dev, 0x002520, save); | ||
135 | |||
131 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); | 136 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); |
132 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 137 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
133 | 138 | ||
@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
184 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 189 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
185 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); | 190 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); |
186 | int i; | 191 | int i; |
192 | u32 save; | ||
187 | 193 | ||
188 | /* set playlist length to zero, fifo will unload context */ | 194 | /* set playlist length to zero, fifo will unload context */ |
189 | nv_wr32(dev, 0x0032ec, 0); | 195 | nv_wr32(dev, 0x0032ec, 0); |
190 | 196 | ||
197 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
198 | |||
191 | /* tell all connected engines to unload their contexts */ | 199 | /* tell all connected engines to unload their contexts */ |
192 | for (i = 0; i < priv->base.channels; i++) { | 200 | for (i = 0; i < priv->base.channels; i++) { |
193 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; | 201 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; |
@@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
199 | } | 207 | } |
200 | } | 208 | } |
201 | 209 | ||
210 | nv_wr32(dev, 0x002520, save); | ||
202 | nv_wr32(dev, 0x002140, 0); | 211 | nv_wr32(dev, 0x002140, 0); |
203 | return 0; | 212 | return 0; |
204 | } | 213 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_fb.c b/drivers/gpu/drm/nouveau/nvc0_fb.c index f704e942372e..f376c39310df 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fb.c +++ b/drivers/gpu/drm/nouveau/nvc0_fb.c | |||
@@ -124,6 +124,7 @@ nvc0_fb_init(struct drm_device *dev) | |||
124 | priv = dev_priv->engine.fb.priv; | 124 | priv = dev_priv->engine.fb.priv; |
125 | 125 | ||
126 | nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); | 126 | nv_wr32(dev, 0x100c10, priv->r100c10 >> 8); |
127 | nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */ | ||
127 | return 0; | 128 | return 0; |
128 | } | 129 | } |
129 | 130 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c index 7d85553d518c..cd39eb99f5b1 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fifo.c +++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c | |||
@@ -373,7 +373,8 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
373 | static void | 373 | static void |
374 | nvc0_fifo_isr(struct drm_device *dev) | 374 | nvc0_fifo_isr(struct drm_device *dev) |
375 | { | 375 | { |
376 | u32 stat = nv_rd32(dev, 0x002100); | 376 | u32 mask = nv_rd32(dev, 0x002140); |
377 | u32 stat = nv_rd32(dev, 0x002100) & mask; | ||
377 | 378 | ||
378 | if (stat & 0x00000100) { | 379 | if (stat & 0x00000100) { |
379 | NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); | 380 | NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); |
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c index 7c95c44e2887..4e712b10ebdb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_pm.c +++ b/drivers/gpu/drm/nouveau/nvc0_pm.c | |||
@@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) | |||
557 | nouveau_mem_exec(&exec, info->perflvl); | 557 | nouveau_mem_exec(&exec, info->perflvl); |
558 | 558 | ||
559 | if (dev_priv->chipset < 0xd0) | 559 | if (dev_priv->chipset < 0xd0) |
560 | nv_wr32(dev, 0x611200, 0x00003300); | 560 | nv_wr32(dev, 0x611200, 0x00003330); |
561 | else | 561 | else |
562 | nv_wr32(dev, 0x62c000, 0x03030300); | 562 | nv_wr32(dev, 0x62c000, 0x03030300); |
563 | } | 563 | } |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index d0d60e1e7f95..8a2fc89b7763 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
791 | int ch = EVO_CURS(nv_crtc->index); | 791 | int ch = EVO_CURS(nv_crtc->index); |
792 | 792 | ||
793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); | 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff)); |
794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); | 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); |
795 | return 0; | 795 | return 0; |
796 | } | 796 | } |
@@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1510 | case OUTPUT_DP: | 1510 | case OUTPUT_DP: |
1511 | if (nv_connector->base.display_info.bpc == 6) { | 1511 | if (nv_connector->base.display_info.bpc == 6) { |
1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; | 1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; |
1513 | syncs |= 0x00000140; | 1513 | syncs |= 0x00000002 << 6; |
1514 | } else { | 1514 | } else { |
1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; | 1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; |
1516 | syncs |= 0x00000180; | 1516 | syncs |= 0x00000005 << 6; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | if (nv_encoder->dcb->sorconf.link & 1) | 1519 | if (nv_encoder->dcb->sorconf.link & 1) |
diff --git a/drivers/gpu/drm/nouveau/nve0_fifo.c b/drivers/gpu/drm/nouveau/nve0_fifo.c index 1855ecbd843b..281bece751b6 100644 --- a/drivers/gpu/drm/nouveau/nve0_fifo.c +++ b/drivers/gpu/drm/nouveau/nve0_fifo.c | |||
@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit) | |||
294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); | 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); |
295 | } | 295 | } |
296 | 296 | ||
297 | static int | ||
298 | nve0_fifo_page_flip(struct drm_device *dev, u32 chid) | ||
299 | { | ||
300 | struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO); | ||
301 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
302 | struct nouveau_channel *chan = NULL; | ||
303 | unsigned long flags; | ||
304 | int ret = -EINVAL; | ||
305 | |||
306 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | ||
307 | if (likely(chid >= 0 && chid < priv->base.channels)) { | ||
308 | chan = dev_priv->channels.ptr[chid]; | ||
309 | if (likely(chan)) | ||
310 | ret = nouveau_finish_page_flip(chan, NULL); | ||
311 | } | ||
312 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); | ||
313 | return ret; | ||
314 | } | ||
315 | |||
297 | static void | 316 | static void |
298 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | 317 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) |
299 | { | 318 | { |
@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
303 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; | 322 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; |
304 | u32 subc = (addr & 0x00070000); | 323 | u32 subc = (addr & 0x00070000); |
305 | u32 mthd = (addr & 0x00003ffc); | 324 | u32 mthd = (addr & 0x00003ffc); |
325 | u32 show = stat; | ||
326 | |||
327 | if (stat & 0x00200000) { | ||
328 | if (mthd == 0x0054) { | ||
329 | if (!nve0_fifo_page_flip(dev, chid)) | ||
330 | show &= ~0x00200000; | ||
331 | } | ||
332 | } | ||
306 | 333 | ||
307 | NV_INFO(dev, "PSUBFIFO %d:", unit); | 334 | if (show) { |
308 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat); | 335 | NV_INFO(dev, "PFIFO%d:", unit); |
309 | NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", | 336 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, show); |
310 | unit, chid, subc, mthd, data); | 337 | NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n", |
338 | unit, chid, subc, mthd, data); | ||
339 | } | ||
311 | 340 | ||
312 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); | 341 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); |
313 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); | 342 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); |
@@ -316,7 +345,8 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
316 | static void | 345 | static void |
317 | nve0_fifo_isr(struct drm_device *dev) | 346 | nve0_fifo_isr(struct drm_device *dev) |
318 | { | 347 | { |
319 | u32 stat = nv_rd32(dev, 0x002100); | 348 | u32 mask = nv_rd32(dev, 0x002140); |
349 | u32 stat = nv_rd32(dev, 0x002100) & mask; | ||
320 | 350 | ||
321 | if (stat & 0x00000100) { | 351 | if (stat & 0x00000100) { |
322 | NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); | 352 | NV_INFO(dev, "PFIFO: unknown status 0x00000100\n"); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9e6f76fec527..2817101fb167 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -258,8 +258,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
258 | radeon_crtc->enabled = true; | 258 | radeon_crtc->enabled = true; |
259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
261 | /* disable crtc pair power gating before programming */ | 261 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
262 | if (ASIC_IS_DCE6(rdev)) | ||
263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 262 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 263 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 264 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
@@ -278,25 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
278 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); | 277 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 278 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
280 | radeon_crtc->enabled = false; | 279 | radeon_crtc->enabled = false; |
281 | /* power gating is per-pair */ | 280 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
282 | if (ASIC_IS_DCE6(rdev)) { | 281 | atombios_powergate_crtc(crtc, ATOM_ENABLE); |
283 | struct drm_crtc *other_crtc; | ||
284 | struct radeon_crtc *other_radeon_crtc; | ||
285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | ||
286 | other_radeon_crtc = to_radeon_crtc(other_crtc); | ||
287 | if (((radeon_crtc->crtc_id == 0) && (other_radeon_crtc->crtc_id == 1)) || | ||
288 | ((radeon_crtc->crtc_id == 1) && (other_radeon_crtc->crtc_id == 0)) || | ||
289 | ((radeon_crtc->crtc_id == 2) && (other_radeon_crtc->crtc_id == 3)) || | ||
290 | ((radeon_crtc->crtc_id == 3) && (other_radeon_crtc->crtc_id == 2)) || | ||
291 | ((radeon_crtc->crtc_id == 4) && (other_radeon_crtc->crtc_id == 5)) || | ||
292 | ((radeon_crtc->crtc_id == 5) && (other_radeon_crtc->crtc_id == 4))) { | ||
293 | /* if both crtcs in the pair are off, enable power gating */ | ||
294 | if (other_radeon_crtc->enabled == false) | ||
295 | atombios_powergate_crtc(crtc, ATOM_ENABLE); | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | /* adjust pm to dpms changes AFTER disabling crtcs */ | 282 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
301 | radeon_pm_compute_clocks(rdev); | 283 | radeon_pm_compute_clocks(rdev); |
302 | break; | 284 | break; |
@@ -444,11 +426,28 @@ union atom_enable_ss { | |||
444 | static void atombios_crtc_program_ss(struct radeon_device *rdev, | 426 | static void atombios_crtc_program_ss(struct radeon_device *rdev, |
445 | int enable, | 427 | int enable, |
446 | int pll_id, | 428 | int pll_id, |
429 | int crtc_id, | ||
447 | struct radeon_atom_ss *ss) | 430 | struct radeon_atom_ss *ss) |
448 | { | 431 | { |
432 | unsigned i; | ||
449 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | 433 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
450 | union atom_enable_ss args; | 434 | union atom_enable_ss args; |
451 | 435 | ||
436 | if (!enable) { | ||
437 | for (i = 0; i < rdev->num_crtc; i++) { | ||
438 | if (rdev->mode_info.crtcs[i] && | ||
439 | rdev->mode_info.crtcs[i]->enabled && | ||
440 | i != crtc_id && | ||
441 | pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
442 | /* one other crtc is using this pll don't turn | ||
443 | * off spread spectrum as it might turn off | ||
444 | * display on active crtc | ||
445 | */ | ||
446 | return; | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | |||
452 | memset(&args, 0, sizeof(args)); | 451 | memset(&args, 0, sizeof(args)); |
453 | 452 | ||
454 | if (ASIC_IS_DCE5(rdev)) { | 453 | if (ASIC_IS_DCE5(rdev)) { |
@@ -1028,7 +1027,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
1028 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 1027 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
1029 | &ref_div, &post_div); | 1028 | &ref_div, &post_div); |
1030 | 1029 | ||
1031 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); | 1030 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); |
1032 | 1031 | ||
1033 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 1032 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
1034 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 1033 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
@@ -1051,7 +1050,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
1051 | ss.step = step_size; | 1050 | ss.step = step_size; |
1052 | } | 1051 | } |
1053 | 1052 | ||
1054 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); | 1053 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, radeon_crtc->crtc_id, &ss); |
1055 | } | 1054 | } |
1056 | } | 1055 | } |
1057 | 1056 | ||
@@ -1531,12 +1530,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1531 | * crtc virtual pixel clock. | 1530 | * crtc virtual pixel clock. |
1532 | */ | 1531 | */ |
1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1532 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1534 | if (ASIC_IS_DCE5(rdev)) | 1533 | if (rdev->clock.dp_extclk) |
1535 | return ATOM_DCPLL; | 1534 | return ATOM_PPLL_INVALID; |
1536 | else if (ASIC_IS_DCE6(rdev)) | 1535 | else if (ASIC_IS_DCE6(rdev)) |
1537 | return ATOM_PPLL0; | 1536 | return ATOM_PPLL0; |
1538 | else if (rdev->clock.dp_extclk) | 1537 | else if (ASIC_IS_DCE5(rdev)) |
1539 | return ATOM_PPLL_INVALID; | 1538 | return ATOM_DCPLL; |
1540 | } | 1539 | } |
1541 | } | 1540 | } |
1542 | } | 1541 | } |
@@ -1572,11 +1571,11 @@ void radeon_atom_disp_eng_pll_init(struct radeon_device *rdev) | |||
1572 | ASIC_INTERNAL_SS_ON_DCPLL, | 1571 | ASIC_INTERNAL_SS_ON_DCPLL, |
1573 | rdev->clock.default_dispclk); | 1572 | rdev->clock.default_dispclk); |
1574 | if (ss_enabled) | 1573 | if (ss_enabled) |
1575 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); | 1574 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, -1, &ss); |
1576 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | 1575 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ |
1577 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); | 1576 | atombios_crtc_set_disp_eng_pll(rdev, rdev->clock.default_dispclk); |
1578 | if (ss_enabled) | 1577 | if (ss_enabled) |
1579 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); | 1578 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, -1, &ss); |
1580 | } | 1579 | } |
1581 | 1580 | ||
1582 | } | 1581 | } |
@@ -1635,18 +1634,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1634 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
1636 | { | 1635 | { |
1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1636 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1637 | struct drm_device *dev = crtc->dev; | ||
1638 | struct radeon_device *rdev = dev->dev_private; | ||
1638 | 1639 | ||
1640 | radeon_crtc->in_mode_set = true; | ||
1639 | /* pick pll */ | 1641 | /* pick pll */ |
1640 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | 1642 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
1641 | 1643 | ||
1644 | /* disable crtc pair power gating before programming */ | ||
1645 | if (ASIC_IS_DCE6(rdev)) | ||
1646 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | ||
1647 | |||
1642 | atombios_lock_crtc(crtc, ATOM_ENABLE); | 1648 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
1643 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1649 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1644 | } | 1650 | } |
1645 | 1651 | ||
1646 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1652 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
1647 | { | 1653 | { |
1654 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1655 | |||
1648 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1656 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
1649 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1657 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1658 | radeon_crtc->in_mode_set = false; | ||
1650 | } | 1659 | } |
1651 | 1660 | ||
1652 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1661 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
@@ -1655,9 +1664,22 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1655 | struct drm_device *dev = crtc->dev; | 1664 | struct drm_device *dev = crtc->dev; |
1656 | struct radeon_device *rdev = dev->dev_private; | 1665 | struct radeon_device *rdev = dev->dev_private; |
1657 | struct radeon_atom_ss ss; | 1666 | struct radeon_atom_ss ss; |
1667 | int i; | ||
1658 | 1668 | ||
1659 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1669 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1660 | 1670 | ||
1671 | for (i = 0; i < rdev->num_crtc; i++) { | ||
1672 | if (rdev->mode_info.crtcs[i] && | ||
1673 | rdev->mode_info.crtcs[i]->enabled && | ||
1674 | i != radeon_crtc->crtc_id && | ||
1675 | radeon_crtc->pll_id == rdev->mode_info.crtcs[i]->pll_id) { | ||
1676 | /* one other crtc is using this pll don't turn | ||
1677 | * off the pll | ||
1678 | */ | ||
1679 | goto done; | ||
1680 | } | ||
1681 | } | ||
1682 | |||
1661 | switch (radeon_crtc->pll_id) { | 1683 | switch (radeon_crtc->pll_id) { |
1662 | case ATOM_PPLL1: | 1684 | case ATOM_PPLL1: |
1663 | case ATOM_PPLL2: | 1685 | case ATOM_PPLL2: |
@@ -1674,6 +1696,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1674 | default: | 1696 | default: |
1675 | break; | 1697 | break; |
1676 | } | 1698 | } |
1699 | done: | ||
1677 | radeon_crtc->pll_id = -1; | 1700 | radeon_crtc->pll_id = -1; |
1678 | } | 1701 | } |
1679 | 1702 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 7712cf5ab33b..3623b98ed3fe 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -577,30 +577,25 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
577 | struct radeon_device *rdev = dev->dev_private; | 577 | struct radeon_device *rdev = dev->dev_private; |
578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 578 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 579 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
580 | u16 dp_bridge = radeon_connector_encoder_get_dp_bridge_encoder_id(connector); | ||
581 | u8 tmp; | ||
580 | 582 | ||
581 | if (!ASIC_IS_DCE4(rdev)) | 583 | if (!ASIC_IS_DCE4(rdev)) |
582 | return panel_mode; | 584 | return panel_mode; |
583 | 585 | ||
584 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 586 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
585 | ENCODER_OBJECT_ID_NUTMEG) | 587 | /* DP bridge chips */ |
586 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 588 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
587 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 589 | if (tmp & 1) |
588 | ENCODER_OBJECT_ID_TRAVIS) { | 590 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
589 | u8 id[6]; | 591 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
590 | int i; | 592 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
591 | for (i = 0; i < 6; i++) | ||
592 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
593 | if (id[0] == 0x73 && | ||
594 | id[1] == 0x69 && | ||
595 | id[2] == 0x76 && | ||
596 | id[3] == 0x61 && | ||
597 | id[4] == 0x72 && | ||
598 | id[5] == 0x54) | ||
599 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 593 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
600 | else | 594 | else |
601 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 595 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
602 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 596 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
603 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 597 | /* eDP */ |
598 | tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | ||
604 | if (tmp & 1) | 599 | if (tmp & 1) |
605 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 600 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
606 | } | 601 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f9bc27fe269a..6e8803a1170c 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -1379,6 +1379,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1379 | struct drm_device *dev = encoder->dev; | 1379 | struct drm_device *dev = encoder->dev; |
1380 | struct radeon_device *rdev = dev->dev_private; | 1380 | struct radeon_device *rdev = dev->dev_private; |
1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1381 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1382 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1383 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1382 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1384 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1383 | struct radeon_connector *radeon_connector = NULL; | 1385 | struct radeon_connector *radeon_connector = NULL; |
1384 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; | 1386 | struct radeon_connector_atom_dig *radeon_dig_connector = NULL; |
@@ -1390,19 +1392,37 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1390 | 1392 | ||
1391 | switch (mode) { | 1393 | switch (mode) { |
1392 | case DRM_MODE_DPMS_ON: | 1394 | case DRM_MODE_DPMS_ON: |
1393 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1395 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1394 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || | 1396 | if (!connector) |
1395 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1397 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
1396 | if (ASIC_IS_DCE6(rdev)) { | 1398 | else |
1397 | /* It seems we need to call ATOM_ENCODER_CMD_SETUP again | 1399 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); |
1398 | * before reenabling encoder on DPMS ON, otherwise we never | 1400 | |
1399 | * get picture | 1401 | /* setup and enable the encoder */ |
1400 | */ | 1402 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); |
1401 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | 1403 | atombios_dig_encoder_setup(encoder, |
1404 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
1405 | dig->panel_mode); | ||
1406 | if (ext_encoder) { | ||
1407 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
1408 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1409 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1402 | } | 1410 | } |
1403 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1411 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
1404 | } else { | 1412 | } else if (ASIC_IS_DCE4(rdev)) { |
1413 | /* setup and enable the encoder */ | ||
1414 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1415 | /* enable the transmitter */ | ||
1416 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1405 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1417 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1418 | } else { | ||
1419 | /* setup and enable the encoder and transmitter */ | ||
1420 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1421 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1422 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1423 | /* some early dce3.2 boards have a bug in their transmitter control table */ | ||
1424 | if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | ||
1425 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1406 | } | 1426 | } |
1407 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1408 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 1428 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
@@ -1420,10 +1440,19 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
1420 | case DRM_MODE_DPMS_STANDBY: | 1440 | case DRM_MODE_DPMS_STANDBY: |
1421 | case DRM_MODE_DPMS_SUSPEND: | 1441 | case DRM_MODE_DPMS_SUSPEND: |
1422 | case DRM_MODE_DPMS_OFF: | 1442 | case DRM_MODE_DPMS_OFF: |
1423 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | 1443 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
1444 | /* disable the transmitter */ | ||
1424 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1445 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
1425 | else | 1446 | } else if (ASIC_IS_DCE4(rdev)) { |
1447 | /* disable the transmitter */ | ||
1448 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1449 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1450 | } else { | ||
1451 | /* disable the encoder and transmitter */ | ||
1426 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1452 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
1453 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1454 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1455 | } | ||
1427 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1456 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
1428 | if (ASIC_IS_DCE4(rdev)) | 1457 | if (ASIC_IS_DCE4(rdev)) |
1429 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1458 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
@@ -1740,13 +1769,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1740 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | 1769 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); |
1741 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1770 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1742 | struct drm_encoder *test_encoder; | 1771 | struct drm_encoder *test_encoder; |
1743 | struct radeon_encoder_atom_dig *dig; | 1772 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
1744 | uint32_t dig_enc_in_use = 0; | 1773 | uint32_t dig_enc_in_use = 0; |
1745 | 1774 | ||
1746 | /* DCE4/5 */ | 1775 | if (ASIC_IS_DCE6(rdev)) { |
1747 | if (ASIC_IS_DCE4(rdev)) { | 1776 | /* DCE6 */ |
1748 | dig = radeon_encoder->enc_priv; | 1777 | switch (radeon_encoder->encoder_id) { |
1749 | if (ASIC_IS_DCE41(rdev)) { | 1778 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1779 | if (dig->linkb) | ||
1780 | return 1; | ||
1781 | else | ||
1782 | return 0; | ||
1783 | break; | ||
1784 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
1785 | if (dig->linkb) | ||
1786 | return 3; | ||
1787 | else | ||
1788 | return 2; | ||
1789 | break; | ||
1790 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
1791 | if (dig->linkb) | ||
1792 | return 5; | ||
1793 | else | ||
1794 | return 4; | ||
1795 | break; | ||
1796 | } | ||
1797 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1798 | /* DCE4/5 */ | ||
1799 | if (ASIC_IS_DCE41(rdev) && !ASIC_IS_DCE61(rdev)) { | ||
1750 | /* ontario follows DCE4 */ | 1800 | /* ontario follows DCE4 */ |
1751 | if (rdev->family == CHIP_PALM) { | 1801 | if (rdev->family == CHIP_PALM) { |
1752 | if (dig->linkb) | 1802 | if (dig->linkb) |
@@ -1848,10 +1898,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1848 | struct drm_device *dev = encoder->dev; | 1898 | struct drm_device *dev = encoder->dev; |
1849 | struct radeon_device *rdev = dev->dev_private; | 1899 | struct radeon_device *rdev = dev->dev_private; |
1850 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 1900 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
1851 | struct drm_encoder *ext_encoder = radeon_get_external_encoder(encoder); | ||
1852 | 1901 | ||
1853 | radeon_encoder->pixel_clock = adjusted_mode->clock; | 1902 | radeon_encoder->pixel_clock = adjusted_mode->clock; |
1854 | 1903 | ||
1904 | /* need to call this here rather than in prepare() since we need some crtc info */ | ||
1905 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
1906 | |||
1855 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { | 1907 | if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE4(rdev)) { |
1856 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) | 1908 | if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) |
1857 | atombios_yuv_setup(encoder, true); | 1909 | atombios_yuv_setup(encoder, true); |
@@ -1870,38 +1922,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1870 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1922 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1871 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1923 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1872 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1924 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
1873 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | 1925 | /* handled in dpms */ |
1874 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
1875 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
1876 | |||
1877 | if (!connector) | ||
1878 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
1879 | else | ||
1880 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
1881 | |||
1882 | /* setup and enable the encoder */ | ||
1883 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1884 | atombios_dig_encoder_setup(encoder, | ||
1885 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
1886 | dig->panel_mode); | ||
1887 | } else if (ASIC_IS_DCE4(rdev)) { | ||
1888 | /* disable the transmitter */ | ||
1889 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1890 | /* setup and enable the encoder */ | ||
1891 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
1892 | |||
1893 | /* enable the transmitter */ | ||
1894 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1895 | } else { | ||
1896 | /* disable the encoder and transmitter */ | ||
1897 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
1898 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
1899 | |||
1900 | /* setup and enable the encoder and transmitter */ | ||
1901 | atombios_dig_encoder_setup(encoder, ATOM_ENABLE, 0); | ||
1902 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); | ||
1903 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | ||
1904 | } | ||
1905 | break; | 1926 | break; |
1906 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 1927 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
1907 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 1928 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
@@ -1922,14 +1943,6 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
1922 | break; | 1943 | break; |
1923 | } | 1944 | } |
1924 | 1945 | ||
1925 | if (ext_encoder) { | ||
1926 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) | ||
1927 | atombios_external_encoder_setup(encoder, ext_encoder, | ||
1928 | EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); | ||
1929 | else | ||
1930 | atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); | ||
1931 | } | ||
1932 | |||
1933 | atombios_apply_encoder_quirks(encoder, adjusted_mode); | 1946 | atombios_apply_encoder_quirks(encoder, adjusted_mode); |
1934 | 1947 | ||
1935 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { | 1948 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { |
@@ -2116,7 +2129,6 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
2116 | } | 2129 | } |
2117 | 2130 | ||
2118 | radeon_atom_output_lock(encoder, true); | 2131 | radeon_atom_output_lock(encoder, true); |
2119 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
2120 | 2132 | ||
2121 | if (connector) { | 2133 | if (connector) { |
2122 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 2134 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
@@ -2137,6 +2149,7 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) | |||
2137 | 2149 | ||
2138 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) | 2150 | static void radeon_atom_encoder_commit(struct drm_encoder *encoder) |
2139 | { | 2151 | { |
2152 | /* need to call this here as we need the crtc set up */ | ||
2140 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 2153 | radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_ON); |
2141 | radeon_atom_output_lock(encoder, false); | 2154 | radeon_atom_output_lock(encoder, false); |
2142 | } | 2155 | } |
@@ -2177,14 +2190,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder) | |||
2177 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 2190 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
2178 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 2191 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
2179 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 2192 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
2180 | if (ASIC_IS_DCE4(rdev)) | 2193 | /* handled in dpms */ |
2181 | /* disable the transmitter */ | ||
2182 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2183 | else { | ||
2184 | /* disable the encoder and transmitter */ | ||
2185 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
2186 | atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0); | ||
2187 | } | ||
2188 | break; | 2194 | break; |
2189 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | 2195 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
2190 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | 2196 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e585a3b947eb..e93b80a6d4e9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
1229 | 1229 | ||
1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
1231 | { | 1231 | { |
1232 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
1233 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
1234 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1232 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
1235 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1233 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
1236 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
1237 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
1238 | if (rdev->num_crtc >= 4) { | ||
1239 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
1240 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
1241 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
1242 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
1243 | } | ||
1244 | if (rdev->num_crtc >= 6) { | ||
1245 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
1246 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
1247 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
1248 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
1249 | } | ||
1250 | 1234 | ||
1251 | /* Stop all video */ | 1235 | /* Stop all video */ |
1252 | WREG32(VGA_RENDER_CONTROL, 0); | 1236 | WREG32(VGA_RENDER_CONTROL, 0); |
@@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1357 | /* Unlock host access */ | 1341 | /* Unlock host access */ |
1358 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1342 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
1359 | mdelay(1); | 1343 | mdelay(1); |
1360 | /* Restore video state */ | ||
1361 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
1362 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
1363 | if (rdev->num_crtc >= 4) { | ||
1364 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
1365 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
1366 | } | ||
1367 | if (rdev->num_crtc >= 6) { | ||
1368 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
1369 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
1370 | } | ||
1371 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
1372 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
1373 | if (rdev->num_crtc >= 4) { | ||
1374 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
1375 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
1376 | } | ||
1377 | if (rdev->num_crtc >= 6) { | ||
1378 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
1379 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
1380 | } | ||
1381 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
1382 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
1383 | if (rdev->num_crtc >= 4) { | ||
1384 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
1385 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
1386 | } | ||
1387 | if (rdev->num_crtc >= 6) { | ||
1388 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
1389 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
1390 | } | ||
1391 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
1392 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
1393 | if (rdev->num_crtc >= 4) { | ||
1394 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
1396 | } | ||
1397 | if (rdev->num_crtc >= 6) { | ||
1398 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
1399 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1400 | } | ||
1401 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1344 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
1402 | } | 1345 | } |
1403 | 1346 | ||
@@ -1986,10 +1929,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1986 | if (rdev->flags & RADEON_IS_IGP) | 1929 | if (rdev->flags & RADEON_IS_IGP) |
1987 | rdev->config.evergreen.tile_config |= 1 << 4; | 1930 | rdev->config.evergreen.tile_config |= 1 << 4; |
1988 | else { | 1931 | else { |
1989 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1932 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
1990 | rdev->config.evergreen.tile_config |= 1 << 4; | 1933 | case 0: /* four banks */ |
1991 | else | ||
1992 | rdev->config.evergreen.tile_config |= 0 << 4; | 1934 | rdev->config.evergreen.tile_config |= 0 << 4; |
1935 | break; | ||
1936 | case 1: /* eight banks */ | ||
1937 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
1938 | break; | ||
1939 | case 2: /* sixteen banks */ | ||
1940 | default: | ||
1941 | rdev->config.evergreen.tile_config |= 2 << 4; | ||
1942 | break; | ||
1943 | } | ||
1993 | } | 1944 | } |
1994 | rdev->config.evergreen.tile_config |= 0 << 8; | 1945 | rdev->config.evergreen.tile_config |= 0 << 8; |
1995 | rdev->config.evergreen.tile_config |= | 1946 | rdev->config.evergreen.tile_config |= |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c16554122ccd..e44a62a07fe3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: |
789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: |
790 | depth = 1; | 790 | depth = 1; |
791 | break; | ||
792 | case V_030000_SQ_TEX_DIM_2D_MSAA: | ||
793 | case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: | ||
794 | surf.nsamples = 1 << llevel; | ||
795 | llevel = 0; | ||
796 | depth = 1; | ||
797 | break; | ||
791 | case V_030000_SQ_TEX_DIM_3D: | 798 | case V_030000_SQ_TEX_DIM_3D: |
792 | break; | 799 | break; |
793 | default: | 800 | default: |
@@ -961,13 +968,15 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
961 | 968 | ||
962 | if (track->db_dirty) { | 969 | if (track->db_dirty) { |
963 | /* Check stencil buffer */ | 970 | /* Check stencil buffer */ |
964 | if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { | 971 | if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID && |
972 | G_028800_STENCIL_ENABLE(track->db_depth_control)) { | ||
965 | r = evergreen_cs_track_validate_stencil(p); | 973 | r = evergreen_cs_track_validate_stencil(p); |
966 | if (r) | 974 | if (r) |
967 | return r; | 975 | return r; |
968 | } | 976 | } |
969 | /* Check depth buffer */ | 977 | /* Check depth buffer */ |
970 | if (G_028800_Z_ENABLE(track->db_depth_control)) { | 978 | if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID && |
979 | G_028800_Z_ENABLE(track->db_depth_control)) { | ||
971 | r = evergreen_cs_track_validate_depth(p); | 980 | r = evergreen_cs_track_validate_depth(p); |
972 | if (r) | 981 | if (r) |
973 | return r; | 982 | return r; |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index d3bd098e4e19..79347855d9bf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -1277,6 +1277,8 @@ | |||
1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) | 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) |
1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) | 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) |
1279 | #define C_028044_FORMAT 0xFFFFFFFE | 1279 | #define C_028044_FORMAT 0xFFFFFFFE |
1280 | #define V_028044_STENCIL_INVALID 0 | ||
1281 | #define V_028044_STENCIL_8 1 | ||
1280 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) | 1282 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) |
1281 | #define DB_Z_READ_BASE 0x28048 | 1283 | #define DB_Z_READ_BASE 0x28048 |
1282 | #define DB_STENCIL_READ_BASE 0x2804c | 1284 | #define DB_STENCIL_READ_BASE 0x2804c |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 9945d86d9001..853800e8582f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
574 | if (rdev->flags & RADEON_IS_IGP) | 574 | if (rdev->flags & RADEON_IS_IGP) |
575 | rdev->config.cayman.tile_config |= 1 << 4; | 575 | rdev->config.cayman.tile_config |= 1 << 4; |
576 | else { | 576 | else { |
577 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 577 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
578 | rdev->config.cayman.tile_config |= 1 << 4; | 578 | case 0: /* four banks */ |
579 | else | ||
580 | rdev->config.cayman.tile_config |= 0 << 4; | 579 | rdev->config.cayman.tile_config |= 0 << 4; |
580 | break; | ||
581 | case 1: /* eight banks */ | ||
582 | rdev->config.cayman.tile_config |= 1 << 4; | ||
583 | break; | ||
584 | case 2: /* sixteen banks */ | ||
585 | default: | ||
586 | rdev->config.cayman.tile_config |= 2 << 4; | ||
587 | break; | ||
588 | } | ||
581 | } | 589 | } |
582 | rdev->config.cayman.tile_config |= | 590 | rdev->config.cayman.tile_config |= |
583 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 591 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8acb34fd3fd5..8d7e33a0b243 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
1182 | ring->ready = true; | 1182 | ring->ready = true; |
1183 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); | 1183 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
1184 | 1184 | ||
1185 | if (radeon_ring_supports_scratch_reg(rdev, ring)) { | 1185 | if (!ring->rptr_save_reg /* not resuming from suspend */ |
1186 | && radeon_ring_supports_scratch_reg(rdev, ring)) { | ||
1186 | r = radeon_scratch_get(rdev, &ring->rptr_save_reg); | 1187 | r = radeon_scratch_get(rdev, &ring->rptr_save_reg); |
1187 | if (r) { | 1188 | if (r) { |
1188 | DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); | 1189 | DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f541a3..d79c639ae739 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); |
3790 | } | 3790 | } |
3791 | } | 3791 | } |
3792 | |||
3793 | /** | ||
3794 | * r600_get_gpu_clock - return GPU clock counter snapshot | ||
3795 | * | ||
3796 | * @rdev: radeon_device pointer | ||
3797 | * | ||
3798 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | ||
3799 | * Returns the 64 bit clock counter snapshot. | ||
3800 | */ | ||
3801 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | ||
3802 | { | ||
3803 | uint64_t clock; | ||
3804 | |||
3805 | mutex_lock(&rdev->gpu_clock_mutex); | ||
3806 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
3807 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
3808 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
3809 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
3810 | return clock; | ||
3811 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..f37676d7f217 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -47,18 +47,23 @@ struct r600_cs_track { | |||
47 | u32 npipes; | 47 | u32 npipes; |
48 | /* value we track */ | 48 | /* value we track */ |
49 | u32 sq_config; | 49 | u32 sq_config; |
50 | u32 log_nsamples; | ||
50 | u32 nsamples; | 51 | u32 nsamples; |
51 | u32 cb_color_base_last[8]; | 52 | u32 cb_color_base_last[8]; |
52 | struct radeon_bo *cb_color_bo[8]; | 53 | struct radeon_bo *cb_color_bo[8]; |
53 | u64 cb_color_bo_mc[8]; | 54 | u64 cb_color_bo_mc[8]; |
54 | u32 cb_color_bo_offset[8]; | 55 | u64 cb_color_bo_offset[8]; |
55 | struct radeon_bo *cb_color_frag_bo[8]; /* unused */ | 56 | struct radeon_bo *cb_color_frag_bo[8]; |
56 | struct radeon_bo *cb_color_tile_bo[8]; /* unused */ | 57 | u64 cb_color_frag_offset[8]; |
58 | struct radeon_bo *cb_color_tile_bo[8]; | ||
59 | u64 cb_color_tile_offset[8]; | ||
60 | u32 cb_color_mask[8]; | ||
57 | u32 cb_color_info[8]; | 61 | u32 cb_color_info[8]; |
58 | u32 cb_color_view[8]; | 62 | u32 cb_color_view[8]; |
59 | u32 cb_color_size_idx[8]; /* unused */ | 63 | u32 cb_color_size_idx[8]; /* unused */ |
60 | u32 cb_target_mask; | 64 | u32 cb_target_mask; |
61 | u32 cb_shader_mask; /* unused */ | 65 | u32 cb_shader_mask; /* unused */ |
66 | bool is_resolve; | ||
62 | u32 cb_color_size[8]; | 67 | u32 cb_color_size[8]; |
63 | u32 vgt_strmout_en; | 68 | u32 vgt_strmout_en; |
64 | u32 vgt_strmout_buffer_en; | 69 | u32 vgt_strmout_buffer_en; |
@@ -311,7 +316,15 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
311 | track->cb_color_bo[i] = NULL; | 316 | track->cb_color_bo[i] = NULL; |
312 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 317 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
313 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 318 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
314 | } | 319 | track->cb_color_frag_bo[i] = NULL; |
320 | track->cb_color_frag_offset[i] = 0xFFFFFFFF; | ||
321 | track->cb_color_tile_bo[i] = NULL; | ||
322 | track->cb_color_tile_offset[i] = 0xFFFFFFFF; | ||
323 | track->cb_color_mask[i] = 0xFFFFFFFF; | ||
324 | } | ||
325 | track->is_resolve = false; | ||
326 | track->nsamples = 16; | ||
327 | track->log_nsamples = 4; | ||
315 | track->cb_target_mask = 0xFFFFFFFF; | 328 | track->cb_target_mask = 0xFFFFFFFF; |
316 | track->cb_shader_mask = 0xFFFFFFFF; | 329 | track->cb_shader_mask = 0xFFFFFFFF; |
317 | track->cb_dirty = true; | 330 | track->cb_dirty = true; |
@@ -348,11 +361,9 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
348 | volatile u32 *ib = p->ib.ptr; | 361 | volatile u32 *ib = p->ib.ptr; |
349 | unsigned array_mode; | 362 | unsigned array_mode; |
350 | u32 format; | 363 | u32 format; |
364 | /* When resolve is used, the second colorbuffer has always 1 sample. */ | ||
365 | unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; | ||
351 | 366 | ||
352 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
353 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); | ||
354 | return -EINVAL; | ||
355 | } | ||
356 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 367 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
357 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 368 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
358 | if (!r600_fmt_is_valid_color(format)) { | 369 | if (!r600_fmt_is_valid_color(format)) { |
@@ -375,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
375 | array_check.group_size = track->group_size; | 386 | array_check.group_size = track->group_size; |
376 | array_check.nbanks = track->nbanks; | 387 | array_check.nbanks = track->nbanks; |
377 | array_check.npipes = track->npipes; | 388 | array_check.npipes = track->npipes; |
378 | array_check.nsamples = track->nsamples; | 389 | array_check.nsamples = nsamples; |
379 | array_check.blocksize = r600_fmt_get_blocksize(format); | 390 | array_check.blocksize = r600_fmt_get_blocksize(format); |
380 | if (r600_get_array_mode_alignment(&array_check, | 391 | if (r600_get_array_mode_alignment(&array_check, |
381 | &pitch_align, &height_align, &depth_align, &base_align)) { | 392 | &pitch_align, &height_align, &depth_align, &base_align)) { |
@@ -420,7 +431,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
420 | } | 431 | } |
421 | 432 | ||
422 | /* check offset */ | 433 | /* check offset */ |
423 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); | 434 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * |
435 | r600_fmt_get_blocksize(format) * nsamples; | ||
424 | switch (array_mode) { | 436 | switch (array_mode) { |
425 | default: | 437 | default: |
426 | case V_0280A0_ARRAY_LINEAR_GENERAL: | 438 | case V_0280A0_ARRAY_LINEAR_GENERAL: |
@@ -441,7 +453,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
441 | * broken userspace. | 453 | * broken userspace. |
442 | */ | 454 | */ |
443 | } else { | 455 | } else { |
444 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", | 456 | dev_warn(p->dev, "%s offset[%d] %d %llu %d %lu too big (%d %d) (%d %d %d)\n", |
445 | __func__, i, array_mode, | 457 | __func__, i, array_mode, |
446 | track->cb_color_bo_offset[i], tmp, | 458 | track->cb_color_bo_offset[i], tmp, |
447 | radeon_bo_size(track->cb_color_bo[i]), | 459 | radeon_bo_size(track->cb_color_bo[i]), |
@@ -458,6 +470,51 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
458 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | | 470 | tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | |
459 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); | 471 | S_028060_SLICE_TILE_MAX(slice_tile_max - 1); |
460 | ib[track->cb_color_size_idx[i]] = tmp; | 472 | ib[track->cb_color_size_idx[i]] = tmp; |
473 | |||
474 | /* FMASK/CMASK */ | ||
475 | switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | ||
476 | case V_0280A0_TILE_DISABLE: | ||
477 | break; | ||
478 | case V_0280A0_FRAG_ENABLE: | ||
479 | if (track->nsamples > 1) { | ||
480 | uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); | ||
481 | /* the tile size is 8x8, but the size is in units of bits. | ||
482 | * for bytes, do just * 8. */ | ||
483 | uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); | ||
484 | |||
485 | if (bytes + track->cb_color_frag_offset[i] > | ||
486 | radeon_bo_size(track->cb_color_frag_bo[i])) { | ||
487 | dev_warn(p->dev, "%s FMASK_TILE_MAX too large " | ||
488 | "(tile_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
489 | __func__, tile_max, bytes, | ||
490 | track->cb_color_frag_offset[i], | ||
491 | radeon_bo_size(track->cb_color_frag_bo[i])); | ||
492 | return -EINVAL; | ||
493 | } | ||
494 | } | ||
495 | /* fall through */ | ||
496 | case V_0280A0_CLEAR_ENABLE: | ||
497 | { | ||
498 | uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); | ||
499 | /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. | ||
500 | * (128*128) / (8*8) / 2 = 128 bytes per block. */ | ||
501 | uint32_t bytes = (block_max + 1) * 128; | ||
502 | |||
503 | if (bytes + track->cb_color_tile_offset[i] > | ||
504 | radeon_bo_size(track->cb_color_tile_bo[i])) { | ||
505 | dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " | ||
506 | "(block_max=%u, bytes=%u, offset=%llu, bo_size=%lu)\n", | ||
507 | __func__, block_max, bytes, | ||
508 | track->cb_color_tile_offset[i], | ||
509 | radeon_bo_size(track->cb_color_tile_bo[i])); | ||
510 | return -EINVAL; | ||
511 | } | ||
512 | break; | ||
513 | } | ||
514 | default: | ||
515 | dev_warn(p->dev, "%s invalid tile mode\n", __func__); | ||
516 | return -EINVAL; | ||
517 | } | ||
461 | return 0; | 518 | return 0; |
462 | } | 519 | } |
463 | 520 | ||
@@ -566,7 +623,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) | |||
566 | 623 | ||
567 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; | 624 | ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; |
568 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; | 625 | nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; |
569 | tmp = ntiles * bpe * 64 * nviews; | 626 | tmp = ntiles * bpe * 64 * nviews * track->nsamples; |
570 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { | 627 | if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { |
571 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", | 628 | dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", |
572 | array_mode, | 629 | array_mode, |
@@ -746,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
746 | */ | 803 | */ |
747 | if (track->cb_dirty) { | 804 | if (track->cb_dirty) { |
748 | tmp = track->cb_target_mask; | 805 | tmp = track->cb_target_mask; |
806 | |||
807 | /* We must check both colorbuffers for RESOLVE. */ | ||
808 | if (track->is_resolve) { | ||
809 | tmp |= 0xff; | ||
810 | } | ||
811 | |||
749 | for (i = 0; i < 8; i++) { | 812 | for (i = 0; i < 8; i++) { |
750 | if ((tmp >> (i * 4)) & 0xF) { | 813 | if ((tmp >> (i * 4)) & 0xF) { |
751 | /* at least one component is enabled */ | 814 | /* at least one component is enabled */ |
@@ -764,8 +827,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
764 | } | 827 | } |
765 | 828 | ||
766 | /* Check depth buffer */ | 829 | /* Check depth buffer */ |
767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 830 | if (track->db_dirty && |
768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 831 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
832 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
833 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
769 | r = r600_cs_track_validate_db(p); | 834 | r = r600_cs_track_validate_db(p); |
770 | if (r) | 835 | if (r) |
771 | return r; | 836 | return r; |
@@ -1229,9 +1294,15 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1229 | break; | 1294 | break; |
1230 | case R_028C04_PA_SC_AA_CONFIG: | 1295 | case R_028C04_PA_SC_AA_CONFIG: |
1231 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); | 1296 | tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); |
1297 | track->log_nsamples = tmp; | ||
1232 | track->nsamples = 1 << tmp; | 1298 | track->nsamples = 1 << tmp; |
1233 | track->cb_dirty = true; | 1299 | track->cb_dirty = true; |
1234 | break; | 1300 | break; |
1301 | case R_028808_CB_COLOR_CONTROL: | ||
1302 | tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); | ||
1303 | track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; | ||
1304 | track->cb_dirty = true; | ||
1305 | break; | ||
1235 | case R_0280A0_CB_COLOR0_INFO: | 1306 | case R_0280A0_CB_COLOR0_INFO: |
1236 | case R_0280A4_CB_COLOR1_INFO: | 1307 | case R_0280A4_CB_COLOR1_INFO: |
1237 | case R_0280A8_CB_COLOR2_INFO: | 1308 | case R_0280A8_CB_COLOR2_INFO: |
@@ -1310,16 +1381,21 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1310 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1381 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1311 | return -EINVAL; | 1382 | return -EINVAL; |
1312 | } | 1383 | } |
1313 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1314 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; | 1384 | track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; |
1385 | track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1386 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1315 | } else { | 1387 | } else { |
1316 | r = r600_cs_packet_next_reloc(p, &reloc); | 1388 | r = r600_cs_packet_next_reloc(p, &reloc); |
1317 | if (r) { | 1389 | if (r) { |
1318 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1390 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1319 | return -EINVAL; | 1391 | return -EINVAL; |
1320 | } | 1392 | } |
1321 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1322 | track->cb_color_frag_bo[tmp] = reloc->robj; | 1393 | track->cb_color_frag_bo[tmp] = reloc->robj; |
1394 | track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; | ||
1395 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1396 | } | ||
1397 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1398 | track->cb_dirty = true; | ||
1323 | } | 1399 | } |
1324 | break; | 1400 | break; |
1325 | case R_0280C0_CB_COLOR0_TILE: | 1401 | case R_0280C0_CB_COLOR0_TILE: |
@@ -1336,16 +1412,35 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1336 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); | 1412 | dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); |
1337 | return -EINVAL; | 1413 | return -EINVAL; |
1338 | } | 1414 | } |
1339 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1340 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; | 1415 | track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; |
1416 | track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; | ||
1417 | ib[idx] = track->cb_color_base_last[tmp]; | ||
1341 | } else { | 1418 | } else { |
1342 | r = r600_cs_packet_next_reloc(p, &reloc); | 1419 | r = r600_cs_packet_next_reloc(p, &reloc); |
1343 | if (r) { | 1420 | if (r) { |
1344 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1421 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1345 | return -EINVAL; | 1422 | return -EINVAL; |
1346 | } | 1423 | } |
1347 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1348 | track->cb_color_tile_bo[tmp] = reloc->robj; | 1424 | track->cb_color_tile_bo[tmp] = reloc->robj; |
1425 | track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; | ||
1426 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1427 | } | ||
1428 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1429 | track->cb_dirty = true; | ||
1430 | } | ||
1431 | break; | ||
1432 | case R_028100_CB_COLOR0_MASK: | ||
1433 | case R_028104_CB_COLOR1_MASK: | ||
1434 | case R_028108_CB_COLOR2_MASK: | ||
1435 | case R_02810C_CB_COLOR3_MASK: | ||
1436 | case R_028110_CB_COLOR4_MASK: | ||
1437 | case R_028114_CB_COLOR5_MASK: | ||
1438 | case R_028118_CB_COLOR6_MASK: | ||
1439 | case R_02811C_CB_COLOR7_MASK: | ||
1440 | tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; | ||
1441 | track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); | ||
1442 | if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { | ||
1443 | track->cb_dirty = true; | ||
1349 | } | 1444 | } |
1350 | break; | 1445 | break; |
1351 | case CB_COLOR0_BASE: | 1446 | case CB_COLOR0_BASE: |
@@ -1490,7 +1585,7 @@ unsigned r600_mip_minify(unsigned size, unsigned level) | |||
1490 | } | 1585 | } |
1491 | 1586 | ||
1492 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | 1587 | static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, |
1493 | unsigned w0, unsigned h0, unsigned d0, unsigned format, | 1588 | unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, |
1494 | unsigned block_align, unsigned height_align, unsigned base_align, | 1589 | unsigned block_align, unsigned height_align, unsigned base_align, |
1495 | unsigned *l0_size, unsigned *mipmap_size) | 1590 | unsigned *l0_size, unsigned *mipmap_size) |
1496 | { | 1591 | { |
@@ -1518,7 +1613,7 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | |||
1518 | 1613 | ||
1519 | depth = r600_mip_minify(d0, i); | 1614 | depth = r600_mip_minify(d0, i); |
1520 | 1615 | ||
1521 | size = nbx * nby * blocksize; | 1616 | size = nbx * nby * blocksize * nsamples; |
1522 | if (nfaces) | 1617 | if (nfaces) |
1523 | size *= nfaces; | 1618 | size *= nfaces; |
1524 | else | 1619 | else |
@@ -1557,13 +1652,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1557 | u32 tiling_flags) | 1652 | u32 tiling_flags) |
1558 | { | 1653 | { |
1559 | struct r600_cs_track *track = p->track; | 1654 | struct r600_cs_track *track = p->track; |
1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1655 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1656 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
1562 | u32 height_align, pitch, pitch_align, depth_align; | 1657 | u32 height_align, pitch, pitch_align, depth_align; |
1563 | u32 array, barray, larray; | 1658 | u32 barray, larray; |
1564 | u64 base_align; | 1659 | u64 base_align; |
1565 | struct array_mode_checker array_check; | 1660 | struct array_mode_checker array_check; |
1566 | u32 format; | 1661 | u32 format; |
1662 | bool is_array; | ||
1567 | 1663 | ||
1568 | /* on legacy kernel we don't perform advanced check */ | 1664 | /* on legacy kernel we don't perform advanced check */ |
1569 | if (p->rdev == NULL) | 1665 | if (p->rdev == NULL) |
@@ -1581,12 +1677,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1677 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
1582 | } | 1678 | } |
1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1679 | word1 = radeon_get_ib_value(p, idx + 1); |
1680 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1681 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1682 | word4 = radeon_get_ib_value(p, idx + 4); | ||
1683 | word5 = radeon_get_ib_value(p, idx + 5); | ||
1684 | dim = G_038000_DIM(word0); | ||
1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1685 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1686 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1687 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1586 | d0 = G_038004_TEX_DEPTH(word1); | 1688 | d0 = G_038004_TEX_DEPTH(word1); |
1689 | format = G_038004_DATA_FORMAT(word1); | ||
1690 | blevel = G_038010_BASE_LEVEL(word4); | ||
1691 | llevel = G_038014_LAST_LEVEL(word5); | ||
1692 | /* pitch in texels */ | ||
1693 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1694 | array_check.group_size = track->group_size; | ||
1695 | array_check.nbanks = track->nbanks; | ||
1696 | array_check.npipes = track->npipes; | ||
1697 | array_check.nsamples = 1; | ||
1698 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1587 | nfaces = 1; | 1699 | nfaces = 1; |
1588 | array = 0; | 1700 | is_array = false; |
1589 | switch (G_038000_DIM(word0)) { | 1701 | switch (dim) { |
1590 | case V_038000_SQ_TEX_DIM_1D: | 1702 | case V_038000_SQ_TEX_DIM_1D: |
1591 | case V_038000_SQ_TEX_DIM_2D: | 1703 | case V_038000_SQ_TEX_DIM_2D: |
1592 | case V_038000_SQ_TEX_DIM_3D: | 1704 | case V_038000_SQ_TEX_DIM_3D: |
@@ -1599,29 +1711,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1599 | break; | 1711 | break; |
1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1712 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1713 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
1602 | array = 1; | 1714 | is_array = true; |
1603 | break; | 1715 | break; |
1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1716 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
1717 | is_array = true; | ||
1718 | /* fall through */ | ||
1719 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1720 | array_check.nsamples = 1 << llevel; | ||
1721 | llevel = 0; | ||
1722 | break; | ||
1606 | default: | 1723 | default: |
1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1724 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
1608 | return -EINVAL; | 1725 | return -EINVAL; |
1609 | } | 1726 | } |
1610 | format = G_038004_DATA_FORMAT(word1); | ||
1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1727 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1728 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
1613 | __func__, __LINE__, format); | 1729 | __func__, __LINE__, format); |
1614 | return -EINVAL; | 1730 | return -EINVAL; |
1615 | } | 1731 | } |
1616 | 1732 | ||
1617 | /* pitch in texels */ | ||
1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1620 | array_check.group_size = track->group_size; | ||
1621 | array_check.nbanks = track->nbanks; | ||
1622 | array_check.npipes = track->npipes; | ||
1623 | array_check.nsamples = 1; | ||
1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1625 | if (r600_get_array_mode_alignment(&array_check, | 1733 | if (r600_get_array_mode_alignment(&array_check, |
1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1734 | &pitch_align, &height_align, &depth_align, &base_align)) { |
1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1735 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
@@ -1647,24 +1755,17 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1647 | return -EINVAL; | 1755 | return -EINVAL; |
1648 | } | 1756 | } |
1649 | 1757 | ||
1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1652 | |||
1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
1657 | if (blevel > llevel) { | 1758 | if (blevel > llevel) { |
1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1759 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
1659 | blevel, llevel); | 1760 | blevel, llevel); |
1660 | } | 1761 | } |
1661 | if (array == 1) { | 1762 | if (is_array) { |
1662 | barray = G_038014_BASE_ARRAY(word1); | 1763 | barray = G_038014_BASE_ARRAY(word5); |
1663 | larray = G_038014_LAST_ARRAY(word1); | 1764 | larray = G_038014_LAST_ARRAY(word5); |
1664 | 1765 | ||
1665 | nfaces = larray - barray + 1; | 1766 | nfaces = larray - barray + 1; |
1666 | } | 1767 | } |
1667 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, format, | 1768 | r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, |
1668 | pitch_align, height_align, base_align, | 1769 | pitch_align, height_align, base_align, |
1669 | &l0_size, &mipmap_size); | 1770 | &l0_size, &mipmap_size); |
1670 | /* using get ib will give us the offset into the texture bo */ | 1771 | /* using get ib will give us the offset into the texture bo */ |
@@ -1677,7 +1778,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1677 | return -EINVAL; | 1778 | return -EINVAL; |
1678 | } | 1779 | } |
1679 | /* using get ib will give us the offset into the mipmap bo */ | 1780 | /* using get ib will give us the offset into the mipmap bo */ |
1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1781 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1782 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1783 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae75fc2..fa6f37099ba9 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -66,6 +66,14 @@ | |||
66 | #define CC_RB_BACKEND_DISABLE 0x98F4 | 66 | #define CC_RB_BACKEND_DISABLE 0x98F4 |
67 | #define BACKEND_DISABLE(x) ((x) << 16) | 67 | #define BACKEND_DISABLE(x) ((x) << 16) |
68 | 68 | ||
69 | #define R_028808_CB_COLOR_CONTROL 0x28808 | ||
70 | #define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) | ||
71 | #define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) | ||
72 | #define C_028808_SPECIAL_OP 0xFFFFFF8F | ||
73 | #define V_028808_SPECIAL_NORMAL 0x00 | ||
74 | #define V_028808_SPECIAL_DISABLE 0x01 | ||
75 | #define V_028808_SPECIAL_RESOLVE_BOX 0x07 | ||
76 | |||
69 | #define CB_COLOR0_BASE 0x28040 | 77 | #define CB_COLOR0_BASE 0x28040 |
70 | #define CB_COLOR1_BASE 0x28044 | 78 | #define CB_COLOR1_BASE 0x28044 |
71 | #define CB_COLOR2_BASE 0x28048 | 79 | #define CB_COLOR2_BASE 0x28048 |
@@ -92,6 +100,20 @@ | |||
92 | #define R_028094_CB_COLOR5_VIEW 0x028094 | 100 | #define R_028094_CB_COLOR5_VIEW 0x028094 |
93 | #define R_028098_CB_COLOR6_VIEW 0x028098 | 101 | #define R_028098_CB_COLOR6_VIEW 0x028098 |
94 | #define R_02809C_CB_COLOR7_VIEW 0x02809C | 102 | #define R_02809C_CB_COLOR7_VIEW 0x02809C |
103 | #define R_028100_CB_COLOR0_MASK 0x028100 | ||
104 | #define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0) | ||
105 | #define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF) | ||
106 | #define C_028100_CMASK_BLOCK_MAX 0xFFFFF000 | ||
107 | #define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12) | ||
108 | #define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF) | ||
109 | #define C_028100_FMASK_TILE_MAX 0x00000FFF | ||
110 | #define R_028104_CB_COLOR1_MASK 0x028104 | ||
111 | #define R_028108_CB_COLOR2_MASK 0x028108 | ||
112 | #define R_02810C_CB_COLOR3_MASK 0x02810C | ||
113 | #define R_028110_CB_COLOR4_MASK 0x028110 | ||
114 | #define R_028114_CB_COLOR5_MASK 0x028114 | ||
115 | #define R_028118_CB_COLOR6_MASK 0x028118 | ||
116 | #define R_02811C_CB_COLOR7_MASK 0x02811C | ||
95 | #define CB_COLOR0_INFO 0x280a0 | 117 | #define CB_COLOR0_INFO 0x280a0 |
96 | # define CB_FORMAT(x) ((x) << 2) | 118 | # define CB_FORMAT(x) ((x) << 2) |
97 | # define CB_ARRAY_MODE(x) ((x) << 8) | 119 | # define CB_ARRAY_MODE(x) ((x) << 8) |
@@ -602,6 +624,9 @@ | |||
602 | #define RLC_HB_WPTR 0x3f1c | 624 | #define RLC_HB_WPTR 0x3f1c |
603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | 625 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 |
604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | 626 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 |
627 | #define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 | ||
628 | #define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c | ||
629 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 | ||
605 | #define RLC_MC_CNTL 0x3f44 | 630 | #define RLC_MC_CNTL 0x3f44 |
606 | #define RLC_UCODE_CNTL 0x3f48 | 631 | #define RLC_UCODE_CNTL 0x3f48 |
607 | #define RLC_UCODE_ADDR 0x3f2c | 632 | #define RLC_UCODE_ADDR 0x3f2c |
@@ -1397,6 +1422,9 @@ | |||
1397 | #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) | 1422 | #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) |
1398 | #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) | 1423 | #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) |
1399 | #define C_0280A0_TILE_MODE 0xFFF3FFFF | 1424 | #define C_0280A0_TILE_MODE 0xFFF3FFFF |
1425 | #define V_0280A0_TILE_DISABLE 0 | ||
1426 | #define V_0280A0_CLEAR_ENABLE 1 | ||
1427 | #define V_0280A0_FRAG_ENABLE 2 | ||
1400 | #define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) | 1428 | #define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20) |
1401 | #define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) | 1429 | #define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1) |
1402 | #define C_0280A0_BLEND_CLAMP 0xFFEFFFFF | 1430 | #define C_0280A0_BLEND_CLAMP 0xFFEFFFFF |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5431af292408..59a15315ae9f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -142,21 +142,6 @@ struct radeon_device; | |||
142 | /* | 142 | /* |
143 | * BIOS. | 143 | * BIOS. |
144 | */ | 144 | */ |
145 | #define ATRM_BIOS_PAGE 4096 | ||
146 | |||
147 | #if defined(CONFIG_VGA_SWITCHEROO) | ||
148 | bool radeon_atrm_supported(struct pci_dev *pdev); | ||
149 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len); | ||
150 | #else | ||
151 | static inline bool radeon_atrm_supported(struct pci_dev *pdev) | ||
152 | { | ||
153 | return false; | ||
154 | } | ||
155 | |||
156 | static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){ | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | #endif | ||
160 | bool radeon_get_bios(struct radeon_device *rdev); | 145 | bool radeon_get_bios(struct radeon_device *rdev); |
161 | 146 | ||
162 | /* | 147 | /* |
@@ -300,6 +285,7 @@ struct radeon_bo_va { | |||
300 | uint64_t soffset; | 285 | uint64_t soffset; |
301 | uint64_t eoffset; | 286 | uint64_t eoffset; |
302 | uint32_t flags; | 287 | uint32_t flags; |
288 | struct radeon_fence *fence; | ||
303 | bool valid; | 289 | bool valid; |
304 | }; | 290 | }; |
305 | 291 | ||
@@ -1533,6 +1519,7 @@ struct radeon_device { | |||
1533 | unsigned debugfs_count; | 1519 | unsigned debugfs_count; |
1534 | /* virtual memory */ | 1520 | /* virtual memory */ |
1535 | struct radeon_vm_manager vm_manager; | 1521 | struct radeon_vm_manager vm_manager; |
1522 | struct mutex gpu_clock_mutex; | ||
1536 | }; | 1523 | }; |
1537 | 1524 | ||
1538 | int radeon_device_init(struct radeon_device *rdev, | 1525 | int radeon_device_init(struct radeon_device *rdev, |
@@ -1733,11 +1720,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
1733 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) | 1720 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) |
1734 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) | 1721 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) |
1735 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) | 1722 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) |
1736 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) | 1723 | #define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) |
1737 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) | 1724 | #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) |
1738 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) | 1725 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
1739 | #define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) | 1726 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
1740 | #define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) | 1727 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
1741 | 1728 | ||
1742 | /* Common functions */ | 1729 | /* Common functions */ |
1743 | /* AGP */ | 1730 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4af24310438..18c38d14c8cd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
255 | * rv515 | 255 | * rv515 |
256 | */ | 256 | */ |
257 | struct rv515_mc_save { | 257 | struct rv515_mc_save { |
258 | u32 d1vga_control; | ||
259 | u32 d2vga_control; | ||
260 | u32 vga_render_control; | 258 | u32 vga_render_control; |
261 | u32 vga_hdp_control; | 259 | u32 vga_hdp_control; |
262 | u32 d1crtc_control; | ||
263 | u32 d2crtc_control; | ||
264 | }; | 260 | }; |
261 | |||
265 | int rv515_init(struct radeon_device *rdev); | 262 | int rv515_init(struct radeon_device *rdev); |
266 | void rv515_fini(struct radeon_device *rdev); | 263 | void rv515_fini(struct radeon_device *rdev); |
267 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 264 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
@@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
371 | unsigned num_gpu_pages, | 368 | unsigned num_gpu_pages, |
372 | struct radeon_sa_bo *vb); | 369 | struct radeon_sa_bo *vb); |
373 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 370 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
371 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | ||
374 | 372 | ||
375 | /* | 373 | /* |
376 | * rv770,rv730,rv710,rv740 | 374 | * rv770,rv730,rv710,rv740 |
@@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
389 | * evergreen | 387 | * evergreen |
390 | */ | 388 | */ |
391 | struct evergreen_mc_save { | 389 | struct evergreen_mc_save { |
392 | u32 vga_control[6]; | ||
393 | u32 vga_render_control; | 390 | u32 vga_render_control; |
394 | u32 vga_hdp_control; | 391 | u32 vga_hdp_control; |
395 | u32 crtc_control[6]; | ||
396 | }; | 392 | }; |
393 | |||
397 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
398 | int evergreen_init(struct radeon_device *rdev); | 395 | int evergreen_init(struct radeon_device *rdev); |
399 | void evergreen_fini(struct radeon_device *rdev); | 396 | void evergreen_fini(struct radeon_device *rdev); |
@@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | |||
472 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); |
473 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); |
474 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
475 | 473 | ||
476 | #endif | 474 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1e3820df363..d67d4f3eb6f4 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -452,7 +452,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
452 | } | 452 | } |
453 | 453 | ||
454 | /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ | 454 | /* Fujitsu D3003-S2 board lists DVI-I as DVI-D and VGA */ |
455 | if ((dev->pdev->device == 0x9802) && | 455 | if (((dev->pdev->device == 0x9802) || (dev->pdev->device == 0x9806)) && |
456 | (dev->pdev->subsystem_vendor == 0x1734) && | 456 | (dev->pdev->subsystem_vendor == 0x1734) && |
457 | (dev->pdev->subsystem_device == 0x11bd)) { | 457 | (dev->pdev->subsystem_device == 0x11bd)) { |
458 | if (*connector_type == DRM_MODE_CONNECTOR_VGA) { | 458 | if (*connector_type == DRM_MODE_CONNECTOR_VGA) { |
@@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
1263 | union igp_info { | 1263 | union igp_info { |
1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
1266 | }; | 1268 | }; |
1267 | 1269 | ||
1268 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1270 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
@@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | |||
1390 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1392 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1391 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | 1393 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); |
1392 | u16 data_offset, size; | 1394 | u16 data_offset, size; |
1393 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | 1395 | union igp_info *igp_info; |
1394 | u8 frev, crev; | 1396 | u8 frev, crev; |
1395 | u16 percentage = 0, rate = 0; | 1397 | u16 percentage = 0, rate = 0; |
1396 | 1398 | ||
1397 | /* get any igp specific overrides */ | 1399 | /* get any igp specific overrides */ |
1398 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | 1400 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
1399 | &frev, &crev, &data_offset)) { | 1401 | &frev, &crev, &data_offset)) { |
1400 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | 1402 | igp_info = (union igp_info *) |
1401 | (mode_info->atom_context->bios + data_offset); | 1403 | (mode_info->atom_context->bios + data_offset); |
1402 | switch (id) { | 1404 | switch (crev) { |
1403 | case ASIC_INTERNAL_SS_ON_TMDS: | 1405 | case 6: |
1404 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | 1406 | switch (id) { |
1405 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | 1407 | case ASIC_INTERNAL_SS_ON_TMDS: |
1408 | percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); | ||
1409 | rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); | ||
1410 | break; | ||
1411 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
1412 | percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); | ||
1413 | rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); | ||
1414 | break; | ||
1415 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
1416 | percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); | ||
1417 | rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); | ||
1418 | break; | ||
1419 | } | ||
1406 | break; | 1420 | break; |
1407 | case ASIC_INTERNAL_SS_ON_HDMI: | 1421 | case 7: |
1408 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | 1422 | switch (id) { |
1409 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | 1423 | case ASIC_INTERNAL_SS_ON_TMDS: |
1424 | percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); | ||
1425 | rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); | ||
1426 | break; | ||
1427 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
1428 | percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); | ||
1429 | rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); | ||
1430 | break; | ||
1431 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
1432 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); | ||
1433 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); | ||
1434 | break; | ||
1435 | } | ||
1410 | break; | 1436 | break; |
1411 | case ASIC_INTERNAL_SS_ON_LVDS: | 1437 | default: |
1412 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | 1438 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
1413 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
1414 | break; | 1439 | break; |
1415 | } | 1440 | } |
1416 | if (percentage) | 1441 | if (percentage) |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb0088..2a2cf0b88a28 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv { | |||
30 | /* handle for device - and atpx */ | 30 | /* handle for device - and atpx */ |
31 | acpi_handle dhandle; | 31 | acpi_handle dhandle; |
32 | acpi_handle atpx_handle; | 32 | acpi_handle atpx_handle; |
33 | acpi_handle atrm_handle; | ||
34 | } radeon_atpx_priv; | 33 | } radeon_atpx_priv; |
35 | 34 | ||
36 | /* retrieve the ROM in 4k blocks */ | ||
37 | static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||
38 | int offset, int len) | ||
39 | { | ||
40 | acpi_status status; | ||
41 | union acpi_object atrm_arg_elements[2], *obj; | ||
42 | struct acpi_object_list atrm_arg; | ||
43 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
44 | |||
45 | atrm_arg.count = 2; | ||
46 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||
47 | |||
48 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
49 | atrm_arg_elements[0].integer.value = offset; | ||
50 | |||
51 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
52 | atrm_arg_elements[1].integer.value = len; | ||
53 | |||
54 | status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); | ||
55 | if (ACPI_FAILURE(status)) { | ||
56 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||
57 | return -ENODEV; | ||
58 | } | ||
59 | |||
60 | obj = (union acpi_object *)buffer.pointer; | ||
61 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); | ||
62 | len = obj->buffer.length; | ||
63 | kfree(buffer.pointer); | ||
64 | return len; | ||
65 | } | ||
66 | |||
67 | bool radeon_atrm_supported(struct pci_dev *pdev) | ||
68 | { | ||
69 | /* get the discrete ROM only via ATRM */ | ||
70 | if (!radeon_atpx_priv.atpx_detected) | ||
71 | return false; | ||
72 | |||
73 | if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
74 | return false; | ||
75 | return true; | ||
76 | } | ||
77 | |||
78 | |||
79 | int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len) | ||
80 | { | ||
81 | return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len); | ||
82 | } | ||
83 | |||
84 | static int radeon_atpx_get_version(acpi_handle handle) | 35 | static int radeon_atpx_get_version(acpi_handle handle) |
85 | { | 36 | { |
86 | acpi_status status; | 37 | acpi_status status; |
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, | |||
198 | 149 | ||
199 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | 150 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
200 | { | 151 | { |
201 | acpi_handle dhandle, atpx_handle, atrm_handle; | 152 | acpi_handle dhandle, atpx_handle; |
202 | acpi_status status; | 153 | acpi_status status; |
203 | 154 | ||
204 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | 155 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
209 | if (ACPI_FAILURE(status)) | 160 | if (ACPI_FAILURE(status)) |
210 | return false; | 161 | return false; |
211 | 162 | ||
212 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||
213 | if (ACPI_FAILURE(status)) | ||
214 | return false; | ||
215 | |||
216 | radeon_atpx_priv.dhandle = dhandle; | 163 | radeon_atpx_priv.dhandle = dhandle; |
217 | radeon_atpx_priv.atpx_handle = atpx_handle; | 164 | radeon_atpx_priv.atpx_handle = atpx_handle; |
218 | radeon_atpx_priv.atrm_handle = atrm_handle; | ||
219 | return true; | 165 | return true; |
220 | } | 166 | } |
221 | 167 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 501f4881e5aa..d306cc8fdeaa 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/vga_switcheroo.h> | 33 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/acpi.h> | ||
35 | /* | 36 | /* |
36 | * BIOS. | 37 | * BIOS. |
37 | */ | 38 | */ |
@@ -98,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev) | |||
98 | return true; | 99 | return true; |
99 | } | 100 | } |
100 | 101 | ||
102 | #ifdef CONFIG_ACPI | ||
101 | /* ATRM is used to get the BIOS on the discrete cards in | 103 | /* ATRM is used to get the BIOS on the discrete cards in |
102 | * dual-gpu systems. | 104 | * dual-gpu systems. |
103 | */ | 105 | */ |
106 | /* retrieve the ROM in 4k blocks */ | ||
107 | #define ATRM_BIOS_PAGE 4096 | ||
108 | /** | ||
109 | * radeon_atrm_call - fetch a chunk of the vbios | ||
110 | * | ||
111 | * @atrm_handle: acpi ATRM handle | ||
112 | * @bios: vbios image pointer | ||
113 | * @offset: offset of vbios image data to fetch | ||
114 | * @len: length of vbios image data to fetch | ||
115 | * | ||
116 | * Executes ATRM to fetch a chunk of the discrete | ||
117 | * vbios image on PX systems (all asics). | ||
118 | * Returns the length of the buffer fetched. | ||
119 | */ | ||
120 | static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | ||
121 | int offset, int len) | ||
122 | { | ||
123 | acpi_status status; | ||
124 | union acpi_object atrm_arg_elements[2], *obj; | ||
125 | struct acpi_object_list atrm_arg; | ||
126 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; | ||
127 | |||
128 | atrm_arg.count = 2; | ||
129 | atrm_arg.pointer = &atrm_arg_elements[0]; | ||
130 | |||
131 | atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; | ||
132 | atrm_arg_elements[0].integer.value = offset; | ||
133 | |||
134 | atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; | ||
135 | atrm_arg_elements[1].integer.value = len; | ||
136 | |||
137 | status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); | ||
138 | if (ACPI_FAILURE(status)) { | ||
139 | printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); | ||
140 | return -ENODEV; | ||
141 | } | ||
142 | |||
143 | obj = (union acpi_object *)buffer.pointer; | ||
144 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); | ||
145 | len = obj->buffer.length; | ||
146 | kfree(buffer.pointer); | ||
147 | return len; | ||
148 | } | ||
149 | |||
104 | static bool radeon_atrm_get_bios(struct radeon_device *rdev) | 150 | static bool radeon_atrm_get_bios(struct radeon_device *rdev) |
105 | { | 151 | { |
106 | int ret; | 152 | int ret; |
107 | int size = 256 * 1024; | 153 | int size = 256 * 1024; |
108 | int i; | 154 | int i; |
155 | struct pci_dev *pdev = NULL; | ||
156 | acpi_handle dhandle, atrm_handle; | ||
157 | acpi_status status; | ||
158 | bool found = false; | ||
159 | |||
160 | /* ATRM is for the discrete card only */ | ||
161 | if (rdev->flags & RADEON_IS_IGP) | ||
162 | return false; | ||
163 | |||
164 | while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { | ||
165 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | ||
166 | if (!dhandle) | ||
167 | continue; | ||
168 | |||
169 | status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); | ||
170 | if (!ACPI_FAILURE(status)) { | ||
171 | found = true; | ||
172 | break; | ||
173 | } | ||
174 | } | ||
109 | 175 | ||
110 | if (!radeon_atrm_supported(rdev->pdev)) | 176 | if (!found) |
111 | return false; | 177 | return false; |
112 | 178 | ||
113 | rdev->bios = kmalloc(size, GFP_KERNEL); | 179 | rdev->bios = kmalloc(size, GFP_KERNEL); |
@@ -117,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
117 | } | 183 | } |
118 | 184 | ||
119 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { | 185 | for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { |
120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | 186 | ret = radeon_atrm_call(atrm_handle, |
121 | (i * ATRM_BIOS_PAGE), | 187 | rdev->bios, |
122 | ATRM_BIOS_PAGE); | 188 | (i * ATRM_BIOS_PAGE), |
189 | ATRM_BIOS_PAGE); | ||
123 | if (ret < ATRM_BIOS_PAGE) | 190 | if (ret < ATRM_BIOS_PAGE) |
124 | break; | 191 | break; |
125 | } | 192 | } |
@@ -130,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
130 | } | 197 | } |
131 | return true; | 198 | return true; |
132 | } | 199 | } |
200 | #else | ||
201 | static inline bool radeon_atrm_get_bios(struct radeon_device *rdev) | ||
202 | { | ||
203 | return false; | ||
204 | } | ||
205 | #endif | ||
133 | 206 | ||
134 | static bool ni_read_disabled_bios(struct radeon_device *rdev) | 207 | static bool ni_read_disabled_bios(struct radeon_device *rdev) |
135 | { | 208 | { |
@@ -476,6 +549,61 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev) | |||
476 | return legacy_read_disabled_bios(rdev); | 549 | return legacy_read_disabled_bios(rdev); |
477 | } | 550 | } |
478 | 551 | ||
552 | #ifdef CONFIG_ACPI | ||
553 | static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | ||
554 | { | ||
555 | bool ret = false; | ||
556 | struct acpi_table_header *hdr; | ||
557 | acpi_size tbl_size; | ||
558 | UEFI_ACPI_VFCT *vfct; | ||
559 | GOP_VBIOS_CONTENT *vbios; | ||
560 | VFCT_IMAGE_HEADER *vhdr; | ||
561 | |||
562 | if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) | ||
563 | return false; | ||
564 | if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { | ||
565 | DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); | ||
566 | goto out_unmap; | ||
567 | } | ||
568 | |||
569 | vfct = (UEFI_ACPI_VFCT *)hdr; | ||
570 | if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { | ||
571 | DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); | ||
572 | goto out_unmap; | ||
573 | } | ||
574 | |||
575 | vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); | ||
576 | vhdr = &vbios->VbiosHeader; | ||
577 | DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", | ||
578 | vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, | ||
579 | vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); | ||
580 | |||
581 | if (vhdr->PCIBus != rdev->pdev->bus->number || | ||
582 | vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) || | ||
583 | vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) || | ||
584 | vhdr->VendorID != rdev->pdev->vendor || | ||
585 | vhdr->DeviceID != rdev->pdev->device) { | ||
586 | DRM_INFO("ACPI VFCT table is not for this card\n"); | ||
587 | goto out_unmap; | ||
588 | }; | ||
589 | |||
590 | if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { | ||
591 | DRM_ERROR("ACPI VFCT image truncated\n"); | ||
592 | goto out_unmap; | ||
593 | } | ||
594 | |||
595 | rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); | ||
596 | ret = !!rdev->bios; | ||
597 | |||
598 | out_unmap: | ||
599 | return ret; | ||
600 | } | ||
601 | #else | ||
602 | static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | ||
603 | { | ||
604 | return false; | ||
605 | } | ||
606 | #endif | ||
479 | 607 | ||
480 | bool radeon_get_bios(struct radeon_device *rdev) | 608 | bool radeon_get_bios(struct radeon_device *rdev) |
481 | { | 609 | { |
@@ -484,6 +612,8 @@ bool radeon_get_bios(struct radeon_device *rdev) | |||
484 | 612 | ||
485 | r = radeon_atrm_get_bios(rdev); | 613 | r = radeon_atrm_get_bios(rdev); |
486 | if (r == false) | 614 | if (r == false) |
615 | r = radeon_acpi_vfct_bios(rdev); | ||
616 | if (r == false) | ||
487 | r = igp_read_bios_from_vram(rdev); | 617 | r = igp_read_bios_from_vram(rdev); |
488 | if (r == false) | 618 | if (r == false) |
489 | r = radeon_read_bios(rdev); | 619 | r = radeon_read_bios(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..f75247d42ffd 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
719 | return i2c; | 719 | return i2c; |
720 | } | 720 | } |
721 | 721 | ||
722 | static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) | ||
723 | { | ||
724 | struct drm_device *dev = rdev->ddev; | ||
725 | struct radeon_i2c_bus_rec i2c; | ||
726 | u16 offset; | ||
727 | u8 id, blocks, clk, data; | ||
728 | int i; | ||
729 | |||
730 | i2c.valid = false; | ||
731 | |||
732 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | ||
733 | if (offset) { | ||
734 | blocks = RBIOS8(offset + 2); | ||
735 | for (i = 0; i < blocks; i++) { | ||
736 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
737 | if (id == 136) { | ||
738 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
739 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
740 | /* gpiopad */ | ||
741 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
742 | (1 << clk), (1 << data)); | ||
743 | break; | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | return i2c; | ||
748 | } | ||
749 | |||
722 | void radeon_combios_i2c_init(struct radeon_device *rdev) | 750 | void radeon_combios_i2c_init(struct radeon_device *rdev) |
723 | { | 751 | { |
724 | struct drm_device *dev = rdev->ddev; | 752 | struct drm_device *dev = rdev->ddev; |
@@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
755 | } else if (rdev->family == CHIP_RS300 || | 783 | } else if (rdev->family == CHIP_RS300 || |
756 | rdev->family == CHIP_RS400 || | 784 | rdev->family == CHIP_RS400 || |
757 | rdev->family == CHIP_RS480) { | 785 | rdev->family == CHIP_RS480) { |
758 | u16 offset; | ||
759 | u8 id, blocks, clk, data; | ||
760 | int i; | ||
761 | |||
762 | /* 0x68 */ | 786 | /* 0x68 */ |
763 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 787 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
764 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 788 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
765 | 789 | ||
766 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | 790 | /* gpiopad */ |
767 | if (offset) { | 791 | i2c = radeon_combios_get_i2c_info_from_table(rdev); |
768 | blocks = RBIOS8(offset + 2); | 792 | if (i2c.valid) |
769 | for (i = 0; i < blocks; i++) { | 793 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
770 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
771 | if (id == 136) { | ||
772 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
773 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
774 | /* gpiopad */ | ||
775 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
776 | (1 << clk), (1 << data)); | ||
777 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | } else if ((rdev->family == CHIP_R200) || | 794 | } else if ((rdev->family == CHIP_R200) || |
783 | (rdev->family >= CHIP_R300)) { | 795 | (rdev->family >= CHIP_R300)) { |
784 | /* 0x68 */ | 796 | /* 0x68 */ |
@@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2321 | connector = (tmp >> 12) & 0xf; | 2333 | connector = (tmp >> 12) & 0xf; |
2322 | 2334 | ||
2323 | ddc_type = (tmp >> 8) & 0xf; | 2335 | ddc_type = (tmp >> 8) & 0xf; |
2324 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | 2336 | if (ddc_type == 5) |
2337 | ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); | ||
2338 | else | ||
2339 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | ||
2325 | 2340 | ||
2326 | switch (connector) { | 2341 | switch (connector) { |
2327 | case CONNECTOR_PROPRIETARY_LEGACY: | 2342 | case CONNECTOR_PROPRIETARY_LEGACY: |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8a4c49ef0cc4..b4a0db24f4dd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | 280 | ||
281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
282 | struct radeon_fence *fence) | ||
283 | { | ||
284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
285 | struct radeon_vm *vm = &fpriv->vm; | ||
286 | struct radeon_bo_list *lobj; | ||
287 | |||
288 | if (parser->chunk_ib_idx == -1) { | ||
289 | return; | ||
290 | } | ||
291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
296 | struct radeon_bo_va *bo_va; | ||
297 | struct radeon_bo *rbo = lobj->bo; | ||
298 | |||
299 | bo_va = radeon_bo_va(rbo, vm); | ||
300 | radeon_fence_unref(&bo_va->fence); | ||
301 | bo_va->fence = radeon_fence_ref(fence); | ||
302 | } | ||
303 | } | ||
304 | |||
281 | /** | 305 | /** |
282 | * cs_parser_fini() - clean parser states | 306 | * cs_parser_fini() - clean parser states |
283 | * @parser: parser structure holding parsing context. | 307 | * @parser: parser structure holding parsing context. |
@@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
290 | { | 314 | { |
291 | unsigned i; | 315 | unsigned i; |
292 | 316 | ||
293 | if (!error) | 317 | if (!error) { |
318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
294 | ttm_eu_fence_buffer_objects(&parser->validated, | 320 | ttm_eu_fence_buffer_objects(&parser->validated, |
295 | parser->ib.fence); | 321 | parser->ib.fence); |
296 | else | 322 | } else { |
297 | ttm_eu_backoff_reservation(&parser->validated); | 323 | ttm_eu_backoff_reservation(&parser->validated); |
324 | } | ||
298 | 325 | ||
299 | if (parser->relocs != NULL) { | 326 | if (parser->relocs != NULL) { |
300 | for (i = 0; i < parser->nrelocs; i++) { | 327 | for (i = 0; i < parser->nrelocs; i++) { |
@@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
388 | 415 | ||
389 | if (parser->chunk_ib_idx == -1) | 416 | if (parser->chunk_ib_idx == -1) |
390 | return 0; | 417 | return 0; |
391 | |||
392 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 418 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
393 | return 0; | 419 | return 0; |
394 | 420 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 711e95ad39bf..8794744cdf1a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
67 | 67 | ||
68 | if (ASIC_IS_DCE4(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
71 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
71 | } else if (ASIC_IS_AVIVO(rdev)) { | 72 | } else if (ASIC_IS_AVIVO(rdev)) { |
72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 73 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 74 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
@@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
94 | if (ASIC_IS_DCE4(rdev)) { | 95 | if (ASIC_IS_DCE4(rdev)) { |
95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 96 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | 97 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 98 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
99 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
98 | } else if (ASIC_IS_AVIVO(rdev)) { | 100 | } else if (ASIC_IS_AVIVO(rdev)) { |
99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 101 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 102 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af8244e89..7a3daebd732d 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1009 | atomic_set(&rdev->ih.lock, 0); | 1009 | atomic_set(&rdev->ih.lock, 0); |
1010 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
1011 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
1012 | mutex_init(&rdev->gpu_clock_mutex); | ||
1012 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
1013 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
1014 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
@@ -1050,7 +1051,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1050 | if (rdev->flags & RADEON_IS_AGP) | 1051 | if (rdev->flags & RADEON_IS_AGP) |
1051 | rdev->need_dma32 = true; | 1052 | rdev->need_dma32 = true; |
1052 | if ((rdev->flags & RADEON_IS_PCI) && | 1053 | if ((rdev->flags & RADEON_IS_PCI) && |
1053 | (rdev->family < CHIP_RS400)) | 1054 | (rdev->family <= CHIP_RS740)) |
1054 | rdev->need_dma32 = true; | 1055 | rdev->need_dma32 = true; |
1055 | 1056 | ||
1056 | dma_bits = rdev->need_dma32 ? 32 : 40; | 1057 | dma_bits = rdev->need_dma32 ? 32 : 40; |
@@ -1345,12 +1346,15 @@ retry: | |||
1345 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { | 1346 | for (i = 0; i < RADEON_NUM_RINGS; ++i) { |
1346 | radeon_ring_restore(rdev, &rdev->ring[i], | 1347 | radeon_ring_restore(rdev, &rdev->ring[i], |
1347 | ring_sizes[i], ring_data[i]); | 1348 | ring_sizes[i], ring_data[i]); |
1349 | ring_sizes[i] = 0; | ||
1350 | ring_data[i] = NULL; | ||
1348 | } | 1351 | } |
1349 | 1352 | ||
1350 | r = radeon_ib_ring_tests(rdev); | 1353 | r = radeon_ib_ring_tests(rdev); |
1351 | if (r) { | 1354 | if (r) { |
1352 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); | 1355 | dev_err(rdev->dev, "ib ring test failed (%d).\n", r); |
1353 | if (saved) { | 1356 | if (saved) { |
1357 | saved = false; | ||
1354 | radeon_suspend(rdev); | 1358 | radeon_suspend(rdev); |
1355 | goto retry; | 1359 | goto retry; |
1356 | } | 1360 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dcea6f01ae4e..8c593ea82c41 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -59,9 +59,14 @@ | |||
59 | * 2.15.0 - add max_pipes query | 59 | * 2.15.0 - add max_pipes query |
60 | * 2.16.0 - fix evergreen 2D tiled surface calculation | 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation |
61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx | 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx |
62 | * 2.18.0 - r600-eg: allow "invalid" DB formats | ||
63 | * 2.19.0 - r600-eg: MSAA textures | ||
64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | ||
65 | * 2.21.0 - r600-r700: FMASK and CMASK | ||
66 | * 2.22.0 - r600 only: RESOLVE_BOX allowed | ||
62 | */ | 67 | */ |
63 | #define KMS_DRIVER_MAJOR 2 | 68 | #define KMS_DRIVER_MAJOR 2 |
64 | #define KMS_DRIVER_MINOR 17 | 69 | #define KMS_DRIVER_MINOR 22 |
65 | #define KMS_DRIVER_PATCHLEVEL 0 | 70 | #define KMS_DRIVER_PATCHLEVEL 0 |
66 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 71 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
67 | int radeon_driver_unload_kms(struct drm_device *dev); | 72 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339ad..2a59375dbe52 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev, | |||
131 | */ | 131 | */ |
132 | void radeon_fence_process(struct radeon_device *rdev, int ring) | 132 | void radeon_fence_process(struct radeon_device *rdev, int ring) |
133 | { | 133 | { |
134 | uint64_t seq, last_seq; | 134 | uint64_t seq, last_seq, last_emitted; |
135 | unsigned count_loop = 0; | 135 | unsigned count_loop = 0; |
136 | bool wake = false; | 136 | bool wake = false; |
137 | 137 | ||
@@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring) | |||
158 | */ | 158 | */ |
159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); | 159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); |
160 | do { | 160 | do { |
161 | last_emitted = rdev->fence_drv[ring].sync_seq[ring]; | ||
161 | seq = radeon_fence_read(rdev, ring); | 162 | seq = radeon_fence_read(rdev, ring); |
162 | seq |= last_seq & 0xffffffff00000000LL; | 163 | seq |= last_seq & 0xffffffff00000000LL; |
163 | if (seq < last_seq) { | 164 | if (seq < last_seq) { |
164 | seq += 0x100000000LL; | 165 | seq &= 0xffffffff; |
166 | seq |= last_emitted & 0xffffffff00000000LL; | ||
165 | } | 167 | } |
166 | 168 | ||
167 | if (seq == last_seq) { | 169 | if (seq <= last_seq || seq > last_emitted) { |
168 | break; | 170 | break; |
169 | } | 171 | } |
170 | /* If we loop over we don't want to return without | 172 | /* If we loop over we don't want to return without |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
814 | return -EINVAL; | 814 | return -EINVAL; |
815 | } | 815 | } |
816 | 816 | ||
817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
818 | return 0; | 818 | return 0; |
819 | 819 | ||
820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
@@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
860 | { | 860 | { |
861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
862 | int r; | ||
862 | 863 | ||
863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
865 | return 0; | 866 | return 0; |
866 | 867 | ||
868 | /* wait for va use to end */ | ||
869 | while (bo_va->fence) { | ||
870 | r = radeon_fence_wait(bo_va->fence, false); | ||
871 | if (r) { | ||
872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
873 | } | ||
874 | if (r == -EDEADLK) { | ||
875 | r = radeon_gpu_reset(rdev); | ||
876 | if (!r) | ||
877 | continue; | ||
878 | } | ||
879 | break; | ||
880 | } | ||
881 | radeon_fence_unref(&bo_va->fence); | ||
882 | |||
867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
@@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
934 | } | 950 | } |
935 | 951 | ||
936 | /** | 952 | /** |
937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
938 | * | 954 | * |
939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
940 | * @vm: requested vm | 956 | * @vm: requested vm |
@@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
954 | 970 | ||
955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
972 | * waited for the last vm fence to signal | ||
973 | */ | ||
956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
957 | if (!r) { | 975 | if (!r) { |
958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
979 | radeon_fence_unref(&bo_va->fence); | ||
961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
962 | kfree(bo_va); | 981 | kfree(bo_va); |
963 | } | 982 | } |
@@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
970 | if (!r) { | 989 | if (!r) { |
971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
991 | radeon_fence_unref(&bo_va->fence); | ||
972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
973 | kfree(bo_va); | 993 | kfree(bo_va); |
974 | } | 994 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d045245739..1b57b0058ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
134 | struct radeon_device *rdev = rbo->rdev; | 134 | struct radeon_device *rdev = rbo->rdev; |
135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
136 | struct radeon_vm *vm = &fpriv->vm; | 136 | struct radeon_vm *vm = &fpriv->vm; |
137 | struct radeon_bo_va *bo_va, *tmp; | ||
138 | 137 | ||
139 | if (rdev->family < CHIP_CAYMAN) { | 138 | if (rdev->family < CHIP_CAYMAN) { |
140 | return; | 139 | return; |
141 | } | 140 | } |
142 | 141 | ||
143 | if (radeon_bo_reserve(rbo, false)) { | 142 | if (radeon_bo_reserve(rbo, false)) { |
143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | ||
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { | 146 | radeon_vm_bo_rmv(rdev, vm, rbo); |
147 | if (bo_va->vm == vm) { | ||
148 | /* remove from this vm address space */ | ||
149 | mutex_lock(&vm->mutex); | ||
150 | list_del(&bo_va->vm_list); | ||
151 | mutex_unlock(&vm->mutex); | ||
152 | list_del(&bo_va->bo_list); | ||
153 | kfree(bo_va); | ||
154 | } | ||
155 | } | ||
156 | radeon_bo_unreserve(rbo); | 147 | radeon_bo_unreserve(rbo); |
157 | } | 148 | } |
158 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 1d73f16b5d97..414b4acf6947 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
32 | #include "radeon_asic.h" | ||
32 | 33 | ||
33 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
@@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 168 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
168 | { | 169 | { |
169 | struct radeon_device *rdev = dev->dev_private; | 170 | struct radeon_device *rdev = dev->dev_private; |
170 | struct drm_radeon_info *info; | 171 | struct drm_radeon_info *info = data; |
171 | struct radeon_mode_info *minfo = &rdev->mode_info; | 172 | struct radeon_mode_info *minfo = &rdev->mode_info; |
172 | uint32_t *value_ptr; | 173 | uint32_t value, *value_ptr; |
173 | uint32_t value; | 174 | uint64_t value64, *value_ptr64; |
174 | struct drm_crtc *crtc; | 175 | struct drm_crtc *crtc; |
175 | int i, found; | 176 | int i, found; |
176 | 177 | ||
177 | info = data; | 178 | /* TIMESTAMP is a 64-bit value, needs special handling. */ |
179 | if (info->request == RADEON_INFO_TIMESTAMP) { | ||
180 | if (rdev->family >= CHIP_R600) { | ||
181 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | ||
182 | if (rdev->family >= CHIP_TAHITI) { | ||
183 | value64 = si_get_gpu_clock(rdev); | ||
184 | } else { | ||
185 | value64 = r600_get_gpu_clock(rdev); | ||
186 | } | ||
187 | |||
188 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | ||
189 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | ||
190 | return -EFAULT; | ||
191 | } | ||
192 | return 0; | ||
193 | } else { | ||
194 | DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | } | ||
198 | |||
178 | value_ptr = (uint32_t *)((unsigned long)info->value); | 199 | value_ptr = (uint32_t *)((unsigned long)info->value); |
179 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) | 200 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { |
201 | DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); | ||
180 | return -EFAULT; | 202 | return -EFAULT; |
203 | } | ||
181 | 204 | ||
182 | switch (info->request) { | 205 | switch (info->request) { |
183 | case RADEON_INFO_DEVICE_ID: | 206 | case RADEON_INFO_DEVICE_ID: |
@@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
337 | return -EINVAL; | 360 | return -EINVAL; |
338 | } | 361 | } |
339 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 362 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
340 | DRM_ERROR("copy_to_user\n"); | 363 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
341 | return -EFAULT; | 364 | return -EFAULT; |
342 | } | 365 | } |
343 | return 0; | 366 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index d5fd615897ec..94b4a1c12893 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1025 | 1025 | ||
1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
1027 | { | 1027 | { |
1028 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1028 | struct drm_device *dev = crtc->dev; | 1029 | struct drm_device *dev = crtc->dev; |
1029 | struct drm_crtc *crtci; | 1030 | struct drm_crtc *crtci; |
1030 | 1031 | ||
1032 | radeon_crtc->in_mode_set = true; | ||
1031 | /* | 1033 | /* |
1032 | * The hardware wedges sometimes if you reconfigure one CRTC | 1034 | * The hardware wedges sometimes if you reconfigure one CRTC |
1033 | * whilst another is running (see fdo bug #24611). | 1035 | * whilst another is running (see fdo bug #24611). |
@@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
1038 | 1040 | ||
1039 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1041 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
1040 | { | 1042 | { |
1043 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1041 | struct drm_device *dev = crtc->dev; | 1044 | struct drm_device *dev = crtc->dev; |
1042 | struct drm_crtc *crtci; | 1045 | struct drm_crtc *crtci; |
1043 | 1046 | ||
@@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
1048 | if (crtci->enabled) | 1051 | if (crtci->enabled) |
1049 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1052 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
1050 | } | 1053 | } |
1054 | radeon_crtc->in_mode_set = false; | ||
1051 | } | 1055 | } |
1052 | 1056 | ||
1053 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1057 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f380d59c5763..d56978949f34 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -275,6 +275,7 @@ struct radeon_crtc { | |||
275 | u16 lut_r[256], lut_g[256], lut_b[256]; | 275 | u16 lut_r[256], lut_g[256], lut_b[256]; |
276 | bool enabled; | 276 | bool enabled; |
277 | bool can_tile; | 277 | bool can_tile; |
278 | bool in_mode_set; | ||
278 | uint32_t crtc_offset; | 279 | uint32_t crtc_offset; |
279 | struct drm_gem_object *cursor_bo; | 280 | struct drm_gem_object *cursor_bo; |
280 | uint64_t cursor_addr; | 281 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f1a4c803c1d..9024e7222839 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
52 | 52 | ||
53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
55 | mutex_lock(&bo_va->vm->mutex); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); |
56 | list_del(&bo_va->vm_list); | ||
57 | mutex_unlock(&bo_va->vm->mutex); | ||
58 | list_del(&bo_va->bo_list); | ||
59 | kfree(bo_va); | ||
60 | } | 56 | } |
61 | } | 57 | } |
62 | 58 | ||
@@ -136,6 +132,7 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
136 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, | 132 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
137 | sizeof(struct radeon_bo)); | 133 | sizeof(struct radeon_bo)); |
138 | 134 | ||
135 | retry: | ||
139 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 136 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
140 | if (bo == NULL) | 137 | if (bo == NULL) |
141 | return -ENOMEM; | 138 | return -ENOMEM; |
@@ -149,8 +146,6 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
149 | bo->surface_reg = -1; | 146 | bo->surface_reg = -1; |
150 | INIT_LIST_HEAD(&bo->list); | 147 | INIT_LIST_HEAD(&bo->list); |
151 | INIT_LIST_HEAD(&bo->va); | 148 | INIT_LIST_HEAD(&bo->va); |
152 | |||
153 | retry: | ||
154 | radeon_ttm_placement_from_domain(bo, domain); | 149 | radeon_ttm_placement_from_domain(bo, domain); |
155 | /* Kernel allocation are uninterruptible */ | 150 | /* Kernel allocation are uninterruptible */ |
156 | down_read(&rdev->pm.mclk_lock); | 151 | down_read(&rdev->pm.mclk_lock); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index ec79b3750430..43c431a2686d 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -706,6 +706,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
706 | if (radeon_debugfs_ring_init(rdev, ring)) { | 706 | if (radeon_debugfs_ring_init(rdev, ring)) { |
707 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 707 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
708 | } | 708 | } |
709 | radeon_ring_lockup_update(ring); | ||
709 | return 0; | 710 | return 0; |
710 | } | 711 | } |
711 | 712 | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 5e659b034d9a..20bfbda7b3f1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -744,15 +744,6 @@ r600 0x9400 | |||
744 | 0x00028C38 CB_CLRCMP_DST | 744 | 0x00028C38 CB_CLRCMP_DST |
745 | 0x00028C3C CB_CLRCMP_MSK | 745 | 0x00028C3C CB_CLRCMP_MSK |
746 | 0x00028C34 CB_CLRCMP_SRC | 746 | 0x00028C34 CB_CLRCMP_SRC |
747 | 0x00028100 CB_COLOR0_MASK | ||
748 | 0x00028104 CB_COLOR1_MASK | ||
749 | 0x00028108 CB_COLOR2_MASK | ||
750 | 0x0002810C CB_COLOR3_MASK | ||
751 | 0x00028110 CB_COLOR4_MASK | ||
752 | 0x00028114 CB_COLOR5_MASK | ||
753 | 0x00028118 CB_COLOR6_MASK | ||
754 | 0x0002811C CB_COLOR7_MASK | ||
755 | 0x00028808 CB_COLOR_CONTROL | ||
756 | 0x0002842C CB_FOG_BLUE | 747 | 0x0002842C CB_FOG_BLUE |
757 | 0x00028428 CB_FOG_GREEN | 748 | 0x00028428 CB_FOG_GREEN |
758 | 0x00028424 CB_FOG_RED | 749 | 0x00028424 CB_FOG_RED |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index a12fbcc8ccb6..aa8ef491ef3c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
281 | 281 | ||
282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
283 | { | 283 | { |
284 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); | ||
285 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); | ||
286 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
287 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
288 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
289 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
290 | 286 | ||
291 | /* Stop all video */ | 287 | /* Stop all video */ |
292 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
@@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
311 | /* Unlock host access */ | 307 | /* Unlock host access */ |
312 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
313 | mdelay(1); | 309 | mdelay(1); |
314 | /* Restore video state */ | ||
315 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
316 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
317 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
318 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
319 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
320 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
321 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
322 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
323 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
324 | } | 311 | } |
325 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c053f8193771..0139e227e3c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
1639 | /* XXX what about 12? */ | 1639 | /* XXX what about 12? */ |
1640 | rdev->config.si.tile_config |= (3 << 0); | 1640 | rdev->config.si.tile_config |= (3 << 0); |
1641 | break; | 1641 | break; |
1642 | } | 1642 | } |
1643 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1643 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
1644 | rdev->config.si.tile_config |= 1 << 4; | 1644 | case 0: /* four banks */ |
1645 | else | ||
1646 | rdev->config.si.tile_config |= 0 << 4; | 1645 | rdev->config.si.tile_config |= 0 << 4; |
1646 | break; | ||
1647 | case 1: /* eight banks */ | ||
1648 | rdev->config.si.tile_config |= 1 << 4; | ||
1649 | break; | ||
1650 | case 2: /* sixteen banks */ | ||
1651 | default: | ||
1652 | rdev->config.si.tile_config |= 2 << 4; | ||
1653 | break; | ||
1654 | } | ||
1647 | rdev->config.si.tile_config |= | 1655 | rdev->config.si.tile_config |= |
1648 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 1656 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
1649 | rdev->config.si.tile_config |= | 1657 | rdev->config.si.tile_config |= |
@@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) | |||
3960 | rdev->bios = NULL; | 3968 | rdev->bios = NULL; |
3961 | } | 3969 | } |
3962 | 3970 | ||
3971 | /** | ||
3972 | * si_get_gpu_clock - return GPU clock counter snapshot | ||
3973 | * | ||
3974 | * @rdev: radeon_device pointer | ||
3975 | * | ||
3976 | * Fetches a GPU clock counter snapshot (SI). | ||
3977 | * Returns the 64 bit clock counter snapshot. | ||
3978 | */ | ||
3979 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | ||
3980 | { | ||
3981 | uint64_t clock; | ||
3982 | |||
3983 | mutex_lock(&rdev->gpu_clock_mutex); | ||
3984 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
3985 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
3986 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
3987 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
3988 | return clock; | ||
3989 | } | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089e8761..ef4815c27b1c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -698,6 +698,9 @@ | |||
698 | #define RLC_UCODE_ADDR 0xC32C | 698 | #define RLC_UCODE_ADDR 0xC32C |
699 | #define RLC_UCODE_DATA 0xC330 | 699 | #define RLC_UCODE_DATA 0xC330 |
700 | 700 | ||
701 | #define RLC_GPU_CLOCK_COUNT_LSB 0xC338 | ||
702 | #define RLC_GPU_CLOCK_COUNT_MSB 0xC33C | ||
703 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 | ||
701 | #define RLC_MC_CNTL 0xC344 | 704 | #define RLC_MC_CNTL 0xC344 |
702 | #define RLC_UCODE_CNTL 0xC348 | 705 | #define RLC_UCODE_CNTL 0xC348 |
703 | 706 | ||
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4c..c5a164337bd5 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = { | |||
43 | .mmap = drm_mmap, | 43 | .mmap = drm_mmap, |
44 | .poll = drm_poll, | 44 | .poll = drm_poll, |
45 | .fasync = drm_fasync, | 45 | .fasync = drm_fasync, |
46 | #ifdef CONFIG_COMPAT | ||
47 | .compat_ioctl = drm_compat_ioctl, | ||
48 | #endif | ||
46 | .llseek = noop_llseek, | 49 | .llseek = noop_llseek, |
47 | }; | 50 | }; |
48 | 51 | ||
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147c..867dc03000e6 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = { | |||
74 | .mmap = drm_mmap, | 74 | .mmap = drm_mmap, |
75 | .poll = drm_poll, | 75 | .poll = drm_poll, |
76 | .fasync = drm_fasync, | 76 | .fasync = drm_fasync, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .llseek = noop_llseek, | 80 | .llseek = noop_llseek, |
78 | }; | 81 | }; |
79 | 82 | ||
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfac..a7f4d6bd1330 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = { | |||
49 | .mmap = drm_mmap, | 49 | .mmap = drm_mmap, |
50 | .poll = drm_poll, | 50 | .poll = drm_poll, |
51 | .fasync = drm_fasync, | 51 | .fasync = drm_fasync, |
52 | #ifdef CONFIG_COMPAT | ||
53 | .compat_ioctl = drm_compat_ioctl, | ||
54 | #endif | ||
52 | .llseek = noop_llseek, | 55 | .llseek = noop_llseek, |
53 | }; | 56 | }; |
54 | 57 | ||
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index 0b5e096d39a6..56e0bf31d425 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config DRM_UDL | 1 | config DRM_UDL |
2 | tristate "DisplayLink" | 2 | tristate "DisplayLink" |
3 | depends on DRM && EXPERIMENTAL | 3 | depends on DRM && EXPERIMENTAL |
4 | depends on USB_ARCH_HAS_HCD | ||
4 | select DRM_USB | 5 | select DRM_USB |
5 | select FB_SYS_FILLRECT | 6 | select FB_SYS_FILLRECT |
6 | select FB_SYS_COPYAREA | 7 | select FB_SYS_COPYAREA |
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index ba055e9ca007..8d9dc44f1f94 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c | |||
@@ -69,6 +69,13 @@ static int udl_get_modes(struct drm_connector *connector) | |||
69 | static int udl_mode_valid(struct drm_connector *connector, | 69 | static int udl_mode_valid(struct drm_connector *connector, |
70 | struct drm_display_mode *mode) | 70 | struct drm_display_mode *mode) |
71 | { | 71 | { |
72 | struct udl_device *udl = connector->dev->dev_private; | ||
73 | if (!udl->sku_pixel_limit) | ||
74 | return 0; | ||
75 | |||
76 | if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit) | ||
77 | return MODE_VIRTUAL_Y; | ||
78 | |||
72 | return 0; | 79 | return 0; |
73 | } | 80 | } |
74 | 81 | ||
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b3..9f84128505bb 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c | |||
@@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = { | |||
66 | .unlocked_ioctl = drm_ioctl, | 66 | .unlocked_ioctl = drm_ioctl, |
67 | .release = drm_release, | 67 | .release = drm_release, |
68 | .fasync = drm_fasync, | 68 | .fasync = drm_fasync, |
69 | #ifdef CONFIG_COMPAT | ||
70 | .compat_ioctl = drm_compat_ioctl, | ||
71 | #endif | ||
69 | .llseek = noop_llseek, | 72 | .llseek = noop_llseek, |
70 | }; | 73 | }; |
71 | 74 | ||
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 7bd65bdd15a8..291ecc145585 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c | |||
@@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, | |||
308 | /* need to attach */ | 308 | /* need to attach */ |
309 | attach = dma_buf_attach(dma_buf, dev->dev); | 309 | attach = dma_buf_attach(dma_buf, dev->dev); |
310 | if (IS_ERR(attach)) | 310 | if (IS_ERR(attach)) |
311 | return ERR_PTR(PTR_ERR(attach)); | 311 | return ERR_CAST(attach); |
312 | 312 | ||
313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
314 | if (IS_ERR(sg)) { | 314 | if (IS_ERR(sg)) { |
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index f5dd89e891de..9159d48d1dfd 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c | |||
@@ -354,8 +354,7 @@ static int udl_crtc_mode_set(struct drm_crtc *crtc, | |||
354 | 354 | ||
355 | static void udl_crtc_disable(struct drm_crtc *crtc) | 355 | static void udl_crtc_disable(struct drm_crtc *crtc) |
356 | { | 356 | { |
357 | 357 | udl_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | |
358 | |||
359 | } | 358 | } |
360 | 359 | ||
361 | static void udl_crtc_destroy(struct drm_crtc *crtc) | 360 | static void udl_crtc_destroy(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f5..af1b914b17e3 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = { | |||
65 | .mmap = drm_mmap, | 65 | .mmap = drm_mmap, |
66 | .poll = drm_poll, | 66 | .poll = drm_poll, |
67 | .fasync = drm_fasync, | 67 | .fasync = drm_fasync, |
68 | #ifdef CONFIG_COMPAT | ||
69 | .compat_ioctl = drm_compat_ioctl, | ||
70 | #endif | ||
68 | .llseek = noop_llseek, | 71 | .llseek = noop_llseek, |
69 | }; | 72 | }; |
70 | 73 | ||
diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c5701..b71bcd0bfbbf 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig | |||
@@ -12,3 +12,11 @@ config DRM_VMWGFX | |||
12 | This is a KMS enabled DRM driver for the VMware SVGA2 | 12 | This is a KMS enabled DRM driver for the VMware SVGA2 |
13 | virtual hardware. | 13 | virtual hardware. |
14 | The compiled module will be called "vmwgfx.ko". | 14 | The compiled module will be called "vmwgfx.ko". |
15 | |||
16 | config DRM_VMWGFX_FBCON | ||
17 | depends on DRM_VMWGFX | ||
18 | bool "Enable framebuffer console under vmwgfx by default" | ||
19 | help | ||
20 | Choose this option if you are shipping a new vmwgfx | ||
21 | userspace driver that supports using the kernel driver. | ||
22 | |||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01ac..ba2c35dbf10e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, | 182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, |
183 | {0, 0, 0} | 183 | {0, 0, 0} |
184 | }; | 184 | }; |
185 | MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); | ||
185 | 186 | ||
186 | static int enable_fbdev; | 187 | static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON); |
187 | 188 | ||
188 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 189 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
189 | static void vmw_master_init(struct vmw_master *); | 190 | static void vmw_master_init(struct vmw_master *); |
@@ -1154,6 +1155,11 @@ static struct drm_driver driver = { | |||
1154 | .open = vmw_driver_open, | 1155 | .open = vmw_driver_open, |
1155 | .preclose = vmw_preclose, | 1156 | .preclose = vmw_preclose, |
1156 | .postclose = vmw_postclose, | 1157 | .postclose = vmw_postclose, |
1158 | |||
1159 | .dumb_create = vmw_dumb_create, | ||
1160 | .dumb_map_offset = vmw_dumb_map_offset, | ||
1161 | .dumb_destroy = vmw_dumb_destroy, | ||
1162 | |||
1157 | .fops = &vmwgfx_driver_fops, | 1163 | .fops = &vmwgfx_driver_fops, |
1158 | .name = VMWGFX_DRIVER_NAME, | 1164 | .name = VMWGFX_DRIVER_NAME, |
1159 | .desc = VMWGFX_DRIVER_DESC, | 1165 | .desc = VMWGFX_DRIVER_DESC, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee27..29c984ff7f23 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
646 | struct drm_file *file_priv); | 646 | struct drm_file *file_priv); |
647 | 647 | ||
648 | int vmw_dumb_create(struct drm_file *file_priv, | ||
649 | struct drm_device *dev, | ||
650 | struct drm_mode_create_dumb *args); | ||
651 | |||
652 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
653 | struct drm_device *dev, uint32_t handle, | ||
654 | uint64_t *offset); | ||
655 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
656 | struct drm_device *dev, | ||
657 | uint32_t handle); | ||
648 | /** | 658 | /** |
649 | * Overlay control - vmwgfx_overlay.c | 659 | * Overlay control - vmwgfx_overlay.c |
650 | */ | 660 | */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index f2fb8f15e2f1..7e0743358dff 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | |||
@@ -1018,7 +1018,7 @@ int vmw_event_fence_action_create(struct drm_file *file_priv, | |||
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | 1020 | ||
1021 | event = kzalloc(sizeof(event->event), GFP_KERNEL); | 1021 | event = kzalloc(sizeof(*event), GFP_KERNEL); |
1022 | if (unlikely(event == NULL)) { | 1022 | if (unlikely(event == NULL)) { |
1023 | DRM_ERROR("Failed to allocate an event.\n"); | 1023 | DRM_ERROR("Failed to allocate an event.\n"); |
1024 | ret = -ENOMEM; | 1024 | ret = -ENOMEM; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 6b0078ffa763..c50724bd30f6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -1688,15 +1688,19 @@ int vmw_du_page_flip(struct drm_crtc *crtc, | |||
1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | 1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); |
1689 | struct drm_framebuffer *old_fb = crtc->fb; | 1689 | struct drm_framebuffer *old_fb = crtc->fb; |
1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); | 1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); |
1691 | struct drm_file *file_priv = event->base.file_priv; | 1691 | struct drm_file *file_priv ; |
1692 | struct vmw_fence_obj *fence = NULL; | 1692 | struct vmw_fence_obj *fence = NULL; |
1693 | struct drm_clip_rect clips; | 1693 | struct drm_clip_rect clips; |
1694 | int ret; | 1694 | int ret; |
1695 | 1695 | ||
1696 | if (event == NULL) | ||
1697 | return -EINVAL; | ||
1698 | |||
1696 | /* require ScreenObject support for page flipping */ | 1699 | /* require ScreenObject support for page flipping */ |
1697 | if (!dev_priv->sou_priv) | 1700 | if (!dev_priv->sou_priv) |
1698 | return -ENOSYS; | 1701 | return -ENOSYS; |
1699 | 1702 | ||
1703 | file_priv = event->base.file_priv; | ||
1700 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) | 1704 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) |
1701 | return -EINVAL; | 1705 | return -EINVAL; |
1702 | 1706 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec71..2c6ffe0e2c07 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -1917,3 +1917,76 @@ err_ref: | |||
1917 | vmw_resource_unreference(&res); | 1917 | vmw_resource_unreference(&res); |
1918 | return ret; | 1918 | return ret; |
1919 | } | 1919 | } |
1920 | |||
1921 | |||
1922 | int vmw_dumb_create(struct drm_file *file_priv, | ||
1923 | struct drm_device *dev, | ||
1924 | struct drm_mode_create_dumb *args) | ||
1925 | { | ||
1926 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
1927 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
1928 | struct vmw_user_dma_buffer *vmw_user_bo; | ||
1929 | struct ttm_buffer_object *tmp; | ||
1930 | int ret; | ||
1931 | |||
1932 | args->pitch = args->width * ((args->bpp + 7) / 8); | ||
1933 | args->size = args->pitch * args->height; | ||
1934 | |||
1935 | vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); | ||
1936 | if (vmw_user_bo == NULL) | ||
1937 | return -ENOMEM; | ||
1938 | |||
1939 | ret = ttm_read_lock(&vmaster->lock, true); | ||
1940 | if (ret != 0) { | ||
1941 | kfree(vmw_user_bo); | ||
1942 | return ret; | ||
1943 | } | ||
1944 | |||
1945 | ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, | ||
1946 | &vmw_vram_sys_placement, true, | ||
1947 | &vmw_user_dmabuf_destroy); | ||
1948 | if (ret != 0) | ||
1949 | goto out_no_dmabuf; | ||
1950 | |||
1951 | tmp = ttm_bo_reference(&vmw_user_bo->dma.base); | ||
1952 | ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, | ||
1953 | &vmw_user_bo->base, | ||
1954 | false, | ||
1955 | ttm_buffer_type, | ||
1956 | &vmw_user_dmabuf_release, NULL); | ||
1957 | if (unlikely(ret != 0)) | ||
1958 | goto out_no_base_object; | ||
1959 | |||
1960 | args->handle = vmw_user_bo->base.hash.key; | ||
1961 | |||
1962 | out_no_base_object: | ||
1963 | ttm_bo_unref(&tmp); | ||
1964 | out_no_dmabuf: | ||
1965 | ttm_read_unlock(&vmaster->lock); | ||
1966 | return ret; | ||
1967 | } | ||
1968 | |||
1969 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
1970 | struct drm_device *dev, uint32_t handle, | ||
1971 | uint64_t *offset) | ||
1972 | { | ||
1973 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | ||
1974 | struct vmw_dma_buffer *out_buf; | ||
1975 | int ret; | ||
1976 | |||
1977 | ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); | ||
1978 | if (ret != 0) | ||
1979 | return -EINVAL; | ||
1980 | |||
1981 | *offset = out_buf->base.addr_space_offset; | ||
1982 | vmw_dmabuf_unreference(&out_buf); | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
1987 | struct drm_device *dev, | ||
1988 | uint32_t handle) | ||
1989 | { | ||
1990 | return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, | ||
1991 | handle, TTM_REF_USAGE); | ||
1992 | } | ||
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc9..e25cf31faab2 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = { | |||
70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), | 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | 73 | static bool vga_switcheroo_ready(void) |
74 | { | ||
75 | mutex_lock(&vgasr_mutex); | ||
76 | if (vgasr_priv.handler) { | ||
77 | mutex_unlock(&vgasr_mutex); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | vgasr_priv.handler = handler; | ||
82 | mutex_unlock(&vgasr_mutex); | ||
83 | return 0; | ||
84 | } | ||
85 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
86 | |||
87 | void vga_switcheroo_unregister_handler(void) | ||
88 | { | 74 | { |
89 | mutex_lock(&vgasr_mutex); | 75 | /* we're ready if we get two clients + handler */ |
90 | vgasr_priv.handler = NULL; | 76 | return !vgasr_priv.active && |
91 | mutex_unlock(&vgasr_mutex); | 77 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler; |
92 | } | 78 | } |
93 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
94 | 79 | ||
95 | static void vga_switcheroo_enable(void) | 80 | static void vga_switcheroo_enable(void) |
96 | { | 81 | { |
@@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void) | |||
98 | struct vga_switcheroo_client *client; | 83 | struct vga_switcheroo_client *client; |
99 | 84 | ||
100 | /* call the handler to init */ | 85 | /* call the handler to init */ |
101 | vgasr_priv.handler->init(); | 86 | if (vgasr_priv.handler->init) |
87 | vgasr_priv.handler->init(); | ||
102 | 88 | ||
103 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 89 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
104 | if (client->id != -1) | 90 | if (client->id != -1) |
@@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void) | |||
113 | vgasr_priv.active = true; | 99 | vgasr_priv.active = true; |
114 | } | 100 | } |
115 | 101 | ||
102 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | ||
103 | { | ||
104 | mutex_lock(&vgasr_mutex); | ||
105 | if (vgasr_priv.handler) { | ||
106 | mutex_unlock(&vgasr_mutex); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | |||
110 | vgasr_priv.handler = handler; | ||
111 | if (vga_switcheroo_ready()) { | ||
112 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | ||
113 | vga_switcheroo_enable(); | ||
114 | } | ||
115 | mutex_unlock(&vgasr_mutex); | ||
116 | return 0; | ||
117 | } | ||
118 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
119 | |||
120 | void vga_switcheroo_unregister_handler(void) | ||
121 | { | ||
122 | mutex_lock(&vgasr_mutex); | ||
123 | vgasr_priv.handler = NULL; | ||
124 | if (vgasr_priv.active) { | ||
125 | pr_info("vga_switcheroo: disabled\n"); | ||
126 | vga_switcheroo_debugfs_fini(&vgasr_priv); | ||
127 | vgasr_priv.active = false; | ||
128 | } | ||
129 | mutex_unlock(&vgasr_mutex); | ||
130 | } | ||
131 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
132 | |||
116 | static int register_client(struct pci_dev *pdev, | 133 | static int register_client(struct pci_dev *pdev, |
117 | const struct vga_switcheroo_client_ops *ops, | 134 | const struct vga_switcheroo_client_ops *ops, |
118 | int id, bool active) | 135 | int id, bool active) |
@@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev, | |||
134 | if (client_is_vga(client)) | 151 | if (client_is_vga(client)) |
135 | vgasr_priv.registered_clients++; | 152 | vgasr_priv.registered_clients++; |
136 | 153 | ||
137 | /* if we get two clients + handler */ | 154 | if (vga_switcheroo_ready()) { |
138 | if (!vgasr_priv.active && | ||
139 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { | ||
140 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | 155 | printk(KERN_INFO "vga_switcheroo: enabled\n"); |
141 | vga_switcheroo_enable(); | 156 | vga_switcheroo_enable(); |
142 | } | 157 | } |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 60ea284407ce..8bcd168fffae 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -996,7 +996,8 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, | |||
996 | struct hid_driver *hdrv = hid->driver; | 996 | struct hid_driver *hdrv = hid->driver; |
997 | int ret; | 997 | int ret; |
998 | 998 | ||
999 | hid_dump_input(hid, usage, value); | 999 | if (!list_empty(&hid->debug_list)) |
1000 | hid_dump_input(hid, usage, value); | ||
1000 | 1001 | ||
1001 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { | 1002 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { |
1002 | ret = hdrv->event(hid, field, usage, value); | 1003 | ret = hdrv->event(hid, field, usage, value); |
@@ -1558,7 +1559,9 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1558 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, | 1559 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, |
1559 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1560 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1560 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, | 1561 | { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, |
1561 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, | 1562 | #if IS_ENABLED(CONFIG_HID_LENOVO_TPKBD) |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, | ||
1564 | #endif | ||
1562 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1565 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
1563 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, | 1566 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, |
1564 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, | 1567 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, |
@@ -1624,7 +1627,6 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
1624 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, | 1627 | { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, |
1625 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, | 1628 | { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, |
1626 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, | 1629 | { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, |
1627 | { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, | ||
1628 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, | 1630 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, |
1629 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 1631 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
1630 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, | 1632 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, |
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c index 77d2df04c97b..60c4e1e85913 100644 --- a/drivers/hid/hid-lenovo-tpkbd.c +++ b/drivers/hid/hid-lenovo-tpkbd.c | |||
@@ -519,6 +519,8 @@ static void tpkbd_remove_tp(struct hid_device *hdev) | |||
519 | led_classdev_unregister(&data_pointer->led_mute); | 519 | led_classdev_unregister(&data_pointer->led_mute); |
520 | 520 | ||
521 | hid_set_drvdata(hdev, NULL); | 521 | hid_set_drvdata(hdev, NULL); |
522 | kfree(data_pointer->led_micmute.name); | ||
523 | kfree(data_pointer->led_mute.name); | ||
522 | kfree(data_pointer); | 524 | kfree(data_pointer); |
523 | } | 525 | } |
524 | 526 | ||
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 0f9c146fc00d..9500f2f3f8fe 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
@@ -193,6 +193,7 @@ static struct hid_ll_driver logi_dj_ll_driver; | |||
193 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | 193 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, |
194 | size_t count, | 194 | size_t count, |
195 | unsigned char report_type); | 195 | unsigned char report_type); |
196 | static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); | ||
196 | 197 | ||
197 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, | 198 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, |
198 | struct dj_report *dj_report) | 199 | struct dj_report *dj_report) |
@@ -233,6 +234,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
233 | if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & | 234 | if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & |
234 | SPFUNCTION_DEVICE_LIST_EMPTY) { | 235 | SPFUNCTION_DEVICE_LIST_EMPTY) { |
235 | dbg_hid("%s: device list is empty\n", __func__); | 236 | dbg_hid("%s: device list is empty\n", __func__); |
237 | djrcv_dev->querying_devices = false; | ||
236 | return; | 238 | return; |
237 | } | 239 | } |
238 | 240 | ||
@@ -243,6 +245,12 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
243 | return; | 245 | return; |
244 | } | 246 | } |
245 | 247 | ||
248 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | ||
249 | /* The device is already known. No need to reallocate it. */ | ||
250 | dbg_hid("%s: device is already known\n", __func__); | ||
251 | return; | ||
252 | } | ||
253 | |||
246 | dj_hiddev = hid_allocate_device(); | 254 | dj_hiddev = hid_allocate_device(); |
247 | if (IS_ERR(dj_hiddev)) { | 255 | if (IS_ERR(dj_hiddev)) { |
248 | dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n", | 256 | dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n", |
@@ -306,6 +314,7 @@ static void delayedwork_callback(struct work_struct *work) | |||
306 | struct dj_report dj_report; | 314 | struct dj_report dj_report; |
307 | unsigned long flags; | 315 | unsigned long flags; |
308 | int count; | 316 | int count; |
317 | int retval; | ||
309 | 318 | ||
310 | dbg_hid("%s\n", __func__); | 319 | dbg_hid("%s\n", __func__); |
311 | 320 | ||
@@ -338,6 +347,25 @@ static void delayedwork_callback(struct work_struct *work) | |||
338 | logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); | 347 | logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); |
339 | break; | 348 | break; |
340 | default: | 349 | default: |
350 | /* A normal report (i. e. not belonging to a pair/unpair notification) | ||
351 | * arriving here, means that the report arrived but we did not have a | ||
352 | * paired dj_device associated to the report's device_index, this | ||
353 | * means that the original "device paired" notification corresponding | ||
354 | * to this dj_device never arrived to this driver. The reason is that | ||
355 | * hid-core discards all packets coming from a device while probe() is | ||
356 | * executing. */ | ||
357 | if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) { | ||
358 | /* ok, we don't know the device, just re-ask the | ||
359 | * receiver for the list of connected devices. */ | ||
360 | retval = logi_dj_recv_query_paired_devices(djrcv_dev); | ||
361 | if (!retval) { | ||
362 | /* everything went fine, so just leave */ | ||
363 | break; | ||
364 | } | ||
365 | dev_err(&djrcv_dev->hdev->dev, | ||
366 | "%s:logi_dj_recv_query_paired_devices " | ||
367 | "error:%d\n", __func__, retval); | ||
368 | } | ||
341 | dbg_hid("%s: unexpected report type\n", __func__); | 369 | dbg_hid("%s: unexpected report type\n", __func__); |
342 | } | 370 | } |
343 | } | 371 | } |
@@ -368,6 +396,12 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev, | |||
368 | if (!djdev) { | 396 | if (!djdev) { |
369 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" | 397 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" |
370 | " is NULL, index %d\n", dj_report->device_index); | 398 | " is NULL, index %d\n", dj_report->device_index); |
399 | kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); | ||
400 | |||
401 | if (schedule_work(&djrcv_dev->work) == 0) { | ||
402 | dbg_hid("%s: did not schedule the work item, was already " | ||
403 | "queued\n", __func__); | ||
404 | } | ||
371 | return; | 405 | return; |
372 | } | 406 | } |
373 | 407 | ||
@@ -398,6 +432,12 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev, | |||
398 | if (dj_device == NULL) { | 432 | if (dj_device == NULL) { |
399 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" | 433 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" |
400 | " is NULL, index %d\n", dj_report->device_index); | 434 | " is NULL, index %d\n", dj_report->device_index); |
435 | kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); | ||
436 | |||
437 | if (schedule_work(&djrcv_dev->work) == 0) { | ||
438 | dbg_hid("%s: did not schedule the work item, was already " | ||
439 | "queued\n", __func__); | ||
440 | } | ||
401 | return; | 441 | return; |
402 | } | 442 | } |
403 | 443 | ||
@@ -439,7 +479,11 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) | |||
439 | struct dj_report *dj_report; | 479 | struct dj_report *dj_report; |
440 | int retval; | 480 | int retval; |
441 | 481 | ||
442 | dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); | 482 | /* no need to protect djrcv_dev->querying_devices */ |
483 | if (djrcv_dev->querying_devices) | ||
484 | return 0; | ||
485 | |||
486 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); | ||
443 | if (!dj_report) | 487 | if (!dj_report) |
444 | return -ENOMEM; | 488 | return -ENOMEM; |
445 | dj_report->report_id = REPORT_ID_DJ_SHORT; | 489 | dj_report->report_id = REPORT_ID_DJ_SHORT; |
@@ -450,13 +494,14 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) | |||
450 | return retval; | 494 | return retval; |
451 | } | 495 | } |
452 | 496 | ||
497 | |||
453 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | 498 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, |
454 | unsigned timeout) | 499 | unsigned timeout) |
455 | { | 500 | { |
456 | struct dj_report *dj_report; | 501 | struct dj_report *dj_report; |
457 | int retval; | 502 | int retval; |
458 | 503 | ||
459 | dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); | 504 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); |
460 | if (!dj_report) | 505 | if (!dj_report) |
461 | return -ENOMEM; | 506 | return -ENOMEM; |
462 | dj_report->report_id = REPORT_ID_DJ_SHORT; | 507 | dj_report->report_id = REPORT_ID_DJ_SHORT; |
diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h index fd28a5e0ca3b..4a4000340ce1 100644 --- a/drivers/hid/hid-logitech-dj.h +++ b/drivers/hid/hid-logitech-dj.h | |||
@@ -101,6 +101,7 @@ struct dj_receiver_dev { | |||
101 | struct work_struct work; | 101 | struct work_struct work; |
102 | struct kfifo notif_fifo; | 102 | struct kfifo notif_fifo; |
103 | spinlock_t lock; | 103 | spinlock_t lock; |
104 | bool querying_devices; | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | struct dj_device { | 107 | struct dj_device { |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 903eef3d3e10..991e85c7325c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -70,6 +70,7 @@ static const struct hid_blacklist { | |||
70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | 70 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, |
71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 72 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
73 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, | ||
73 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, | 74 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, |
74 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, | 75 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, |
75 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, | 76 | { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2, HID_QUIRK_NO_INIT_REPORTS }, |
diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index cfec802cf9ca..f915eb1c29f7 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c | |||
@@ -87,10 +87,18 @@ static ssize_t ad7314_show_temperature(struct device *dev, | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | static ssize_t ad7314_show_name(struct device *dev, | ||
91 | struct device_attribute *devattr, char *buf) | ||
92 | { | ||
93 | return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); | ||
94 | } | ||
95 | |||
96 | static DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL); | ||
90 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | 97 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, |
91 | ad7314_show_temperature, NULL, 0); | 98 | ad7314_show_temperature, NULL, 0); |
92 | 99 | ||
93 | static struct attribute *ad7314_attributes[] = { | 100 | static struct attribute *ad7314_attributes[] = { |
101 | &dev_attr_name.attr, | ||
94 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 102 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
95 | NULL, | 103 | NULL, |
96 | }; | 104 | }; |
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index e65c6e45d36b..7bf4ce3d405e 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -139,6 +139,12 @@ static ssize_t show_voltage(struct device *dev, | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | static ssize_t ads7871_show_name(struct device *dev, | ||
143 | struct device_attribute *devattr, char *buf) | ||
144 | { | ||
145 | return sprintf(buf, "%s\n", to_spi_device(dev)->modalias); | ||
146 | } | ||
147 | |||
142 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0); | 148 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0); |
143 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1); | 149 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1); |
144 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2); | 150 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2); |
@@ -148,6 +154,8 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5); | |||
148 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6); | 154 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6); |
149 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7); | 155 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7); |
150 | 156 | ||
157 | static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL); | ||
158 | |||
151 | static struct attribute *ads7871_attributes[] = { | 159 | static struct attribute *ads7871_attributes[] = { |
152 | &sensor_dev_attr_in0_input.dev_attr.attr, | 160 | &sensor_dev_attr_in0_input.dev_attr.attr, |
153 | &sensor_dev_attr_in1_input.dev_attr.attr, | 161 | &sensor_dev_attr_in1_input.dev_attr.attr, |
@@ -157,6 +165,7 @@ static struct attribute *ads7871_attributes[] = { | |||
157 | &sensor_dev_attr_in5_input.dev_attr.attr, | 165 | &sensor_dev_attr_in5_input.dev_attr.attr, |
158 | &sensor_dev_attr_in6_input.dev_attr.attr, | 166 | &sensor_dev_attr_in6_input.dev_attr.attr, |
159 | &sensor_dev_attr_in7_input.dev_attr.attr, | 167 | &sensor_dev_attr_in7_input.dev_attr.attr, |
168 | &dev_attr_name.attr, | ||
160 | NULL | 169 | NULL |
161 | }; | 170 | }; |
162 | 171 | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 282708860517..8f3f6f2c45fd 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -53,10 +53,10 @@ | |||
53 | 53 | ||
54 | #define APPLESMC_MAX_DATA_LENGTH 32 | 54 | #define APPLESMC_MAX_DATA_LENGTH 32 |
55 | 55 | ||
56 | /* wait up to 32 ms for a status change. */ | 56 | /* wait up to 128 ms for a status change. */ |
57 | #define APPLESMC_MIN_WAIT 0x0010 | 57 | #define APPLESMC_MIN_WAIT 0x0010 |
58 | #define APPLESMC_RETRY_WAIT 0x0100 | 58 | #define APPLESMC_RETRY_WAIT 0x0100 |
59 | #define APPLESMC_MAX_WAIT 0x8000 | 59 | #define APPLESMC_MAX_WAIT 0x20000 |
60 | 60 | ||
61 | #define APPLESMC_READ_CMD 0x10 | 61 | #define APPLESMC_READ_CMD 0x10 |
62 | #define APPLESMC_WRITE_CMD 0x11 | 62 | #define APPLESMC_WRITE_CMD 0x11 |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 351d1f4593e7..4ee578948723 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -34,6 +34,12 @@ static const struct dmi_system_id __initconst atk_force_new_if[] = { | |||
34 | .matches = { | 34 | .matches = { |
35 | DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") | 35 | DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58") |
36 | } | 36 | } |
37 | }, { | ||
38 | /* Old interface reads the same sensor for fan0 and fan1 */ | ||
39 | .ident = "Asus M5A78L", | ||
40 | .matches = { | ||
41 | DMI_MATCH(DMI_BOARD_NAME, "M5A78L") | ||
42 | } | ||
37 | }, | 43 | }, |
38 | { } | 44 | { } |
39 | }; | 45 | }; |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index faa16f80db9c..984a3f13923b 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -196,7 +196,7 @@ struct tjmax { | |||
196 | int tjmax; | 196 | int tjmax; |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static struct tjmax __cpuinitconst tjmax_table[] = { | 199 | static const struct tjmax __cpuinitconst tjmax_table[] = { |
200 | { "CPU D410", 100000 }, | 200 | { "CPU D410", 100000 }, |
201 | { "CPU D425", 100000 }, | 201 | { "CPU D425", 100000 }, |
202 | { "CPU D510", 100000 }, | 202 | { "CPU D510", 100000 }, |
@@ -815,17 +815,20 @@ static int __init coretemp_init(void) | |||
815 | if (err) | 815 | if (err) |
816 | goto exit; | 816 | goto exit; |
817 | 817 | ||
818 | get_online_cpus(); | ||
818 | for_each_online_cpu(i) | 819 | for_each_online_cpu(i) |
819 | get_core_online(i); | 820 | get_core_online(i); |
820 | 821 | ||
821 | #ifndef CONFIG_HOTPLUG_CPU | 822 | #ifndef CONFIG_HOTPLUG_CPU |
822 | if (list_empty(&pdev_list)) { | 823 | if (list_empty(&pdev_list)) { |
824 | put_online_cpus(); | ||
823 | err = -ENODEV; | 825 | err = -ENODEV; |
824 | goto exit_driver_unreg; | 826 | goto exit_driver_unreg; |
825 | } | 827 | } |
826 | #endif | 828 | #endif |
827 | 829 | ||
828 | register_hotcpu_notifier(&coretemp_cpu_notifier); | 830 | register_hotcpu_notifier(&coretemp_cpu_notifier); |
831 | put_online_cpus(); | ||
829 | return 0; | 832 | return 0; |
830 | 833 | ||
831 | #ifndef CONFIG_HOTPLUG_CPU | 834 | #ifndef CONFIG_HOTPLUG_CPU |
@@ -840,6 +843,7 @@ static void __exit coretemp_exit(void) | |||
840 | { | 843 | { |
841 | struct pdev_entry *p, *n; | 844 | struct pdev_entry *p, *n; |
842 | 845 | ||
846 | get_online_cpus(); | ||
843 | unregister_hotcpu_notifier(&coretemp_cpu_notifier); | 847 | unregister_hotcpu_notifier(&coretemp_cpu_notifier); |
844 | mutex_lock(&pdev_list_mutex); | 848 | mutex_lock(&pdev_list_mutex); |
845 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 849 | list_for_each_entry_safe(p, n, &pdev_list, list) { |
@@ -848,6 +852,7 @@ static void __exit coretemp_exit(void) | |||
848 | kfree(p); | 852 | kfree(p); |
849 | } | 853 | } |
850 | mutex_unlock(&pdev_list_mutex); | 854 | mutex_unlock(&pdev_list_mutex); |
855 | put_online_cpus(); | ||
851 | platform_driver_unregister(&coretemp_driver); | 856 | platform_driver_unregister(&coretemp_driver); |
852 | } | 857 | } |
853 | 858 | ||
diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index 2764b78a784b..af69073b3fe8 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c | |||
@@ -129,12 +129,12 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) | |||
129 | * counter saturations resulting in bogus power readings. | 129 | * counter saturations resulting in bogus power readings. |
130 | * We correct this value ourselves to cope with older BIOSes. | 130 | * We correct this value ourselves to cope with older BIOSes. |
131 | */ | 131 | */ |
132 | static DEFINE_PCI_DEVICE_TABLE(affected_device) = { | 132 | static const struct pci_device_id affected_device[] = { |
133 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, | 133 | { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, |
134 | { 0 } | 134 | { 0 } |
135 | }; | 135 | }; |
136 | 136 | ||
137 | static void __devinit tweak_runavg_range(struct pci_dev *pdev) | 137 | static void tweak_runavg_range(struct pci_dev *pdev) |
138 | { | 138 | { |
139 | u32 val; | 139 | u32 val; |
140 | 140 | ||
@@ -158,6 +158,16 @@ static void __devinit tweak_runavg_range(struct pci_dev *pdev) | |||
158 | REG_TDP_RUNNING_AVERAGE, val); | 158 | REG_TDP_RUNNING_AVERAGE, val); |
159 | } | 159 | } |
160 | 160 | ||
161 | #ifdef CONFIG_PM | ||
162 | static int fam15h_power_resume(struct pci_dev *pdev) | ||
163 | { | ||
164 | tweak_runavg_range(pdev); | ||
165 | return 0; | ||
166 | } | ||
167 | #else | ||
168 | #define fam15h_power_resume NULL | ||
169 | #endif | ||
170 | |||
161 | static void __devinit fam15h_power_init_data(struct pci_dev *f4, | 171 | static void __devinit fam15h_power_init_data(struct pci_dev *f4, |
162 | struct fam15h_power_data *data) | 172 | struct fam15h_power_data *data) |
163 | { | 173 | { |
@@ -256,6 +266,7 @@ static struct pci_driver fam15h_power_driver = { | |||
256 | .id_table = fam15h_power_id_table, | 266 | .id_table = fam15h_power_id_table, |
257 | .probe = fam15h_power_probe, | 267 | .probe = fam15h_power_probe, |
258 | .remove = __devexit_p(fam15h_power_remove), | 268 | .remove = __devexit_p(fam15h_power_remove), |
269 | .resume = fam15h_power_resume, | ||
259 | }; | 270 | }; |
260 | 271 | ||
261 | module_pci_driver(fam15h_power_driver); | 272 | module_pci_driver(fam15h_power_driver); |
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a385729..602148299f68 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -69,22 +69,6 @@ struct ina2xx_data { | |||
69 | u16 regs[INA2XX_MAX_REGISTERS]; | 69 | u16 regs[INA2XX_MAX_REGISTERS]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | int ina2xx_read_word(struct i2c_client *client, int reg) | ||
73 | { | ||
74 | int val = i2c_smbus_read_word_data(client, reg); | ||
75 | if (unlikely(val < 0)) { | ||
76 | dev_dbg(&client->dev, | ||
77 | "Failed to read register: %d\n", reg); | ||
78 | return val; | ||
79 | } | ||
80 | return be16_to_cpu(val); | ||
81 | } | ||
82 | |||
83 | void ina2xx_write_word(struct i2c_client *client, int reg, int data) | ||
84 | { | ||
85 | i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); | ||
86 | } | ||
87 | |||
88 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) | 72 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) |
89 | { | 73 | { |
90 | struct i2c_client *client = to_i2c_client(dev); | 74 | struct i2c_client *client = to_i2c_client(dev); |
@@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev) | |||
102 | 86 | ||
103 | /* Read all registers */ | 87 | /* Read all registers */ |
104 | for (i = 0; i < data->registers; i++) { | 88 | for (i = 0; i < data->registers; i++) { |
105 | int rv = ina2xx_read_word(client, i); | 89 | int rv = i2c_smbus_read_word_swapped(client, i); |
106 | if (rv < 0) { | 90 | if (rv < 0) { |
107 | ret = ERR_PTR(rv); | 91 | ret = ERR_PTR(rv); |
108 | goto abort; | 92 | goto abort; |
@@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client, | |||
279 | switch (data->kind) { | 263 | switch (data->kind) { |
280 | case ina219: | 264 | case ina219: |
281 | /* device configuration */ | 265 | /* device configuration */ |
282 | ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); | 266 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
267 | INA219_CONFIG_DEFAULT); | ||
283 | 268 | ||
284 | /* set current LSB to 1mA, shunt is in uOhms */ | 269 | /* set current LSB to 1mA, shunt is in uOhms */ |
285 | /* (equation 13 in datasheet) */ | 270 | /* (equation 13 in datasheet) */ |
286 | ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); | 271 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
272 | 40960000 / shunt); | ||
287 | dev_info(&client->dev, | 273 | dev_info(&client->dev, |
288 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); | 274 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); |
289 | data->registers = INA219_REGISTERS; | 275 | data->registers = INA219_REGISTERS; |
290 | break; | 276 | break; |
291 | case ina226: | 277 | case ina226: |
292 | /* device configuration */ | 278 | /* device configuration */ |
293 | ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); | 279 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
280 | INA226_CONFIG_DEFAULT); | ||
294 | 281 | ||
295 | /* set current LSB to 1mA, shunt is in uOhms */ | 282 | /* set current LSB to 1mA, shunt is in uOhms */ |
296 | /* (equation 1 in datasheet)*/ | 283 | /* (equation 1 in datasheet)*/ |
297 | ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); | 284 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
285 | 5120000 / shunt); | ||
298 | dev_info(&client->dev, | 286 | dev_info(&client->dev, |
299 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); | 287 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); |
300 | data->registers = INA226_REGISTERS; | 288 | data->registers = INA226_REGISTERS; |
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd0097..1a174f0a3cde 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c | |||
@@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev, | |||
44 | struct device_attribute *devattr, char *buf) | 44 | struct device_attribute *devattr, char *buf) |
45 | { | 45 | { |
46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
47 | struct twl4030_madc_request req; | 47 | struct twl4030_madc_request req = { |
48 | .channels = 1 << attr->index, | ||
49 | .method = TWL4030_MADC_SW2, | ||
50 | .type = TWL4030_MADC_WAIT, | ||
51 | }; | ||
48 | long val; | 52 | long val; |
49 | 53 | ||
50 | req.channels = (1 << attr->index); | ||
51 | req.method = TWL4030_MADC_SW2; | ||
52 | req.func_cb = NULL; | ||
53 | val = twl4030_madc_conversion(&req); | 54 | val = twl4030_madc_conversion(&req); |
54 | if (val < 0) | 55 | if (val < 0) |
55 | return val; | 56 | return val; |
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index ee4ebc198a94..2e56c6ce9fb6 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c | |||
@@ -328,6 +328,7 @@ static int __init via_cputemp_init(void) | |||
328 | if (err) | 328 | if (err) |
329 | goto exit; | 329 | goto exit; |
330 | 330 | ||
331 | get_online_cpus(); | ||
331 | for_each_online_cpu(i) { | 332 | for_each_online_cpu(i) { |
332 | struct cpuinfo_x86 *c = &cpu_data(i); | 333 | struct cpuinfo_x86 *c = &cpu_data(i); |
333 | 334 | ||
@@ -347,12 +348,14 @@ static int __init via_cputemp_init(void) | |||
347 | 348 | ||
348 | #ifndef CONFIG_HOTPLUG_CPU | 349 | #ifndef CONFIG_HOTPLUG_CPU |
349 | if (list_empty(&pdev_list)) { | 350 | if (list_empty(&pdev_list)) { |
351 | put_online_cpus(); | ||
350 | err = -ENODEV; | 352 | err = -ENODEV; |
351 | goto exit_driver_unreg; | 353 | goto exit_driver_unreg; |
352 | } | 354 | } |
353 | #endif | 355 | #endif |
354 | 356 | ||
355 | register_hotcpu_notifier(&via_cputemp_cpu_notifier); | 357 | register_hotcpu_notifier(&via_cputemp_cpu_notifier); |
358 | put_online_cpus(); | ||
356 | return 0; | 359 | return 0; |
357 | 360 | ||
358 | #ifndef CONFIG_HOTPLUG_CPU | 361 | #ifndef CONFIG_HOTPLUG_CPU |
@@ -367,6 +370,7 @@ static void __exit via_cputemp_exit(void) | |||
367 | { | 370 | { |
368 | struct pdev_entry *p, *n; | 371 | struct pdev_entry *p, *n; |
369 | 372 | ||
373 | get_online_cpus(); | ||
370 | unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); | 374 | unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); |
371 | mutex_lock(&pdev_list_mutex); | 375 | mutex_lock(&pdev_list_mutex); |
372 | list_for_each_entry_safe(p, n, &pdev_list, list) { | 376 | list_for_each_entry_safe(p, n, &pdev_list, list) { |
@@ -375,6 +379,7 @@ static void __exit via_cputemp_exit(void) | |||
375 | kfree(p); | 379 | kfree(p); |
376 | } | 380 | } |
377 | mutex_unlock(&pdev_list_mutex); | 381 | mutex_unlock(&pdev_list_mutex); |
382 | put_online_cpus(); | ||
378 | platform_driver_unregister(&via_cputemp_driver); | 383 | platform_driver_unregister(&via_cputemp_driver); |
379 | } | 384 | } |
380 | 385 | ||
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index ab4825205a9d..5b1a6a666441 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -1206,7 +1206,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, | |||
1206 | int err = -ENODEV; | 1206 | int err = -ENODEV; |
1207 | u16 val; | 1207 | u16 val; |
1208 | 1208 | ||
1209 | static const __initdata char *names[] = { | 1209 | static __initconst char *const names[] = { |
1210 | "W83627HF", | 1210 | "W83627HF", |
1211 | "W83627THF", | 1211 | "W83627THF", |
1212 | "W83697HF", | 1212 | "W83697HF", |
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 1201a15784c3..db713c0dfba4 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c | |||
@@ -552,7 +552,7 @@ EXPORT_SYMBOL_GPL(hwspin_lock_request_specific); | |||
552 | */ | 552 | */ |
553 | int hwspin_lock_free(struct hwspinlock *hwlock) | 553 | int hwspin_lock_free(struct hwspinlock *hwlock) |
554 | { | 554 | { |
555 | struct device *dev = hwlock->bank->dev; | 555 | struct device *dev; |
556 | struct hwspinlock *tmp; | 556 | struct hwspinlock *tmp; |
557 | int ret; | 557 | int ret; |
558 | 558 | ||
@@ -561,6 +561,7 @@ int hwspin_lock_free(struct hwspinlock *hwlock) | |||
561 | return -EINVAL; | 561 | return -EINVAL; |
562 | } | 562 | } |
563 | 563 | ||
564 | dev = hwlock->bank->dev; | ||
564 | mutex_lock(&hwspinlock_tree_lock); | 565 | mutex_lock(&hwspinlock_tree_lock); |
565 | 566 | ||
566 | /* make sure the hwspinlock is used */ | 567 | /* make sure the hwspinlock is used */ |
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 73133b1063f0..6f5f98d69af7 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -476,17 +476,17 @@ static int pca_init(struct i2c_adapter *adap) | |||
476 | /* To avoid integer overflow, use clock/100 for calculations */ | 476 | /* To avoid integer overflow, use clock/100 for calculations */ |
477 | clock = pca_clock(pca_data) / 100; | 477 | clock = pca_clock(pca_data) / 100; |
478 | 478 | ||
479 | if (pca_data->i2c_clock > 10000) { | 479 | if (pca_data->i2c_clock > 1000000) { |
480 | mode = I2C_PCA_MODE_TURBO; | 480 | mode = I2C_PCA_MODE_TURBO; |
481 | min_tlow = 14; | 481 | min_tlow = 14; |
482 | min_thi = 5; | 482 | min_thi = 5; |
483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
484 | } else if (pca_data->i2c_clock > 4000) { | 484 | } else if (pca_data->i2c_clock > 400000) { |
485 | mode = I2C_PCA_MODE_FASTP; | 485 | mode = I2C_PCA_MODE_FASTP; |
486 | min_tlow = 17; | 486 | min_tlow = 17; |
487 | min_thi = 9; | 487 | min_thi = 9; |
488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
489 | } else if (pca_data->i2c_clock > 1000) { | 489 | } else if (pca_data->i2c_clock > 100000) { |
490 | mode = I2C_PCA_MODE_FAST; | 490 | mode = I2C_PCA_MODE_FAST; |
491 | min_tlow = 44; | 491 | min_tlow = 44; |
492 | min_thi = 20; | 492 | min_thi = 20; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd6728..970a1612e795 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -104,6 +104,7 @@ config I2C_I801 | |||
104 | DH89xxCC (PCH) | 104 | DH89xxCC (PCH) |
105 | Panther Point (PCH) | 105 | Panther Point (PCH) |
106 | Lynx Point (PCH) | 106 | Lynx Point (PCH) |
107 | Lynx Point-LP (PCH) | ||
107 | 108 | ||
108 | This driver can also be built as a module. If so, the module | 109 | This driver can also be built as a module. If so, the module |
109 | will be called i2c-i801. | 110 | will be called i2c-i801. |
@@ -354,9 +355,13 @@ config I2C_DAVINCI | |||
354 | devices such as DaVinci NIC. | 355 | devices such as DaVinci NIC. |
355 | For details please see http://www.ti.com/davinci | 356 | For details please see http://www.ti.com/davinci |
356 | 357 | ||
358 | config I2C_DESIGNWARE_CORE | ||
359 | tristate | ||
360 | |||
357 | config I2C_DESIGNWARE_PLATFORM | 361 | config I2C_DESIGNWARE_PLATFORM |
358 | tristate "Synopsys DesignWare Platform" | 362 | tristate "Synopsys DesignWare Platform" |
359 | depends on HAVE_CLK | 363 | depends on HAVE_CLK |
364 | select I2C_DESIGNWARE_CORE | ||
360 | help | 365 | help |
361 | If you say yes to this option, support will be included for the | 366 | If you say yes to this option, support will be included for the |
362 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 367 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM | |||
367 | config I2C_DESIGNWARE_PCI | 372 | config I2C_DESIGNWARE_PCI |
368 | tristate "Synopsys DesignWare PCI" | 373 | tristate "Synopsys DesignWare PCI" |
369 | depends on PCI | 374 | depends on PCI |
375 | select I2C_DESIGNWARE_CORE | ||
370 | help | 376 | help |
371 | If you say yes to this option, support will be included for the | 377 | If you say yes to this option, support will be included for the |
372 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 378 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb40..37c4182cc98b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | |||
33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o | 33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o |
34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o | 34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o |
35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o | 35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o |
36 | obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o | ||
36 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o | 37 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o |
37 | i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o | 38 | i2c-designware-platform-objs := i2c-designware-platdrv.o |
38 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o | 39 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o |
39 | i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o | 40 | i2c-designware-pci-objs := i2c-designware-pcidrv.o |
40 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o | 41 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o |
41 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o | 42 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o |
42 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o | 43 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80edf..7b8ebbefb581 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * ---------------------------------------------------------------------------- | 25 | * ---------------------------------------------------------------------------- |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | #include <linux/export.h> | ||
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
316 | dw_writel(dev, dev->master_cfg , DW_IC_CON); | 317 | dw_writel(dev, dev->master_cfg , DW_IC_CON); |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(i2c_dw_init); | ||
319 | 321 | ||
320 | /* | 322 | /* |
321 | * Waiting for bus not busy | 323 | * Waiting for bus not busy |
@@ -568,12 +570,14 @@ done: | |||
568 | 570 | ||
569 | return ret; | 571 | return ret; |
570 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(i2c_dw_xfer); | ||
571 | 574 | ||
572 | u32 i2c_dw_func(struct i2c_adapter *adap) | 575 | u32 i2c_dw_func(struct i2c_adapter *adap) |
573 | { | 576 | { |
574 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | 577 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); |
575 | return dev->functionality; | 578 | return dev->functionality; |
576 | } | 579 | } |
580 | EXPORT_SYMBOL_GPL(i2c_dw_func); | ||
577 | 581 | ||
578 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | 582 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
579 | { | 583 | { |
@@ -678,17 +682,20 @@ tx_aborted: | |||
678 | 682 | ||
679 | return IRQ_HANDLED; | 683 | return IRQ_HANDLED; |
680 | } | 684 | } |
685 | EXPORT_SYMBOL_GPL(i2c_dw_isr); | ||
681 | 686 | ||
682 | void i2c_dw_enable(struct dw_i2c_dev *dev) | 687 | void i2c_dw_enable(struct dw_i2c_dev *dev) |
683 | { | 688 | { |
684 | /* Enable the adapter */ | 689 | /* Enable the adapter */ |
685 | dw_writel(dev, 1, DW_IC_ENABLE); | 690 | dw_writel(dev, 1, DW_IC_ENABLE); |
686 | } | 691 | } |
692 | EXPORT_SYMBOL_GPL(i2c_dw_enable); | ||
687 | 693 | ||
688 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) | 694 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) |
689 | { | 695 | { |
690 | return dw_readl(dev, DW_IC_ENABLE); | 696 | return dw_readl(dev, DW_IC_ENABLE); |
691 | } | 697 | } |
698 | EXPORT_SYMBOL_GPL(i2c_dw_is_enabled); | ||
692 | 699 | ||
693 | void i2c_dw_disable(struct dw_i2c_dev *dev) | 700 | void i2c_dw_disable(struct dw_i2c_dev *dev) |
694 | { | 701 | { |
@@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) | |||
699 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 706 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
700 | dw_readl(dev, DW_IC_CLR_INTR); | 707 | dw_readl(dev, DW_IC_CLR_INTR); |
701 | } | 708 | } |
709 | EXPORT_SYMBOL_GPL(i2c_dw_disable); | ||
702 | 710 | ||
703 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) | 711 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) |
704 | { | 712 | { |
705 | dw_readl(dev, DW_IC_CLR_INTR); | 713 | dw_readl(dev, DW_IC_CLR_INTR); |
706 | } | 714 | } |
715 | EXPORT_SYMBOL_GPL(i2c_dw_clear_int); | ||
707 | 716 | ||
708 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) | 717 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) |
709 | { | 718 | { |
710 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 719 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
711 | } | 720 | } |
721 | EXPORT_SYMBOL_GPL(i2c_dw_disable_int); | ||
712 | 722 | ||
713 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) | 723 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) |
714 | { | 724 | { |
715 | return dw_readl(dev, DW_IC_COMP_PARAM_1); | 725 | return dw_readl(dev, DW_IC_COMP_PARAM_1); |
716 | } | 726 | } |
727 | EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); | ||
diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c index aedb94f34bf7..dae3ddfe7619 100644 --- a/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/drivers/i2c/busses/i2c-diolan-u2c.c | |||
@@ -405,6 +405,7 @@ static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, | |||
405 | } | 405 | } |
406 | } | 406 | } |
407 | } | 407 | } |
408 | ret = num; | ||
408 | abort: | 409 | abort: |
409 | sret = diolan_i2c_stop(dev); | 410 | sret = diolan_i2c_stop(dev); |
410 | if (sret < 0 && ret >= 0) | 411 | if (sret < 0 && ret >= 0) |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ade..33e9b0c09af2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -52,6 +52,7 @@ | |||
52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes | 52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes |
53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes | 53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes |
54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes | 54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes |
55 | Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes | ||
55 | 56 | ||
56 | Features supported by this driver: | 57 | Features supported by this driver: |
57 | Software PEC no | 58 | Software PEC no |
@@ -155,6 +156,7 @@ | |||
155 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | 156 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 |
156 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | 157 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 |
157 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 | 158 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 |
159 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 | ||
158 | 160 | ||
159 | struct i801_priv { | 161 | struct i801_priv { |
160 | struct i2c_adapter adapter; | 162 | struct i2c_adapter adapter; |
@@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { | |||
771 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, | 773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, |
772 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, | 774 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, |
773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, | 775 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, |
776 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, | ||
774 | { 0, } | 777 | { 0, } |
775 | }; | 778 | }; |
776 | 779 | ||
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17d..51f05b8520ed 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
365 | struct device_node *node = dev->of_node; | 365 | struct device_node *node = dev->of_node; |
366 | int ret; | 366 | int ret; |
367 | 367 | ||
368 | if (!node) | ||
369 | return -EINVAL; | ||
370 | |||
371 | i2c->speed = &mxs_i2c_95kHz_config; | ||
372 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 368 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
373 | if (ret) | 369 | if (ret) |
374 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); | 370 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); |
@@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) | |||
419 | return err; | 415 | return err; |
420 | 416 | ||
421 | i2c->dev = dev; | 417 | i2c->dev = dev; |
418 | i2c->speed = &mxs_i2c_95kHz_config; | ||
422 | 419 | ||
423 | err = mxs_i2c_get_ofdata(i2c); | 420 | if (dev->of_node) { |
424 | if (err) | 421 | err = mxs_i2c_get_ofdata(i2c); |
425 | return err; | 422 | if (err) |
423 | return err; | ||
424 | } | ||
426 | 425 | ||
427 | platform_set_drvdata(pdev, i2c); | 426 | platform_set_drvdata(pdev, i2c); |
428 | 427 | ||
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 5e6f1eed4f83..61b00edacb08 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c | |||
@@ -350,10 +350,6 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev) | |||
350 | 350 | ||
351 | i2c_clk = clk_get_rate(dev->clk); | 351 | i2c_clk = clk_get_rate(dev->clk); |
352 | 352 | ||
353 | /* fallback to std. mode if machine has not provided it */ | ||
354 | if (dev->cfg.clk_freq == 0) | ||
355 | dev->cfg.clk_freq = 100000; | ||
356 | |||
357 | /* | 353 | /* |
358 | * The spec says, in case of std. mode the divider is | 354 | * The spec says, in case of std. mode the divider is |
359 | * 2 whereas it is 3 for fast and fastplus mode of | 355 | * 2 whereas it is 3 for fast and fastplus mode of |
@@ -911,20 +907,32 @@ static const struct i2c_algorithm nmk_i2c_algo = { | |||
911 | .functionality = nmk_i2c_functionality | 907 | .functionality = nmk_i2c_functionality |
912 | }; | 908 | }; |
913 | 909 | ||
910 | static struct nmk_i2c_controller u8500_i2c = { | ||
911 | /* | ||
912 | * Slave data setup time; 250ns, 100ns, and 10ns, which | ||
913 | * is 14, 6 and 2 respectively for a 48Mhz i2c clock. | ||
914 | */ | ||
915 | .slsu = 0xe, | ||
916 | .tft = 1, /* Tx FIFO threshold */ | ||
917 | .rft = 8, /* Rx FIFO threshold */ | ||
918 | .clk_freq = 400000, /* fast mode operation */ | ||
919 | .timeout = 200, /* Slave response timeout(ms) */ | ||
920 | .sm = I2C_FREQ_MODE_FAST, | ||
921 | }; | ||
922 | |||
914 | static atomic_t adapter_id = ATOMIC_INIT(0); | 923 | static atomic_t adapter_id = ATOMIC_INIT(0); |
915 | 924 | ||
916 | static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) | 925 | static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id) |
917 | { | 926 | { |
918 | int ret = 0; | 927 | int ret = 0; |
919 | struct nmk_i2c_controller *pdata = | 928 | struct nmk_i2c_controller *pdata = adev->dev.platform_data; |
920 | adev->dev.platform_data; | ||
921 | struct nmk_i2c_dev *dev; | 929 | struct nmk_i2c_dev *dev; |
922 | struct i2c_adapter *adap; | 930 | struct i2c_adapter *adap; |
923 | 931 | ||
924 | if (!pdata) { | 932 | if (!pdata) |
925 | dev_warn(&adev->dev, "no platform data\n"); | 933 | /* No i2c configuration found, using the default. */ |
926 | return -ENODEV; | 934 | pdata = &u8500_i2c; |
927 | } | 935 | |
928 | dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); | 936 | dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL); |
929 | if (!dev) { | 937 | if (!dev) { |
930 | dev_err(&adev->dev, "cannot allocate memory\n"); | 938 | dev_err(&adev->dev, "cannot allocate memory\n"); |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 6849635b268a..5d19a49803c1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -584,7 +584,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |||
584 | 584 | ||
585 | r = pm_runtime_get_sync(dev->dev); | 585 | r = pm_runtime_get_sync(dev->dev); |
586 | if (IS_ERR_VALUE(r)) | 586 | if (IS_ERR_VALUE(r)) |
587 | return r; | 587 | goto out; |
588 | 588 | ||
589 | r = omap_i2c_wait_for_bb(dev); | 589 | r = omap_i2c_wait_for_bb(dev); |
590 | if (r < 0) | 590 | if (r < 0) |
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b0..8488bddfe465 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -48,8 +48,9 @@ enum { | |||
48 | mcntrl_afie = 0x00000002, | 48 | mcntrl_afie = 0x00000002, |
49 | mcntrl_naie = 0x00000004, | 49 | mcntrl_naie = 0x00000004, |
50 | mcntrl_drmie = 0x00000008, | 50 | mcntrl_drmie = 0x00000008, |
51 | mcntrl_daie = 0x00000020, | 51 | mcntrl_drsie = 0x00000010, |
52 | mcntrl_rffie = 0x00000040, | 52 | mcntrl_rffie = 0x00000020, |
53 | mcntrl_daie = 0x00000040, | ||
53 | mcntrl_tffie = 0x00000080, | 54 | mcntrl_tffie = 0x00000080, |
54 | mcntrl_reset = 0x00000100, | 55 | mcntrl_reset = 0x00000100, |
55 | mcntrl_cdbmode = 0x00000400, | 56 | mcntrl_cdbmode = 0x00000400, |
@@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) | |||
290 | * or we didn't 'ask' for it yet. | 291 | * or we didn't 'ask' for it yet. |
291 | */ | 292 | */ |
292 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 293 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
293 | dev_dbg(&alg_data->adapter.dev, | 294 | /* 'Asking' is done asynchronously, e.g. dummy TX of several |
294 | "%s(): Write dummy data to fill Rx-fifo...\n", | 295 | * bytes is done before the first actual RX arrives in FIFO. |
295 | __func__); | 296 | * Therefore, ordered bytes (via TX) are counted separately. |
297 | */ | ||
298 | if (alg_data->mif.order) { | ||
299 | dev_dbg(&alg_data->adapter.dev, | ||
300 | "%s(): Write dummy data to fill Rx-fifo...\n", | ||
301 | __func__); | ||
296 | 302 | ||
297 | if (alg_data->mif.len == 1) { | 303 | if (alg_data->mif.order == 1) { |
298 | /* Last byte, do not acknowledge next rcv. */ | 304 | /* Last byte, do not acknowledge next rcv. */ |
299 | val |= stop_bit; | 305 | val |= stop_bit; |
306 | |||
307 | /* | ||
308 | * Enable interrupt RFDAIE (data in Rx fifo), | ||
309 | * and disable DRMIE (need data for Tx) | ||
310 | */ | ||
311 | ctl = ioread32(I2C_REG_CTL(alg_data)); | ||
312 | ctl |= mcntrl_rffie | mcntrl_daie; | ||
313 | ctl &= ~mcntrl_drmie; | ||
314 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
315 | } | ||
300 | 316 | ||
301 | /* | 317 | /* |
302 | * Enable interrupt RFDAIE (data in Rx fifo), | 318 | * Now we'll 'ask' for data: |
303 | * and disable DRMIE (need data for Tx) | 319 | * For each byte we want to receive, we must |
320 | * write a (dummy) byte to the Tx-FIFO. | ||
304 | */ | 321 | */ |
305 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 322 | iowrite32(val, I2C_REG_TX(alg_data)); |
306 | ctl |= mcntrl_rffie | mcntrl_daie; | 323 | alg_data->mif.order--; |
307 | ctl &= ~mcntrl_drmie; | ||
308 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
309 | } | 324 | } |
310 | |||
311 | /* | ||
312 | * Now we'll 'ask' for data: | ||
313 | * For each byte we want to receive, we must | ||
314 | * write a (dummy) byte to the Tx-FIFO. | ||
315 | */ | ||
316 | iowrite32(val, I2C_REG_TX(alg_data)); | ||
317 | |||
318 | return 0; | 325 | return 0; |
319 | } | 326 | } |
320 | 327 | ||
@@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
514 | 521 | ||
515 | alg_data->mif.buf = pmsg->buf; | 522 | alg_data->mif.buf = pmsg->buf; |
516 | alg_data->mif.len = pmsg->len; | 523 | alg_data->mif.len = pmsg->len; |
524 | alg_data->mif.order = pmsg->len; | ||
517 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? | 525 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? |
518 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; | 526 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; |
519 | alg_data->mif.ret = 0; | 527 | alg_data->mif.ret = 0; |
@@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
566 | /* Cleanup to be sure... */ | 574 | /* Cleanup to be sure... */ |
567 | alg_data->mif.buf = NULL; | 575 | alg_data->mif.buf = NULL; |
568 | alg_data->mif.len = 0; | 576 | alg_data->mif.len = 0; |
577 | alg_data->mif.order = 0; | ||
569 | 578 | ||
570 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", | 579 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
571 | __func__, ioread32(I2C_REG_STS(alg_data))); | 580 | __func__, ioread32(I2C_REG_STS(alg_data))); |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 66eb53fac202..9a08c57bc936 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -712,7 +712,7 @@ static int __devexit tegra_i2c_remove(struct platform_device *pdev) | |||
712 | return 0; | 712 | return 0; |
713 | } | 713 | } |
714 | 714 | ||
715 | #ifdef CONFIG_PM | 715 | #ifdef CONFIG_PM_SLEEP |
716 | static int tegra_i2c_suspend(struct device *dev) | 716 | static int tegra_i2c_suspend(struct device *dev) |
717 | { | 717 | { |
718 | struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); | 718 | struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2c..2091ae8f539a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * This function is only needed for mutex_lock_nested, so it is never | ||
641 | * called unless locking correctness checking is enabled. Thus we | ||
642 | * make it inline to avoid a compiler warning. That's what gcc ends up | ||
643 | * doing anyway. | ||
644 | */ | ||
645 | static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) | ||
646 | { | ||
647 | unsigned int depth = 0; | ||
648 | |||
649 | while ((adapter = i2c_parent_is_i2c_adapter(adapter))) | ||
650 | depth++; | ||
651 | |||
652 | return depth; | ||
653 | } | ||
654 | |||
655 | /* | ||
640 | * Let users instantiate I2C devices through sysfs. This can be used when | 656 | * Let users instantiate I2C devices through sysfs. This can be used when |
641 | * platform initialization code doesn't contain the proper data for | 657 | * platform initialization code doesn't contain the proper data for |
642 | * whatever reason. Also useful for drivers that do device detection and | 658 | * whatever reason. Also useful for drivers that do device detection and |
@@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
726 | 742 | ||
727 | /* Make sure the device was added through sysfs */ | 743 | /* Make sure the device was added through sysfs */ |
728 | res = -ENOENT; | 744 | res = -ENOENT; |
729 | mutex_lock(&adap->userspace_clients_lock); | 745 | mutex_lock_nested(&adap->userspace_clients_lock, |
746 | i2c_adapter_depth(adap)); | ||
730 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 747 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
731 | detected) { | 748 | detected) { |
732 | if (client->addr == addr) { | 749 | if (client->addr == addr) { |
@@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1073 | return res; | 1090 | return res; |
1074 | 1091 | ||
1075 | /* Remove devices instantiated from sysfs */ | 1092 | /* Remove devices instantiated from sysfs */ |
1076 | mutex_lock(&adap->userspace_clients_lock); | 1093 | mutex_lock_nested(&adap->userspace_clients_lock, |
1094 | i2c_adapter_depth(adap)); | ||
1077 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1095 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1078 | detected) { | 1096 | detected) { |
1079 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1097 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 92406097efeb..8d1e32d7cd97 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
6 | { | 6 | { |
7 | ide_drive_t *drive = dev_get_drvdata(dev); | 7 | ide_drive_t *drive = to_ide_device(dev); |
8 | ide_drive_t *pair = ide_get_pair_dev(drive); | 8 | ide_drive_t *pair = ide_get_pair_dev(drive); |
9 | ide_hwif_t *hwif = drive->hwif; | 9 | ide_hwif_t *hwif = drive->hwif; |
10 | struct request *rq; | 10 | struct request *rq; |
@@ -40,7 +40,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
40 | 40 | ||
41 | int generic_ide_resume(struct device *dev) | 41 | int generic_ide_resume(struct device *dev) |
42 | { | 42 | { |
43 | ide_drive_t *drive = dev_get_drvdata(dev); | 43 | ide_drive_t *drive = to_ide_device(dev); |
44 | ide_drive_t *pair = ide_get_pair_dev(drive); | 44 | ide_drive_t *pair = ide_get_pair_dev(drive); |
45 | ide_hwif_t *hwif = drive->hwif; | 45 | ide_hwif_t *hwif = drive->hwif; |
46 | struct request *rq; | 46 | struct request *rq; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index f559088869f6..e8726177d103 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -606,8 +606,9 @@ static int __init intel_idle_init(void) | |||
606 | intel_idle_cpuidle_driver_init(); | 606 | intel_idle_cpuidle_driver_init(); |
607 | retval = cpuidle_register_driver(&intel_idle_driver); | 607 | retval = cpuidle_register_driver(&intel_idle_driver); |
608 | if (retval) { | 608 | if (retval) { |
609 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
609 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | 610 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", |
610 | cpuidle_get_driver()->name); | 611 | drv ? drv->name : "none"); |
611 | return retval; | 612 | return retval; |
612 | } | 613 | } |
613 | 614 | ||
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a02374..3bd5540238a7 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
@@ -617,7 +617,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) | |||
617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); | 617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); |
618 | if (IS_ERR(st->adc_clk)) { | 618 | if (IS_ERR(st->adc_clk)) { |
619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); | 619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); |
620 | ret = PTR_ERR(st->clk); | 620 | ret = PTR_ERR(st->adc_clk); |
621 | goto error_disable_clk; | 621 | goto error_disable_clk; |
622 | } | 622 | } |
623 | 623 | ||
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 59fbb3ae40e7..e35bb8f6fe75 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c | |||
@@ -129,7 +129,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
129 | { | 129 | { |
130 | struct adf4350_platform_data *pdata = st->pdata; | 130 | struct adf4350_platform_data *pdata = st->pdata; |
131 | u64 tmp; | 131 | u64 tmp; |
132 | u32 div_gcd, prescaler; | 132 | u32 div_gcd, prescaler, chspc; |
133 | u16 mdiv, r_cnt = 0; | 133 | u16 mdiv, r_cnt = 0; |
134 | u8 band_sel_div; | 134 | u8 band_sel_div; |
135 | 135 | ||
@@ -158,14 +158,20 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
158 | if (pdata->ref_div_factor) | 158 | if (pdata->ref_div_factor) |
159 | r_cnt = pdata->ref_div_factor - 1; | 159 | r_cnt = pdata->ref_div_factor - 1; |
160 | 160 | ||
161 | do { | 161 | chspc = st->chspc; |
162 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | ||
163 | 162 | ||
164 | st->r1_mod = st->fpfd / st->chspc; | 163 | do { |
165 | while (st->r1_mod > ADF4350_MAX_MODULUS) { | 164 | do { |
166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | 165 | do { |
167 | st->r1_mod = st->fpfd / st->chspc; | 166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); |
168 | } | 167 | st->r1_mod = st->fpfd / chspc; |
168 | if (r_cnt > ADF4350_MAX_R_CNT) { | ||
169 | /* try higher spacing values */ | ||
170 | chspc++; | ||
171 | r_cnt = 0; | ||
172 | } | ||
173 | } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); | ||
174 | } while (r_cnt == 0); | ||
169 | 175 | ||
170 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); | 176 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); |
171 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ | 177 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ |
@@ -194,7 +200,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
194 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | | 200 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | |
195 | ADF4350_REG0_FRACT(st->r0_fract); | 201 | ADF4350_REG0_FRACT(st->r0_fract); |
196 | 202 | ||
197 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) | | 203 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(1) | |
198 | ADF4350_REG1_MOD(st->r1_mod) | | 204 | ADF4350_REG1_MOD(st->r1_mod) | |
199 | prescaler; | 205 | prescaler; |
200 | 206 | ||
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 1cbb449b319a..9a99f43094f0 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c | |||
@@ -271,9 +271,10 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev, | |||
271 | const unsigned long *scan_mask) | 271 | const unsigned long *scan_mask) |
272 | { | 272 | { |
273 | struct adjd_s311_data *data = iio_priv(indio_dev); | 273 | struct adjd_s311_data *data = iio_priv(indio_dev); |
274 | data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, | 274 | |
275 | GFP_KERNEL); | 275 | kfree(data->buffer); |
276 | if (!data->buffer) | 276 | data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); |
277 | if (data->buffer == NULL) | ||
277 | return -ENOMEM; | 278 | return -ENOMEM; |
278 | 279 | ||
279 | return 0; | 280 | return 0; |
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index c3e7bac13123..e45712a921ce 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c | |||
@@ -404,7 +404,7 @@ out: | |||
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |
406 | 406 | ||
407 | static int show_thresh_either_en(struct device *dev, | 407 | static ssize_t show_thresh_either_en(struct device *dev, |
408 | struct device_attribute *attr, | 408 | struct device_attribute *attr, |
409 | char *buf) | 409 | char *buf) |
410 | { | 410 | { |
@@ -424,7 +424,7 @@ static int show_thresh_either_en(struct device *dev, | |||
424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); | 424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); |
425 | } | 425 | } |
426 | 426 | ||
427 | static int store_thresh_either_en(struct device *dev, | 427 | static ssize_t store_thresh_either_en(struct device *dev, |
428 | struct device_attribute *attr, | 428 | struct device_attribute *attr, |
429 | const char *buf, size_t len) | 429 | const char *buf, size_t len) |
430 | { | 430 | { |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6bf850422895..055ed59838dc 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -267,6 +267,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
267 | if (!uevent) | 267 | if (!uevent) |
268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; | 268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; |
269 | 269 | ||
270 | mutex_lock(&ctx->file->mut); | ||
270 | uevent->cm_id = cm_id; | 271 | uevent->cm_id = cm_id; |
271 | ucma_set_event_context(ctx, event, uevent); | 272 | ucma_set_event_context(ctx, event, uevent); |
272 | uevent->resp.event = event->event; | 273 | uevent->resp.event = event->event; |
@@ -277,7 +278,6 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
277 | ucma_copy_conn_event(&uevent->resp.param.conn, | 278 | ucma_copy_conn_event(&uevent->resp.param.conn, |
278 | &event->param.conn); | 279 | &event->param.conn); |
279 | 280 | ||
280 | mutex_lock(&ctx->file->mut); | ||
281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { | 281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { |
282 | if (!ctx->backlog) { | 282 | if (!ctx->backlog) { |
283 | ret = -ENOMEM; | 283 | ret = -ENOMEM; |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 8c81992fa6db..e4a73158fc7f 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -439,7 +439,7 @@ static int c2_rnic_close(struct c2_dev *c2dev) | |||
439 | 439 | ||
440 | /* | 440 | /* |
441 | * Called by c2_probe to initialize the RNIC. This principally | 441 | * Called by c2_probe to initialize the RNIC. This principally |
442 | * involves initalizing the various limits and resouce pools that | 442 | * involves initializing the various limits and resource pools that |
443 | * comprise the RNIC instance. | 443 | * comprise the RNIC instance. |
444 | */ | 444 | */ |
445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) | 445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 77b6b182778a..aaf88ef9409c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1680,7 +1680,7 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1680 | * T3A does 3 things when a TERM is received: | 1680 | * T3A does 3 things when a TERM is received: |
1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet | 1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet |
1682 | * 2) generate an async event on the QP with the TERMINATE opcode | 1682 | * 2) generate an async event on the QP with the TERMINATE opcode |
1683 | * 3) post a TERMINATE opcde cqe into the associated CQ. | 1683 | * 3) post a TERMINATE opcode cqe into the associated CQ. |
1684 | * | 1684 | * |
1685 | * For (1), we save the message in the qp for later consumer consumption. | 1685 | * For (1), we save the message in the qp for later consumer consumption. |
1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. | 1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. |
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 51f42061dae9..6cfd4d8fd0bd 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c | |||
@@ -1361,11 +1361,11 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | |||
1361 | struct tid_info *t = dev->rdev.lldi.tids; | 1361 | struct tid_info *t = dev->rdev.lldi.tids; |
1362 | 1362 | ||
1363 | ep = lookup_tid(t, tid); | 1363 | ep = lookup_tid(t, tid); |
1364 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | ||
1365 | if (!ep) { | 1364 | if (!ep) { |
1366 | printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n"); | 1365 | printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n"); |
1367 | return 0; | 1366 | return 0; |
1368 | } | 1367 | } |
1368 | PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); | ||
1369 | mutex_lock(&ep->com.mutex); | 1369 | mutex_lock(&ep->com.mutex); |
1370 | switch (ep->com.state) { | 1370 | switch (ep->com.state) { |
1371 | case ABORTING: | 1371 | case ABORTING: |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index c27141fef1ab..9c2ae7efd00f 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -125,6 +125,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
125 | { | 125 | { |
126 | struct ib_ah *new_ah; | 126 | struct ib_ah *new_ah; |
127 | struct ib_ah_attr ah_attr; | 127 | struct ib_ah_attr ah_attr; |
128 | unsigned long flags; | ||
128 | 129 | ||
129 | if (!dev->send_agent[port_num - 1][0]) | 130 | if (!dev->send_agent[port_num - 1][0]) |
130 | return; | 131 | return; |
@@ -139,11 +140,11 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
139 | if (IS_ERR(new_ah)) | 140 | if (IS_ERR(new_ah)) |
140 | return; | 141 | return; |
141 | 142 | ||
142 | spin_lock(&dev->sm_lock); | 143 | spin_lock_irqsave(&dev->sm_lock, flags); |
143 | if (dev->sm_ah[port_num - 1]) | 144 | if (dev->sm_ah[port_num - 1]) |
144 | ib_destroy_ah(dev->sm_ah[port_num - 1]); | 145 | ib_destroy_ah(dev->sm_ah[port_num - 1]); |
145 | dev->sm_ah[port_num - 1] = new_ah; | 146 | dev->sm_ah[port_num - 1] = new_ah; |
146 | spin_unlock(&dev->sm_lock); | 147 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
147 | } | 148 | } |
148 | 149 | ||
149 | /* | 150 | /* |
@@ -197,13 +198,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
197 | static void node_desc_override(struct ib_device *dev, | 198 | static void node_desc_override(struct ib_device *dev, |
198 | struct ib_mad *mad) | 199 | struct ib_mad *mad) |
199 | { | 200 | { |
201 | unsigned long flags; | ||
202 | |||
200 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || | 203 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || |
201 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && | 204 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && |
202 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && | 205 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && |
203 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { | 206 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { |
204 | spin_lock(&to_mdev(dev)->sm_lock); | 207 | spin_lock_irqsave(&to_mdev(dev)->sm_lock, flags); |
205 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); | 208 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); |
206 | spin_unlock(&to_mdev(dev)->sm_lock); | 209 | spin_unlock_irqrestore(&to_mdev(dev)->sm_lock, flags); |
207 | } | 210 | } |
208 | } | 211 | } |
209 | 212 | ||
@@ -213,6 +216,7 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
213 | struct ib_mad_send_buf *send_buf; | 216 | struct ib_mad_send_buf *send_buf; |
214 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; | 217 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; |
215 | int ret; | 218 | int ret; |
219 | unsigned long flags; | ||
216 | 220 | ||
217 | if (agent) { | 221 | if (agent) { |
218 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, | 222 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, |
@@ -225,13 +229,13 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
225 | * wrong following the IB spec strictly, but we know | 229 | * wrong following the IB spec strictly, but we know |
226 | * it's OK for our devices). | 230 | * it's OK for our devices). |
227 | */ | 231 | */ |
228 | spin_lock(&dev->sm_lock); | 232 | spin_lock_irqsave(&dev->sm_lock, flags); |
229 | memcpy(send_buf->mad, mad, sizeof *mad); | 233 | memcpy(send_buf->mad, mad, sizeof *mad); |
230 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) | 234 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) |
231 | ret = ib_post_send_mad(send_buf, NULL); | 235 | ret = ib_post_send_mad(send_buf, NULL); |
232 | else | 236 | else |
233 | ret = -EINVAL; | 237 | ret = -EINVAL; |
234 | spin_unlock(&dev->sm_lock); | 238 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
235 | 239 | ||
236 | if (ret) | 240 | if (ret) |
237 | ib_free_send_mad(send_buf); | 241 | ib_free_send_mad(send_buf); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index fe2088cfa6ee..cc05579ebce7 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -423,6 +423,7 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
423 | struct ib_device_modify *props) | 423 | struct ib_device_modify *props) |
424 | { | 424 | { |
425 | struct mlx4_cmd_mailbox *mailbox; | 425 | struct mlx4_cmd_mailbox *mailbox; |
426 | unsigned long flags; | ||
426 | 427 | ||
427 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) | 428 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) |
428 | return -EOPNOTSUPP; | 429 | return -EOPNOTSUPP; |
@@ -430,9 +431,9 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
430 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) | 431 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) |
431 | return 0; | 432 | return 0; |
432 | 433 | ||
433 | spin_lock(&to_mdev(ibdev)->sm_lock); | 434 | spin_lock_irqsave(&to_mdev(ibdev)->sm_lock, flags); |
434 | memcpy(ibdev->node_desc, props->node_desc, 64); | 435 | memcpy(ibdev->node_desc, props->node_desc, 64); |
435 | spin_unlock(&to_mdev(ibdev)->sm_lock); | 436 | spin_unlock_irqrestore(&to_mdev(ibdev)->sm_lock, flags); |
436 | 437 | ||
437 | /* | 438 | /* |
438 | * If possible, pass node desc to FW, so it can generate | 439 | * If possible, pass node desc to FW, so it can generate |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a6d8ea060ea8..f585eddef4b7 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -1407,6 +1407,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; | 1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; | 1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; |
1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); | 1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); |
1410 | struct net_device *ndev; | ||
1410 | union ib_gid sgid; | 1411 | union ib_gid sgid; |
1411 | u16 pkey; | 1412 | u16 pkey; |
1412 | int send_size; | 1413 | int send_size; |
@@ -1483,7 +1484,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
1483 | 1484 | ||
1484 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); | 1485 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); |
1485 | /* FIXME: cache smac value? */ | 1486 | /* FIXME: cache smac value? */ |
1486 | smac = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]->dev_addr; | 1487 | ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]; |
1488 | if (!ndev) | ||
1489 | return -ENODEV; | ||
1490 | smac = ndev->dev_addr; | ||
1487 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); | 1491 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); |
1488 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) | 1492 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) |
1489 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); | 1493 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 5a044526e4f4..c4e0131f1b57 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
@@ -161,7 +161,7 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) | |||
161 | ocrdma_get_guid(dev, &sgid->raw[8]); | 161 | ocrdma_get_guid(dev, &sgid->raw[8]); |
162 | } | 162 | } |
163 | 163 | ||
164 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 164 | #if IS_ENABLED(CONFIG_VLAN_8021Q) |
165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) |
166 | { | 166 | { |
167 | struct net_device *netdev, *tmp; | 167 | struct net_device *netdev, *tmp; |
@@ -202,14 +202,13 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_VLAN_8021Q) | 205 | #if IS_ENABLED(CONFIG_IPV6) |
206 | 206 | ||
207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, | 207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, |
208 | unsigned long event, void *ptr) | 208 | unsigned long event, void *ptr) |
209 | { | 209 | { |
210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; | 210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; |
211 | struct net_device *event_netdev = ifa->idev->dev; | 211 | struct net_device *netdev = ifa->idev->dev; |
212 | struct net_device *netdev = NULL; | ||
213 | struct ib_event gid_event; | 212 | struct ib_event gid_event; |
214 | struct ocrdma_dev *dev; | 213 | struct ocrdma_dev *dev; |
215 | bool found = false; | 214 | bool found = false; |
@@ -217,11 +216,12 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
217 | bool is_vlan = false; | 216 | bool is_vlan = false; |
218 | u16 vid = 0; | 217 | u16 vid = 0; |
219 | 218 | ||
220 | netdev = vlan_dev_real_dev(event_netdev); | 219 | is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; |
221 | if (netdev != event_netdev) { | 220 | if (is_vlan) { |
222 | is_vlan = true; | 221 | vid = vlan_dev_vlan_id(netdev); |
223 | vid = vlan_dev_vlan_id(event_netdev); | 222 | netdev = vlan_dev_real_dev(netdev); |
224 | } | 223 | } |
224 | |||
225 | rcu_read_lock(); | 225 | rcu_read_lock(); |
226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { | 226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { |
227 | if (dev->nic_info.netdev == netdev) { | 227 | if (dev->nic_info.netdev == netdev) { |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index cb5b7f7d4d38..b29a4246ef41 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
@@ -2219,7 +2219,6 @@ static bool ocrdma_poll_success_scqe(struct ocrdma_qp *qp, | |||
2219 | u32 wqe_idx; | 2219 | u32 wqe_idx; |
2220 | 2220 | ||
2221 | if (!qp->wqe_wr_id_tbl[tail].signaled) { | 2221 | if (!qp->wqe_wr_id_tbl[tail].signaled) { |
2222 | expand = true; /* CQE cannot be consumed yet */ | ||
2223 | *polled = false; /* WC cannot be consumed yet */ | 2222 | *polled = false; /* WC cannot be consumed yet */ |
2224 | } else { | 2223 | } else { |
2225 | ibwc->status = IB_WC_SUCCESS; | 2224 | ibwc->status = IB_WC_SUCCESS; |
@@ -2227,10 +2226,11 @@ static bool ocrdma_poll_success_scqe(struct ocrdma_qp *qp, | |||
2227 | ibwc->qp = &qp->ibqp; | 2226 | ibwc->qp = &qp->ibqp; |
2228 | ocrdma_update_wc(qp, ibwc, tail); | 2227 | ocrdma_update_wc(qp, ibwc, tail); |
2229 | *polled = true; | 2228 | *polled = true; |
2230 | wqe_idx = le32_to_cpu(cqe->wq.wqeidx) & OCRDMA_CQE_WQEIDX_MASK; | ||
2231 | if (tail != wqe_idx) | ||
2232 | expand = true; /* Coalesced CQE can't be consumed yet */ | ||
2233 | } | 2229 | } |
2230 | wqe_idx = le32_to_cpu(cqe->wq.wqeidx) & OCRDMA_CQE_WQEIDX_MASK; | ||
2231 | if (tail != wqe_idx) | ||
2232 | expand = true; /* Coalesced CQE can't be consumed yet */ | ||
2233 | |||
2234 | ocrdma_hwq_inc_tail(&qp->sq); | 2234 | ocrdma_hwq_inc_tail(&qp->sq); |
2235 | return expand; | 2235 | return expand; |
2236 | } | 2236 | } |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 0d7280af99bc..3f6b21e9dc11 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -6346,8 +6346,10 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
6346 | dd->piobcnt4k * dd->align4k; | 6346 | dd->piobcnt4k * dd->align4k; |
6347 | dd->piovl15base = ioremap_nocache(vl15off, | 6347 | dd->piovl15base = ioremap_nocache(vl15off, |
6348 | NUM_VL15_BUFS * dd->align4k); | 6348 | NUM_VL15_BUFS * dd->align4k); |
6349 | if (!dd->piovl15base) | 6349 | if (!dd->piovl15base) { |
6350 | ret = -ENOMEM; | ||
6350 | goto bail; | 6351 | goto bail; |
6352 | } | ||
6351 | } | 6353 | } |
6352 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ | 6354 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ |
6353 | 6355 | ||
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 19f1e6c45fb6..ccb119143d20 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c | |||
@@ -471,9 +471,10 @@ static int subn_get_portinfo(struct ib_smp *smp, struct ib_device *ibdev, | |||
471 | if (port_num != port) { | 471 | if (port_num != port) { |
472 | ibp = to_iport(ibdev, port_num); | 472 | ibp = to_iport(ibdev, port_num); |
473 | ret = check_mkey(ibp, smp, 0); | 473 | ret = check_mkey(ibp, smp, 0); |
474 | if (ret) | 474 | if (ret) { |
475 | ret = IB_MAD_RESULT_FAILURE; | 475 | ret = IB_MAD_RESULT_FAILURE; |
476 | goto bail; | 476 | goto bail; |
477 | } | ||
477 | } | 478 | } |
478 | } | 479 | } |
479 | 480 | ||
diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c index a322d5171a2c..50a8a0d4fe67 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c | |||
@@ -372,7 +372,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd, | |||
372 | /* Read CTRL reg for each channel to check TRIMDONE */ | 372 | /* Read CTRL reg for each channel to check TRIMDONE */ |
373 | if (baduns & (1 << chn)) { | 373 | if (baduns & (1 << chn)) { |
374 | qib_dev_err(dd, | 374 | qib_dev_err(dd, |
375 | "Reseting TRIMDONE on chn %d (%s)\n", | 375 | "Resetting TRIMDONE on chn %d (%s)\n", |
376 | chn, where); | 376 | chn, where); |
377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, | 377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, |
378 | IB_CTRL2(chn), 0x10, 0x10); | 378 | IB_CTRL2(chn), 0x10, 0x10); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index ca43901ed861..0af216d21f87 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -262,7 +262,10 @@ struct ipoib_ethtool_st { | |||
262 | u16 max_coalesced_frames; | 262 | u16 max_coalesced_frames; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | struct ipoib_neigh_table; | ||
266 | |||
265 | struct ipoib_neigh_hash { | 267 | struct ipoib_neigh_hash { |
268 | struct ipoib_neigh_table *ntbl; | ||
266 | struct ipoib_neigh __rcu **buckets; | 269 | struct ipoib_neigh __rcu **buckets; |
267 | struct rcu_head rcu; | 270 | struct rcu_head rcu; |
268 | u32 mask; | 271 | u32 mask; |
@@ -271,9 +274,9 @@ struct ipoib_neigh_hash { | |||
271 | 274 | ||
272 | struct ipoib_neigh_table { | 275 | struct ipoib_neigh_table { |
273 | struct ipoib_neigh_hash __rcu *htbl; | 276 | struct ipoib_neigh_hash __rcu *htbl; |
274 | rwlock_t rwlock; | ||
275 | atomic_t entries; | 277 | atomic_t entries; |
276 | struct completion flushed; | 278 | struct completion flushed; |
279 | struct completion deleted; | ||
277 | }; | 280 | }; |
278 | 281 | ||
279 | /* | 282 | /* |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 95ecf4eadf5f..24683fda8e21 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1271,12 +1271,15 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path | |||
1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) | 1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) |
1272 | { | 1272 | { |
1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); | 1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); |
1274 | unsigned long flags; | ||
1274 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { | 1275 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { |
1276 | spin_lock_irqsave(&priv->lock, flags); | ||
1275 | list_move(&tx->list, &priv->cm.reap_list); | 1277 | list_move(&tx->list, &priv->cm.reap_list); |
1276 | queue_work(ipoib_workqueue, &priv->cm.reap_task); | 1278 | queue_work(ipoib_workqueue, &priv->cm.reap_task); |
1277 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", | 1279 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", |
1278 | tx->neigh->daddr + 4); | 1280 | tx->neigh->daddr + 4); |
1279 | tx->neigh = NULL; | 1281 | tx->neigh = NULL; |
1282 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1280 | } | 1283 | } |
1281 | } | 1284 | } |
1282 | 1285 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 97920b77a5d0..1e19b5ae7c47 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -546,15 +546,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
546 | struct ipoib_neigh *neigh; | 546 | struct ipoib_neigh *neigh; |
547 | unsigned long flags; | 547 | unsigned long flags; |
548 | 548 | ||
549 | spin_lock_irqsave(&priv->lock, flags); | ||
549 | neigh = ipoib_neigh_alloc(daddr, dev); | 550 | neigh = ipoib_neigh_alloc(daddr, dev); |
550 | if (!neigh) { | 551 | if (!neigh) { |
552 | spin_unlock_irqrestore(&priv->lock, flags); | ||
551 | ++dev->stats.tx_dropped; | 553 | ++dev->stats.tx_dropped; |
552 | dev_kfree_skb_any(skb); | 554 | dev_kfree_skb_any(skb); |
553 | return; | 555 | return; |
554 | } | 556 | } |
555 | 557 | ||
556 | spin_lock_irqsave(&priv->lock, flags); | ||
557 | |||
558 | path = __path_find(dev, daddr + 4); | 558 | path = __path_find(dev, daddr + 4); |
559 | if (!path) { | 559 | if (!path) { |
560 | path = path_rec_create(dev, daddr + 4); | 560 | path = path_rec_create(dev, daddr + 4); |
@@ -863,10 +863,10 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
863 | if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags)) | 863 | if (test_bit(IPOIB_STOP_NEIGH_GC, &priv->flags)) |
864 | return; | 864 | return; |
865 | 865 | ||
866 | write_lock_bh(&ntbl->rwlock); | 866 | spin_lock_irqsave(&priv->lock, flags); |
867 | 867 | ||
868 | htbl = rcu_dereference_protected(ntbl->htbl, | 868 | htbl = rcu_dereference_protected(ntbl->htbl, |
869 | lockdep_is_held(&ntbl->rwlock)); | 869 | lockdep_is_held(&priv->lock)); |
870 | 870 | ||
871 | if (!htbl) | 871 | if (!htbl) |
872 | goto out_unlock; | 872 | goto out_unlock; |
@@ -883,16 +883,14 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
883 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 883 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
884 | 884 | ||
885 | while ((neigh = rcu_dereference_protected(*np, | 885 | while ((neigh = rcu_dereference_protected(*np, |
886 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 886 | lockdep_is_held(&priv->lock))) != NULL) { |
887 | /* was the neigh idle for two GC periods */ | 887 | /* was the neigh idle for two GC periods */ |
888 | if (time_after(neigh_obsolete, neigh->alive)) { | 888 | if (time_after(neigh_obsolete, neigh->alive)) { |
889 | rcu_assign_pointer(*np, | 889 | rcu_assign_pointer(*np, |
890 | rcu_dereference_protected(neigh->hnext, | 890 | rcu_dereference_protected(neigh->hnext, |
891 | lockdep_is_held(&ntbl->rwlock))); | 891 | lockdep_is_held(&priv->lock))); |
892 | /* remove from path/mc list */ | 892 | /* remove from path/mc list */ |
893 | spin_lock_irqsave(&priv->lock, flags); | ||
894 | list_del(&neigh->list); | 893 | list_del(&neigh->list); |
895 | spin_unlock_irqrestore(&priv->lock, flags); | ||
896 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 894 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
897 | } else { | 895 | } else { |
898 | np = &neigh->hnext; | 896 | np = &neigh->hnext; |
@@ -902,7 +900,7 @@ static void __ipoib_reap_neigh(struct ipoib_dev_priv *priv) | |||
902 | } | 900 | } |
903 | 901 | ||
904 | out_unlock: | 902 | out_unlock: |
905 | write_unlock_bh(&ntbl->rwlock); | 903 | spin_unlock_irqrestore(&priv->lock, flags); |
906 | } | 904 | } |
907 | 905 | ||
908 | static void ipoib_reap_neigh(struct work_struct *work) | 906 | static void ipoib_reap_neigh(struct work_struct *work) |
@@ -947,10 +945,8 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
947 | struct ipoib_neigh *neigh; | 945 | struct ipoib_neigh *neigh; |
948 | u32 hash_val; | 946 | u32 hash_val; |
949 | 947 | ||
950 | write_lock_bh(&ntbl->rwlock); | ||
951 | |||
952 | htbl = rcu_dereference_protected(ntbl->htbl, | 948 | htbl = rcu_dereference_protected(ntbl->htbl, |
953 | lockdep_is_held(&ntbl->rwlock)); | 949 | lockdep_is_held(&priv->lock)); |
954 | if (!htbl) { | 950 | if (!htbl) { |
955 | neigh = NULL; | 951 | neigh = NULL; |
956 | goto out_unlock; | 952 | goto out_unlock; |
@@ -961,10 +957,10 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
961 | */ | 957 | */ |
962 | hash_val = ipoib_addr_hash(htbl, daddr); | 958 | hash_val = ipoib_addr_hash(htbl, daddr); |
963 | for (neigh = rcu_dereference_protected(htbl->buckets[hash_val], | 959 | for (neigh = rcu_dereference_protected(htbl->buckets[hash_val], |
964 | lockdep_is_held(&ntbl->rwlock)); | 960 | lockdep_is_held(&priv->lock)); |
965 | neigh != NULL; | 961 | neigh != NULL; |
966 | neigh = rcu_dereference_protected(neigh->hnext, | 962 | neigh = rcu_dereference_protected(neigh->hnext, |
967 | lockdep_is_held(&ntbl->rwlock))) { | 963 | lockdep_is_held(&priv->lock))) { |
968 | if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { | 964 | if (memcmp(daddr, neigh->daddr, INFINIBAND_ALEN) == 0) { |
969 | /* found, take one ref on behalf of the caller */ | 965 | /* found, take one ref on behalf of the caller */ |
970 | if (!atomic_inc_not_zero(&neigh->refcnt)) { | 966 | if (!atomic_inc_not_zero(&neigh->refcnt)) { |
@@ -987,12 +983,11 @@ struct ipoib_neigh *ipoib_neigh_alloc(u8 *daddr, | |||
987 | /* put in hash */ | 983 | /* put in hash */ |
988 | rcu_assign_pointer(neigh->hnext, | 984 | rcu_assign_pointer(neigh->hnext, |
989 | rcu_dereference_protected(htbl->buckets[hash_val], | 985 | rcu_dereference_protected(htbl->buckets[hash_val], |
990 | lockdep_is_held(&ntbl->rwlock))); | 986 | lockdep_is_held(&priv->lock))); |
991 | rcu_assign_pointer(htbl->buckets[hash_val], neigh); | 987 | rcu_assign_pointer(htbl->buckets[hash_val], neigh); |
992 | atomic_inc(&ntbl->entries); | 988 | atomic_inc(&ntbl->entries); |
993 | 989 | ||
994 | out_unlock: | 990 | out_unlock: |
995 | write_unlock_bh(&ntbl->rwlock); | ||
996 | 991 | ||
997 | return neigh; | 992 | return neigh; |
998 | } | 993 | } |
@@ -1040,35 +1035,29 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh) | |||
1040 | struct ipoib_neigh *n; | 1035 | struct ipoib_neigh *n; |
1041 | u32 hash_val; | 1036 | u32 hash_val; |
1042 | 1037 | ||
1043 | write_lock_bh(&ntbl->rwlock); | ||
1044 | |||
1045 | htbl = rcu_dereference_protected(ntbl->htbl, | 1038 | htbl = rcu_dereference_protected(ntbl->htbl, |
1046 | lockdep_is_held(&ntbl->rwlock)); | 1039 | lockdep_is_held(&priv->lock)); |
1047 | if (!htbl) | 1040 | if (!htbl) |
1048 | goto out_unlock; | 1041 | return; |
1049 | 1042 | ||
1050 | hash_val = ipoib_addr_hash(htbl, neigh->daddr); | 1043 | hash_val = ipoib_addr_hash(htbl, neigh->daddr); |
1051 | np = &htbl->buckets[hash_val]; | 1044 | np = &htbl->buckets[hash_val]; |
1052 | for (n = rcu_dereference_protected(*np, | 1045 | for (n = rcu_dereference_protected(*np, |
1053 | lockdep_is_held(&ntbl->rwlock)); | 1046 | lockdep_is_held(&priv->lock)); |
1054 | n != NULL; | 1047 | n != NULL; |
1055 | n = rcu_dereference_protected(neigh->hnext, | 1048 | n = rcu_dereference_protected(*np, |
1056 | lockdep_is_held(&ntbl->rwlock))) { | 1049 | lockdep_is_held(&priv->lock))) { |
1057 | if (n == neigh) { | 1050 | if (n == neigh) { |
1058 | /* found */ | 1051 | /* found */ |
1059 | rcu_assign_pointer(*np, | 1052 | rcu_assign_pointer(*np, |
1060 | rcu_dereference_protected(neigh->hnext, | 1053 | rcu_dereference_protected(neigh->hnext, |
1061 | lockdep_is_held(&ntbl->rwlock))); | 1054 | lockdep_is_held(&priv->lock))); |
1062 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1055 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1063 | goto out_unlock; | 1056 | return; |
1064 | } else { | 1057 | } else { |
1065 | np = &n->hnext; | 1058 | np = &n->hnext; |
1066 | } | 1059 | } |
1067 | } | 1060 | } |
1068 | |||
1069 | out_unlock: | ||
1070 | write_unlock_bh(&ntbl->rwlock); | ||
1071 | |||
1072 | } | 1061 | } |
1073 | 1062 | ||
1074 | static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | 1063 | static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) |
@@ -1080,7 +1069,6 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | |||
1080 | 1069 | ||
1081 | clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); | 1070 | clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); |
1082 | ntbl->htbl = NULL; | 1071 | ntbl->htbl = NULL; |
1083 | rwlock_init(&ntbl->rwlock); | ||
1084 | htbl = kzalloc(sizeof(*htbl), GFP_KERNEL); | 1072 | htbl = kzalloc(sizeof(*htbl), GFP_KERNEL); |
1085 | if (!htbl) | 1073 | if (!htbl) |
1086 | return -ENOMEM; | 1074 | return -ENOMEM; |
@@ -1095,6 +1083,7 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) | |||
1095 | htbl->mask = (size - 1); | 1083 | htbl->mask = (size - 1); |
1096 | htbl->buckets = buckets; | 1084 | htbl->buckets = buckets; |
1097 | ntbl->htbl = htbl; | 1085 | ntbl->htbl = htbl; |
1086 | htbl->ntbl = ntbl; | ||
1098 | atomic_set(&ntbl->entries, 0); | 1087 | atomic_set(&ntbl->entries, 0); |
1099 | 1088 | ||
1100 | /* start garbage collection */ | 1089 | /* start garbage collection */ |
@@ -1111,9 +1100,11 @@ static void neigh_hash_free_rcu(struct rcu_head *head) | |||
1111 | struct ipoib_neigh_hash, | 1100 | struct ipoib_neigh_hash, |
1112 | rcu); | 1101 | rcu); |
1113 | struct ipoib_neigh __rcu **buckets = htbl->buckets; | 1102 | struct ipoib_neigh __rcu **buckets = htbl->buckets; |
1103 | struct ipoib_neigh_table *ntbl = htbl->ntbl; | ||
1114 | 1104 | ||
1115 | kfree(buckets); | 1105 | kfree(buckets); |
1116 | kfree(htbl); | 1106 | kfree(htbl); |
1107 | complete(&ntbl->deleted); | ||
1117 | } | 1108 | } |
1118 | 1109 | ||
1119 | void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | 1110 | void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) |
@@ -1125,10 +1116,10 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1125 | int i; | 1116 | int i; |
1126 | 1117 | ||
1127 | /* remove all neigh connected to a given path or mcast */ | 1118 | /* remove all neigh connected to a given path or mcast */ |
1128 | write_lock_bh(&ntbl->rwlock); | 1119 | spin_lock_irqsave(&priv->lock, flags); |
1129 | 1120 | ||
1130 | htbl = rcu_dereference_protected(ntbl->htbl, | 1121 | htbl = rcu_dereference_protected(ntbl->htbl, |
1131 | lockdep_is_held(&ntbl->rwlock)); | 1122 | lockdep_is_held(&priv->lock)); |
1132 | 1123 | ||
1133 | if (!htbl) | 1124 | if (!htbl) |
1134 | goto out_unlock; | 1125 | goto out_unlock; |
@@ -1138,16 +1129,14 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1138 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 1129 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
1139 | 1130 | ||
1140 | while ((neigh = rcu_dereference_protected(*np, | 1131 | while ((neigh = rcu_dereference_protected(*np, |
1141 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 1132 | lockdep_is_held(&priv->lock))) != NULL) { |
1142 | /* delete neighs belong to this parent */ | 1133 | /* delete neighs belong to this parent */ |
1143 | if (!memcmp(gid, neigh->daddr + 4, sizeof (union ib_gid))) { | 1134 | if (!memcmp(gid, neigh->daddr + 4, sizeof (union ib_gid))) { |
1144 | rcu_assign_pointer(*np, | 1135 | rcu_assign_pointer(*np, |
1145 | rcu_dereference_protected(neigh->hnext, | 1136 | rcu_dereference_protected(neigh->hnext, |
1146 | lockdep_is_held(&ntbl->rwlock))); | 1137 | lockdep_is_held(&priv->lock))); |
1147 | /* remove from parent list */ | 1138 | /* remove from parent list */ |
1148 | spin_lock_irqsave(&priv->lock, flags); | ||
1149 | list_del(&neigh->list); | 1139 | list_del(&neigh->list); |
1150 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1151 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1140 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1152 | } else { | 1141 | } else { |
1153 | np = &neigh->hnext; | 1142 | np = &neigh->hnext; |
@@ -1156,7 +1145,7 @@ void ipoib_del_neighs_by_gid(struct net_device *dev, u8 *gid) | |||
1156 | } | 1145 | } |
1157 | } | 1146 | } |
1158 | out_unlock: | 1147 | out_unlock: |
1159 | write_unlock_bh(&ntbl->rwlock); | 1148 | spin_unlock_irqrestore(&priv->lock, flags); |
1160 | } | 1149 | } |
1161 | 1150 | ||
1162 | static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) | 1151 | static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) |
@@ -1164,37 +1153,44 @@ static void ipoib_flush_neighs(struct ipoib_dev_priv *priv) | |||
1164 | struct ipoib_neigh_table *ntbl = &priv->ntbl; | 1153 | struct ipoib_neigh_table *ntbl = &priv->ntbl; |
1165 | struct ipoib_neigh_hash *htbl; | 1154 | struct ipoib_neigh_hash *htbl; |
1166 | unsigned long flags; | 1155 | unsigned long flags; |
1167 | int i; | 1156 | int i, wait_flushed = 0; |
1168 | 1157 | ||
1169 | write_lock_bh(&ntbl->rwlock); | 1158 | init_completion(&priv->ntbl.flushed); |
1159 | |||
1160 | spin_lock_irqsave(&priv->lock, flags); | ||
1170 | 1161 | ||
1171 | htbl = rcu_dereference_protected(ntbl->htbl, | 1162 | htbl = rcu_dereference_protected(ntbl->htbl, |
1172 | lockdep_is_held(&ntbl->rwlock)); | 1163 | lockdep_is_held(&priv->lock)); |
1173 | if (!htbl) | 1164 | if (!htbl) |
1174 | goto out_unlock; | 1165 | goto out_unlock; |
1175 | 1166 | ||
1167 | wait_flushed = atomic_read(&priv->ntbl.entries); | ||
1168 | if (!wait_flushed) | ||
1169 | goto free_htbl; | ||
1170 | |||
1176 | for (i = 0; i < htbl->size; i++) { | 1171 | for (i = 0; i < htbl->size; i++) { |
1177 | struct ipoib_neigh *neigh; | 1172 | struct ipoib_neigh *neigh; |
1178 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; | 1173 | struct ipoib_neigh __rcu **np = &htbl->buckets[i]; |
1179 | 1174 | ||
1180 | while ((neigh = rcu_dereference_protected(*np, | 1175 | while ((neigh = rcu_dereference_protected(*np, |
1181 | lockdep_is_held(&ntbl->rwlock))) != NULL) { | 1176 | lockdep_is_held(&priv->lock))) != NULL) { |
1182 | rcu_assign_pointer(*np, | 1177 | rcu_assign_pointer(*np, |
1183 | rcu_dereference_protected(neigh->hnext, | 1178 | rcu_dereference_protected(neigh->hnext, |
1184 | lockdep_is_held(&ntbl->rwlock))); | 1179 | lockdep_is_held(&priv->lock))); |
1185 | /* remove from path/mc list */ | 1180 | /* remove from path/mc list */ |
1186 | spin_lock_irqsave(&priv->lock, flags); | ||
1187 | list_del(&neigh->list); | 1181 | list_del(&neigh->list); |
1188 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1189 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); | 1182 | call_rcu(&neigh->rcu, ipoib_neigh_reclaim); |
1190 | } | 1183 | } |
1191 | } | 1184 | } |
1192 | 1185 | ||
1186 | free_htbl: | ||
1193 | rcu_assign_pointer(ntbl->htbl, NULL); | 1187 | rcu_assign_pointer(ntbl->htbl, NULL); |
1194 | call_rcu(&htbl->rcu, neigh_hash_free_rcu); | 1188 | call_rcu(&htbl->rcu, neigh_hash_free_rcu); |
1195 | 1189 | ||
1196 | out_unlock: | 1190 | out_unlock: |
1197 | write_unlock_bh(&ntbl->rwlock); | 1191 | spin_unlock_irqrestore(&priv->lock, flags); |
1192 | if (wait_flushed) | ||
1193 | wait_for_completion(&priv->ntbl.flushed); | ||
1198 | } | 1194 | } |
1199 | 1195 | ||
1200 | static void ipoib_neigh_hash_uninit(struct net_device *dev) | 1196 | static void ipoib_neigh_hash_uninit(struct net_device *dev) |
@@ -1203,7 +1199,7 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev) | |||
1203 | int stopped; | 1199 | int stopped; |
1204 | 1200 | ||
1205 | ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); | 1201 | ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); |
1206 | init_completion(&priv->ntbl.flushed); | 1202 | init_completion(&priv->ntbl.deleted); |
1207 | set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); | 1203 | set_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); |
1208 | 1204 | ||
1209 | /* Stop GC if called at init fail need to cancel work */ | 1205 | /* Stop GC if called at init fail need to cancel work */ |
@@ -1211,10 +1207,9 @@ static void ipoib_neigh_hash_uninit(struct net_device *dev) | |||
1211 | if (!stopped) | 1207 | if (!stopped) |
1212 | cancel_delayed_work(&priv->neigh_reap_task); | 1208 | cancel_delayed_work(&priv->neigh_reap_task); |
1213 | 1209 | ||
1214 | if (atomic_read(&priv->ntbl.entries)) { | 1210 | ipoib_flush_neighs(priv); |
1215 | ipoib_flush_neighs(priv); | 1211 | |
1216 | wait_for_completion(&priv->ntbl.flushed); | 1212 | wait_for_completion(&priv->ntbl.deleted); |
1217 | } | ||
1218 | } | 1213 | } |
1219 | 1214 | ||
1220 | 1215 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 13f4aa7593c8..75367249f447 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -707,9 +707,7 @@ out: | |||
707 | neigh = ipoib_neigh_get(dev, daddr); | 707 | neigh = ipoib_neigh_get(dev, daddr); |
708 | spin_lock_irqsave(&priv->lock, flags); | 708 | spin_lock_irqsave(&priv->lock, flags); |
709 | if (!neigh) { | 709 | if (!neigh) { |
710 | spin_unlock_irqrestore(&priv->lock, flags); | ||
711 | neigh = ipoib_neigh_alloc(daddr, dev); | 710 | neigh = ipoib_neigh_alloc(daddr, dev); |
712 | spin_lock_irqsave(&priv->lock, flags); | ||
713 | if (neigh) { | 711 | if (neigh) { |
714 | kref_get(&mcast->ah->ref); | 712 | kref_get(&mcast->ah->ref); |
715 | neigh->ah = mcast->ah; | 713 | neigh->ah = mcast->ah; |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index bcbf22ee0aa7..1b5b0c730054 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -586,24 +586,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
586 | scmnd->sc_data_direction); | 586 | scmnd->sc_data_direction); |
587 | } | 587 | } |
588 | 588 | ||
589 | static void srp_remove_req(struct srp_target_port *target, | 589 | /** |
590 | struct srp_request *req, s32 req_lim_delta) | 590 | * srp_claim_req - Take ownership of the scmnd associated with a request. |
591 | * @target: SRP target port. | ||
592 | * @req: SRP request. | ||
593 | * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take | ||
594 | * ownership of @req->scmnd if it equals @scmnd. | ||
595 | * | ||
596 | * Return value: | ||
597 | * Either NULL or a pointer to the SCSI command the caller became owner of. | ||
598 | */ | ||
599 | static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, | ||
600 | struct srp_request *req, | ||
601 | struct scsi_cmnd *scmnd) | ||
602 | { | ||
603 | unsigned long flags; | ||
604 | |||
605 | spin_lock_irqsave(&target->lock, flags); | ||
606 | if (!scmnd) { | ||
607 | scmnd = req->scmnd; | ||
608 | req->scmnd = NULL; | ||
609 | } else if (req->scmnd == scmnd) { | ||
610 | req->scmnd = NULL; | ||
611 | } else { | ||
612 | scmnd = NULL; | ||
613 | } | ||
614 | spin_unlock_irqrestore(&target->lock, flags); | ||
615 | |||
616 | return scmnd; | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * srp_free_req() - Unmap data and add request to the free request list. | ||
621 | */ | ||
622 | static void srp_free_req(struct srp_target_port *target, | ||
623 | struct srp_request *req, struct scsi_cmnd *scmnd, | ||
624 | s32 req_lim_delta) | ||
591 | { | 625 | { |
592 | unsigned long flags; | 626 | unsigned long flags; |
593 | 627 | ||
594 | srp_unmap_data(req->scmnd, target, req); | 628 | srp_unmap_data(scmnd, target, req); |
629 | |||
595 | spin_lock_irqsave(&target->lock, flags); | 630 | spin_lock_irqsave(&target->lock, flags); |
596 | target->req_lim += req_lim_delta; | 631 | target->req_lim += req_lim_delta; |
597 | req->scmnd = NULL; | ||
598 | list_add_tail(&req->list, &target->free_reqs); | 632 | list_add_tail(&req->list, &target->free_reqs); |
599 | spin_unlock_irqrestore(&target->lock, flags); | 633 | spin_unlock_irqrestore(&target->lock, flags); |
600 | } | 634 | } |
601 | 635 | ||
602 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) | 636 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) |
603 | { | 637 | { |
604 | req->scmnd->result = DID_RESET << 16; | 638 | struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL); |
605 | req->scmnd->scsi_done(req->scmnd); | 639 | |
606 | srp_remove_req(target, req, 0); | 640 | if (scmnd) { |
641 | scmnd->result = DID_RESET << 16; | ||
642 | scmnd->scsi_done(scmnd); | ||
643 | srp_free_req(target, req, scmnd, 0); | ||
644 | } | ||
607 | } | 645 | } |
608 | 646 | ||
609 | static int srp_reconnect_target(struct srp_target_port *target) | 647 | static int srp_reconnect_target(struct srp_target_port *target) |
@@ -1073,11 +1111,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
1073 | complete(&target->tsk_mgmt_done); | 1111 | complete(&target->tsk_mgmt_done); |
1074 | } else { | 1112 | } else { |
1075 | req = &target->req_ring[rsp->tag]; | 1113 | req = &target->req_ring[rsp->tag]; |
1076 | scmnd = req->scmnd; | 1114 | scmnd = srp_claim_req(target, req, NULL); |
1077 | if (!scmnd) | 1115 | if (!scmnd) { |
1078 | shost_printk(KERN_ERR, target->scsi_host, | 1116 | shost_printk(KERN_ERR, target->scsi_host, |
1079 | "Null scmnd for RSP w/tag %016llx\n", | 1117 | "Null scmnd for RSP w/tag %016llx\n", |
1080 | (unsigned long long) rsp->tag); | 1118 | (unsigned long long) rsp->tag); |
1119 | |||
1120 | spin_lock_irqsave(&target->lock, flags); | ||
1121 | target->req_lim += be32_to_cpu(rsp->req_lim_delta); | ||
1122 | spin_unlock_irqrestore(&target->lock, flags); | ||
1123 | |||
1124 | return; | ||
1125 | } | ||
1081 | scmnd->result = rsp->status; | 1126 | scmnd->result = rsp->status; |
1082 | 1127 | ||
1083 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { | 1128 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { |
@@ -1092,7 +1137,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
1092 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) | 1137 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) |
1093 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); | 1138 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); |
1094 | 1139 | ||
1095 | srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta)); | 1140 | srp_free_req(target, req, scmnd, |
1141 | be32_to_cpu(rsp->req_lim_delta)); | ||
1142 | |||
1096 | scmnd->host_scribble = NULL; | 1143 | scmnd->host_scribble = NULL; |
1097 | scmnd->scsi_done(scmnd); | 1144 | scmnd->scsi_done(scmnd); |
1098 | } | 1145 | } |
@@ -1631,25 +1678,17 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
1631 | { | 1678 | { |
1632 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1679 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
1633 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; | 1680 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; |
1634 | int ret = SUCCESS; | ||
1635 | 1681 | ||
1636 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); | 1682 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
1637 | 1683 | ||
1638 | if (!req || target->qp_in_error) | 1684 | if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) |
1639 | return FAILED; | 1685 | return FAILED; |
1640 | if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, | 1686 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, |
1641 | SRP_TSK_ABORT_TASK)) | 1687 | SRP_TSK_ABORT_TASK); |
1642 | return FAILED; | 1688 | srp_free_req(target, req, scmnd, 0); |
1643 | 1689 | scmnd->result = DID_ABORT << 16; | |
1644 | if (req->scmnd) { | ||
1645 | if (!target->tsk_mgmt_status) { | ||
1646 | srp_remove_req(target, req, 0); | ||
1647 | scmnd->result = DID_ABORT << 16; | ||
1648 | } else | ||
1649 | ret = FAILED; | ||
1650 | } | ||
1651 | 1690 | ||
1652 | return ret; | 1691 | return SUCCESS; |
1653 | } | 1692 | } |
1654 | 1693 | ||
1655 | static int srp_reset_device(struct scsi_cmnd *scmnd) | 1694 | static int srp_reset_device(struct scsi_cmnd *scmnd) |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 7a0ce8d42887..9e1449f8c6a2 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -1469,7 +1469,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, | |||
1469 | * | 1469 | * |
1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping | 1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping |
1471 | * the data that has been transferred via IB RDMA had to be postponed until the | 1471 | * the data that has been transferred via IB RDMA had to be postponed until the |
1472 | * check_stop_free() callback. None of this is nessecary anymore and needs to | 1472 | * check_stop_free() callback. None of this is necessary anymore and needs to |
1473 | * be cleaned up. | 1473 | * be cleaned up. |
1474 | */ | 1474 | */ |
1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, | 1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, |
diff --git a/drivers/input/keyboard/imx_keypad.c b/drivers/input/keyboard/imx_keypad.c index ff4c0a87a25f..cdc252612c0b 100644 --- a/drivers/input/keyboard/imx_keypad.c +++ b/drivers/input/keyboard/imx_keypad.c | |||
@@ -358,6 +358,7 @@ static void imx_keypad_inhibit(struct imx_keypad *keypad) | |||
358 | /* Inhibit KDI and KRI interrupts. */ | 358 | /* Inhibit KDI and KRI interrupts. */ |
359 | reg_val = readw(keypad->mmio_base + KPSR); | 359 | reg_val = readw(keypad->mmio_base + KPSR); |
360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); | 360 | reg_val &= ~(KBD_STAT_KRIE | KBD_STAT_KDIE); |
361 | reg_val |= KBD_STAT_KPKR | KBD_STAT_KPKD; | ||
361 | writew(reg_val, keypad->mmio_base + KPSR); | 362 | writew(reg_val, keypad->mmio_base + KPSR); |
362 | 363 | ||
363 | /* Colums as open drain and disable all rows */ | 364 | /* Colums as open drain and disable all rows */ |
@@ -515,7 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev) | |||
515 | input_set_drvdata(input_dev, keypad); | 516 | input_set_drvdata(input_dev, keypad); |
516 | 517 | ||
517 | /* Ensure that the keypad will stay dormant until opened */ | 518 | /* Ensure that the keypad will stay dormant until opened */ |
519 | clk_prepare_enable(keypad->clk); | ||
518 | imx_keypad_inhibit(keypad); | 520 | imx_keypad_inhibit(keypad); |
521 | clk_disable_unprepare(keypad->clk); | ||
519 | 522 | ||
520 | error = request_irq(irq, imx_keypad_irq_handler, 0, | 523 | error = request_irq(irq, imx_keypad_irq_handler, 0, |
521 | pdev->name, keypad); | 524 | pdev->name, keypad); |
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index f06231b7cab1..84ec691c05aa 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -74,8 +74,8 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev) | |||
74 | 74 | ||
75 | ponkey->idev = input; | 75 | ponkey->idev = input; |
76 | ponkey->ab8500 = ab8500; | 76 | ponkey->ab8500 = ab8500; |
77 | ponkey->irq_dbf = ab8500_irq_get_virq(ab8500, irq_dbf); | 77 | ponkey->irq_dbf = irq_dbf; |
78 | ponkey->irq_dbr = ab8500_irq_get_virq(ab8500, irq_dbr); | 78 | ponkey->irq_dbr = irq_dbr; |
79 | 79 | ||
80 | input->name = "AB8500 POn(PowerOn) Key"; | 80 | input->name = "AB8500 POn(PowerOn) Key"; |
81 | input->dev.parent = &pdev->dev; | 81 | input->dev.parent = &pdev->dev; |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 3f5649f19082..a261d8576919 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
721 | 721 | ||
722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { | 722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { |
723 | case FSP_PKT_TYPE_ABS: | 723 | case FSP_PKT_TYPE_ABS: |
724 | |||
725 | if ((packet[0] == 0x48 || packet[0] == 0x49) && | ||
726 | packet[1] == 0 && packet[2] == 0) { | ||
727 | /* | ||
728 | * Ignore coordinate noise when finger leaving the | ||
729 | * surface, otherwise cursor may jump to upper-left | ||
730 | * corner. | ||
731 | */ | ||
732 | packet[3] &= 0xf0; | ||
733 | } | ||
734 | |||
724 | abs_x = GET_ABS_X(packet); | 735 | abs_x = GET_ABS_X(packet); |
725 | abs_y = GET_ABS_Y(packet); | 736 | abs_y = GET_ABS_Y(packet); |
726 | 737 | ||
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 2ffd110bd5bc..2e77246c2e5a 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -72,7 +72,7 @@ static int amba_kmi_open(struct serio *io) | |||
72 | unsigned int divisor; | 72 | unsigned int divisor; |
73 | int ret; | 73 | int ret; |
74 | 74 | ||
75 | ret = clk_enable(kmi->clk); | 75 | ret = clk_prepare_enable(kmi->clk); |
76 | if (ret) | 76 | if (ret) |
77 | goto out; | 77 | goto out; |
78 | 78 | ||
@@ -92,7 +92,7 @@ static int amba_kmi_open(struct serio *io) | |||
92 | return 0; | 92 | return 0; |
93 | 93 | ||
94 | clk_disable: | 94 | clk_disable: |
95 | clk_disable(kmi->clk); | 95 | clk_disable_unprepare(kmi->clk); |
96 | out: | 96 | out: |
97 | return ret; | 97 | return ret; |
98 | } | 98 | } |
@@ -104,7 +104,7 @@ static void amba_kmi_close(struct serio *io) | |||
104 | writeb(0, KMICR); | 104 | writeb(0, KMICR); |
105 | 105 | ||
106 | free_irq(kmi->irq, kmi); | 106 | free_irq(kmi->irq, kmi); |
107 | clk_disable(kmi->clk); | 107 | clk_disable_unprepare(kmi->clk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int __devinit amba_kmi_probe(struct amba_device *dev, | 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5ec774d6c82b..d6cc77a53c7e 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -177,6 +177,20 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
177 | }, | 177 | }, |
178 | }, | 178 | }, |
179 | { | 179 | { |
180 | /* Gigabyte T1005 - defines wrong chassis type ("Other") */ | ||
181 | .matches = { | ||
182 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
183 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), | ||
184 | }, | ||
185 | }, | ||
186 | { | ||
187 | /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ | ||
188 | .matches = { | ||
189 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
190 | DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), | ||
191 | }, | ||
192 | }, | ||
193 | { | ||
180 | .matches = { | 194 | .matches = { |
181 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 195 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
182 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 196 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
@@ -321,6 +335,12 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | |||
321 | }, | 335 | }, |
322 | { | 336 | { |
323 | .matches = { | 337 | .matches = { |
338 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
339 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), | ||
340 | }, | ||
341 | }, | ||
342 | { | ||
343 | .matches = { | ||
324 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | 344 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), |
325 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | 345 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), |
326 | }, | 346 | }, |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 002041975de9..532d067a9e07 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1848,7 +1848,10 @@ static const struct wacom_features wacom_features_0x2A = | |||
1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | 1848 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1849 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
1850 | static const struct wacom_features wacom_features_0xF4 = | 1850 | static const struct wacom_features wacom_features_0xF4 = |
1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 1851 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | ||
1853 | static const struct wacom_features wacom_features_0xF8 = | ||
1854 | { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | ||
1852 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 1855 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
1853 | static const struct wacom_features wacom_features_0x3F = | 1856 | static const struct wacom_features wacom_features_0x3F = |
1854 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, | 1857 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
@@ -2091,6 +2094,7 @@ const struct usb_device_id wacom_ids[] = { | |||
2091 | { USB_DEVICE_WACOM(0xEF) }, | 2094 | { USB_DEVICE_WACOM(0xEF) }, |
2092 | { USB_DEVICE_WACOM(0x47) }, | 2095 | { USB_DEVICE_WACOM(0x47) }, |
2093 | { USB_DEVICE_WACOM(0xF4) }, | 2096 | { USB_DEVICE_WACOM(0xF4) }, |
2097 | { USB_DEVICE_WACOM(0xF8) }, | ||
2094 | { USB_DEVICE_WACOM(0xFA) }, | 2098 | { USB_DEVICE_WACOM(0xFA) }, |
2095 | { USB_DEVICE_LENOVO(0x6004) }, | 2099 | { USB_DEVICE_LENOVO(0x6004) }, |
2096 | { } | 2100 | { } |
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 9afc777a40a7..64957770b522 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c | |||
@@ -566,9 +566,12 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file, | |||
566 | } | 566 | } |
567 | 567 | ||
568 | read = min_t(size_t, count, tsdata->raw_bufsize - *off); | 568 | read = min_t(size_t, count, tsdata->raw_bufsize - *off); |
569 | error = copy_to_user(buf, tsdata->raw_buffer + *off, read); | 569 | if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) { |
570 | if (!error) | 570 | error = -EFAULT; |
571 | *off += read; | 571 | goto out; |
572 | } | ||
573 | |||
574 | *off += read; | ||
572 | out: | 575 | out: |
573 | mutex_unlock(&tsdata->mutex); | 576 | mutex_unlock(&tsdata->mutex); |
574 | return error ?: read; | 577 | return error ?: read; |
@@ -602,6 +605,7 @@ edt_ft5x06_ts_teardown_debugfs(struct edt_ft5x06_ts_data *tsdata) | |||
602 | { | 605 | { |
603 | if (tsdata->debug_dir) | 606 | if (tsdata->debug_dir) |
604 | debugfs_remove_recursive(tsdata->debug_dir); | 607 | debugfs_remove_recursive(tsdata->debug_dir); |
608 | kfree(tsdata->raw_buffer); | ||
605 | } | 609 | } |
606 | 610 | ||
607 | #else | 611 | #else |
@@ -843,7 +847,6 @@ static int __devexit edt_ft5x06_ts_remove(struct i2c_client *client) | |||
843 | if (gpio_is_valid(pdata->reset_pin)) | 847 | if (gpio_is_valid(pdata->reset_pin)) |
844 | gpio_free(pdata->reset_pin); | 848 | gpio_free(pdata->reset_pin); |
845 | 849 | ||
846 | kfree(tsdata->raw_buffer); | ||
847 | kfree(tsdata); | 850 | kfree(tsdata); |
848 | 851 | ||
849 | return 0; | 852 | return 0; |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 503c7096ed36..908407efc672 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -48,7 +48,7 @@ struct eeti_ts_priv { | |||
48 | struct input_dev *input; | 48 | struct input_dev *input; |
49 | struct work_struct work; | 49 | struct work_struct work; |
50 | struct mutex mutex; | 50 | struct mutex mutex; |
51 | int irq, irq_active_high; | 51 | int irq_gpio, irq, irq_active_high; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #define EETI_TS_BITDEPTH (11) | 54 | #define EETI_TS_BITDEPTH (11) |
@@ -62,7 +62,7 @@ struct eeti_ts_priv { | |||
62 | 62 | ||
63 | static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) | 63 | static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) |
64 | { | 64 | { |
65 | return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high; | 65 | return gpio_get_value(priv->irq_gpio) == priv->irq_active_high; |
66 | } | 66 | } |
67 | 67 | ||
68 | static void eeti_ts_read(struct work_struct *work) | 68 | static void eeti_ts_read(struct work_struct *work) |
@@ -157,7 +157,7 @@ static void eeti_ts_close(struct input_dev *dev) | |||
157 | static int __devinit eeti_ts_probe(struct i2c_client *client, | 157 | static int __devinit eeti_ts_probe(struct i2c_client *client, |
158 | const struct i2c_device_id *idp) | 158 | const struct i2c_device_id *idp) |
159 | { | 159 | { |
160 | struct eeti_ts_platform_data *pdata; | 160 | struct eeti_ts_platform_data *pdata = client->dev.platform_data; |
161 | struct eeti_ts_priv *priv; | 161 | struct eeti_ts_priv *priv; |
162 | struct input_dev *input; | 162 | struct input_dev *input; |
163 | unsigned int irq_flags; | 163 | unsigned int irq_flags; |
@@ -199,9 +199,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
199 | 199 | ||
200 | priv->client = client; | 200 | priv->client = client; |
201 | priv->input = input; | 201 | priv->input = input; |
202 | priv->irq = client->irq; | 202 | priv->irq_gpio = pdata->irq_gpio; |
203 | priv->irq = gpio_to_irq(pdata->irq_gpio); | ||
203 | 204 | ||
204 | pdata = client->dev.platform_data; | 205 | err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name); |
206 | if (err < 0) | ||
207 | goto err1; | ||
205 | 208 | ||
206 | if (pdata) | 209 | if (pdata) |
207 | priv->irq_active_high = pdata->irq_active_high; | 210 | priv->irq_active_high = pdata->irq_active_high; |
@@ -215,13 +218,13 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
215 | 218 | ||
216 | err = input_register_device(input); | 219 | err = input_register_device(input); |
217 | if (err) | 220 | if (err) |
218 | goto err1; | 221 | goto err2; |
219 | 222 | ||
220 | err = request_irq(priv->irq, eeti_ts_isr, irq_flags, | 223 | err = request_irq(priv->irq, eeti_ts_isr, irq_flags, |
221 | client->name, priv); | 224 | client->name, priv); |
222 | if (err) { | 225 | if (err) { |
223 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); | 226 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); |
224 | goto err2; | 227 | goto err3; |
225 | } | 228 | } |
226 | 229 | ||
227 | /* | 230 | /* |
@@ -233,9 +236,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
233 | device_init_wakeup(&client->dev, 0); | 236 | device_init_wakeup(&client->dev, 0); |
234 | return 0; | 237 | return 0; |
235 | 238 | ||
236 | err2: | 239 | err3: |
237 | input_unregister_device(input); | 240 | input_unregister_device(input); |
238 | input = NULL; /* so we dont try to free it below */ | 241 | input = NULL; /* so we dont try to free it below */ |
242 | err2: | ||
243 | gpio_free(pdata->irq_gpio); | ||
239 | err1: | 244 | err1: |
240 | input_free_device(input); | 245 | input_free_device(input); |
241 | kfree(priv); | 246 | kfree(priv); |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index e32709e0dd65..721fdb3597ca 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
304 | #define EGALAX_PKT_TYPE_REPT 0x80 | 304 | #define EGALAX_PKT_TYPE_REPT 0x80 |
305 | #define EGALAX_PKT_TYPE_DIAG 0x0A | 305 | #define EGALAX_PKT_TYPE_DIAG 0x0A |
306 | 306 | ||
307 | static int egalax_init(struct usbtouch_usb *usbtouch) | ||
308 | { | ||
309 | int ret, i; | ||
310 | unsigned char *buf; | ||
311 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
312 | |||
313 | /* | ||
314 | * An eGalax diagnostic packet kicks the device into using the right | ||
315 | * protocol. We send a "check active" packet. The response will be | ||
316 | * read later and ignored. | ||
317 | */ | ||
318 | |||
319 | buf = kmalloc(3, GFP_KERNEL); | ||
320 | if (!buf) | ||
321 | return -ENOMEM; | ||
322 | |||
323 | buf[0] = EGALAX_PKT_TYPE_DIAG; | ||
324 | buf[1] = 1; /* length */ | ||
325 | buf[2] = 'A'; /* command - check active */ | ||
326 | |||
327 | for (i = 0; i < 3; i++) { | ||
328 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
329 | 0, | ||
330 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
331 | 0, 0, buf, 3, | ||
332 | USB_CTRL_SET_TIMEOUT); | ||
333 | if (ret >= 0) { | ||
334 | ret = 0; | ||
335 | break; | ||
336 | } | ||
337 | if (ret != -EPIPE) | ||
338 | break; | ||
339 | } | ||
340 | |||
341 | kfree(buf); | ||
342 | |||
343 | return ret; | ||
344 | } | ||
345 | |||
307 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 346 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
308 | { | 347 | { |
309 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) | 348 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) |
@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
1056 | .process_pkt = usbtouch_process_multi, | 1095 | .process_pkt = usbtouch_process_multi, |
1057 | .get_pkt_len = egalax_get_pkt_len, | 1096 | .get_pkt_len = egalax_get_pkt_len, |
1058 | .read_data = egalax_read_data, | 1097 | .read_data = egalax_read_data, |
1098 | .init = egalax_init, | ||
1059 | }, | 1099 | }, |
1060 | #endif | 1100 | #endif |
1061 | 1101 | ||
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 6d1cbdfc9b2a..b64502dfa9f4 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -296,8 +296,13 @@ static int iommu_init_device(struct device *dev) | |||
296 | } else | 296 | } else |
297 | dma_pdev = pci_dev_get(pdev); | 297 | dma_pdev = pci_dev_get(pdev); |
298 | 298 | ||
299 | /* Account for quirked devices */ | ||
299 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 300 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
300 | 301 | ||
302 | /* | ||
303 | * If it's a multifunction device that does not support our | ||
304 | * required ACS flags, add to the same group as function 0. | ||
305 | */ | ||
301 | if (dma_pdev->multifunction && | 306 | if (dma_pdev->multifunction && |
302 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 307 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
303 | swap_pci_ref(&dma_pdev, | 308 | swap_pci_ref(&dma_pdev, |
@@ -305,14 +310,28 @@ static int iommu_init_device(struct device *dev) | |||
305 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 310 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
306 | 0))); | 311 | 0))); |
307 | 312 | ||
313 | /* | ||
314 | * Devices on the root bus go through the iommu. If that's not us, | ||
315 | * find the next upstream device and test ACS up to the root bus. | ||
316 | * Finding the next device may require skipping virtual buses. | ||
317 | */ | ||
308 | while (!pci_is_root_bus(dma_pdev->bus)) { | 318 | while (!pci_is_root_bus(dma_pdev->bus)) { |
309 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 319 | struct pci_bus *bus = dma_pdev->bus; |
310 | NULL, REQ_ACS_FLAGS)) | 320 | |
321 | while (!bus->self) { | ||
322 | if (!pci_is_root_bus(bus)) | ||
323 | bus = bus->parent; | ||
324 | else | ||
325 | goto root_bus; | ||
326 | } | ||
327 | |||
328 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
311 | break; | 329 | break; |
312 | 330 | ||
313 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 331 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
314 | } | 332 | } |
315 | 333 | ||
334 | root_bus: | ||
316 | group = iommu_group_get(&dma_pdev->dev); | 335 | group = iommu_group_get(&dma_pdev->dev); |
317 | pci_dev_put(dma_pdev); | 336 | pci_dev_put(dma_pdev); |
318 | if (!group) { | 337 | if (!group) { |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 500e7f15f5c2..18a89b760aaa 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -1111,7 +1111,7 @@ static void print_iommu_info(void) | |||
1111 | 1111 | ||
1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { | 1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { |
1113 | pr_info("AMD-Vi: Extended features: "); | 1113 | pr_info("AMD-Vi: Extended features: "); |
1114 | for (i = 0; ARRAY_SIZE(feat_str); ++i) { | 1114 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { |
1115 | if (iommu_feature(iommu, (1ULL << i))) | 1115 | if (iommu_feature(iommu, (1ULL << i))) |
1116 | pr_cont(" %s", feat_str[i]); | 1116 | pr_cont(" %s", feat_str[i]); |
1117 | } | 1117 | } |
@@ -1131,9 +1131,6 @@ static int __init amd_iommu_init_pci(void) | |||
1131 | break; | 1131 | break; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | /* Make sure ACS will be enabled */ | ||
1135 | pci_request_acs(); | ||
1136 | |||
1137 | ret = amd_iommu_init_devices(); | 1134 | ret = amd_iommu_init_devices(); |
1138 | 1135 | ||
1139 | print_iommu_info(); | 1136 | print_iommu_info(); |
@@ -1652,6 +1649,9 @@ static bool detect_ivrs(void) | |||
1652 | 1649 | ||
1653 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); | 1650 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); |
1654 | 1651 | ||
1652 | /* Make sure ACS will be enabled during PCI probe */ | ||
1653 | pci_request_acs(); | ||
1654 | |||
1655 | return true; | 1655 | return true; |
1656 | } | 1656 | } |
1657 | 1657 | ||
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 45350ff5e93c..80bad32aa463 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -732,9 +732,9 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) | |||
732 | spin_lock_init(&priv->pgtablelock); | 732 | spin_lock_init(&priv->pgtablelock); |
733 | INIT_LIST_HEAD(&priv->clients); | 733 | INIT_LIST_HEAD(&priv->clients); |
734 | 734 | ||
735 | dom->geometry.aperture_start = 0; | 735 | domain->geometry.aperture_start = 0; |
736 | dom->geometry.aperture_end = ~0UL; | 736 | domain->geometry.aperture_end = ~0UL; |
737 | dom->geometry.force_aperture = true; | 737 | domain->geometry.force_aperture = true; |
738 | 738 | ||
739 | domain->priv = priv; | 739 | domain->priv = priv; |
740 | return 0; | 740 | return 0; |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 7469b5346643..2297ec193eb4 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2008,6 +2008,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
2008 | if (!drhd) { | 2008 | if (!drhd) { |
2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", | 2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", |
2010 | pci_name(pdev)); | 2010 | pci_name(pdev)); |
2011 | free_domain_mem(domain); | ||
2011 | return NULL; | 2012 | return NULL; |
2012 | } | 2013 | } |
2013 | iommu = drhd->iommu; | 2014 | iommu = drhd->iommu; |
@@ -4124,8 +4125,13 @@ static int intel_iommu_add_device(struct device *dev) | |||
4124 | } else | 4125 | } else |
4125 | dma_pdev = pci_dev_get(pdev); | 4126 | dma_pdev = pci_dev_get(pdev); |
4126 | 4127 | ||
4128 | /* Account for quirked devices */ | ||
4127 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 4129 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
4128 | 4130 | ||
4131 | /* | ||
4132 | * If it's a multifunction device that does not support our | ||
4133 | * required ACS flags, add to the same group as function 0. | ||
4134 | */ | ||
4129 | if (dma_pdev->multifunction && | 4135 | if (dma_pdev->multifunction && |
4130 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 4136 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
4131 | swap_pci_ref(&dma_pdev, | 4137 | swap_pci_ref(&dma_pdev, |
@@ -4133,14 +4139,28 @@ static int intel_iommu_add_device(struct device *dev) | |||
4133 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 4139 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
4134 | 0))); | 4140 | 0))); |
4135 | 4141 | ||
4142 | /* | ||
4143 | * Devices on the root bus go through the iommu. If that's not us, | ||
4144 | * find the next upstream device and test ACS up to the root bus. | ||
4145 | * Finding the next device may require skipping virtual buses. | ||
4146 | */ | ||
4136 | while (!pci_is_root_bus(dma_pdev->bus)) { | 4147 | while (!pci_is_root_bus(dma_pdev->bus)) { |
4137 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 4148 | struct pci_bus *bus = dma_pdev->bus; |
4138 | NULL, REQ_ACS_FLAGS)) | 4149 | |
4150 | while (!bus->self) { | ||
4151 | if (!pci_is_root_bus(bus)) | ||
4152 | bus = bus->parent; | ||
4153 | else | ||
4154 | goto root_bus; | ||
4155 | } | ||
4156 | |||
4157 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
4139 | break; | 4158 | break; |
4140 | 4159 | ||
4141 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 4160 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
4142 | } | 4161 | } |
4143 | 4162 | ||
4163 | root_bus: | ||
4144 | group = iommu_group_get(&dma_pdev->dev); | 4164 | group = iommu_group_get(&dma_pdev->dev); |
4145 | pci_dev_put(dma_pdev); | 4165 | pci_dev_put(dma_pdev); |
4146 | if (!group) { | 4166 | if (!group) { |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index e0b18f3ae9a8..af8904de1d44 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void) | |||
736 | { | 736 | { |
737 | struct dmar_drhd_unit *drhd; | 737 | struct dmar_drhd_unit *drhd; |
738 | int ir_supported = 0; | 738 | int ir_supported = 0; |
739 | int ioapic_idx; | ||
739 | 740 | ||
740 | for_each_drhd_unit(drhd) { | 741 | for_each_drhd_unit(drhd) { |
741 | struct intel_iommu *iommu = drhd->iommu; | 742 | struct intel_iommu *iommu = drhd->iommu; |
@@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void) | |||
748 | } | 749 | } |
749 | } | 750 | } |
750 | 751 | ||
751 | if (ir_supported && ir_ioapic_num != nr_ioapics) { | 752 | if (!ir_supported) |
752 | printk(KERN_WARNING | 753 | return 0; |
753 | "Not all IO-APIC's listed under remapping hardware\n"); | 754 | |
754 | return -1; | 755 | for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) { |
756 | int ioapic_id = mpc_ioapic_id(ioapic_idx); | ||
757 | if (!map_ioapic_to_ir(ioapic_id)) { | ||
758 | pr_err(FW_BUG "ioapic %d has no mapping iommu, " | ||
759 | "interrupt remapping will be disabled\n", | ||
760 | ioapic_id); | ||
761 | return -1; | ||
762 | } | ||
755 | } | 763 | } |
756 | 764 | ||
757 | return ir_supported; | 765 | return 1; |
758 | } | 766 | } |
759 | 767 | ||
760 | int __init ir_dev_scope_init(void) | 768 | int __init ir_dev_scope_init(void) |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 4ba325ab6262..2a4bb36bc688 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -799,14 +799,14 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain, | |||
799 | goto out; | 799 | goto out; |
800 | } | 800 | } |
801 | } | 801 | } |
802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); | 802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(dev)); |
803 | out: | 803 | out: |
804 | spin_unlock(&as->client_lock); | 804 | spin_unlock(&as->client_lock); |
805 | } | 805 | } |
806 | 806 | ||
807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) | 807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) |
808 | { | 808 | { |
809 | int i, err = -ENODEV; | 809 | int i, err = -EAGAIN; |
810 | unsigned long flags; | 810 | unsigned long flags; |
811 | struct smmu_as *as; | 811 | struct smmu_as *as; |
812 | struct smmu_device *smmu = smmu_handle; | 812 | struct smmu_device *smmu = smmu_handle; |
@@ -814,11 +814,14 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain) | |||
814 | /* Look for a free AS with lock held */ | 814 | /* Look for a free AS with lock held */ |
815 | for (i = 0; i < smmu->num_as; i++) { | 815 | for (i = 0; i < smmu->num_as; i++) { |
816 | as = &smmu->as[i]; | 816 | as = &smmu->as[i]; |
817 | if (!as->pdir_page) { | 817 | |
818 | err = alloc_pdir(as); | 818 | if (as->pdir_page) |
819 | if (!err) | 819 | continue; |
820 | goto found; | 820 | |
821 | } | 821 | err = alloc_pdir(as); |
822 | if (!err) | ||
823 | goto found; | ||
824 | |||
822 | if (err != -EAGAIN) | 825 | if (err != -EAGAIN) |
823 | break; | 826 | break; |
824 | } | 827 | } |
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index fa6ca4733725..dceaec821b0e 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c | |||
@@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
857 | switch (cmd) { | 857 | switch (cmd) { |
858 | case CLOSE_CHANNEL: | 858 | case CLOSE_CHANNEL: |
859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
860 | cancel_work_sync(&bch->workq); | ||
860 | spin_lock_irqsave(&fc->lock, flags); | 861 | spin_lock_irqsave(&fc->lock, flags); |
861 | mISDN_freebchannel(bch); | 862 | mISDN_clear_bchannel(bch); |
862 | modehdlc(bch, ISDN_P_NONE); | 863 | modehdlc(bch, ISDN_P_NONE); |
863 | spin_unlock_irqrestore(&fc->lock, flags); | 864 | spin_unlock_irqrestore(&fc->lock, flags); |
864 | ch->protocol = ISDN_P_NONE; | 865 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e795..f02794203bb1 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5059 | printk(KERN_INFO | 5059 | printk(KERN_INFO |
5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", | 5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", |
5061 | E1_cnt + 1, pt); | 5061 | E1_cnt + 1, pt); |
5062 | kfree(hc); | ||
5062 | return -EINVAL; | 5063 | return -EINVAL; |
5063 | } | 5064 | } |
5064 | maskcheck |= hc->bmask[pt]; | 5065 | maskcheck |= hc->bmask[pt]; |
@@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5086 | if ((poll >> 1) > sizeof(hc->silence_data)) { | 5087 | if ((poll >> 1) > sizeof(hc->silence_data)) { |
5087 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " | 5088 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " |
5088 | "please fix\n"); | 5089 | "please fix\n"); |
5090 | kfree(hc); | ||
5089 | return -EINVAL; | 5091 | return -EINVAL; |
5090 | } | 5092 | } |
5091 | for (i = 0; i < (poll >> 1); i++) | 5093 | for (i = 0; i < (poll >> 1); i++) |
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591f..ccd7d851be26 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c | |||
@@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1406 | switch (cmd) { | 1406 | switch (cmd) { |
1407 | case CLOSE_CHANNEL: | 1407 | case CLOSE_CHANNEL: |
1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1409 | cancel_work_sync(&bch->workq); | ||
1409 | spin_lock_irqsave(hx->ip->hwlock, flags); | 1410 | spin_lock_irqsave(hx->ip->hwlock, flags); |
1410 | mISDN_freebchannel(bch); | 1411 | mISDN_clear_bchannel(bch); |
1411 | hscx_mode(hx, ISDN_P_NONE); | 1412 | hscx_mode(hx, ISDN_P_NONE); |
1412 | spin_unlock_irqrestore(hx->ip->hwlock, flags); | 1413 | spin_unlock_irqrestore(hx->ip->hwlock, flags); |
1413 | ch->protocol = ISDN_P_NONE; | 1414 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d6..182ecf0626c2 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c | |||
@@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1588 | switch (cmd) { | 1588 | switch (cmd) { |
1589 | case CLOSE_CHANNEL: | 1589 | case CLOSE_CHANNEL: |
1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1591 | cancel_work_sync(&bch->workq); | ||
1591 | spin_lock_irqsave(ich->is->hwlock, flags); | 1592 | spin_lock_irqsave(ich->is->hwlock, flags); |
1592 | mISDN_freebchannel(bch); | 1593 | mISDN_clear_bchannel(bch); |
1593 | modeisar(ich, ISDN_P_NONE); | 1594 | modeisar(ich, ISDN_P_NONE); |
1594 | spin_unlock_irqrestore(ich->is->hwlock, flags); | 1595 | spin_unlock_irqrestore(ich->is->hwlock, flags); |
1595 | ch->protocol = ISDN_P_NONE; | 1596 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index c3e3e7686273..9bcade59eb73 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c | |||
@@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
812 | switch (cmd) { | 812 | switch (cmd) { |
813 | case CLOSE_CHANNEL: | 813 | case CLOSE_CHANNEL: |
814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
815 | cancel_work_sync(&bch->workq); | ||
815 | spin_lock_irqsave(&card->lock, flags); | 816 | spin_lock_irqsave(&card->lock, flags); |
816 | mISDN_freebchannel(bch); | 817 | mISDN_clear_bchannel(bch); |
817 | mode_tiger(bc, ISDN_P_NONE); | 818 | mode_tiger(bc, ISDN_P_NONE); |
818 | spin_unlock_irqrestore(&card->lock, flags); | 819 | spin_unlock_irqrestore(&card->lock, flags); |
819 | ch->protocol = ISDN_P_NONE; | 820 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 26a86b846099..335fe6455002 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c | |||
@@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1054 | switch (cmd) { | 1054 | switch (cmd) { |
1055 | case CLOSE_CHANNEL: | 1055 | case CLOSE_CHANNEL: |
1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1057 | cancel_work_sync(&bch->workq); | ||
1057 | spin_lock_irqsave(&card->lock, flags); | 1058 | spin_lock_irqsave(&card->lock, flags); |
1058 | mISDN_freebchannel(bch); | 1059 | mISDN_clear_bchannel(bch); |
1059 | w6692_mode(bc, ISDN_P_NONE); | 1060 | w6692_mode(bc, ISDN_P_NONE); |
1060 | spin_unlock_irqrestore(&card->lock, flags); | 1061 | spin_unlock_irqrestore(&card->lock, flags); |
1061 | ch->protocol = ISDN_P_NONE; | 1062 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 5405ec644db3..baf2686aa8eb 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include "isdnloop.h" | 17 | #include "isdnloop.h" |
18 | 18 | ||
19 | static char *revision = "$Revision: 1.11.6.7 $"; | ||
20 | static char *isdnloop_id = "loop0"; | 19 | static char *isdnloop_id = "loop0"; |
21 | 20 | ||
22 | MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); | 21 | MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); |
@@ -1494,17 +1493,6 @@ isdnloop_addcard(char *id1) | |||
1494 | static int __init | 1493 | static int __init |
1495 | isdnloop_init(void) | 1494 | isdnloop_init(void) |
1496 | { | 1495 | { |
1497 | char *p; | ||
1498 | char rev[10]; | ||
1499 | |||
1500 | if ((p = strchr(revision, ':'))) { | ||
1501 | strcpy(rev, p + 1); | ||
1502 | p = strchr(rev, '$'); | ||
1503 | *p = 0; | ||
1504 | } else | ||
1505 | strcpy(rev, " ??? "); | ||
1506 | printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev); | ||
1507 | |||
1508 | if (isdnloop_id) | 1496 | if (isdnloop_id) |
1509 | return (isdnloop_addcard(isdnloop_id)); | 1497 | return (isdnloop_addcard(isdnloop_id)); |
1510 | 1498 | ||
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ef34fd40867c..2602be23f341 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch) | |||
148 | ch->next_minlen = ch->init_minlen; | 148 | ch->next_minlen = ch->init_minlen; |
149 | ch->maxlen = ch->init_maxlen; | 149 | ch->maxlen = ch->init_maxlen; |
150 | ch->next_maxlen = ch->init_maxlen; | 150 | ch->next_maxlen = ch->init_maxlen; |
151 | skb_queue_purge(&ch->rqueue); | ||
152 | ch->rcount = 0; | ||
151 | } | 153 | } |
152 | EXPORT_SYMBOL(mISDN_clear_bchannel); | 154 | EXPORT_SYMBOL(mISDN_clear_bchannel); |
153 | 155 | ||
154 | int | 156 | void |
155 | mISDN_freebchannel(struct bchannel *ch) | 157 | mISDN_freebchannel(struct bchannel *ch) |
156 | { | 158 | { |
159 | cancel_work_sync(&ch->workq); | ||
157 | mISDN_clear_bchannel(ch); | 160 | mISDN_clear_bchannel(ch); |
158 | skb_queue_purge(&ch->rqueue); | ||
159 | ch->rcount = 0; | ||
160 | flush_work_sync(&ch->workq); | ||
161 | return 0; | ||
162 | } | 161 | } |
163 | EXPORT_SYMBOL(mISDN_freebchannel); | 162 | EXPORT_SYMBOL(mISDN_freebchannel); |
164 | 163 | ||
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index 0dc8abca1407..949cabb88f1c 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c | |||
@@ -2222,7 +2222,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, | |||
2222 | InitWin(l2); | 2222 | InitWin(l2); |
2223 | l2->l2m.fsm = &l2fsm; | 2223 | l2->l2m.fsm = &l2fsm; |
2224 | if (test_bit(FLG_LAPB, &l2->flag) || | 2224 | if (test_bit(FLG_LAPB, &l2->flag) || |
2225 | test_bit(FLG_PTP, &l2->flag) || | 2225 | test_bit(FLG_FIXED_TEI, &l2->flag) || |
2226 | test_bit(FLG_LAPD_NET, &l2->flag)) | 2226 | test_bit(FLG_LAPD_NET, &l2->flag)) |
2227 | l2->l2m.state = ST_L2_4; | 2227 | l2->l2m.state = ST_L2_4; |
2228 | else | 2228 | else |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 6157cbbf4113..363975b3c925 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -224,7 +224,7 @@ void led_trigger_event(struct led_trigger *trig, | |||
224 | struct led_classdev *led_cdev; | 224 | struct led_classdev *led_cdev; |
225 | 225 | ||
226 | led_cdev = list_entry(entry, struct led_classdev, trig_list); | 226 | led_cdev = list_entry(entry, struct led_classdev, trig_list); |
227 | led_set_brightness(led_cdev, brightness); | 227 | __led_set_brightness(led_cdev, brightness); |
228 | } | 228 | } |
229 | read_unlock(&trig->leddev_list_lock); | 229 | read_unlock(&trig->leddev_list_lock); |
230 | } | 230 | } |
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c index 53bd136f1ef0..0ade6ebfc914 100644 --- a/drivers/leds/leds-lp8788.c +++ b/drivers/leds/leds-lp8788.c | |||
@@ -63,7 +63,7 @@ static int lp8788_led_init_device(struct lp8788_led *led, | |||
63 | /* scale configuration */ | 63 | /* scale configuration */ |
64 | addr = LP8788_ISINK_CTRL; | 64 | addr = LP8788_ISINK_CTRL; |
65 | mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET); | 65 | mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET); |
66 | val = cfg->scale << cfg->num; | 66 | val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET); |
67 | ret = lp8788_update_bits(led->lp, addr, mask, val); | 67 | ret = lp8788_update_bits(led->lp, addr, mask, val); |
68 | if (ret) | 68 | if (ret) |
69 | return ret; | 69 | return ret; |
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c index 9ee12c28059a..771ea067e680 100644 --- a/drivers/leds/leds-renesas-tpu.c +++ b/drivers/leds/leds-renesas-tpu.c | |||
@@ -247,7 +247,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev) | |||
247 | 247 | ||
248 | if (!cfg) { | 248 | if (!cfg) { |
249 | dev_err(&pdev->dev, "missing platform data\n"); | 249 | dev_err(&pdev->dev, "missing platform data\n"); |
250 | goto err0; | 250 | return -ENODEV; |
251 | } | 251 | } |
252 | 252 | ||
253 | p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); | 253 | p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index fcd098794d37..308e87b417e0 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor | |||
1108 | ret = 0; | 1108 | ret = 0; |
1109 | } | 1109 | } |
1110 | rdev->sectors = rdev->sb_start; | 1110 | rdev->sectors = rdev->sb_start; |
1111 | /* Limit to 4TB as metadata cannot record more than that */ | 1111 | /* Limit to 4TB as metadata cannot record more than that. |
1112 | if (rdev->sectors >= (2ULL << 32)) | 1112 | * (not needed for Linear and RAID0 as metadata doesn't |
1113 | * record this size) | ||
1114 | */ | ||
1115 | if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) | ||
1113 | rdev->sectors = (2ULL << 32) - 2; | 1116 | rdev->sectors = (2ULL << 32) - 2; |
1114 | 1117 | ||
1115 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) | 1118 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
@@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1400 | /* Limit to 4TB as metadata cannot record more than that. | 1403 | /* Limit to 4TB as metadata cannot record more than that. |
1401 | * 4TB == 2^32 KB, or 2*2^32 sectors. | 1404 | * 4TB == 2^32 KB, or 2*2^32 sectors. |
1402 | */ | 1405 | */ |
1403 | if (num_sectors >= (2ULL << 32)) | 1406 | if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) |
1404 | num_sectors = (2ULL << 32) - 2; | 1407 | num_sectors = (2ULL << 32) - 2; |
1405 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1408 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1406 | rdev->sb_page); | 1409 | rdev->sb_page); |
@@ -7616,6 +7619,8 @@ static int remove_and_add_spares(struct mddev *mddev) | |||
7616 | } | 7619 | } |
7617 | } | 7620 | } |
7618 | } | 7621 | } |
7622 | if (removed) | ||
7623 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
7619 | return spares; | 7624 | return spares; |
7620 | } | 7625 | } |
7621 | 7626 | ||
@@ -7629,9 +7634,11 @@ static void reap_sync_thread(struct mddev *mddev) | |||
7629 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 7634 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
7630 | /* success...*/ | 7635 | /* success...*/ |
7631 | /* activate any spares */ | 7636 | /* activate any spares */ |
7632 | if (mddev->pers->spare_active(mddev)) | 7637 | if (mddev->pers->spare_active(mddev)) { |
7633 | sysfs_notify(&mddev->kobj, NULL, | 7638 | sysfs_notify(&mddev->kobj, NULL, |
7634 | "degraded"); | 7639 | "degraded"); |
7640 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
7641 | } | ||
7635 | } | 7642 | } |
7636 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && | 7643 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && |
7637 | mddev->pers->finish_reshape) | 7644 | mddev->pers->finish_reshape) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de5ed6fd8806..0138a727c1f3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
659 | max = biovec->bv_len; | 659 | max = biovec->bv_len; |
660 | 660 | ||
661 | if (mddev->merge_check_needed) { | 661 | if (mddev->merge_check_needed) { |
662 | struct r10bio r10_bio; | 662 | struct { |
663 | struct r10bio r10_bio; | ||
664 | struct r10dev devs[conf->copies]; | ||
665 | } on_stack; | ||
666 | struct r10bio *r10_bio = &on_stack.r10_bio; | ||
663 | int s; | 667 | int s; |
664 | if (conf->reshape_progress != MaxSector) { | 668 | if (conf->reshape_progress != MaxSector) { |
665 | /* Cannot give any guidance during reshape */ | 669 | /* Cannot give any guidance during reshape */ |
@@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
667 | return biovec->bv_len; | 671 | return biovec->bv_len; |
668 | return 0; | 672 | return 0; |
669 | } | 673 | } |
670 | r10_bio.sector = sector; | 674 | r10_bio->sector = sector; |
671 | raid10_find_phys(conf, &r10_bio); | 675 | raid10_find_phys(conf, r10_bio); |
672 | rcu_read_lock(); | 676 | rcu_read_lock(); |
673 | for (s = 0; s < conf->copies; s++) { | 677 | for (s = 0; s < conf->copies; s++) { |
674 | int disk = r10_bio.devs[s].devnum; | 678 | int disk = r10_bio->devs[s].devnum; |
675 | struct md_rdev *rdev = rcu_dereference( | 679 | struct md_rdev *rdev = rcu_dereference( |
676 | conf->mirrors[disk].rdev); | 680 | conf->mirrors[disk].rdev); |
677 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | 681 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
678 | struct request_queue *q = | 682 | struct request_queue *q = |
679 | bdev_get_queue(rdev->bdev); | 683 | bdev_get_queue(rdev->bdev); |
680 | if (q->merge_bvec_fn) { | 684 | if (q->merge_bvec_fn) { |
681 | bvm->bi_sector = r10_bio.devs[s].addr | 685 | bvm->bi_sector = r10_bio->devs[s].addr |
682 | + rdev->data_offset; | 686 | + rdev->data_offset; |
683 | bvm->bi_bdev = rdev->bdev; | 687 | bvm->bi_bdev = rdev->bdev; |
684 | max = min(max, q->merge_bvec_fn( | 688 | max = min(max, q->merge_bvec_fn( |
@@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
690 | struct request_queue *q = | 694 | struct request_queue *q = |
691 | bdev_get_queue(rdev->bdev); | 695 | bdev_get_queue(rdev->bdev); |
692 | if (q->merge_bvec_fn) { | 696 | if (q->merge_bvec_fn) { |
693 | bvm->bi_sector = r10_bio.devs[s].addr | 697 | bvm->bi_sector = r10_bio->devs[s].addr |
694 | + rdev->data_offset; | 698 | + rdev->data_offset; |
695 | bvm->bi_bdev = rdev->bdev; | 699 | bvm->bi_bdev = rdev->bdev; |
696 | max = min(max, q->merge_bvec_fn( | 700 | max = min(max, q->merge_bvec_fn( |
@@ -1508,14 +1512,16 @@ static int _enough(struct r10conf *conf, struct geom *geo, int ignore) | |||
1508 | do { | 1512 | do { |
1509 | int n = conf->copies; | 1513 | int n = conf->copies; |
1510 | int cnt = 0; | 1514 | int cnt = 0; |
1515 | int this = first; | ||
1511 | while (n--) { | 1516 | while (n--) { |
1512 | if (conf->mirrors[first].rdev && | 1517 | if (conf->mirrors[this].rdev && |
1513 | first != ignore) | 1518 | this != ignore) |
1514 | cnt++; | 1519 | cnt++; |
1515 | first = (first+1) % geo->raid_disks; | 1520 | this = (this+1) % geo->raid_disks; |
1516 | } | 1521 | } |
1517 | if (cnt == 0) | 1522 | if (cnt == 0) |
1518 | return 0; | 1523 | return 0; |
1524 | first = (first + geo->near_copies) % geo->raid_disks; | ||
1519 | } while (first != 0); | 1525 | } while (first != 0); |
1520 | return 1; | 1526 | return 1; |
1521 | } | 1527 | } |
@@ -4414,14 +4420,18 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4414 | { | 4420 | { |
4415 | /* Use sync reads to get the blocks from somewhere else */ | 4421 | /* Use sync reads to get the blocks from somewhere else */ |
4416 | int sectors = r10_bio->sectors; | 4422 | int sectors = r10_bio->sectors; |
4417 | struct r10bio r10b; | ||
4418 | struct r10conf *conf = mddev->private; | 4423 | struct r10conf *conf = mddev->private; |
4424 | struct { | ||
4425 | struct r10bio r10_bio; | ||
4426 | struct r10dev devs[conf->copies]; | ||
4427 | } on_stack; | ||
4428 | struct r10bio *r10b = &on_stack.r10_bio; | ||
4419 | int slot = 0; | 4429 | int slot = 0; |
4420 | int idx = 0; | 4430 | int idx = 0; |
4421 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; | 4431 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; |
4422 | 4432 | ||
4423 | r10b.sector = r10_bio->sector; | 4433 | r10b->sector = r10_bio->sector; |
4424 | __raid10_find_phys(&conf->prev, &r10b); | 4434 | __raid10_find_phys(&conf->prev, r10b); |
4425 | 4435 | ||
4426 | while (sectors) { | 4436 | while (sectors) { |
4427 | int s = sectors; | 4437 | int s = sectors; |
@@ -4432,7 +4442,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4432 | s = PAGE_SIZE >> 9; | 4442 | s = PAGE_SIZE >> 9; |
4433 | 4443 | ||
4434 | while (!success) { | 4444 | while (!success) { |
4435 | int d = r10b.devs[slot].devnum; | 4445 | int d = r10b->devs[slot].devnum; |
4436 | struct md_rdev *rdev = conf->mirrors[d].rdev; | 4446 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
4437 | sector_t addr; | 4447 | sector_t addr; |
4438 | if (rdev == NULL || | 4448 | if (rdev == NULL || |
@@ -4440,7 +4450,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4440 | !test_bit(In_sync, &rdev->flags)) | 4450 | !test_bit(In_sync, &rdev->flags)) |
4441 | goto failed; | 4451 | goto failed; |
4442 | 4452 | ||
4443 | addr = r10b.devs[slot].addr + idx * PAGE_SIZE; | 4453 | addr = r10b->devs[slot].addr + idx * PAGE_SIZE; |
4444 | success = sync_page_io(rdev, | 4454 | success = sync_page_io(rdev, |
4445 | addr, | 4455 | addr, |
4446 | s << 9, | 4456 | s << 9, |
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 007c2c68dd83..1054cf602345 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h | |||
@@ -110,7 +110,7 @@ struct r10bio { | |||
110 | * We choose the number when they are allocated. | 110 | * We choose the number when they are allocated. |
111 | * We sometimes need an extra bio to write to the replacement. | 111 | * We sometimes need an extra bio to write to the replacement. |
112 | */ | 112 | */ |
113 | struct { | 113 | struct r10dev { |
114 | struct bio *bio; | 114 | struct bio *bio; |
115 | union { | 115 | union { |
116 | struct bio *repl_bio; /* used for resync and | 116 | struct bio *repl_bio; /* used for resync and |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index adda94df5eb2..0689173fd9f5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -393,6 +393,8 @@ static int calc_degraded(struct r5conf *conf) | |||
393 | degraded = 0; | 393 | degraded = 0; |
394 | for (i = 0; i < conf->previous_raid_disks; i++) { | 394 | for (i = 0; i < conf->previous_raid_disks; i++) { |
395 | struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); | 395 | struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); |
396 | if (rdev && test_bit(Faulty, &rdev->flags)) | ||
397 | rdev = rcu_dereference(conf->disks[i].replacement); | ||
396 | if (!rdev || test_bit(Faulty, &rdev->flags)) | 398 | if (!rdev || test_bit(Faulty, &rdev->flags)) |
397 | degraded++; | 399 | degraded++; |
398 | else if (test_bit(In_sync, &rdev->flags)) | 400 | else if (test_bit(In_sync, &rdev->flags)) |
@@ -417,6 +419,8 @@ static int calc_degraded(struct r5conf *conf) | |||
417 | degraded2 = 0; | 419 | degraded2 = 0; |
418 | for (i = 0; i < conf->raid_disks; i++) { | 420 | for (i = 0; i < conf->raid_disks; i++) { |
419 | struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); | 421 | struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); |
422 | if (rdev && test_bit(Faulty, &rdev->flags)) | ||
423 | rdev = rcu_dereference(conf->disks[i].replacement); | ||
420 | if (!rdev || test_bit(Faulty, &rdev->flags)) | 424 | if (!rdev || test_bit(Faulty, &rdev->flags)) |
421 | degraded2++; | 425 | degraded2++; |
422 | else if (test_bit(In_sync, &rdev->flags)) | 426 | else if (test_bit(In_sync, &rdev->flags)) |
@@ -1587,6 +1591,7 @@ static int resize_stripes(struct r5conf *conf, int newsize) | |||
1587 | #ifdef CONFIG_MULTICORE_RAID456 | 1591 | #ifdef CONFIG_MULTICORE_RAID456 |
1588 | init_waitqueue_head(&nsh->ops.wait_for_ops); | 1592 | init_waitqueue_head(&nsh->ops.wait_for_ops); |
1589 | #endif | 1593 | #endif |
1594 | spin_lock_init(&nsh->stripe_lock); | ||
1590 | 1595 | ||
1591 | list_add(&nsh->lru, &newstripes); | 1596 | list_add(&nsh->lru, &newstripes); |
1592 | } | 1597 | } |
@@ -4192,7 +4197,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) | |||
4192 | finish_wait(&conf->wait_for_overlap, &w); | 4197 | finish_wait(&conf->wait_for_overlap, &w); |
4193 | set_bit(STRIPE_HANDLE, &sh->state); | 4198 | set_bit(STRIPE_HANDLE, &sh->state); |
4194 | clear_bit(STRIPE_DELAYED, &sh->state); | 4199 | clear_bit(STRIPE_DELAYED, &sh->state); |
4195 | if ((bi->bi_rw & REQ_NOIDLE) && | 4200 | if ((bi->bi_rw & REQ_SYNC) && |
4196 | !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) | 4201 | !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) |
4197 | atomic_inc(&conf->preread_active_stripes); | 4202 | atomic_inc(&conf->preread_active_stripes); |
4198 | release_stripe_plug(mddev, sh); | 4203 | release_stripe_plug(mddev, sh); |
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 664e460f247b..aac622200e99 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c | |||
@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf) | |||
481 | return 0; | 481 | return 0; |
482 | } | 482 | } |
483 | 483 | ||
484 | static const struct usb_device_id smsusb_id_table[] __devinitconst = { | 484 | static const struct usb_device_id smsusb_id_table[] = { |
485 | { USB_DEVICE(0x187f, 0x0010), | 485 | { USB_DEVICE(0x187f, 0x0010), |
486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
487 | { USB_DEVICE(0x187f, 0x0100), | 487 | { USB_DEVICE(0x187f, 0x0100), |
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index d0b6bb507634..72ded29728bb 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <sound/tea575x-tuner.h> | 36 | #include <sound/tea575x-tuner.h> |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | /* | 43 | /* |
39 | * Version Information | 44 | * Version Information |
40 | */ | 45 | */ |
@@ -56,44 +61,18 @@ MODULE_LICENSE("GPL"); | |||
56 | 61 | ||
57 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; | 62 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; |
58 | 63 | ||
59 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | static void shark_led_set_blue_pulse(struct led_classdev *led_cdev, | ||
62 | enum led_brightness value); | ||
63 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
64 | enum led_brightness value); | ||
65 | |||
66 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
67 | [BLUE_LED] = { | ||
68 | .name = "%s:blue:", | ||
69 | .brightness = LED_OFF, | ||
70 | .max_brightness = 127, | ||
71 | .brightness_set = shark_led_set_blue, | ||
72 | }, | ||
73 | [BLUE_PULSE_LED] = { | ||
74 | .name = "%s:blue-pulse:", | ||
75 | .brightness = LED_OFF, | ||
76 | .max_brightness = 255, | ||
77 | .brightness_set = shark_led_set_blue_pulse, | ||
78 | }, | ||
79 | [RED_LED] = { | ||
80 | .name = "%s:red:", | ||
81 | .brightness = LED_OFF, | ||
82 | .max_brightness = 1, | ||
83 | .brightness_set = shark_led_set_red, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | struct shark_device { | 64 | struct shark_device { |
88 | struct usb_device *usbdev; | 65 | struct usb_device *usbdev; |
89 | struct v4l2_device v4l2_dev; | 66 | struct v4l2_device v4l2_dev; |
90 | struct snd_tea575x tea; | 67 | struct snd_tea575x tea; |
91 | 68 | ||
69 | #ifdef SHARK_USE_LEDS | ||
92 | struct work_struct led_work; | 70 | struct work_struct led_work; |
93 | struct led_classdev leds[NO_LEDS]; | 71 | struct led_classdev leds[NO_LEDS]; |
94 | char led_names[NO_LEDS][32]; | 72 | char led_names[NO_LEDS][32]; |
95 | atomic_t brightness[NO_LEDS]; | 73 | atomic_t brightness[NO_LEDS]; |
96 | unsigned long brightness_new; | 74 | unsigned long brightness_new; |
75 | #endif | ||
97 | 76 | ||
98 | u8 *transfer_buffer; | 77 | u8 *transfer_buffer; |
99 | u32 last_val; | 78 | u32 last_val; |
@@ -175,20 +154,13 @@ static struct snd_tea575x_ops shark_tea_ops = { | |||
175 | .read_val = shark_read_val, | 154 | .read_val = shark_read_val, |
176 | }; | 155 | }; |
177 | 156 | ||
157 | #ifdef SHARK_USE_LEDS | ||
178 | static void shark_led_work(struct work_struct *work) | 158 | static void shark_led_work(struct work_struct *work) |
179 | { | 159 | { |
180 | struct shark_device *shark = | 160 | struct shark_device *shark = |
181 | container_of(work, struct shark_device, led_work); | 161 | container_of(work, struct shark_device, led_work); |
182 | int i, res, brightness, actual_len; | 162 | int i, res, brightness, actual_len; |
183 | 163 | ||
184 | /* | ||
185 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
186 | * does not get unplugged and unreffed while we're running. | ||
187 | */ | ||
188 | mutex_lock(&shark->tea.mutex); | ||
189 | if (!video_is_registered(&shark->tea.vd)) | ||
190 | goto leave; | ||
191 | |||
192 | for (i = 0; i < 3; i++) { | 164 | for (i = 0; i < 3; i++) { |
193 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 165 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
194 | continue; | 166 | continue; |
@@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work) | |||
208 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 180 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
209 | shark->led_names[i], res); | 181 | shark->led_names[i], res); |
210 | } | 182 | } |
211 | leave: | ||
212 | mutex_unlock(&shark->tea.mutex); | ||
213 | } | 183 | } |
214 | 184 | ||
215 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 185 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
245 | schedule_work(&shark->led_work); | 215 | schedule_work(&shark->led_work); |
246 | } | 216 | } |
247 | 217 | ||
218 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
219 | [BLUE_LED] = { | ||
220 | .name = "%s:blue:", | ||
221 | .brightness = LED_OFF, | ||
222 | .max_brightness = 127, | ||
223 | .brightness_set = shark_led_set_blue, | ||
224 | }, | ||
225 | [BLUE_PULSE_LED] = { | ||
226 | .name = "%s:blue-pulse:", | ||
227 | .brightness = LED_OFF, | ||
228 | .max_brightness = 255, | ||
229 | .brightness_set = shark_led_set_blue_pulse, | ||
230 | }, | ||
231 | [RED_LED] = { | ||
232 | .name = "%s:red:", | ||
233 | .brightness = LED_OFF, | ||
234 | .max_brightness = 1, | ||
235 | .brightness_set = shark_led_set_red, | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
240 | { | ||
241 | int i, retval; | ||
242 | |||
243 | INIT_WORK(&shark->led_work, shark_led_work); | ||
244 | for (i = 0; i < NO_LEDS; i++) { | ||
245 | shark->leds[i] = shark_led_templates[i]; | ||
246 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
247 | shark->leds[i].name, shark->v4l2_dev.name); | ||
248 | shark->leds[i].name = shark->led_names[i]; | ||
249 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
250 | if (retval) { | ||
251 | v4l2_err(&shark->v4l2_dev, | ||
252 | "couldn't register led: %s\n", | ||
253 | shark->led_names[i]); | ||
254 | return retval; | ||
255 | } | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static void shark_unregister_leds(struct shark_device *shark) | ||
261 | { | ||
262 | int i; | ||
263 | |||
264 | for (i = 0; i < NO_LEDS; i++) | ||
265 | led_classdev_unregister(&shark->leds[i]); | ||
266 | |||
267 | cancel_work_sync(&shark->led_work); | ||
268 | } | ||
269 | #else | ||
270 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
271 | { | ||
272 | v4l2_warn(&shark->v4l2_dev, | ||
273 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
274 | return 0; | ||
275 | } | ||
276 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
277 | #endif | ||
278 | |||
248 | static void usb_shark_disconnect(struct usb_interface *intf) | 279 | static void usb_shark_disconnect(struct usb_interface *intf) |
249 | { | 280 | { |
250 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 281 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
251 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 282 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
252 | int i; | ||
253 | 283 | ||
254 | mutex_lock(&shark->tea.mutex); | 284 | mutex_lock(&shark->tea.mutex); |
255 | v4l2_device_disconnect(&shark->v4l2_dev); | 285 | v4l2_device_disconnect(&shark->v4l2_dev); |
256 | snd_tea575x_exit(&shark->tea); | 286 | snd_tea575x_exit(&shark->tea); |
257 | mutex_unlock(&shark->tea.mutex); | 287 | mutex_unlock(&shark->tea.mutex); |
258 | 288 | ||
259 | for (i = 0; i < NO_LEDS; i++) | 289 | shark_unregister_leds(shark); |
260 | led_classdev_unregister(&shark->leds[i]); | ||
261 | 290 | ||
262 | v4l2_device_put(&shark->v4l2_dev); | 291 | v4l2_device_put(&shark->v4l2_dev); |
263 | } | 292 | } |
@@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
266 | { | 295 | { |
267 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 296 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
268 | 297 | ||
269 | cancel_work_sync(&shark->led_work); | ||
270 | v4l2_device_unregister(&shark->v4l2_dev); | 298 | v4l2_device_unregister(&shark->v4l2_dev); |
271 | kfree(shark->transfer_buffer); | 299 | kfree(shark->transfer_buffer); |
272 | kfree(shark); | 300 | kfree(shark); |
@@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
276 | const struct usb_device_id *id) | 304 | const struct usb_device_id *id) |
277 | { | 305 | { |
278 | struct shark_device *shark; | 306 | struct shark_device *shark; |
279 | int i, retval = -ENOMEM; | 307 | int retval = -ENOMEM; |
280 | 308 | ||
281 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 309 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
282 | if (!shark) | 310 | if (!shark) |
@@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
286 | if (!shark->transfer_buffer) | 314 | if (!shark->transfer_buffer) |
287 | goto err_alloc_buffer; | 315 | goto err_alloc_buffer; |
288 | 316 | ||
289 | /* | 317 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
290 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 318 | |
291 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 319 | retval = shark_register_leds(shark, &intf->dev); |
292 | * results in usb_shark_disconnect() referencing the dangling pointer | 320 | if (retval) |
293 | * | 321 | goto err_reg_leds; |
294 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
295 | */ | ||
296 | usb_set_intfdata(intf, NULL); | ||
297 | 322 | ||
298 | shark->v4l2_dev.release = usb_shark_release; | 323 | shark->v4l2_dev.release = usb_shark_release; |
299 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
300 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 324 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
301 | if (retval) { | 325 | if (retval) { |
302 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 326 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
320 | goto err_init_tea; | 344 | goto err_init_tea; |
321 | } | 345 | } |
322 | 346 | ||
323 | INIT_WORK(&shark->led_work, shark_led_work); | ||
324 | for (i = 0; i < NO_LEDS; i++) { | ||
325 | shark->leds[i] = shark_led_templates[i]; | ||
326 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
327 | shark->leds[i].name, shark->v4l2_dev.name); | ||
328 | shark->leds[i].name = shark->led_names[i]; | ||
329 | /* | ||
330 | * We don't fail the probe if we fail to register the leds, | ||
331 | * because once we've called snd_tea575x_init, the /dev/radio0 | ||
332 | * node may be opened from userspace holding a reference to us! | ||
333 | * | ||
334 | * Note we cannot register the leds first instead as | ||
335 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
336 | */ | ||
337 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
338 | if (retval) | ||
339 | v4l2_err(&shark->v4l2_dev, | ||
340 | "couldn't register led: %s\n", | ||
341 | shark->led_names[i]); | ||
342 | } | ||
343 | |||
344 | return 0; | 347 | return 0; |
345 | 348 | ||
346 | err_init_tea: | 349 | err_init_tea: |
347 | v4l2_device_unregister(&shark->v4l2_dev); | 350 | v4l2_device_unregister(&shark->v4l2_dev); |
348 | err_reg_dev: | 351 | err_reg_dev: |
352 | shark_unregister_leds(shark); | ||
353 | err_reg_leds: | ||
349 | kfree(shark->transfer_buffer); | 354 | kfree(shark->transfer_buffer); |
350 | err_alloc_buffer: | 355 | err_alloc_buffer: |
351 | kfree(shark); | 356 | kfree(shark); |
diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index b9575de3e7e8..7b4efdfaae28 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include "radio-tea5777.h" | 36 | #include "radio-tea5777.h" |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK2_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 43 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
39 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); | 44 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); |
40 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
@@ -43,7 +48,6 @@ static int debug; | |||
43 | module_param(debug, int, 0); | 48 | module_param(debug, int, 0); |
44 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 49 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
45 | 50 | ||
46 | |||
47 | #define SHARK_IN_EP 0x83 | 51 | #define SHARK_IN_EP 0x83 |
48 | #define SHARK_OUT_EP 0x05 | 52 | #define SHARK_OUT_EP 0x05 |
49 | 53 | ||
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
54 | 58 | ||
55 | enum { BLUE_LED, RED_LED, NO_LEDS }; | 59 | enum { BLUE_LED, RED_LED, NO_LEDS }; |
56 | 60 | ||
57 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
58 | enum led_brightness value); | ||
59 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | |||
62 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
63 | [BLUE_LED] = { | ||
64 | .name = "%s:blue:", | ||
65 | .brightness = LED_OFF, | ||
66 | .max_brightness = 127, | ||
67 | .brightness_set = shark_led_set_blue, | ||
68 | }, | ||
69 | [RED_LED] = { | ||
70 | .name = "%s:red:", | ||
71 | .brightness = LED_OFF, | ||
72 | .max_brightness = 1, | ||
73 | .brightness_set = shark_led_set_red, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | struct shark_device { | 61 | struct shark_device { |
78 | struct usb_device *usbdev; | 62 | struct usb_device *usbdev; |
79 | struct v4l2_device v4l2_dev; | 63 | struct v4l2_device v4l2_dev; |
80 | struct radio_tea5777 tea; | 64 | struct radio_tea5777 tea; |
81 | 65 | ||
66 | #ifdef SHARK_USE_LEDS | ||
82 | struct work_struct led_work; | 67 | struct work_struct led_work; |
83 | struct led_classdev leds[NO_LEDS]; | 68 | struct led_classdev leds[NO_LEDS]; |
84 | char led_names[NO_LEDS][32]; | 69 | char led_names[NO_LEDS][32]; |
85 | atomic_t brightness[NO_LEDS]; | 70 | atomic_t brightness[NO_LEDS]; |
86 | unsigned long brightness_new; | 71 | unsigned long brightness_new; |
72 | #endif | ||
87 | 73 | ||
88 | u8 *transfer_buffer; | 74 | u8 *transfer_buffer; |
89 | }; | 75 | }; |
@@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = { | |||
161 | .read_reg = shark_read_reg, | 147 | .read_reg = shark_read_reg, |
162 | }; | 148 | }; |
163 | 149 | ||
150 | #ifdef SHARK_USE_LEDS | ||
164 | static void shark_led_work(struct work_struct *work) | 151 | static void shark_led_work(struct work_struct *work) |
165 | { | 152 | { |
166 | struct shark_device *shark = | 153 | struct shark_device *shark = |
167 | container_of(work, struct shark_device, led_work); | 154 | container_of(work, struct shark_device, led_work); |
168 | int i, res, brightness, actual_len; | 155 | int i, res, brightness, actual_len; |
169 | /* | ||
170 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
171 | * does not get unplugged and unreffed while we're running. | ||
172 | */ | ||
173 | mutex_lock(&shark->tea.mutex); | ||
174 | if (!video_is_registered(&shark->tea.vd)) | ||
175 | goto leave; | ||
176 | 156 | ||
177 | for (i = 0; i < 2; i++) { | 157 | for (i = 0; i < 2; i++) { |
178 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 158 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
@@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work) | |||
191 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 171 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
192 | shark->led_names[i], res); | 172 | shark->led_names[i], res); |
193 | } | 173 | } |
194 | leave: | ||
195 | mutex_unlock(&shark->tea.mutex); | ||
196 | } | 174 | } |
197 | 175 | ||
198 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 176 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
217 | schedule_work(&shark->led_work); | 195 | schedule_work(&shark->led_work); |
218 | } | 196 | } |
219 | 197 | ||
198 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
199 | [BLUE_LED] = { | ||
200 | .name = "%s:blue:", | ||
201 | .brightness = LED_OFF, | ||
202 | .max_brightness = 127, | ||
203 | .brightness_set = shark_led_set_blue, | ||
204 | }, | ||
205 | [RED_LED] = { | ||
206 | .name = "%s:red:", | ||
207 | .brightness = LED_OFF, | ||
208 | .max_brightness = 1, | ||
209 | .brightness_set = shark_led_set_red, | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
214 | { | ||
215 | int i, retval; | ||
216 | |||
217 | INIT_WORK(&shark->led_work, shark_led_work); | ||
218 | for (i = 0; i < NO_LEDS; i++) { | ||
219 | shark->leds[i] = shark_led_templates[i]; | ||
220 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
221 | shark->leds[i].name, shark->v4l2_dev.name); | ||
222 | shark->leds[i].name = shark->led_names[i]; | ||
223 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
224 | if (retval) { | ||
225 | v4l2_err(&shark->v4l2_dev, | ||
226 | "couldn't register led: %s\n", | ||
227 | shark->led_names[i]); | ||
228 | return retval; | ||
229 | } | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void shark_unregister_leds(struct shark_device *shark) | ||
235 | { | ||
236 | int i; | ||
237 | |||
238 | for (i = 0; i < NO_LEDS; i++) | ||
239 | led_classdev_unregister(&shark->leds[i]); | ||
240 | |||
241 | cancel_work_sync(&shark->led_work); | ||
242 | } | ||
243 | #else | ||
244 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
245 | { | ||
246 | v4l2_warn(&shark->v4l2_dev, | ||
247 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
248 | return 0; | ||
249 | } | ||
250 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
251 | #endif | ||
252 | |||
220 | static void usb_shark_disconnect(struct usb_interface *intf) | 253 | static void usb_shark_disconnect(struct usb_interface *intf) |
221 | { | 254 | { |
222 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 255 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
223 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 256 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
224 | int i; | ||
225 | 257 | ||
226 | mutex_lock(&shark->tea.mutex); | 258 | mutex_lock(&shark->tea.mutex); |
227 | v4l2_device_disconnect(&shark->v4l2_dev); | 259 | v4l2_device_disconnect(&shark->v4l2_dev); |
228 | radio_tea5777_exit(&shark->tea); | 260 | radio_tea5777_exit(&shark->tea); |
229 | mutex_unlock(&shark->tea.mutex); | 261 | mutex_unlock(&shark->tea.mutex); |
230 | 262 | ||
231 | for (i = 0; i < NO_LEDS; i++) | 263 | shark_unregister_leds(shark); |
232 | led_classdev_unregister(&shark->leds[i]); | ||
233 | 264 | ||
234 | v4l2_device_put(&shark->v4l2_dev); | 265 | v4l2_device_put(&shark->v4l2_dev); |
235 | } | 266 | } |
@@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
238 | { | 269 | { |
239 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 270 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
240 | 271 | ||
241 | cancel_work_sync(&shark->led_work); | ||
242 | v4l2_device_unregister(&shark->v4l2_dev); | 272 | v4l2_device_unregister(&shark->v4l2_dev); |
243 | kfree(shark->transfer_buffer); | 273 | kfree(shark->transfer_buffer); |
244 | kfree(shark); | 274 | kfree(shark); |
@@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
248 | const struct usb_device_id *id) | 278 | const struct usb_device_id *id) |
249 | { | 279 | { |
250 | struct shark_device *shark; | 280 | struct shark_device *shark; |
251 | int i, retval = -ENOMEM; | 281 | int retval = -ENOMEM; |
252 | 282 | ||
253 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 283 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
254 | if (!shark) | 284 | if (!shark) |
@@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
258 | if (!shark->transfer_buffer) | 288 | if (!shark->transfer_buffer) |
259 | goto err_alloc_buffer; | 289 | goto err_alloc_buffer; |
260 | 290 | ||
261 | /* | 291 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
262 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 292 | |
263 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 293 | retval = shark_register_leds(shark, &intf->dev); |
264 | * results in usb_shark_disconnect() referencing the dangling pointer | 294 | if (retval) |
265 | * | 295 | goto err_reg_leds; |
266 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
267 | */ | ||
268 | usb_set_intfdata(intf, NULL); | ||
269 | 296 | ||
270 | shark->v4l2_dev.release = usb_shark_release; | 297 | shark->v4l2_dev.release = usb_shark_release; |
271 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
272 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 298 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
273 | if (retval) { | 299 | if (retval) { |
274 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 300 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
292 | goto err_init_tea; | 318 | goto err_init_tea; |
293 | } | 319 | } |
294 | 320 | ||
295 | INIT_WORK(&shark->led_work, shark_led_work); | ||
296 | for (i = 0; i < NO_LEDS; i++) { | ||
297 | shark->leds[i] = shark_led_templates[i]; | ||
298 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
299 | shark->leds[i].name, shark->v4l2_dev.name); | ||
300 | shark->leds[i].name = shark->led_names[i]; | ||
301 | /* | ||
302 | * We don't fail the probe if we fail to register the leds, | ||
303 | * because once we've called radio_tea5777_init, the /dev/radio0 | ||
304 | * node may be opened from userspace holding a reference to us! | ||
305 | * | ||
306 | * Note we cannot register the leds first instead as | ||
307 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
308 | */ | ||
309 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
310 | if (retval) | ||
311 | v4l2_err(&shark->v4l2_dev, | ||
312 | "couldn't register led: %s\n", | ||
313 | shark->led_names[i]); | ||
314 | } | ||
315 | |||
316 | return 0; | 321 | return 0; |
317 | 322 | ||
318 | err_init_tea: | 323 | err_init_tea: |
319 | v4l2_device_unregister(&shark->v4l2_dev); | 324 | v4l2_device_unregister(&shark->v4l2_dev); |
320 | err_reg_dev: | 325 | err_reg_dev: |
326 | shark_unregister_leds(shark); | ||
327 | err_reg_leds: | ||
321 | kfree(shark->transfer_buffer); | 328 | kfree(shark->transfer_buffer); |
322 | err_alloc_buffer: | 329 | err_alloc_buffer: |
323 | kfree(shark); | 330 | kfree(shark); |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9e38132afec6..9bb65e170d99 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
151 | .index = 0, | 151 | .index = 0, |
152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
154 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
154 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 155 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
155 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 156 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
156 | .rangelow = 87500 * 16, | 157 | .rangelow = 87500 * 16, |
@@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
162 | .index = 1, | 163 | .index = 1, |
163 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 164 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
164 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 165 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
166 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
165 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 167 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
166 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 168 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
167 | .rangelow = 76000 * 16, | 169 | .rangelow = 76000 * 16, |
@@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
173 | .index = 2, | 175 | .index = 2, |
174 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 176 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
175 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 177 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
178 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
176 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 179 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
177 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 180 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
178 | .rangelow = 76000 * 16, | 181 | .rangelow = 76000 * 16, |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 643a6ff7c5d0..f867f04cccc9 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
225 | { | 225 | { |
226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); | 226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); |
227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
228 | capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | | 228 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO; | 229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
230 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
230 | 231 | ||
231 | return 0; | 232 | return 0; |
232 | } | 233 | } |
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 146be4263ea1..be076f7181e7 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
532 | usb_make_path(radio->usbdev, capability->bus_info, | 532 | usb_make_path(radio->usbdev, capability->bus_info, |
533 | sizeof(capability->bus_info)); | 533 | sizeof(capability->bus_info)); |
534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | | 534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; | 535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | 536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; |
537 | return 0; | 537 | return 0; |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 5180390be7ab..8be57634ba60 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -261,6 +261,7 @@ config IR_WINBOND_CIR | |||
261 | 261 | ||
262 | config IR_IGUANA | 262 | config IR_IGUANA |
263 | tristate "IguanaWorks USB IR Transceiver" | 263 | tristate "IguanaWorks USB IR Transceiver" |
264 | depends on USB_ARCH_HAS_HCD | ||
264 | depends on RC_CORE | 265 | depends on RC_CORE |
265 | select USB | 266 | select USB |
266 | ---help--- | 267 | ---help--- |
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c index cf9d9fca5b84..234777116e5f 100644 --- a/drivers/media/video/gspca/jl2005bcd.c +++ b/drivers/media/video/gspca/jl2005bcd.c | |||
@@ -512,7 +512,7 @@ static const struct sd_desc sd_desc = { | |||
512 | }; | 512 | }; |
513 | 513 | ||
514 | /* -- module initialisation -- */ | 514 | /* -- module initialisation -- */ |
515 | static const __devinitdata struct usb_device_id device_table[] = { | 515 | static const struct usb_device_id device_table[] = { |
516 | {USB_DEVICE(0x0979, 0x0227)}, | 516 | {USB_DEVICE(0x0979, 0x0227)}, |
517 | {} | 517 | {} |
518 | }; | 518 | }; |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 969bb5a4cd93..bab01c86c315 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -579,7 +579,7 @@ static const struct sd_desc sd_desc = { | |||
579 | }; | 579 | }; |
580 | 580 | ||
581 | /* -- module initialisation -- */ | 581 | /* -- module initialisation -- */ |
582 | static const struct usb_device_id device_table[] __devinitconst = { | 582 | static const struct usb_device_id device_table[] = { |
583 | {USB_DEVICE(0x06e1, 0xa190)}, | 583 | {USB_DEVICE(0x06e1, 0xa190)}, |
584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 | 584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 |
585 | {USB_DEVICE(0x0733, 0x0430)}, */ | 585 | {USB_DEVICE(0x0733, 0x0430)}, */ |
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 7efe9ad7acc7..0b91a5cd38eb 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c | |||
@@ -431,7 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); | 431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); |
432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); | 432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); |
433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); | 433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); |
434 | cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | 434 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; |
435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
436 | return 0; | 436 | return 0; |
437 | } | 437 | } |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index d2e6f82ecfac..560a65aa7038 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -403,7 +403,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
403 | 403 | ||
404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); | 404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); |
405 | 405 | ||
406 | clk_enable(pcdev->clk); | 406 | clk_prepare_enable(pcdev->clk); |
407 | 407 | ||
408 | /* enable CSI before doing anything else */ | 408 | /* enable CSI before doing anything else */ |
409 | __raw_writel(csicr1, pcdev->base + CSICR1); | 409 | __raw_writel(csicr1, pcdev->base + CSICR1); |
@@ -422,7 +422,7 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | |||
422 | /* Disable all CSI interface */ | 422 | /* Disable all CSI interface */ |
423 | __raw_writel(0x00, pcdev->base + CSICR1); | 423 | __raw_writel(0x00, pcdev->base + CSICR1); |
424 | 424 | ||
425 | clk_disable(pcdev->clk); | 425 | clk_disable_unprepare(pcdev->clk); |
426 | } | 426 | } |
427 | 427 | ||
428 | /* | 428 | /* |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 637bde8aca28..ac175406e582 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -272,7 +272,7 @@ struct mx2_camera_dev { | |||
272 | struct device *dev; | 272 | struct device *dev; |
273 | struct soc_camera_host soc_host; | 273 | struct soc_camera_host soc_host; |
274 | struct soc_camera_device *icd; | 274 | struct soc_camera_device *icd; |
275 | struct clk *clk_csi, *clk_emma; | 275 | struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg; |
276 | 276 | ||
277 | unsigned int irq_csi, irq_emma; | 277 | unsigned int irq_csi, irq_emma; |
278 | void __iomem *base_csi, *base_emma; | 278 | void __iomem *base_csi, *base_emma; |
@@ -407,7 +407,7 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) | |||
407 | { | 407 | { |
408 | unsigned long flags; | 408 | unsigned long flags; |
409 | 409 | ||
410 | clk_disable(pcdev->clk_csi); | 410 | clk_disable_unprepare(pcdev->clk_csi); |
411 | writel(0, pcdev->base_csi + CSICR1); | 411 | writel(0, pcdev->base_csi + CSICR1); |
412 | if (cpu_is_mx27()) { | 412 | if (cpu_is_mx27()) { |
413 | writel(0, pcdev->base_emma + PRP_CNTL); | 413 | writel(0, pcdev->base_emma + PRP_CNTL); |
@@ -435,7 +435,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) | |||
435 | if (pcdev->icd) | 435 | if (pcdev->icd) |
436 | return -EBUSY; | 436 | return -EBUSY; |
437 | 437 | ||
438 | ret = clk_enable(pcdev->clk_csi); | 438 | ret = clk_prepare_enable(pcdev->clk_csi); |
439 | if (ret < 0) | 439 | if (ret < 0) |
440 | return ret; | 440 | return ret; |
441 | 441 | ||
@@ -1633,23 +1633,34 @@ static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev) | |||
1633 | goto exit_iounmap; | 1633 | goto exit_iounmap; |
1634 | } | 1634 | } |
1635 | 1635 | ||
1636 | pcdev->clk_emma = clk_get(NULL, "emma"); | 1636 | pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg"); |
1637 | if (IS_ERR(pcdev->clk_emma)) { | 1637 | if (IS_ERR(pcdev->clk_emma_ipg)) { |
1638 | err = PTR_ERR(pcdev->clk_emma); | 1638 | err = PTR_ERR(pcdev->clk_emma_ipg); |
1639 | goto exit_free_irq; | 1639 | goto exit_free_irq; |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | clk_enable(pcdev->clk_emma); | 1642 | clk_prepare_enable(pcdev->clk_emma_ipg); |
1643 | |||
1644 | pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb"); | ||
1645 | if (IS_ERR(pcdev->clk_emma_ahb)) { | ||
1646 | err = PTR_ERR(pcdev->clk_emma_ahb); | ||
1647 | goto exit_clk_emma_ipg_put; | ||
1648 | } | ||
1649 | |||
1650 | clk_prepare_enable(pcdev->clk_emma_ahb); | ||
1643 | 1651 | ||
1644 | err = mx27_camera_emma_prp_reset(pcdev); | 1652 | err = mx27_camera_emma_prp_reset(pcdev); |
1645 | if (err) | 1653 | if (err) |
1646 | goto exit_clk_emma_put; | 1654 | goto exit_clk_emma_ahb_put; |
1647 | 1655 | ||
1648 | return err; | 1656 | return err; |
1649 | 1657 | ||
1650 | exit_clk_emma_put: | 1658 | exit_clk_emma_ahb_put: |
1651 | clk_disable(pcdev->clk_emma); | 1659 | clk_disable_unprepare(pcdev->clk_emma_ahb); |
1652 | clk_put(pcdev->clk_emma); | 1660 | clk_put(pcdev->clk_emma_ahb); |
1661 | exit_clk_emma_ipg_put: | ||
1662 | clk_disable_unprepare(pcdev->clk_emma_ipg); | ||
1663 | clk_put(pcdev->clk_emma_ipg); | ||
1653 | exit_free_irq: | 1664 | exit_free_irq: |
1654 | free_irq(pcdev->irq_emma, pcdev); | 1665 | free_irq(pcdev->irq_emma, pcdev); |
1655 | exit_iounmap: | 1666 | exit_iounmap: |
@@ -1685,7 +1696,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1685 | goto exit; | 1696 | goto exit; |
1686 | } | 1697 | } |
1687 | 1698 | ||
1688 | pcdev->clk_csi = clk_get(&pdev->dev, NULL); | 1699 | pcdev->clk_csi = clk_get(&pdev->dev, "ahb"); |
1689 | if (IS_ERR(pcdev->clk_csi)) { | 1700 | if (IS_ERR(pcdev->clk_csi)) { |
1690 | dev_err(&pdev->dev, "Could not get csi clock\n"); | 1701 | dev_err(&pdev->dev, "Could not get csi clock\n"); |
1691 | err = PTR_ERR(pcdev->clk_csi); | 1702 | err = PTR_ERR(pcdev->clk_csi); |
@@ -1785,8 +1796,10 @@ exit_free_emma: | |||
1785 | eallocctx: | 1796 | eallocctx: |
1786 | if (cpu_is_mx27()) { | 1797 | if (cpu_is_mx27()) { |
1787 | free_irq(pcdev->irq_emma, pcdev); | 1798 | free_irq(pcdev->irq_emma, pcdev); |
1788 | clk_disable(pcdev->clk_emma); | 1799 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1789 | clk_put(pcdev->clk_emma); | 1800 | clk_put(pcdev->clk_emma_ipg); |
1801 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1802 | clk_put(pcdev->clk_emma_ahb); | ||
1790 | iounmap(pcdev->base_emma); | 1803 | iounmap(pcdev->base_emma); |
1791 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); | 1804 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); |
1792 | } | 1805 | } |
@@ -1825,8 +1838,10 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev) | |||
1825 | iounmap(pcdev->base_csi); | 1838 | iounmap(pcdev->base_csi); |
1826 | 1839 | ||
1827 | if (cpu_is_mx27()) { | 1840 | if (cpu_is_mx27()) { |
1828 | clk_disable(pcdev->clk_emma); | 1841 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1829 | clk_put(pcdev->clk_emma); | 1842 | clk_put(pcdev->clk_emma_ipg); |
1843 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1844 | clk_put(pcdev->clk_emma_ahb); | ||
1830 | iounmap(pcdev->base_emma); | 1845 | iounmap(pcdev->base_emma); |
1831 | res = pcdev->res_emma; | 1846 | res = pcdev->res_emma; |
1832 | release_mem_region(res->start, resource_size(res)); | 1847 | release_mem_region(res->start, resource_size(res)); |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index f13643d31353..af2297dd49c8 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -61,15 +61,9 @@ | |||
61 | 61 | ||
62 | #define MAX_VIDEO_MEM 16 | 62 | #define MAX_VIDEO_MEM 16 |
63 | 63 | ||
64 | enum csi_buffer_state { | ||
65 | CSI_BUF_NEEDS_INIT, | ||
66 | CSI_BUF_PREPARED, | ||
67 | }; | ||
68 | |||
69 | struct mx3_camera_buffer { | 64 | struct mx3_camera_buffer { |
70 | /* common v4l buffer stuff -- must be first */ | 65 | /* common v4l buffer stuff -- must be first */ |
71 | struct vb2_buffer vb; | 66 | struct vb2_buffer vb; |
72 | enum csi_buffer_state state; | ||
73 | struct list_head queue; | 67 | struct list_head queue; |
74 | 68 | ||
75 | /* One descriptot per scatterlist (per frame) */ | 69 | /* One descriptot per scatterlist (per frame) */ |
@@ -285,7 +279,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
285 | goto error; | 279 | goto error; |
286 | } | 280 | } |
287 | 281 | ||
288 | if (buf->state == CSI_BUF_NEEDS_INIT) { | 282 | if (!buf->txd) { |
289 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); | 283 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); |
290 | sg_dma_len(sg) = new_size; | 284 | sg_dma_len(sg) = new_size; |
291 | 285 | ||
@@ -298,7 +292,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
298 | txd->callback_param = txd; | 292 | txd->callback_param = txd; |
299 | txd->callback = mx3_cam_dma_done; | 293 | txd->callback = mx3_cam_dma_done; |
300 | 294 | ||
301 | buf->state = CSI_BUF_PREPARED; | ||
302 | buf->txd = txd; | 295 | buf->txd = txd; |
303 | } else { | 296 | } else { |
304 | txd = buf->txd; | 297 | txd = buf->txd; |
@@ -385,7 +378,6 @@ static void mx3_videobuf_release(struct vb2_buffer *vb) | |||
385 | 378 | ||
386 | /* Doesn't hurt also if the list is empty */ | 379 | /* Doesn't hurt also if the list is empty */ |
387 | list_del_init(&buf->queue); | 380 | list_del_init(&buf->queue); |
388 | buf->state = CSI_BUF_NEEDS_INIT; | ||
389 | 381 | ||
390 | if (txd) { | 382 | if (txd) { |
391 | buf->txd = NULL; | 383 | buf->txd = NULL; |
@@ -405,13 +397,13 @@ static int mx3_videobuf_init(struct vb2_buffer *vb) | |||
405 | struct mx3_camera_dev *mx3_cam = ici->priv; | 397 | struct mx3_camera_dev *mx3_cam = ici->priv; |
406 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); | 398 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); |
407 | 399 | ||
408 | /* This is for locking debugging only */ | 400 | if (!buf->txd) { |
409 | INIT_LIST_HEAD(&buf->queue); | 401 | /* This is for locking debugging only */ |
410 | sg_init_table(&buf->sg, 1); | 402 | INIT_LIST_HEAD(&buf->queue); |
403 | sg_init_table(&buf->sg, 1); | ||
411 | 404 | ||
412 | buf->state = CSI_BUF_NEEDS_INIT; | 405 | mx3_cam->buf_total += vb2_plane_size(vb, 0); |
413 | 406 | } | |
414 | mx3_cam->buf_total += vb2_plane_size(vb, 0); | ||
415 | 407 | ||
416 | return 0; | 408 | return 0; |
417 | } | 409 | } |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b03ffecb7438..1bde255e45df 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -171,7 +171,8 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, | |||
171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", | 171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", |
172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); | 172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); |
173 | 173 | ||
174 | if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | 174 | if (pix->pixelformat != V4L2_PIX_FMT_JPEG && |
175 | !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | ||
175 | pix->bytesperline = 0; | 176 | pix->bytesperline = 0; |
176 | pix->sizeimage = 0; | 177 | pix->sizeimage = 0; |
177 | } | 178 | } |
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c index 89dce097a827..a397812635d6 100644 --- a/drivers/media/video/soc_mediabus.c +++ b/drivers/media/video/soc_mediabus.c | |||
@@ -378,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel); | |||
378 | 378 | ||
379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) | 379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) |
380 | { | 380 | { |
381 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
382 | return 0; | ||
383 | |||
381 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) | 384 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) |
382 | return width * mf->bits_per_sample / 8; | 385 | return width * mf->bits_per_sample / 8; |
383 | 386 | ||
@@ -400,6 +403,9 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line); | |||
400 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, | 403 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, |
401 | u32 bytes_per_line, u32 height) | 404 | u32 bytes_per_line, u32 height) |
402 | { | 405 | { |
406 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
407 | return 0; | ||
408 | |||
403 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) | 409 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) |
404 | return bytes_per_line * height; | 410 | return bytes_per_line * height; |
405 | 411 | ||
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 9288fbd5001b..5577381b5bf0 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -338,6 +338,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { | 338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { |
339 | buf->error = 0; | 339 | buf->error = 0; |
340 | buf->state = UVC_BUF_STATE_QUEUED; | 340 | buf->state = UVC_BUF_STATE_QUEUED; |
341 | buf->bytesused = 0; | ||
341 | vb2_set_plane_payload(&buf->buf, 0, 0); | 342 | vb2_set_plane_payload(&buf->buf, 0, 0); |
342 | return buf; | 343 | return buf; |
343 | } | 344 | } |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index c3b7b5f59b32..6bc47fc82fe2 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -402,8 +402,10 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only) | |||
402 | { | 402 | { |
403 | const struct v4l2_hw_freq_seek *p = arg; | 403 | const struct v4l2_hw_freq_seek *p = arg; |
404 | 404 | ||
405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", | 405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, " |
406 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); | 406 | "rangelow=%u, rangehigh=%u\n", |
407 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, | ||
408 | p->rangelow, p->rangehigh); | ||
407 | } | 409 | } |
408 | 410 | ||
409 | static void v4l_print_requestbuffers(const void *arg, bool write_only) | 411 | static void v4l_print_requestbuffers(const void *arg, bool write_only) |
@@ -1853,6 +1855,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1853 | .type = type, | 1855 | .type = type, |
1854 | }; | 1856 | }; |
1855 | 1857 | ||
1858 | if (p->index) | ||
1859 | return -EINVAL; | ||
1856 | err = ops->vidioc_g_tuner(file, fh, &t); | 1860 | err = ops->vidioc_g_tuner(file, fh, &t); |
1857 | if (err) | 1861 | if (err) |
1858 | return err; | 1862 | return err; |
@@ -1870,6 +1874,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1870 | 1874 | ||
1871 | if (type != V4L2_TUNER_RADIO) | 1875 | if (type != V4L2_TUNER_RADIO) |
1872 | return -EINVAL; | 1876 | return -EINVAL; |
1877 | if (p->index) | ||
1878 | return -EINVAL; | ||
1873 | err = ops->vidioc_g_modulator(file, fh, &m); | 1879 | err = ops->vidioc_g_modulator(file, fh, &m); |
1874 | if (err) | 1880 | if (err) |
1875 | return err; | 1881 | return err; |
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index b67a3018b136..ce229ea933d1 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c | |||
@@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
470 | 470 | ||
471 | ret = | 471 | ret = |
472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0); | 473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0, |
474 | NULL); | ||
474 | if (ret < 0) { | 475 | if (ret < 0) { |
475 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 476 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
476 | goto out_dev; | 477 | goto out_dev; |
@@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
481 | rtc_devs[0].platform_data = pdata->rtc; | 482 | rtc_devs[0].platform_data = pdata->rtc; |
482 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); | 483 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); |
483 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 484 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
484 | ARRAY_SIZE(rtc_devs), NULL, 0); | 485 | ARRAY_SIZE(rtc_devs), NULL, 0, NULL); |
485 | if (ret < 0) { | 486 | if (ret < 0) { |
486 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 487 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
487 | goto out_dev; | 488 | goto out_dev; |
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 6146583589f6..c20a31136f04 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c | |||
@@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
220 | NULL); | ||
220 | if (ret < 0) { | 221 | if (ret < 0) { |
221 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 222 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
222 | goto out_codec; | 223 | goto out_codec; |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index d09918cf1b15..b73f033b2c60 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip, | |||
637 | bk_devs[i].resources = &bk_resources[j]; | 637 | bk_devs[i].resources = &bk_resources[j]; |
638 | ret = mfd_add_devices(chip->dev, 0, | 638 | ret = mfd_add_devices(chip->dev, 0, |
639 | &bk_devs[i], 1, | 639 | &bk_devs[i], 1, |
640 | &bk_resources[j], 0); | 640 | &bk_resources[j], 0, NULL); |
641 | if (ret < 0) { | 641 | if (ret < 0) { |
642 | dev_err(chip->dev, "Failed to add " | 642 | dev_err(chip->dev, "Failed to add " |
643 | "backlight subdev\n"); | 643 | "backlight subdev\n"); |
@@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip, | |||
672 | led_devs[i].resources = &led_resources[j], | 672 | led_devs[i].resources = &led_resources[j], |
673 | ret = mfd_add_devices(chip->dev, 0, | 673 | ret = mfd_add_devices(chip->dev, 0, |
674 | &led_devs[i], 1, | 674 | &led_devs[i], 1, |
675 | &led_resources[j], 0); | 675 | &led_resources[j], 0, NULL); |
676 | if (ret < 0) { | 676 | if (ret < 0) { |
677 | dev_err(chip->dev, "Failed to add " | 677 | dev_err(chip->dev, "Failed to add " |
678 | "led subdev\n"); | 678 | "led subdev\n"); |
@@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip, | |||
709 | regulator_devs[i].resources = ®ulator_resources[seq]; | 709 | regulator_devs[i].resources = ®ulator_resources[seq]; |
710 | 710 | ||
711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, | 711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, |
712 | ®ulator_resources[seq], 0); | 712 | ®ulator_resources[seq], 0, NULL); |
713 | if (ret < 0) { | 713 | if (ret < 0) { |
714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
715 | goto out; | 715 | goto out; |
@@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip, | |||
733 | rtc_devs[0].resources = &rtc_resources[0]; | 733 | rtc_devs[0].resources = &rtc_resources[0]; |
734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], | 735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], |
736 | chip->irq_base); | 736 | chip->irq_base, NULL); |
737 | if (ret < 0) | 737 | if (ret < 0) |
738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
739 | } | 739 | } |
@@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip, | |||
752 | touch_devs[0].resources = &touch_resources[0]; | 752 | touch_devs[0].resources = &touch_resources[0]; |
753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
754 | ARRAY_SIZE(touch_devs), &touch_resources[0], | 754 | ARRAY_SIZE(touch_devs), &touch_resources[0], |
755 | chip->irq_base); | 755 | chip->irq_base, NULL); |
756 | if (ret < 0) | 756 | if (ret < 0) |
757 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 757 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
758 | } | 758 | } |
@@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); | 770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); |
771 | power_devs[0].resources = &battery_resources[0], | 771 | power_devs[0].resources = &battery_resources[0], |
772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, | 772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, |
773 | &battery_resources[0], chip->irq_base); | 773 | &battery_resources[0], chip->irq_base, NULL); |
774 | if (ret < 0) | 774 | if (ret < 0) |
775 | dev_err(chip->dev, "Failed to add battery subdev\n"); | 775 | dev_err(chip->dev, "Failed to add battery subdev\n"); |
776 | 776 | ||
@@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); | 779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); |
780 | power_devs[1].resources = &charger_resources[0], | 780 | power_devs[1].resources = &charger_resources[0], |
781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, | 781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, |
782 | &charger_resources[0], chip->irq_base); | 782 | &charger_resources[0], chip->irq_base, NULL); |
783 | if (ret < 0) | 783 | if (ret < 0) |
784 | dev_err(chip->dev, "Failed to add charger subdev\n"); | 784 | dev_err(chip->dev, "Failed to add charger subdev\n"); |
785 | 785 | ||
@@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); | 788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); |
789 | power_devs[2].resources = &preg_resources[0], | 789 | power_devs[2].resources = &preg_resources[0], |
790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, | 790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, |
791 | &preg_resources[0], chip->irq_base); | 791 | &preg_resources[0], chip->irq_base, NULL); |
792 | if (ret < 0) | 792 | if (ret < 0) |
793 | dev_err(chip->dev, "Failed to add preg subdev\n"); | 793 | dev_err(chip->dev, "Failed to add preg subdev\n"); |
794 | } | 794 | } |
@@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip, | |||
802 | onkey_devs[0].resources = &onkey_resources[0], | 802 | onkey_devs[0].resources = &onkey_resources[0], |
803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], | 804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], |
805 | chip->irq_base); | 805 | chip->irq_base, NULL); |
806 | if (ret < 0) | 806 | if (ret < 0) |
807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
808 | } | 808 | } |
@@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip, | |||
815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); | 815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); |
816 | codec_devs[0].resources = &codec_resources[0], | 816 | codec_devs[0].resources = &codec_resources[0], |
817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
819 | NULL); | ||
819 | if (ret < 0) | 820 | if (ret < 0) |
820 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 821 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
821 | } | 822 | } |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d1facef28a60..b1a146205c08 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -395,7 +395,8 @@ config MFD_TC6387XB | |||
395 | 395 | ||
396 | config MFD_TC6393XB | 396 | config MFD_TC6393XB |
397 | bool "Support Toshiba TC6393XB" | 397 | bool "Support Toshiba TC6393XB" |
398 | depends on GPIOLIB && ARM && HAVE_CLK | 398 | depends on ARM && HAVE_CLK |
399 | select GPIOLIB | ||
399 | select MFD_CORE | 400 | select MFD_CORE |
400 | select MFD_TMIO | 401 | select MFD_TMIO |
401 | help | 402 | help |
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 44a3fdbadef4..f1beb4971f87 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client, | |||
424 | } | 424 | } |
425 | 425 | ||
426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, | 426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, |
427 | ARRAY_SIZE(aat2870_devs), NULL, 0); | 427 | ARRAY_SIZE(aat2870_devs), NULL, 0, NULL); |
428 | if (ret != 0) { | 428 | if (ret != 0) { |
429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); | 429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); |
430 | goto out_disable; | 430 | goto out_disable; |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 78fca2902c8d..01781ae5d0d7 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client, | |||
946 | } | 946 | } |
947 | 947 | ||
948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, | 948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, |
949 | ARRAY_SIZE(ab3100_devs), NULL, 0); | 949 | ARRAY_SIZE(ab3100_devs), NULL, 0, NULL); |
950 | 950 | ||
951 | ab3100_setup_debugfs(ab3100); | 951 | ab3100_setup_debugfs(ab3100); |
952 | 952 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 626b4ecaf647..47adf800024e 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1418 | 1418 | ||
1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, | 1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, |
1420 | ARRAY_SIZE(abx500_common_devs), NULL, | 1420 | ARRAY_SIZE(abx500_common_devs), NULL, |
1421 | ab8500->irq_base); | 1421 | ab8500->irq_base, ab8500->domain); |
1422 | if (ret) | 1422 | if (ret) |
1423 | goto out_freeirq; | 1423 | goto out_freeirq; |
1424 | 1424 | ||
1425 | if (is_ab9540(ab8500)) | 1425 | if (is_ab9540(ab8500)) |
1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | 1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, |
1427 | ARRAY_SIZE(ab9540_devs), NULL, | 1427 | ARRAY_SIZE(ab9540_devs), NULL, |
1428 | ab8500->irq_base); | 1428 | ab8500->irq_base, ab8500->domain); |
1429 | else | 1429 | else |
1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | 1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, |
1431 | ARRAY_SIZE(ab8500_devs), NULL, | 1431 | ARRAY_SIZE(ab8500_devs), NULL, |
1432 | ab8500->irq_base); | 1432 | ab8500->irq_base, ab8500->domain); |
1433 | if (ret) | 1433 | if (ret) |
1434 | goto out_freeirq; | 1434 | goto out_freeirq; |
1435 | 1435 | ||
1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) | 1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) |
1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, | 1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, |
1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, | 1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, |
1439 | ab8500->irq_base); | 1439 | ab8500->irq_base, ab8500->domain); |
1440 | if (ret) | 1440 | if (ret) |
1441 | goto out_freeirq; | 1441 | goto out_freeirq; |
1442 | 1442 | ||
@@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1444 | /* Add battery management devices */ | 1444 | /* Add battery management devices */ |
1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, | 1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, |
1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, | 1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, |
1447 | ab8500->irq_base); | 1447 | ab8500->irq_base, ab8500->domain); |
1448 | if (ret) | 1448 | if (ret) |
1449 | dev_err(ab8500->dev, "error adding bm devices\n"); | 1449 | dev_err(ab8500->dev, "error adding bm devices\n"); |
1450 | } | 1450 | } |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c7983e862549..1b48f2094806 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, | 318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, |
319 | ARRAY_SIZE(early_devs), NULL, 0); | 319 | ARRAY_SIZE(early_devs), NULL, 0, NULL); |
320 | if (ret != 0) { | 320 | if (ret != 0) { |
321 | dev_err(dev, "Failed to add early children: %d\n", ret); | 321 | dev_err(dev, "Failed to add early children: %d\n", ret); |
322 | return ret; | 322 | return ret; |
@@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
516 | switch (arizona->type) { | 516 | switch (arizona->type) { |
517 | case WM5102: | 517 | case WM5102: |
518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, | 518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, |
519 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 519 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
520 | break; | 520 | break; |
521 | case WM5110: | 521 | case WM5110: |
522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, | 522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, |
523 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 523 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
524 | break; | 524 | break; |
525 | } | 525 | } |
526 | 526 | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 383421bf5760..62f0883a7630 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -913,18 +913,19 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
913 | if (pdata->clock_rate) { | 913 | if (pdata->clock_rate) { |
914 | ds1wm_pdata.clock_rate = pdata->clock_rate; | 914 | ds1wm_pdata.clock_rate = pdata->clock_rate; |
915 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 915 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base); | 916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); |
917 | if (ret < 0) | 917 | if (ret < 0) |
918 | goto out; | 918 | goto out; |
919 | } | 919 | } |
920 | 920 | ||
921 | if (mem_sdio && (irq >= 0)) { | 921 | if (mem_sdio && (irq >= 0)) { |
922 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 922 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
923 | &asic3_cell_mmc, 1, mem_sdio, irq); | 923 | &asic3_cell_mmc, 1, mem_sdio, irq, NULL); |
924 | if (ret < 0) | 924 | if (ret < 0) |
925 | goto out; | 925 | goto out; |
926 | } | 926 | } |
927 | 927 | ||
928 | ret = 0; | ||
928 | if (pdata->leds) { | 929 | if (pdata->leds) { |
929 | int i; | 930 | int i; |
930 | 931 | ||
@@ -933,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
933 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); | 934 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); |
934 | } | 935 | } |
935 | ret = mfd_add_devices(&pdev->dev, 0, | 936 | ret = mfd_add_devices(&pdev->dev, 0, |
936 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); | 937 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); |
937 | } | 938 | } |
938 | 939 | ||
939 | out: | 940 | out: |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 3419e726de47..2b282133c725 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, | 151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, |
152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); | 152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL); |
153 | if (err) { | 153 | if (err) { |
154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | 154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); |
155 | goto err_disable; | 155 | goto err_disable; |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 2544910e1fd6..a0a62b24621b 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); | 803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); |
804 | 804 | ||
805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | 805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, |
806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); | 806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); |
807 | if (ret) | 807 | if (ret) |
808 | goto err; | 808 | goto err; |
809 | 809 | ||
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 4e2af2cb2d26..45e83a68641b 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c | |||
@@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) | |||
129 | cell->pdata_size = sizeof(*davinci_vc); | 129 | cell->pdata_size = sizeof(*davinci_vc); |
130 | 130 | ||
131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, | 131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, |
132 | DAVINCI_VC_CELLS, NULL, 0); | 132 | DAVINCI_VC_CELLS, NULL, 0, NULL); |
133 | if (ret != 0) { | 133 | if (ret != 0) { |
134 | dev_err(&pdev->dev, "fail to register client devices\n"); | 134 | dev_err(&pdev->dev, "fail to register client devices\n"); |
135 | goto fail4; | 135 | goto fail4; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a0081130..0e63cdd9b52a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -3010,7 +3010,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev) | |||
3010 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); | 3010 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); |
3011 | 3011 | ||
3012 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, | 3012 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, |
3013 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); | 3013 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); |
3014 | if (err) { | 3014 | if (err) { |
3015 | pr_err("prcmu: Failed to add subdevices\n"); | 3015 | pr_err("prcmu: Failed to add subdevices\n"); |
3016 | return err; | 3016 | return err; |
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 43a76c41cfcc..db662e2dcfa5 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
@@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work) | |||
202 | } | 202 | } |
203 | local_irq_enable(); | 203 | local_irq_enable(); |
204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); | 204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); |
205 | } while (gpio_get_value(irq_to_gpio(pcap->spi->irq))); | 205 | } while (gpio_get_value(pdata->gpio)); |
206 | } | 206 | } |
207 | 207 | ||
208 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | 208 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 04c7093d6499..9e5453d21a68 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c | |||
@@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
168 | /* the first 5 PASIC3 registers control the DS1WM */ | 168 | /* the first 5 PASIC3 registers control the DS1WM */ |
169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; | 169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; |
170 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 170 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
171 | &ds1wm_cell, 1, r, irq); | 171 | &ds1wm_cell, 1, r, irq, NULL); |
172 | if (ret < 0) | 172 | if (ret < 0) |
173 | dev_warn(dev, "failed to register DS1WM\n"); | 173 | dev_warn(dev, "failed to register DS1WM\n"); |
174 | } | 174 | } |
@@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
176 | if (pdata && pdata->led_pdata) { | 176 | if (pdata && pdata->led_pdata) { |
177 | led_cell.platform_data = pdata->led_pdata; | 177 | led_cell.platform_data = pdata->led_pdata; |
178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); | 178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); |
179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); | 179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, |
180 | 0, NULL); | ||
180 | if (ret < 0) | 181 | if (ret < 0) |
181 | dev_warn(dev, "failed to register LED device\n"); | 182 | dev_warn(dev, "failed to register LED device\n"); |
182 | } | 183 | } |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 59df5584cb58..266bdc5bd96d 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c | |||
@@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic) | |||
344 | continue; | 344 | continue; |
345 | 345 | ||
346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, | 346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, |
347 | pdata->irq[i]); | 347 | pdata->irq[i], NULL); |
348 | if (ret) | 348 | if (ret) |
349 | goto fail; | 349 | goto fail; |
350 | } | 350 | } |
351 | 351 | ||
352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, | 352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, |
353 | ARRAY_SIZE(msic_other_devs), NULL, 0); | 353 | ARRAY_SIZE(msic_other_devs), NULL, 0, NULL); |
354 | if (ret) | 354 | if (ret) |
355 | goto fail; | 355 | goto fail; |
356 | 356 | ||
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 2ea99989551a..965c4801df8a 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c | |||
@@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv) | |||
147 | } | 147 | } |
148 | 148 | ||
149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, | 149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, |
150 | num_probed, NULL, pdev->irq); | 150 | num_probed, NULL, pdev->irq, NULL); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* | 153 | /* |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 87662a17dec6..c6b6d7dda517 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev) | |||
287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); | 287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); |
288 | 288 | ||
289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, | 289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, |
290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); | 290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, |
291 | irq_base, NULL); | ||
291 | if (ret < 0) | 292 | if (ret < 0) |
292 | goto err_clk_put; | 293 | goto err_clk_put; |
293 | 294 | ||
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0b2879b87fd9..24212f45b201 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c | |||
@@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533) | |||
393 | lm3533_als_devs[0].platform_data = pdata->als; | 393 | lm3533_als_devs[0].platform_data = pdata->als; |
394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); | 394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); |
395 | 395 | ||
396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); | 396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, |
397 | 0, NULL); | ||
397 | if (ret) { | 398 | if (ret) { |
398 | dev_err(lm3533->dev, "failed to add ALS device\n"); | 399 | dev_err(lm3533->dev, "failed to add ALS device\n"); |
399 | return ret; | 400 | return ret; |
@@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533) | |||
422 | } | 423 | } |
423 | 424 | ||
424 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, | 425 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, |
425 | pdata->num_backlights, NULL, 0); | 426 | pdata->num_backlights, NULL, 0, NULL); |
426 | if (ret) { | 427 | if (ret) { |
427 | dev_err(lm3533->dev, "failed to add backlight devices\n"); | 428 | dev_err(lm3533->dev, "failed to add backlight devices\n"); |
428 | return ret; | 429 | return ret; |
@@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533) | |||
451 | } | 452 | } |
452 | 453 | ||
453 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, | 454 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, |
454 | pdata->num_leds, NULL, 0); | 455 | pdata->num_leds, NULL, 0, NULL); |
455 | if (ret) { | 456 | if (ret) { |
456 | dev_err(lm3533->dev, "failed to add LED devices\n"); | 457 | dev_err(lm3533->dev, "failed to add LED devices\n"); |
457 | return ret; | 458 | return ret; |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 027cc8f86132..092ad4b44b6d 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -750,7 +750,7 @@ gpe0_done: | |||
750 | 750 | ||
751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); | 751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); |
752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], | 752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], |
753 | 1, NULL, 0); | 753 | 1, NULL, 0, NULL); |
754 | 754 | ||
755 | gpio_done: | 755 | gpio_done: |
756 | if (acpi_conflict) | 756 | if (acpi_conflict) |
@@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
765 | u32 base_addr_cfg; | 765 | u32 base_addr_cfg; |
766 | u32 base_addr; | 766 | u32 base_addr; |
767 | int ret; | 767 | int ret; |
768 | bool acpi_conflict = false; | ||
769 | struct resource *res; | 768 | struct resource *res; |
770 | 769 | ||
771 | /* Setup power management base register */ | 770 | /* Setup power management base register */ |
@@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
780 | res = wdt_io_res(ICH_RES_IO_TCO); | 779 | res = wdt_io_res(ICH_RES_IO_TCO); |
781 | res->start = base_addr + ACPIBASE_TCO_OFF; | 780 | res->start = base_addr + ACPIBASE_TCO_OFF; |
782 | res->end = base_addr + ACPIBASE_TCO_END; | 781 | res->end = base_addr + ACPIBASE_TCO_END; |
783 | ret = acpi_check_resource_conflict(res); | ||
784 | if (ret) { | ||
785 | acpi_conflict = true; | ||
786 | goto wdt_done; | ||
787 | } | ||
788 | 782 | ||
789 | res = wdt_io_res(ICH_RES_IO_SMI); | 783 | res = wdt_io_res(ICH_RES_IO_SMI); |
790 | res->start = base_addr + ACPIBASE_SMI_OFF; | 784 | res->start = base_addr + ACPIBASE_SMI_OFF; |
791 | res->end = base_addr + ACPIBASE_SMI_END; | 785 | res->end = base_addr + ACPIBASE_SMI_END; |
792 | ret = acpi_check_resource_conflict(res); | 786 | |
793 | if (ret) { | ||
794 | acpi_conflict = true; | ||
795 | goto wdt_done; | ||
796 | } | ||
797 | lpc_ich_enable_acpi_space(dev); | 787 | lpc_ich_enable_acpi_space(dev); |
798 | 788 | ||
799 | /* | 789 | /* |
@@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
813 | res = wdt_mem_res(ICH_RES_MEM_GCS); | 803 | res = wdt_mem_res(ICH_RES_MEM_GCS); |
814 | res->start = base_addr + ACPIBASE_GCS_OFF; | 804 | res->start = base_addr + ACPIBASE_GCS_OFF; |
815 | res->end = base_addr + ACPIBASE_GCS_END; | 805 | res->end = base_addr + ACPIBASE_GCS_END; |
816 | ret = acpi_check_resource_conflict(res); | ||
817 | if (ret) { | ||
818 | acpi_conflict = true; | ||
819 | goto wdt_done; | ||
820 | } | ||
821 | } | 806 | } |
822 | 807 | ||
823 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); | 808 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); |
824 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], | 809 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], |
825 | 1, NULL, 0); | 810 | 1, NULL, 0, NULL); |
826 | 811 | ||
827 | wdt_done: | 812 | wdt_done: |
828 | if (acpi_conflict) | ||
829 | pr_warn("Resource conflict(s) found affecting %s\n", | ||
830 | lpc_ich_cells[LPC_WDT].name); | ||
831 | return ret; | 813 | return ret; |
832 | } | 814 | } |
833 | 815 | ||
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 9f20abc5e393..f6b9c5c96b24 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
127 | lpc_sch_cells[i].id = id->device; | 127 | lpc_sch_cells[i].id = id->device; |
128 | 128 | ||
129 | ret = mfd_add_devices(&dev->dev, 0, | 129 | ret = mfd_add_devices(&dev->dev, 0, |
130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); | 130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, |
131 | 0, NULL); | ||
131 | if (ret) | 132 | if (ret) |
132 | goto out_dev; | 133 | goto out_dev; |
133 | 134 | ||
@@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
153 | tunnelcreek_cells[i].id = id->device; | 154 | tunnelcreek_cells[i].id = id->device; |
154 | 155 | ||
155 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, | 156 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, |
156 | ARRAY_SIZE(tunnelcreek_cells), NULL, 0); | 157 | ARRAY_SIZE(tunnelcreek_cells), NULL, |
158 | 0, NULL); | ||
157 | } | 159 | } |
158 | 160 | ||
159 | return ret; | 161 | return ret; |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index c03e12b51924..d9e24c849a00 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
126 | max77686_irq_init(max77686); | 126 | max77686_irq_init(max77686); |
127 | 127 | ||
128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, | 128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, |
129 | ARRAY_SIZE(max77686_devs), NULL, 0); | 129 | ARRAY_SIZE(max77686_devs), NULL, 0, NULL); |
130 | 130 | ||
131 | if (ret < 0) | 131 | if (ret < 0) |
132 | goto err_mfd; | 132 | goto err_mfd; |
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 2b403569e0a6..1029d018c739 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c | |||
@@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data) | |||
137 | const struct max77693_irq_data *irq_data = | 137 | const struct max77693_irq_data *irq_data = |
138 | irq_to_max77693_irq(max77693, data->irq); | 138 | irq_to_max77693_irq(max77693, data->irq); |
139 | 139 | ||
140 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
141 | return; | ||
142 | |||
140 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 143 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
141 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | 144 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; |
142 | else | 145 | else |
@@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data) | |||
149 | const struct max77693_irq_data *irq_data = | 152 | const struct max77693_irq_data *irq_data = |
150 | irq_to_max77693_irq(max77693, data->irq); | 153 | irq_to_max77693_irq(max77693, data->irq); |
151 | 154 | ||
155 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
156 | return; | ||
157 | |||
152 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 158 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
153 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; | 159 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; |
154 | else | 160 | else |
@@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) | |||
200 | 206 | ||
201 | if (irq_src & MAX77693_IRQSRC_MUIC) | 207 | if (irq_src & MAX77693_IRQSRC_MUIC) |
202 | /* MUIC INT1 ~ INT3 */ | 208 | /* MUIC INT1 ~ INT3 */ |
203 | max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, | 209 | max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, |
204 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); | 210 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); |
205 | 211 | ||
206 | /* Apply masking */ | 212 | /* Apply masking */ |
@@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
255 | { | 261 | { |
256 | struct irq_domain *domain; | 262 | struct irq_domain *domain; |
257 | int i; | 263 | int i; |
258 | int ret; | 264 | int ret = 0; |
265 | u8 intsrc_mask; | ||
259 | 266 | ||
260 | mutex_init(&max77693->irqlock); | 267 | mutex_init(&max77693->irqlock); |
261 | 268 | ||
@@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
287 | &max77693_irq_domain_ops, max77693); | 294 | &max77693_irq_domain_ops, max77693); |
288 | if (!domain) { | 295 | if (!domain) { |
289 | dev_err(max77693->dev, "could not create irq domain\n"); | 296 | dev_err(max77693->dev, "could not create irq domain\n"); |
290 | return -ENODEV; | 297 | ret = -ENODEV; |
298 | goto err_irq; | ||
291 | } | 299 | } |
292 | max77693->irq_domain = domain; | 300 | max77693->irq_domain = domain; |
293 | 301 | ||
302 | /* Unmask max77693 interrupt */ | ||
303 | ret = max77693_read_reg(max77693->regmap, | ||
304 | MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); | ||
305 | if (ret < 0) { | ||
306 | dev_err(max77693->dev, "fail to read PMIC register\n"); | ||
307 | goto err_irq; | ||
308 | } | ||
309 | |||
310 | intsrc_mask &= ~(MAX77693_IRQSRC_CHG); | ||
311 | intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); | ||
312 | intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); | ||
313 | ret = max77693_write_reg(max77693->regmap, | ||
314 | MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); | ||
315 | if (ret < 0) { | ||
316 | dev_err(max77693->dev, "fail to write PMIC register\n"); | ||
317 | goto err_irq; | ||
318 | } | ||
319 | |||
294 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, | 320 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, |
295 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 321 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
296 | "max77693-irq", max77693); | 322 | "max77693-irq", max77693); |
297 | |||
298 | if (ret) | 323 | if (ret) |
299 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", | 324 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", |
300 | max77693->irq, ret); | 325 | max77693->irq, ret); |
301 | 326 | ||
302 | return 0; | 327 | err_irq: |
328 | return ret; | ||
303 | } | 329 | } |
304 | 330 | ||
305 | void max77693_irq_exit(struct max77693_dev *max77693) | 331 | void max77693_irq_exit(struct max77693_dev *max77693) |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a1811cb50ec7..cc5155e20494 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | 152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); |
153 | i2c_set_clientdata(max77693->haptic, max77693); | 153 | i2c_set_clientdata(max77693->haptic, max77693); |
154 | 154 | ||
155 | /* | ||
156 | * Initialize register map for MUIC device because use regmap-muic | ||
157 | * instance of MUIC device when irq of max77693 is initialized | ||
158 | * before call max77693-muic probe() function. | ||
159 | */ | ||
160 | max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, | ||
161 | &max77693_regmap_config); | ||
162 | if (IS_ERR(max77693->regmap_muic)) { | ||
163 | ret = PTR_ERR(max77693->regmap_muic); | ||
164 | dev_err(max77693->dev, | ||
165 | "failed to allocate register map: %d\n", ret); | ||
166 | goto err_regmap; | ||
167 | } | ||
168 | |||
155 | ret = max77693_irq_init(max77693); | 169 | ret = max77693_irq_init(max77693); |
156 | if (ret < 0) | 170 | if (ret < 0) |
157 | goto err_irq; | 171 | goto err_irq; |
@@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
159 | pm_runtime_set_active(max77693->dev); | 173 | pm_runtime_set_active(max77693->dev); |
160 | 174 | ||
161 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, | 175 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, |
162 | ARRAY_SIZE(max77693_devs), NULL, 0); | 176 | ARRAY_SIZE(max77693_devs), NULL, 0, NULL); |
163 | if (ret < 0) | 177 | if (ret < 0) |
164 | goto err_mfd; | 178 | goto err_mfd; |
165 | 179 | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 825a7f06d9ba..ee53757beca7 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
598 | 598 | ||
599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
600 | ARRAY_SIZE(rtc_devs), | 600 | ARRAY_SIZE(rtc_devs), |
601 | &rtc_resources[0], chip->irq_base); | 601 | &rtc_resources[0], chip->irq_base, NULL); |
602 | if (ret < 0) { | 602 | if (ret < 0) { |
603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
604 | goto out; | 604 | goto out; |
@@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
606 | 606 | ||
607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
608 | ARRAY_SIZE(onkey_devs), | 608 | ARRAY_SIZE(onkey_devs), |
609 | &onkey_resources[0], 0); | 609 | &onkey_resources[0], 0, NULL); |
610 | if (ret < 0) { | 610 | if (ret < 0) { |
611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
612 | goto out_dev; | 612 | goto out_dev; |
@@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
615 | if (pdata) { | 615 | if (pdata) { |
616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], | 616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], |
617 | ARRAY_SIZE(regulator_devs), | 617 | ARRAY_SIZE(regulator_devs), |
618 | ®ulator_resources[0], 0); | 618 | ®ulator_resources[0], 0, NULL); |
619 | if (ret < 0) { | 619 | if (ret < 0) { |
620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
621 | goto out_dev; | 621 | goto out_dev; |
@@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
625 | if (pdata && pdata->backlight) { | 625 | if (pdata && pdata->backlight) { |
626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], | 626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], |
627 | ARRAY_SIZE(backlight_devs), | 627 | ARRAY_SIZE(backlight_devs), |
628 | &backlight_resources[0], 0); | 628 | &backlight_resources[0], 0, NULL); |
629 | if (ret < 0) { | 629 | if (ret < 0) { |
630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); | 630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); |
631 | goto out_dev; | 631 | goto out_dev; |
@@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
635 | if (pdata && pdata->power) { | 635 | if (pdata && pdata->power) { |
636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], | 636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], |
637 | ARRAY_SIZE(power_devs), | 637 | ARRAY_SIZE(power_devs), |
638 | &power_supply_resources[0], 0); | 638 | &power_supply_resources[0], 0, NULL); |
639 | if (ret < 0) { | 639 | if (ret < 0) { |
640 | dev_err(chip->dev, "Failed to add power supply " | 640 | dev_err(chip->dev, "Failed to add power supply " |
641 | "subdev\n"); | 641 | "subdev\n"); |
@@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
646 | if (pdata && pdata->touch) { | 646 | if (pdata && pdata->touch) { |
647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
648 | ARRAY_SIZE(touch_devs), | 648 | ARRAY_SIZE(touch_devs), |
649 | &touch_resources[0], 0); | 649 | &touch_resources[0], 0, NULL); |
650 | if (ret < 0) { | 650 | if (ret < 0) { |
651 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 651 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
652 | goto out_dev; | 652 | goto out_dev; |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 10b629c245b6..f123517065ec 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
160 | 160 | ||
161 | mfd_add_devices(max8997->dev, -1, max8997_devs, | 161 | mfd_add_devices(max8997->dev, -1, max8997_devs, |
162 | ARRAY_SIZE(max8997_devs), | 162 | ARRAY_SIZE(max8997_devs), |
163 | NULL, 0); | 163 | NULL, 0, NULL); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * TODO: enable others (flash, muic, rtc, battery, ...) and | 166 | * TODO: enable others (flash, muic, rtc, battery, ...) and |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 6ef56d28c056..d7218cc90945 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
161 | switch (id->driver_data) { | 161 | switch (id->driver_data) { |
162 | case TYPE_LP3974: | 162 | case TYPE_LP3974: |
163 | ret = mfd_add_devices(max8998->dev, -1, | 163 | ret = mfd_add_devices(max8998->dev, -1, |
164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), | 164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), |
165 | NULL, 0); | 165 | NULL, 0, NULL); |
166 | break; | 166 | break; |
167 | case TYPE_MAX8998: | 167 | case TYPE_MAX8998: |
168 | ret = mfd_add_devices(max8998->dev, -1, | 168 | ret = mfd_add_devices(max8998->dev, -1, |
169 | max8998_devs, ARRAY_SIZE(max8998_devs), | 169 | max8998_devs, ARRAY_SIZE(max8998_devs), |
170 | NULL, 0); | 170 | NULL, 0, NULL); |
171 | break; | 171 | break; |
172 | default: | 172 | default: |
173 | ret = -EINVAL; | 173 | ret = -EINVAL; |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index b801dc72f041..1ec79b54bd2f 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
612 | if (!cell.name) | 612 | if (!cell.name) |
613 | return -ENOMEM; | 613 | return -ENOMEM; |
614 | 614 | ||
615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); | 615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL); |
616 | } | 616 | } |
617 | 617 | ||
618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0c3a01cde2f7..f8b77711ad2d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev, | |||
74 | static int mfd_add_device(struct device *parent, int id, | 74 | static int mfd_add_device(struct device *parent, int id, |
75 | const struct mfd_cell *cell, | 75 | const struct mfd_cell *cell, |
76 | struct resource *mem_base, | 76 | struct resource *mem_base, |
77 | int irq_base) | 77 | int irq_base, struct irq_domain *domain) |
78 | { | 78 | { |
79 | struct resource *res; | 79 | struct resource *res; |
80 | struct platform_device *pdev; | 80 | struct platform_device *pdev; |
81 | struct device_node *np = NULL; | 81 | struct device_node *np = NULL; |
82 | struct irq_domain *domain = NULL; | ||
83 | int ret = -ENOMEM; | 82 | int ret = -ENOMEM; |
84 | int r; | 83 | int r; |
85 | 84 | ||
@@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id, | |||
97 | for_each_child_of_node(parent->of_node, np) { | 96 | for_each_child_of_node(parent->of_node, np) { |
98 | if (of_device_is_compatible(np, cell->of_compatible)) { | 97 | if (of_device_is_compatible(np, cell->of_compatible)) { |
99 | pdev->dev.of_node = np; | 98 | pdev->dev.of_node = np; |
100 | domain = irq_find_host(parent->of_node); | ||
101 | break; | 99 | break; |
102 | } | 100 | } |
103 | } | 101 | } |
@@ -177,7 +175,7 @@ fail_alloc: | |||
177 | int mfd_add_devices(struct device *parent, int id, | 175 | int mfd_add_devices(struct device *parent, int id, |
178 | struct mfd_cell *cells, int n_devs, | 176 | struct mfd_cell *cells, int n_devs, |
179 | struct resource *mem_base, | 177 | struct resource *mem_base, |
180 | int irq_base) | 178 | int irq_base, struct irq_domain *domain) |
181 | { | 179 | { |
182 | int i; | 180 | int i; |
183 | int ret = 0; | 181 | int ret = 0; |
@@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id, | |||
191 | for (i = 0; i < n_devs; i++) { | 189 | for (i = 0; i < n_devs; i++) { |
192 | atomic_set(&cnts[i], 0); | 190 | atomic_set(&cnts[i], 0); |
193 | cells[i].usage_count = &cnts[i]; | 191 | cells[i].usage_count = &cnts[i]; |
194 | ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); | 192 | ret = mfd_add_device(parent, id, cells + i, mem_base, |
193 | irq_base, domain); | ||
195 | if (ret) | 194 | if (ret) |
196 | break; | 195 | break; |
197 | } | 196 | } |
@@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) | |||
247 | for (i = 0; i < n_clones; i++) { | 246 | for (i = 0; i < n_clones; i++) { |
248 | cell_entry.name = clones[i]; | 247 | cell_entry.name = clones[i]; |
249 | /* don't give up if a single call fails; just report error */ | 248 | /* don't give up if a single call fails; just report error */ |
250 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) | 249 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0, |
250 | NULL)) | ||
251 | dev_err(dev, "failed to create platform device '%s'\n", | 251 | dev_err(dev, "failed to create platform device '%s'\n", |
252 | clones[i]); | 252 | clones[i]); |
253 | } | 253 | } |
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c4a69f193a1d..a345f9bb7b47 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c | |||
@@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, | |||
453 | 453 | ||
454 | ret = mfd_add_devices(palmas->dev, -1, | 454 | ret = mfd_add_devices(palmas->dev, -1, |
455 | children, ARRAY_SIZE(palmas_children), | 455 | children, ARRAY_SIZE(palmas_children), |
456 | NULL, regmap_irq_chip_get_base(palmas->irq_data)); | 456 | NULL, regmap_irq_chip_get_base(palmas->irq_data), |
457 | NULL); | ||
457 | kfree(children); | 458 | kfree(children); |
458 | 459 | ||
459 | if (ret < 0) | 460 | if (ret < 0) |
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index cdc1df7fa0e9..3a8fa88567b1 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c | |||
@@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, | 291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, |
292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0); | 292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL); |
293 | if (ret) { | 293 | if (ret) { |
294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); | 294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); |
295 | goto err_add_devs; | 295 | goto err_add_devs; |
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 685d61e431ad..0f70dce61160 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, | |||
87 | rdc321x_wdt_pdata.sb_pdev = pdev; | 87 | rdc321x_wdt_pdata.sb_pdev = pdev; |
88 | 88 | ||
89 | return mfd_add_devices(&pdev->dev, -1, | 89 | return mfd_add_devices(&pdev->dev, -1, |
90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); | 90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), |
91 | NULL, 0, NULL); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) | 94 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 2988efde11eb..49d361a618d0 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
141 | switch (sec_pmic->device_type) { | 141 | switch (sec_pmic->device_type) { |
142 | case S5M8751X: | 142 | case S5M8751X: |
143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, | 143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, |
144 | ARRAY_SIZE(s5m8751_devs), NULL, 0); | 144 | ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL); |
145 | break; | 145 | break; |
146 | case S5M8763X: | 146 | case S5M8763X: |
147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, | 147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, |
148 | ARRAY_SIZE(s5m8763_devs), NULL, 0); | 148 | ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL); |
149 | break; | 149 | break; |
150 | case S5M8767X: | 150 | case S5M8767X: |
151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, | 151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, |
152 | ARRAY_SIZE(s5m8767_devs), NULL, 0); | 152 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); |
153 | break; | 153 | break; |
154 | case S2MPS11X: | 154 | case S2MPS11X: |
155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, | 155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, |
156 | ARRAY_SIZE(s2mps11_devs), NULL, 0); | 156 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); |
157 | break; | 157 | break; |
158 | default: | 158 | default: |
159 | /* If this happens the probe function is problem */ | 159 | /* If this happens the probe function is problem */ |
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index d31fed07aefb..d35da6820bea 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c | |||
@@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
407 | sta2x11_mfd_bar0, | 407 | sta2x11_mfd_bar0, |
408 | ARRAY_SIZE(sta2x11_mfd_bar0), | 408 | ARRAY_SIZE(sta2x11_mfd_bar0), |
409 | &pdev->resource[0], | 409 | &pdev->resource[0], |
410 | 0); | 410 | 0, NULL); |
411 | if (err) { | 411 | if (err) { |
412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); | 412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); |
413 | goto err_disable; | 413 | goto err_disable; |
@@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
417 | sta2x11_mfd_bar1, | 417 | sta2x11_mfd_bar1, |
418 | ARRAY_SIZE(sta2x11_mfd_bar1), | 418 | ARRAY_SIZE(sta2x11_mfd_bar1), |
419 | &pdev->resource[1], | 419 | &pdev->resource[1], |
420 | 0); | 420 | 0, NULL); |
421 | if (err) { | 421 | if (err) { |
422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); | 422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); |
423 | goto err_disable; | 423 | goto err_disable; |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2dd8d49cb30b..c94f521f392c 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe, | |||
962 | struct mfd_cell *cell, int irq) | 962 | struct mfd_cell *cell, int irq) |
963 | { | 963 | { |
964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, | 964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, |
965 | NULL, stmpe->irq_base + irq); | 965 | NULL, stmpe->irq_base + irq, NULL); |
966 | } | 966 | } |
967 | 967 | ||
968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) | 968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 2d9e8799e733..b32940ec9034 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
388 | 388 | ||
389 | ret = mfd_add_devices(&dev->dev, dev->id, | 389 | ret = mfd_add_devices(&dev->dev, dev->id, |
390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), | 390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), |
391 | iomem, t7l66xb->irq_base); | 391 | iomem, t7l66xb->irq_base, NULL); |
392 | 392 | ||
393 | if (!ret) | 393 | if (!ret) |
394 | return 0; | 394 | return 0; |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 048bf0532a09..b56ba6b43294 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
262 | 262 | ||
263 | if (blocks & TC3589x_BLOCK_GPIO) { | 263 | if (blocks & TC3589x_BLOCK_GPIO) { |
264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, | 264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, |
265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, | 265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, |
266 | tc3589x->irq_base); | 266 | tc3589x->irq_base, NULL); |
267 | if (ret) { | 267 | if (ret) { |
268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); | 268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); |
269 | return ret; | 269 | return ret; |
@@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
273 | 273 | ||
274 | if (blocks & TC3589x_BLOCK_KEYPAD) { | 274 | if (blocks & TC3589x_BLOCK_KEYPAD) { |
275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, | 275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, |
276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, | 276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, |
277 | tc3589x->irq_base); | 277 | tc3589x->irq_base, NULL); |
278 | if (ret) { | 278 | if (ret) { |
279 | dev_err(tc3589x->dev, "failed to keypad child\n"); | 279 | dev_err(tc3589x->dev, "failed to keypad child\n"); |
280 | return ret; | 280 | return ret; |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index d20a284ad4ba..413c891102f8 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev) | |||
192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); | 192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); |
193 | 193 | ||
194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, | 194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, |
195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq); | 195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); |
196 | 196 | ||
197 | if (!ret) | 197 | if (!ret) |
198 | return 0; | 198 | return 0; |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 9612264f0e6d..dcab026fcbb2 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); | 700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); |
701 | 701 | ||
702 | ret = mfd_add_devices(&dev->dev, dev->id, | 702 | ret = mfd_add_devices(&dev->dev, dev->id, |
703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
704 | iomem, tcpd->irq_base); | 704 | iomem, tcpd->irq_base, NULL); |
705 | 705 | ||
706 | if (!ret) | 706 | if (!ret) |
707 | return 0; | 707 | return 0; |
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index 4fb0e6c8e8fe..7c3675a74f93 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c | |||
@@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev) | |||
412 | cells[id].data_size = data->pdata_size; | 412 | cells[id].data_size = data->pdata_size; |
413 | } | 413 | } |
414 | 414 | ||
415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); | 415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL); |
416 | if (error < 0) { | 416 | if (error < 0) { |
417 | dev_err(dev, "cannot add mfd cells\n"); | 417 | dev_err(dev, "cannot add mfd cells\n"); |
418 | goto error_enable; | 418 | goto error_enable; |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index a447f4ec11fb..cccc626c83c8 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
757 | err = mfd_add_devices(&dev->dev, -1, | 757 | err = mfd_add_devices(&dev->dev, -1, |
758 | timberdale_cells_bar0_cfg0, | 758 | timberdale_cells_bar0_cfg0, |
759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), | 759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), |
760 | &dev->resource[0], msix_entries[0].vector); | 760 | &dev->resource[0], msix_entries[0].vector, NULL); |
761 | break; | 761 | break; |
762 | case TIMB_HW_VER1: | 762 | case TIMB_HW_VER1: |
763 | err = mfd_add_devices(&dev->dev, -1, | 763 | err = mfd_add_devices(&dev->dev, -1, |
764 | timberdale_cells_bar0_cfg1, | 764 | timberdale_cells_bar0_cfg1, |
765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), | 765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), |
766 | &dev->resource[0], msix_entries[0].vector); | 766 | &dev->resource[0], msix_entries[0].vector, NULL); |
767 | break; | 767 | break; |
768 | case TIMB_HW_VER2: | 768 | case TIMB_HW_VER2: |
769 | err = mfd_add_devices(&dev->dev, -1, | 769 | err = mfd_add_devices(&dev->dev, -1, |
770 | timberdale_cells_bar0_cfg2, | 770 | timberdale_cells_bar0_cfg2, |
771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), | 771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), |
772 | &dev->resource[0], msix_entries[0].vector); | 772 | &dev->resource[0], msix_entries[0].vector, NULL); |
773 | break; | 773 | break; |
774 | case TIMB_HW_VER3: | 774 | case TIMB_HW_VER3: |
775 | err = mfd_add_devices(&dev->dev, -1, | 775 | err = mfd_add_devices(&dev->dev, -1, |
776 | timberdale_cells_bar0_cfg3, | 776 | timberdale_cells_bar0_cfg3, |
777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), | 777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), |
778 | &dev->resource[0], msix_entries[0].vector); | 778 | &dev->resource[0], msix_entries[0].vector, NULL); |
779 | break; | 779 | break; |
780 | default: | 780 | default: |
781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", | 781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", |
@@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
792 | 792 | ||
793 | err = mfd_add_devices(&dev->dev, 0, | 793 | err = mfd_add_devices(&dev->dev, 0, |
794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), | 794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), |
795 | &dev->resource[1], msix_entries[0].vector); | 795 | &dev->resource[1], msix_entries[0].vector, NULL); |
796 | if (err) { | 796 | if (err) { |
797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
798 | goto err_mfd2; | 798 | goto err_mfd2; |
@@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { | 803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { |
804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, | 804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, |
805 | ARRAY_SIZE(timberdale_cells_bar2), | 805 | ARRAY_SIZE(timberdale_cells_bar2), |
806 | &dev->resource[2], msix_entries[0].vector); | 806 | &dev->resource[2], msix_entries[0].vector, NULL); |
807 | if (err) { | 807 | if (err) { |
808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
809 | goto err_mfd2; | 809 | goto err_mfd2; |
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a293b978e27c..14051bdc714b 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c | |||
@@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, | 190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, |
191 | ARRAY_SIZE(tps6105x_cells), NULL, 0); | 191 | ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); |
192 | if (ret) | 192 | if (ret) |
193 | goto fail; | 193 | goto fail; |
194 | 194 | ||
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 33ba7723c967..1b203499c744 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c | |||
@@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c, | |||
100 | 100 | ||
101 | ret = mfd_add_devices(tps6507x->dev, -1, | 101 | ret = mfd_add_devices(tps6507x->dev, -1, |
102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), | 102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), |
103 | NULL, 0); | 103 | NULL, 0, NULL); |
104 | 104 | ||
105 | if (ret < 0) | 105 | if (ret < 0) |
106 | goto err; | 106 | goto err; |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 80e24f4b47bf..50fd87c87a1c 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client, | |||
292 | } | 292 | } |
293 | 293 | ||
294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
295 | ARRAY_SIZE(tps65090s), NULL, 0); | 295 | ARRAY_SIZE(tps65090s), NULL, 0, NULL); |
296 | if (ret) { | 296 | if (ret) { |
297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
298 | ret); | 298 | ret); |
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 61c097a98f5d..a95e9421b735 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -24,11 +24,18 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/regulator/of_regulator.h> | 27 | #include <linux/of.h> |
28 | #include <linux/of_device.h> | ||
28 | 29 | ||
29 | #include <linux/mfd/core.h> | 30 | #include <linux/mfd/core.h> |
30 | #include <linux/mfd/tps65217.h> | 31 | #include <linux/mfd/tps65217.h> |
31 | 32 | ||
33 | static struct mfd_cell tps65217s[] = { | ||
34 | { | ||
35 | .name = "tps65217-pmic", | ||
36 | }, | ||
37 | }; | ||
38 | |||
32 | /** | 39 | /** |
33 | * tps65217_reg_read: Read a single tps65217 register. | 40 | * tps65217_reg_read: Read a single tps65217 register. |
34 | * | 41 | * |
@@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, | |||
133 | } | 140 | } |
134 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); | 141 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); |
135 | 142 | ||
136 | #ifdef CONFIG_OF | ||
137 | static struct of_regulator_match reg_matches[] = { | ||
138 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
139 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
140 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
141 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
142 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
143 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
144 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
145 | }; | ||
146 | |||
147 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
148 | { | ||
149 | struct device_node *node = client->dev.of_node; | ||
150 | struct tps65217_board *pdata; | ||
151 | struct device_node *regs; | ||
152 | int count = ARRAY_SIZE(reg_matches); | ||
153 | int ret, i; | ||
154 | |||
155 | regs = of_find_node_by_name(node, "regulators"); | ||
156 | if (!regs) | ||
157 | return NULL; | ||
158 | |||
159 | ret = of_regulator_match(&client->dev, regs, reg_matches, count); | ||
160 | of_node_put(regs); | ||
161 | if ((ret < 0) || (ret > count)) | ||
162 | return NULL; | ||
163 | |||
164 | count = ret; | ||
165 | pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); | ||
166 | if (!pdata) | ||
167 | return NULL; | ||
168 | |||
169 | for (i = 0; i < count; i++) { | ||
170 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
171 | continue; | ||
172 | |||
173 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
174 | pdata->of_node[i] = reg_matches[i].of_node; | ||
175 | } | ||
176 | |||
177 | return pdata; | ||
178 | } | ||
179 | |||
180 | static struct of_device_id tps65217_of_match[] = { | ||
181 | { .compatible = "ti,tps65217", }, | ||
182 | { }, | ||
183 | }; | ||
184 | #else | ||
185 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
186 | { | ||
187 | return NULL; | ||
188 | } | ||
189 | #endif | ||
190 | |||
191 | static struct regmap_config tps65217_regmap_config = { | 143 | static struct regmap_config tps65217_regmap_config = { |
192 | .reg_bits = 8, | 144 | .reg_bits = 8, |
193 | .val_bits = 8, | 145 | .val_bits = 8, |
194 | }; | 146 | }; |
195 | 147 | ||
148 | static const struct of_device_id tps65217_of_match[] = { | ||
149 | { .compatible = "ti,tps65217", .data = (void *)TPS65217 }, | ||
150 | { /* sentinel */ }, | ||
151 | }; | ||
152 | |||
196 | static int __devinit tps65217_probe(struct i2c_client *client, | 153 | static int __devinit tps65217_probe(struct i2c_client *client, |
197 | const struct i2c_device_id *ids) | 154 | const struct i2c_device_id *ids) |
198 | { | 155 | { |
199 | struct tps65217 *tps; | 156 | struct tps65217 *tps; |
200 | struct regulator_init_data *reg_data; | ||
201 | struct tps65217_board *pdata = client->dev.platform_data; | ||
202 | int i, ret; | ||
203 | unsigned int version; | 157 | unsigned int version; |
158 | unsigned int chip_id = ids->driver_data; | ||
159 | const struct of_device_id *match; | ||
160 | int ret; | ||
204 | 161 | ||
205 | if (!pdata && client->dev.of_node) | 162 | if (client->dev.of_node) { |
206 | pdata = tps65217_parse_dt(client); | 163 | match = of_match_device(tps65217_of_match, &client->dev); |
164 | if (!match) { | ||
165 | dev_err(&client->dev, | ||
166 | "Failed to find matching dt id\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | chip_id = (unsigned int)match->data; | ||
170 | } | ||
171 | |||
172 | if (!chip_id) { | ||
173 | dev_err(&client->dev, "id is null.\n"); | ||
174 | return -ENODEV; | ||
175 | } | ||
207 | 176 | ||
208 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 177 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
209 | if (!tps) | 178 | if (!tps) |
210 | return -ENOMEM; | 179 | return -ENOMEM; |
211 | 180 | ||
212 | tps->pdata = pdata; | 181 | i2c_set_clientdata(client, tps); |
182 | tps->dev = &client->dev; | ||
183 | tps->id = chip_id; | ||
184 | |||
213 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); | 185 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); |
214 | if (IS_ERR(tps->regmap)) { | 186 | if (IS_ERR(tps->regmap)) { |
215 | ret = PTR_ERR(tps->regmap); | 187 | ret = PTR_ERR(tps->regmap); |
@@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
218 | return ret; | 190 | return ret; |
219 | } | 191 | } |
220 | 192 | ||
221 | i2c_set_clientdata(client, tps); | 193 | ret = mfd_add_devices(tps->dev, -1, tps65217s, |
222 | tps->dev = &client->dev; | 194 | ARRAY_SIZE(tps65217s), NULL, 0, NULL); |
195 | if (ret < 0) { | ||
196 | dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
223 | 199 | ||
224 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); | 200 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); |
225 | if (ret < 0) { | 201 | if (ret < 0) { |
@@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
232 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, | 208 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, |
233 | version & TPS65217_CHIPID_REV_MASK); | 209 | version & TPS65217_CHIPID_REV_MASK); |
234 | 210 | ||
235 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
236 | struct platform_device *pdev; | ||
237 | |||
238 | pdev = platform_device_alloc("tps65217-pmic", i); | ||
239 | if (!pdev) { | ||
240 | dev_err(tps->dev, "Cannot create regulator %d\n", i); | ||
241 | continue; | ||
242 | } | ||
243 | |||
244 | pdev->dev.parent = tps->dev; | ||
245 | pdev->dev.of_node = pdata->of_node[i]; | ||
246 | reg_data = pdata->tps65217_init_data[i]; | ||
247 | platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); | ||
248 | tps->regulator_pdev[i] = pdev; | ||
249 | |||
250 | platform_device_add(pdev); | ||
251 | } | ||
252 | |||
253 | return 0; | 211 | return 0; |
254 | } | 212 | } |
255 | 213 | ||
256 | static int __devexit tps65217_remove(struct i2c_client *client) | 214 | static int __devexit tps65217_remove(struct i2c_client *client) |
257 | { | 215 | { |
258 | struct tps65217 *tps = i2c_get_clientdata(client); | 216 | struct tps65217 *tps = i2c_get_clientdata(client); |
259 | int i; | ||
260 | 217 | ||
261 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | 218 | mfd_remove_devices(tps->dev); |
262 | platform_device_unregister(tps->regulator_pdev[i]); | ||
263 | 219 | ||
264 | return 0; | 220 | return 0; |
265 | } | 221 | } |
266 | 222 | ||
267 | static const struct i2c_device_id tps65217_id_table[] = { | 223 | static const struct i2c_device_id tps65217_id_table[] = { |
268 | {"tps65217", 0xF0}, | 224 | {"tps65217", TPS65217}, |
269 | {/* end of list */} | 225 | { /* sentinel */ } |
270 | }; | 226 | }; |
271 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); | 227 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); |
272 | 228 | ||
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 353c34812120..5f58370ccf55 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -493,7 +493,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
493 | } | 493 | } |
494 | 494 | ||
495 | ret = mfd_add_devices(tps6586x->dev, -1, | 495 | ret = mfd_add_devices(tps6586x->dev, -1, |
496 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0); | 496 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), |
497 | NULL, 0, NULL); | ||
497 | if (ret < 0) { | 498 | if (ret < 0) { |
498 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); | 499 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); |
499 | goto err_mfd_add; | 500 | goto err_mfd_add; |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1c563792c777..d3ce4d569deb 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, | |||
254 | 254 | ||
255 | ret = mfd_add_devices(tps65910->dev, -1, | 255 | ret = mfd_add_devices(tps65910->dev, -1, |
256 | tps65910s, ARRAY_SIZE(tps65910s), | 256 | tps65910s, ARRAY_SIZE(tps65910s), |
257 | NULL, 0); | 257 | NULL, 0, NULL); |
258 | if (ret < 0) { | 258 | if (ret < 0) { |
259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); | 259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); |
260 | return ret; | 260 | return ret; |
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 74fd8cb5f372..4658b5bdcd84 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
146 | 146 | ||
147 | ret = mfd_add_devices(tps65912->dev, -1, | 147 | ret = mfd_add_devices(tps65912->dev, -1, |
148 | tps65912s, ARRAY_SIZE(tps65912s), | 148 | tps65912s, ARRAY_SIZE(tps65912s), |
149 | NULL, 0); | 149 | NULL, 0, NULL); |
150 | if (ret < 0) | 150 | if (ret < 0) |
151 | goto err; | 151 | goto err; |
152 | 152 | ||
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 838ce4eb444e..77c9acb14583 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c | |||
@@ -223,7 +223,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev) | |||
223 | 223 | ||
224 | if (childs) | 224 | if (childs) |
225 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, | 225 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, |
226 | childs, NULL, 0); | 226 | childs, NULL, 0, NULL); |
227 | else { | 227 | else { |
228 | dev_err(&pdev->dev, "No platform data found for childs\n"); | 228 | dev_err(&pdev->dev, "No platform data found for childs\n"); |
229 | ret = -ENODEV; | 229 | ret = -ENODEV; |
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b0fad0ffca56..3dca5c195a20 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
@@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
632 | } | 632 | } |
633 | 633 | ||
634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, | 634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, |
635 | NULL, 0); | 635 | NULL, 0, NULL); |
636 | if (ret) | 636 | if (ret) |
637 | goto mfd_err; | 637 | goto mfd_err; |
638 | 638 | ||
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index 872aff21e4be..b9a636d44c7f 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
@@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev, | |||
102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; | 102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; |
103 | 103 | ||
104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), | 104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), |
105 | NULL, 0); | 105 | NULL, 0, NULL); |
106 | 106 | ||
107 | /* we always return -ENODEV here in order to enable other | 107 | /* we always return -ENODEV here in order to enable other |
108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ | 108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ |
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f39b756df561..86e0e4309fc2 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c | |||
@@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client, | |||
241 | __func__, children); | 241 | __func__, children); |
242 | 242 | ||
243 | r = mfd_add_devices(&client->dev, -1, core->cells, | 243 | r = mfd_add_devices(&client->dev, -1, core->cells, |
244 | children, NULL, 0); | 244 | children, NULL, 0, NULL); |
245 | if (r) | 245 | if (r) |
246 | goto err; | 246 | goto err; |
247 | 247 | ||
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc6..301731035940 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1813 | case WM8310: | 1813 | case WM8310: |
1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), | 1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), |
1816 | NULL, 0); | 1816 | NULL, 0, NULL); |
1817 | break; | 1817 | break; |
1818 | 1818 | ||
1819 | case WM8311: | 1819 | case WM8311: |
1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), | 1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), |
1822 | NULL, 0); | 1822 | NULL, 0, NULL); |
1823 | if (!pdata || !pdata->disable_touch) | 1823 | if (!pdata || !pdata->disable_touch) |
1824 | mfd_add_devices(wm831x->dev, wm831x_num, | 1824 | mfd_add_devices(wm831x->dev, wm831x_num, |
1825 | touch_devs, ARRAY_SIZE(touch_devs), | 1825 | touch_devs, ARRAY_SIZE(touch_devs), |
1826 | NULL, 0); | 1826 | NULL, 0, NULL); |
1827 | break; | 1827 | break; |
1828 | 1828 | ||
1829 | case WM8312: | 1829 | case WM8312: |
1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), | 1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), |
1832 | NULL, 0); | 1832 | NULL, 0, NULL); |
1833 | if (!pdata || !pdata->disable_touch) | 1833 | if (!pdata || !pdata->disable_touch) |
1834 | mfd_add_devices(wm831x->dev, wm831x_num, | 1834 | mfd_add_devices(wm831x->dev, wm831x_num, |
1835 | touch_devs, ARRAY_SIZE(touch_devs), | 1835 | touch_devs, ARRAY_SIZE(touch_devs), |
1836 | NULL, 0); | 1836 | NULL, 0, NULL); |
1837 | break; | 1837 | break; |
1838 | 1838 | ||
1839 | case WM8320: | 1839 | case WM8320: |
@@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1842 | case WM8326: | 1842 | case WM8326: |
1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
1845 | NULL, 0); | 1845 | NULL, 0, NULL); |
1846 | break; | 1846 | break; |
1847 | 1847 | ||
1848 | default: | 1848 | default: |
@@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1867 | if (ret & WM831X_XTAL_ENA) { | 1867 | if (ret & WM831X_XTAL_ENA) { |
1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1869 | rtc_devs, ARRAY_SIZE(rtc_devs), | 1869 | rtc_devs, ARRAY_SIZE(rtc_devs), |
1870 | NULL, 0); | 1870 | NULL, 0, NULL); |
1871 | if (ret != 0) { | 1871 | if (ret != 0) { |
1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); | 1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); |
1873 | goto err_irq; | 1873 | goto err_irq; |
@@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1880 | /* Treat errors as non-critical */ | 1880 | /* Treat errors as non-critical */ |
1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, | 1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, |
1882 | ARRAY_SIZE(backlight_devs), NULL, | 1882 | ARRAY_SIZE(backlight_devs), NULL, |
1883 | 0); | 1883 | 0, NULL); |
1884 | if (ret < 0) | 1884 | if (ret < 0) |
1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", | 1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", |
1886 | ret); | 1886 | ret); |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 4b7d378551d5..639ca359242f 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400) | |||
70 | .pdata_size = sizeof(*wm8400), | 70 | .pdata_size = sizeof(*wm8400), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); | 73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | 76 | /* |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index eec74aa55fdf..2febf88cfce8 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
414 | ret = mfd_add_devices(wm8994->dev, -1, | 414 | ret = mfd_add_devices(wm8994->dev, -1, |
415 | wm8994_regulator_devs, | 415 | wm8994_regulator_devs, |
416 | ARRAY_SIZE(wm8994_regulator_devs), | 416 | ARRAY_SIZE(wm8994_regulator_devs), |
417 | NULL, 0); | 417 | NULL, 0, NULL); |
418 | if (ret != 0) { | 418 | if (ret != 0) { |
419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
420 | goto err; | 420 | goto err; |
@@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
648 | 648 | ||
649 | ret = mfd_add_devices(wm8994->dev, -1, | 649 | ret = mfd_add_devices(wm8994->dev, -1, |
650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), | 650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), |
651 | NULL, 0); | 651 | NULL, 0, NULL); |
652 | if (ret != 0) { | 652 | if (ret != 0) { |
653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
654 | goto err_irq; | 654 | goto err_irq; |
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index c6ffbbe5a6c0..d78c05e693f7 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -1253,7 +1253,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, | |||
1253 | if (dev->wd_timeout) | 1253 | if (dev->wd_timeout) |
1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); |
1255 | else | 1255 | else |
1256 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1256 | *slots -= mei_data2slots(MEI_WD_PARAMS_SIZE); |
1257 | } | 1257 | } |
1258 | } | 1258 | } |
1259 | if (dev->stop) | 1259 | if (dev->stop) |
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 092330208869..7422c7652845 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -925,6 +925,27 @@ static struct miscdevice mei_misc_device = { | |||
925 | }; | 925 | }; |
926 | 926 | ||
927 | /** | 927 | /** |
928 | * mei_quirk_probe - probe for devices that doesn't valid ME interface | ||
929 | * @pdev: PCI device structure | ||
930 | * @ent: entry into pci_device_table | ||
931 | * | ||
932 | * returns true if ME Interface is valid, false otherwise | ||
933 | */ | ||
934 | static bool __devinit mei_quirk_probe(struct pci_dev *pdev, | ||
935 | const struct pci_device_id *ent) | ||
936 | { | ||
937 | u32 reg; | ||
938 | if (ent->device == MEI_DEV_ID_PBG_1) { | ||
939 | pci_read_config_dword(pdev, 0x48, ®); | ||
940 | /* make sure that bit 9 is up and bit 10 is down */ | ||
941 | if ((reg & 0x600) == 0x200) { | ||
942 | dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); | ||
943 | return false; | ||
944 | } | ||
945 | } | ||
946 | return true; | ||
947 | } | ||
948 | /** | ||
928 | * mei_probe - Device Initialization Routine | 949 | * mei_probe - Device Initialization Routine |
929 | * | 950 | * |
930 | * @pdev: PCI device structure | 951 | * @pdev: PCI device structure |
@@ -939,6 +960,12 @@ static int __devinit mei_probe(struct pci_dev *pdev, | |||
939 | int err; | 960 | int err; |
940 | 961 | ||
941 | mutex_lock(&mei_mutex); | 962 | mutex_lock(&mei_mutex); |
963 | |||
964 | if (!mei_quirk_probe(pdev, ent)) { | ||
965 | err = -ENODEV; | ||
966 | goto end; | ||
967 | } | ||
968 | |||
942 | if (mei_device) { | 969 | if (mei_device) { |
943 | err = -EEXIST; | 970 | err = -EEXIST; |
944 | goto end; | 971 | goto end; |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 87b251ab6ec5..b9e2000969f0 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/cpu.h> | ||
22 | #include <linux/module.h> | ||
21 | #include <linux/err.h> | 23 | #include <linux/err.h> |
22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
23 | #include <asm/uv/uv_hub.h> | 25 | #include <asm/uv/uv_hub.h> |
@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv; | |||
59 | XPC_NOTIFY_MSG_SIZE_UV) | 61 | XPC_NOTIFY_MSG_SIZE_UV) |
60 | #define XPC_NOTIFY_IRQ_NAME "xpc_notify" | 62 | #define XPC_NOTIFY_IRQ_NAME "xpc_notify" |
61 | 63 | ||
64 | static int xpc_mq_node = -1; | ||
65 | |||
62 | static struct xpc_gru_mq_uv *xpc_activate_mq_uv; | 66 | static struct xpc_gru_mq_uv *xpc_activate_mq_uv; |
63 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; | 67 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; |
64 | 68 | ||
@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) | |||
109 | #if defined CONFIG_X86_64 | 113 | #if defined CONFIG_X86_64 |
110 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, | 114 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, |
111 | UV_AFFINITY_CPU); | 115 | UV_AFFINITY_CPU); |
112 | if (mq->irq < 0) { | 116 | if (mq->irq < 0) |
113 | dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", | ||
114 | -mq->irq); | ||
115 | return mq->irq; | 117 | return mq->irq; |
116 | } | ||
117 | 118 | ||
118 | mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); | 119 | mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); |
119 | 120 | ||
@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, | |||
238 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); | 239 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); |
239 | 240 | ||
240 | nid = cpu_to_node(cpu); | 241 | nid = cpu_to_node(cpu); |
241 | page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 242 | page = alloc_pages_exact_node(nid, |
242 | pg_order); | 243 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
244 | pg_order); | ||
243 | if (page == NULL) { | 245 | if (page == NULL) { |
244 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " | 246 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " |
245 | "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); | 247 | "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); |
@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_arch_ops_uv = { | |||
1731 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, | 1733 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, |
1732 | }; | 1734 | }; |
1733 | 1735 | ||
1736 | static int | ||
1737 | xpc_init_mq_node(int nid) | ||
1738 | { | ||
1739 | int cpu; | ||
1740 | |||
1741 | get_online_cpus(); | ||
1742 | |||
1743 | for_each_cpu(cpu, cpumask_of_node(nid)) { | ||
1744 | xpc_activate_mq_uv = | ||
1745 | xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, | ||
1746 | XPC_ACTIVATE_IRQ_NAME, | ||
1747 | xpc_handle_activate_IRQ_uv); | ||
1748 | if (!IS_ERR(xpc_activate_mq_uv)) | ||
1749 | break; | ||
1750 | } | ||
1751 | if (IS_ERR(xpc_activate_mq_uv)) { | ||
1752 | put_online_cpus(); | ||
1753 | return PTR_ERR(xpc_activate_mq_uv); | ||
1754 | } | ||
1755 | |||
1756 | for_each_cpu(cpu, cpumask_of_node(nid)) { | ||
1757 | xpc_notify_mq_uv = | ||
1758 | xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, | ||
1759 | XPC_NOTIFY_IRQ_NAME, | ||
1760 | xpc_handle_notify_IRQ_uv); | ||
1761 | if (!IS_ERR(xpc_notify_mq_uv)) | ||
1762 | break; | ||
1763 | } | ||
1764 | if (IS_ERR(xpc_notify_mq_uv)) { | ||
1765 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | ||
1766 | put_online_cpus(); | ||
1767 | return PTR_ERR(xpc_notify_mq_uv); | ||
1768 | } | ||
1769 | |||
1770 | put_online_cpus(); | ||
1771 | return 0; | ||
1772 | } | ||
1773 | |||
1734 | int | 1774 | int |
1735 | xpc_init_uv(void) | 1775 | xpc_init_uv(void) |
1736 | { | 1776 | { |
1777 | int nid; | ||
1778 | int ret = 0; | ||
1779 | |||
1737 | xpc_arch_ops = xpc_arch_ops_uv; | 1780 | xpc_arch_ops = xpc_arch_ops_uv; |
1738 | 1781 | ||
1739 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { | 1782 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { |
@@ -1742,21 +1785,21 @@ xpc_init_uv(void) | |||
1742 | return -E2BIG; | 1785 | return -E2BIG; |
1743 | } | 1786 | } |
1744 | 1787 | ||
1745 | xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, | 1788 | if (xpc_mq_node < 0) |
1746 | XPC_ACTIVATE_IRQ_NAME, | 1789 | for_each_online_node(nid) { |
1747 | xpc_handle_activate_IRQ_uv); | 1790 | ret = xpc_init_mq_node(nid); |
1748 | if (IS_ERR(xpc_activate_mq_uv)) | ||
1749 | return PTR_ERR(xpc_activate_mq_uv); | ||
1750 | 1791 | ||
1751 | xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, | 1792 | if (!ret) |
1752 | XPC_NOTIFY_IRQ_NAME, | 1793 | break; |
1753 | xpc_handle_notify_IRQ_uv); | 1794 | } |
1754 | if (IS_ERR(xpc_notify_mq_uv)) { | 1795 | else |
1755 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | 1796 | ret = xpc_init_mq_node(xpc_mq_node); |
1756 | return PTR_ERR(xpc_notify_mq_uv); | ||
1757 | } | ||
1758 | 1797 | ||
1759 | return 0; | 1798 | if (ret < 0) |
1799 | dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", | ||
1800 | -ret); | ||
1801 | |||
1802 | return ret; | ||
1760 | } | 1803 | } |
1761 | 1804 | ||
1762 | void | 1805 | void |
@@ -1765,3 +1808,6 @@ xpc_exit_uv(void) | |||
1765 | xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); | 1808 | xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); |
1766 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | 1809 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); |
1767 | } | 1810 | } |
1811 | |||
1812 | module_param(xpc_mq_node, int, 0); | ||
1813 | MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); | ||
diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index 1ff460a8e9c7..93b4d67cc4a3 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c | |||
@@ -87,7 +87,7 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data) | |||
87 | /* communicate to platform about chip wakeup */ | 87 | /* communicate to platform about chip wakeup */ |
88 | kim_data = st_data->kim_data; | 88 | kim_data = st_data->kim_data; |
89 | pdata = kim_data->kim_pdev->dev.platform_data; | 89 | pdata = kim_data->kim_pdev->dev.platform_data; |
90 | if (pdata->chip_asleep) | 90 | if (pdata->chip_awake) |
91 | pdata->chip_awake(NULL); | 91 | pdata->chip_awake(NULL); |
92 | } | 92 | } |
93 | 93 | ||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f1c84decb192..172a768036d8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -1411,7 +1411,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1411 | /* complete ongoing async transfer before issuing discard */ | 1411 | /* complete ongoing async transfer before issuing discard */ |
1412 | if (card->host->areq) | 1412 | if (card->host->areq) |
1413 | mmc_blk_issue_rw_rq(mq, NULL); | 1413 | mmc_blk_issue_rw_rq(mq, NULL); |
1414 | if (req->cmd_flags & REQ_SECURE) | 1414 | if (req->cmd_flags & REQ_SECURE && |
1415 | !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN)) | ||
1415 | ret = mmc_blk_issue_secdiscard_rq(mq, req); | 1416 | ret = mmc_blk_issue_secdiscard_rq(mq, req); |
1416 | else | 1417 | else |
1417 | ret = mmc_blk_issue_discard_rq(mq, req); | 1418 | ret = mmc_blk_issue_discard_rq(mq, req); |
@@ -1716,6 +1717,7 @@ force_ro_fail: | |||
1716 | #define CID_MANFID_SANDISK 0x2 | 1717 | #define CID_MANFID_SANDISK 0x2 |
1717 | #define CID_MANFID_TOSHIBA 0x11 | 1718 | #define CID_MANFID_TOSHIBA 0x11 |
1718 | #define CID_MANFID_MICRON 0x13 | 1719 | #define CID_MANFID_MICRON 0x13 |
1720 | #define CID_MANFID_SAMSUNG 0x15 | ||
1719 | 1721 | ||
1720 | static const struct mmc_fixup blk_fixups[] = | 1722 | static const struct mmc_fixup blk_fixups[] = |
1721 | { | 1723 | { |
@@ -1752,6 +1754,28 @@ static const struct mmc_fixup blk_fixups[] = | |||
1752 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, | 1754 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
1753 | MMC_QUIRK_LONG_READ_TIME), | 1755 | MMC_QUIRK_LONG_READ_TIME), |
1754 | 1756 | ||
1757 | /* | ||
1758 | * On these Samsung MoviNAND parts, performing secure erase or | ||
1759 | * secure trim can result in unrecoverable corruption due to a | ||
1760 | * firmware bug. | ||
1761 | */ | ||
1762 | MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1763 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1764 | MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1765 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1766 | MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1767 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1768 | MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1769 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1770 | MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1771 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1772 | MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1773 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1774 | MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1775 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1776 | MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, | ||
1777 | MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), | ||
1778 | |||
1755 | END_FIXUP | 1779 | END_FIXUP |
1756 | }; | 1780 | }; |
1757 | 1781 | ||
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 322412cec4ee..a53c7c478e05 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -81,6 +81,7 @@ struct atmel_mci_caps { | |||
81 | bool has_bad_data_ordering; | 81 | bool has_bad_data_ordering; |
82 | bool need_reset_after_xfer; | 82 | bool need_reset_after_xfer; |
83 | bool need_blksz_mul_4; | 83 | bool need_blksz_mul_4; |
84 | bool need_notbusy_for_read_ops; | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | struct atmel_mci_dma { | 87 | struct atmel_mci_dma { |
@@ -1625,7 +1626,8 @@ static void atmci_tasklet_func(unsigned long priv) | |||
1625 | __func__); | 1626 | __func__); |
1626 | atmci_set_completed(host, EVENT_XFER_COMPLETE); | 1627 | atmci_set_completed(host, EVENT_XFER_COMPLETE); |
1627 | 1628 | ||
1628 | if (host->data->flags & MMC_DATA_WRITE) { | 1629 | if (host->caps.need_notbusy_for_read_ops || |
1630 | (host->data->flags & MMC_DATA_WRITE)) { | ||
1629 | atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); | 1631 | atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); |
1630 | state = STATE_WAITING_NOTBUSY; | 1632 | state = STATE_WAITING_NOTBUSY; |
1631 | } else if (host->mrq->stop) { | 1633 | } else if (host->mrq->stop) { |
@@ -2218,6 +2220,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2218 | host->caps.has_bad_data_ordering = 1; | 2220 | host->caps.has_bad_data_ordering = 1; |
2219 | host->caps.need_reset_after_xfer = 1; | 2221 | host->caps.need_reset_after_xfer = 1; |
2220 | host->caps.need_blksz_mul_4 = 1; | 2222 | host->caps.need_blksz_mul_4 = 1; |
2223 | host->caps.need_notbusy_for_read_ops = 0; | ||
2221 | 2224 | ||
2222 | /* keep only major version number */ | 2225 | /* keep only major version number */ |
2223 | switch (version & 0xf00) { | 2226 | switch (version & 0xf00) { |
@@ -2238,6 +2241,7 @@ static void __init atmci_get_cap(struct atmel_mci *host) | |||
2238 | case 0x200: | 2241 | case 0x200: |
2239 | host->caps.has_rwproof = 1; | 2242 | host->caps.has_rwproof = 1; |
2240 | host->caps.need_blksz_mul_4 = 0; | 2243 | host->caps.need_blksz_mul_4 = 0; |
2244 | host->caps.need_notbusy_for_read_ops = 1; | ||
2241 | case 0x100: | 2245 | case 0x100: |
2242 | host->caps.has_bad_data_ordering = 0; | 2246 | host->caps.has_bad_data_ordering = 0; |
2243 | host->caps.need_reset_after_xfer = 0; | 2247 | host->caps.need_reset_after_xfer = 0; |
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 03666174ca48..a17dd7363ceb 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c | |||
@@ -49,13 +49,6 @@ | |||
49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG | 49 | #define bfin_write_SDH_CFG bfin_write_RSI_CFG |
50 | #endif | 50 | #endif |
51 | 51 | ||
52 | struct dma_desc_array { | ||
53 | unsigned long start_addr; | ||
54 | unsigned short cfg; | ||
55 | unsigned short x_count; | ||
56 | short x_modify; | ||
57 | } __packed; | ||
58 | |||
59 | struct sdh_host { | 52 | struct sdh_host { |
60 | struct mmc_host *mmc; | 53 | struct mmc_host *mmc; |
61 | spinlock_t lock; | 54 | spinlock_t lock; |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 72dc3cde646d..af40d227bece 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -627,6 +627,7 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
627 | { | 627 | { |
628 | struct dw_mci *host = slot->host; | 628 | struct dw_mci *host = slot->host; |
629 | u32 div; | 629 | u32 div; |
630 | u32 clk_en_a; | ||
630 | 631 | ||
631 | if (slot->clock != host->current_speed) { | 632 | if (slot->clock != host->current_speed) { |
632 | div = host->bus_hz / slot->clock; | 633 | div = host->bus_hz / slot->clock; |
@@ -659,9 +660,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
659 | mci_send_cmd(slot, | 660 | mci_send_cmd(slot, |
660 | SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); | 661 | SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); |
661 | 662 | ||
662 | /* enable clock */ | 663 | /* enable clock; only low power if no SDIO */ |
663 | mci_writel(host, CLKENA, ((SDMMC_CLKEN_ENABLE | | 664 | clk_en_a = SDMMC_CLKEN_ENABLE << slot->id; |
664 | SDMMC_CLKEN_LOW_PWR) << slot->id)); | 665 | if (!(mci_readl(host, INTMASK) & SDMMC_INT_SDIO(slot->id))) |
666 | clk_en_a |= SDMMC_CLKEN_LOW_PWR << slot->id; | ||
667 | mci_writel(host, CLKENA, clk_en_a); | ||
665 | 668 | ||
666 | /* inform CIU */ | 669 | /* inform CIU */ |
667 | mci_send_cmd(slot, | 670 | mci_send_cmd(slot, |
@@ -862,6 +865,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc) | |||
862 | return present; | 865 | return present; |
863 | } | 866 | } |
864 | 867 | ||
868 | /* | ||
869 | * Disable lower power mode. | ||
870 | * | ||
871 | * Low power mode will stop the card clock when idle. According to the | ||
872 | * description of the CLKENA register we should disable low power mode | ||
873 | * for SDIO cards if we need SDIO interrupts to work. | ||
874 | * | ||
875 | * This function is fast if low power mode is already disabled. | ||
876 | */ | ||
877 | static void dw_mci_disable_low_power(struct dw_mci_slot *slot) | ||
878 | { | ||
879 | struct dw_mci *host = slot->host; | ||
880 | u32 clk_en_a; | ||
881 | const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id; | ||
882 | |||
883 | clk_en_a = mci_readl(host, CLKENA); | ||
884 | |||
885 | if (clk_en_a & clken_low_pwr) { | ||
886 | mci_writel(host, CLKENA, clk_en_a & ~clken_low_pwr); | ||
887 | mci_send_cmd(slot, SDMMC_CMD_UPD_CLK | | ||
888 | SDMMC_CMD_PRV_DAT_WAIT, 0); | ||
889 | } | ||
890 | } | ||
891 | |||
865 | static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | 892 | static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) |
866 | { | 893 | { |
867 | struct dw_mci_slot *slot = mmc_priv(mmc); | 894 | struct dw_mci_slot *slot = mmc_priv(mmc); |
@@ -871,6 +898,14 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb) | |||
871 | /* Enable/disable Slot Specific SDIO interrupt */ | 898 | /* Enable/disable Slot Specific SDIO interrupt */ |
872 | int_mask = mci_readl(host, INTMASK); | 899 | int_mask = mci_readl(host, INTMASK); |
873 | if (enb) { | 900 | if (enb) { |
901 | /* | ||
902 | * Turn off low power mode if it was enabled. This is a bit of | ||
903 | * a heavy operation and we disable / enable IRQs a lot, so | ||
904 | * we'll leave low power mode disabled and it will get | ||
905 | * re-enabled again in dw_mci_setup_bus(). | ||
906 | */ | ||
907 | dw_mci_disable_low_power(slot); | ||
908 | |||
874 | mci_writel(host, INTMASK, | 909 | mci_writel(host, INTMASK, |
875 | (int_mask | SDMMC_INT_SDIO(slot->id))); | 910 | (int_mask | SDMMC_INT_SDIO(slot->id))); |
876 | } else { | 911 | } else { |
@@ -1429,22 +1464,10 @@ static void dw_mci_read_data_pio(struct dw_mci *host) | |||
1429 | nbytes += len; | 1464 | nbytes += len; |
1430 | remain -= len; | 1465 | remain -= len; |
1431 | } while (remain); | 1466 | } while (remain); |
1432 | sg_miter->consumed = offset; | ||
1433 | 1467 | ||
1468 | sg_miter->consumed = offset; | ||
1434 | status = mci_readl(host, MINTSTS); | 1469 | status = mci_readl(host, MINTSTS); |
1435 | mci_writel(host, RINTSTS, SDMMC_INT_RXDR); | 1470 | mci_writel(host, RINTSTS, SDMMC_INT_RXDR); |
1436 | if (status & DW_MCI_DATA_ERROR_FLAGS) { | ||
1437 | host->data_status = status; | ||
1438 | data->bytes_xfered += nbytes; | ||
1439 | sg_miter_stop(sg_miter); | ||
1440 | host->sg = NULL; | ||
1441 | smp_wmb(); | ||
1442 | |||
1443 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | ||
1444 | |||
1445 | tasklet_schedule(&host->tasklet); | ||
1446 | return; | ||
1447 | } | ||
1448 | } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ | 1471 | } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ |
1449 | data->bytes_xfered += nbytes; | 1472 | data->bytes_xfered += nbytes; |
1450 | 1473 | ||
@@ -1497,23 +1520,10 @@ static void dw_mci_write_data_pio(struct dw_mci *host) | |||
1497 | nbytes += len; | 1520 | nbytes += len; |
1498 | remain -= len; | 1521 | remain -= len; |
1499 | } while (remain); | 1522 | } while (remain); |
1500 | sg_miter->consumed = offset; | ||
1501 | 1523 | ||
1524 | sg_miter->consumed = offset; | ||
1502 | status = mci_readl(host, MINTSTS); | 1525 | status = mci_readl(host, MINTSTS); |
1503 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR); | 1526 | mci_writel(host, RINTSTS, SDMMC_INT_TXDR); |
1504 | if (status & DW_MCI_DATA_ERROR_FLAGS) { | ||
1505 | host->data_status = status; | ||
1506 | data->bytes_xfered += nbytes; | ||
1507 | sg_miter_stop(sg_miter); | ||
1508 | host->sg = NULL; | ||
1509 | |||
1510 | smp_wmb(); | ||
1511 | |||
1512 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | ||
1513 | |||
1514 | tasklet_schedule(&host->tasklet); | ||
1515 | return; | ||
1516 | } | ||
1517 | } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ | 1527 | } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ |
1518 | data->bytes_xfered += nbytes; | 1528 | data->bytes_xfered += nbytes; |
1519 | 1529 | ||
@@ -1547,12 +1557,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) | |||
1547 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | 1557 | static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) |
1548 | { | 1558 | { |
1549 | struct dw_mci *host = dev_id; | 1559 | struct dw_mci *host = dev_id; |
1550 | u32 status, pending; | 1560 | u32 pending; |
1551 | unsigned int pass_count = 0; | 1561 | unsigned int pass_count = 0; |
1552 | int i; | 1562 | int i; |
1553 | 1563 | ||
1554 | do { | 1564 | do { |
1555 | status = mci_readl(host, RINTSTS); | ||
1556 | pending = mci_readl(host, MINTSTS); /* read-only mask reg */ | 1565 | pending = mci_readl(host, MINTSTS); /* read-only mask reg */ |
1557 | 1566 | ||
1558 | /* | 1567 | /* |
@@ -1570,7 +1579,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1570 | 1579 | ||
1571 | if (pending & DW_MCI_CMD_ERROR_FLAGS) { | 1580 | if (pending & DW_MCI_CMD_ERROR_FLAGS) { |
1572 | mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); | 1581 | mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); |
1573 | host->cmd_status = status; | 1582 | host->cmd_status = pending; |
1574 | smp_wmb(); | 1583 | smp_wmb(); |
1575 | set_bit(EVENT_CMD_COMPLETE, &host->pending_events); | 1584 | set_bit(EVENT_CMD_COMPLETE, &host->pending_events); |
1576 | } | 1585 | } |
@@ -1578,18 +1587,16 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1578 | if (pending & DW_MCI_DATA_ERROR_FLAGS) { | 1587 | if (pending & DW_MCI_DATA_ERROR_FLAGS) { |
1579 | /* if there is an error report DATA_ERROR */ | 1588 | /* if there is an error report DATA_ERROR */ |
1580 | mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); | 1589 | mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); |
1581 | host->data_status = status; | 1590 | host->data_status = pending; |
1582 | smp_wmb(); | 1591 | smp_wmb(); |
1583 | set_bit(EVENT_DATA_ERROR, &host->pending_events); | 1592 | set_bit(EVENT_DATA_ERROR, &host->pending_events); |
1584 | if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | | 1593 | tasklet_schedule(&host->tasklet); |
1585 | SDMMC_INT_SBE | SDMMC_INT_EBE))) | ||
1586 | tasklet_schedule(&host->tasklet); | ||
1587 | } | 1594 | } |
1588 | 1595 | ||
1589 | if (pending & SDMMC_INT_DATA_OVER) { | 1596 | if (pending & SDMMC_INT_DATA_OVER) { |
1590 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); | 1597 | mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); |
1591 | if (!host->data_status) | 1598 | if (!host->data_status) |
1592 | host->data_status = status; | 1599 | host->data_status = pending; |
1593 | smp_wmb(); | 1600 | smp_wmb(); |
1594 | if (host->dir_status == DW_MCI_RECV_STATUS) { | 1601 | if (host->dir_status == DW_MCI_RECV_STATUS) { |
1595 | if (host->sg != NULL) | 1602 | if (host->sg != NULL) |
@@ -1613,7 +1620,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) | |||
1613 | 1620 | ||
1614 | if (pending & SDMMC_INT_CMD_DONE) { | 1621 | if (pending & SDMMC_INT_CMD_DONE) { |
1615 | mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); | 1622 | mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); |
1616 | dw_mci_cmd_interrupt(host, status); | 1623 | dw_mci_cmd_interrupt(host, pending); |
1617 | } | 1624 | } |
1618 | 1625 | ||
1619 | if (pending & SDMMC_INT_CD) { | 1626 | if (pending & SDMMC_INT_CD) { |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index a51f9309ffbb..ad3fcea1269e 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -285,11 +285,11 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id) | |||
285 | writel(stat & MXS_MMC_IRQ_BITS, | 285 | writel(stat & MXS_MMC_IRQ_BITS, |
286 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); | 286 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR); |
287 | 287 | ||
288 | spin_unlock(&host->lock); | ||
289 | |||
288 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) | 290 | if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) |
289 | mmc_signal_sdio_irq(host->mmc); | 291 | mmc_signal_sdio_irq(host->mmc); |
290 | 292 | ||
291 | spin_unlock(&host->lock); | ||
292 | |||
293 | if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) | 293 | if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ) |
294 | cmd->error = -ETIMEDOUT; | 294 | cmd->error = -ETIMEDOUT; |
295 | else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) | 295 | else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ) |
@@ -644,11 +644,6 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
644 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); | 644 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET); |
645 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, | 645 | writel(BM_SSP_CTRL1_SDIO_IRQ_EN, |
646 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); | 646 | host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET); |
647 | |||
648 | if (readl(host->base + HW_SSP_STATUS(host)) & | ||
649 | BM_SSP_STATUS_SDIO_IRQ) | ||
650 | mmc_signal_sdio_irq(host->mmc); | ||
651 | |||
652 | } else { | 647 | } else { |
653 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, | 648 | writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, |
654 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); | 649 | host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR); |
@@ -657,6 +652,11 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) | |||
657 | } | 652 | } |
658 | 653 | ||
659 | spin_unlock_irqrestore(&host->lock, flags); | 654 | spin_unlock_irqrestore(&host->lock, flags); |
655 | |||
656 | if (enable && readl(host->base + HW_SSP_STATUS(host)) & | ||
657 | BM_SSP_STATUS_SDIO_IRQ) | ||
658 | mmc_signal_sdio_irq(host->mmc); | ||
659 | |||
660 | } | 660 | } |
661 | 661 | ||
662 | static const struct mmc_host_ops mxs_mmc_ops = { | 662 | static const struct mmc_host_ops mxs_mmc_ops = { |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 50e08f03aa65..a5999a74496a 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -668,7 +668,7 @@ mmc_omap_clk_timer(unsigned long data) | |||
668 | static void | 668 | static void |
669 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | 669 | mmc_omap_xfer_data(struct mmc_omap_host *host, int write) |
670 | { | 670 | { |
671 | int n; | 671 | int n, nwords; |
672 | 672 | ||
673 | if (host->buffer_bytes_left == 0) { | 673 | if (host->buffer_bytes_left == 0) { |
674 | host->sg_idx++; | 674 | host->sg_idx++; |
@@ -678,15 +678,23 @@ mmc_omap_xfer_data(struct mmc_omap_host *host, int write) | |||
678 | n = 64; | 678 | n = 64; |
679 | if (n > host->buffer_bytes_left) | 679 | if (n > host->buffer_bytes_left) |
680 | n = host->buffer_bytes_left; | 680 | n = host->buffer_bytes_left; |
681 | |||
682 | nwords = n / 2; | ||
683 | nwords += n & 1; /* handle odd number of bytes to transfer */ | ||
684 | |||
681 | host->buffer_bytes_left -= n; | 685 | host->buffer_bytes_left -= n; |
682 | host->total_bytes_left -= n; | 686 | host->total_bytes_left -= n; |
683 | host->data->bytes_xfered += n; | 687 | host->data->bytes_xfered += n; |
684 | 688 | ||
685 | if (write) { | 689 | if (write) { |
686 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 690 | __raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), |
691 | host->buffer, nwords); | ||
687 | } else { | 692 | } else { |
688 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n); | 693 | __raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), |
694 | host->buffer, nwords); | ||
689 | } | 695 | } |
696 | |||
697 | host->buffer += nwords; | ||
690 | } | 698 | } |
691 | 699 | ||
692 | static inline void mmc_omap_report_irq(u16 status) | 700 | static inline void mmc_omap_report_irq(u16 status) |
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index b97b2f5dafdb..d25f9ab9a54d 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h | |||
@@ -48,14 +48,14 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | |||
48 | int div = 1; | 48 | int div = 1; |
49 | u32 temp; | 49 | u32 temp; |
50 | 50 | ||
51 | if (clock == 0) | ||
52 | goto out; | ||
53 | |||
51 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); | 54 | temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); |
52 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | 55 | temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
53 | | ESDHC_CLOCK_MASK); | 56 | | ESDHC_CLOCK_MASK); |
54 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 57 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
55 | 58 | ||
56 | if (clock == 0) | ||
57 | goto out; | ||
58 | |||
59 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) | 59 | while (host->max_clk / pre_div / 16 > clock && pre_div < 256) |
60 | pre_div *= 2; | 60 | pre_div *= 2; |
61 | 61 | ||
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index cfff454f628b..c3bb304eca07 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
@@ -19,14 +19,13 @@ | |||
19 | #include <linux/mtd/map.h> | 19 | #include <linux/mtd/map.h> |
20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <asm/sections.h> | ||
22 | 23 | ||
23 | /****************************************************************************/ | 24 | /****************************************************************************/ |
24 | 25 | ||
25 | extern char _ebss; | ||
26 | |||
27 | struct map_info uclinux_ram_map = { | 26 | struct map_info uclinux_ram_map = { |
28 | .name = "RAM", | 27 | .name = "RAM", |
29 | .phys = (unsigned long)&_ebss, | 28 | .phys = (unsigned long)__bss_stop, |
30 | .size = 0, | 29 | .size = 0, |
31 | }; | 30 | }; |
32 | 31 | ||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 31bb7e5b504a..8ca417614c57 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -480,7 +480,7 @@ config MTD_NAND_NANDSIM | |||
480 | 480 | ||
481 | config MTD_NAND_GPMI_NAND | 481 | config MTD_NAND_GPMI_NAND |
482 | bool "GPMI NAND Flash Controller driver" | 482 | bool "GPMI NAND Flash Controller driver" |
483 | depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q) | 483 | depends on MTD_NAND && MXS_DMA |
484 | help | 484 | help |
485 | Enables NAND Flash support for IMX23 or IMX28. | 485 | Enables NAND Flash support for IMX23 or IMX28. |
486 | The GPMI controller is very powerful, with the help of BCH | 486 | The GPMI controller is very powerful, with the help of BCH |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index e9309b3659e7..ac4fd756eda3 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1245,7 +1245,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1245 | goto out_release_mem_region; | 1245 | goto out_release_mem_region; |
1246 | } else { | 1246 | } else { |
1247 | struct dma_slave_config cfg; | 1247 | struct dma_slave_config cfg; |
1248 | int rc; | ||
1249 | 1248 | ||
1250 | memset(&cfg, 0, sizeof(cfg)); | 1249 | memset(&cfg, 0, sizeof(cfg)); |
1251 | cfg.src_addr = info->phys_base; | 1250 | cfg.src_addr = info->phys_base; |
@@ -1254,10 +1253,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1254 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 1253 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
1255 | cfg.src_maxburst = 16; | 1254 | cfg.src_maxburst = 16; |
1256 | cfg.dst_maxburst = 16; | 1255 | cfg.dst_maxburst = 16; |
1257 | rc = dmaengine_slave_config(info->dma, &cfg); | 1256 | err = dmaengine_slave_config(info->dma, &cfg); |
1258 | if (rc) { | 1257 | if (err) { |
1259 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", | 1258 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", |
1260 | rc); | 1259 | err); |
1261 | goto out_release_mem_region; | 1260 | goto out_release_mem_region; |
1262 | } | 1261 | } |
1263 | info->nand.read_buf = omap_read_buf_dma_pref; | 1262 | info->nand.read_buf = omap_read_buf_dma_pref; |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 437bc193e170..568307cc7caf 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -340,7 +340,7 @@ retry: | |||
340 | * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. | 340 | * of this LEB as it will be deleted and freed in 'ubi_add_to_av()'. |
341 | */ | 341 | */ |
342 | err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); | 342 | err = ubi_add_to_av(ubi, ai, new_aeb->pnum, new_aeb->ec, vid_hdr, 0); |
343 | kfree(new_aeb); | 343 | kmem_cache_free(ai->aeb_slab_cache, new_aeb); |
344 | ubi_free_vid_hdr(ubi, vid_hdr); | 344 | ubi_free_vid_hdr(ubi, vid_hdr); |
345 | return err; | 345 | return err; |
346 | 346 | ||
@@ -353,7 +353,7 @@ write_error: | |||
353 | list_add(&new_aeb->u.list, &ai->erase); | 353 | list_add(&new_aeb->u.list, &ai->erase); |
354 | goto retry; | 354 | goto retry; |
355 | } | 355 | } |
356 | kfree(new_aeb); | 356 | kmem_cache_free(ai->aeb_slab_cache, new_aeb); |
357 | out_free: | 357 | out_free: |
358 | ubi_free_vid_hdr(ubi, vid_hdr); | 358 | ubi_free_vid_hdr(ubi, vid_hdr); |
359 | return err; | 359 | return err; |
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 545c09ed9079..cff6f023c03a 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c | |||
@@ -996,9 +996,7 @@ static int __init cops_module_init(void) | |||
996 | printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", | 996 | printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", |
997 | cardname); | 997 | cardname); |
998 | cops_dev = cops_probe(-1); | 998 | cops_dev = cops_probe(-1); |
999 | if (IS_ERR(cops_dev)) | 999 | return PTR_RET(cops_dev); |
1000 | return PTR_ERR(cops_dev); | ||
1001 | return 0; | ||
1002 | } | 1000 | } |
1003 | 1001 | ||
1004 | static void __exit cops_module_exit(void) | 1002 | static void __exit cops_module_exit(void) |
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 0910dce3996d..b5782cdf0bca 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c | |||
@@ -1243,9 +1243,7 @@ static int __init ltpc_module_init(void) | |||
1243 | "ltpc: Autoprobing is not recommended for modules\n"); | 1243 | "ltpc: Autoprobing is not recommended for modules\n"); |
1244 | 1244 | ||
1245 | dev_ltpc = ltpc_probe(); | 1245 | dev_ltpc = ltpc_probe(); |
1246 | if (IS_ERR(dev_ltpc)) | 1246 | return PTR_RET(dev_ltpc); |
1247 | return PTR_ERR(dev_ltpc); | ||
1248 | return 0; | ||
1249 | } | 1247 | } |
1250 | module_init(ltpc_module_init); | 1248 | module_init(ltpc_module_init); |
1251 | #endif | 1249 | #endif |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6fae5f3ec7f6..d688a8af432c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -398,7 +398,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, | |||
398 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); | 398 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); |
399 | skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; | 399 | skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; |
400 | 400 | ||
401 | if (unlikely(netpoll_tx_running(slave_dev))) | 401 | if (unlikely(netpoll_tx_running(bond->dev))) |
402 | bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); | 402 | bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); |
403 | else | 403 | else |
404 | dev_queue_xmit(skb); | 404 | dev_queue_xmit(skb); |
@@ -1235,12 +1235,12 @@ static inline int slave_enable_netpoll(struct slave *slave) | |||
1235 | struct netpoll *np; | 1235 | struct netpoll *np; |
1236 | int err = 0; | 1236 | int err = 0; |
1237 | 1237 | ||
1238 | np = kzalloc(sizeof(*np), GFP_KERNEL); | 1238 | np = kzalloc(sizeof(*np), GFP_ATOMIC); |
1239 | err = -ENOMEM; | 1239 | err = -ENOMEM; |
1240 | if (!np) | 1240 | if (!np) |
1241 | goto out; | 1241 | goto out; |
1242 | 1242 | ||
1243 | err = __netpoll_setup(np, slave->dev); | 1243 | err = __netpoll_setup(np, slave->dev, GFP_ATOMIC); |
1244 | if (err) { | 1244 | if (err) { |
1245 | kfree(np); | 1245 | kfree(np); |
1246 | goto out; | 1246 | goto out; |
@@ -1257,9 +1257,7 @@ static inline void slave_disable_netpoll(struct slave *slave) | |||
1257 | return; | 1257 | return; |
1258 | 1258 | ||
1259 | slave->np = NULL; | 1259 | slave->np = NULL; |
1260 | synchronize_rcu_bh(); | 1260 | __netpoll_free_rcu(np); |
1261 | __netpoll_cleanup(np); | ||
1262 | kfree(np); | ||
1263 | } | 1261 | } |
1264 | static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) | 1262 | static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) |
1265 | { | 1263 | { |
@@ -1292,7 +1290,7 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) | |||
1292 | read_unlock(&bond->lock); | 1290 | read_unlock(&bond->lock); |
1293 | } | 1291 | } |
1294 | 1292 | ||
1295 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) | 1293 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp) |
1296 | { | 1294 | { |
1297 | struct bonding *bond = netdev_priv(dev); | 1295 | struct bonding *bond = netdev_priv(dev); |
1298 | struct slave *slave; | 1296 | struct slave *slave; |
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c index 98ee43819911..7edadee487ba 100644 --- a/drivers/net/can/janz-ican3.c +++ b/drivers/net/can/janz-ican3.c | |||
@@ -1391,7 +1391,6 @@ static irqreturn_t ican3_irq(int irq, void *dev_id) | |||
1391 | */ | 1391 | */ |
1392 | static int ican3_reset_module(struct ican3_dev *mod) | 1392 | static int ican3_reset_module(struct ican3_dev *mod) |
1393 | { | 1393 | { |
1394 | u8 val = 1 << mod->num; | ||
1395 | unsigned long start; | 1394 | unsigned long start; |
1396 | u8 runold, runnew; | 1395 | u8 runold, runnew; |
1397 | 1396 | ||
@@ -1405,8 +1404,7 @@ static int ican3_reset_module(struct ican3_dev *mod) | |||
1405 | runold = ioread8(mod->dpm + TARGET_RUNNING); | 1404 | runold = ioread8(mod->dpm + TARGET_RUNNING); |
1406 | 1405 | ||
1407 | /* reset the module */ | 1406 | /* reset the module */ |
1408 | iowrite8(val, &mod->ctrl->reset_assert); | 1407 | iowrite8(0x00, &mod->dpmctrl->hwreset); |
1409 | iowrite8(val, &mod->ctrl->reset_deassert); | ||
1410 | 1408 | ||
1411 | /* wait until the module has finished resetting and is running */ | 1409 | /* wait until the module has finished resetting and is running */ |
1412 | start = jiffies; | 1410 | start = jiffies; |
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e503..26e7129332ab 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -83,6 +83,11 @@ | |||
83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) | 83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) |
84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) | 84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) |
85 | #define INSTRUCTION_RESET 0xC0 | 85 | #define INSTRUCTION_RESET 0xC0 |
86 | #define RTS_TXB0 0x01 | ||
87 | #define RTS_TXB1 0x02 | ||
88 | #define RTS_TXB2 0x04 | ||
89 | #define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) | ||
90 | |||
86 | 91 | ||
87 | /* MPC251x registers */ | 92 | /* MPC251x registers */ |
88 | #define CANSTAT 0x0e | 93 | #define CANSTAT 0x0e |
@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, | |||
397 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | 402 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, |
398 | int tx_buf_idx) | 403 | int tx_buf_idx) |
399 | { | 404 | { |
405 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | ||
400 | u32 sid, eid, exide, rtr; | 406 | u32 sid, eid, exide, rtr; |
401 | u8 buf[SPI_TRANSFER_BUF_LEN]; | 407 | u8 buf[SPI_TRANSFER_BUF_LEN]; |
402 | 408 | ||
@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | |||
418 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; | 424 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; |
419 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); | 425 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); |
420 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); | 426 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); |
421 | mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); | 427 | |
428 | /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ | ||
429 | priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); | ||
430 | mcp251x_spi_trans(priv->spi, 1); | ||
422 | } | 431 | } |
423 | 432 | ||
424 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, | 433 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, |
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c index 4f50145f6483..662c5f7eb0c5 100644 --- a/drivers/net/can/sja1000/sja1000_platform.c +++ b/drivers/net/can/sja1000/sja1000_platform.c | |||
@@ -109,7 +109,9 @@ static int sp_probe(struct platform_device *pdev) | |||
109 | priv = netdev_priv(dev); | 109 | priv = netdev_priv(dev); |
110 | 110 | ||
111 | dev->irq = res_irq->start; | 111 | dev->irq = res_irq->start; |
112 | priv->irq_flags = res_irq->flags & (IRQF_TRIGGER_MASK | IRQF_SHARED); | 112 | priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; |
113 | if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) | ||
114 | priv->irq_flags |= IRQF_SHARED; | ||
113 | priv->reg_base = addr; | 115 | priv->reg_base = addr; |
114 | /* The CAN clock frequency is half the oscillator clock frequency */ | 116 | /* The CAN clock frequency is half the oscillator clock frequency */ |
115 | priv->can.clock.freq = pdata->osc_freq / 2; | 117 | priv->can.clock.freq = pdata->osc_freq / 2; |
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index 310596175676..b595d3422b9f 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c | |||
@@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card, | |||
150 | const uint8_t *mem, *end, *dat; | 150 | const uint8_t *mem, *end, *dat; |
151 | uint16_t type, len; | 151 | uint16_t type, len; |
152 | uint32_t addr; | 152 | uint32_t addr; |
153 | uint8_t *buf = NULL; | 153 | uint8_t *buf = NULL, *new_buf; |
154 | int buflen = 0; | 154 | int buflen = 0; |
155 | int8_t type_end = 0; | 155 | int8_t type_end = 0; |
156 | 156 | ||
@@ -199,11 +199,12 @@ int softing_load_fw(const char *file, struct softing *card, | |||
199 | if (len > buflen) { | 199 | if (len > buflen) { |
200 | /* align buflen */ | 200 | /* align buflen */ |
201 | buflen = (len + (1024-1)) & ~(1024-1); | 201 | buflen = (len + (1024-1)) & ~(1024-1); |
202 | buf = krealloc(buf, buflen, GFP_KERNEL); | 202 | new_buf = krealloc(buf, buflen, GFP_KERNEL); |
203 | if (!buf) { | 203 | if (!new_buf) { |
204 | ret = -ENOMEM; | 204 | ret = -ENOMEM; |
205 | goto failed; | 205 | goto failed; |
206 | } | 206 | } |
207 | buf = new_buf; | ||
207 | } | 208 | } |
208 | /* verify record data */ | 209 | /* verify record data */ |
209 | memcpy_fromio(buf, &dpram[addr + offset], len); | 210 | memcpy_fromio(buf, &dpram[addr + offset], len); |
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 527dbcf95335..9ded21e79db5 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -984,12 +984,12 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev) | |||
984 | struct net_device *ndev = platform_get_drvdata(pdev); | 984 | struct net_device *ndev = platform_get_drvdata(pdev); |
985 | struct ti_hecc_priv *priv = netdev_priv(ndev); | 985 | struct ti_hecc_priv *priv = netdev_priv(ndev); |
986 | 986 | ||
987 | unregister_candev(ndev); | ||
987 | clk_disable(priv->clk); | 988 | clk_disable(priv->clk); |
988 | clk_put(priv->clk); | 989 | clk_put(priv->clk); |
989 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 990 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
990 | iounmap(priv->base); | 991 | iounmap(priv->base); |
991 | release_mem_region(res->start, resource_size(res)); | 992 | release_mem_region(res->start, resource_size(res)); |
992 | unregister_candev(ndev); | ||
993 | free_candev(ndev); | 993 | free_candev(ndev); |
994 | platform_set_drvdata(pdev, NULL); | 994 | platform_set_drvdata(pdev, NULL); |
995 | 995 | ||
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index f0c8bd54ce29..021d69c5d9bc 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
@@ -1712,7 +1712,7 @@ e100_set_network_leds(int active) | |||
1712 | static void | 1712 | static void |
1713 | e100_netpoll(struct net_device* netdev) | 1713 | e100_netpoll(struct net_device* netdev) |
1714 | { | 1714 | { |
1715 | e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); | 1715 | e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev); |
1716 | } | 1716 | } |
1717 | #endif | 1717 | #endif |
1718 | 1718 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 77bcd4cb4ffb..6d1a24acb77e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1278,7 +1278,7 @@ struct bnx2x { | |||
1278 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) | 1278 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) |
1279 | 1279 | ||
1280 | #define BNX2X_FW_RX_ALIGN_END \ | 1280 | #define BNX2X_FW_RX_ALIGN_END \ |
1281 | max(1UL << BNX2X_RX_ALIGN_SHIFT, \ | 1281 | max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT, \ |
1282 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | 1282 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) |
1283 | 1283 | ||
1284 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) | 1284 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) |
@@ -1708,9 +1708,6 @@ struct bnx2x_func_init_params { | |||
1708 | continue; \ | 1708 | continue; \ |
1709 | else | 1709 | else |
1710 | 1710 | ||
1711 | #define for_each_napi_rx_queue(bp, var) \ | ||
1712 | for ((var) = 0; (var) < bp->num_napi_queues; (var)++) | ||
1713 | |||
1714 | /* Skip OOO FP */ | 1711 | /* Skip OOO FP */ |
1715 | #define for_each_tx_queue(bp, var) \ | 1712 | #define for_each_tx_queue(bp, var) \ |
1716 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ | 1713 | for ((var) = 0; (var) < BNX2X_NUM_QUEUES(bp); (var)++) \ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e879e19eb0d6..e8e97a7d1d06 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -662,14 +662,16 @@ void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, | |||
662 | struct bnx2x_fastpath *fp, | 662 | struct bnx2x_fastpath *fp, |
663 | struct bnx2x_eth_q_stats *qstats) | 663 | struct bnx2x_eth_q_stats *qstats) |
664 | { | 664 | { |
665 | /* Do nothing if no IP/L4 csum validation was done */ | 665 | /* Do nothing if no L4 csum validation was done. |
666 | 666 | * We do not check whether IP csum was validated. For IPv4 we assume | |
667 | * that if the card got as far as validating the L4 csum, it also | ||
668 | * validated the IP csum. IPv6 has no IP csum. | ||
669 | */ | ||
667 | if (cqe->fast_path_cqe.status_flags & | 670 | if (cqe->fast_path_cqe.status_flags & |
668 | (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | | 671 | ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) |
669 | ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)) | ||
670 | return; | 672 | return; |
671 | 673 | ||
672 | /* If both IP/L4 validation were done, check if an error was found. */ | 674 | /* If L4 validation was done, check if an error was found. */ |
673 | 675 | ||
674 | if (cqe->fast_path_cqe.type_error_flags & | 676 | if (cqe->fast_path_cqe.type_error_flags & |
675 | (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | | 677 | (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | |
@@ -2046,6 +2048,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
2046 | */ | 2048 | */ |
2047 | bnx2x_setup_tc(bp->dev, bp->max_cos); | 2049 | bnx2x_setup_tc(bp->dev, bp->max_cos); |
2048 | 2050 | ||
2051 | /* Add all NAPI objects */ | ||
2052 | bnx2x_add_all_napi(bp); | ||
2049 | bnx2x_napi_enable(bp); | 2053 | bnx2x_napi_enable(bp); |
2050 | 2054 | ||
2051 | /* set pf load just before approaching the MCP */ | 2055 | /* set pf load just before approaching the MCP */ |
@@ -2408,6 +2412,8 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) | |||
2408 | 2412 | ||
2409 | /* Disable HW interrupts, NAPI */ | 2413 | /* Disable HW interrupts, NAPI */ |
2410 | bnx2x_netif_stop(bp, 1); | 2414 | bnx2x_netif_stop(bp, 1); |
2415 | /* Delete all NAPI objects */ | ||
2416 | bnx2x_del_all_napi(bp); | ||
2411 | 2417 | ||
2412 | /* Release IRQs */ | 2418 | /* Release IRQs */ |
2413 | bnx2x_free_irq(bp); | 2419 | bnx2x_free_irq(bp); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index dfa757e74296..dfd86a55f1dc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp, | |||
710 | prod = txdata->tx_bd_prod; | 710 | prod = txdata->tx_bd_prod; |
711 | cons = txdata->tx_bd_cons; | 711 | cons = txdata->tx_bd_cons; |
712 | 712 | ||
713 | /* NUM_TX_RINGS = number of "next-page" entries | 713 | used = SUB_S16(prod, cons); |
714 | It will be used as a threshold */ | ||
715 | used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; | ||
716 | 714 | ||
717 | #ifdef BNX2X_STOP_ON_ERROR | 715 | #ifdef BNX2X_STOP_ON_ERROR |
718 | WARN_ON(used < 0); | 716 | WARN_ON(used < 0); |
719 | WARN_ON(used > bp->tx_ring_size); | 717 | WARN_ON(used > txdata->tx_ring_size); |
720 | WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); | 718 | WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL); |
721 | #endif | 719 | #endif |
722 | 720 | ||
723 | return (s16)(bp->tx_ring_size) - used; | 721 | return (s16)(txdata->tx_ring_size) - used; |
724 | } | 722 | } |
725 | 723 | ||
726 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) | 724 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) |
@@ -792,7 +790,7 @@ static inline void bnx2x_add_all_napi(struct bnx2x *bp) | |||
792 | bp->num_napi_queues = bp->num_queues; | 790 | bp->num_napi_queues = bp->num_queues; |
793 | 791 | ||
794 | /* Add NAPI objects */ | 792 | /* Add NAPI objects */ |
795 | for_each_napi_rx_queue(bp, i) | 793 | for_each_rx_queue(bp, i) |
796 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), | 794 | netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), |
797 | bnx2x_poll, BNX2X_NAPI_WEIGHT); | 795 | bnx2x_poll, BNX2X_NAPI_WEIGHT); |
798 | } | 796 | } |
@@ -801,7 +799,7 @@ static inline void bnx2x_del_all_napi(struct bnx2x *bp) | |||
801 | { | 799 | { |
802 | int i; | 800 | int i; |
803 | 801 | ||
804 | for_each_napi_rx_queue(bp, i) | 802 | for_each_rx_queue(bp, i) |
805 | netif_napi_del(&bnx2x_fp(bp, i, napi)); | 803 | netif_napi_del(&bnx2x_fp(bp, i, napi)); |
806 | } | 804 | } |
807 | 805 | ||
@@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, | |||
1088 | txdata->txq_index = txq_index; | 1086 | txdata->txq_index = txq_index; |
1089 | txdata->tx_cons_sb = tx_cons_sb; | 1087 | txdata->tx_cons_sb = tx_cons_sb; |
1090 | txdata->parent_fp = fp; | 1088 | txdata->parent_fp = fp; |
1089 | txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size; | ||
1091 | 1090 | ||
1092 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", | 1091 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", |
1093 | txdata->cid, txdata->txq_index); | 1092 | txdata->cid, txdata->txq_index); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1ebe..b926f58e983b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | |||
@@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = { | |||
401 | { 0x70000, 8, RI_ALL_ONLINE }, | 401 | { 0x70000, 8, RI_ALL_ONLINE }, |
402 | { 0x70020, 8184, RI_ALL_OFFLINE }, | 402 | { 0x70020, 8184, RI_ALL_OFFLINE }, |
403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, | 403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, |
404 | { 0x85000, 3, RI_ALL_ONLINE }, | 404 | { 0x85000, 3, RI_ALL_OFFLINE }, |
405 | { 0x8501c, 7, RI_ALL_ONLINE }, | 405 | { 0x8501c, 7, RI_ALL_OFFLINE }, |
406 | { 0x85048, 1, RI_ALL_ONLINE }, | 406 | { 0x85048, 1, RI_ALL_OFFLINE }, |
407 | { 0x85200, 32, RI_ALL_ONLINE }, | 407 | { 0x85200, 32, RI_ALL_OFFLINE }, |
408 | { 0xb0000, 16384, RI_E1H_ONLINE }, | 408 | { 0xb0000, 16384, RI_E1H_OFFLINE }, |
409 | { 0xc1000, 7, RI_ALL_ONLINE }, | 409 | { 0xc1000, 7, RI_ALL_ONLINE }, |
410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, | 410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, |
411 | { 0xc1800, 2, RI_ALL_ONLINE }, | 411 | { 0xc1800, 2, RI_ALL_ONLINE }, |
@@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = { | |||
581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, | 581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, |
582 | { 0x140194, 13, RI_ALL_ONLINE }, | 582 | { 0x140194, 13, RI_ALL_ONLINE }, |
583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, | 583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, |
584 | { 0x140220, 4, RI_E2E3_ONLINE }, | ||
585 | { 0x140240, 4, RI_E2E3_ONLINE }, | ||
586 | { 0x140260, 4, RI_E2E3_ONLINE }, | 584 | { 0x140260, 4, RI_E2E3_ONLINE }, |
587 | { 0x140280, 4, RI_E2E3_ONLINE }, | 585 | { 0x140280, 4, RI_E2E3_ONLINE }, |
588 | { 0x1402a0, 4, RI_E2E3_ONLINE }, | ||
589 | { 0x1402c0, 4, RI_E2E3_ONLINE }, | ||
590 | { 0x1402e0, 2, RI_E2E3_ONLINE }, | 586 | { 0x1402e0, 2, RI_E2E3_ONLINE }, |
591 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, | 587 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, |
592 | { 0x1402f0, 9, RI_E2E3_ONLINE }, | 588 | { 0x1402f0, 9, RI_E2E3_ONLINE }, |
593 | { 0x140314, 44, RI_E3B0_ONLINE }, | 589 | { 0x140314, 44, RI_E3B0_ONLINE }, |
594 | { 0x1403d0, 70, RI_E3B0_ONLINE }, | ||
595 | { 0x144000, 4, RI_E1E1H_ONLINE }, | 590 | { 0x144000, 4, RI_E1E1H_ONLINE }, |
596 | { 0x148000, 4, RI_E1E1H_ONLINE }, | 591 | { 0x148000, 4, RI_E1E1H_ONLINE }, |
597 | { 0x14c000, 4, RI_E1E1H_ONLINE }, | 592 | { 0x14c000, 4, RI_E1E1H_ONLINE }, |
@@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = { | |||
704 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, | 699 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, |
705 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, | 700 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, |
706 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, | 701 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, |
707 | { 0x180400, 1, RI_ALL_ONLINE }, | ||
708 | { 0x180404, 255, RI_E1E1H_OFFLINE }, | 702 | { 0x180404, 255, RI_E1E1H_OFFLINE }, |
709 | { 0x181000, 4, RI_ALL_ONLINE }, | 703 | { 0x181000, 4, RI_ALL_ONLINE }, |
710 | { 0x181010, 1020, RI_ALL_OFFLINE }, | 704 | { 0x181010, 1020, RI_ALL_OFFLINE }, |
@@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = { | |||
800 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, | 794 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, |
801 | { 0x1b9064, 1, RI_E3B0_ONLINE }, | 795 | { 0x1b9064, 1, RI_E3B0_ONLINE }, |
802 | { 0x1b9080, 10, RI_E3B0_ONLINE }, | 796 | { 0x1b9080, 10, RI_E3B0_ONLINE }, |
803 | { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, | 797 | { 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, |
804 | { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, | 798 | { 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, |
805 | { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, | 799 | { 0x1b9490, 10, RI_E2E3E3B0_OFFLINE }, |
806 | { 0x1c0000, 2, RI_ALL_ONLINE }, | 800 | { 0x1c0000, 2, RI_ALL_ONLINE }, |
807 | { 0x200000, 65, RI_ALL_ONLINE }, | 801 | { 0x200000, 65, RI_ALL_ONLINE }, |
808 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, | 802 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, |
@@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = { | |||
814 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, | 808 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, |
815 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, | 809 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, |
816 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, | 810 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, |
817 | { 0x200400, 1, RI_ALL_ONLINE }, | ||
818 | { 0x200404, 255, RI_E1E1H_OFFLINE }, | 811 | { 0x200404, 255, RI_E1E1H_OFFLINE }, |
819 | { 0x202000, 4, RI_ALL_ONLINE }, | 812 | { 0x202000, 4, RI_ALL_ONLINE }, |
820 | { 0x202010, 2044, RI_ALL_OFFLINE }, | 813 | { 0x202010, 2044, RI_ALL_OFFLINE }, |
@@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = { | |||
921 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, | 914 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, |
922 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, | 915 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, |
923 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, | 916 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, |
924 | { 0x280400, 1, RI_ALL_ONLINE }, | ||
925 | { 0x280404, 255, RI_E1E1H_OFFLINE }, | 917 | { 0x280404, 255, RI_E1E1H_OFFLINE }, |
926 | { 0x282000, 4, RI_ALL_ONLINE }, | 918 | { 0x282000, 4, RI_ALL_ONLINE }, |
927 | { 0x282010, 2044, RI_ALL_OFFLINE }, | 919 | { 0x282010, 2044, RI_ALL_OFFLINE }, |
@@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = { | |||
1031 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, | 1023 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, |
1032 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, | 1024 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, |
1033 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, | 1025 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, |
1034 | { 0x300400, 1, RI_ALL_ONLINE }, | ||
1035 | { 0x300404, 255, RI_E1E1H_OFFLINE }, | 1026 | { 0x300404, 255, RI_E1E1H_OFFLINE }, |
1036 | { 0x302000, 4, RI_ALL_ONLINE }, | 1027 | { 0x302000, 4, RI_ALL_ONLINE }, |
1037 | { 0x302010, 2044, RI_ALL_OFFLINE }, | 1028 | { 0x302010, 2044, RI_ALL_OFFLINE }, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index fc4e0e3885b0..ebf40cd7aa10 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev, | |||
775 | struct bnx2x *bp = netdev_priv(dev); | 775 | struct bnx2x *bp = netdev_priv(dev); |
776 | struct dump_hdr dump_hdr = {0}; | 776 | struct dump_hdr dump_hdr = {0}; |
777 | 777 | ||
778 | regs->version = 0; | 778 | regs->version = 1; |
779 | memset(p, 0, regs->len); | 779 | memset(p, 0, regs->len); |
780 | 780 | ||
781 | if (!netif_running(bp->dev)) | 781 | if (!netif_running(bp->dev)) |
@@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev, | |||
1587 | bp->link_params.req_flow_ctrl[cfg_idx] = | 1587 | bp->link_params.req_flow_ctrl[cfg_idx] = |
1588 | BNX2X_FLOW_CTRL_AUTO; | 1588 | BNX2X_FLOW_CTRL_AUTO; |
1589 | } | 1589 | } |
1590 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; | ||
1591 | if (epause->rx_pause) | ||
1592 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; | ||
1593 | |||
1594 | if (epause->tx_pause) | ||
1595 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX; | ||
1590 | } | 1596 | } |
1591 | 1597 | ||
1592 | DP(BNX2X_MSG_ETHTOOL, | 1598 | DP(BNX2X_MSG_ETHTOOL, |
@@ -2888,11 +2894,9 @@ static void bnx2x_get_channels(struct net_device *dev, | |||
2888 | */ | 2894 | */ |
2889 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) | 2895 | static void bnx2x_change_num_queues(struct bnx2x *bp, int num_rss) |
2890 | { | 2896 | { |
2891 | bnx2x_del_all_napi(bp); | ||
2892 | bnx2x_disable_msi(bp); | 2897 | bnx2x_disable_msi(bp); |
2893 | BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; | 2898 | BNX2X_NUM_QUEUES(bp) = num_rss + NON_ETH_CONTEXT_USE; |
2894 | bnx2x_set_int_mode(bp); | 2899 | bnx2x_set_int_mode(bp); |
2895 | bnx2x_add_all_napi(bp); | ||
2896 | } | 2900 | } |
2897 | 2901 | ||
2898 | /** | 2902 | /** |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c4709..b046beb435b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params, | |||
2667 | return bnx2x_status; | 2667 | return bnx2x_status; |
2668 | 2668 | ||
2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); | 2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); |
2670 | if (CHIP_IS_E3(bp)) | 2670 | |
2671 | bnx2x_update_pfc_xmac(params, vars, 0); | 2671 | if (CHIP_IS_E3(bp)) { |
2672 | else { | 2672 | if (vars->mac_type == MAC_TYPE_XMAC) |
2673 | bnx2x_update_pfc_xmac(params, vars, 0); | ||
2674 | } else { | ||
2673 | val = REG_RD(bp, MISC_REG_RESET_REG_2); | 2675 | val = REG_RD(bp, MISC_REG_RESET_REG_2); |
2674 | if ((val & | 2676 | if ((val & |
2675 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) | 2677 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) |
@@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5432 | switch (speed_mask) { | 5434 | switch (speed_mask) { |
5433 | case GP_STATUS_10M: | 5435 | case GP_STATUS_10M: |
5434 | vars->line_speed = SPEED_10; | 5436 | vars->line_speed = SPEED_10; |
5435 | if (vars->duplex == DUPLEX_FULL) | 5437 | if (is_duplex == DUPLEX_FULL) |
5436 | vars->link_status |= LINK_10TFD; | 5438 | vars->link_status |= LINK_10TFD; |
5437 | else | 5439 | else |
5438 | vars->link_status |= LINK_10THD; | 5440 | vars->link_status |= LINK_10THD; |
@@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5440 | 5442 | ||
5441 | case GP_STATUS_100M: | 5443 | case GP_STATUS_100M: |
5442 | vars->line_speed = SPEED_100; | 5444 | vars->line_speed = SPEED_100; |
5443 | if (vars->duplex == DUPLEX_FULL) | 5445 | if (is_duplex == DUPLEX_FULL) |
5444 | vars->link_status |= LINK_100TXFD; | 5446 | vars->link_status |= LINK_100TXFD; |
5445 | else | 5447 | else |
5446 | vars->link_status |= LINK_100TXHD; | 5448 | vars->link_status |= LINK_100TXHD; |
@@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5449 | case GP_STATUS_1G: | 5451 | case GP_STATUS_1G: |
5450 | case GP_STATUS_1G_KX: | 5452 | case GP_STATUS_1G_KX: |
5451 | vars->line_speed = SPEED_1000; | 5453 | vars->line_speed = SPEED_1000; |
5452 | if (vars->duplex == DUPLEX_FULL) | 5454 | if (is_duplex == DUPLEX_FULL) |
5453 | vars->link_status |= LINK_1000TFD; | 5455 | vars->link_status |= LINK_1000TFD; |
5454 | else | 5456 | else |
5455 | vars->link_status |= LINK_1000THD; | 5457 | vars->link_status |= LINK_1000THD; |
@@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5457 | 5459 | ||
5458 | case GP_STATUS_2_5G: | 5460 | case GP_STATUS_2_5G: |
5459 | vars->line_speed = SPEED_2500; | 5461 | vars->line_speed = SPEED_2500; |
5460 | if (vars->duplex == DUPLEX_FULL) | 5462 | if (is_duplex == DUPLEX_FULL) |
5461 | vars->link_status |= LINK_2500TFD; | 5463 | vars->link_status |= LINK_2500TFD; |
5462 | else | 5464 | else |
5463 | vars->link_status |= LINK_2500THD; | 5465 | vars->link_status |= LINK_2500THD; |
@@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
5531 | 5533 | ||
5532 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 5534 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { |
5533 | if (SINGLE_MEDIA_DIRECT(params)) { | 5535 | if (SINGLE_MEDIA_DIRECT(params)) { |
5536 | vars->duplex = duplex; | ||
5534 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | 5537 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); |
5535 | if (phy->req_line_speed == SPEED_AUTO_NEG) | 5538 | if (phy->req_line_speed == SPEED_AUTO_NEG) |
5536 | bnx2x_xgxs_an_resolve(phy, params, vars, | 5539 | bnx2x_xgxs_an_resolve(phy, params, vars, |
@@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5625 | LINK_STATUS_PARALLEL_DETECTION_USED; | 5628 | LINK_STATUS_PARALLEL_DETECTION_USED; |
5626 | } | 5629 | } |
5627 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5630 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5631 | vars->duplex = duplex; | ||
5628 | } | 5632 | } |
5629 | } | 5633 | } |
5630 | 5634 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index dd451c3dd83d..0875ecfe3372 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -4041,20 +4041,6 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine) | |||
4041 | return val != 0; | 4041 | return val != 0; |
4042 | } | 4042 | } |
4043 | 4043 | ||
4044 | /* | ||
4045 | * Reset the load status for the current engine. | ||
4046 | */ | ||
4047 | static void bnx2x_clear_load_status(struct bnx2x *bp) | ||
4048 | { | ||
4049 | u32 val; | ||
4050 | u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : | ||
4051 | BNX2X_PATH0_LOAD_CNT_MASK); | ||
4052 | bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); | ||
4053 | val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); | ||
4054 | REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); | ||
4055 | bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); | ||
4056 | } | ||
4057 | |||
4058 | static void _print_next_block(int idx, const char *blk) | 4044 | static void _print_next_block(int idx, const char *blk) |
4059 | { | 4045 | { |
4060 | pr_cont("%s%s", idx ? ", " : "", blk); | 4046 | pr_cont("%s%s", idx ? ", " : "", blk); |
@@ -7575,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, | |||
7575 | } | 7561 | } |
7576 | 7562 | ||
7577 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); | 7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); |
7578 | if (rc < 0) | 7564 | |
7565 | if (rc == -EEXIST) { | ||
7566 | DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); | ||
7567 | /* do not treat adding same MAC as error */ | ||
7568 | rc = 0; | ||
7569 | } else if (rc < 0) | ||
7579 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); | 7570 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); |
7571 | |||
7580 | return rc; | 7572 | return rc; |
7581 | } | 7573 | } |
7582 | 7574 | ||
@@ -8441,6 +8433,8 @@ unload_error: | |||
8441 | 8433 | ||
8442 | /* Disable HW interrupts, NAPI */ | 8434 | /* Disable HW interrupts, NAPI */ |
8443 | bnx2x_netif_stop(bp, 1); | 8435 | bnx2x_netif_stop(bp, 1); |
8436 | /* Delete all NAPI objects */ | ||
8437 | bnx2x_del_all_napi(bp); | ||
8444 | 8438 | ||
8445 | /* Release IRQs */ | 8439 | /* Release IRQs */ |
8446 | bnx2x_free_irq(bp); | 8440 | bnx2x_free_irq(bp); |
@@ -9384,32 +9378,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) | |||
9384 | return rc; | 9378 | return rc; |
9385 | } | 9379 | } |
9386 | 9380 | ||
9387 | static bool __devinit bnx2x_can_flr(struct bnx2x *bp) | ||
9388 | { | ||
9389 | int pos; | ||
9390 | u32 cap; | ||
9391 | struct pci_dev *dev = bp->pdev; | ||
9392 | |||
9393 | pos = pci_pcie_cap(dev); | ||
9394 | if (!pos) | ||
9395 | return false; | ||
9396 | |||
9397 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); | ||
9398 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
9399 | return false; | ||
9400 | |||
9401 | return true; | ||
9402 | } | ||
9403 | |||
9404 | static int __devinit bnx2x_do_flr(struct bnx2x *bp) | 9381 | static int __devinit bnx2x_do_flr(struct bnx2x *bp) |
9405 | { | 9382 | { |
9406 | int i, pos; | 9383 | int i, pos; |
9407 | u16 status; | 9384 | u16 status; |
9408 | struct pci_dev *dev = bp->pdev; | 9385 | struct pci_dev *dev = bp->pdev; |
9409 | 9386 | ||
9410 | /* probe the capability first */ | 9387 | |
9411 | if (bnx2x_can_flr(bp)) | 9388 | if (CHIP_IS_E1x(bp)) { |
9412 | return -ENOTTY; | 9389 | BNX2X_DEV_INFO("FLR not supported in E1/E1H\n"); |
9390 | return -EINVAL; | ||
9391 | } | ||
9392 | |||
9393 | /* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */ | ||
9394 | if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { | ||
9395 | BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", | ||
9396 | bp->common.bc_ver); | ||
9397 | return -EINVAL; | ||
9398 | } | ||
9413 | 9399 | ||
9414 | pos = pci_pcie_cap(dev); | 9400 | pos = pci_pcie_cap(dev); |
9415 | if (!pos) | 9401 | if (!pos) |
@@ -9429,12 +9415,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) | |||
9429 | "transaction is not cleared; proceeding with reset anyway\n"); | 9415 | "transaction is not cleared; proceeding with reset anyway\n"); |
9430 | 9416 | ||
9431 | clear: | 9417 | clear: |
9432 | if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { | ||
9433 | BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", | ||
9434 | bp->common.bc_ver); | ||
9435 | return -EINVAL; | ||
9436 | } | ||
9437 | 9418 | ||
9419 | BNX2X_DEV_INFO("Initiating FLR\n"); | ||
9438 | bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); | 9420 | bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); |
9439 | 9421 | ||
9440 | return 0; | 9422 | return 0; |
@@ -9454,8 +9436,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp) | |||
9454 | * the one required, then FLR will be sufficient to clean any residue | 9436 | * the one required, then FLR will be sufficient to clean any residue |
9455 | * left by previous driver | 9437 | * left by previous driver |
9456 | */ | 9438 | */ |
9457 | if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) | 9439 | rc = bnx2x_test_firmware_version(bp, false); |
9458 | return bnx2x_do_flr(bp); | 9440 | |
9441 | if (!rc) { | ||
9442 | /* fw version is good */ | ||
9443 | BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n"); | ||
9444 | rc = bnx2x_do_flr(bp); | ||
9445 | } | ||
9446 | |||
9447 | if (!rc) { | ||
9448 | /* FLR was performed */ | ||
9449 | BNX2X_DEV_INFO("FLR successful\n"); | ||
9450 | return 0; | ||
9451 | } | ||
9452 | |||
9453 | BNX2X_DEV_INFO("Could not FLR\n"); | ||
9459 | 9454 | ||
9460 | /* Close the MCP request, return failure*/ | 9455 | /* Close the MCP request, return failure*/ |
9461 | rc = bnx2x_prev_mcp_done(bp); | 9456 | rc = bnx2x_prev_mcp_done(bp); |
@@ -9836,12 +9831,13 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) | |||
9836 | } | 9831 | } |
9837 | 9832 | ||
9838 | #ifdef CONFIG_PCI_MSI | 9833 | #ifdef CONFIG_PCI_MSI |
9839 | /* | 9834 | /* Due to new PF resource allocation by MFW T7.4 and above, it's |
9840 | * It's expected that number of CAM entries for this functions is equal | 9835 | * optional that number of CAM entries will not be equal to the value |
9841 | * to the number evaluated based on the MSI-X table size. We want a | 9836 | * advertised in PCI. |
9842 | * harsh warning if these values are different! | 9837 | * Driver should use the minimal value of both as the actual status |
9838 | * block count | ||
9843 | */ | 9839 | */ |
9844 | WARN_ON(bp->igu_sb_cnt != igu_sb_cnt); | 9840 | bp->igu_sb_cnt = min_t(int, bp->igu_sb_cnt, igu_sb_cnt); |
9845 | #endif | 9841 | #endif |
9846 | 9842 | ||
9847 | if (igu_sb_cnt == 0) | 9843 | if (igu_sb_cnt == 0) |
@@ -10305,13 +10301,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | |||
10305 | dev_info.port_hw_config[port]. | 10301 | dev_info.port_hw_config[port]. |
10306 | fcoe_wwn_node_name_lower); | 10302 | fcoe_wwn_node_name_lower); |
10307 | } else if (!IS_MF_SD(bp)) { | 10303 | } else if (!IS_MF_SD(bp)) { |
10308 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); | ||
10309 | |||
10310 | /* | 10304 | /* |
10311 | * Read the WWN info only if the FCoE feature is enabled for | 10305 | * Read the WWN info only if the FCoE feature is enabled for |
10312 | * this function. | 10306 | * this function. |
10313 | */ | 10307 | */ |
10314 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) | 10308 | if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp)) |
10315 | bnx2x_get_ext_wwn_info(bp, func); | 10309 | bnx2x_get_ext_wwn_info(bp, func); |
10316 | 10310 | ||
10317 | } else if (IS_MF_FCOE_SD(bp)) | 10311 | } else if (IS_MF_FCOE_SD(bp)) |
@@ -11084,7 +11078,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp) | |||
11084 | netdev_for_each_uc_addr(ha, dev) { | 11078 | netdev_for_each_uc_addr(ha, dev) { |
11085 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, | 11079 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, |
11086 | BNX2X_UC_LIST_MAC, &ramrod_flags); | 11080 | BNX2X_UC_LIST_MAC, &ramrod_flags); |
11087 | if (rc < 0) { | 11081 | if (rc == -EEXIST) { |
11082 | DP(BNX2X_MSG_SP, | ||
11083 | "Failed to schedule ADD operations: %d\n", rc); | ||
11084 | /* do not treat adding same MAC as error */ | ||
11085 | rc = 0; | ||
11086 | |||
11087 | } else if (rc < 0) { | ||
11088 | |||
11088 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", | 11089 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", |
11089 | rc); | 11090 | rc); |
11090 | return rc; | 11091 | return rc; |
@@ -11242,10 +11243,12 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
11242 | static void poll_bnx2x(struct net_device *dev) | 11243 | static void poll_bnx2x(struct net_device *dev) |
11243 | { | 11244 | { |
11244 | struct bnx2x *bp = netdev_priv(dev); | 11245 | struct bnx2x *bp = netdev_priv(dev); |
11246 | int i; | ||
11245 | 11247 | ||
11246 | disable_irq(bp->pdev->irq); | 11248 | for_each_eth_queue(bp, i) { |
11247 | bnx2x_interrupt(bp->pdev->irq, dev); | 11249 | struct bnx2x_fastpath *fp = &bp->fp[i]; |
11248 | enable_irq(bp->pdev->irq); | 11250 | napi_schedule(&bnx2x_fp(bp, fp->index, napi)); |
11251 | } | ||
11249 | } | 11252 | } |
11250 | #endif | 11253 | #endif |
11251 | 11254 | ||
@@ -11427,9 +11430,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, | |||
11427 | if (!chip_is_e1x) | 11430 | if (!chip_is_e1x) |
11428 | REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); | 11431 | REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); |
11429 | 11432 | ||
11430 | /* Reset the load counter */ | ||
11431 | bnx2x_clear_load_status(bp); | ||
11432 | |||
11433 | dev->watchdog_timeo = TX_TIMEOUT; | 11433 | dev->watchdog_timeo = TX_TIMEOUT; |
11434 | 11434 | ||
11435 | dev->netdev_ops = &bnx2x_netdev_ops; | 11435 | dev->netdev_ops = &bnx2x_netdev_ops; |
@@ -11915,9 +11915,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, | |||
11915 | */ | 11915 | */ |
11916 | bnx2x_set_int_mode(bp); | 11916 | bnx2x_set_int_mode(bp); |
11917 | 11917 | ||
11918 | /* Add all NAPI objects */ | ||
11919 | bnx2x_add_all_napi(bp); | ||
11920 | |||
11921 | rc = register_netdev(dev); | 11918 | rc = register_netdev(dev); |
11922 | if (rc) { | 11919 | if (rc) { |
11923 | dev_err(&pdev->dev, "Cannot register net device\n"); | 11920 | dev_err(&pdev->dev, "Cannot register net device\n"); |
@@ -11992,9 +11989,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) | |||
11992 | 11989 | ||
11993 | unregister_netdev(dev); | 11990 | unregister_netdev(dev); |
11994 | 11991 | ||
11995 | /* Delete all NAPI objects */ | ||
11996 | bnx2x_del_all_napi(bp); | ||
11997 | |||
11998 | /* Power on: we can't let PCI layer write to us while we are in D3 */ | 11992 | /* Power on: we can't let PCI layer write to us while we are in D3 */ |
11999 | bnx2x_set_power_state(bp, PCI_D0); | 11993 | bnx2x_set_power_state(bp, PCI_D0); |
12000 | 11994 | ||
@@ -12041,6 +12035,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) | |||
12041 | bnx2x_tx_disable(bp); | 12035 | bnx2x_tx_disable(bp); |
12042 | 12036 | ||
12043 | bnx2x_netif_stop(bp, 0); | 12037 | bnx2x_netif_stop(bp, 0); |
12038 | /* Delete all NAPI objects */ | ||
12039 | bnx2x_del_all_napi(bp); | ||
12044 | 12040 | ||
12045 | del_timer_sync(&bp->timer); | 12041 | del_timer_sync(&bp->timer); |
12046 | 12042 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 734fd87cd990..62f754bd0dfe 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -2485,6 +2485,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, | |||
2485 | break; | 2485 | break; |
2486 | 2486 | ||
2487 | default: | 2487 | default: |
2488 | kfree(new_cmd); | ||
2488 | BNX2X_ERR("Unknown command: %d\n", cmd); | 2489 | BNX2X_ERR("Unknown command: %d\n", cmd); |
2489 | return -EINVAL; | 2490 | return -EINVAL; |
2490 | } | 2491 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5be..a1d0446b39b3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
101 | if (CHIP_REV_IS_SLOW(bp)) | 101 | if (CHIP_REV_IS_SLOW(bp)) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Update MCP's statistics if possible */ | ||
105 | if (bp->func_stx) | ||
106 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
107 | sizeof(bp->func_stats)); | ||
108 | |||
104 | /* loader */ | 109 | /* loader */ |
105 | if (bp->executer_idx) { | 110 | if (bp->executer_idx) { |
106 | int loader_idx = PMF_DMAE_C(bp); | 111 | int loader_idx = PMF_DMAE_C(bp); |
@@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
128 | 133 | ||
129 | } else if (bp->func_stx) { | 134 | } else if (bp->func_stx) { |
130 | *stats_comp = 0; | 135 | *stats_comp = 0; |
131 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
132 | sizeof(bp->func_stats)); | ||
133 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | 136 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); |
134 | } | 137 | } |
135 | } | 138 | } |
@@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp) | |||
1151 | if (bp->port.pmf) | 1154 | if (bp->port.pmf) |
1152 | bnx2x_hw_stats_update(bp); | 1155 | bnx2x_hw_stats_update(bp); |
1153 | 1156 | ||
1154 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | 1157 | if (bnx2x_storm_stats_update(bp)) { |
1155 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | 1158 | if (bp->stats_pending++ == 3) { |
1156 | bnx2x_panic(); | 1159 | BNX2X_ERR("storm stats were not updated for 3 times\n"); |
1160 | bnx2x_panic(); | ||
1161 | } | ||
1157 | return; | 1162 | return; |
1158 | } | 1163 | } |
1159 | 1164 | ||
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index 77884191a8c6..4e980a7886fb 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c | |||
@@ -1086,7 +1086,7 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
1086 | /* Clock */ | 1086 | /* Clock */ |
1087 | lp->ether_clk = clk_get(&pdev->dev, "ether_clk"); | 1087 | lp->ether_clk = clk_get(&pdev->dev, "ether_clk"); |
1088 | if (IS_ERR(lp->ether_clk)) { | 1088 | if (IS_ERR(lp->ether_clk)) { |
1089 | res = -ENODEV; | 1089 | res = PTR_ERR(lp->ether_clk); |
1090 | goto err_ioumap; | 1090 | goto err_ioumap; |
1091 | } | 1091 | } |
1092 | clk_enable(lp->ether_clk); | 1092 | clk_enable(lp->ether_clk); |
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 845b2020f291..138446957786 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c | |||
@@ -1243,6 +1243,7 @@ static void set_multicast_list(struct net_device *dev) | |||
1243 | { | 1243 | { |
1244 | struct net_local *lp = netdev_priv(dev); | 1244 | struct net_local *lp = netdev_priv(dev); |
1245 | unsigned long flags; | 1245 | unsigned long flags; |
1246 | u16 cfg; | ||
1246 | 1247 | ||
1247 | spin_lock_irqsave(&lp->lock, flags); | 1248 | spin_lock_irqsave(&lp->lock, flags); |
1248 | if (dev->flags & IFF_PROMISC) | 1249 | if (dev->flags & IFF_PROMISC) |
@@ -1260,11 +1261,10 @@ static void set_multicast_list(struct net_device *dev) | |||
1260 | /* in promiscuous mode, we accept errored packets, | 1261 | /* in promiscuous mode, we accept errored packets, |
1261 | * so we have to enable interrupts on them also | 1262 | * so we have to enable interrupts on them also |
1262 | */ | 1263 | */ |
1263 | writereg(dev, PP_RxCFG, | 1264 | cfg = lp->curr_rx_cfg; |
1264 | (lp->curr_rx_cfg | | 1265 | if (lp->rx_mode == RX_ALL_ACCEPT) |
1265 | (lp->rx_mode == RX_ALL_ACCEPT) | 1266 | cfg |= RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL; |
1266 | ? (RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | RX_EXTRA_DATA_ENBL) | 1267 | writereg(dev, PP_RxCFG, cfg); |
1267 | : 0)); | ||
1268 | spin_unlock_irqrestore(&lp->lock, flags); | 1268 | spin_unlock_irqrestore(&lp->lock, flags); |
1269 | } | 1269 | } |
1270 | 1270 | ||
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 7fac97b4bb59..8c63d06ab12b 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -259,7 +259,7 @@ int be_process_mcc(struct be_adapter *adapter) | |||
259 | int num = 0, status = 0; | 259 | int num = 0, status = 0; |
260 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; | 260 | struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; |
261 | 261 | ||
262 | spin_lock_bh(&adapter->mcc_cq_lock); | 262 | spin_lock(&adapter->mcc_cq_lock); |
263 | while ((compl = be_mcc_compl_get(adapter))) { | 263 | while ((compl = be_mcc_compl_get(adapter))) { |
264 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { | 264 | if (compl->flags & CQE_FLAGS_ASYNC_MASK) { |
265 | /* Interpret flags as an async trailer */ | 265 | /* Interpret flags as an async trailer */ |
@@ -280,7 +280,7 @@ int be_process_mcc(struct be_adapter *adapter) | |||
280 | if (num) | 280 | if (num) |
281 | be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); | 281 | be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); |
282 | 282 | ||
283 | spin_unlock_bh(&adapter->mcc_cq_lock); | 283 | spin_unlock(&adapter->mcc_cq_lock); |
284 | return status; | 284 | return status; |
285 | } | 285 | } |
286 | 286 | ||
@@ -295,7 +295,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) | |||
295 | if (be_error(adapter)) | 295 | if (be_error(adapter)) |
296 | return -EIO; | 296 | return -EIO; |
297 | 297 | ||
298 | local_bh_disable(); | ||
298 | status = be_process_mcc(adapter); | 299 | status = be_process_mcc(adapter); |
300 | local_bh_enable(); | ||
299 | 301 | ||
300 | if (atomic_read(&mcc_obj->q.used) == 0) | 302 | if (atomic_read(&mcc_obj->q.used) == 0) |
301 | break; | 303 | break; |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c60de89b6669..78b8aa8069f0 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -1948,7 +1948,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) | |||
1948 | 1948 | ||
1949 | if (adapter->num_rx_qs != MAX_RX_QS) | 1949 | if (adapter->num_rx_qs != MAX_RX_QS) |
1950 | dev_info(&adapter->pdev->dev, | 1950 | dev_info(&adapter->pdev->dev, |
1951 | "Created only %d receive queues", adapter->num_rx_qs); | 1951 | "Created only %d receive queues\n", adapter->num_rx_qs); |
1952 | 1952 | ||
1953 | return 0; | 1953 | return 0; |
1954 | } | 1954 | } |
@@ -3763,7 +3763,9 @@ static void be_worker(struct work_struct *work) | |||
3763 | /* when interrupts are not yet enabled, just reap any pending | 3763 | /* when interrupts are not yet enabled, just reap any pending |
3764 | * mcc completions */ | 3764 | * mcc completions */ |
3765 | if (!netif_running(adapter->netdev)) { | 3765 | if (!netif_running(adapter->netdev)) { |
3766 | local_bh_disable(); | ||
3766 | be_process_mcc(adapter); | 3767 | be_process_mcc(adapter); |
3768 | local_bh_enable(); | ||
3767 | goto reschedule; | 3769 | goto reschedule; |
3768 | } | 3770 | } |
3769 | 3771 | ||
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 0f2d1a710909..151453309401 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c | |||
@@ -174,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
174 | 174 | ||
175 | new_bus->phy_mask = ~0; | 175 | new_bus->phy_mask = ~0; |
176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
177 | if (!new_bus->irq) | 177 | if (!new_bus->irq) { |
178 | ret = -ENOMEM; | ||
178 | goto out_unmap_regs; | 179 | goto out_unmap_regs; |
180 | } | ||
179 | 181 | ||
180 | new_bus->parent = &ofdev->dev; | 182 | new_bus->parent = &ofdev->dev; |
181 | dev_set_drvdata(&ofdev->dev, new_bus); | 183 | dev_set_drvdata(&ofdev->dev, new_bus); |
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index 55bb867258e6..cdf702a59485 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c | |||
@@ -137,8 +137,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
137 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); | 137 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); |
138 | 138 | ||
139 | fec->fecp = ioremap(res.start, resource_size(&res)); | 139 | fec->fecp = ioremap(res.start, resource_size(&res)); |
140 | if (!fec->fecp) | 140 | if (!fec->fecp) { |
141 | ret = -ENOMEM; | ||
141 | goto out_fec; | 142 | goto out_fec; |
143 | } | ||
142 | 144 | ||
143 | if (get_bus_freq) { | 145 | if (get_bus_freq) { |
144 | clock = get_bus_freq(ofdev->dev.of_node); | 146 | clock = get_bus_freq(ofdev->dev.of_node); |
@@ -172,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
172 | 174 | ||
173 | new_bus->phy_mask = ~0; | 175 | new_bus->phy_mask = ~0; |
174 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
175 | if (!new_bus->irq) | 177 | if (!new_bus->irq) { |
178 | ret = -ENOMEM; | ||
176 | goto out_unmap_regs; | 179 | goto out_unmap_regs; |
180 | } | ||
177 | 181 | ||
178 | new_bus->parent = &ofdev->dev; | 182 | new_bus->parent = &ofdev->dev; |
179 | dev_set_drvdata(&ofdev->dev, new_bus); | 183 | dev_set_drvdata(&ofdev->dev, new_bus); |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4605f7246687..d3233f59a82e 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -1041,7 +1041,7 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1041 | 1041 | ||
1042 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { | 1042 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) { |
1043 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 1043 | dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
1044 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 1044 | dev->features |= NETIF_F_HW_VLAN_RX; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | 1047 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { |
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 8971921cc1c8..ab6762caa957 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c | |||
@@ -1773,6 +1773,7 @@ static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd, | |||
1773 | } | 1773 | } |
1774 | 1774 | ||
1775 | int gfar_phc_index = -1; | 1775 | int gfar_phc_index = -1; |
1776 | EXPORT_SYMBOL(gfar_phc_index); | ||
1776 | 1777 | ||
1777 | static int gfar_get_ts_info(struct net_device *dev, | 1778 | static int gfar_get_ts_info(struct net_device *dev, |
1778 | struct ethtool_ts_info *info) | 1779 | struct ethtool_ts_info *info) |
diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c index c08e5d40fecb..0daa66b8eca0 100644 --- a/drivers/net/ethernet/freescale/gianfar_ptp.c +++ b/drivers/net/ethernet/freescale/gianfar_ptp.c | |||
@@ -515,7 +515,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) | |||
515 | err = PTR_ERR(etsects->clock); | 515 | err = PTR_ERR(etsects->clock); |
516 | goto no_clock; | 516 | goto no_clock; |
517 | } | 517 | } |
518 | gfar_phc_clock = ptp_clock_index(etsects->clock); | 518 | gfar_phc_index = ptp_clock_index(etsects->clock); |
519 | 519 | ||
520 | dev_set_drvdata(&dev->dev, etsects); | 520 | dev_set_drvdata(&dev->dev, etsects); |
521 | 521 | ||
@@ -539,7 +539,7 @@ static int gianfar_ptp_remove(struct platform_device *dev) | |||
539 | gfar_write(&etsects->regs->tmr_temask, 0); | 539 | gfar_write(&etsects->regs->tmr_temask, 0); |
540 | gfar_write(&etsects->regs->tmr_ctrl, 0); | 540 | gfar_write(&etsects->regs->tmr_ctrl, 0); |
541 | 541 | ||
542 | gfar_phc_clock = -1; | 542 | gfar_phc_index = -1; |
543 | ptp_clock_unregister(etsects->clock); | 543 | ptp_clock_unregister(etsects->clock); |
544 | iounmap(etsects->regs); | 544 | iounmap(etsects->regs); |
545 | release_resource(etsects->rsrc); | 545 | release_resource(etsects->rsrc); |
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e19..ba4e0cea3506 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c | |||
@@ -139,8 +139,11 @@ struct znet_private { | |||
139 | /* Only one can be built-in;-> */ | 139 | /* Only one can be built-in;-> */ |
140 | static struct net_device *znet_dev; | 140 | static struct net_device *znet_dev; |
141 | 141 | ||
142 | #define NETIDBLK_MAGIC "NETIDBLK" | ||
143 | #define NETIDBLK_MAGIC_SIZE 8 | ||
144 | |||
142 | struct netidblk { | 145 | struct netidblk { |
143 | char magic[8]; /* The magic number (string) "NETIDBLK" */ | 146 | char magic[NETIDBLK_MAGIC_SIZE]; /* The magic number (string) "NETIDBLK" */ |
144 | unsigned char netid[8]; /* The physical station address */ | 147 | unsigned char netid[8]; /* The physical station address */ |
145 | char nettype, globalopt; | 148 | char nettype, globalopt; |
146 | char vendor[8]; /* The machine vendor and product name. */ | 149 | char vendor[8]; /* The machine vendor and product name. */ |
@@ -373,14 +376,16 @@ static int __init znet_probe (void) | |||
373 | struct znet_private *znet; | 376 | struct znet_private *znet; |
374 | struct net_device *dev; | 377 | struct net_device *dev; |
375 | char *p; | 378 | char *p; |
379 | char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE); | ||
376 | int err = -ENOMEM; | 380 | int err = -ENOMEM; |
377 | 381 | ||
378 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ | 382 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ |
379 | for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) | 383 | for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) |
380 | if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0) | 384 | if (*p == 'N' && |
385 | strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0) | ||
381 | break; | 386 | break; |
382 | 387 | ||
383 | if (p >= (char *)phys_to_virt(0x100000)) { | 388 | if (p > plast) { |
384 | if (znet_debug > 1) | 389 | if (znet_debug > 1) |
385 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); | 390 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); |
386 | return -ENODEV; | 391 | return -ENODEV; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc3..b68d28a130e6 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | if (adapter->rx_queue.queue_addr != NULL) { | 474 | if (adapter->rx_queue.queue_addr != NULL) { |
475 | if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { | 475 | dma_free_coherent(dev, adapter->rx_queue.queue_len, |
476 | dma_unmap_single(dev, | 476 | adapter->rx_queue.queue_addr, |
477 | adapter->rx_queue.queue_dma, | 477 | adapter->rx_queue.queue_dma); |
478 | adapter->rx_queue.queue_len, | ||
479 | DMA_BIDIRECTIONAL); | ||
480 | adapter->rx_queue.queue_dma = DMA_ERROR_CODE; | ||
481 | } | ||
482 | kfree(adapter->rx_queue.queue_addr); | ||
483 | adapter->rx_queue.queue_addr = NULL; | 478 | adapter->rx_queue.queue_addr = NULL; |
484 | } | 479 | } |
485 | 480 | ||
@@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
556 | goto err_out; | 551 | goto err_out; |
557 | } | 552 | } |
558 | 553 | ||
554 | dev = &adapter->vdev->dev; | ||
555 | |||
559 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * | 556 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * |
560 | rxq_entries; | 557 | rxq_entries; |
561 | adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, | 558 | adapter->rx_queue.queue_addr = |
562 | GFP_KERNEL); | 559 | dma_alloc_coherent(dev, adapter->rx_queue.queue_len, |
560 | &adapter->rx_queue.queue_dma, GFP_KERNEL); | ||
563 | 561 | ||
564 | if (!adapter->rx_queue.queue_addr) { | 562 | if (!adapter->rx_queue.queue_addr) { |
565 | netdev_err(netdev, "unable to allocate rx queue pages\n"); | 563 | netdev_err(netdev, "unable to allocate rx queue pages\n"); |
@@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
567 | goto err_out; | 565 | goto err_out; |
568 | } | 566 | } |
569 | 567 | ||
570 | dev = &adapter->vdev->dev; | ||
571 | |||
572 | adapter->buffer_list_dma = dma_map_single(dev, | 568 | adapter->buffer_list_dma = dma_map_single(dev, |
573 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); | 569 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); |
574 | adapter->filter_list_dma = dma_map_single(dev, | 570 | adapter->filter_list_dma = dma_map_single(dev, |
575 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); | 571 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); |
576 | adapter->rx_queue.queue_dma = dma_map_single(dev, | ||
577 | adapter->rx_queue.queue_addr, | ||
578 | adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); | ||
579 | 572 | ||
580 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || | 573 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || |
581 | (dma_mapping_error(dev, adapter->filter_list_dma)) || | 574 | (dma_mapping_error(dev, adapter->filter_list_dma))) { |
582 | (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { | ||
583 | netdev_err(netdev, "unable to map filter or buffer list " | 575 | netdev_err(netdev, "unable to map filter or buffer list " |
584 | "pages\n"); | 576 | "pages\n"); |
585 | rc = -ENOMEM; | 577 | rc = -ENOMEM; |
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 3bfbb8df8989..bde337ee1a34 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -3149,6 +3149,17 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
3149 | return NETDEV_TX_OK; | 3149 | return NETDEV_TX_OK; |
3150 | } | 3150 | } |
3151 | 3151 | ||
3152 | /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN, | ||
3153 | * packets may get corrupted during padding by HW. | ||
3154 | * To WA this issue, pad all small packets manually. | ||
3155 | */ | ||
3156 | if (skb->len < ETH_ZLEN) { | ||
3157 | if (skb_pad(skb, ETH_ZLEN - skb->len)) | ||
3158 | return NETDEV_TX_OK; | ||
3159 | skb->len = ETH_ZLEN; | ||
3160 | skb_set_tail_pointer(skb, ETH_ZLEN); | ||
3161 | } | ||
3162 | |||
3152 | mss = skb_shinfo(skb)->gso_size; | 3163 | mss = skb_shinfo(skb)->gso_size; |
3153 | /* The controller does a simple calculation to | 3164 | /* The controller does a simple calculation to |
3154 | * make sure there is enough room in the FIFO before | 3165 | * make sure there is enough room in the FIFO before |
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 0b3bade957fd..080c89093feb 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c | |||
@@ -999,7 +999,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) | |||
999 | **/ | 999 | **/ |
1000 | static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | 1000 | static s32 e1000_reset_hw_82571(struct e1000_hw *hw) |
1001 | { | 1001 | { |
1002 | u32 ctrl, ctrl_ext, eecd; | 1002 | u32 ctrl, ctrl_ext, eecd, tctl; |
1003 | s32 ret_val; | 1003 | s32 ret_val; |
1004 | 1004 | ||
1005 | /* | 1005 | /* |
@@ -1014,7 +1014,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
1014 | ew32(IMC, 0xffffffff); | 1014 | ew32(IMC, 0xffffffff); |
1015 | 1015 | ||
1016 | ew32(RCTL, 0); | 1016 | ew32(RCTL, 0); |
1017 | ew32(TCTL, E1000_TCTL_PSP); | 1017 | tctl = er32(TCTL); |
1018 | tctl &= ~E1000_TCTL_EN; | ||
1019 | ew32(TCTL, tctl); | ||
1018 | e1e_flush(); | 1020 | e1e_flush(); |
1019 | 1021 | ||
1020 | usleep_range(10000, 20000); | 1022 | usleep_range(10000, 20000); |
@@ -1601,10 +1603,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1601 | * auto-negotiation in the TXCW register and disable | 1603 | * auto-negotiation in the TXCW register and disable |
1602 | * forced link in the Device Control register in an | 1604 | * forced link in the Device Control register in an |
1603 | * attempt to auto-negotiate with our link partner. | 1605 | * attempt to auto-negotiate with our link partner. |
1604 | * If the partner code word is null, stop forcing | ||
1605 | * and restart auto negotiation. | ||
1606 | */ | 1606 | */ |
1607 | if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { | 1607 | if (rxcw & E1000_RXCW_C) { |
1608 | /* Enable autoneg, and unforce link up */ | 1608 | /* Enable autoneg, and unforce link up */ |
1609 | ew32(TXCW, mac->txcw); | 1609 | ew32(TXCW, mac->txcw); |
1610 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); | 1610 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index cd153326c3cf..cb3356c9af80 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h | |||
@@ -310,6 +310,7 @@ struct e1000_adapter { | |||
310 | */ | 310 | */ |
311 | struct e1000_ring *tx_ring /* One per active queue */ | 311 | struct e1000_ring *tx_ring /* One per active queue */ |
312 | ____cacheline_aligned_in_smp; | 312 | ____cacheline_aligned_in_smp; |
313 | u32 tx_fifo_limit; | ||
313 | 314 | ||
314 | struct napi_struct napi; | 315 | struct napi_struct napi; |
315 | 316 | ||
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 95b245310f17..d01a099475a1 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -178,6 +178,24 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | |||
178 | pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); | 178 | pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void e1000e_dump_ps_pages(struct e1000_adapter *adapter, | ||
182 | struct e1000_buffer *bi) | ||
183 | { | ||
184 | int i; | ||
185 | struct e1000_ps_page *ps_page; | ||
186 | |||
187 | for (i = 0; i < adapter->rx_ps_pages; i++) { | ||
188 | ps_page = &bi->ps_pages[i]; | ||
189 | |||
190 | if (ps_page->page) { | ||
191 | pr_info("packet dump for ps_page %d:\n", i); | ||
192 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | ||
193 | 16, 1, page_address(ps_page->page), | ||
194 | PAGE_SIZE, true); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
181 | /* | 199 | /* |
182 | * e1000e_dump - Print registers, Tx-ring and Rx-ring | 200 | * e1000e_dump - Print registers, Tx-ring and Rx-ring |
183 | */ | 201 | */ |
@@ -299,10 +317,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
299 | (unsigned long long)buffer_info->time_stamp, | 317 | (unsigned long long)buffer_info->time_stamp, |
300 | buffer_info->skb, next_desc); | 318 | buffer_info->skb, next_desc); |
301 | 319 | ||
302 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 320 | if (netif_msg_pktdata(adapter) && buffer_info->skb) |
303 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | 321 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, |
304 | 16, 1, phys_to_virt(buffer_info->dma), | 322 | 16, 1, buffer_info->skb->data, |
305 | buffer_info->length, true); | 323 | buffer_info->skb->len, true); |
306 | } | 324 | } |
307 | 325 | ||
308 | /* Print Rx Ring Summary */ | 326 | /* Print Rx Ring Summary */ |
@@ -381,10 +399,8 @@ rx_ring_summary: | |||
381 | buffer_info->skb, next_desc); | 399 | buffer_info->skb, next_desc); |
382 | 400 | ||
383 | if (netif_msg_pktdata(adapter)) | 401 | if (netif_msg_pktdata(adapter)) |
384 | print_hex_dump(KERN_INFO, "", | 402 | e1000e_dump_ps_pages(adapter, |
385 | DUMP_PREFIX_ADDRESS, 16, 1, | 403 | buffer_info); |
386 | phys_to_virt(buffer_info->dma), | ||
387 | adapter->rx_ps_bsize0, true); | ||
388 | } | 404 | } |
389 | } | 405 | } |
390 | break; | 406 | break; |
@@ -444,12 +460,12 @@ rx_ring_summary: | |||
444 | (unsigned long long)buffer_info->dma, | 460 | (unsigned long long)buffer_info->dma, |
445 | buffer_info->skb, next_desc); | 461 | buffer_info->skb, next_desc); |
446 | 462 | ||
447 | if (netif_msg_pktdata(adapter)) | 463 | if (netif_msg_pktdata(adapter) && |
464 | buffer_info->skb) | ||
448 | print_hex_dump(KERN_INFO, "", | 465 | print_hex_dump(KERN_INFO, "", |
449 | DUMP_PREFIX_ADDRESS, 16, | 466 | DUMP_PREFIX_ADDRESS, 16, |
450 | 1, | 467 | 1, |
451 | phys_to_virt | 468 | buffer_info->skb->data, |
452 | (buffer_info->dma), | ||
453 | adapter->rx_buffer_len, | 469 | adapter->rx_buffer_len, |
454 | true); | 470 | true); |
455 | } | 471 | } |
@@ -3501,6 +3517,15 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
3501 | } | 3517 | } |
3502 | 3518 | ||
3503 | /* | 3519 | /* |
3520 | * Alignment of Tx data is on an arbitrary byte boundary with the | ||
3521 | * maximum size per Tx descriptor limited only to the transmit | ||
3522 | * allocation of the packet buffer minus 96 bytes with an upper | ||
3523 | * limit of 24KB due to receive synchronization limitations. | ||
3524 | */ | ||
3525 | adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96, | ||
3526 | 24 << 10); | ||
3527 | |||
3528 | /* | ||
3504 | * Disable Adaptive Interrupt Moderation if 2 full packets cannot | 3529 | * Disable Adaptive Interrupt Moderation if 2 full packets cannot |
3505 | * fit in receive buffer. | 3530 | * fit in receive buffer. |
3506 | */ | 3531 | */ |
@@ -4769,12 +4794,9 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) | |||
4769 | return 1; | 4794 | return 1; |
4770 | } | 4795 | } |
4771 | 4796 | ||
4772 | #define E1000_MAX_PER_TXD 8192 | ||
4773 | #define E1000_MAX_TXD_PWR 12 | ||
4774 | |||
4775 | static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, | 4797 | static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, |
4776 | unsigned int first, unsigned int max_per_txd, | 4798 | unsigned int first, unsigned int max_per_txd, |
4777 | unsigned int nr_frags, unsigned int mss) | 4799 | unsigned int nr_frags) |
4778 | { | 4800 | { |
4779 | struct e1000_adapter *adapter = tx_ring->adapter; | 4801 | struct e1000_adapter *adapter = tx_ring->adapter; |
4780 | struct pci_dev *pdev = adapter->pdev; | 4802 | struct pci_dev *pdev = adapter->pdev; |
@@ -5007,20 +5029,19 @@ static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) | |||
5007 | 5029 | ||
5008 | static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) | 5030 | static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) |
5009 | { | 5031 | { |
5032 | BUG_ON(size > tx_ring->count); | ||
5033 | |||
5010 | if (e1000_desc_unused(tx_ring) >= size) | 5034 | if (e1000_desc_unused(tx_ring) >= size) |
5011 | return 0; | 5035 | return 0; |
5012 | return __e1000_maybe_stop_tx(tx_ring, size); | 5036 | return __e1000_maybe_stop_tx(tx_ring, size); |
5013 | } | 5037 | } |
5014 | 5038 | ||
5015 | #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1) | ||
5016 | static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | 5039 | static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, |
5017 | struct net_device *netdev) | 5040 | struct net_device *netdev) |
5018 | { | 5041 | { |
5019 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5042 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5020 | struct e1000_ring *tx_ring = adapter->tx_ring; | 5043 | struct e1000_ring *tx_ring = adapter->tx_ring; |
5021 | unsigned int first; | 5044 | unsigned int first; |
5022 | unsigned int max_per_txd = E1000_MAX_PER_TXD; | ||
5023 | unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; | ||
5024 | unsigned int tx_flags = 0; | 5045 | unsigned int tx_flags = 0; |
5025 | unsigned int len = skb_headlen(skb); | 5046 | unsigned int len = skb_headlen(skb); |
5026 | unsigned int nr_frags; | 5047 | unsigned int nr_frags; |
@@ -5040,18 +5061,8 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5040 | } | 5061 | } |
5041 | 5062 | ||
5042 | mss = skb_shinfo(skb)->gso_size; | 5063 | mss = skb_shinfo(skb)->gso_size; |
5043 | /* | ||
5044 | * The controller does a simple calculation to | ||
5045 | * make sure there is enough room in the FIFO before | ||
5046 | * initiating the DMA for each buffer. The calc is: | ||
5047 | * 4 = ceil(buffer len/mss). To make sure we don't | ||
5048 | * overrun the FIFO, adjust the max buffer len if mss | ||
5049 | * drops. | ||
5050 | */ | ||
5051 | if (mss) { | 5064 | if (mss) { |
5052 | u8 hdr_len; | 5065 | u8 hdr_len; |
5053 | max_per_txd = min(mss << 2, max_per_txd); | ||
5054 | max_txd_pwr = fls(max_per_txd) - 1; | ||
5055 | 5066 | ||
5056 | /* | 5067 | /* |
5057 | * TSO Workaround for 82571/2/3 Controllers -- if skb->data | 5068 | * TSO Workaround for 82571/2/3 Controllers -- if skb->data |
@@ -5081,12 +5092,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5081 | count++; | 5092 | count++; |
5082 | count++; | 5093 | count++; |
5083 | 5094 | ||
5084 | count += TXD_USE_COUNT(len, max_txd_pwr); | 5095 | count += DIV_ROUND_UP(len, adapter->tx_fifo_limit); |
5085 | 5096 | ||
5086 | nr_frags = skb_shinfo(skb)->nr_frags; | 5097 | nr_frags = skb_shinfo(skb)->nr_frags; |
5087 | for (f = 0; f < nr_frags; f++) | 5098 | for (f = 0; f < nr_frags; f++) |
5088 | count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]), | 5099 | count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]), |
5089 | max_txd_pwr); | 5100 | adapter->tx_fifo_limit); |
5090 | 5101 | ||
5091 | if (adapter->hw.mac.tx_pkt_filtering) | 5102 | if (adapter->hw.mac.tx_pkt_filtering) |
5092 | e1000_transfer_dhcp_info(adapter, skb); | 5103 | e1000_transfer_dhcp_info(adapter, skb); |
@@ -5128,15 +5139,18 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, | |||
5128 | tx_flags |= E1000_TX_FLAGS_NO_FCS; | 5139 | tx_flags |= E1000_TX_FLAGS_NO_FCS; |
5129 | 5140 | ||
5130 | /* if count is 0 then mapping error has occurred */ | 5141 | /* if count is 0 then mapping error has occurred */ |
5131 | count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); | 5142 | count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit, |
5143 | nr_frags); | ||
5132 | if (count) { | 5144 | if (count) { |
5133 | skb_tx_timestamp(skb); | 5145 | skb_tx_timestamp(skb); |
5134 | 5146 | ||
5135 | netdev_sent_queue(netdev, skb->len); | 5147 | netdev_sent_queue(netdev, skb->len); |
5136 | e1000_tx_queue(tx_ring, tx_flags, count); | 5148 | e1000_tx_queue(tx_ring, tx_flags, count); |
5137 | /* Make sure there is space in the ring for the next send. */ | 5149 | /* Make sure there is space in the ring for the next send. */ |
5138 | e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); | 5150 | e1000_maybe_stop_tx(tx_ring, |
5139 | 5151 | (MAX_SKB_FRAGS * | |
5152 | DIV_ROUND_UP(PAGE_SIZE, | ||
5153 | adapter->tx_fifo_limit) + 2)); | ||
5140 | } else { | 5154 | } else { |
5141 | dev_kfree_skb_any(skb); | 5155 | dev_kfree_skb_any(skb); |
5142 | tx_ring->buffer_info[first].time_stamp = 0; | 5156 | tx_ring->buffer_info[first].time_stamp = 0; |
@@ -6311,8 +6325,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
6311 | adapter->hw.phy.autoneg_advertised = 0x2f; | 6325 | adapter->hw.phy.autoneg_advertised = 0x2f; |
6312 | 6326 | ||
6313 | /* ring size defaults */ | 6327 | /* ring size defaults */ |
6314 | adapter->rx_ring->count = 256; | 6328 | adapter->rx_ring->count = E1000_DEFAULT_RXD; |
6315 | adapter->tx_ring->count = 256; | 6329 | adapter->tx_ring->count = E1000_DEFAULT_TXD; |
6316 | 6330 | ||
6317 | /* | 6331 | /* |
6318 | * Initial Wake on LAN setting - If APM wake is enabled in | 6332 | * Initial Wake on LAN setting - If APM wake is enabled in |
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 5e84eaac48c1..ba994fb4cec6 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -254,6 +254,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
254 | */ | 254 | */ |
255 | size += NVM_WORD_SIZE_BASE_SHIFT; | 255 | size += NVM_WORD_SIZE_BASE_SHIFT; |
256 | 256 | ||
257 | /* | ||
258 | * Check for invalid size | ||
259 | */ | ||
260 | if ((hw->mac.type == e1000_82576) && (size > 15)) { | ||
261 | pr_notice("The NVM size is not valid, defaulting to 32K\n"); | ||
262 | size = 15; | ||
263 | } | ||
264 | |||
257 | nvm->word_size = 1 << size; | 265 | nvm->word_size = 1 << size; |
258 | if (hw->mac.type < e1000_i210) { | 266 | if (hw->mac.type < e1000_i210) { |
259 | nvm->opcode_bits = 8; | 267 | nvm->opcode_bits = 8; |
@@ -281,14 +289,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
281 | } else | 289 | } else |
282 | nvm->type = e1000_nvm_flash_hw; | 290 | nvm->type = e1000_nvm_flash_hw; |
283 | 291 | ||
284 | /* | ||
285 | * Check for invalid size | ||
286 | */ | ||
287 | if ((hw->mac.type == e1000_82576) && (size > 15)) { | ||
288 | pr_notice("The NVM size is not valid, defaulting to 32K\n"); | ||
289 | size = 15; | ||
290 | } | ||
291 | |||
292 | /* NVM Function Pointers */ | 292 | /* NVM Function Pointers */ |
293 | switch (hw->mac.type) { | 293 | switch (hw->mac.type) { |
294 | case e1000_82580: | 294 | case e1000_82580: |
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index 10efcd88dca0..28394bea5253 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h | |||
@@ -156,8 +156,12 @@ | |||
156 | : (0x0E018 + ((_n) * 0x40))) | 156 | : (0x0E018 + ((_n) * 0x40))) |
157 | #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ | 157 | #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ |
158 | : (0x0E028 + ((_n) * 0x40))) | 158 | : (0x0E028 + ((_n) * 0x40))) |
159 | #define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) | 159 | #define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ |
160 | #define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) | 160 | (0x0C014 + ((_n) * 0x40))) |
161 | #define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) | ||
162 | #define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ | ||
163 | (0x0E014 + ((_n) * 0x40))) | ||
164 | #define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) | ||
161 | #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ | 165 | #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ |
162 | : (0x0E038 + ((_n) * 0x40))) | 166 | : (0x0E038 + ((_n) * 0x40))) |
163 | #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ | 167 | #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index a19c84cad0e9..70591117051b 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
209 | /* When SoL/IDER sessions are active, autoneg/speed/duplex | 209 | /* When SoL/IDER sessions are active, autoneg/speed/duplex |
210 | * cannot be changed */ | 210 | * cannot be changed */ |
211 | if (igb_check_reset_block(hw)) { | 211 | if (igb_check_reset_block(hw)) { |
212 | dev_err(&adapter->pdev->dev, "Cannot change link " | 212 | dev_err(&adapter->pdev->dev, |
213 | "characteristics when SoL/IDER is active.\n"); | 213 | "Cannot change link characteristics when SoL/IDER is active.\n"); |
214 | return -EINVAL; | 214 | return -EINVAL; |
215 | } | 215 | } |
216 | 216 | ||
@@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, | |||
1089 | wr32(reg, (_test[pat] & write)); | 1089 | wr32(reg, (_test[pat] & write)); |
1090 | val = rd32(reg) & mask; | 1090 | val = rd32(reg) & mask; |
1091 | if (val != (_test[pat] & write & mask)) { | 1091 | if (val != (_test[pat] & write & mask)) { |
1092 | dev_err(&adapter->pdev->dev, "pattern test reg %04X " | 1092 | dev_err(&adapter->pdev->dev, |
1093 | "failed: got 0x%08X expected 0x%08X\n", | 1093 | "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", |
1094 | reg, val, (_test[pat] & write & mask)); | 1094 | reg, val, (_test[pat] & write & mask)); |
1095 | *data = reg; | 1095 | *data = reg; |
1096 | return 1; | 1096 | return 1; |
@@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, | |||
1108 | wr32(reg, write & mask); | 1108 | wr32(reg, write & mask); |
1109 | val = rd32(reg); | 1109 | val = rd32(reg); |
1110 | if ((write & mask) != (val & mask)) { | 1110 | if ((write & mask) != (val & mask)) { |
1111 | dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:" | 1111 | dev_err(&adapter->pdev->dev, |
1112 | " got 0x%08X expected 0x%08X\n", reg, | 1112 | "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, |
1113 | (val & mask), (write & mask)); | 1113 | (val & mask), (write & mask)); |
1114 | *data = reg; | 1114 | *data = reg; |
1115 | return 1; | 1115 | return 1; |
@@ -1171,8 +1171,9 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) | |||
1171 | wr32(E1000_STATUS, toggle); | 1171 | wr32(E1000_STATUS, toggle); |
1172 | after = rd32(E1000_STATUS) & toggle; | 1172 | after = rd32(E1000_STATUS) & toggle; |
1173 | if (value != after) { | 1173 | if (value != after) { |
1174 | dev_err(&adapter->pdev->dev, "failed STATUS register test " | 1174 | dev_err(&adapter->pdev->dev, |
1175 | "got: 0x%08X expected: 0x%08X\n", after, value); | 1175 | "failed STATUS register test got: 0x%08X expected: 0x%08X\n", |
1176 | after, value); | ||
1176 | *data = 1; | 1177 | *data = 1; |
1177 | return 1; | 1178 | return 1; |
1178 | } | 1179 | } |
@@ -1497,6 +1498,9 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) | |||
1497 | break; | 1498 | break; |
1498 | } | 1499 | } |
1499 | 1500 | ||
1501 | /* add small delay to avoid loopback test failure */ | ||
1502 | msleep(50); | ||
1503 | |||
1500 | /* force 1000, set loopback */ | 1504 | /* force 1000, set loopback */ |
1501 | igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); | 1505 | igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); |
1502 | 1506 | ||
@@ -1777,16 +1781,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data) | |||
1777 | * sessions are active */ | 1781 | * sessions are active */ |
1778 | if (igb_check_reset_block(&adapter->hw)) { | 1782 | if (igb_check_reset_block(&adapter->hw)) { |
1779 | dev_err(&adapter->pdev->dev, | 1783 | dev_err(&adapter->pdev->dev, |
1780 | "Cannot do PHY loopback test " | 1784 | "Cannot do PHY loopback test when SoL/IDER is active.\n"); |
1781 | "when SoL/IDER is active.\n"); | ||
1782 | *data = 0; | 1785 | *data = 0; |
1783 | goto out; | 1786 | goto out; |
1784 | } | 1787 | } |
1785 | if ((adapter->hw.mac.type == e1000_i210) | 1788 | if ((adapter->hw.mac.type == e1000_i210) |
1786 | || (adapter->hw.mac.type == e1000_i210)) { | 1789 | || (adapter->hw.mac.type == e1000_i211)) { |
1787 | dev_err(&adapter->pdev->dev, | 1790 | dev_err(&adapter->pdev->dev, |
1788 | "Loopback test not supported " | 1791 | "Loopback test not supported on this part at this time.\n"); |
1789 | "on this part at this time.\n"); | ||
1790 | *data = 0; | 1792 | *data = 0; |
1791 | goto out; | 1793 | goto out; |
1792 | } | 1794 | } |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index b7c2d5050572..48cc4fb1a307 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -462,10 +462,10 @@ static void igb_dump(struct igb_adapter *adapter) | |||
462 | (u64)buffer_info->time_stamp, | 462 | (u64)buffer_info->time_stamp, |
463 | buffer_info->skb, next_desc); | 463 | buffer_info->skb, next_desc); |
464 | 464 | ||
465 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 465 | if (netif_msg_pktdata(adapter) && buffer_info->skb) |
466 | print_hex_dump(KERN_INFO, "", | 466 | print_hex_dump(KERN_INFO, "", |
467 | DUMP_PREFIX_ADDRESS, | 467 | DUMP_PREFIX_ADDRESS, |
468 | 16, 1, phys_to_virt(buffer_info->dma), | 468 | 16, 1, buffer_info->skb->data, |
469 | buffer_info->length, true); | 469 | buffer_info->length, true); |
470 | } | 470 | } |
471 | } | 471 | } |
@@ -547,18 +547,17 @@ rx_ring_summary: | |||
547 | (u64)buffer_info->dma, | 547 | (u64)buffer_info->dma, |
548 | buffer_info->skb, next_desc); | 548 | buffer_info->skb, next_desc); |
549 | 549 | ||
550 | if (netif_msg_pktdata(adapter)) { | 550 | if (netif_msg_pktdata(adapter) && |
551 | buffer_info->dma && buffer_info->skb) { | ||
551 | print_hex_dump(KERN_INFO, "", | 552 | print_hex_dump(KERN_INFO, "", |
552 | DUMP_PREFIX_ADDRESS, | 553 | DUMP_PREFIX_ADDRESS, |
553 | 16, 1, | 554 | 16, 1, buffer_info->skb->data, |
554 | phys_to_virt(buffer_info->dma), | 555 | IGB_RX_HDR_LEN, true); |
555 | IGB_RX_HDR_LEN, true); | ||
556 | print_hex_dump(KERN_INFO, "", | 556 | print_hex_dump(KERN_INFO, "", |
557 | DUMP_PREFIX_ADDRESS, | 557 | DUMP_PREFIX_ADDRESS, |
558 | 16, 1, | 558 | 16, 1, |
559 | phys_to_virt( | 559 | page_address(buffer_info->page) + |
560 | buffer_info->page_dma + | 560 | buffer_info->page_offset, |
561 | buffer_info->page_offset), | ||
562 | PAGE_SIZE/2, true); | 561 | PAGE_SIZE/2, true); |
563 | } | 562 | } |
564 | } | 563 | } |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 50fc137501da..18bf08c9d7a4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | |||
@@ -804,12 +804,13 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, | |||
804 | link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { | 804 | link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { |
805 | /* Set KX4/KX/KR support according to speed requested */ | 805 | /* Set KX4/KX/KR support according to speed requested */ |
806 | autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); | 806 | autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); |
807 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) | 807 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) { |
808 | if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) | 808 | if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) |
809 | autoc |= IXGBE_AUTOC_KX4_SUPP; | 809 | autoc |= IXGBE_AUTOC_KX4_SUPP; |
810 | if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && | 810 | if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && |
811 | (hw->phy.smart_speed_active == false)) | 811 | (hw->phy.smart_speed_active == false)) |
812 | autoc |= IXGBE_AUTOC_KR_SUPP; | 812 | autoc |= IXGBE_AUTOC_KR_SUPP; |
813 | } | ||
813 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) | 814 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) |
814 | autoc |= IXGBE_AUTOC_KX_SUPP; | 815 | autoc |= IXGBE_AUTOC_KX_SUPP; |
815 | } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && | 816 | } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index f32e70300770..5aba5ecdf1e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -614,8 +614,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
614 | /* If source MAC is equal to our own MAC and not performing | 614 | /* If source MAC is equal to our own MAC and not performing |
615 | * the selftest or flb disabled - drop the packet */ | 615 | * the selftest or flb disabled - drop the packet */ |
616 | if (s_mac == priv->mac && | 616 | if (s_mac == priv->mac && |
617 | (!(dev->features & NETIF_F_LOOPBACK) || | 617 | !((dev->features & NETIF_F_LOOPBACK) || |
618 | !priv->validate_loopback)) | 618 | priv->validate_loopback)) |
619 | goto next; | 619 | goto next; |
620 | 620 | ||
621 | /* | 621 | /* |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 019d856b1334..10bba09c44ea 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -164,7 +164,6 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, | |||
164 | ring->cons = 0xffffffff; | 164 | ring->cons = 0xffffffff; |
165 | ring->last_nr_txbb = 1; | 165 | ring->last_nr_txbb = 1; |
166 | ring->poll_cnt = 0; | 166 | ring->poll_cnt = 0; |
167 | ring->blocked = 0; | ||
168 | memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); | 167 | memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); |
169 | memset(ring->buf, 0, ring->buf_size); | 168 | memset(ring->buf, 0, ring->buf_size); |
170 | 169 | ||
@@ -365,14 +364,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
365 | ring->cons += txbbs_skipped; | 364 | ring->cons += txbbs_skipped; |
366 | netdev_tx_completed_queue(ring->tx_queue, packets, bytes); | 365 | netdev_tx_completed_queue(ring->tx_queue, packets, bytes); |
367 | 366 | ||
368 | /* Wakeup Tx queue if this ring stopped it */ | 367 | /* |
369 | if (unlikely(ring->blocked)) { | 368 | * Wakeup Tx queue if this stopped, and at least 1 packet |
370 | if ((u32) (ring->prod - ring->cons) <= | 369 | * was completed |
371 | ring->size - HEADROOM - MAX_DESC_TXBBS) { | 370 | */ |
372 | ring->blocked = 0; | 371 | if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) { |
373 | netif_tx_wake_queue(ring->tx_queue); | 372 | netif_tx_wake_queue(ring->tx_queue); |
374 | priv->port_stats.wake_queue++; | 373 | priv->port_stats.wake_queue++; |
375 | } | ||
376 | } | 374 | } |
377 | } | 375 | } |
378 | 376 | ||
@@ -592,7 +590,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
592 | ring->size - HEADROOM - MAX_DESC_TXBBS)) { | 590 | ring->size - HEADROOM - MAX_DESC_TXBBS)) { |
593 | /* every full Tx ring stops queue */ | 591 | /* every full Tx ring stops queue */ |
594 | netif_tx_stop_queue(ring->tx_queue); | 592 | netif_tx_stop_queue(ring->tx_queue); |
595 | ring->blocked = 1; | ||
596 | priv->port_stats.queue_stopped++; | 593 | priv->port_stats.queue_stopped++; |
597 | 594 | ||
598 | return NETDEV_TX_BUSY; | 595 | return NETDEV_TX_BUSY; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 88b7b3e75ab1..31d02649be41 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c | |||
@@ -227,9 +227,10 @@ int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev) | |||
227 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | 227 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); |
228 | } | 228 | } |
229 | 229 | ||
230 | int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj) | 230 | int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj) |
231 | { | 231 | { |
232 | int i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size); | 232 | u32 i = (obj & (table->num_obj - 1)) / |
233 | (MLX4_TABLE_CHUNK_SIZE / table->obj_size); | ||
233 | int ret = 0; | 234 | int ret = 0; |
234 | 235 | ||
235 | mutex_lock(&table->mutex); | 236 | mutex_lock(&table->mutex); |
@@ -262,16 +263,18 @@ out: | |||
262 | return ret; | 263 | return ret; |
263 | } | 264 | } |
264 | 265 | ||
265 | void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj) | 266 | void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj) |
266 | { | 267 | { |
267 | int i; | 268 | u32 i; |
269 | u64 offset; | ||
268 | 270 | ||
269 | i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size); | 271 | i = (obj & (table->num_obj - 1)) / (MLX4_TABLE_CHUNK_SIZE / table->obj_size); |
270 | 272 | ||
271 | mutex_lock(&table->mutex); | 273 | mutex_lock(&table->mutex); |
272 | 274 | ||
273 | if (--table->icm[i]->refcount == 0) { | 275 | if (--table->icm[i]->refcount == 0) { |
274 | mlx4_UNMAP_ICM(dev, table->virt + i * MLX4_TABLE_CHUNK_SIZE, | 276 | offset = (u64) i * MLX4_TABLE_CHUNK_SIZE; |
277 | mlx4_UNMAP_ICM(dev, table->virt + offset, | ||
275 | MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); | 278 | MLX4_TABLE_CHUNK_SIZE / MLX4_ICM_PAGE_SIZE); |
276 | mlx4_free_icm(dev, table->icm[i], table->coherent); | 279 | mlx4_free_icm(dev, table->icm[i], table->coherent); |
277 | table->icm[i] = NULL; | 280 | table->icm[i] = NULL; |
@@ -280,9 +283,11 @@ void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj) | |||
280 | mutex_unlock(&table->mutex); | 283 | mutex_unlock(&table->mutex); |
281 | } | 284 | } |
282 | 285 | ||
283 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle) | 286 | void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj, |
287 | dma_addr_t *dma_handle) | ||
284 | { | 288 | { |
285 | int idx, offset, dma_offset, i; | 289 | int offset, dma_offset, i; |
290 | u64 idx; | ||
286 | struct mlx4_icm_chunk *chunk; | 291 | struct mlx4_icm_chunk *chunk; |
287 | struct mlx4_icm *icm; | 292 | struct mlx4_icm *icm; |
288 | struct page *page = NULL; | 293 | struct page *page = NULL; |
@@ -292,7 +297,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han | |||
292 | 297 | ||
293 | mutex_lock(&table->mutex); | 298 | mutex_lock(&table->mutex); |
294 | 299 | ||
295 | idx = (obj & (table->num_obj - 1)) * table->obj_size; | 300 | idx = (u64) (obj & (table->num_obj - 1)) * table->obj_size; |
296 | icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE]; | 301 | icm = table->icm[idx / MLX4_TABLE_CHUNK_SIZE]; |
297 | dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE; | 302 | dma_offset = offset = idx % MLX4_TABLE_CHUNK_SIZE; |
298 | 303 | ||
@@ -326,10 +331,11 @@ out: | |||
326 | } | 331 | } |
327 | 332 | ||
328 | int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 333 | int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
329 | int start, int end) | 334 | u32 start, u32 end) |
330 | { | 335 | { |
331 | int inc = MLX4_TABLE_CHUNK_SIZE / table->obj_size; | 336 | int inc = MLX4_TABLE_CHUNK_SIZE / table->obj_size; |
332 | int i, err; | 337 | int err; |
338 | u32 i; | ||
333 | 339 | ||
334 | for (i = start; i <= end; i += inc) { | 340 | for (i = start; i <= end; i += inc) { |
335 | err = mlx4_table_get(dev, table, i); | 341 | err = mlx4_table_get(dev, table, i); |
@@ -349,22 +355,23 @@ fail: | |||
349 | } | 355 | } |
350 | 356 | ||
351 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 357 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
352 | int start, int end) | 358 | u32 start, u32 end) |
353 | { | 359 | { |
354 | int i; | 360 | u32 i; |
355 | 361 | ||
356 | for (i = start; i <= end; i += MLX4_TABLE_CHUNK_SIZE / table->obj_size) | 362 | for (i = start; i <= end; i += MLX4_TABLE_CHUNK_SIZE / table->obj_size) |
357 | mlx4_table_put(dev, table, i); | 363 | mlx4_table_put(dev, table, i); |
358 | } | 364 | } |
359 | 365 | ||
360 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 366 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
361 | u64 virt, int obj_size, int nobj, int reserved, | 367 | u64 virt, int obj_size, u32 nobj, int reserved, |
362 | int use_lowmem, int use_coherent) | 368 | int use_lowmem, int use_coherent) |
363 | { | 369 | { |
364 | int obj_per_chunk; | 370 | int obj_per_chunk; |
365 | int num_icm; | 371 | int num_icm; |
366 | unsigned chunk_size; | 372 | unsigned chunk_size; |
367 | int i; | 373 | int i; |
374 | u64 size; | ||
368 | 375 | ||
369 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; | 376 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; |
370 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; | 377 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; |
@@ -380,10 +387,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
380 | table->coherent = use_coherent; | 387 | table->coherent = use_coherent; |
381 | mutex_init(&table->mutex); | 388 | mutex_init(&table->mutex); |
382 | 389 | ||
390 | size = (u64) nobj * obj_size; | ||
383 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { | 391 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { |
384 | chunk_size = MLX4_TABLE_CHUNK_SIZE; | 392 | chunk_size = MLX4_TABLE_CHUNK_SIZE; |
385 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size) | 393 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size) |
386 | chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE); | 394 | chunk_size = PAGE_ALIGN(size - |
395 | i * MLX4_TABLE_CHUNK_SIZE); | ||
387 | 396 | ||
388 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, | 397 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, |
389 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | | 398 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h index 19e4efc0b342..dee67fa39107 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.h +++ b/drivers/net/ethernet/mellanox/mlx4/icm.h | |||
@@ -71,17 +71,17 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, | |||
71 | gfp_t gfp_mask, int coherent); | 71 | gfp_t gfp_mask, int coherent); |
72 | void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent); | 72 | void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent); |
73 | 73 | ||
74 | int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); | 74 | int mlx4_table_get(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj); |
75 | void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, int obj); | 75 | void mlx4_table_put(struct mlx4_dev *dev, struct mlx4_icm_table *table, u32 obj); |
76 | int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 76 | int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
77 | int start, int end); | 77 | u32 start, u32 end); |
78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
79 | int start, int end); | 79 | u32 start, u32 end); |
80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
81 | u64 virt, int obj_size, int nobj, int reserved, | 81 | u64 virt, int obj_size, u32 nobj, int reserved, |
82 | int use_lowmem, int use_coherent); | 82 | int use_lowmem, int use_coherent); |
83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); | 83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); |
84 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); | 84 | void *mlx4_table_find(struct mlx4_icm_table *table, u32 obj, dma_addr_t *dma_handle); |
85 | 85 | ||
86 | static inline void mlx4_icm_first(struct mlx4_icm *icm, | 86 | static inline void mlx4_icm_first(struct mlx4_icm *icm, |
87 | struct mlx4_icm_iter *iter) | 87 | struct mlx4_icm_iter *iter) |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 48d0e90194cb..2f816c6aed72 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -157,9 +157,6 @@ int mlx4_check_port_params(struct mlx4_dev *dev, | |||
157 | "on this HCA, aborting.\n"); | 157 | "on this HCA, aborting.\n"); |
158 | return -EINVAL; | 158 | return -EINVAL; |
159 | } | 159 | } |
160 | if (port_type[i] == MLX4_PORT_TYPE_ETH && | ||
161 | port_type[i + 1] == MLX4_PORT_TYPE_IB) | ||
162 | return -EINVAL; | ||
163 | } | 160 | } |
164 | } | 161 | } |
165 | 162 | ||
@@ -1237,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1237 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | 1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); |
1238 | else | 1235 | else |
1239 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); |
1240 | goto unmap_bf; | 1237 | return err; |
1241 | } | 1238 | } |
1242 | 1239 | ||
1243 | err = mlx4_load_fw(dev); | 1240 | err = mlx4_load_fw(dev); |
1244 | if (err) { | 1241 | if (err) { |
1245 | mlx4_err(dev, "Failed to start FW, aborting.\n"); | 1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); |
1246 | goto unmap_bf; | 1243 | return err; |
1247 | } | 1244 | } |
1248 | 1245 | ||
1249 | mlx4_cfg.log_pg_sz_m = 1; | 1246 | mlx4_cfg.log_pg_sz_m = 1; |
@@ -1307,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1307 | err = mlx4_init_slave(dev); | 1304 | err = mlx4_init_slave(dev); |
1308 | if (err) { | 1305 | if (err) { |
1309 | mlx4_err(dev, "Failed to initialize slave\n"); | 1306 | mlx4_err(dev, "Failed to initialize slave\n"); |
1310 | goto unmap_bf; | 1307 | return err; |
1311 | } | 1308 | } |
1312 | 1309 | ||
1313 | err = mlx4_slave_cap(dev); | 1310 | err = mlx4_slave_cap(dev); |
@@ -1327,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1327 | err = mlx4_QUERY_ADAPTER(dev, &adapter); | 1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); |
1328 | if (err) { | 1325 | if (err) { |
1329 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); | 1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); |
1330 | goto err_close; | 1327 | goto unmap_bf; |
1331 | } | 1328 | } |
1332 | 1329 | ||
1333 | priv->eq_table.inta_pin = adapter.inta_pin; | 1330 | priv->eq_table.inta_pin = adapter.inta_pin; |
@@ -1335,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1335 | 1332 | ||
1336 | return 0; | 1333 | return 0; |
1337 | 1334 | ||
1335 | unmap_bf: | ||
1336 | unmap_bf_area(dev); | ||
1337 | |||
1338 | err_close: | 1338 | err_close: |
1339 | mlx4_close_hca(dev); | 1339 | mlx4_close_hca(dev); |
1340 | 1340 | ||
@@ -1347,8 +1347,6 @@ err_stop_fw: | |||
1347 | mlx4_UNMAP_FA(dev); | 1347 | mlx4_UNMAP_FA(dev); |
1348 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | 1348 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); |
1349 | } | 1349 | } |
1350 | unmap_bf: | ||
1351 | unmap_bf_area(dev); | ||
1352 | return err; | 1350 | return err; |
1353 | } | 1351 | } |
1354 | 1352 | ||
@@ -1999,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1999 | } | 1997 | } |
2000 | 1998 | ||
2001 | slave_start: | 1999 | slave_start: |
2002 | if (mlx4_cmd_init(dev)) { | 2000 | err = mlx4_cmd_init(dev); |
2001 | if (err) { | ||
2003 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); | 2002 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); |
2004 | goto err_sriov; | 2003 | goto err_sriov; |
2005 | } | 2004 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 4ec3835e1bc2..e151c21baf2b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, | |||
137 | return err; | 137 | return err; |
138 | } | 138 | } |
139 | 139 | ||
140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, | 140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, |
141 | enum mlx4_steer_type steer, | 141 | enum mlx4_steer_type steer, |
142 | u32 qpn) | 142 | u32 qpn) |
143 | { | 143 | { |
144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; | 144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1]; |
145 | struct mlx4_promisc_qp *pqp; | 145 | struct mlx4_promisc_qp *pqp; |
146 | 146 | ||
147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { | 147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { |
@@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, | |||
182 | /* If the given qpn is also a promisc qp, | 182 | /* If the given qpn is also a promisc qp, |
183 | * it should be inserted to duplicates list | 183 | * it should be inserted to duplicates list |
184 | */ | 184 | */ |
185 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 185 | pqp = get_promisc_qp(dev, port, steer, qpn); |
186 | if (pqp) { | 186 | if (pqp) { |
187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
188 | if (!dqp) { | 188 | if (!dqp) { |
@@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, | |||
256 | 256 | ||
257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
258 | 258 | ||
259 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 259 | pqp = get_promisc_qp(dev, port, steer, qpn); |
260 | if (!pqp) | 260 | if (!pqp) |
261 | return 0; /* nothing to do */ | 261 | return 0; /* nothing to do */ |
262 | 262 | ||
@@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, | |||
302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
303 | 303 | ||
304 | /* if qp is not promisc, it cannot be duplicated */ | 304 | /* if qp is not promisc, it cannot be duplicated */ |
305 | if (!get_promisc_qp(dev, 0, steer, qpn)) | 305 | if (!get_promisc_qp(dev, port, steer, qpn)) |
306 | return false; | 306 | return false; |
307 | 307 | ||
308 | /* The qp is promisc qp so it is a duplicate on this index | 308 | /* The qp is promisc qp so it is a duplicate on this index |
@@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, | |||
352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; | 352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; |
353 | for (i = 0; i < members_count; i++) { | 353 | for (i = 0; i < members_count; i++) { |
354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; | 354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; |
355 | if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { | 355 | if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) { |
356 | /* the qp is not promisc, the entry can't be removed */ | 356 | /* the qp is not promisc, the entry can't be removed */ |
357 | goto out; | 357 | goto out; |
358 | } | 358 | } |
@@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
398 | 398 | ||
399 | mutex_lock(&priv->mcg_table.mutex); | 399 | mutex_lock(&priv->mcg_table.mutex); |
400 | 400 | ||
401 | if (get_promisc_qp(dev, 0, steer, qpn)) { | 401 | if (get_promisc_qp(dev, port, steer, qpn)) { |
402 | err = 0; /* Noting to do, already exists */ | 402 | err = 0; /* Noting to do, already exists */ |
403 | goto out_mutex; | 403 | goto out_mutex; |
404 | } | 404 | } |
@@ -432,8 +432,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
432 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { | 432 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { |
433 | /* Entry already exists, add to duplicates */ | 433 | /* Entry already exists, add to duplicates */ |
434 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 434 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
435 | if (!dqp) | 435 | if (!dqp) { |
436 | err = -ENOMEM; | ||
436 | goto out_mailbox; | 437 | goto out_mailbox; |
438 | } | ||
437 | dqp->qpn = qpn; | 439 | dqp->qpn = qpn; |
438 | list_add_tail(&dqp->list, &entry->duplicates); | 440 | list_add_tail(&dqp->list, &entry->duplicates); |
439 | found = true; | 441 | found = true; |
@@ -501,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
501 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
502 | mutex_lock(&priv->mcg_table.mutex); | 504 | mutex_lock(&priv->mcg_table.mutex); |
503 | 505 | ||
504 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 506 | pqp = get_promisc_qp(dev, port, steer, qpn); |
505 | if (unlikely(!pqp)) { | 507 | if (unlikely(!pqp)) { |
506 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); | 508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); |
507 | /* nothing to do */ | 509 | /* nothing to do */ |
@@ -648,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
648 | return err; | 650 | return err; |
649 | } | 651 | } |
650 | 652 | ||
651 | struct mlx4_net_trans_rule_hw_ctrl { | ||
652 | __be32 ctrl; | ||
653 | __be32 vf_vep_port; | ||
654 | __be32 qpn; | ||
655 | __be32 reserved; | ||
656 | }; | ||
657 | |||
658 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | 653 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, |
659 | struct mlx4_net_trans_rule_hw_ctrl *hw) | 654 | struct mlx4_net_trans_rule_hw_ctrl *hw) |
660 | { | 655 | { |
@@ -678,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | |||
678 | hw->qpn = cpu_to_be32(ctrl->qpn); | 673 | hw->qpn = cpu_to_be32(ctrl->qpn); |
679 | } | 674 | } |
680 | 675 | ||
681 | struct mlx4_net_trans_rule_hw_ib { | 676 | const u16 __sw_id_hw[] = { |
682 | u8 size; | 677 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, |
683 | u8 rsvd1; | 678 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, |
684 | __be16 id; | 679 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, |
685 | u32 rsvd2; | 680 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, |
686 | __be32 qpn; | 681 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, |
687 | __be32 qpn_mask; | 682 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 |
688 | u8 dst_gid[16]; | ||
689 | u8 dst_gid_msk[16]; | ||
690 | } __packed; | ||
691 | |||
692 | struct mlx4_net_trans_rule_hw_eth { | ||
693 | u8 size; | ||
694 | u8 rsvd; | ||
695 | __be16 id; | ||
696 | u8 rsvd1[6]; | ||
697 | u8 dst_mac[6]; | ||
698 | u16 rsvd2; | ||
699 | u8 dst_mac_msk[6]; | ||
700 | u16 rsvd3; | ||
701 | u8 src_mac[6]; | ||
702 | u16 rsvd4; | ||
703 | u8 src_mac_msk[6]; | ||
704 | u8 rsvd5; | ||
705 | u8 ether_type_enable; | ||
706 | __be16 ether_type; | ||
707 | __be16 vlan_id_msk; | ||
708 | __be16 vlan_id; | ||
709 | } __packed; | ||
710 | |||
711 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
712 | u8 size; | ||
713 | u8 rsvd; | ||
714 | __be16 id; | ||
715 | __be16 rsvd1[3]; | ||
716 | __be16 dst_port; | ||
717 | __be16 rsvd2; | ||
718 | __be16 dst_port_msk; | ||
719 | __be16 rsvd3; | ||
720 | __be16 src_port; | ||
721 | __be16 rsvd4; | ||
722 | __be16 src_port_msk; | ||
723 | } __packed; | ||
724 | |||
725 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
726 | u8 size; | ||
727 | u8 rsvd; | ||
728 | __be16 id; | ||
729 | __be32 rsvd1; | ||
730 | __be32 dst_ip; | ||
731 | __be32 dst_ip_msk; | ||
732 | __be32 src_ip; | ||
733 | __be32 src_ip_msk; | ||
734 | } __packed; | ||
735 | |||
736 | struct _rule_hw { | ||
737 | union { | ||
738 | struct { | ||
739 | u8 size; | ||
740 | u8 rsvd; | ||
741 | __be16 id; | ||
742 | }; | ||
743 | struct mlx4_net_trans_rule_hw_eth eth; | ||
744 | struct mlx4_net_trans_rule_hw_ib ib; | ||
745 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
746 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
747 | }; | ||
748 | }; | 683 | }; |
749 | 684 | ||
750 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, | 685 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, |
751 | struct _rule_hw *rule_hw) | 686 | struct _rule_hw *rule_hw) |
752 | { | 687 | { |
753 | static const u16 __sw_id_hw[] = { | ||
754 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, | ||
755 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, | ||
756 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, | ||
757 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, | ||
758 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, | ||
759 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 | ||
760 | }; | ||
761 | |||
762 | static const size_t __rule_hw_sz[] = { | 688 | static const size_t __rule_hw_sz[] = { |
763 | [MLX4_NET_TRANS_RULE_ID_ETH] = | 689 | [MLX4_NET_TRANS_RULE_ID_ETH] = |
764 | sizeof(struct mlx4_net_trans_rule_hw_eth), | 690 | sizeof(struct mlx4_net_trans_rule_hw_eth), |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 59ebc0339638..dba69d98734a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -249,7 +249,7 @@ struct mlx4_bitmap { | |||
249 | struct mlx4_buddy { | 249 | struct mlx4_buddy { |
250 | unsigned long **bits; | 250 | unsigned long **bits; |
251 | unsigned int *num_free; | 251 | unsigned int *num_free; |
252 | int max_order; | 252 | u32 max_order; |
253 | spinlock_t lock; | 253 | spinlock_t lock; |
254 | }; | 254 | }; |
255 | 255 | ||
@@ -258,7 +258,7 @@ struct mlx4_icm; | |||
258 | struct mlx4_icm_table { | 258 | struct mlx4_icm_table { |
259 | u64 virt; | 259 | u64 virt; |
260 | int num_icm; | 260 | int num_icm; |
261 | int num_obj; | 261 | u32 num_obj; |
262 | int obj_size; | 262 | int obj_size; |
263 | int lowmem; | 263 | int lowmem; |
264 | int coherent; | 264 | int coherent; |
@@ -690,6 +690,82 @@ struct mlx4_steer { | |||
690 | struct list_head steer_entries[MLX4_NUM_STEERS]; | 690 | struct list_head steer_entries[MLX4_NUM_STEERS]; |
691 | }; | 691 | }; |
692 | 692 | ||
693 | struct mlx4_net_trans_rule_hw_ctrl { | ||
694 | __be32 ctrl; | ||
695 | __be32 vf_vep_port; | ||
696 | __be32 qpn; | ||
697 | __be32 reserved; | ||
698 | }; | ||
699 | |||
700 | struct mlx4_net_trans_rule_hw_ib { | ||
701 | u8 size; | ||
702 | u8 rsvd1; | ||
703 | __be16 id; | ||
704 | u32 rsvd2; | ||
705 | __be32 qpn; | ||
706 | __be32 qpn_mask; | ||
707 | u8 dst_gid[16]; | ||
708 | u8 dst_gid_msk[16]; | ||
709 | } __packed; | ||
710 | |||
711 | struct mlx4_net_trans_rule_hw_eth { | ||
712 | u8 size; | ||
713 | u8 rsvd; | ||
714 | __be16 id; | ||
715 | u8 rsvd1[6]; | ||
716 | u8 dst_mac[6]; | ||
717 | u16 rsvd2; | ||
718 | u8 dst_mac_msk[6]; | ||
719 | u16 rsvd3; | ||
720 | u8 src_mac[6]; | ||
721 | u16 rsvd4; | ||
722 | u8 src_mac_msk[6]; | ||
723 | u8 rsvd5; | ||
724 | u8 ether_type_enable; | ||
725 | __be16 ether_type; | ||
726 | __be16 vlan_id_msk; | ||
727 | __be16 vlan_id; | ||
728 | } __packed; | ||
729 | |||
730 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
731 | u8 size; | ||
732 | u8 rsvd; | ||
733 | __be16 id; | ||
734 | __be16 rsvd1[3]; | ||
735 | __be16 dst_port; | ||
736 | __be16 rsvd2; | ||
737 | __be16 dst_port_msk; | ||
738 | __be16 rsvd3; | ||
739 | __be16 src_port; | ||
740 | __be16 rsvd4; | ||
741 | __be16 src_port_msk; | ||
742 | } __packed; | ||
743 | |||
744 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
745 | u8 size; | ||
746 | u8 rsvd; | ||
747 | __be16 id; | ||
748 | __be32 rsvd1; | ||
749 | __be32 dst_ip; | ||
750 | __be32 dst_ip_msk; | ||
751 | __be32 src_ip; | ||
752 | __be32 src_ip_msk; | ||
753 | } __packed; | ||
754 | |||
755 | struct _rule_hw { | ||
756 | union { | ||
757 | struct { | ||
758 | u8 size; | ||
759 | u8 rsvd; | ||
760 | __be16 id; | ||
761 | }; | ||
762 | struct mlx4_net_trans_rule_hw_eth eth; | ||
763 | struct mlx4_net_trans_rule_hw_ib ib; | ||
764 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
765 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
766 | }; | ||
767 | }; | ||
768 | |||
693 | struct mlx4_priv { | 769 | struct mlx4_priv { |
694 | struct mlx4_dev dev; | 770 | struct mlx4_dev dev; |
695 | 771 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 5f1ab105debc..9d27e42264e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -248,7 +248,6 @@ struct mlx4_en_tx_ring { | |||
248 | u32 doorbell_qpn; | 248 | u32 doorbell_qpn; |
249 | void *buf; | 249 | void *buf; |
250 | u16 poll_cnt; | 250 | u16 poll_cnt; |
251 | int blocked; | ||
252 | struct mlx4_en_tx_info *tx_info; | 251 | struct mlx4_en_tx_info *tx_info; |
253 | u8 *bounce_buf; | 252 | u8 *bounce_buf; |
254 | u32 last_nr_txbb; | 253 | u32 last_nr_txbb; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index af55b7ce5341..c202d3ad2a0e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/export.h> | 37 | #include <linux/export.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/vmalloc.h> | ||
40 | 41 | ||
41 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
42 | 43 | ||
@@ -120,7 +121,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
120 | buddy->max_order = max_order; | 121 | buddy->max_order = max_order; |
121 | spin_lock_init(&buddy->lock); | 122 | spin_lock_init(&buddy->lock); |
122 | 123 | ||
123 | buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), | 124 | buddy->bits = kcalloc(buddy->max_order + 1, sizeof (long *), |
124 | GFP_KERNEL); | 125 | GFP_KERNEL); |
125 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, | 126 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, |
126 | GFP_KERNEL); | 127 | GFP_KERNEL); |
@@ -129,10 +130,12 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
129 | 130 | ||
130 | for (i = 0; i <= buddy->max_order; ++i) { | 131 | for (i = 0; i <= buddy->max_order; ++i) { |
131 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); | 132 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); |
132 | buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL); | 133 | buddy->bits[i] = kcalloc(s, sizeof (long), GFP_KERNEL | __GFP_NOWARN); |
133 | if (!buddy->bits[i]) | 134 | if (!buddy->bits[i]) { |
134 | goto err_out_free; | 135 | buddy->bits[i] = vzalloc(s * sizeof(long)); |
135 | bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i)); | 136 | if (!buddy->bits[i]) |
137 | goto err_out_free; | ||
138 | } | ||
136 | } | 139 | } |
137 | 140 | ||
138 | set_bit(0, buddy->bits[buddy->max_order]); | 141 | set_bit(0, buddy->bits[buddy->max_order]); |
@@ -142,7 +145,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
142 | 145 | ||
143 | err_out_free: | 146 | err_out_free: |
144 | for (i = 0; i <= buddy->max_order; ++i) | 147 | for (i = 0; i <= buddy->max_order; ++i) |
145 | kfree(buddy->bits[i]); | 148 | if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i])) |
149 | vfree(buddy->bits[i]); | ||
150 | else | ||
151 | kfree(buddy->bits[i]); | ||
146 | 152 | ||
147 | err_out: | 153 | err_out: |
148 | kfree(buddy->bits); | 154 | kfree(buddy->bits); |
@@ -156,7 +162,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) | |||
156 | int i; | 162 | int i; |
157 | 163 | ||
158 | for (i = 0; i <= buddy->max_order; ++i) | 164 | for (i = 0; i <= buddy->max_order; ++i) |
159 | kfree(buddy->bits[i]); | 165 | if (is_vmalloc_addr(buddy->bits[i])) |
166 | vfree(buddy->bits[i]); | ||
167 | else | ||
168 | kfree(buddy->bits[i]); | ||
160 | 169 | ||
161 | kfree(buddy->bits); | 170 | kfree(buddy->bits); |
162 | kfree(buddy->num_free); | 171 | kfree(buddy->num_free); |
@@ -668,7 +677,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
668 | return err; | 677 | return err; |
669 | 678 | ||
670 | err = mlx4_buddy_init(&mr_table->mtt_buddy, | 679 | err = mlx4_buddy_init(&mr_table->mtt_buddy, |
671 | ilog2(dev->caps.num_mtts / | 680 | ilog2((u32)dev->caps.num_mtts / |
672 | (1 << log_mtts_per_seg))); | 681 | (1 << log_mtts_per_seg))); |
673 | if (err) | 682 | if (err) |
674 | goto err_buddy; | 683 | goto err_buddy; |
@@ -678,7 +687,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
678 | mlx4_alloc_mtt_range(dev, | 687 | mlx4_alloc_mtt_range(dev, |
679 | fls(dev->caps.reserved_mtts - 1)); | 688 | fls(dev->caps.reserved_mtts - 1)); |
680 | if (priv->reserved_mtts < 0) { | 689 | if (priv->reserved_mtts < 0) { |
681 | mlx4_warn(dev, "MTT table of order %d is too small.\n", | 690 | mlx4_warn(dev, "MTT table of order %u is too small.\n", |
682 | mr_table->mtt_buddy.max_order); | 691 | mr_table->mtt_buddy.max_order); |
683 | err = -ENOMEM; | 692 | err = -ENOMEM; |
684 | goto err_reserve_mtts; | 693 | goto err_reserve_mtts; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 9ee4725363d5..8e0c3cc2a1ec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c | |||
@@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
76 | u64 size; | 76 | u64 size; |
77 | u64 start; | 77 | u64 start; |
78 | int type; | 78 | int type; |
79 | int num; | 79 | u32 num; |
80 | int log_num; | 80 | int log_num; |
81 | }; | 81 | }; |
82 | 82 | ||
@@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
105 | si_meminfo(&si); | 105 | si_meminfo(&si); |
106 | request->num_mtt = | 106 | request->num_mtt = |
107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, | 107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, |
108 | min(1UL << 31, | 108 | min(1UL << (31 - log_mtts_per_seg), |
109 | si.totalram >> (log_mtts_per_seg - 1)))); | 109 | si.totalram >> (log_mtts_per_seg - 1)))); |
110 | 110 | ||
111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; | 111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab2..293c9e820c49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
43 | #include <linux/mlx4/qp.h> | 43 | #include <linux/mlx4/qp.h> |
44 | #include <linux/if_ether.h> | 44 | #include <linux/if_ether.h> |
45 | #include <linux/etherdevice.h> | ||
45 | 46 | ||
46 | #include "mlx4.h" | 47 | #include "mlx4.h" |
47 | #include "fw.h" | 48 | #include "fw.h" |
@@ -2776,18 +2777,133 @@ ex_put: | |||
2776 | return err; | 2777 | return err; |
2777 | } | 2778 | } |
2778 | 2779 | ||
2780 | /* | ||
2781 | * MAC validation for Flow Steering rules. | ||
2782 | * VF can attach rules only with a mac address which is assigned to it. | ||
2783 | */ | ||
2784 | static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, | ||
2785 | struct list_head *rlist) | ||
2786 | { | ||
2787 | struct mac_res *res, *tmp; | ||
2788 | __be64 be_mac; | ||
2789 | |||
2790 | /* make sure it isn't multicast or broadcast mac*/ | ||
2791 | if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && | ||
2792 | !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { | ||
2793 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2794 | be_mac = cpu_to_be64(res->mac << 16); | ||
2795 | if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) | ||
2796 | return 0; | ||
2797 | } | ||
2798 | pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", | ||
2799 | eth_header->eth.dst_mac, slave); | ||
2800 | return -EINVAL; | ||
2801 | } | ||
2802 | return 0; | ||
2803 | } | ||
2804 | |||
2805 | /* | ||
2806 | * In case of missing eth header, append eth header with a MAC address | ||
2807 | * assigned to the VF. | ||
2808 | */ | ||
2809 | static int add_eth_header(struct mlx4_dev *dev, int slave, | ||
2810 | struct mlx4_cmd_mailbox *inbox, | ||
2811 | struct list_head *rlist, int header_id) | ||
2812 | { | ||
2813 | struct mac_res *res, *tmp; | ||
2814 | u8 port; | ||
2815 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2816 | struct mlx4_net_trans_rule_hw_eth *eth_header; | ||
2817 | struct mlx4_net_trans_rule_hw_ipv4 *ip_header; | ||
2818 | struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; | ||
2819 | __be64 be_mac = 0; | ||
2820 | __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
2821 | |||
2822 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2823 | port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; | ||
2824 | eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); | ||
2825 | |||
2826 | /* Clear a space in the inbox for eth header */ | ||
2827 | switch (header_id) { | ||
2828 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2829 | ip_header = | ||
2830 | (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); | ||
2831 | memmove(ip_header, eth_header, | ||
2832 | sizeof(*ip_header) + sizeof(*l4_header)); | ||
2833 | break; | ||
2834 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2835 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2836 | l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) | ||
2837 | (eth_header + 1); | ||
2838 | memmove(l4_header, eth_header, sizeof(*l4_header)); | ||
2839 | break; | ||
2840 | default: | ||
2841 | return -EINVAL; | ||
2842 | } | ||
2843 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2844 | if (port == res->port) { | ||
2845 | be_mac = cpu_to_be64(res->mac << 16); | ||
2846 | break; | ||
2847 | } | ||
2848 | } | ||
2849 | if (!be_mac) { | ||
2850 | pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", | ||
2851 | port); | ||
2852 | return -EINVAL; | ||
2853 | } | ||
2854 | |||
2855 | memset(eth_header, 0, sizeof(*eth_header)); | ||
2856 | eth_header->size = sizeof(*eth_header) >> 2; | ||
2857 | eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); | ||
2858 | memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); | ||
2859 | memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); | ||
2860 | |||
2861 | return 0; | ||
2862 | |||
2863 | } | ||
2864 | |||
2779 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 2865 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
2780 | struct mlx4_vhcr *vhcr, | 2866 | struct mlx4_vhcr *vhcr, |
2781 | struct mlx4_cmd_mailbox *inbox, | 2867 | struct mlx4_cmd_mailbox *inbox, |
2782 | struct mlx4_cmd_mailbox *outbox, | 2868 | struct mlx4_cmd_mailbox *outbox, |
2783 | struct mlx4_cmd_info *cmd) | 2869 | struct mlx4_cmd_info *cmd) |
2784 | { | 2870 | { |
2871 | |||
2872 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
2873 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | ||
2874 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | ||
2785 | int err; | 2875 | int err; |
2876 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2877 | struct _rule_hw *rule_header; | ||
2878 | int header_id; | ||
2786 | 2879 | ||
2787 | if (dev->caps.steering_mode != | 2880 | if (dev->caps.steering_mode != |
2788 | MLX4_STEERING_MODE_DEVICE_MANAGED) | 2881 | MLX4_STEERING_MODE_DEVICE_MANAGED) |
2789 | return -EOPNOTSUPP; | 2882 | return -EOPNOTSUPP; |
2790 | 2883 | ||
2884 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2885 | rule_header = (struct _rule_hw *)(ctrl + 1); | ||
2886 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | ||
2887 | |||
2888 | switch (header_id) { | ||
2889 | case MLX4_NET_TRANS_RULE_ID_ETH: | ||
2890 | if (validate_eth_header_mac(slave, rule_header, rlist)) | ||
2891 | return -EINVAL; | ||
2892 | break; | ||
2893 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2894 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2895 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2896 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | ||
2897 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | ||
2898 | return -EINVAL; | ||
2899 | vhcr->in_modifier += | ||
2900 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | ||
2901 | break; | ||
2902 | default: | ||
2903 | pr_err("Corrupted mailbox.\n"); | ||
2904 | return -EINVAL; | ||
2905 | } | ||
2906 | |||
2791 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 2907 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
2792 | vhcr->in_modifier, 0, | 2908 | vhcr->in_modifier, 0, |
2793 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 2909 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/sense.c b/drivers/net/ethernet/mellanox/mlx4/sense.c index 802498293528..34ee09bae36e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/sense.c +++ b/drivers/net/ethernet/mellanox/mlx4/sense.c | |||
@@ -81,20 +81,6 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev, | |||
81 | } | 81 | } |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Adjust port configuration: | ||
85 | * If port 1 sensed nothing and port 2 is IB, set both as IB | ||
86 | * If port 2 sensed nothing and port 1 is Eth, set both as Eth | ||
87 | */ | ||
88 | if (stype[0] == MLX4_PORT_TYPE_ETH) { | ||
89 | for (i = 1; i < dev->caps.num_ports; i++) | ||
90 | stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH; | ||
91 | } | ||
92 | if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) { | ||
93 | for (i = 0; i < dev->caps.num_ports - 1; i++) | ||
94 | stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * If sensed nothing, remain in current configuration. | 84 | * If sensed nothing, remain in current configuration. |
99 | */ | 85 | */ |
100 | for (i = 0; i < dev->caps.num_ports; i++) | 86 | for (i = 0; i < dev->caps.num_ports; i++) |
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 4069edab229e..53743f7a2ca9 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
@@ -346,28 +346,15 @@ static phy_interface_t lpc_phy_interface_mode(struct device *dev) | |||
346 | "phy-mode", NULL); | 346 | "phy-mode", NULL); |
347 | if (mode && !strcmp(mode, "mii")) | 347 | if (mode && !strcmp(mode, "mii")) |
348 | return PHY_INTERFACE_MODE_MII; | 348 | return PHY_INTERFACE_MODE_MII; |
349 | return PHY_INTERFACE_MODE_RMII; | ||
350 | } | 349 | } |
351 | |||
352 | /* non-DT */ | ||
353 | #ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT | ||
354 | return PHY_INTERFACE_MODE_MII; | ||
355 | #else | ||
356 | return PHY_INTERFACE_MODE_RMII; | 350 | return PHY_INTERFACE_MODE_RMII; |
357 | #endif | ||
358 | } | 351 | } |
359 | 352 | ||
360 | static bool use_iram_for_net(struct device *dev) | 353 | static bool use_iram_for_net(struct device *dev) |
361 | { | 354 | { |
362 | if (dev && dev->of_node) | 355 | if (dev && dev->of_node) |
363 | return of_property_read_bool(dev->of_node, "use-iram"); | 356 | return of_property_read_bool(dev->of_node, "use-iram"); |
364 | |||
365 | /* non-DT */ | ||
366 | #ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET | ||
367 | return true; | ||
368 | #else | ||
369 | return false; | 357 | return false; |
370 | #endif | ||
371 | } | 358 | } |
372 | 359 | ||
373 | /* Receive Status information word */ | 360 | /* Receive Status information word */ |
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 342b3a79bd0f..a77c558d8f40 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | |||
@@ -1378,6 +1378,10 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) | |||
1378 | struct pci_dev *root = pdev->bus->self; | 1378 | struct pci_dev *root = pdev->bus->self; |
1379 | u32 aer_pos; | 1379 | u32 aer_pos; |
1380 | 1380 | ||
1381 | /* root bus? */ | ||
1382 | if (!root) | ||
1383 | return; | ||
1384 | |||
1381 | if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM && | 1385 | if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM && |
1382 | adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) | 1386 | adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) |
1383 | return; | 1387 | return; |
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 46df3a04030c..24c2305d7948 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig | |||
@@ -8,7 +8,7 @@ config SH_ETH | |||
8 | (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ | 8 | (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ |
9 | CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ | 9 | CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ |
10 | CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ | 10 | CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ |
11 | CPU_SUBTYPE_SH7757 || ARCH_R8A7740) | 11 | CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || ARCH_R8A7779) |
12 | select CRC32 | 12 | select CRC32 |
13 | select NET_CORE | 13 | select NET_CORE |
14 | select MII | 14 | select MII |
@@ -18,4 +18,4 @@ config SH_ETH | |||
18 | Renesas SuperH Ethernet device driver. | 18 | Renesas SuperH Ethernet device driver. |
19 | This driver supporting CPUs are: | 19 | This driver supporting CPUs are: |
20 | - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, | 20 | - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, |
21 | and R8A7740. | 21 | R8A7740 and R8A7779. |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index af0b867a6cf6..bad8f2eec9b4 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -78,7 +78,7 @@ static void sh_eth_select_mii(struct net_device *ndev) | |||
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | /* There is CPU dependent code */ | 80 | /* There is CPU dependent code */ |
81 | #if defined(CONFIG_CPU_SUBTYPE_SH7724) | 81 | #if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779) |
82 | #define SH_ETH_RESET_DEFAULT 1 | 82 | #define SH_ETH_RESET_DEFAULT 1 |
83 | static void sh_eth_set_duplex(struct net_device *ndev) | 83 | static void sh_eth_set_duplex(struct net_device *ndev) |
84 | { | 84 | { |
@@ -93,13 +93,18 @@ static void sh_eth_set_duplex(struct net_device *ndev) | |||
93 | static void sh_eth_set_rate(struct net_device *ndev) | 93 | static void sh_eth_set_rate(struct net_device *ndev) |
94 | { | 94 | { |
95 | struct sh_eth_private *mdp = netdev_priv(ndev); | 95 | struct sh_eth_private *mdp = netdev_priv(ndev); |
96 | unsigned int bits = ECMR_RTM; | ||
97 | |||
98 | #if defined(CONFIG_ARCH_R8A7779) | ||
99 | bits |= ECMR_ELB; | ||
100 | #endif | ||
96 | 101 | ||
97 | switch (mdp->speed) { | 102 | switch (mdp->speed) { |
98 | case 10: /* 10BASE */ | 103 | case 10: /* 10BASE */ |
99 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); | 104 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR); |
100 | break; | 105 | break; |
101 | case 100:/* 100BASE */ | 106 | case 100:/* 100BASE */ |
102 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); | 107 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR); |
103 | break; | 108 | break; |
104 | default: | 109 | default: |
105 | break; | 110 | break; |
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122b..4d15bf413bdc 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c | |||
@@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
751 | sp->srings = sr; | 751 | sp->srings = sr; |
752 | sp->rx_desc = sp->srings->rxvector; | 752 | sp->rx_desc = sp->srings->rxvector; |
753 | sp->tx_desc = sp->srings->txvector; | 753 | sp->tx_desc = sp->srings->txvector; |
754 | spin_lock_init(&sp->tx_lock); | ||
754 | 755 | ||
755 | /* A couple calculations now, saves many cycles later. */ | 756 | /* A couple calculations now, saves many cycles later. */ |
756 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); | 757 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 70554a1b2b02..65a8d49106a4 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx) | |||
1503 | goto fail2; | 1503 | goto fail2; |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT); | ||
1507 | if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) { | ||
1508 | rc = -EINVAL; | ||
1509 | goto fail3; | ||
1510 | } | ||
1506 | efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; | 1511 | efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; |
1507 | 1512 | ||
1508 | rc = efx_probe_filters(efx); | 1513 | rc = efx_probe_filters(efx); |
@@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx) | |||
2070 | net_dev->irq = efx->pci_dev->irq; | 2075 | net_dev->irq = efx->pci_dev->irq; |
2071 | net_dev->netdev_ops = &efx_netdev_ops; | 2076 | net_dev->netdev_ops = &efx_netdev_ops; |
2072 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); | 2077 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); |
2078 | net_dev->gso_max_segs = EFX_TSO_MAX_SEGS; | ||
2073 | 2079 | ||
2074 | rtnl_lock(); | 2080 | rtnl_lock(); |
2075 | 2081 | ||
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index be8f9158a714..70755c97251a 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h | |||
@@ -30,6 +30,7 @@ extern netdev_tx_t | |||
30 | efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); | 30 | efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); |
31 | extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); | 31 | extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); |
32 | extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); | 32 | extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); |
33 | extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); | ||
33 | 34 | ||
34 | /* RX */ | 35 | /* RX */ |
35 | extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); | 36 | extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); |
@@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); | |||
52 | #define EFX_MAX_EVQ_SIZE 16384UL | 53 | #define EFX_MAX_EVQ_SIZE 16384UL |
53 | #define EFX_MIN_EVQ_SIZE 512UL | 54 | #define EFX_MIN_EVQ_SIZE 512UL |
54 | 55 | ||
55 | /* The smallest [rt]xq_entries that the driver supports. Callers of | 56 | /* Maximum number of TCP segments we support for soft-TSO */ |
56 | * efx_wake_queue() assume that they can subsequently send at least one | 57 | #define EFX_TSO_MAX_SEGS 100 |
57 | * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ | 58 | |
58 | #define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) | 59 | /* The smallest [rt]xq_entries that the driver supports. RX minimum |
60 | * is a bit arbitrary. For TX, we must have space for at least 2 | ||
61 | * TSO skbs. | ||
62 | */ | ||
63 | #define EFX_RXQ_MIN_ENT 128U | ||
64 | #define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) | ||
59 | 65 | ||
60 | /* Filters */ | 66 | /* Filters */ |
61 | extern int efx_probe_filters(struct efx_nic *efx); | 67 | extern int efx_probe_filters(struct efx_nic *efx); |
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 10536f93b561..5faedd855b77 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
@@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev, | |||
680 | struct ethtool_ringparam *ring) | 680 | struct ethtool_ringparam *ring) |
681 | { | 681 | { |
682 | struct efx_nic *efx = netdev_priv(net_dev); | 682 | struct efx_nic *efx = netdev_priv(net_dev); |
683 | u32 txq_entries; | ||
683 | 684 | ||
684 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || | 685 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || |
685 | ring->rx_pending > EFX_MAX_DMAQ_SIZE || | 686 | ring->rx_pending > EFX_MAX_DMAQ_SIZE || |
686 | ring->tx_pending > EFX_MAX_DMAQ_SIZE) | 687 | ring->tx_pending > EFX_MAX_DMAQ_SIZE) |
687 | return -EINVAL; | 688 | return -EINVAL; |
688 | 689 | ||
689 | if (ring->rx_pending < EFX_MIN_RING_SIZE || | 690 | if (ring->rx_pending < EFX_RXQ_MIN_ENT) { |
690 | ring->tx_pending < EFX_MIN_RING_SIZE) { | ||
691 | netif_err(efx, drv, efx->net_dev, | 691 | netif_err(efx, drv, efx->net_dev, |
692 | "TX and RX queues cannot be smaller than %ld\n", | 692 | "RX queues cannot be smaller than %u\n", |
693 | EFX_MIN_RING_SIZE); | 693 | EFX_RXQ_MIN_ENT); |
694 | return -EINVAL; | 694 | return -EINVAL; |
695 | } | 695 | } |
696 | 696 | ||
697 | return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); | 697 | txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx)); |
698 | if (txq_entries != ring->tx_pending) | ||
699 | netif_warn(efx, drv, efx->net_dev, | ||
700 | "increasing TX queue size to minimum of %u\n", | ||
701 | txq_entries); | ||
702 | |||
703 | return efx_realloc_channels(efx, ring->rx_pending, txq_entries); | ||
698 | } | 704 | } |
699 | 705 | ||
700 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, | 706 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, |
@@ -857,8 +863,8 @@ static int efx_ethtool_get_class_rule(struct efx_nic *efx, | |||
857 | &ip_entry->ip4dst, &ip_entry->pdst); | 863 | &ip_entry->ip4dst, &ip_entry->pdst); |
858 | if (rc != 0) { | 864 | if (rc != 0) { |
859 | rc = efx_filter_get_ipv4_full( | 865 | rc = efx_filter_get_ipv4_full( |
860 | &spec, &proto, &ip_entry->ip4src, &ip_entry->psrc, | 866 | &spec, &proto, &ip_entry->ip4dst, &ip_entry->pdst, |
861 | &ip_entry->ip4dst, &ip_entry->pdst); | 867 | &ip_entry->ip4src, &ip_entry->psrc); |
862 | EFX_WARN_ON_PARANOID(rc); | 868 | EFX_WARN_ON_PARANOID(rc); |
863 | ip_mask->ip4src = ~0; | 869 | ip_mask->ip4src = ~0; |
864 | ip_mask->psrc = ~0; | 870 | ip_mask->psrc = ~0; |
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 9b225a7769f7..18713436b443 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
@@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr) | |||
119 | return len; | 119 | return len; |
120 | } | 120 | } |
121 | 121 | ||
122 | unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) | ||
123 | { | ||
124 | /* Header and payload descriptor for each output segment, plus | ||
125 | * one for every input fragment boundary within a segment | ||
126 | */ | ||
127 | unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS; | ||
128 | |||
129 | /* Possibly one more per segment for the alignment workaround */ | ||
130 | if (EFX_WORKAROUND_5391(efx)) | ||
131 | max_descs += EFX_TSO_MAX_SEGS; | ||
132 | |||
133 | /* Possibly more for PCIe page boundaries within input fragments */ | ||
134 | if (PAGE_SIZE > EFX_PAGE_SIZE) | ||
135 | max_descs += max_t(unsigned int, MAX_SKB_FRAGS, | ||
136 | DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE)); | ||
137 | |||
138 | return max_descs; | ||
139 | } | ||
140 | |||
122 | /* | 141 | /* |
123 | * Add a socket buffer to a TX queue | 142 | * Add a socket buffer to a TX queue |
124 | * | 143 | * |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e2d083228f3a..719be3912aa9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __COMMON_H__ | ||
26 | #define __COMMON_H__ | ||
27 | |||
25 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
26 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
27 | #include <linux/phy.h> | 30 | #include <linux/phy.h> |
@@ -366,3 +369,5 @@ extern void stmmac_set_mac(void __iomem *ioaddr, bool enable); | |||
366 | 369 | ||
367 | extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); | 370 | extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); |
368 | extern const struct stmmac_ring_mode_ops ring_mode_ops; | 371 | extern const struct stmmac_ring_mode_ops ring_mode_ops; |
372 | |||
373 | #endif /* __COMMON_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs.h b/drivers/net/ethernet/stmicro/stmmac/descs.h index 9820ec842cc0..223adf95fd03 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs.h | |||
@@ -20,6 +20,10 @@ | |||
20 | 20 | ||
21 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 21 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
22 | *******************************************************************************/ | 22 | *******************************************************************************/ |
23 | |||
24 | #ifndef __DESCS_H__ | ||
25 | #define __DESCS_H__ | ||
26 | |||
23 | struct dma_desc { | 27 | struct dma_desc { |
24 | /* Receive descriptor */ | 28 | /* Receive descriptor */ |
25 | union { | 29 | union { |
@@ -166,3 +170,5 @@ enum tdes_csum_insertion { | |||
166 | * is not calculated */ | 170 | * is not calculated */ |
167 | cic_full = 3, /* IP header and pseudoheader */ | 171 | cic_full = 3, /* IP header and pseudoheader */ |
168 | }; | 172 | }; |
173 | |||
174 | #endif /* __DESCS_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index dd8d6e19dff6..7ee9499a6e38 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h | |||
@@ -27,6 +27,9 @@ | |||
27 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 27 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
28 | *******************************************************************************/ | 28 | *******************************************************************************/ |
29 | 29 | ||
30 | #ifndef __DESC_COM_H__ | ||
31 | #define __DESC_COM_H__ | ||
32 | |||
30 | #if defined(CONFIG_STMMAC_RING) | 33 | #if defined(CONFIG_STMMAC_RING) |
31 | static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end) | 34 | static inline void ehn_desc_rx_set_on_ring_chain(struct dma_desc *p, int end) |
32 | { | 35 | { |
@@ -124,3 +127,5 @@ static inline void norm_set_tx_desc_len(struct dma_desc *p, int len) | |||
124 | p->des01.tx.buffer1_size = len; | 127 | p->des01.tx.buffer1_size = len; |
125 | } | 128 | } |
126 | #endif | 129 | #endif |
130 | |||
131 | #endif /* __DESC_COM_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h index 7c6d857a9cc7..2ec6aeae349e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __DWMAC100_H__ | ||
26 | #define __DWMAC100_H__ | ||
27 | |||
25 | #include <linux/phy.h> | 28 | #include <linux/phy.h> |
26 | #include "common.h" | 29 | #include "common.h" |
27 | 30 | ||
@@ -119,3 +122,5 @@ enum ttc_control { | |||
119 | #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ | 122 | #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ |
120 | 123 | ||
121 | extern const struct stmmac_dma_ops dwmac100_dma_ops; | 124 | extern const struct stmmac_dma_ops dwmac100_dma_ops; |
125 | |||
126 | #endif /* __DWMAC100_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index f90fcb5f9573..0e4cacedc1f0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
21 | *******************************************************************************/ | 21 | *******************************************************************************/ |
22 | #ifndef __DWMAC1000_H__ | ||
23 | #define __DWMAC1000_H__ | ||
22 | 24 | ||
23 | #include <linux/phy.h> | 25 | #include <linux/phy.h> |
24 | #include "common.h" | 26 | #include "common.h" |
@@ -229,6 +231,7 @@ enum rtc_control { | |||
229 | #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 | 231 | #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 |
230 | 232 | ||
231 | /* Synopsys Core versions */ | 233 | /* Synopsys Core versions */ |
232 | #define DWMAC_CORE_3_40 34 | 234 | #define DWMAC_CORE_3_40 0x34 |
233 | 235 | ||
234 | extern const struct stmmac_dma_ops dwmac1000_dma_ops; | 236 | extern const struct stmmac_dma_ops dwmac1000_dma_ops; |
237 | #endif /* __DWMAC1000_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h index e678ce39d014..e49c9a0fd6ff 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __DWMAC_DMA_H__ | ||
26 | #define __DWMAC_DMA_H__ | ||
27 | |||
25 | /* DMA CRS Control and Status Register Mapping */ | 28 | /* DMA CRS Control and Status Register Mapping */ |
26 | #define DMA_BUS_MODE 0x00001000 /* Bus Mode */ | 29 | #define DMA_BUS_MODE 0x00001000 /* Bus Mode */ |
27 | #define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ | 30 | #define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */ |
@@ -109,3 +112,5 @@ extern void dwmac_dma_start_rx(void __iomem *ioaddr); | |||
109 | extern void dwmac_dma_stop_rx(void __iomem *ioaddr); | 112 | extern void dwmac_dma_stop_rx(void __iomem *ioaddr); |
110 | extern int dwmac_dma_interrupt(void __iomem *ioaddr, | 113 | extern int dwmac_dma_interrupt(void __iomem *ioaddr, |
111 | struct stmmac_extra_stats *x); | 114 | struct stmmac_extra_stats *x); |
115 | |||
116 | #endif /* __DWMAC_DMA_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h index a38352024cb8..67995ef25251 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc.h +++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h | |||
@@ -22,6 +22,9 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #ifndef __MMC_H__ | ||
26 | #define __MMC_H__ | ||
27 | |||
25 | /* MMC control register */ | 28 | /* MMC control register */ |
26 | /* When set, all counter are reset */ | 29 | /* When set, all counter are reset */ |
27 | #define MMC_CNTRL_COUNTER_RESET 0x1 | 30 | #define MMC_CNTRL_COUNTER_RESET 0x1 |
@@ -129,3 +132,5 @@ struct stmmac_counters { | |||
129 | extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); | 132 | extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode); |
130 | extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); | 133 | extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr); |
131 | extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); | 134 | extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc); |
135 | |||
136 | #endif /* __MMC_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index c07cfe989f6e..0c74a702d461 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */ | 33 | #define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */ |
34 | #define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */ | 34 | #define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */ |
35 | #define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */ | 35 | #define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */ |
36 | #define MMC_DEFAUL_MASK 0xffffffff | 36 | #define MMC_DEFAULT_MASK 0xffffffff |
37 | 37 | ||
38 | /* MMC TX counter registers */ | 38 | /* MMC TX counter registers */ |
39 | 39 | ||
@@ -147,8 +147,8 @@ void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode) | |||
147 | /* To mask all all interrupts.*/ | 147 | /* To mask all all interrupts.*/ |
148 | void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) | 148 | void dwmac_mmc_intr_all_mask(void __iomem *ioaddr) |
149 | { | 149 | { |
150 | writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK); | 150 | writel(MMC_DEFAULT_MASK, ioaddr + MMC_RX_INTR_MASK); |
151 | writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK); | 151 | writel(MMC_DEFAULT_MASK, ioaddr + MMC_TX_INTR_MASK); |
152 | } | 152 | } |
153 | 153 | ||
154 | /* This reads the MAC core counters (if actaully supported). | 154 | /* This reads the MAC core counters (if actaully supported). |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index f2d3665430ad..e872e1da3137 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h | |||
@@ -20,6 +20,9 @@ | |||
20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 20 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
21 | *******************************************************************************/ | 21 | *******************************************************************************/ |
22 | 22 | ||
23 | #ifndef __STMMAC_H__ | ||
24 | #define __STMMAC_H__ | ||
25 | |||
23 | #define STMMAC_RESOURCE_NAME "stmmaceth" | 26 | #define STMMAC_RESOURCE_NAME "stmmaceth" |
24 | #define DRV_MODULE_VERSION "March_2012" | 27 | #define DRV_MODULE_VERSION "March_2012" |
25 | 28 | ||
@@ -166,3 +169,5 @@ static inline void stmmac_unregister_pci(void) | |||
166 | { | 169 | { |
167 | } | 170 | } |
168 | #endif /* CONFIG_STMMAC_PCI */ | 171 | #endif /* CONFIG_STMMAC_PCI */ |
172 | |||
173 | #endif /* __STMMAC_H__ */ | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fd8882f9602a..3be88331d17a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -1066,7 +1066,7 @@ static int stmmac_open(struct net_device *dev) | |||
1066 | } else | 1066 | } else |
1067 | priv->tm->enable = 1; | 1067 | priv->tm->enable = 1; |
1068 | #endif | 1068 | #endif |
1069 | clk_enable(priv->stmmac_clk); | 1069 | clk_prepare_enable(priv->stmmac_clk); |
1070 | 1070 | ||
1071 | stmmac_check_ether_addr(priv); | 1071 | stmmac_check_ether_addr(priv); |
1072 | 1072 | ||
@@ -1188,7 +1188,7 @@ open_error: | |||
1188 | if (priv->phydev) | 1188 | if (priv->phydev) |
1189 | phy_disconnect(priv->phydev); | 1189 | phy_disconnect(priv->phydev); |
1190 | 1190 | ||
1191 | clk_disable(priv->stmmac_clk); | 1191 | clk_disable_unprepare(priv->stmmac_clk); |
1192 | 1192 | ||
1193 | return ret; | 1193 | return ret; |
1194 | } | 1194 | } |
@@ -1246,7 +1246,7 @@ static int stmmac_release(struct net_device *dev) | |||
1246 | #ifdef CONFIG_STMMAC_DEBUG_FS | 1246 | #ifdef CONFIG_STMMAC_DEBUG_FS |
1247 | stmmac_exit_fs(); | 1247 | stmmac_exit_fs(); |
1248 | #endif | 1248 | #endif |
1249 | clk_disable(priv->stmmac_clk); | 1249 | clk_disable_unprepare(priv->stmmac_clk); |
1250 | 1250 | ||
1251 | return 0; | 1251 | return 0; |
1252 | } | 1252 | } |
@@ -2077,7 +2077,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, | |||
2077 | goto error_netdev_register; | 2077 | goto error_netdev_register; |
2078 | } | 2078 | } |
2079 | 2079 | ||
2080 | priv->stmmac_clk = clk_get(priv->device, NULL); | 2080 | priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME); |
2081 | if (IS_ERR(priv->stmmac_clk)) { | 2081 | if (IS_ERR(priv->stmmac_clk)) { |
2082 | pr_warning("%s: warning: cannot get CSR clock\n", __func__); | 2082 | pr_warning("%s: warning: cannot get CSR clock\n", __func__); |
2083 | goto error_clk_get; | 2083 | goto error_clk_get; |
@@ -2178,7 +2178,7 @@ int stmmac_suspend(struct net_device *ndev) | |||
2178 | else { | 2178 | else { |
2179 | stmmac_set_mac(priv->ioaddr, false); | 2179 | stmmac_set_mac(priv->ioaddr, false); |
2180 | /* Disable clock in case of PWM is off */ | 2180 | /* Disable clock in case of PWM is off */ |
2181 | clk_disable(priv->stmmac_clk); | 2181 | clk_disable_unprepare(priv->stmmac_clk); |
2182 | } | 2182 | } |
2183 | spin_unlock_irqrestore(&priv->lock, flags); | 2183 | spin_unlock_irqrestore(&priv->lock, flags); |
2184 | return 0; | 2184 | return 0; |
@@ -2203,7 +2203,7 @@ int stmmac_resume(struct net_device *ndev) | |||
2203 | priv->hw->mac->pmt(priv->ioaddr, 0); | 2203 | priv->hw->mac->pmt(priv->ioaddr, 0); |
2204 | else | 2204 | else |
2205 | /* enable the clk prevously disabled */ | 2205 | /* enable the clk prevously disabled */ |
2206 | clk_enable(priv->stmmac_clk); | 2206 | clk_prepare_enable(priv->stmmac_clk); |
2207 | 2207 | ||
2208 | netif_device_attach(ndev); | 2208 | netif_device_attach(ndev); |
2209 | 2209 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index cd01ee7ecef1..b93245c11995 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -74,7 +74,7 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, | |||
74 | * the necessary resources and invokes the main to init | 74 | * the necessary resources and invokes the main to init |
75 | * the net device, register the mdio bus etc. | 75 | * the net device, register the mdio bus etc. |
76 | */ | 76 | */ |
77 | static int stmmac_pltfr_probe(struct platform_device *pdev) | 77 | static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) |
78 | { | 78 | { |
79 | int ret = 0; | 79 | int ret = 0; |
80 | struct resource *res; | 80 | struct resource *res; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c index 2a0e1abde7e7..4ccd4e2977b7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c | |||
@@ -97,19 +97,19 @@ static struct clk *timer_clock; | |||
97 | static void stmmac_tmu_start(unsigned int new_freq) | 97 | static void stmmac_tmu_start(unsigned int new_freq) |
98 | { | 98 | { |
99 | clk_set_rate(timer_clock, new_freq); | 99 | clk_set_rate(timer_clock, new_freq); |
100 | clk_enable(timer_clock); | 100 | clk_prepare_enable(timer_clock); |
101 | } | 101 | } |
102 | 102 | ||
103 | static void stmmac_tmu_stop(void) | 103 | static void stmmac_tmu_stop(void) |
104 | { | 104 | { |
105 | clk_disable(timer_clock); | 105 | clk_disable_unprepare(timer_clock); |
106 | } | 106 | } |
107 | 107 | ||
108 | int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | 108 | int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) |
109 | { | 109 | { |
110 | timer_clock = clk_get(NULL, TMU_CHANNEL); | 110 | timer_clock = clk_get(NULL, TMU_CHANNEL); |
111 | 111 | ||
112 | if (timer_clock == NULL) | 112 | if (IS_ERR(timer_clock)) |
113 | return -1; | 113 | return -1; |
114 | 114 | ||
115 | if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) { | 115 | if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) { |
@@ -126,7 +126,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | |||
126 | 126 | ||
127 | int stmmac_close_ext_timer(void) | 127 | int stmmac_close_ext_timer(void) |
128 | { | 128 | { |
129 | clk_disable(timer_clock); | 129 | clk_disable_unprepare(timer_clock); |
130 | tmu2_unregister_user(); | 130 | tmu2_unregister_user(); |
131 | clk_put(timer_clock); | 131 | clk_put(timer_clock); |
132 | return 0; | 132 | return 0; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h index 6863590d184b..aea9b14cdfbe 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_timer.h | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | #ifndef __STMMAC_TIMER_H__ | ||
25 | #define __STMMAC_TIMER_H__ | ||
24 | 26 | ||
25 | struct stmmac_timer { | 27 | struct stmmac_timer { |
26 | void (*timer_start) (unsigned int new_freq); | 28 | void (*timer_start) (unsigned int new_freq); |
@@ -40,3 +42,5 @@ void stmmac_schedule(struct net_device *dev); | |||
40 | extern int tmu2_register_user(void *fnt, void *data); | 42 | extern int tmu2_register_user(void *fnt, void *data); |
41 | extern void tmu2_unregister_user(void); | 43 | extern void tmu2_unregister_user(void); |
42 | #endif | 44 | #endif |
45 | |||
46 | #endif /* __STMMAC_TIMER_H__ */ | ||
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 3b5c4571b55e..d15c888e9df8 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
@@ -538,11 +538,12 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create); | |||
538 | 538 | ||
539 | int cpdma_chan_destroy(struct cpdma_chan *chan) | 539 | int cpdma_chan_destroy(struct cpdma_chan *chan) |
540 | { | 540 | { |
541 | struct cpdma_ctlr *ctlr = chan->ctlr; | 541 | struct cpdma_ctlr *ctlr; |
542 | unsigned long flags; | 542 | unsigned long flags; |
543 | 543 | ||
544 | if (!chan) | 544 | if (!chan) |
545 | return -EINVAL; | 545 | return -EINVAL; |
546 | ctlr = chan->ctlr; | ||
546 | 547 | ||
547 | spin_lock_irqsave(&ctlr->lock, flags); | 548 | spin_lock_irqsave(&ctlr->lock, flags); |
548 | if (chan->state != CPDMA_STATE_IDLE) | 549 | if (chan->state != CPDMA_STATE_IDLE) |
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index cd7ee204e94a..a9ca4a03d31b 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c | |||
@@ -394,8 +394,10 @@ static int __devexit davinci_mdio_remove(struct platform_device *pdev) | |||
394 | struct device *dev = &pdev->dev; | 394 | struct device *dev = &pdev->dev; |
395 | struct davinci_mdio_data *data = dev_get_drvdata(dev); | 395 | struct davinci_mdio_data *data = dev_get_drvdata(dev); |
396 | 396 | ||
397 | if (data->bus) | 397 | if (data->bus) { |
398 | mdiobus_unregister(data->bus); | ||
398 | mdiobus_free(data->bus); | 399 | mdiobus_free(data->bus); |
400 | } | ||
399 | 401 | ||
400 | if (data->clk) | 402 | if (data->clk) |
401 | clk_put(data->clk); | 403 | clk_put(data->clk); |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 482648fcf0b6..98934bdf6acf 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
@@ -1003,6 +1003,7 @@ static int ixp4xx_nway_reset(struct net_device *dev) | |||
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | int ixp46x_phc_index = -1; | 1005 | int ixp46x_phc_index = -1; |
1006 | EXPORT_SYMBOL_GPL(ixp46x_phc_index); | ||
1006 | 1007 | ||
1007 | static int ixp4xx_get_ts_info(struct net_device *dev, | 1008 | static int ixp4xx_get_ts_info(struct net_device *dev, |
1008 | struct ethtool_ts_info *info) | 1009 | struct ethtool_ts_info *info) |
diff --git a/drivers/net/fddi/skfp/pmf.c b/drivers/net/fddi/skfp/pmf.c index 24d8566cfd8b..441b4dc79450 100644 --- a/drivers/net/fddi/skfp/pmf.c +++ b/drivers/net/fddi/skfp/pmf.c | |||
@@ -673,7 +673,7 @@ void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, | |||
673 | sm_pm_get_ls(smc,port_to_mib(smc,port))) ; | 673 | sm_pm_get_ls(smc,port_to_mib(smc,port))) ; |
674 | break ; | 674 | break ; |
675 | case SMT_P_REASON : | 675 | case SMT_P_REASON : |
676 | * (u_long *) to = 0 ; | 676 | *(u32 *)to = 0 ; |
677 | sp_len = 4 ; | 677 | sp_len = 4 ; |
678 | goto sp_done ; | 678 | goto sp_done ; |
679 | case SMT_P1033 : /* time stamp */ | 679 | case SMT_P1033 : /* time stamp */ |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 6cee2917eb02..4a1a5f58fa73 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -383,13 +383,6 @@ int netvsc_device_remove(struct hv_device *device) | |||
383 | unsigned long flags; | 383 | unsigned long flags; |
384 | 384 | ||
385 | net_device = hv_get_drvdata(device); | 385 | net_device = hv_get_drvdata(device); |
386 | spin_lock_irqsave(&device->channel->inbound_lock, flags); | ||
387 | net_device->destroy = true; | ||
388 | spin_unlock_irqrestore(&device->channel->inbound_lock, flags); | ||
389 | |||
390 | /* Wait for all send completions */ | ||
391 | wait_event(net_device->wait_drain, | ||
392 | atomic_read(&net_device->num_outstanding_sends) == 0); | ||
393 | 386 | ||
394 | netvsc_disconnect_vsp(net_device); | 387 | netvsc_disconnect_vsp(net_device); |
395 | 388 | ||
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index e5d6146937fa..1e88a1095934 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -718,6 +718,9 @@ static void rndis_filter_halt_device(struct rndis_device *dev) | |||
718 | { | 718 | { |
719 | struct rndis_request *request; | 719 | struct rndis_request *request; |
720 | struct rndis_halt_request *halt; | 720 | struct rndis_halt_request *halt; |
721 | struct netvsc_device *nvdev = dev->net_dev; | ||
722 | struct hv_device *hdev = nvdev->dev; | ||
723 | ulong flags; | ||
721 | 724 | ||
722 | /* Attempt to do a rndis device halt */ | 725 | /* Attempt to do a rndis device halt */ |
723 | request = get_rndis_request(dev, RNDIS_MSG_HALT, | 726 | request = get_rndis_request(dev, RNDIS_MSG_HALT, |
@@ -735,6 +738,14 @@ static void rndis_filter_halt_device(struct rndis_device *dev) | |||
735 | dev->state = RNDIS_DEV_UNINITIALIZED; | 738 | dev->state = RNDIS_DEV_UNINITIALIZED; |
736 | 739 | ||
737 | cleanup: | 740 | cleanup: |
741 | spin_lock_irqsave(&hdev->channel->inbound_lock, flags); | ||
742 | nvdev->destroy = true; | ||
743 | spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags); | ||
744 | |||
745 | /* Wait for all send completions */ | ||
746 | wait_event(nvdev->wait_drain, | ||
747 | atomic_read(&nvdev->num_outstanding_sends) == 0); | ||
748 | |||
738 | if (request) | 749 | if (request) |
739 | put_rndis_request(dev, request); | 750 | put_rndis_request(dev, request); |
740 | return; | 751 | return; |
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index a561ae44a9ac..c6a0299aa9f9 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c | |||
@@ -158,7 +158,7 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) | |||
158 | /* If not add the 'RPOLC', we can't catch the receive interrupt. | 158 | /* If not add the 'RPOLC', we can't catch the receive interrupt. |
159 | * It's related with the HW layout and the IR transiver. | 159 | * It's related with the HW layout and the IR transiver. |
160 | */ | 160 | */ |
161 | val |= IREN | RPOLC; | 161 | val |= UMOD_IRDA | RPOLC; |
162 | UART_PUT_GCTL(port, val); | 162 | UART_PUT_GCTL(port, val); |
163 | return ret; | 163 | return ret; |
164 | } | 164 | } |
@@ -432,7 +432,7 @@ static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev | |||
432 | bfin_sir_stop_rx(port); | 432 | bfin_sir_stop_rx(port); |
433 | 433 | ||
434 | val = UART_GET_GCTL(port); | 434 | val = UART_GET_GCTL(port); |
435 | val &= ~(UCEN | IREN | RPOLC); | 435 | val &= ~(UCEN | UMOD_MASK | RPOLC); |
436 | UART_PUT_GCTL(port, val); | 436 | UART_PUT_GCTL(port, val); |
437 | 437 | ||
438 | #ifdef CONFIG_SIR_BFIN_DMA | 438 | #ifdef CONFIG_SIR_BFIN_DMA |
@@ -518,10 +518,10 @@ static void bfin_sir_send_work(struct work_struct *work) | |||
518 | * reset all the UART. | 518 | * reset all the UART. |
519 | */ | 519 | */ |
520 | val = UART_GET_GCTL(port); | 520 | val = UART_GET_GCTL(port); |
521 | val &= ~(IREN | RPOLC); | 521 | val &= ~(UMOD_MASK | RPOLC); |
522 | UART_PUT_GCTL(port, val); | 522 | UART_PUT_GCTL(port, val); |
523 | SSYNC(); | 523 | SSYNC(); |
524 | val |= IREN | RPOLC; | 524 | val |= UMOD_IRDA | RPOLC; |
525 | UART_PUT_GCTL(port, val); | 525 | UART_PUT_GCTL(port, val); |
526 | SSYNC(); | 526 | SSYNC(); |
527 | /* bfin_sir_set_speed(port, self->speed); */ | 527 | /* bfin_sir_set_speed(port, self->speed); */ |
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 824e2a93fe8a..5f3aeac3f86d 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c | |||
@@ -542,6 +542,7 @@ static int ks959_net_open(struct net_device *netdev) | |||
542 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); | 542 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); |
543 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); | 543 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); |
544 | if (!kingsun->irlap) { | 544 | if (!kingsun->irlap) { |
545 | err = -ENOMEM; | ||
545 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); | 546 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); |
546 | goto free_mem; | 547 | goto free_mem; |
547 | } | 548 | } |
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index 5a278ab83c2f..2d4b6a1ab202 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c | |||
@@ -436,6 +436,7 @@ static int ksdazzle_net_open(struct net_device *netdev) | |||
436 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); | 436 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); |
437 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); | 437 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); |
438 | if (!kingsun->irlap) { | 438 | if (!kingsun->irlap) { |
439 | err = -ENOMEM; | ||
439 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); | 440 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); |
440 | goto free_mem; | 441 | goto free_mem; |
441 | } | 442 | } |
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c index 256eddf1f75a..795109425568 100644 --- a/drivers/net/irda/sh_sir.c +++ b/drivers/net/irda/sh_sir.c | |||
@@ -280,7 +280,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | clk = clk_get(NULL, "irda_clk"); | 282 | clk = clk_get(NULL, "irda_clk"); |
283 | if (!clk) { | 283 | if (IS_ERR(clk)) { |
284 | dev_err(dev, "can not get irda_clk\n"); | 284 | dev_err(dev, "can not get irda_clk\n"); |
285 | return -EIO; | 285 | return -EIO; |
286 | } | 286 | } |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 0737bd4d1669..0f0f9ce3a776 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -94,7 +94,8 @@ static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q) | |||
94 | int i; | 94 | int i; |
95 | 95 | ||
96 | for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { | 96 | for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { |
97 | if (rcu_dereference(vlan->taps[i]) == q) | 97 | if (rcu_dereference_protected(vlan->taps[i], |
98 | lockdep_is_held(&macvtap_lock)) == q) | ||
98 | return i; | 99 | return i; |
99 | } | 100 | } |
100 | 101 | ||
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index f9347ea3d381..b3321129a83c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -640,15 +640,9 @@ static int netconsole_netdev_event(struct notifier_block *this, | |||
640 | * rtnl_lock already held | 640 | * rtnl_lock already held |
641 | */ | 641 | */ |
642 | if (nt->np.dev) { | 642 | if (nt->np.dev) { |
643 | spin_unlock_irqrestore( | ||
644 | &target_list_lock, | ||
645 | flags); | ||
646 | __netpoll_cleanup(&nt->np); | 643 | __netpoll_cleanup(&nt->np); |
647 | spin_lock_irqsave(&target_list_lock, | ||
648 | flags); | ||
649 | dev_put(nt->np.dev); | 644 | dev_put(nt->np.dev); |
650 | nt->np.dev = NULL; | 645 | nt->np.dev = NULL; |
651 | netconsole_target_put(nt); | ||
652 | } | 646 | } |
653 | nt->enabled = 0; | 647 | nt->enabled = 0; |
654 | stopped = true; | 648 | stopped = true; |
diff --git a/drivers/net/phy/bcm87xx.c b/drivers/net/phy/bcm87xx.c index 2346b38b9837..799789518e87 100644 --- a/drivers/net/phy/bcm87xx.c +++ b/drivers/net/phy/bcm87xx.c | |||
@@ -229,3 +229,5 @@ static void __exit bcm87xx_exit(void) | |||
229 | ARRAY_SIZE(bcm87xx_driver)); | 229 | ARRAY_SIZE(bcm87xx_driver)); |
230 | } | 230 | } |
231 | module_exit(bcm87xx_exit); | 231 | module_exit(bcm87xx_exit); |
232 | |||
233 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c index e0cc4ef33dee..eefe49e8713c 100644 --- a/drivers/net/phy/mdio-mux-gpio.c +++ b/drivers/net/phy/mdio-mux-gpio.c | |||
@@ -101,7 +101,6 @@ err: | |||
101 | n--; | 101 | n--; |
102 | gpio_free(s->gpio[n]); | 102 | gpio_free(s->gpio[n]); |
103 | } | 103 | } |
104 | devm_kfree(&pdev->dev, s); | ||
105 | return r; | 104 | return r; |
106 | } | 105 | } |
107 | 106 | ||
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 5c120189ec86..4d4d25efc1e1 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c | |||
@@ -132,7 +132,7 @@ int mdio_mux_init(struct device *dev, | |||
132 | pb->mii_bus = parent_bus; | 132 | pb->mii_bus = parent_bus; |
133 | 133 | ||
134 | ret_val = -ENODEV; | 134 | ret_val = -ENODEV; |
135 | for_each_child_of_node(dev->of_node, child_bus_node) { | 135 | for_each_available_child_of_node(dev->of_node, child_bus_node) { |
136 | u32 v; | 136 | u32 v; |
137 | 137 | ||
138 | r = of_property_read_u32(child_bus_node, "reg", &v); | 138 | r = of_property_read_u32(child_bus_node, "reg", &v); |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index cf287e0eb408..2165d5fdb8c0 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -21,6 +21,12 @@ | |||
21 | #include <linux/phy.h> | 21 | #include <linux/phy.h> |
22 | #include <linux/micrel_phy.h> | 22 | #include <linux/micrel_phy.h> |
23 | 23 | ||
24 | /* Operation Mode Strap Override */ | ||
25 | #define MII_KSZPHY_OMSO 0x16 | ||
26 | #define KSZPHY_OMSO_B_CAST_OFF (1 << 9) | ||
27 | #define KSZPHY_OMSO_RMII_OVERRIDE (1 << 1) | ||
28 | #define KSZPHY_OMSO_MII_OVERRIDE (1 << 0) | ||
29 | |||
24 | /* general Interrupt control/status reg in vendor specific block. */ | 30 | /* general Interrupt control/status reg in vendor specific block. */ |
25 | #define MII_KSZPHY_INTCS 0x1B | 31 | #define MII_KSZPHY_INTCS 0x1B |
26 | #define KSZPHY_INTCS_JABBER (1 << 15) | 32 | #define KSZPHY_INTCS_JABBER (1 << 15) |
@@ -101,6 +107,13 @@ static int kszphy_config_init(struct phy_device *phydev) | |||
101 | return 0; | 107 | return 0; |
102 | } | 108 | } |
103 | 109 | ||
110 | static int ksz8021_config_init(struct phy_device *phydev) | ||
111 | { | ||
112 | const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE; | ||
113 | phy_write(phydev, MII_KSZPHY_OMSO, val); | ||
114 | return 0; | ||
115 | } | ||
116 | |||
104 | static int ks8051_config_init(struct phy_device *phydev) | 117 | static int ks8051_config_init(struct phy_device *phydev) |
105 | { | 118 | { |
106 | int regval; | 119 | int regval; |
@@ -128,9 +141,22 @@ static struct phy_driver ksphy_driver[] = { | |||
128 | .config_intr = ks8737_config_intr, | 141 | .config_intr = ks8737_config_intr, |
129 | .driver = { .owner = THIS_MODULE,}, | 142 | .driver = { .owner = THIS_MODULE,}, |
130 | }, { | 143 | }, { |
131 | .phy_id = PHY_ID_KS8041, | 144 | .phy_id = PHY_ID_KSZ8021, |
145 | .phy_id_mask = 0x00ffffff, | ||
146 | .name = "Micrel KSZ8021", | ||
147 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | | ||
148 | SUPPORTED_Asym_Pause), | ||
149 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | ||
150 | .config_init = ksz8021_config_init, | ||
151 | .config_aneg = genphy_config_aneg, | ||
152 | .read_status = genphy_read_status, | ||
153 | .ack_interrupt = kszphy_ack_interrupt, | ||
154 | .config_intr = kszphy_config_intr, | ||
155 | .driver = { .owner = THIS_MODULE,}, | ||
156 | }, { | ||
157 | .phy_id = PHY_ID_KSZ8041, | ||
132 | .phy_id_mask = 0x00fffff0, | 158 | .phy_id_mask = 0x00fffff0, |
133 | .name = "Micrel KS8041", | 159 | .name = "Micrel KSZ8041", |
134 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | 160 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
135 | | SUPPORTED_Asym_Pause), | 161 | | SUPPORTED_Asym_Pause), |
136 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 162 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
@@ -141,9 +167,9 @@ static struct phy_driver ksphy_driver[] = { | |||
141 | .config_intr = kszphy_config_intr, | 167 | .config_intr = kszphy_config_intr, |
142 | .driver = { .owner = THIS_MODULE,}, | 168 | .driver = { .owner = THIS_MODULE,}, |
143 | }, { | 169 | }, { |
144 | .phy_id = PHY_ID_KS8051, | 170 | .phy_id = PHY_ID_KSZ8051, |
145 | .phy_id_mask = 0x00fffff0, | 171 | .phy_id_mask = 0x00fffff0, |
146 | .name = "Micrel KS8051", | 172 | .name = "Micrel KSZ8051", |
147 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause | 173 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
148 | | SUPPORTED_Asym_Pause), | 174 | | SUPPORTED_Asym_Pause), |
149 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 175 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
@@ -154,8 +180,8 @@ static struct phy_driver ksphy_driver[] = { | |||
154 | .config_intr = kszphy_config_intr, | 180 | .config_intr = kszphy_config_intr, |
155 | .driver = { .owner = THIS_MODULE,}, | 181 | .driver = { .owner = THIS_MODULE,}, |
156 | }, { | 182 | }, { |
157 | .phy_id = PHY_ID_KS8001, | 183 | .phy_id = PHY_ID_KSZ8001, |
158 | .name = "Micrel KS8001 or KS8721", | 184 | .name = "Micrel KSZ8001 or KS8721", |
159 | .phy_id_mask = 0x00ffffff, | 185 | .phy_id_mask = 0x00ffffff, |
160 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), | 186 | .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), |
161 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | 187 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, |
@@ -201,10 +227,11 @@ MODULE_LICENSE("GPL"); | |||
201 | 227 | ||
202 | static struct mdio_device_id __maybe_unused micrel_tbl[] = { | 228 | static struct mdio_device_id __maybe_unused micrel_tbl[] = { |
203 | { PHY_ID_KSZ9021, 0x000ffffe }, | 229 | { PHY_ID_KSZ9021, 0x000ffffe }, |
204 | { PHY_ID_KS8001, 0x00ffffff }, | 230 | { PHY_ID_KSZ8001, 0x00ffffff }, |
205 | { PHY_ID_KS8737, 0x00fffff0 }, | 231 | { PHY_ID_KS8737, 0x00fffff0 }, |
206 | { PHY_ID_KS8041, 0x00fffff0 }, | 232 | { PHY_ID_KSZ8021, 0x00ffffff }, |
207 | { PHY_ID_KS8051, 0x00fffff0 }, | 233 | { PHY_ID_KSZ8041, 0x00fffff0 }, |
234 | { PHY_ID_KSZ8051, 0x00fffff0 }, | ||
208 | { } | 235 | { } |
209 | }; | 236 | }; |
210 | 237 | ||
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index cbf7047decc0..20f31d0d1536 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c | |||
@@ -570,7 +570,7 @@ static int pppoe_release(struct socket *sock) | |||
570 | 570 | ||
571 | po = pppox_sk(sk); | 571 | po = pppox_sk(sk); |
572 | 572 | ||
573 | if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { | 573 | if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) { |
574 | dev_put(po->pppoe_dev); | 574 | dev_put(po->pppoe_dev); |
575 | po->pppoe_dev = NULL; | 575 | po->pppoe_dev = NULL; |
576 | } | 576 | } |
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 1c98321b56cc..162464fe86bf 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
@@ -189,7 +189,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
189 | if (sk_pppox(po)->sk_state & PPPOX_DEAD) | 189 | if (sk_pppox(po)->sk_state & PPPOX_DEAD) |
190 | goto tx_error; | 190 | goto tx_error; |
191 | 191 | ||
192 | rt = ip_route_output_ports(&init_net, &fl4, NULL, | 192 | rt = ip_route_output_ports(sock_net(sk), &fl4, NULL, |
193 | opt->dst_addr.sin_addr.s_addr, | 193 | opt->dst_addr.sin_addr.s_addr, |
194 | opt->src_addr.sin_addr.s_addr, | 194 | opt->src_addr.sin_addr.s_addr, |
195 | 0, 0, IPPROTO_GRE, | 195 | 0, 0, IPPROTO_GRE, |
@@ -468,7 +468,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
468 | po->chan.private = sk; | 468 | po->chan.private = sk; |
469 | po->chan.ops = &pptp_chan_ops; | 469 | po->chan.ops = &pptp_chan_ops; |
470 | 470 | ||
471 | rt = ip_route_output_ports(&init_net, &fl4, sk, | 471 | rt = ip_route_output_ports(sock_net(sk), &fl4, sk, |
472 | opt->dst_addr.sin_addr.s_addr, | 472 | opt->dst_addr.sin_addr.s_addr, |
473 | opt->src_addr.sin_addr.s_addr, | 473 | opt->src_addr.sin_addr.s_addr, |
474 | 0, 0, | 474 | 0, 0, |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 87707ab39430..3ffe8a6e3c8b 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -795,16 +795,17 @@ static void team_port_leave(struct team *team, struct team_port *port) | |||
795 | } | 795 | } |
796 | 796 | ||
797 | #ifdef CONFIG_NET_POLL_CONTROLLER | 797 | #ifdef CONFIG_NET_POLL_CONTROLLER |
798 | static int team_port_enable_netpoll(struct team *team, struct team_port *port) | 798 | static int team_port_enable_netpoll(struct team *team, struct team_port *port, |
799 | gfp_t gfp) | ||
799 | { | 800 | { |
800 | struct netpoll *np; | 801 | struct netpoll *np; |
801 | int err; | 802 | int err; |
802 | 803 | ||
803 | np = kzalloc(sizeof(*np), GFP_KERNEL); | 804 | np = kzalloc(sizeof(*np), gfp); |
804 | if (!np) | 805 | if (!np) |
805 | return -ENOMEM; | 806 | return -ENOMEM; |
806 | 807 | ||
807 | err = __netpoll_setup(np, port->dev); | 808 | err = __netpoll_setup(np, port->dev, gfp); |
808 | if (err) { | 809 | if (err) { |
809 | kfree(np); | 810 | kfree(np); |
810 | return err; | 811 | return err; |
@@ -833,7 +834,8 @@ static struct netpoll_info *team_netpoll_info(struct team *team) | |||
833 | } | 834 | } |
834 | 835 | ||
835 | #else | 836 | #else |
836 | static int team_port_enable_netpoll(struct team *team, struct team_port *port) | 837 | static int team_port_enable_netpoll(struct team *team, struct team_port *port, |
838 | gfp_t gfp) | ||
837 | { | 839 | { |
838 | return 0; | 840 | return 0; |
839 | } | 841 | } |
@@ -846,7 +848,7 @@ static struct netpoll_info *team_netpoll_info(struct team *team) | |||
846 | } | 848 | } |
847 | #endif | 849 | #endif |
848 | 850 | ||
849 | static void __team_port_change_check(struct team_port *port, bool linkup); | 851 | static void __team_port_change_port_added(struct team_port *port, bool linkup); |
850 | 852 | ||
851 | static int team_port_add(struct team *team, struct net_device *port_dev) | 853 | static int team_port_add(struct team *team, struct net_device *port_dev) |
852 | { | 854 | { |
@@ -913,7 +915,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) | |||
913 | } | 915 | } |
914 | 916 | ||
915 | if (team_netpoll_info(team)) { | 917 | if (team_netpoll_info(team)) { |
916 | err = team_port_enable_netpoll(team, port); | 918 | err = team_port_enable_netpoll(team, port, GFP_KERNEL); |
917 | if (err) { | 919 | if (err) { |
918 | netdev_err(dev, "Failed to enable netpoll on device %s\n", | 920 | netdev_err(dev, "Failed to enable netpoll on device %s\n", |
919 | portname); | 921 | portname); |
@@ -946,7 +948,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) | |||
946 | team_port_enable(team, port); | 948 | team_port_enable(team, port); |
947 | list_add_tail_rcu(&port->list, &team->port_list); | 949 | list_add_tail_rcu(&port->list, &team->port_list); |
948 | __team_compute_features(team); | 950 | __team_compute_features(team); |
949 | __team_port_change_check(port, !!netif_carrier_ok(port_dev)); | 951 | __team_port_change_port_added(port, !!netif_carrier_ok(port_dev)); |
950 | __team_options_change_check(team); | 952 | __team_options_change_check(team); |
951 | 953 | ||
952 | netdev_info(dev, "Port device %s added\n", portname); | 954 | netdev_info(dev, "Port device %s added\n", portname); |
@@ -981,6 +983,8 @@ err_set_mtu: | |||
981 | return err; | 983 | return err; |
982 | } | 984 | } |
983 | 985 | ||
986 | static void __team_port_change_port_removed(struct team_port *port); | ||
987 | |||
984 | static int team_port_del(struct team *team, struct net_device *port_dev) | 988 | static int team_port_del(struct team *team, struct net_device *port_dev) |
985 | { | 989 | { |
986 | struct net_device *dev = team->dev; | 990 | struct net_device *dev = team->dev; |
@@ -997,8 +1001,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev) | |||
997 | __team_option_inst_mark_removed_port(team, port); | 1001 | __team_option_inst_mark_removed_port(team, port); |
998 | __team_options_change_check(team); | 1002 | __team_options_change_check(team); |
999 | __team_option_inst_del_port(team, port); | 1003 | __team_option_inst_del_port(team, port); |
1000 | port->removed = true; | 1004 | __team_port_change_port_removed(port); |
1001 | __team_port_change_check(port, false); | ||
1002 | team_port_disable(team, port); | 1005 | team_port_disable(team, port); |
1003 | list_del_rcu(&port->list); | 1006 | list_del_rcu(&port->list); |
1004 | netdev_rx_handler_unregister(port_dev); | 1007 | netdev_rx_handler_unregister(port_dev); |
@@ -1443,7 +1446,7 @@ static void team_netpoll_cleanup(struct net_device *dev) | |||
1443 | } | 1446 | } |
1444 | 1447 | ||
1445 | static int team_netpoll_setup(struct net_device *dev, | 1448 | static int team_netpoll_setup(struct net_device *dev, |
1446 | struct netpoll_info *npifo) | 1449 | struct netpoll_info *npifo, gfp_t gfp) |
1447 | { | 1450 | { |
1448 | struct team *team = netdev_priv(dev); | 1451 | struct team *team = netdev_priv(dev); |
1449 | struct team_port *port; | 1452 | struct team_port *port; |
@@ -1451,7 +1454,7 @@ static int team_netpoll_setup(struct net_device *dev, | |||
1451 | 1454 | ||
1452 | mutex_lock(&team->lock); | 1455 | mutex_lock(&team->lock); |
1453 | list_for_each_entry(port, &team->port_list, list) { | 1456 | list_for_each_entry(port, &team->port_list, list) { |
1454 | err = team_port_enable_netpoll(team, port); | 1457 | err = team_port_enable_netpoll(team, port, gfp); |
1455 | if (err) { | 1458 | if (err) { |
1456 | __team_netpoll_cleanup(team); | 1459 | __team_netpoll_cleanup(team); |
1457 | break; | 1460 | break; |
@@ -2249,13 +2252,11 @@ static void __team_options_change_check(struct team *team) | |||
2249 | } | 2252 | } |
2250 | 2253 | ||
2251 | /* rtnl lock is held */ | 2254 | /* rtnl lock is held */ |
2252 | static void __team_port_change_check(struct team_port *port, bool linkup) | 2255 | |
2256 | static void __team_port_change_send(struct team_port *port, bool linkup) | ||
2253 | { | 2257 | { |
2254 | int err; | 2258 | int err; |
2255 | 2259 | ||
2256 | if (!port->removed && port->state.linkup == linkup) | ||
2257 | return; | ||
2258 | |||
2259 | port->changed = true; | 2260 | port->changed = true; |
2260 | port->state.linkup = linkup; | 2261 | port->state.linkup = linkup; |
2261 | team_refresh_port_linkup(port); | 2262 | team_refresh_port_linkup(port); |
@@ -2280,6 +2281,23 @@ send_event: | |||
2280 | 2281 | ||
2281 | } | 2282 | } |
2282 | 2283 | ||
2284 | static void __team_port_change_check(struct team_port *port, bool linkup) | ||
2285 | { | ||
2286 | if (port->state.linkup != linkup) | ||
2287 | __team_port_change_send(port, linkup); | ||
2288 | } | ||
2289 | |||
2290 | static void __team_port_change_port_added(struct team_port *port, bool linkup) | ||
2291 | { | ||
2292 | __team_port_change_send(port, linkup); | ||
2293 | } | ||
2294 | |||
2295 | static void __team_port_change_port_removed(struct team_port *port) | ||
2296 | { | ||
2297 | port->removed = true; | ||
2298 | __team_port_change_send(port, false); | ||
2299 | } | ||
2300 | |||
2283 | static void team_port_change_check(struct team_port *port, bool linkup) | 2301 | static void team_port_change_check(struct team_port *port, bool linkup) |
2284 | { | 2302 | { |
2285 | struct team *team = port->team; | 2303 | struct team *team = port->team; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 926d4db5cb38..3a16d4fdaa05 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -187,7 +187,6 @@ static void __tun_detach(struct tun_struct *tun) | |||
187 | netif_tx_lock_bh(tun->dev); | 187 | netif_tx_lock_bh(tun->dev); |
188 | netif_carrier_off(tun->dev); | 188 | netif_carrier_off(tun->dev); |
189 | tun->tfile = NULL; | 189 | tun->tfile = NULL; |
190 | tun->socket.file = NULL; | ||
191 | netif_tx_unlock_bh(tun->dev); | 190 | netif_tx_unlock_bh(tun->dev); |
192 | 191 | ||
193 | /* Drop read queue */ | 192 | /* Drop read queue */ |
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 4fd48df6b989..32e31c5c5dc6 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c | |||
@@ -962,6 +962,10 @@ static const struct usb_device_id products [] = { | |||
962 | USB_DEVICE (0x2001, 0x3c05), | 962 | USB_DEVICE (0x2001, 0x3c05), |
963 | .driver_info = (unsigned long) &ax88772_info, | 963 | .driver_info = (unsigned long) &ax88772_info, |
964 | }, { | 964 | }, { |
965 | // DLink DUB-E100 H/W Ver C1 | ||
966 | USB_DEVICE (0x2001, 0x1a02), | ||
967 | .driver_info = (unsigned long) &ax88772_info, | ||
968 | }, { | ||
965 | // Linksys USB1000 | 969 | // Linksys USB1000 |
966 | USB_DEVICE (0x1737, 0x0039), | 970 | USB_DEVICE (0x1737, 0x0039), |
967 | .driver_info = (unsigned long) &ax88178_info, | 971 | .driver_info = (unsigned long) &ax88178_info, |
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 64610048ce87..7d78669000d7 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -232,6 +232,7 @@ static int usbpn_open(struct net_device *dev) | |||
232 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | 232 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); |
233 | 233 | ||
234 | if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { | 234 | if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { |
235 | usb_free_urb(req); | ||
235 | usbpn_close(dev); | 236 | usbpn_close(dev); |
236 | return -ENOMEM; | 237 | return -ENOMEM; |
237 | } | 238 | } |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index f4ce5957df32..4cd582a4f625 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -1225,6 +1225,26 @@ static const struct usb_device_id cdc_devs[] = { | |||
1225 | .driver_info = (unsigned long) &wwan_info, | 1225 | .driver_info = (unsigned long) &wwan_info, |
1226 | }, | 1226 | }, |
1227 | 1227 | ||
1228 | /* Dell branded MBM devices like DW5550 */ | ||
1229 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | ||
1230 | | USB_DEVICE_ID_MATCH_VENDOR, | ||
1231 | .idVendor = 0x413c, | ||
1232 | .bInterfaceClass = USB_CLASS_COMM, | ||
1233 | .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, | ||
1234 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
1235 | .driver_info = (unsigned long) &wwan_info, | ||
1236 | }, | ||
1237 | |||
1238 | /* Toshiba branded MBM devices */ | ||
1239 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | ||
1240 | | USB_DEVICE_ID_MATCH_VENDOR, | ||
1241 | .idVendor = 0x0930, | ||
1242 | .bInterfaceClass = USB_CLASS_COMM, | ||
1243 | .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, | ||
1244 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
1245 | .driver_info = (unsigned long) &wwan_info, | ||
1246 | }, | ||
1247 | |||
1228 | /* Generic CDC-NCM devices */ | 1248 | /* Generic CDC-NCM devices */ |
1229 | { USB_INTERFACE_INFO(USB_CLASS_COMM, | 1249 | { USB_INTERFACE_INFO(USB_CLASS_COMM, |
1230 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | 1250 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 2ea126a16d79..3543c9e57824 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -247,30 +247,12 @@ err: | |||
247 | */ | 247 | */ |
248 | static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | 248 | static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) |
249 | { | 249 | { |
250 | int rv; | ||
251 | struct qmi_wwan_state *info = (void *)&dev->data; | 250 | struct qmi_wwan_state *info = (void *)&dev->data; |
252 | 251 | ||
253 | /* ZTE makes devices where the interface descriptors and endpoint | ||
254 | * configurations of two or more interfaces are identical, even | ||
255 | * though the functions are completely different. If set, then | ||
256 | * driver_info->data is a bitmap of acceptable interface numbers | ||
257 | * allowing us to bind to one such interface without binding to | ||
258 | * all of them | ||
259 | */ | ||
260 | if (dev->driver_info->data && | ||
261 | !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) { | ||
262 | dev_info(&intf->dev, "not on our whitelist - ignored"); | ||
263 | rv = -ENODEV; | ||
264 | goto err; | ||
265 | } | ||
266 | |||
267 | /* control and data is shared */ | 252 | /* control and data is shared */ |
268 | info->control = intf; | 253 | info->control = intf; |
269 | info->data = intf; | 254 | info->data = intf; |
270 | rv = qmi_wwan_register_subdriver(dev); | 255 | return qmi_wwan_register_subdriver(dev); |
271 | |||
272 | err: | ||
273 | return rv; | ||
274 | } | 256 | } |
275 | 257 | ||
276 | static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) | 258 | static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) |
@@ -315,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) | |||
315 | if (ret < 0) | 297 | if (ret < 0) |
316 | goto err; | 298 | goto err; |
317 | 299 | ||
318 | if (info->subdriver && info->subdriver->suspend) | 300 | if (intf == info->control && info->subdriver && info->subdriver->suspend) |
319 | ret = info->subdriver->suspend(intf, message); | 301 | ret = info->subdriver->suspend(intf, message); |
320 | if (ret < 0) | 302 | if (ret < 0) |
321 | usbnet_resume(intf); | 303 | usbnet_resume(intf); |
@@ -328,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf) | |||
328 | struct usbnet *dev = usb_get_intfdata(intf); | 310 | struct usbnet *dev = usb_get_intfdata(intf); |
329 | struct qmi_wwan_state *info = (void *)&dev->data; | 311 | struct qmi_wwan_state *info = (void *)&dev->data; |
330 | int ret = 0; | 312 | int ret = 0; |
313 | bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); | ||
331 | 314 | ||
332 | if (info->subdriver && info->subdriver->resume) | 315 | if (callsub) |
333 | ret = info->subdriver->resume(intf); | 316 | ret = info->subdriver->resume(intf); |
334 | if (ret < 0) | 317 | if (ret < 0) |
335 | goto err; | 318 | goto err; |
336 | ret = usbnet_resume(intf); | 319 | ret = usbnet_resume(intf); |
337 | if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) | 320 | if (ret < 0 && callsub && info->subdriver->suspend) |
338 | info->subdriver->suspend(intf, PMSG_SUSPEND); | 321 | info->subdriver->suspend(intf, PMSG_SUSPEND); |
339 | err: | 322 | err: |
340 | return ret; | 323 | return ret; |
@@ -356,217 +339,71 @@ static const struct driver_info qmi_wwan_shared = { | |||
356 | .manage_power = qmi_wwan_manage_power, | 339 | .manage_power = qmi_wwan_manage_power, |
357 | }; | 340 | }; |
358 | 341 | ||
359 | static const struct driver_info qmi_wwan_force_int0 = { | ||
360 | .description = "Qualcomm WWAN/QMI device", | ||
361 | .flags = FLAG_WWAN, | ||
362 | .bind = qmi_wwan_bind_shared, | ||
363 | .unbind = qmi_wwan_unbind, | ||
364 | .manage_power = qmi_wwan_manage_power, | ||
365 | .data = BIT(0), /* interface whitelist bitmap */ | ||
366 | }; | ||
367 | |||
368 | static const struct driver_info qmi_wwan_force_int1 = { | ||
369 | .description = "Qualcomm WWAN/QMI device", | ||
370 | .flags = FLAG_WWAN, | ||
371 | .bind = qmi_wwan_bind_shared, | ||
372 | .unbind = qmi_wwan_unbind, | ||
373 | .manage_power = qmi_wwan_manage_power, | ||
374 | .data = BIT(1), /* interface whitelist bitmap */ | ||
375 | }; | ||
376 | |||
377 | static const struct driver_info qmi_wwan_force_int2 = { | ||
378 | .description = "Qualcomm WWAN/QMI device", | ||
379 | .flags = FLAG_WWAN, | ||
380 | .bind = qmi_wwan_bind_shared, | ||
381 | .unbind = qmi_wwan_unbind, | ||
382 | .manage_power = qmi_wwan_manage_power, | ||
383 | .data = BIT(2), /* interface whitelist bitmap */ | ||
384 | }; | ||
385 | |||
386 | static const struct driver_info qmi_wwan_force_int3 = { | ||
387 | .description = "Qualcomm WWAN/QMI device", | ||
388 | .flags = FLAG_WWAN, | ||
389 | .bind = qmi_wwan_bind_shared, | ||
390 | .unbind = qmi_wwan_unbind, | ||
391 | .manage_power = qmi_wwan_manage_power, | ||
392 | .data = BIT(3), /* interface whitelist bitmap */ | ||
393 | }; | ||
394 | |||
395 | static const struct driver_info qmi_wwan_force_int4 = { | ||
396 | .description = "Qualcomm WWAN/QMI device", | ||
397 | .flags = FLAG_WWAN, | ||
398 | .bind = qmi_wwan_bind_shared, | ||
399 | .unbind = qmi_wwan_unbind, | ||
400 | .manage_power = qmi_wwan_manage_power, | ||
401 | .data = BIT(4), /* interface whitelist bitmap */ | ||
402 | }; | ||
403 | |||
404 | /* Sierra Wireless provide equally useless interface descriptors | ||
405 | * Devices in QMI mode can be switched between two different | ||
406 | * configurations: | ||
407 | * a) USB interface #8 is QMI/wwan | ||
408 | * b) USB interfaces #8, #19 and #20 are QMI/wwan | ||
409 | * | ||
410 | * Both configurations provide a number of other interfaces (serial++), | ||
411 | * some of which have the same endpoint configuration as we expect, so | ||
412 | * a whitelist or blacklist is necessary. | ||
413 | * | ||
414 | * FIXME: The below whitelist should include BIT(20). It does not | ||
415 | * because I cannot get it to work... | ||
416 | */ | ||
417 | static const struct driver_info qmi_wwan_sierra = { | ||
418 | .description = "Sierra Wireless wwan/QMI device", | ||
419 | .flags = FLAG_WWAN, | ||
420 | .bind = qmi_wwan_bind_shared, | ||
421 | .unbind = qmi_wwan_unbind, | ||
422 | .manage_power = qmi_wwan_manage_power, | ||
423 | .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ | ||
424 | }; | ||
425 | |||
426 | #define HUAWEI_VENDOR_ID 0x12D1 | 342 | #define HUAWEI_VENDOR_ID 0x12D1 |
427 | 343 | ||
344 | /* map QMI/wwan function by a fixed interface number */ | ||
345 | #define QMI_FIXED_INTF(vend, prod, num) \ | ||
346 | USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ | ||
347 | .driver_info = (unsigned long)&qmi_wwan_shared | ||
348 | |||
428 | /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ | 349 | /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ |
429 | #define QMI_GOBI1K_DEVICE(vend, prod) \ | 350 | #define QMI_GOBI1K_DEVICE(vend, prod) \ |
430 | USB_DEVICE(vend, prod), \ | 351 | QMI_FIXED_INTF(vend, prod, 3) |
431 | .driver_info = (unsigned long)&qmi_wwan_force_int3 | ||
432 | 352 | ||
433 | /* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ | 353 | /* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial */ |
434 | #define QMI_GOBI_DEVICE(vend, prod) \ | 354 | #define QMI_GOBI_DEVICE(vend, prod) \ |
435 | USB_DEVICE(vend, prod), \ | 355 | QMI_FIXED_INTF(vend, prod, 0) |
436 | .driver_info = (unsigned long)&qmi_wwan_force_int0 | ||
437 | 356 | ||
438 | static const struct usb_device_id products[] = { | 357 | static const struct usb_device_id products[] = { |
358 | /* 1. CDC ECM like devices match on the control interface */ | ||
439 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ | 359 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ |
440 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | 360 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9), |
441 | .idVendor = HUAWEI_VENDOR_ID, | ||
442 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
443 | .bInterfaceSubClass = 1, | ||
444 | .bInterfaceProtocol = 9, /* CDC Ethernet *control* interface */ | ||
445 | .driver_info = (unsigned long)&qmi_wwan_info, | 361 | .driver_info = (unsigned long)&qmi_wwan_info, |
446 | }, | 362 | }, |
447 | { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ | 363 | { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ |
448 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | 364 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), |
449 | .idVendor = HUAWEI_VENDOR_ID, | ||
450 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
451 | .bInterfaceSubClass = 1, | ||
452 | .bInterfaceProtocol = 57, /* CDC Ethernet *control* interface */ | ||
453 | .driver_info = (unsigned long)&qmi_wwan_info, | 365 | .driver_info = (unsigned long)&qmi_wwan_info, |
454 | }, | 366 | }, |
455 | { /* Huawei E392, E398 and possibly others in "Windows mode" | 367 | |
456 | * using a combined control and data interface without any CDC | 368 | /* 2. Combined interface devices matching on class+protocol */ |
457 | * functional descriptors | 369 | { /* Huawei E367 and possibly others in "Windows mode" */ |
458 | */ | 370 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 7), |
459 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | 371 | .driver_info = (unsigned long)&qmi_wwan_info, |
460 | .idVendor = HUAWEI_VENDOR_ID, | ||
461 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
462 | .bInterfaceSubClass = 1, | ||
463 | .bInterfaceProtocol = 17, | ||
464 | .driver_info = (unsigned long)&qmi_wwan_shared, | ||
465 | }, | 372 | }, |
466 | { /* Pantech UML290 */ | 373 | { /* Huawei E392, E398 and possibly others in "Windows mode" */ |
467 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 374 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), |
468 | .idVendor = 0x106c, | ||
469 | .idProduct = 0x3718, | ||
470 | .bInterfaceClass = 0xff, | ||
471 | .bInterfaceSubClass = 0xf0, | ||
472 | .bInterfaceProtocol = 0xff, | ||
473 | .driver_info = (unsigned long)&qmi_wwan_shared, | 375 | .driver_info = (unsigned long)&qmi_wwan_shared, |
474 | }, | 376 | }, |
475 | { /* ZTE MF820D */ | 377 | { /* Pantech UML290, P4200 and more */ |
476 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 378 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), |
477 | .idVendor = 0x19d2, | 379 | .driver_info = (unsigned long)&qmi_wwan_shared, |
478 | .idProduct = 0x0167, | ||
479 | .bInterfaceClass = 0xff, | ||
480 | .bInterfaceSubClass = 0xff, | ||
481 | .bInterfaceProtocol = 0xff, | ||
482 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
483 | }, | ||
484 | { /* ZTE MF821D */ | ||
485 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
486 | .idVendor = 0x19d2, | ||
487 | .idProduct = 0x0326, | ||
488 | .bInterfaceClass = 0xff, | ||
489 | .bInterfaceSubClass = 0xff, | ||
490 | .bInterfaceProtocol = 0xff, | ||
491 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
492 | }, | ||
493 | { /* ZTE (Vodafone) K3520-Z */ | ||
494 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
495 | .idVendor = 0x19d2, | ||
496 | .idProduct = 0x0055, | ||
497 | .bInterfaceClass = 0xff, | ||
498 | .bInterfaceSubClass = 0xff, | ||
499 | .bInterfaceProtocol = 0xff, | ||
500 | .driver_info = (unsigned long)&qmi_wwan_force_int1, | ||
501 | }, | ||
502 | { /* ZTE (Vodafone) K3565-Z */ | ||
503 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
504 | .idVendor = 0x19d2, | ||
505 | .idProduct = 0x0063, | ||
506 | .bInterfaceClass = 0xff, | ||
507 | .bInterfaceSubClass = 0xff, | ||
508 | .bInterfaceProtocol = 0xff, | ||
509 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
510 | }, | ||
511 | { /* ZTE (Vodafone) K3570-Z */ | ||
512 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
513 | .idVendor = 0x19d2, | ||
514 | .idProduct = 0x1008, | ||
515 | .bInterfaceClass = 0xff, | ||
516 | .bInterfaceSubClass = 0xff, | ||
517 | .bInterfaceProtocol = 0xff, | ||
518 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
519 | }, | ||
520 | { /* ZTE (Vodafone) K3571-Z */ | ||
521 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
522 | .idVendor = 0x19d2, | ||
523 | .idProduct = 0x1010, | ||
524 | .bInterfaceClass = 0xff, | ||
525 | .bInterfaceSubClass = 0xff, | ||
526 | .bInterfaceProtocol = 0xff, | ||
527 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
528 | }, | ||
529 | { /* ZTE (Vodafone) K3765-Z */ | ||
530 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
531 | .idVendor = 0x19d2, | ||
532 | .idProduct = 0x2002, | ||
533 | .bInterfaceClass = 0xff, | ||
534 | .bInterfaceSubClass = 0xff, | ||
535 | .bInterfaceProtocol = 0xff, | ||
536 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
537 | }, | ||
538 | { /* ZTE (Vodafone) K4505-Z */ | ||
539 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
540 | .idVendor = 0x19d2, | ||
541 | .idProduct = 0x0104, | ||
542 | .bInterfaceClass = 0xff, | ||
543 | .bInterfaceSubClass = 0xff, | ||
544 | .bInterfaceProtocol = 0xff, | ||
545 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
546 | }, | ||
547 | { /* ZTE MF60 */ | ||
548 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
549 | .idVendor = 0x19d2, | ||
550 | .idProduct = 0x1402, | ||
551 | .bInterfaceClass = 0xff, | ||
552 | .bInterfaceSubClass = 0xff, | ||
553 | .bInterfaceProtocol = 0xff, | ||
554 | .driver_info = (unsigned long)&qmi_wwan_force_int2, | ||
555 | }, | 380 | }, |
556 | { /* Sierra Wireless MC77xx in QMI mode */ | 381 | { /* Pantech UML290 - newer firmware */ |
557 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 382 | USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff), |
558 | .idVendor = 0x1199, | 383 | .driver_info = (unsigned long)&qmi_wwan_shared, |
559 | .idProduct = 0x68a2, | ||
560 | .bInterfaceClass = 0xff, | ||
561 | .bInterfaceSubClass = 0xff, | ||
562 | .bInterfaceProtocol = 0xff, | ||
563 | .driver_info = (unsigned long)&qmi_wwan_sierra, | ||
564 | }, | 384 | }, |
565 | 385 | ||
566 | /* Gobi 1000 devices */ | 386 | /* 3. Combined interface devices matching on interface number */ |
387 | {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ | ||
388 | {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ | ||
389 | {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ | ||
390 | {QMI_FIXED_INTF(0x19d2, 0x0157, 5)}, /* ZTE MF683 */ | ||
391 | {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ | ||
392 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ | ||
393 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ | ||
394 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ | ||
395 | {QMI_FIXED_INTF(0x19d2, 0x1018, 3)}, /* ZTE (Vodafone) K5006-Z */ | ||
396 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | ||
397 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ | ||
398 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ | ||
399 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ | ||
400 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | ||
401 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | ||
402 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | ||
403 | |||
404 | /* 4. Gobi 1000 devices */ | ||
567 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 405 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
568 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 406 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
569 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
570 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 407 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
571 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 408 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
572 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 409 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ |
@@ -579,9 +416,11 @@ static const struct usb_device_id products[] = { | |||
579 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | 416 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ |
580 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ | 417 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ |
581 | 418 | ||
582 | /* Gobi 2000 and 3000 devices */ | 419 | /* 5. Gobi 2000 and 3000 devices */ |
583 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | 420 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ |
421 | {QMI_GOBI_DEVICE(0x413c, 0x8194)}, /* Dell Gobi 3000 Composite */ | ||
584 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ | 422 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ |
423 | {QMI_GOBI_DEVICE(0x05c6, 0x920d)}, /* Gobi 3000 Composite */ | ||
585 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | 424 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ |
586 | {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ | 425 | {QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */ |
587 | {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ | 426 | {QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */ |
@@ -589,6 +428,8 @@ static const struct usb_device_id products[] = { | |||
589 | {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ | 428 | {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ |
590 | {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ | 429 | {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ |
591 | {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ | 430 | {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ |
431 | {QMI_GOBI_DEVICE(0x1199, 0x68a5)}, /* Sierra Wireless Modem */ | ||
432 | {QMI_GOBI_DEVICE(0x1199, 0x68a9)}, /* Sierra Wireless Modem */ | ||
592 | {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 433 | {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
593 | {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 434 | {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
594 | {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 435 | {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
@@ -600,11 +441,17 @@ static const struct usb_device_id products[] = { | |||
600 | {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 441 | {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
601 | {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 442 | {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
602 | {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ | 443 | {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ |
444 | {QMI_FIXED_INTF(0x1199, 0x9011, 5)}, /* alternate interface number!? */ | ||
603 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 445 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
604 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | 446 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ |
605 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ | 447 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ |
448 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
606 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ | 449 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ |
607 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ | 450 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ |
451 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ | ||
452 | {QMI_GOBI_DEVICE(0x12d1, 0x14f1)}, /* Sony Gobi 3000 Composite */ | ||
453 | {QMI_GOBI_DEVICE(0x1410, 0xa021)}, /* Foxconn Gobi 3000 Modem device (Novatel E396) */ | ||
454 | |||
608 | { } /* END */ | 455 | { } /* END */ |
609 | }; | 456 | }; |
610 | MODULE_DEVICE_TABLE(usb, products); | 457 | MODULE_DEVICE_TABLE(usb, products); |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index d75d1f56becf..8e22417fa6c1 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
@@ -68,15 +68,8 @@ static atomic_t iface_counter = ATOMIC_INIT(0); | |||
68 | */ | 68 | */ |
69 | #define SIERRA_NET_USBCTL_BUF_LEN 1024 | 69 | #define SIERRA_NET_USBCTL_BUF_LEN 1024 |
70 | 70 | ||
71 | /* list of interface numbers - used for constructing interface lists */ | ||
72 | struct sierra_net_iface_info { | ||
73 | const u32 infolen; /* number of interface numbers on list */ | ||
74 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
75 | }; | ||
76 | |||
77 | struct sierra_net_info_data { | 71 | struct sierra_net_info_data { |
78 | u16 rx_urb_size; | 72 | u16 rx_urb_size; |
79 | struct sierra_net_iface_info whitelist; | ||
80 | }; | 73 | }; |
81 | 74 | ||
82 | /* Private data structure */ | 75 | /* Private data structure */ |
@@ -637,21 +630,6 @@ static int sierra_net_change_mtu(struct net_device *net, int new_mtu) | |||
637 | return usbnet_change_mtu(net, new_mtu); | 630 | return usbnet_change_mtu(net, new_mtu); |
638 | } | 631 | } |
639 | 632 | ||
640 | static int is_whitelisted(const u8 ifnum, | ||
641 | const struct sierra_net_iface_info *whitelist) | ||
642 | { | ||
643 | if (whitelist) { | ||
644 | const u8 *list = whitelist->ifaceinfo; | ||
645 | int i; | ||
646 | |||
647 | for (i = 0; i < whitelist->infolen; i++) { | ||
648 | if (list[i] == ifnum) | ||
649 | return 1; | ||
650 | } | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | 633 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) |
656 | { | 634 | { |
657 | int result = 0; | 635 | int result = 0; |
@@ -678,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | |||
678 | return -EIO; | 656 | return -EIO; |
679 | } | 657 | } |
680 | 658 | ||
681 | *datap = *attrdata; | 659 | *datap = le16_to_cpu(*attrdata); |
682 | 660 | ||
683 | kfree(attrdata); | 661 | kfree(attrdata); |
684 | return result; | 662 | return result; |
@@ -706,11 +684,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) | |||
706 | dev_dbg(&dev->udev->dev, "%s", __func__); | 684 | dev_dbg(&dev->udev->dev, "%s", __func__); |
707 | 685 | ||
708 | ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; | 686 | ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; |
709 | /* We only accept certain interfaces */ | ||
710 | if (!is_whitelisted(ifacenum, &data->whitelist)) { | ||
711 | dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum); | ||
712 | return -ENODEV; | ||
713 | } | ||
714 | numendpoints = intf->cur_altsetting->desc.bNumEndpoints; | 687 | numendpoints = intf->cur_altsetting->desc.bNumEndpoints; |
715 | /* We have three endpoints, bulk in and out, and a status */ | 688 | /* We have three endpoints, bulk in and out, and a status */ |
716 | if (numendpoints != 3) { | 689 | if (numendpoints != 3) { |
@@ -945,13 +918,8 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
945 | return NULL; | 918 | return NULL; |
946 | } | 919 | } |
947 | 920 | ||
948 | static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; | ||
949 | static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { | 921 | static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { |
950 | .rx_urb_size = 8 * 1024, | 922 | .rx_urb_size = 8 * 1024, |
951 | .whitelist = { | ||
952 | .infolen = ARRAY_SIZE(sierra_net_ifnum_list), | ||
953 | .ifaceinfo = sierra_net_ifnum_list | ||
954 | } | ||
955 | }; | 923 | }; |
956 | 924 | ||
957 | static const struct driver_info sierra_net_info_direct_ip = { | 925 | static const struct driver_info sierra_net_info_direct_ip = { |
@@ -965,15 +933,19 @@ static const struct driver_info sierra_net_info_direct_ip = { | |||
965 | .data = (unsigned long)&sierra_net_info_data_direct_ip, | 933 | .data = (unsigned long)&sierra_net_info_data_direct_ip, |
966 | }; | 934 | }; |
967 | 935 | ||
936 | #define DIRECT_IP_DEVICE(vend, prod) \ | ||
937 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \ | ||
938 | .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ | ||
939 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 10), \ | ||
940 | .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ | ||
941 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 11), \ | ||
942 | .driver_info = (unsigned long)&sierra_net_info_direct_ip} | ||
943 | |||
968 | static const struct usb_device_id products[] = { | 944 | static const struct usb_device_id products[] = { |
969 | {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ | 945 | DIRECT_IP_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ |
970 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | 946 | DIRECT_IP_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ |
971 | {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ | 947 | DIRECT_IP_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ |
972 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | 948 | DIRECT_IP_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ |
973 | {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ | ||
974 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | ||
975 | {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ | ||
976 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | ||
977 | 949 | ||
978 | {}, /* last item */ | 950 | {}, /* last item */ |
979 | }; | 951 | }; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8531c1caac28..fc9f578a1e25 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1201,19 +1201,26 @@ deferred: | |||
1201 | } | 1201 | } |
1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
1203 | 1203 | ||
1204 | static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) | 1204 | static int rx_alloc_submit(struct usbnet *dev, gfp_t flags) |
1205 | { | 1205 | { |
1206 | struct urb *urb; | 1206 | struct urb *urb; |
1207 | int i; | 1207 | int i; |
1208 | int ret = 0; | ||
1208 | 1209 | ||
1209 | /* don't refill the queue all at once */ | 1210 | /* don't refill the queue all at once */ |
1210 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { | 1211 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { |
1211 | urb = usb_alloc_urb(0, flags); | 1212 | urb = usb_alloc_urb(0, flags); |
1212 | if (urb != NULL) { | 1213 | if (urb != NULL) { |
1213 | if (rx_submit(dev, urb, flags) == -ENOLINK) | 1214 | ret = rx_submit(dev, urb, flags); |
1214 | return; | 1215 | if (ret) |
1216 | goto err; | ||
1217 | } else { | ||
1218 | ret = -ENOMEM; | ||
1219 | goto err; | ||
1215 | } | 1220 | } |
1216 | } | 1221 | } |
1222 | err: | ||
1223 | return ret; | ||
1217 | } | 1224 | } |
1218 | 1225 | ||
1219 | /*-------------------------------------------------------------------------*/ | 1226 | /*-------------------------------------------------------------------------*/ |
@@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param) | |||
1257 | int temp = dev->rxq.qlen; | 1264 | int temp = dev->rxq.qlen; |
1258 | 1265 | ||
1259 | if (temp < RX_QLEN(dev)) { | 1266 | if (temp < RX_QLEN(dev)) { |
1260 | rx_alloc_submit(dev, GFP_ATOMIC); | 1267 | if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) |
1268 | return; | ||
1261 | if (temp != dev->rxq.qlen) | 1269 | if (temp != dev->rxq.qlen) |
1262 | netif_dbg(dev, link, dev->net, | 1270 | netif_dbg(dev, link, dev->net, |
1263 | "rxqlen %d --> %d\n", | 1271 | "rxqlen %d --> %d\n", |
@@ -1573,7 +1581,7 @@ int usbnet_resume (struct usb_interface *intf) | |||
1573 | netif_device_present(dev->net) && | 1581 | netif_device_present(dev->net) && |
1574 | !timer_pending(&dev->delay) && | 1582 | !timer_pending(&dev->delay) && |
1575 | !test_bit(EVENT_RX_HALT, &dev->flags)) | 1583 | !test_bit(EVENT_RX_HALT, &dev->flags)) |
1576 | rx_alloc_submit(dev, GFP_KERNEL); | 1584 | rx_alloc_submit(dev, GFP_NOIO); |
1577 | 1585 | ||
1578 | if (!(dev->txq.qlen >= TX_QLEN(dev))) | 1586 | if (!(dev->txq.qlen >= TX_QLEN(dev))) |
1579 | netif_tx_wake_all_queues(dev->net); | 1587 | netif_tx_wake_all_queues(dev->net); |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 93e0cfb739b8..ce9d4f2c9776 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -3019,6 +3019,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
3019 | netdev->watchdog_timeo = 5 * HZ; | 3019 | netdev->watchdog_timeo = 5 * HZ; |
3020 | 3020 | ||
3021 | INIT_WORK(&adapter->work, vmxnet3_reset_work); | 3021 | INIT_WORK(&adapter->work, vmxnet3_reset_work); |
3022 | set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); | ||
3022 | 3023 | ||
3023 | if (adapter->intr.type == VMXNET3_IT_MSIX) { | 3024 | if (adapter->intr.type == VMXNET3_IT_MSIX) { |
3024 | int i; | 3025 | int i; |
@@ -3043,7 +3044,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
3043 | goto err_register; | 3044 | goto err_register; |
3044 | } | 3045 | } |
3045 | 3046 | ||
3046 | set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); | ||
3047 | vmxnet3_check_link(adapter, false); | 3047 | vmxnet3_check_link(adapter, false); |
3048 | atomic_inc(&devices_found); | 3048 | atomic_inc(&devices_found); |
3049 | return 0; | 3049 | return 0; |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 9eb6479306d6..ef36cafd44b7 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -774,14 +774,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, | |||
774 | } | 774 | } |
775 | /* Global interrupt queue */ | 775 | /* Global interrupt queue */ |
776 | writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); | 776 | writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); |
777 | |||
778 | rc = -ENOMEM; | ||
779 | |||
777 | priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, | 780 | priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, |
778 | IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); | 781 | IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); |
779 | if (!priv->iqcfg) | 782 | if (!priv->iqcfg) |
780 | goto err_free_irq_5; | 783 | goto err_free_irq_5; |
781 | writel(priv->iqcfg_dma, ioaddr + IQCFG); | 784 | writel(priv->iqcfg_dma, ioaddr + IQCFG); |
782 | 785 | ||
783 | rc = -ENOMEM; | ||
784 | |||
785 | /* | 786 | /* |
786 | * SCC 0-3 private rx/tx irq structures | 787 | * SCC 0-3 private rx/tx irq structures |
787 | * IQRX/TXi needs to be set soon. Learned it the hard way... | 788 | * IQRX/TXi needs to be set soon. Learned it the hard way... |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa2293..3f575afd8cfc 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
12 | 12 | ||
13 | #include <linux/module.h> | ||
13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
14 | #include <linux/cdev.h> | 15 | #include <linux/cdev.h> |
15 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 283237f6f074..def12b38cbf7 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c | |||
@@ -326,8 +326,10 @@ int i2400m_barker_db_init(const char *_options) | |||
326 | unsigned barker; | 326 | unsigned barker; |
327 | 327 | ||
328 | options_orig = kstrdup(_options, GFP_KERNEL); | 328 | options_orig = kstrdup(_options, GFP_KERNEL); |
329 | if (options_orig == NULL) | 329 | if (options_orig == NULL) { |
330 | result = -ENOMEM; | ||
330 | goto error_parse; | 331 | goto error_parse; |
332 | } | ||
331 | options = options_orig; | 333 | options = options_orig; |
332 | 334 | ||
333 | while ((token = strsep(&options, ",")) != NULL) { | 335 | while ((token = strsep(&options, ",")) != NULL) { |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index efc162e0b511..88b8d64c90f1 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -342,7 +342,7 @@ static int at76_dfu_get_status(struct usb_device *udev, | |||
342 | return ret; | 342 | return ret; |
343 | } | 343 | } |
344 | 344 | ||
345 | static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state) | 345 | static int at76_dfu_get_state(struct usb_device *udev, u8 *state) |
346 | { | 346 | { |
347 | int ret; | 347 | int ret; |
348 | 348 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8c4c040a47b8..2aab20ee9f38 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2056,9 +2056,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) | |||
2056 | void | 2056 | void |
2057 | ath5k_beacon_config(struct ath5k_hw *ah) | 2057 | ath5k_beacon_config(struct ath5k_hw *ah) |
2058 | { | 2058 | { |
2059 | unsigned long flags; | 2059 | spin_lock_bh(&ah->block); |
2060 | |||
2061 | spin_lock_irqsave(&ah->block, flags); | ||
2062 | ah->bmisscount = 0; | 2060 | ah->bmisscount = 0; |
2063 | ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); | 2061 | ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); |
2064 | 2062 | ||
@@ -2085,7 +2083,7 @@ ath5k_beacon_config(struct ath5k_hw *ah) | |||
2085 | 2083 | ||
2086 | ath5k_hw_set_imr(ah, ah->imask); | 2084 | ath5k_hw_set_imr(ah, ah->imask); |
2087 | mmiowb(); | 2085 | mmiowb(); |
2088 | spin_unlock_irqrestore(&ah->block, flags); | 2086 | spin_unlock_bh(&ah->block); |
2089 | } | 2087 | } |
2090 | 2088 | ||
2091 | static void ath5k_tasklet_beacon(unsigned long data) | 2089 | static void ath5k_tasklet_beacon(unsigned long data) |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4026c906cc7b..b7e0258887e7 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | |||
1482 | case AR5K_EEPROM_MODE_11A: | 1482 | case AR5K_EEPROM_MODE_11A: |
1483 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); | 1483 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); |
1484 | rate_pcal_info = ee->ee_rate_tpwr_a; | 1484 | rate_pcal_info = ee->ee_rate_tpwr_a; |
1485 | ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; | 1485 | ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN; |
1486 | break; | 1486 | break; |
1487 | case AR5K_EEPROM_MODE_11B: | 1487 | case AR5K_EEPROM_MODE_11B: |
1488 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); | 1488 | offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index dc2bcfeadeb4..94a9bbea6874 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h | |||
@@ -182,6 +182,7 @@ | |||
182 | #define AR5K_EEPROM_EEP_DELTA 10 | 182 | #define AR5K_EEPROM_EEP_DELTA 10 |
183 | #define AR5K_EEPROM_N_MODES 3 | 183 | #define AR5K_EEPROM_N_MODES 3 |
184 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 | 184 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 |
185 | #define AR5K_EEPROM_N_5GHZ_RATE_CHAN 8 | ||
185 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 | 186 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 |
186 | #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 | 187 | #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 |
187 | #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 | 188 | #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 260e7dc7f751..d56453e43d7e 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -254,7 +254,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
254 | struct ath5k_vif *avf = (void *)vif->drv_priv; | 254 | struct ath5k_vif *avf = (void *)vif->drv_priv; |
255 | struct ath5k_hw *ah = hw->priv; | 255 | struct ath5k_hw *ah = hw->priv; |
256 | struct ath_common *common = ath5k_hw_common(ah); | 256 | struct ath_common *common = ath5k_hw_common(ah); |
257 | unsigned long flags; | ||
258 | 257 | ||
259 | mutex_lock(&ah->lock); | 258 | mutex_lock(&ah->lock); |
260 | 259 | ||
@@ -300,9 +299,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
300 | } | 299 | } |
301 | 300 | ||
302 | if (changes & BSS_CHANGED_BEACON) { | 301 | if (changes & BSS_CHANGED_BEACON) { |
303 | spin_lock_irqsave(&ah->block, flags); | 302 | spin_lock_bh(&ah->block); |
304 | ath5k_beacon_update(hw, vif); | 303 | ath5k_beacon_update(hw, vif); |
305 | spin_unlock_irqrestore(&ah->block, flags); | 304 | spin_unlock_bh(&ah->block); |
306 | } | 305 | } |
307 | 306 | ||
308 | if (changes & BSS_CHANGED_BEACON_ENABLED) | 307 | if (changes & BSS_CHANGED_BEACON_ENABLED) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 2588848f4a82..d066f2516e47 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -2982,6 +2982,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | |||
2982 | case EEP_RX_MASK: | 2982 | case EEP_RX_MASK: |
2983 | return pBase->txrxMask & 0xf; | 2983 | return pBase->txrxMask & 0xf; |
2984 | case EEP_PAPRD: | 2984 | case EEP_PAPRD: |
2985 | if (AR_SREV_9462(ah)) | ||
2986 | return false; | ||
2987 | if (!ah->config.enable_paprd); | ||
2988 | return false; | ||
2985 | return !!(pBase->featureEnable & BIT(5)); | 2989 | return !!(pBase->featureEnable & BIT(5)); |
2986 | case EEP_CHAIN_MASK_REDUCE: | 2990 | case EEP_CHAIN_MASK_REDUCE: |
2987 | return (pBase->miscConfiguration >> 0x3) & 0x1; | 2991 | return (pBase->miscConfiguration >> 0x3) & 0x1; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4cc..0ed3846f9cbb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
142 | }; | 142 | }; |
143 | int training_power; | 143 | int training_power; |
144 | int i, val; | 144 | int i, val; |
145 | u32 am2pm_mask = ah->paprd_ratemask; | ||
145 | 146 | ||
146 | if (IS_CHAN_2GHZ(ah->curchan)) | 147 | if (IS_CHAN_2GHZ(ah->curchan)) |
147 | training_power = ar9003_get_training_power_2g(ah); | 148 | training_power = ar9003_get_training_power_2g(ah); |
@@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
158 | } | 159 | } |
159 | ah->paprd_training_power = training_power; | 160 | ah->paprd_training_power = training_power; |
160 | 161 | ||
162 | if (AR_SREV_9330(ah)) | ||
163 | am2pm_mask = 0; | ||
164 | |||
161 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, | 165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, |
162 | ah->paprd_ratemask); | 166 | ah->paprd_ratemask); |
163 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, | 167 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, |
164 | ah->paprd_ratemask); | 168 | am2pm_mask); |
165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, | 169 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, |
166 | ah->paprd_ratemask_ht40); | 170 | ah->paprd_ratemask_ht40); |
167 | 171 | ||
@@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
782 | } | 786 | } |
783 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 787 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
784 | 788 | ||
789 | static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, | ||
790 | struct ath9k_hw_cal_data *caldata, | ||
791 | int chain) | ||
792 | { | ||
793 | u32 *pa_in = caldata->pa_table[chain]; | ||
794 | int capdiv_offset, quick_drop_offset; | ||
795 | int capdiv2g, quick_drop; | ||
796 | int count = 0; | ||
797 | int i; | ||
798 | |||
799 | if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) | ||
800 | return false; | ||
801 | |||
802 | capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
803 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); | ||
804 | |||
805 | quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
806 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); | ||
807 | |||
808 | if (quick_drop) | ||
809 | quick_drop -= 0x40; | ||
810 | |||
811 | for (i = 0; i < NUM_BIN + 1; i++) { | ||
812 | if (pa_in[i] == 1400) | ||
813 | count++; | ||
814 | } | ||
815 | |||
816 | if (AR_SREV_9485(ah)) { | ||
817 | if (pa_in[23] < 800) { | ||
818 | capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); | ||
819 | capdiv2g += capdiv_offset; | ||
820 | if (capdiv2g > 7) { | ||
821 | capdiv2g = 7; | ||
822 | if (pa_in[23] < 600) { | ||
823 | quick_drop++; | ||
824 | if (quick_drop > 0) | ||
825 | quick_drop = 0; | ||
826 | } | ||
827 | } | ||
828 | } else if (pa_in[23] == 1400) { | ||
829 | quick_drop_offset = min_t(int, count / 3, 2); | ||
830 | quick_drop += quick_drop_offset; | ||
831 | capdiv2g += quick_drop_offset / 2; | ||
832 | |||
833 | if (capdiv2g > 7) | ||
834 | capdiv2g = 7; | ||
835 | |||
836 | if (quick_drop > 0) { | ||
837 | quick_drop = 0; | ||
838 | capdiv2g -= quick_drop_offset; | ||
839 | if (capdiv2g < 0) | ||
840 | capdiv2g = 0; | ||
841 | } | ||
842 | } else { | ||
843 | return false; | ||
844 | } | ||
845 | } else if (AR_SREV_9330(ah)) { | ||
846 | if (pa_in[23] < 1000) { | ||
847 | capdiv_offset = (1000 - pa_in[23]) / 100; | ||
848 | capdiv2g += capdiv_offset; | ||
849 | if (capdiv_offset > 3) { | ||
850 | capdiv_offset = 1; | ||
851 | quick_drop--; | ||
852 | } | ||
853 | |||
854 | capdiv2g += capdiv_offset; | ||
855 | if (capdiv2g > 6) | ||
856 | capdiv2g = 6; | ||
857 | if (quick_drop < -4) | ||
858 | quick_drop = -4; | ||
859 | } else if (pa_in[23] == 1400) { | ||
860 | if (count > 3) { | ||
861 | quick_drop++; | ||
862 | capdiv2g -= count / 4; | ||
863 | if (quick_drop > -2) | ||
864 | quick_drop = -2; | ||
865 | } else { | ||
866 | capdiv2g--; | ||
867 | } | ||
868 | |||
869 | if (capdiv2g < 0) | ||
870 | capdiv2g = 0; | ||
871 | } else { | ||
872 | return false; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
877 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); | ||
878 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
879 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | ||
880 | quick_drop); | ||
881 | |||
882 | return true; | ||
883 | } | ||
884 | |||
785 | int ar9003_paprd_create_curve(struct ath_hw *ah, | 885 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
786 | struct ath9k_hw_cal_data *caldata, int chain) | 886 | struct ath9k_hw_cal_data *caldata, int chain) |
787 | { | 887 | { |
@@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
817 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) | 917 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) |
818 | status = -2; | 918 | status = -2; |
819 | 919 | ||
920 | if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) | ||
921 | status = -EINPROGRESS; | ||
922 | |||
820 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 923 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
821 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 924 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
822 | 925 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a43..84d3d4956861 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -625,6 +625,10 @@ | |||
625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) | 625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) |
626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) | 626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) |
627 | 627 | ||
628 | #define AR_PHY_65NM_CH0_TXRF3 0x16048 | ||
629 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e | ||
630 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 | ||
631 | |||
628 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c | 632 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c |
629 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) | 633 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) |
630 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) | 634 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 68b643c8943c..c8ef30127adb 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -1577,6 +1577,8 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1577 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask); | 1577 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask); |
1578 | debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, | 1578 | debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, |
1579 | sc->debug.debugfs_phy, sc, &fops_disable_ani); | 1579 | sc->debug.debugfs_phy, sc, &fops_disable_ani); |
1580 | debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1581 | &sc->sc_ah->config.enable_paprd); | ||
1580 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1582 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1581 | sc, &fops_regidx); | 1583 | sc, &fops_regidx); |
1582 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1584 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef4..9f83f71742a5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | |||
341 | { | 341 | { |
342 | struct ath_btcoex *btcoex = &sc->btcoex; | 342 | struct ath_btcoex *btcoex = &sc->btcoex; |
343 | 343 | ||
344 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | 344 | if (btcoex->hw_timer_enabled) |
345 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
345 | } | 346 | } |
346 | 347 | ||
347 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 348 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index cfa91ab7acf8..4faf0a395876 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
463 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 463 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
464 | } | 464 | } |
465 | 465 | ||
466 | /* PAPRD needs some more work to be enabled */ | ||
467 | ah->config.paprd_disable = 1; | ||
468 | |||
469 | ah->config.rx_intr_mitigation = true; | 466 | ah->config.rx_intr_mitigation = true; |
470 | ah->config.pcieSerDesWrite = true; | 467 | ah->config.pcieSerDesWrite = true; |
471 | 468 | ||
@@ -730,6 +727,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
730 | case AR9300_DEVID_QCA955X: | 727 | case AR9300_DEVID_QCA955X: |
731 | case AR9300_DEVID_AR9580: | 728 | case AR9300_DEVID_AR9580: |
732 | case AR9300_DEVID_AR9462: | 729 | case AR9300_DEVID_AR9462: |
730 | case AR9485_DEVID_AR1111: | ||
733 | break; | 731 | break; |
734 | default: | 732 | default: |
735 | if (common->bus_ops->ath_bus_type == ATH_USB) | 733 | if (common->bus_ops->ath_bus_type == ATH_USB) |
@@ -977,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
977 | else | 975 | else |
978 | imr_reg |= AR_IMR_TXOK; | 976 | imr_reg |= AR_IMR_TXOK; |
979 | 977 | ||
980 | if (opmode == NL80211_IFTYPE_AP) | ||
981 | imr_reg |= AR_IMR_MIB; | ||
982 | |||
983 | ENABLE_REGWRITE_BUFFER(ah); | 978 | ENABLE_REGWRITE_BUFFER(ah); |
984 | 979 | ||
985 | REG_WRITE(ah, AR_IMR, imr_reg); | 980 | REG_WRITE(ah, AR_IMR, imr_reg); |
@@ -1777,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1777 | /* Operating channel changed, reset channel calibration data */ | 1772 | /* Operating channel changed, reset channel calibration data */ |
1778 | memset(caldata, 0, sizeof(*caldata)); | 1773 | memset(caldata, 0, sizeof(*caldata)); |
1779 | ath9k_init_nfcal_hist_buffer(ah, chan); | 1774 | ath9k_init_nfcal_hist_buffer(ah, chan); |
1775 | } else if (caldata) { | ||
1776 | caldata->paprd_packet_sent = false; | ||
1780 | } | 1777 | } |
1781 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1778 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
1782 | 1779 | ||
@@ -2500,9 +2497,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2500 | pCap->rx_status_len = sizeof(struct ar9003_rxs); | 2497 | pCap->rx_status_len = sizeof(struct ar9003_rxs); |
2501 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 2498 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
2502 | pCap->txs_len = sizeof(struct ar9003_txs); | 2499 | pCap->txs_len = sizeof(struct ar9003_txs); |
2503 | if (!ah->config.paprd_disable && | ||
2504 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | ||
2505 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | ||
2506 | } else { | 2500 | } else { |
2507 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2501 | pCap->tx_desc_len = sizeof(struct ath_desc); |
2508 | if (AR_SREV_9280_20(ah)) | 2502 | if (AR_SREV_9280_20(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dd0c146d81dc..de6968fc64f4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define AR9300_DEVID_AR9462 0x0034 | 49 | #define AR9300_DEVID_AR9462 0x0034 |
50 | #define AR9300_DEVID_AR9330 0x0035 | 50 | #define AR9300_DEVID_AR9330 0x0035 |
51 | #define AR9300_DEVID_QCA955X 0x0038 | 51 | #define AR9300_DEVID_QCA955X 0x0038 |
52 | #define AR9485_DEVID_AR1111 0x0037 | ||
52 | 53 | ||
53 | #define AR5416_AR9100_DEVID 0x000b | 54 | #define AR5416_AR9100_DEVID 0x000b |
54 | 55 | ||
@@ -235,7 +236,6 @@ enum ath9k_hw_caps { | |||
235 | ATH9K_HW_CAP_LDPC = BIT(6), | 236 | ATH9K_HW_CAP_LDPC = BIT(6), |
236 | ATH9K_HW_CAP_FASTCLOCK = BIT(7), | 237 | ATH9K_HW_CAP_FASTCLOCK = BIT(7), |
237 | ATH9K_HW_CAP_SGI_20 = BIT(8), | 238 | ATH9K_HW_CAP_SGI_20 = BIT(8), |
238 | ATH9K_HW_CAP_PAPRD = BIT(9), | ||
239 | ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10), | 239 | ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10), |
240 | ATH9K_HW_CAP_2GHZ = BIT(11), | 240 | ATH9K_HW_CAP_2GHZ = BIT(11), |
241 | ATH9K_HW_CAP_5GHZ = BIT(12), | 241 | ATH9K_HW_CAP_5GHZ = BIT(12), |
@@ -286,12 +286,12 @@ struct ath9k_ops_config { | |||
286 | u8 pcie_clock_req; | 286 | u8 pcie_clock_req; |
287 | u32 pcie_waen; | 287 | u32 pcie_waen; |
288 | u8 analog_shiftreg; | 288 | u8 analog_shiftreg; |
289 | u8 paprd_disable; | ||
290 | u32 ofdm_trig_low; | 289 | u32 ofdm_trig_low; |
291 | u32 ofdm_trig_high; | 290 | u32 ofdm_trig_high; |
292 | u32 cck_trig_high; | 291 | u32 cck_trig_high; |
293 | u32 cck_trig_low; | 292 | u32 cck_trig_low; |
294 | u32 enable_ani; | 293 | u32 enable_ani; |
294 | u32 enable_paprd; | ||
295 | int serialize_regmode; | 295 | int serialize_regmode; |
296 | bool rx_intr_mitigation; | 296 | bool rx_intr_mitigation; |
297 | bool tx_intr_mitigation; | 297 | bool tx_intr_mitigation; |
@@ -404,6 +404,7 @@ struct ath9k_hw_cal_data { | |||
404 | int8_t iCoff; | 404 | int8_t iCoff; |
405 | int8_t qCoff; | 405 | int8_t qCoff; |
406 | bool rtt_done; | 406 | bool rtt_done; |
407 | bool paprd_packet_sent; | ||
407 | bool paprd_done; | 408 | bool paprd_done; |
408 | bool nfcal_pending; | 409 | bool nfcal_pending; |
409 | bool nfcal_interference; | 410 | bool nfcal_interference; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5c..7b88b9c39ccd 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
254 | int chain_ok = 0; | 254 | int chain_ok = 0; |
255 | int chain; | 255 | int chain; |
256 | int len = 1800; | 256 | int len = 1800; |
257 | int ret; | ||
257 | 258 | ||
258 | if (!caldata) | 259 | if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) |
259 | return; | 260 | return; |
260 | 261 | ||
261 | ath9k_ps_wakeup(sc); | 262 | ath9k_ps_wakeup(sc); |
@@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
282 | continue; | 283 | continue; |
283 | 284 | ||
284 | chain_ok = 0; | 285 | chain_ok = 0; |
285 | |||
286 | ath_dbg(common, CALIBRATE, | ||
287 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
288 | chain); | ||
289 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
290 | goto fail_paprd; | ||
291 | |||
292 | ar9003_paprd_setup_gain_table(ah, chain); | 286 | ar9003_paprd_setup_gain_table(ah, chain); |
293 | 287 | ||
294 | ath_dbg(common, CALIBRATE, | 288 | ath_dbg(common, CALIBRATE, |
@@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
302 | break; | 296 | break; |
303 | } | 297 | } |
304 | 298 | ||
305 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | 299 | ret = ar9003_paprd_create_curve(ah, caldata, chain); |
300 | if (ret == -EINPROGRESS) { | ||
301 | ath_dbg(common, CALIBRATE, | ||
302 | "PAPRD curve on chain %d needs to be re-trained\n", | ||
303 | chain); | ||
304 | break; | ||
305 | } else if (ret) { | ||
306 | ath_dbg(common, CALIBRATE, | 306 | ath_dbg(common, CALIBRATE, |
307 | "PAPRD create curve failed on chain %d\n", | 307 | "PAPRD create curve failed on chain %d\n", |
308 | chain); | 308 | chain); |
@@ -423,7 +423,7 @@ set_timer: | |||
423 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 423 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
424 | 424 | ||
425 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 425 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
426 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { | 426 | if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) { |
427 | if (!ah->caldata->paprd_done) | 427 | if (!ah->caldata->paprd_done) |
428 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | 428 | ieee80211_queue_work(sc->hw, &sc->paprd_work); |
429 | else if (!ah->paprd_table_write_done) | 429 | else if (!ah->paprd_table_write_done) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 7990cd55599c..b42be910a83d 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -773,15 +773,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah) | |||
773 | } | 773 | } |
774 | EXPORT_SYMBOL(ath9k_hw_intrpend); | 774 | EXPORT_SYMBOL(ath9k_hw_intrpend); |
775 | 775 | ||
776 | void ath9k_hw_disable_interrupts(struct ath_hw *ah) | 776 | void ath9k_hw_kill_interrupts(struct ath_hw *ah) |
777 | { | 777 | { |
778 | struct ath_common *common = ath9k_hw_common(ah); | 778 | struct ath_common *common = ath9k_hw_common(ah); |
779 | 779 | ||
780 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | ||
781 | atomic_set(&ah->intr_ref_cnt, -1); | ||
782 | else | ||
783 | atomic_dec(&ah->intr_ref_cnt); | ||
784 | |||
785 | ath_dbg(common, INTERRUPT, "disable IER\n"); | 780 | ath_dbg(common, INTERRUPT, "disable IER\n"); |
786 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | 781 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); |
787 | (void) REG_READ(ah, AR_IER); | 782 | (void) REG_READ(ah, AR_IER); |
@@ -793,6 +788,17 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah) | |||
793 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); | 788 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); |
794 | } | 789 | } |
795 | } | 790 | } |
791 | EXPORT_SYMBOL(ath9k_hw_kill_interrupts); | ||
792 | |||
793 | void ath9k_hw_disable_interrupts(struct ath_hw *ah) | ||
794 | { | ||
795 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | ||
796 | atomic_set(&ah->intr_ref_cnt, -1); | ||
797 | else | ||
798 | atomic_dec(&ah->intr_ref_cnt); | ||
799 | |||
800 | ath9k_hw_kill_interrupts(ah); | ||
801 | } | ||
796 | EXPORT_SYMBOL(ath9k_hw_disable_interrupts); | 802 | EXPORT_SYMBOL(ath9k_hw_disable_interrupts); |
797 | 803 | ||
798 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) | 804 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0eba36dca6f8..4a745e68dd94 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -738,6 +738,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah); | |||
738 | void ath9k_hw_set_interrupts(struct ath_hw *ah); | 738 | void ath9k_hw_set_interrupts(struct ath_hw *ah); |
739 | void ath9k_hw_enable_interrupts(struct ath_hw *ah); | 739 | void ath9k_hw_enable_interrupts(struct ath_hw *ah); |
740 | void ath9k_hw_disable_interrupts(struct ath_hw *ah); | 740 | void ath9k_hw_disable_interrupts(struct ath_hw *ah); |
741 | void ath9k_hw_kill_interrupts(struct ath_hw *ah); | ||
741 | 742 | ||
742 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah); | 743 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah); |
743 | 744 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6049d8b82855..a22df749b8db 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -462,8 +462,10 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
462 | if (!ath9k_hw_intrpend(ah)) | 462 | if (!ath9k_hw_intrpend(ah)) |
463 | return IRQ_NONE; | 463 | return IRQ_NONE; |
464 | 464 | ||
465 | if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | 465 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { |
466 | ath9k_hw_kill_interrupts(ah); | ||
466 | return IRQ_HANDLED; | 467 | return IRQ_HANDLED; |
468 | } | ||
467 | 469 | ||
468 | /* | 470 | /* |
469 | * Figure out the reason(s) for the interrupt. Note | 471 | * Figure out the reason(s) for the interrupt. Note |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 87b89d55e637..a978984d78a5 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -37,6 +37,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
37 | { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ | 37 | { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ |
38 | { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ | 38 | { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ |
39 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ | 39 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ |
40 | { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ | ||
40 | { 0 } | 41 | { 0 } |
41 | }; | 42 | }; |
42 | 43 | ||
@@ -320,6 +321,7 @@ static int ath_pci_suspend(struct device *device) | |||
320 | * Otherwise the chip never moved to full sleep, | 321 | * Otherwise the chip never moved to full sleep, |
321 | * when no interface is up. | 322 | * when no interface is up. |
322 | */ | 323 | */ |
324 | ath9k_stop_btcoex(sc); | ||
323 | ath9k_hw_disable(sc->sc_ah); | 325 | ath9k_hw_disable(sc->sc_ah); |
324 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | 326 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); |
325 | 327 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 12aca02228c2..4480c0cc655f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1044,7 +1044,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1044 | struct ieee80211_hw *hw = sc->hw; | 1044 | struct ieee80211_hw *hw = sc->hw; |
1045 | struct ieee80211_hdr *hdr; | 1045 | struct ieee80211_hdr *hdr; |
1046 | int retval; | 1046 | int retval; |
1047 | bool decrypt_error = false; | ||
1048 | struct ath_rx_status rs; | 1047 | struct ath_rx_status rs; |
1049 | enum ath9k_rx_qtype qtype; | 1048 | enum ath9k_rx_qtype qtype; |
1050 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 1049 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
@@ -1066,6 +1065,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1066 | tsf_lower = tsf & 0xffffffff; | 1065 | tsf_lower = tsf & 0xffffffff; |
1067 | 1066 | ||
1068 | do { | 1067 | do { |
1068 | bool decrypt_error = false; | ||
1069 | /* If handling rx interrupt and flush is in progress => exit */ | 1069 | /* If handling rx interrupt and flush is in progress => exit */ |
1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) | 1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) |
1071 | break; | 1071 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb1..0d4155aec48d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2018 | 2018 | ||
2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
2020 | 2020 | ||
2021 | if (sc->sc_ah->caldata) | ||
2022 | sc->sc_ah->caldata->paprd_packet_sent = true; | ||
2023 | |||
2021 | if (!(tx_flags & ATH_TX_ERROR)) | 2024 | if (!(tx_flags & ATH_TX_ERROR)) |
2022 | /* Frame was ACKed */ | 2025 | /* Frame was ACKed */ |
2023 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 2026 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b80352b308d5..a140165dfee0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2719,32 +2719,37 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2719 | if (dev->dev->chip_id == 0x4301) { | 2719 | if (dev->dev->chip_id == 0x4301) { |
2720 | mask |= 0x0060; | 2720 | mask |= 0x0060; |
2721 | set |= 0x0060; | 2721 | set |= 0x0060; |
2722 | } else if (dev->dev->chip_id == 0x5354) { | ||
2723 | /* Don't allow overtaking buttons GPIOs */ | ||
2724 | set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ | ||
2722 | } | 2725 | } |
2723 | if (dev->dev->chip_id == 0x5354) | 2726 | |
2724 | set &= 0xff02; | ||
2725 | if (0 /* FIXME: conditional unknown */ ) { | 2727 | if (0 /* FIXME: conditional unknown */ ) { |
2726 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2728 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2727 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2729 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2728 | | 0x0100); | 2730 | | 0x0100); |
2729 | mask |= 0x0180; | 2731 | /* BT Coexistance Input */ |
2730 | set |= 0x0180; | 2732 | mask |= 0x0080; |
2733 | set |= 0x0080; | ||
2734 | /* BT Coexistance Out */ | ||
2735 | mask |= 0x0100; | ||
2736 | set |= 0x0100; | ||
2731 | } | 2737 | } |
2732 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { | 2738 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { |
2739 | /* PA is controlled by gpio 9, let ucode handle it */ | ||
2733 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2740 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2734 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2741 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2735 | | 0x0200); | 2742 | | 0x0200); |
2736 | mask |= 0x0200; | 2743 | mask |= 0x0200; |
2737 | set |= 0x0200; | 2744 | set |= 0x0200; |
2738 | } | 2745 | } |
2739 | if (dev->dev->core_rev >= 2) | ||
2740 | mask |= 0x0010; /* FIXME: This is redundant. */ | ||
2741 | 2746 | ||
2742 | switch (dev->dev->bus_type) { | 2747 | switch (dev->dev->bus_type) { |
2743 | #ifdef CONFIG_B43_BCMA | 2748 | #ifdef CONFIG_B43_BCMA |
2744 | case B43_BUS_BCMA: | 2749 | case B43_BUS_BCMA: |
2745 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, | 2750 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, |
2746 | (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, | 2751 | (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, |
2747 | BCMA_CC_GPIOCTL) & mask) | set); | 2752 | BCMA_CC_GPIOCTL) & ~mask) | set); |
2748 | break; | 2753 | break; |
2749 | #endif | 2754 | #endif |
2750 | #ifdef CONFIG_B43_SSB | 2755 | #ifdef CONFIG_B43_SSB |
@@ -2753,7 +2758,7 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2753 | if (gpiodev) | 2758 | if (gpiodev) |
2754 | ssb_write32(gpiodev, B43_GPIO_CONTROL, | 2759 | ssb_write32(gpiodev, B43_GPIO_CONTROL, |
2755 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) | 2760 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) |
2756 | & mask) | set); | 2761 | & ~mask) | set); |
2757 | break; | 2762 | break; |
2758 | #endif | 2763 | #endif |
2759 | } | 2764 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 49765d34b4e0..7c4ee72f9d56 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -638,6 +638,8 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev) | |||
638 | 638 | ||
639 | oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq), | 639 | oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq), |
640 | GFP_KERNEL); | 640 | GFP_KERNEL); |
641 | if (!oobirq_entry) | ||
642 | return -ENOMEM; | ||
641 | oobirq_entry->irq = res->start; | 643 | oobirq_entry->irq = res->start; |
642 | oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK; | 644 | oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK; |
643 | list_add_tail(&oobirq_entry->list, &oobirq_lh); | 645 | list_add_tail(&oobirq_entry->list, &oobirq_lh); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 2621dd3d7dcd..6f70953f0bad 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -764,8 +764,11 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) | |||
764 | { | 764 | { |
765 | char iovbuf[32]; | 765 | char iovbuf[32]; |
766 | int retcode; | 766 | int retcode; |
767 | __le32 arp_mode_le; | ||
767 | 768 | ||
768 | brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); | 769 | arp_mode_le = cpu_to_le32(arp_mode); |
770 | brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf, | ||
771 | sizeof(iovbuf)); | ||
769 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, | 772 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, |
770 | iovbuf, sizeof(iovbuf)); | 773 | iovbuf, sizeof(iovbuf)); |
771 | retcode = retcode >= 0 ? 0 : retcode; | 774 | retcode = retcode >= 0 ? 0 : retcode; |
@@ -781,8 +784,11 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) | |||
781 | { | 784 | { |
782 | char iovbuf[32]; | 785 | char iovbuf[32]; |
783 | int retcode; | 786 | int retcode; |
787 | __le32 arp_enable_le; | ||
784 | 788 | ||
785 | brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4, | 789 | arp_enable_le = cpu_to_le32(arp_enable); |
790 | |||
791 | brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4, | ||
786 | iovbuf, sizeof(iovbuf)); | 792 | iovbuf, sizeof(iovbuf)); |
787 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, | 793 | retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, |
788 | iovbuf, sizeof(iovbuf)); | 794 | iovbuf, sizeof(iovbuf)); |
@@ -800,10 +806,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
800 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for | 806 | char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for |
801 | "event_msgs" + '\0' + bitvec */ | 807 | "event_msgs" + '\0' + bitvec */ |
802 | char buf[128], *ptr; | 808 | char buf[128], *ptr; |
803 | u32 roaming = 1; | 809 | __le32 roaming_le = cpu_to_le32(1); |
804 | uint bcn_timeout = 3; | 810 | __le32 bcn_timeout_le = cpu_to_le32(3); |
805 | int scan_assoc_time = 40; | 811 | __le32 scan_assoc_time_le = cpu_to_le32(40); |
806 | int scan_unassoc_time = 40; | 812 | __le32 scan_unassoc_time_le = cpu_to_le32(40); |
807 | int i; | 813 | int i; |
808 | struct brcmf_bus_dcmd *cmdlst; | 814 | struct brcmf_bus_dcmd *cmdlst; |
809 | struct list_head *cur, *q; | 815 | struct list_head *cur, *q; |
@@ -829,14 +835,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
829 | 835 | ||
830 | /* Setup timeout if Beacons are lost and roam is off to report | 836 | /* Setup timeout if Beacons are lost and roam is off to report |
831 | link down */ | 837 | link down */ |
832 | brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, | 838 | brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf, |
833 | sizeof(iovbuf)); | 839 | sizeof(iovbuf)); |
834 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | 840 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, |
835 | sizeof(iovbuf)); | 841 | sizeof(iovbuf)); |
836 | 842 | ||
837 | /* Enable/Disable build-in roaming to allowed ext supplicant to take | 843 | /* Enable/Disable build-in roaming to allowed ext supplicant to take |
838 | of romaing */ | 844 | of romaing */ |
839 | brcmf_c_mkiovar("roam_off", (char *)&roaming, 4, | 845 | brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4, |
840 | iovbuf, sizeof(iovbuf)); | 846 | iovbuf, sizeof(iovbuf)); |
841 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, | 847 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, |
842 | sizeof(iovbuf)); | 848 | sizeof(iovbuf)); |
@@ -848,9 +854,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) | |||
848 | sizeof(iovbuf)); | 854 | sizeof(iovbuf)); |
849 | 855 | ||
850 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, | 856 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, |
851 | (char *)&scan_assoc_time, sizeof(scan_assoc_time)); | 857 | (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le)); |
852 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, | 858 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, |
853 | (char *)&scan_unassoc_time, sizeof(scan_unassoc_time)); | 859 | (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le)); |
854 | 860 | ||
855 | /* Set and enable ARP offload feature */ | 861 | /* Set and enable ARP offload feature */ |
856 | brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); | 862 | brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e7..58f89fa9c9f8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
519 | else | 519 | else |
520 | devinfo->bus_pub.bus->dstats.tx_errors++; | 520 | devinfo->bus_pub.bus->dstats.tx_errors++; |
521 | 521 | ||
522 | dev_kfree_skb(req->skb); | 522 | brcmu_pkt_buf_free_skb(req->skb); |
523 | req->skb = NULL; | 523 | req->skb = NULL; |
524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
525 | 525 | ||
@@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
540 | devinfo->bus_pub.bus->dstats.rx_packets++; | 540 | devinfo->bus_pub.bus->dstats.rx_packets++; |
541 | } else { | 541 | } else { |
542 | devinfo->bus_pub.bus->dstats.rx_errors++; | 542 | devinfo->bus_pub.bus->dstats.rx_errors++; |
543 | dev_kfree_skb(skb); | 543 | brcmu_pkt_buf_free_skb(skb); |
544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
545 | return; | 545 | return; |
546 | } | 546 | } |
@@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
551 | brcmf_dbg(ERROR, "rx protocol error\n"); | 551 | brcmf_dbg(ERROR, "rx protocol error\n"); |
552 | brcmu_pkt_buf_free_skb(skb); | 552 | brcmu_pkt_buf_free_skb(skb); |
553 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
553 | devinfo->bus_pub.bus->dstats.rx_errors++; | 554 | devinfo->bus_pub.bus->dstats.rx_errors++; |
554 | } else { | 555 | } else { |
555 | brcmf_rx_packet(devinfo->dev, ifidx, skb); | 556 | brcmf_rx_packet(devinfo->dev, ifidx, skb); |
556 | brcmf_usb_rx_refill(devinfo, req); | 557 | brcmf_usb_rx_refill(devinfo, req); |
557 | } | 558 | } |
558 | } else { | 559 | } else { |
559 | dev_kfree_skb(skb); | 560 | brcmu_pkt_buf_free_skb(skb); |
561 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
560 | } | 562 | } |
561 | return; | 563 | return; |
562 | 564 | ||
@@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, | |||
581 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, | 583 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, |
582 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, | 584 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, |
583 | req); | 585 | req); |
584 | req->urb->transfer_flags |= URB_ZERO_PACKET; | ||
585 | req->devinfo = devinfo; | 586 | req->devinfo = devinfo; |
587 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | ||
586 | 588 | ||
587 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 589 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
588 | if (ret == 0) { | 590 | if (ret) { |
589 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | 591 | brcmf_usb_del_fromq(devinfo, req); |
590 | } else { | 592 | brcmu_pkt_buf_free_skb(req->skb); |
591 | dev_kfree_skb(req->skb); | ||
592 | req->skb = NULL; | 593 | req->skb = NULL; |
593 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 594 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
594 | } | 595 | } |
@@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
683 | 684 | ||
684 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); | 685 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); |
685 | if (!req) { | 686 | if (!req) { |
687 | brcmu_pkt_buf_free_skb(skb); | ||
686 | brcmf_dbg(ERROR, "no req to send\n"); | 688 | brcmf_dbg(ERROR, "no req to send\n"); |
687 | return -ENOMEM; | 689 | return -ENOMEM; |
688 | } | 690 | } |
689 | if (!req->urb) { | ||
690 | brcmf_dbg(ERROR, "no urb for req %p\n", req); | ||
691 | return -ENOBUFS; | ||
692 | } | ||
693 | 691 | ||
694 | req->skb = skb; | 692 | req->skb = skb; |
695 | req->devinfo = devinfo; | 693 | req->devinfo = devinfo; |
696 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, | 694 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, |
697 | skb->data, skb->len, brcmf_usb_tx_complete, req); | 695 | skb->data, skb->len, brcmf_usb_tx_complete, req); |
698 | req->urb->transfer_flags |= URB_ZERO_PACKET; | 696 | req->urb->transfer_flags |= URB_ZERO_PACKET; |
697 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | ||
699 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 698 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
700 | if (!ret) { | 699 | if (ret) { |
701 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | 700 | brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); |
702 | } else { | 701 | brcmf_usb_del_fromq(devinfo, req); |
702 | brcmu_pkt_buf_free_skb(req->skb); | ||
703 | req->skb = NULL; | 703 | req->skb = NULL; |
704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
705 | } | 705 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af26..50b5553b6964 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -500,8 +500,10 @@ static void wl_iscan_prep(struct brcmf_scan_params_le *params_le, | |||
500 | params_le->active_time = cpu_to_le32(-1); | 500 | params_le->active_time = cpu_to_le32(-1); |
501 | params_le->passive_time = cpu_to_le32(-1); | 501 | params_le->passive_time = cpu_to_le32(-1); |
502 | params_le->home_time = cpu_to_le32(-1); | 502 | params_le->home_time = cpu_to_le32(-1); |
503 | if (ssid && ssid->SSID_len) | 503 | if (ssid && ssid->SSID_len) { |
504 | memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid)); | 504 | params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len); |
505 | memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len); | ||
506 | } | ||
505 | } | 507 | } |
506 | 508 | ||
507 | static s32 | 509 | static s32 |
@@ -1876,16 +1878,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
1876 | } | 1878 | } |
1877 | 1879 | ||
1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { | 1880 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { |
1879 | scb_val.val = cpu_to_le32(0); | 1881 | memset(&scb_val, 0, sizeof(scb_val)); |
1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, | 1882 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, |
1881 | sizeof(struct brcmf_scb_val_le)); | 1883 | sizeof(struct brcmf_scb_val_le)); |
1882 | if (err) | 1884 | if (err) { |
1883 | WL_ERR("Could not get rssi (%d)\n", err); | 1885 | WL_ERR("Could not get rssi (%d)\n", err); |
1884 | 1886 | } else { | |
1885 | rssi = le32_to_cpu(scb_val.val); | 1887 | rssi = le32_to_cpu(scb_val.val); |
1886 | sinfo->filled |= STATION_INFO_SIGNAL; | 1888 | sinfo->filled |= STATION_INFO_SIGNAL; |
1887 | sinfo->signal = rssi; | 1889 | sinfo->signal = rssi; |
1888 | WL_CONN("RSSI %d dBm\n", rssi); | 1890 | WL_CONN("RSSI %d dBm\n", rssi); |
1891 | } | ||
1889 | } | 1892 | } |
1890 | 1893 | ||
1891 | done: | 1894 | done: |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 9a4c63f927cb..64a48f06d68b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -77,7 +77,7 @@ | |||
77 | NL80211_RRF_NO_IBSS) | 77 | NL80211_RRF_NO_IBSS) |
78 | 78 | ||
79 | static const struct ieee80211_regdomain brcms_regdom_x2 = { | 79 | static const struct ieee80211_regdomain brcms_regdom_x2 = { |
80 | .n_reg_rules = 7, | 80 | .n_reg_rules = 6, |
81 | .alpha2 = "X2", | 81 | .alpha2 = "X2", |
82 | .reg_rules = { | 82 | .reg_rules = { |
83 | BRCM_2GHZ_2412_2462, | 83 | BRCM_2GHZ_2412_2462, |
@@ -382,9 +382,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
382 | { | 382 | { |
383 | struct brcms_c_info *wlc = wlc_cm->wlc; | 383 | struct brcms_c_info *wlc = wlc_cm->wlc; |
384 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 384 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; |
385 | const struct ieee80211_reg_rule *reg_rule; | ||
386 | struct txpwr_limits txpwr; | 385 | struct txpwr_limits txpwr; |
387 | int ret; | ||
388 | 386 | ||
389 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); | 387 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); |
390 | 388 | ||
@@ -393,8 +391,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
393 | ); | 391 | ); |
394 | 392 | ||
395 | /* set or restore gmode as required by regulatory */ | 393 | /* set or restore gmode as required by regulatory */ |
396 | ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, ®_rule); | 394 | if (ch->flags & IEEE80211_CHAN_NO_OFDM) |
397 | if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM)) | ||
398 | brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); | 395 | brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); |
399 | else | 396 | else |
400 | brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); | 397 | brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 9e79d47e077f..a5edebeb0b4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -121,7 +121,8 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = { | |||
121 | IEEE80211_CHAN_NO_HT40PLUS), | 121 | IEEE80211_CHAN_NO_HT40PLUS), |
122 | CHAN2GHZ(14, 2484, | 122 | CHAN2GHZ(14, 2484, |
123 | IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | | 123 | IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | |
124 | IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) | 124 | IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | |
125 | IEEE80211_CHAN_NO_OFDM) | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { | 128 | static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { |
@@ -1232,6 +1233,9 @@ uint brcms_reset(struct brcms_info *wl) | |||
1232 | /* dpc will not be rescheduled */ | 1233 | /* dpc will not be rescheduled */ |
1233 | wl->resched = false; | 1234 | wl->resched = false; |
1234 | 1235 | ||
1236 | /* inform publicly that interface is down */ | ||
1237 | wl->pub->up = false; | ||
1238 | |||
1235 | return 0; | 1239 | return 0; |
1236 | } | 1240 | } |
1237 | 1241 | ||
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 95aa8e1683ec..83324b321652 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2042,7 +2042,8 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) | |||
2042 | return; | 2042 | return; |
2043 | } | 2043 | } |
2044 | len = ETH_ALEN; | 2044 | len = ETH_ALEN; |
2045 | ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); | 2045 | ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, bssid, |
2046 | &len); | ||
2046 | if (ret) { | 2047 | if (ret) { |
2047 | IPW_DEBUG_INFO("failed querying ordinals at line %d\n", | 2048 | IPW_DEBUG_INFO("failed querying ordinals at line %d\n", |
2048 | __LINE__); | 2049 | __LINE__); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 46782f1102ac..a47b306b522c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -124,6 +124,9 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, | |||
124 | const struct fw_img *img; | 124 | const struct fw_img *img; |
125 | size_t bufsz; | 125 | size_t bufsz; |
126 | 126 | ||
127 | if (!iwl_is_ready_rf(priv)) | ||
128 | return -EAGAIN; | ||
129 | |||
127 | /* default is to dump the entire data segment */ | 130 | /* default is to dump the entire data segment */ |
128 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { | 131 | if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { |
129 | priv->dbgfs_sram_offset = 0x800000; | 132 | priv->dbgfs_sram_offset = 0x800000; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 6fddd2785e6e..a82f46c10f5e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -707,11 +707,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | |||
707 | */ | 707 | */ |
708 | static bool rs_use_green(struct ieee80211_sta *sta) | 708 | static bool rs_use_green(struct ieee80211_sta *sta) |
709 | { | 709 | { |
710 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 710 | /* |
711 | struct iwl_rxon_context *ctx = sta_priv->ctx; | 711 | * There's a bug somewhere in this code that causes the |
712 | 712 | * scaling to get stuck because GF+SGI can't be combined | |
713 | return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && | 713 | * in SISO rates. Until we find that bug, disable GF, it |
714 | !(ctx->ht.non_gf_sta_present); | 714 | * has only limited benefit and we still interoperate with |
715 | * GF APs since we can always receive GF transmissions. | ||
716 | */ | ||
717 | return false; | ||
715 | } | 718 | } |
716 | 719 | ||
717 | /** | 720 | /** |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index d9694c58208c..4ffc18dc3a57 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -350,7 +350,7 @@ int iwl_queue_space(const struct iwl_queue *q); | |||
350 | /***************************************************** | 350 | /***************************************************** |
351 | * Error handling | 351 | * Error handling |
352 | ******************************************************/ | 352 | ******************************************************/ |
353 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); | 353 | int iwl_dump_fh(struct iwl_trans *trans, char **buf); |
354 | void iwl_dump_csr(struct iwl_trans *trans); | 354 | void iwl_dump_csr(struct iwl_trans *trans); |
355 | 355 | ||
356 | /***************************************************** | 356 | /***************************************************** |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 39a6ca1f009c..d1a61ba6247a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -555,7 +555,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | iwl_dump_csr(trans); | 557 | iwl_dump_csr(trans); |
558 | iwl_dump_fh(trans, NULL, false); | 558 | iwl_dump_fh(trans, NULL); |
559 | 559 | ||
560 | iwl_op_mode_nic_error(trans->op_mode); | 560 | iwl_op_mode_nic_error(trans->op_mode); |
561 | } | 561 | } |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 939c2f78df58..dbeebef562d5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1442,6 +1442,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1442 | return err; | 1442 | return err; |
1443 | 1443 | ||
1444 | err_free_irq: | 1444 | err_free_irq: |
1445 | trans_pcie->irq_requested = false; | ||
1445 | free_irq(trans_pcie->irq, trans); | 1446 | free_irq(trans_pcie->irq, trans); |
1446 | error: | 1447 | error: |
1447 | iwl_free_isr_ict(trans); | 1448 | iwl_free_isr_ict(trans); |
@@ -1649,13 +1650,9 @@ static const char *get_fh_string(int cmd) | |||
1649 | #undef IWL_CMD | 1650 | #undef IWL_CMD |
1650 | } | 1651 | } |
1651 | 1652 | ||
1652 | int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | 1653 | int iwl_dump_fh(struct iwl_trans *trans, char **buf) |
1653 | { | 1654 | { |
1654 | int i; | 1655 | int i; |
1655 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1656 | int pos = 0; | ||
1657 | size_t bufsz = 0; | ||
1658 | #endif | ||
1659 | static const u32 fh_tbl[] = { | 1656 | static const u32 fh_tbl[] = { |
1660 | FH_RSCSR_CHNL0_STTS_WPTR_REG, | 1657 | FH_RSCSR_CHNL0_STTS_WPTR_REG, |
1661 | FH_RSCSR_CHNL0_RBDCB_BASE_REG, | 1658 | FH_RSCSR_CHNL0_RBDCB_BASE_REG, |
@@ -1667,29 +1664,35 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) | |||
1667 | FH_TSSR_TX_STATUS_REG, | 1664 | FH_TSSR_TX_STATUS_REG, |
1668 | FH_TSSR_TX_ERROR_REG | 1665 | FH_TSSR_TX_ERROR_REG |
1669 | }; | 1666 | }; |
1670 | #ifdef CONFIG_IWLWIFI_DEBUG | 1667 | |
1671 | if (display) { | 1668 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1672 | bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | 1669 | if (buf) { |
1670 | int pos = 0; | ||
1671 | size_t bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; | ||
1672 | |||
1673 | *buf = kmalloc(bufsz, GFP_KERNEL); | 1673 | *buf = kmalloc(bufsz, GFP_KERNEL); |
1674 | if (!*buf) | 1674 | if (!*buf) |
1675 | return -ENOMEM; | 1675 | return -ENOMEM; |
1676 | |||
1676 | pos += scnprintf(*buf + pos, bufsz - pos, | 1677 | pos += scnprintf(*buf + pos, bufsz - pos, |
1677 | "FH register values:\n"); | 1678 | "FH register values:\n"); |
1678 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { | 1679 | |
1680 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) | ||
1679 | pos += scnprintf(*buf + pos, bufsz - pos, | 1681 | pos += scnprintf(*buf + pos, bufsz - pos, |
1680 | " %34s: 0X%08x\n", | 1682 | " %34s: 0X%08x\n", |
1681 | get_fh_string(fh_tbl[i]), | 1683 | get_fh_string(fh_tbl[i]), |
1682 | iwl_read_direct32(trans, fh_tbl[i])); | 1684 | iwl_read_direct32(trans, fh_tbl[i])); |
1683 | } | 1685 | |
1684 | return pos; | 1686 | return pos; |
1685 | } | 1687 | } |
1686 | #endif | 1688 | #endif |
1689 | |||
1687 | IWL_ERR(trans, "FH register values:\n"); | 1690 | IWL_ERR(trans, "FH register values:\n"); |
1688 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { | 1691 | for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) |
1689 | IWL_ERR(trans, " %34s: 0X%08x\n", | 1692 | IWL_ERR(trans, " %34s: 0X%08x\n", |
1690 | get_fh_string(fh_tbl[i]), | 1693 | get_fh_string(fh_tbl[i]), |
1691 | iwl_read_direct32(trans, fh_tbl[i])); | 1694 | iwl_read_direct32(trans, fh_tbl[i])); |
1692 | } | 1695 | |
1693 | return 0; | 1696 | return 0; |
1694 | } | 1697 | } |
1695 | 1698 | ||
@@ -1982,11 +1985,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
1982 | size_t count, loff_t *ppos) | 1985 | size_t count, loff_t *ppos) |
1983 | { | 1986 | { |
1984 | struct iwl_trans *trans = file->private_data; | 1987 | struct iwl_trans *trans = file->private_data; |
1985 | char *buf; | 1988 | char *buf = NULL; |
1986 | int pos = 0; | 1989 | int pos = 0; |
1987 | ssize_t ret = -EFAULT; | 1990 | ssize_t ret = -EFAULT; |
1988 | 1991 | ||
1989 | ret = pos = iwl_dump_fh(trans, &buf, true); | 1992 | ret = pos = iwl_dump_fh(trans, &buf); |
1990 | if (buf) { | 1993 | if (buf) { |
1991 | ret = simple_read_from_buffer(user_buf, | 1994 | ret = simple_read_from_buffer(user_buf, |
1992 | count, ppos, buf, pos); | 1995 | count, ppos, buf, pos); |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index eb5de800ed90..1c10b542ab23 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -1254,6 +1254,7 @@ static int lbs_associate(struct lbs_private *priv, | |||
1254 | netif_tx_wake_all_queues(priv->dev); | 1254 | netif_tx_wake_all_queues(priv->dev); |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | kfree(cmd); | ||
1257 | done: | 1258 | done: |
1258 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | 1259 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
1259 | return ret; | 1260 | return ret; |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 76caebaa4397..4cb234349fbf 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1314,6 +1314,7 @@ static void if_sdio_remove(struct sdio_func *func) | |||
1314 | kfree(packet); | 1314 | kfree(packet); |
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | kfree(card); | ||
1317 | lbs_deb_leave(LBS_DEB_SDIO); | 1318 | lbs_deb_leave(LBS_DEB_SDIO); |
1318 | } | 1319 | } |
1319 | 1320 | ||
@@ -1325,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev) | |||
1325 | 1326 | ||
1326 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); | 1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); |
1327 | 1328 | ||
1329 | /* If we're powered off anyway, just let the mmc layer remove the | ||
1330 | * card. */ | ||
1331 | if (!lbs_iface_active(card->priv)) | ||
1332 | return -ENOSYS; | ||
1333 | |||
1328 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", | 1334 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", |
1329 | sdio_func_id(func), flags); | 1335 | sdio_func_id(func), flags); |
1330 | 1336 | ||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 58048189bd24..fe1ea43c5149 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -571,7 +571,10 @@ static int lbs_thread(void *data) | |||
571 | netdev_info(dev, "Timeout submitting command 0x%04x\n", | 571 | netdev_info(dev, "Timeout submitting command 0x%04x\n", |
572 | le16_to_cpu(cmdnode->cmdbuf->command)); | 572 | le16_to_cpu(cmdnode->cmdbuf->command)); |
573 | lbs_complete_command(priv, cmdnode, -ETIMEDOUT); | 573 | lbs_complete_command(priv, cmdnode, -ETIMEDOUT); |
574 | if (priv->reset_card) | 574 | |
575 | /* Reset card, but only when it isn't in the process | ||
576 | * of being shutdown anyway. */ | ||
577 | if (!dev->dismantle && priv->reset_card) | ||
575 | priv->reset_card(priv); | 578 | priv->reset_card(priv); |
576 | } | 579 | } |
577 | priv->cmd_timed_out = 0; | 580 | priv->cmd_timed_out = 0; |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8b..565527aee0ea 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
170 | cmd_code = le16_to_cpu(host_cmd->command); | 170 | cmd_code = le16_to_cpu(host_cmd->command); |
171 | cmd_size = le16_to_cpu(host_cmd->size); | 171 | cmd_size = le16_to_cpu(host_cmd->size); |
172 | 172 | ||
173 | skb_trim(cmd_node->cmd_skb, cmd_size); | 173 | /* Adjust skb length */ |
174 | if (cmd_node->cmd_skb->len > cmd_size) | ||
175 | /* | ||
176 | * cmd_size is less than sizeof(struct host_cmd_ds_command). | ||
177 | * Trim off the unused portion. | ||
178 | */ | ||
179 | skb_trim(cmd_node->cmd_skb, cmd_size); | ||
180 | else if (cmd_node->cmd_skb->len < cmd_size) | ||
181 | /* | ||
182 | * cmd_size is larger than sizeof(struct host_cmd_ds_command) | ||
183 | * because we have appended custom IE TLV. Increase skb length | ||
184 | * accordingly. | ||
185 | */ | ||
186 | skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len); | ||
174 | 187 | ||
175 | do_gettimeofday(&tstamp); | 188 | do_gettimeofday(&tstamp); |
176 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," | 189 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 7f207b6e9552..effb044a8a9d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb"); | |||
42 | * whenever you add a new device. | 42 | * whenever you add a new device. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | static struct usb_device_id p54u_table[] __devinitdata = { | 45 | static struct usb_device_id p54u_table[] = { |
46 | /* Version 1 devices (pci chip + net2280) */ | 46 | /* Version 1 devices (pci chip + net2280) */ |
47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ | 47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ |
48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ | 48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 241162e8111d..7a4ae9ee1c63 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -1803,6 +1803,7 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
1803 | struct cfg80211_pmksa *pmksa, | 1803 | struct cfg80211_pmksa *pmksa, |
1804 | int max_pmkids) | 1804 | int max_pmkids) |
1805 | { | 1805 | { |
1806 | struct ndis_80211_pmkid *new_pmkids; | ||
1806 | int i, err, newlen; | 1807 | int i, err, newlen; |
1807 | unsigned int count; | 1808 | unsigned int count; |
1808 | 1809 | ||
@@ -1833,11 +1834,12 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
1833 | /* add new pmkid */ | 1834 | /* add new pmkid */ |
1834 | newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); | 1835 | newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); |
1835 | 1836 | ||
1836 | pmkids = krealloc(pmkids, newlen, GFP_KERNEL); | 1837 | new_pmkids = krealloc(pmkids, newlen, GFP_KERNEL); |
1837 | if (!pmkids) { | 1838 | if (!new_pmkids) { |
1838 | err = -ENOMEM; | 1839 | err = -ENOMEM; |
1839 | goto error; | 1840 | goto error; |
1840 | } | 1841 | } |
1842 | pmkids = new_pmkids; | ||
1841 | 1843 | ||
1842 | pmkids->length = cpu_to_le32(newlen); | 1844 | pmkids->length = cpu_to_le32(newlen); |
1843 | pmkids->bssid_info_count = cpu_to_le32(count + 1); | 1845 | pmkids->bssid_info_count = cpu_to_le32(count + 1); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a252..64328af496f5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1612 | { | 1612 | { |
1613 | int retval; | 1613 | int retval; |
1614 | u32 reg; | ||
1614 | 1615 | ||
1615 | /* | 1616 | /* |
1616 | * Allocate eeprom data. | 1617 | * Allocate eeprom data. |
@@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1624 | return retval; | 1625 | return retval; |
1625 | 1626 | ||
1626 | /* | 1627 | /* |
1628 | * Enable rfkill polling by setting GPIO direction of the | ||
1629 | * rfkill switch GPIO pin correctly. | ||
1630 | */ | ||
1631 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1632 | rt2x00_set_field32(®, GPIOCSR_BIT8, 1); | ||
1633 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1634 | |||
1635 | /* | ||
1627 | * Initialize hw specifications. | 1636 | * Initialize hw specifications. |
1628 | */ | 1637 | */ |
1629 | retval = rt2400pci_probe_hw_mode(rt2x00dev); | 1638 | retval = rt2400pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc439..7564ae992b73 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -670,6 +670,7 @@ | |||
670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | 670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) |
671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | 671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) |
672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | 672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) |
673 | #define GPIOCSR_BIT8 FIELD32(0x00000100) | ||
673 | 674 | ||
674 | /* | 675 | /* |
675 | * BBPPCSR: BBP Pin control register. | 676 | * BBPPCSR: BBP Pin control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b5..3de0406735f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1930 | { | 1930 | { |
1931 | int retval; | 1931 | int retval; |
1932 | u32 reg; | ||
1932 | 1933 | ||
1933 | /* | 1934 | /* |
1934 | * Allocate eeprom data. | 1935 | * Allocate eeprom data. |
@@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1942 | return retval; | 1943 | return retval; |
1943 | 1944 | ||
1944 | /* | 1945 | /* |
1946 | * Enable rfkill polling by setting GPIO direction of the | ||
1947 | * rfkill switch GPIO pin correctly. | ||
1948 | */ | ||
1949 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1950 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | ||
1951 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1952 | |||
1953 | /* | ||
1945 | * Initialize hw specifications. | 1954 | * Initialize hw specifications. |
1946 | */ | 1955 | */ |
1947 | retval = rt2500pci_probe_hw_mode(rt2x00dev); | 1956 | retval = rt2500pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9e..89fee311d8fd 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
283 | u16 reg; | 283 | u16 reg; |
284 | 284 | ||
285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | 285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); |
286 | return rt2x00_get_field32(reg, MAC_CSR19_BIT7); | 286 | return rt2x00_get_field16(reg, MAC_CSR19_BIT7); |
287 | } | 287 | } |
288 | 288 | ||
289 | #ifdef CONFIG_RT2X00_LIB_LEDS | 289 | #ifdef CONFIG_RT2X00_LIB_LEDS |
@@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
1769 | { | 1769 | { |
1770 | int retval; | 1770 | int retval; |
1771 | u16 reg; | ||
1771 | 1772 | ||
1772 | /* | 1773 | /* |
1773 | * Allocate eeprom data. | 1774 | * Allocate eeprom data. |
@@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1781 | return retval; | 1782 | return retval; |
1782 | 1783 | ||
1783 | /* | 1784 | /* |
1785 | * Enable rfkill polling by setting GPIO direction of the | ||
1786 | * rfkill switch GPIO pin correctly. | ||
1787 | */ | ||
1788 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | ||
1789 | rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); | ||
1790 | rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); | ||
1791 | |||
1792 | /* | ||
1784 | * Initialize hw specifications. | 1793 | * Initialize hw specifications. |
1785 | */ | 1794 | */ |
1786 | retval = rt2500usb_probe_hw_mode(rt2x00dev); | 1795 | retval = rt2500usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7eed..196bd5103e4f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -189,14 +189,15 @@ | |||
189 | * MAC_CSR19: GPIO control register. | 189 | * MAC_CSR19: GPIO control register. |
190 | */ | 190 | */ |
191 | #define MAC_CSR19 0x0426 | 191 | #define MAC_CSR19 0x0426 |
192 | #define MAC_CSR19_BIT0 FIELD32(0x0001) | 192 | #define MAC_CSR19_BIT0 FIELD16(0x0001) |
193 | #define MAC_CSR19_BIT1 FIELD32(0x0002) | 193 | #define MAC_CSR19_BIT1 FIELD16(0x0002) |
194 | #define MAC_CSR19_BIT2 FIELD32(0x0004) | 194 | #define MAC_CSR19_BIT2 FIELD16(0x0004) |
195 | #define MAC_CSR19_BIT3 FIELD32(0x0008) | 195 | #define MAC_CSR19_BIT3 FIELD16(0x0008) |
196 | #define MAC_CSR19_BIT4 FIELD32(0x0010) | 196 | #define MAC_CSR19_BIT4 FIELD16(0x0010) |
197 | #define MAC_CSR19_BIT5 FIELD32(0x0020) | 197 | #define MAC_CSR19_BIT5 FIELD16(0x0020) |
198 | #define MAC_CSR19_BIT6 FIELD32(0x0040) | 198 | #define MAC_CSR19_BIT6 FIELD16(0x0040) |
199 | #define MAC_CSR19_BIT7 FIELD32(0x0080) | 199 | #define MAC_CSR19_BIT7 FIELD16(0x0080) |
200 | #define MAC_CSR19_BIT8 FIELD16(0x0100) | ||
200 | 201 | ||
201 | /* | 202 | /* |
202 | * MAC_CSR20: LED control register. | 203 | * MAC_CSR20: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 88455b1b9fe0..b93516d832fb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -221,6 +221,67 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, | |||
221 | mutex_unlock(&rt2x00dev->csr_mutex); | 221 | mutex_unlock(&rt2x00dev->csr_mutex); |
222 | } | 222 | } |
223 | 223 | ||
224 | static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) | ||
225 | { | ||
226 | u32 reg; | ||
227 | int i, count; | ||
228 | |||
229 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
230 | if (rt2x00_get_field32(reg, WLAN_EN)) | ||
231 | return 0; | ||
232 | |||
233 | rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); | ||
234 | rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); | ||
235 | rt2x00_set_field32(®, WLAN_CLK_EN, 0); | ||
236 | rt2x00_set_field32(®, WLAN_EN, 1); | ||
237 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
238 | |||
239 | udelay(REGISTER_BUSY_DELAY); | ||
240 | |||
241 | count = 0; | ||
242 | do { | ||
243 | /* | ||
244 | * Check PLL_LD & XTAL_RDY. | ||
245 | */ | ||
246 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
247 | rt2800_register_read(rt2x00dev, CMB_CTRL, ®); | ||
248 | if (rt2x00_get_field32(reg, PLL_LD) && | ||
249 | rt2x00_get_field32(reg, XTAL_RDY)) | ||
250 | break; | ||
251 | udelay(REGISTER_BUSY_DELAY); | ||
252 | } | ||
253 | |||
254 | if (i >= REGISTER_BUSY_COUNT) { | ||
255 | |||
256 | if (count >= 10) | ||
257 | return -EIO; | ||
258 | |||
259 | rt2800_register_write(rt2x00dev, 0x58, 0x018); | ||
260 | udelay(REGISTER_BUSY_DELAY); | ||
261 | rt2800_register_write(rt2x00dev, 0x58, 0x418); | ||
262 | udelay(REGISTER_BUSY_DELAY); | ||
263 | rt2800_register_write(rt2x00dev, 0x58, 0x618); | ||
264 | udelay(REGISTER_BUSY_DELAY); | ||
265 | count++; | ||
266 | } else { | ||
267 | count = 0; | ||
268 | } | ||
269 | |||
270 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
271 | rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); | ||
272 | rt2x00_set_field32(®, WLAN_CLK_EN, 1); | ||
273 | rt2x00_set_field32(®, WLAN_RESET, 1); | ||
274 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
275 | udelay(10); | ||
276 | rt2x00_set_field32(®, WLAN_RESET, 0); | ||
277 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
278 | udelay(10); | ||
279 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); | ||
280 | } while (count != 0); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
224 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | 285 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, |
225 | const u8 command, const u8 token, | 286 | const u8 command, const u8 token, |
226 | const u8 arg0, const u8 arg1) | 287 | const u8 arg0, const u8 arg1) |
@@ -400,6 +461,13 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
400 | { | 461 | { |
401 | unsigned int i; | 462 | unsigned int i; |
402 | u32 reg; | 463 | u32 reg; |
464 | int retval; | ||
465 | |||
466 | if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
467 | retval = rt2800_enable_wlan_rt3290(rt2x00dev); | ||
468 | if (retval) | ||
469 | return -EBUSY; | ||
470 | } | ||
403 | 471 | ||
404 | /* | 472 | /* |
405 | * If driver doesn't wake up firmware here, | 473 | * If driver doesn't wake up firmware here, |
@@ -4021,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
4021 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4022 | msleep(1); | 4090 | msleep(1); |
4023 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | 4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); |
4092 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
4024 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | 4093 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); |
4025 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4094 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4026 | } | 4095 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 235376e9cb04..4765bbd654cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -980,69 +980,10 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
980 | return rt2800_validate_eeprom(rt2x00dev); | 980 | return rt2800_validate_eeprom(rt2x00dev); |
981 | } | 981 | } |
982 | 982 | ||
983 | static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) | ||
984 | { | ||
985 | u32 reg; | ||
986 | int i, count; | ||
987 | |||
988 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
989 | if (rt2x00_get_field32(reg, WLAN_EN)) | ||
990 | return 0; | ||
991 | |||
992 | rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); | ||
993 | rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); | ||
994 | rt2x00_set_field32(®, WLAN_CLK_EN, 0); | ||
995 | rt2x00_set_field32(®, WLAN_EN, 1); | ||
996 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
997 | |||
998 | udelay(REGISTER_BUSY_DELAY); | ||
999 | |||
1000 | count = 0; | ||
1001 | do { | ||
1002 | /* | ||
1003 | * Check PLL_LD & XTAL_RDY. | ||
1004 | */ | ||
1005 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
1006 | rt2800_register_read(rt2x00dev, CMB_CTRL, ®); | ||
1007 | if (rt2x00_get_field32(reg, PLL_LD) && | ||
1008 | rt2x00_get_field32(reg, XTAL_RDY)) | ||
1009 | break; | ||
1010 | udelay(REGISTER_BUSY_DELAY); | ||
1011 | } | ||
1012 | |||
1013 | if (i >= REGISTER_BUSY_COUNT) { | ||
1014 | |||
1015 | if (count >= 10) | ||
1016 | return -EIO; | ||
1017 | |||
1018 | rt2800_register_write(rt2x00dev, 0x58, 0x018); | ||
1019 | udelay(REGISTER_BUSY_DELAY); | ||
1020 | rt2800_register_write(rt2x00dev, 0x58, 0x418); | ||
1021 | udelay(REGISTER_BUSY_DELAY); | ||
1022 | rt2800_register_write(rt2x00dev, 0x58, 0x618); | ||
1023 | udelay(REGISTER_BUSY_DELAY); | ||
1024 | count++; | ||
1025 | } else { | ||
1026 | count = 0; | ||
1027 | } | ||
1028 | |||
1029 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
1030 | rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); | ||
1031 | rt2x00_set_field32(®, WLAN_CLK_EN, 1); | ||
1032 | rt2x00_set_field32(®, WLAN_RESET, 1); | ||
1033 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
1034 | udelay(10); | ||
1035 | rt2x00_set_field32(®, WLAN_RESET, 0); | ||
1036 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
1037 | udelay(10); | ||
1038 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); | ||
1039 | } while (count != 0); | ||
1040 | |||
1041 | return 0; | ||
1042 | } | ||
1043 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1044 | { | 984 | { |
1045 | int retval; | 985 | int retval; |
986 | u32 reg; | ||
1046 | 987 | ||
1047 | /* | 988 | /* |
1048 | * Allocate eeprom data. | 989 | * Allocate eeprom data. |
@@ -1056,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1056 | return retval; | 997 | return retval; |
1057 | 998 | ||
1058 | /* | 999 | /* |
1000 | * Enable rfkill polling by setting GPIO direction of the | ||
1001 | * rfkill switch GPIO pin correctly. | ||
1002 | */ | ||
1003 | rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
1004 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
1005 | rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1006 | |||
1007 | /* | ||
1059 | * Initialize hw specifications. | 1008 | * Initialize hw specifications. |
1060 | */ | 1009 | */ |
1061 | retval = rt2800_probe_hw_mode(rt2x00dev); | 1010 | retval = rt2800_probe_hw_mode(rt2x00dev); |
@@ -1063,17 +1012,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1063 | return retval; | 1012 | return retval; |
1064 | 1013 | ||
1065 | /* | 1014 | /* |
1066 | * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan | ||
1067 | * clk for rt3290. That avoid the MCU fail in start phase. | ||
1068 | */ | ||
1069 | if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
1070 | retval = rt2800_enable_wlan_rt3290(rt2x00dev); | ||
1071 | |||
1072 | if (retval) | ||
1073 | return retval; | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | * This device has multiple filters for control frames | 1015 | * This device has multiple filters for control frames |
1078 | * and has a separate filter for PS Poll frames. | 1016 | * and has a separate filter for PS Poll frames. |
1079 | */ | 1017 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e25..6b4226b71618 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); | 667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); |
668 | 668 | ||
669 | /* | 669 | /* |
670 | * FIXME: we need to check for rx_pkt_len validity | 670 | * Check for rx_pkt_len validity. Return if invalid, leaving |
671 | * rxdesc->size zeroed out by the upper level. | ||
671 | */ | 672 | */ |
673 | if (unlikely(rx_pkt_len == 0 || | ||
674 | rx_pkt_len > entry->queue->data_size)) { | ||
675 | ERROR(entry->queue->rt2x00dev, | ||
676 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); | ||
677 | return; | ||
678 | } | ||
679 | |||
672 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); | 680 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); |
673 | 681 | ||
674 | /* | 682 | /* |
@@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
736 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 744 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
737 | { | 745 | { |
738 | int retval; | 746 | int retval; |
747 | u32 reg; | ||
739 | 748 | ||
740 | /* | 749 | /* |
741 | * Allocate eeprom data. | 750 | * Allocate eeprom data. |
@@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
749 | return retval; | 758 | return retval; |
750 | 759 | ||
751 | /* | 760 | /* |
761 | * Enable rfkill polling by setting GPIO direction of the | ||
762 | * rfkill switch GPIO pin correctly. | ||
763 | */ | ||
764 | rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
765 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
766 | rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
767 | |||
768 | /* | ||
752 | * Initialize hw specifications. | 769 | * Initialize hw specifications. |
753 | */ | 770 | */ |
754 | retval = rt2800_probe_hw_mode(rt2x00dev); | 771 | retval = rt2800_probe_hw_mode(rt2x00dev); |
@@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1157 | { USB_DEVICE(0x1690, 0x0744) }, | 1174 | { USB_DEVICE(0x1690, 0x0744) }, |
1158 | { USB_DEVICE(0x1690, 0x0761) }, | 1175 | { USB_DEVICE(0x1690, 0x0761) }, |
1159 | { USB_DEVICE(0x1690, 0x0764) }, | 1176 | { USB_DEVICE(0x1690, 0x0764) }, |
1177 | /* ASUS */ | ||
1178 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1160 | /* Cisco */ | 1179 | /* Cisco */ |
1161 | { USB_DEVICE(0x167b, 0x4001) }, | 1180 | { USB_DEVICE(0x167b, 0x4001) }, |
1162 | /* EnGenius */ | 1181 | /* EnGenius */ |
@@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1222 | { USB_DEVICE(0x0b05, 0x1760) }, | 1241 | { USB_DEVICE(0x0b05, 0x1760) }, |
1223 | { USB_DEVICE(0x0b05, 0x1761) }, | 1242 | { USB_DEVICE(0x0b05, 0x1761) }, |
1224 | { USB_DEVICE(0x0b05, 0x1790) }, | 1243 | { USB_DEVICE(0x0b05, 0x1790) }, |
1225 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1226 | /* AzureWave */ | 1244 | /* AzureWave */ |
1227 | { USB_DEVICE(0x13d3, 0x3262) }, | 1245 | { USB_DEVICE(0x13d3, 0x3262) }, |
1228 | { USB_DEVICE(0x13d3, 0x3284) }, | 1246 | { USB_DEVICE(0x13d3, 0x3284) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a5..3f07e36f462b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
629 | */ | 629 | */ |
630 | if (unlikely(rxdesc.size == 0 || | 630 | if (unlikely(rxdesc.size == 0 || |
631 | rxdesc.size > entry->queue->data_size)) { | 631 | rxdesc.size > entry->queue->data_size)) { |
632 | WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", | 632 | ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", |
633 | rxdesc.size, entry->queue->data_size); | 633 | rxdesc.size, entry->queue->data_size); |
634 | dev_kfree_skb(entry->skb); | 634 | dev_kfree_skb(entry->skb); |
635 | goto renew_skb; | 635 | goto renew_skb; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f32259686b45..b8ec96163922 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2243,8 +2243,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2243 | 2243 | ||
2244 | static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) | 2244 | static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) |
2245 | { | 2245 | { |
2246 | struct ieee80211_conf conf = { .flags = 0 }; | 2246 | struct rt2x00lib_conf libconf = { .conf = &rt2x00dev->hw->conf }; |
2247 | struct rt2x00lib_conf libconf = { .conf = &conf }; | ||
2248 | 2247 | ||
2249 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); | 2248 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); |
2250 | } | 2249 | } |
@@ -2833,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2833 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
2834 | { | 2833 | { |
2835 | int retval; | 2834 | int retval; |
2835 | u32 reg; | ||
2836 | 2836 | ||
2837 | /* | 2837 | /* |
2838 | * Disable power saving. | 2838 | * Disable power saving. |
@@ -2851,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2851 | return retval; | 2851 | return retval; |
2852 | 2852 | ||
2853 | /* | 2853 | /* |
2854 | * Enable rfkill polling by setting GPIO direction of the | ||
2855 | * rfkill switch GPIO pin correctly. | ||
2856 | */ | ||
2857 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2858 | rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); | ||
2859 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2860 | |||
2861 | /* | ||
2854 | * Initialize hw specifications. | 2862 | * Initialize hw specifications. |
2855 | */ | 2863 | */ |
2856 | retval = rt61pci_probe_hw_mode(rt2x00dev); | 2864 | retval = rt61pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0e..8f3da5a56766 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry { | |||
372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
375 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
375 | 376 | ||
376 | /* | 377 | /* |
377 | * MAC_CSR14: LED control register. | 378 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859d..248436c13ce0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
2178 | { | 2178 | { |
2179 | int retval; | 2179 | int retval; |
2180 | u32 reg; | ||
2180 | 2181 | ||
2181 | /* | 2182 | /* |
2182 | * Allocate eeprom data. | 2183 | * Allocate eeprom data. |
@@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2190 | return retval; | 2191 | return retval; |
2191 | 2192 | ||
2192 | /* | 2193 | /* |
2194 | * Enable rfkill polling by setting GPIO direction of the | ||
2195 | * rfkill switch GPIO pin correctly. | ||
2196 | */ | ||
2197 | rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2198 | rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); | ||
2199 | rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2200 | |||
2201 | /* | ||
2193 | * Initialize hw specifications. | 2202 | * Initialize hw specifications. |
2194 | */ | 2203 | */ |
2195 | retval = rt73usb_probe_hw_mode(rt2x00dev); | 2204 | retval = rt73usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d3..df1cc116b83b 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry { | |||
282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
285 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
286 | #define MAC_CSR13_BIT14 FIELD32(0x00004000) | ||
287 | #define MAC_CSR13_BIT15 FIELD32(0x00008000) | ||
285 | 288 | ||
286 | /* | 289 | /* |
287 | * MAC_CSR14: LED control register. | 290 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 71a30b026089..533024095c43 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | |||
44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); | 44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); |
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static struct usb_device_id rtl8187_table[] __devinitdata = { | 47 | static struct usb_device_id rtl8187_table[] = { |
48 | /* Asus */ | 48 | /* Asus */ |
49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, | 49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, |
50 | /* Belkin */ | 50 | /* Belkin */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 04c3aef8a4f6..2925094b2d91 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h | |||
@@ -117,6 +117,7 @@ | |||
117 | 117 | ||
118 | #define CHIP_VER_B BIT(4) | 118 | #define CHIP_VER_B BIT(4) |
119 | #define CHIP_92C_BITMASK BIT(0) | 119 | #define CHIP_92C_BITMASK BIT(0) |
120 | #define CHIP_UNKNOWN BIT(7) | ||
120 | #define CHIP_92C_1T2R 0x03 | 121 | #define CHIP_92C_1T2R 0x03 |
121 | #define CHIP_92C 0x01 | 122 | #define CHIP_92C 0x01 |
122 | #define CHIP_88C 0x00 | 123 | #define CHIP_88C 0x00 |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index bd0da7ef290b..dd4bb0950a57 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -994,8 +994,16 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) | |||
994 | version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : | 994 | version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C : |
995 | VERSION_A_CHIP_88C; | 995 | VERSION_A_CHIP_88C; |
996 | } else { | 996 | } else { |
997 | version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C : | 997 | version = (enum version_8192c) (CHIP_VER_B | |
998 | VERSION_B_CHIP_88C; | 998 | ((value32 & TYPE_ID) ? CHIP_92C_BITMASK : 0) | |
999 | ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); | ||
1000 | if ((!IS_CHIP_VENDOR_UMC(version)) && (value32 & | ||
1001 | CHIP_VER_RTL_MASK)) { | ||
1002 | version = (enum version_8192c)(version | | ||
1003 | ((((value32 & CHIP_VER_RTL_MASK) == BIT(12)) | ||
1004 | ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | | ||
1005 | CHIP_VENDOR_UMC)); | ||
1006 | } | ||
999 | } | 1007 | } |
1000 | 1008 | ||
1001 | switch (version) { | 1009 | switch (version) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 3aa927f8b9b9..7d8f96405f42 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -162,10 +162,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | |||
162 | 162 | ||
163 | /* request fw */ | 163 | /* request fw */ |
164 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && | 164 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && |
165 | !IS_92C_SERIAL(rtlhal->version)) | 165 | !IS_92C_SERIAL(rtlhal->version)) { |
166 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; | 166 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; |
167 | else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) | 167 | } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { |
168 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; | 168 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; |
169 | pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n"); | ||
170 | } | ||
169 | 171 | ||
170 | rtlpriv->max_fw_size = 0x4000; | 172 | rtlpriv->max_fw_size = 0x4000; |
171 | pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); | 173 | pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 30899901aef5..650f79a1f2bd 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -57,8 +57,7 @@ | |||
57 | static const struct ethtool_ops xennet_ethtool_ops; | 57 | static const struct ethtool_ops xennet_ethtool_ops; |
58 | 58 | ||
59 | struct netfront_cb { | 59 | struct netfront_cb { |
60 | struct page *page; | 60 | int pull_to; |
61 | unsigned offset; | ||
62 | }; | 61 | }; |
63 | 62 | ||
64 | #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) | 63 | #define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) |
@@ -867,15 +866,9 @@ static int handle_incoming_queue(struct net_device *dev, | |||
867 | struct sk_buff *skb; | 866 | struct sk_buff *skb; |
868 | 867 | ||
869 | while ((skb = __skb_dequeue(rxq)) != NULL) { | 868 | while ((skb = __skb_dequeue(rxq)) != NULL) { |
870 | struct page *page = NETFRONT_SKB_CB(skb)->page; | 869 | int pull_to = NETFRONT_SKB_CB(skb)->pull_to; |
871 | void *vaddr = page_address(page); | ||
872 | unsigned offset = NETFRONT_SKB_CB(skb)->offset; | ||
873 | |||
874 | memcpy(skb->data, vaddr + offset, | ||
875 | skb_headlen(skb)); | ||
876 | 870 | ||
877 | if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) | 871 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); |
878 | __free_page(page); | ||
879 | 872 | ||
880 | /* Ethernet work: Delayed to here as it peeks the header. */ | 873 | /* Ethernet work: Delayed to here as it peeks the header. */ |
881 | skb->protocol = eth_type_trans(skb, dev); | 874 | skb->protocol = eth_type_trans(skb, dev); |
@@ -913,7 +906,6 @@ static int xennet_poll(struct napi_struct *napi, int budget) | |||
913 | struct sk_buff_head errq; | 906 | struct sk_buff_head errq; |
914 | struct sk_buff_head tmpq; | 907 | struct sk_buff_head tmpq; |
915 | unsigned long flags; | 908 | unsigned long flags; |
916 | unsigned int len; | ||
917 | int err; | 909 | int err; |
918 | 910 | ||
919 | spin_lock(&np->rx_lock); | 911 | spin_lock(&np->rx_lock); |
@@ -955,24 +947,13 @@ err: | |||
955 | } | 947 | } |
956 | } | 948 | } |
957 | 949 | ||
958 | NETFRONT_SKB_CB(skb)->page = | 950 | NETFRONT_SKB_CB(skb)->pull_to = rx->status; |
959 | skb_frag_page(&skb_shinfo(skb)->frags[0]); | 951 | if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD) |
960 | NETFRONT_SKB_CB(skb)->offset = rx->offset; | 952 | NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD; |
961 | |||
962 | len = rx->status; | ||
963 | if (len > RX_COPY_THRESHOLD) | ||
964 | len = RX_COPY_THRESHOLD; | ||
965 | skb_put(skb, len); | ||
966 | 953 | ||
967 | if (rx->status > len) { | 954 | skb_shinfo(skb)->frags[0].page_offset = rx->offset; |
968 | skb_shinfo(skb)->frags[0].page_offset = | 955 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); |
969 | rx->offset + len; | 956 | skb->data_len = rx->status; |
970 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len); | ||
971 | skb->data_len = rx->status - len; | ||
972 | } else { | ||
973 | __skb_fill_page_desc(skb, 0, NULL, 0, 0); | ||
974 | skb_shinfo(skb)->nr_frags = 0; | ||
975 | } | ||
976 | 957 | ||
977 | i = xennet_fill_frags(np, skb, &tmpq); | 958 | i = xennet_fill_frags(np, skb, &tmpq); |
978 | 959 | ||
@@ -999,7 +980,7 @@ err: | |||
999 | * receive throughout using the standard receive | 980 | * receive throughout using the standard receive |
1000 | * buffer size was cut by 25%(!!!). | 981 | * buffer size was cut by 25%(!!!). |
1001 | */ | 982 | */ |
1002 | skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); | 983 | skb->truesize += skb->data_len - RX_COPY_THRESHOLD; |
1003 | skb->len += skb->data_len; | 984 | skb->len += skb->data_len; |
1004 | 985 | ||
1005 | if (rx->flags & XEN_NETRXF_csum_blank) | 986 | if (rx->flags & XEN_NETRXF_csum_blank) |
diff --git a/drivers/of/base.c b/drivers/of/base.c index c181b94abc36..d4a1c9a043e1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -364,6 +364,33 @@ struct device_node *of_get_next_child(const struct device_node *node, | |||
364 | EXPORT_SYMBOL(of_get_next_child); | 364 | EXPORT_SYMBOL(of_get_next_child); |
365 | 365 | ||
366 | /** | 366 | /** |
367 | * of_get_next_available_child - Find the next available child node | ||
368 | * @node: parent node | ||
369 | * @prev: previous child of the parent node, or NULL to get first | ||
370 | * | ||
371 | * This function is like of_get_next_child(), except that it | ||
372 | * automatically skips any disabled nodes (i.e. status = "disabled"). | ||
373 | */ | ||
374 | struct device_node *of_get_next_available_child(const struct device_node *node, | ||
375 | struct device_node *prev) | ||
376 | { | ||
377 | struct device_node *next; | ||
378 | |||
379 | read_lock(&devtree_lock); | ||
380 | next = prev ? prev->sibling : node->child; | ||
381 | for (; next; next = next->sibling) { | ||
382 | if (!of_device_is_available(next)) | ||
383 | continue; | ||
384 | if (of_node_get(next)) | ||
385 | break; | ||
386 | } | ||
387 | of_node_put(prev); | ||
388 | read_unlock(&devtree_lock); | ||
389 | return next; | ||
390 | } | ||
391 | EXPORT_SYMBOL(of_get_next_available_child); | ||
392 | |||
393 | /** | ||
367 | * of_find_node_by_path - Find a node matching a full OF path | 394 | * of_find_node_by_path - Find a node matching a full OF path |
368 | * @path: The full path to match | 395 | * @path: The full path to match |
369 | * | 396 | * |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index fbf7b26c7c8a..c5792d622dc4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -266,8 +266,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | if (!error) | 268 | if (!error) |
269 | dev_printk(KERN_INFO, &dev->dev, | 269 | dev_info(&dev->dev, "power state changed by ACPI to %s\n", |
270 | "power state changed by ACPI to D%d\n", state); | 270 | pci_power_name(state)); |
271 | 271 | ||
272 | return error; | 272 | return error; |
273 | } | 273 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 185be3703343..d6fd6b6d9d4b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -280,8 +280,12 @@ static long local_pci_probe(void *_ddi) | |||
280 | { | 280 | { |
281 | struct drv_dev_and_id *ddi = _ddi; | 281 | struct drv_dev_and_id *ddi = _ddi; |
282 | struct device *dev = &ddi->dev->dev; | 282 | struct device *dev = &ddi->dev->dev; |
283 | struct device *parent = dev->parent; | ||
283 | int rc; | 284 | int rc; |
284 | 285 | ||
286 | /* The parent bridge must be in active state when probing */ | ||
287 | if (parent) | ||
288 | pm_runtime_get_sync(parent); | ||
285 | /* Unbound PCI devices are always set to disabled and suspended. | 289 | /* Unbound PCI devices are always set to disabled and suspended. |
286 | * During probe, the device is set to enabled and active and the | 290 | * During probe, the device is set to enabled and active and the |
287 | * usage count is incremented. If the driver supports runtime PM, | 291 | * usage count is incremented. If the driver supports runtime PM, |
@@ -298,6 +302,8 @@ static long local_pci_probe(void *_ddi) | |||
298 | pm_runtime_set_suspended(dev); | 302 | pm_runtime_set_suspended(dev); |
299 | pm_runtime_put_noidle(dev); | 303 | pm_runtime_put_noidle(dev); |
300 | } | 304 | } |
305 | if (parent) | ||
306 | pm_runtime_put(parent); | ||
301 | return rc; | 307 | return rc; |
302 | } | 308 | } |
303 | 309 | ||
@@ -959,6 +965,13 @@ static int pci_pm_poweroff_noirq(struct device *dev) | |||
959 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) | 965 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) |
960 | pci_prepare_to_sleep(pci_dev); | 966 | pci_prepare_to_sleep(pci_dev); |
961 | 967 | ||
968 | /* | ||
969 | * The reason for doing this here is the same as for the analogous code | ||
970 | * in pci_pm_suspend_noirq(). | ||
971 | */ | ||
972 | if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
973 | pci_write_config_word(pci_dev, PCI_COMMAND, 0); | ||
974 | |||
962 | return 0; | 975 | return 0; |
963 | } | 976 | } |
964 | 977 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6869009c7393..02d107b15281 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -458,6 +458,40 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
458 | } | 458 | } |
459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); | 459 | struct device_attribute vga_attr = __ATTR_RO(boot_vga); |
460 | 460 | ||
461 | static void | ||
462 | pci_config_pm_runtime_get(struct pci_dev *pdev) | ||
463 | { | ||
464 | struct device *dev = &pdev->dev; | ||
465 | struct device *parent = dev->parent; | ||
466 | |||
467 | if (parent) | ||
468 | pm_runtime_get_sync(parent); | ||
469 | pm_runtime_get_noresume(dev); | ||
470 | /* | ||
471 | * pdev->current_state is set to PCI_D3cold during suspending, | ||
472 | * so wait until suspending completes | ||
473 | */ | ||
474 | pm_runtime_barrier(dev); | ||
475 | /* | ||
476 | * Only need to resume devices in D3cold, because config | ||
477 | * registers are still accessible for devices suspended but | ||
478 | * not in D3cold. | ||
479 | */ | ||
480 | if (pdev->current_state == PCI_D3cold) | ||
481 | pm_runtime_resume(dev); | ||
482 | } | ||
483 | |||
484 | static void | ||
485 | pci_config_pm_runtime_put(struct pci_dev *pdev) | ||
486 | { | ||
487 | struct device *dev = &pdev->dev; | ||
488 | struct device *parent = dev->parent; | ||
489 | |||
490 | pm_runtime_put(dev); | ||
491 | if (parent) | ||
492 | pm_runtime_put_sync(parent); | ||
493 | } | ||
494 | |||
461 | static ssize_t | 495 | static ssize_t |
462 | pci_read_config(struct file *filp, struct kobject *kobj, | 496 | pci_read_config(struct file *filp, struct kobject *kobj, |
463 | struct bin_attribute *bin_attr, | 497 | struct bin_attribute *bin_attr, |
@@ -484,6 +518,8 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
484 | size = count; | 518 | size = count; |
485 | } | 519 | } |
486 | 520 | ||
521 | pci_config_pm_runtime_get(dev); | ||
522 | |||
487 | if ((off & 1) && size) { | 523 | if ((off & 1) && size) { |
488 | u8 val; | 524 | u8 val; |
489 | pci_user_read_config_byte(dev, off, &val); | 525 | pci_user_read_config_byte(dev, off, &val); |
@@ -529,6 +565,8 @@ pci_read_config(struct file *filp, struct kobject *kobj, | |||
529 | --size; | 565 | --size; |
530 | } | 566 | } |
531 | 567 | ||
568 | pci_config_pm_runtime_put(dev); | ||
569 | |||
532 | return count; | 570 | return count; |
533 | } | 571 | } |
534 | 572 | ||
@@ -549,6 +587,8 @@ pci_write_config(struct file* filp, struct kobject *kobj, | |||
549 | count = size; | 587 | count = size; |
550 | } | 588 | } |
551 | 589 | ||
590 | pci_config_pm_runtime_get(dev); | ||
591 | |||
552 | if ((off & 1) && size) { | 592 | if ((off & 1) && size) { |
553 | pci_user_write_config_byte(dev, off, data[off - init_off]); | 593 | pci_user_write_config_byte(dev, off, data[off - init_off]); |
554 | off++; | 594 | off++; |
@@ -587,6 +627,8 @@ pci_write_config(struct file* filp, struct kobject *kobj, | |||
587 | --size; | 627 | --size; |
588 | } | 628 | } |
589 | 629 | ||
630 | pci_config_pm_runtime_put(dev); | ||
631 | |||
590 | return count; | 632 | return count; |
591 | } | 633 | } |
592 | 634 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f3ea977a5b1b..ab4bf5a4c2f1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1941,6 +1941,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1941 | dev->pm_cap = pm; | 1941 | dev->pm_cap = pm; |
1942 | dev->d3_delay = PCI_PM_D3_WAIT; | 1942 | dev->d3_delay = PCI_PM_D3_WAIT; |
1943 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; | 1943 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; |
1944 | dev->d3cold_allowed = true; | ||
1944 | 1945 | ||
1945 | dev->d1_support = false; | 1946 | dev->d1_support = false; |
1946 | dev->d2_support = false; | 1947 | dev->d2_support = false; |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 3a7eefcb270a..e76b44777dbf 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -140,9 +140,17 @@ static int pcie_port_runtime_resume(struct device *dev) | |||
140 | { | 140 | { |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | |||
144 | static int pcie_port_runtime_idle(struct device *dev) | ||
145 | { | ||
146 | /* Delay for a short while to prevent too frequent suspend/resume */ | ||
147 | pm_schedule_suspend(dev, 10); | ||
148 | return -EBUSY; | ||
149 | } | ||
143 | #else | 150 | #else |
144 | #define pcie_port_runtime_suspend NULL | 151 | #define pcie_port_runtime_suspend NULL |
145 | #define pcie_port_runtime_resume NULL | 152 | #define pcie_port_runtime_resume NULL |
153 | #define pcie_port_runtime_idle NULL | ||
146 | #endif | 154 | #endif |
147 | 155 | ||
148 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 156 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
@@ -155,6 +163,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
155 | .resume_noirq = pcie_port_resume_noirq, | 163 | .resume_noirq = pcie_port_resume_noirq, |
156 | .runtime_suspend = pcie_port_runtime_suspend, | 164 | .runtime_suspend = pcie_port_runtime_suspend, |
157 | .runtime_resume = pcie_port_runtime_resume, | 165 | .runtime_resume = pcie_port_runtime_resume, |
166 | .runtime_idle = pcie_port_runtime_idle, | ||
158 | }; | 167 | }; |
159 | 168 | ||
160 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 169 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
@@ -200,6 +209,11 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, | |||
200 | return status; | 209 | return status; |
201 | 210 | ||
202 | pci_save_state(dev); | 211 | pci_save_state(dev); |
212 | /* | ||
213 | * D3cold may not work properly on some PCIe port, so disable | ||
214 | * it by default. | ||
215 | */ | ||
216 | dev->d3cold_allowed = false; | ||
203 | if (!pci_match_id(port_runtime_pm_black_list, dev)) | 217 | if (!pci_match_id(port_runtime_pm_black_list, dev)) |
204 | pm_runtime_put_noidle(&dev->dev); | 218 | pm_runtime_put_noidle(&dev->dev); |
205 | 219 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6c143b4497ca..9f8a6b79a8ec 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -144,15 +144,13 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar) | |||
144 | case PCI_BASE_ADDRESS_MEM_TYPE_32: | 144 | case PCI_BASE_ADDRESS_MEM_TYPE_32: |
145 | break; | 145 | break; |
146 | case PCI_BASE_ADDRESS_MEM_TYPE_1M: | 146 | case PCI_BASE_ADDRESS_MEM_TYPE_1M: |
147 | dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n"); | 147 | /* 1M mem BAR treated as 32-bit BAR */ |
148 | break; | 148 | break; |
149 | case PCI_BASE_ADDRESS_MEM_TYPE_64: | 149 | case PCI_BASE_ADDRESS_MEM_TYPE_64: |
150 | flags |= IORESOURCE_MEM_64; | 150 | flags |= IORESOURCE_MEM_64; |
151 | break; | 151 | break; |
152 | default: | 152 | default: |
153 | dev_warn(&dev->dev, | 153 | /* mem unknown type treated as 32-bit BAR */ |
154 | "mem unknown type %x treated as 32-bit BAR\n", | ||
155 | mem_type); | ||
156 | break; | 154 | break; |
157 | } | 155 | } |
158 | return flags; | 156 | return flags; |
@@ -173,9 +171,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
173 | u32 l, sz, mask; | 171 | u32 l, sz, mask; |
174 | u16 orig_cmd; | 172 | u16 orig_cmd; |
175 | struct pci_bus_region region; | 173 | struct pci_bus_region region; |
174 | bool bar_too_big = false, bar_disabled = false; | ||
176 | 175 | ||
177 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 176 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
178 | 177 | ||
178 | /* No printks while decoding is disabled! */ | ||
179 | if (!dev->mmio_always_on) { | 179 | if (!dev->mmio_always_on) { |
180 | pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); | 180 | pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); |
181 | pci_write_config_word(dev, PCI_COMMAND, | 181 | pci_write_config_word(dev, PCI_COMMAND, |
@@ -240,8 +240,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
240 | goto fail; | 240 | goto fail; |
241 | 241 | ||
242 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 242 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
243 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", | 243 | bar_too_big = true; |
244 | pos); | ||
245 | goto fail; | 244 | goto fail; |
246 | } | 245 | } |
247 | 246 | ||
@@ -252,12 +251,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
252 | region.start = 0; | 251 | region.start = 0; |
253 | region.end = sz64; | 252 | region.end = sz64; |
254 | pcibios_bus_to_resource(dev, res, ®ion); | 253 | pcibios_bus_to_resource(dev, res, ®ion); |
254 | bar_disabled = true; | ||
255 | } else { | 255 | } else { |
256 | region.start = l64; | 256 | region.start = l64; |
257 | region.end = l64 + sz64; | 257 | region.end = l64 + sz64; |
258 | pcibios_bus_to_resource(dev, res, ®ion); | 258 | pcibios_bus_to_resource(dev, res, ®ion); |
259 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", | ||
260 | pos, res); | ||
261 | } | 259 | } |
262 | } else { | 260 | } else { |
263 | sz = pci_size(l, sz, mask); | 261 | sz = pci_size(l, sz, mask); |
@@ -268,18 +266,23 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
268 | region.start = l; | 266 | region.start = l; |
269 | region.end = l + sz; | 267 | region.end = l + sz; |
270 | pcibios_bus_to_resource(dev, res, ®ion); | 268 | pcibios_bus_to_resource(dev, res, ®ion); |
271 | |||
272 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | ||
273 | } | 269 | } |
274 | 270 | ||
275 | out: | 271 | goto out; |
272 | |||
273 | |||
274 | fail: | ||
275 | res->flags = 0; | ||
276 | out: | ||
276 | if (!dev->mmio_always_on) | 277 | if (!dev->mmio_always_on) |
277 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); | 278 | pci_write_config_word(dev, PCI_COMMAND, orig_cmd); |
278 | 279 | ||
280 | if (bar_too_big) | ||
281 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", pos); | ||
282 | if (res->flags && !bar_disabled) | ||
283 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | ||
284 | |||
279 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; | 285 | return (res->flags & IORESOURCE_MEM_64) ? 1 : 0; |
280 | fail: | ||
281 | res->flags = 0; | ||
282 | goto out; | ||
283 | } | 286 | } |
284 | 287 | ||
285 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) | 288 | static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index fb7f3bebdc69..dc5c126e398a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -657,11 +657,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev) | |||
657 | if (p != NULL) | 657 | if (p != NULL) |
658 | return ERR_PTR(-EBUSY); | 658 | return ERR_PTR(-EBUSY); |
659 | 659 | ||
660 | p = create_pinctrl(dev); | 660 | return create_pinctrl(dev); |
661 | if (IS_ERR(p)) | ||
662 | return p; | ||
663 | |||
664 | return p; | ||
665 | } | 661 | } |
666 | 662 | ||
667 | /** | 663 | /** |
@@ -738,11 +734,8 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, | |||
738 | dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", | 734 | dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", |
739 | name); | 735 | name); |
740 | state = create_state(p, name); | 736 | state = create_state(p, name); |
741 | if (IS_ERR(state)) | 737 | } else |
742 | return state; | 738 | state = ERR_PTR(-ENODEV); |
743 | } else { | ||
744 | return ERR_PTR(-ENODEV); | ||
745 | } | ||
746 | } | 739 | } |
747 | 740 | ||
748 | return state; | 741 | return state; |
diff --git a/drivers/pinctrl/pinctrl-imx23.c b/drivers/pinctrl/pinctrl-imx23.c index 75d3eff94296..3674d877ed7c 100644 --- a/drivers/pinctrl/pinctrl-imx23.c +++ b/drivers/pinctrl/pinctrl-imx23.c | |||
@@ -292,7 +292,7 @@ static int __init imx23_pinctrl_init(void) | |||
292 | { | 292 | { |
293 | return platform_driver_register(&imx23_pinctrl_driver); | 293 | return platform_driver_register(&imx23_pinctrl_driver); |
294 | } | 294 | } |
295 | arch_initcall(imx23_pinctrl_init); | 295 | postcore_initcall(imx23_pinctrl_init); |
296 | 296 | ||
297 | static void __exit imx23_pinctrl_exit(void) | 297 | static void __exit imx23_pinctrl_exit(void) |
298 | { | 298 | { |
diff --git a/drivers/pinctrl/pinctrl-imx28.c b/drivers/pinctrl/pinctrl-imx28.c index b973026811a2..0f5b2122b1ba 100644 --- a/drivers/pinctrl/pinctrl-imx28.c +++ b/drivers/pinctrl/pinctrl-imx28.c | |||
@@ -408,7 +408,7 @@ static int __init imx28_pinctrl_init(void) | |||
408 | { | 408 | { |
409 | return platform_driver_register(&imx28_pinctrl_driver); | 409 | return platform_driver_register(&imx28_pinctrl_driver); |
410 | } | 410 | } |
411 | arch_initcall(imx28_pinctrl_init); | 411 | postcore_initcall(imx28_pinctrl_init); |
412 | 412 | ||
413 | static void __exit imx28_pinctrl_exit(void) | 413 | static void __exit imx28_pinctrl_exit(void) |
414 | { | 414 | { |
diff --git a/drivers/pinctrl/pinctrl-imx51.c b/drivers/pinctrl/pinctrl-imx51.c index 689b3c88dd2e..9fd02162a3c2 100644 --- a/drivers/pinctrl/pinctrl-imx51.c +++ b/drivers/pinctrl/pinctrl-imx51.c | |||
@@ -974,7 +974,7 @@ static struct imx_pin_reg imx51_pin_regs[] = { | |||
974 | IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */ | 974 | IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */ |
975 | IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */ | 975 | IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */ |
976 | IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */ | 976 | IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */ |
977 | IMX_PIN_REG(MX51_PAD_SD2_CMD, NO_PAD, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */ | 977 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */ |
978 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */ | 978 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */ |
979 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */ | 979 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */ |
980 | IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */ | 980 | IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */ |
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index 6f99769c6733..a39fb7a6fc51 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c | |||
@@ -505,6 +505,8 @@ static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1, | |||
505 | DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1, | 505 | DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1, |
506 | DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2, | 506 | DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2, |
507 | DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 }; | 507 | DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 }; |
508 | static const unsigned kp_b_2_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1, | ||
509 | DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_F4, DB8500_PIN_E3}; | ||
508 | static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, | 510 | static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, |
509 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, | 511 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, |
510 | DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8, | 512 | DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8, |
@@ -662,6 +664,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { | |||
662 | DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), | 664 | DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), |
663 | DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), | 665 | DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), |
664 | DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), | 666 | DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), |
667 | DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B), | ||
665 | DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), | 668 | DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), |
666 | DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), | 669 | DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), |
667 | DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), | 670 | DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), |
@@ -751,7 +754,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1"); | |||
751 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); | 754 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); |
752 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", | 755 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", |
753 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); | 756 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); |
754 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1"); | 757 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); |
755 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); | 758 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); |
756 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); | 759 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); |
757 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); | 760 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); |
@@ -766,7 +769,7 @@ DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1", | |||
766 | DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); | 769 | DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); |
767 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); | 770 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); |
768 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1"); | 771 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1"); |
769 | DB8500_FUNC_GROUPS(hsi, "hsir1_a_1", "hsit1_a_1", "hsit_a_2"); | 772 | DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); |
770 | DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); | 773 | DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); |
771 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); | 774 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); |
772 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); | 775 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); |
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 53b0d49a7a1c..3dde6537adb8 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
@@ -1292,7 +1292,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
1292 | NOMADIK_GPIO_TO_IRQ(pdata->first_gpio), | 1292 | NOMADIK_GPIO_TO_IRQ(pdata->first_gpio), |
1293 | 0, &nmk_gpio_irq_simple_ops, nmk_chip); | 1293 | 0, &nmk_gpio_irq_simple_ops, nmk_chip); |
1294 | if (!nmk_chip->domain) { | 1294 | if (!nmk_chip->domain) { |
1295 | pr_err("%s: Failed to create irqdomain\n", np->full_name); | 1295 | dev_err(&dev->dev, "failed to create irqdomain\n"); |
1296 | ret = -ENOSYS; | 1296 | ret = -ENOSYS; |
1297 | goto out; | 1297 | goto out; |
1298 | } | 1298 | } |
@@ -1731,7 +1731,6 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1731 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { | 1731 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { |
1732 | if (!nmk_gpio_chips[i]) { | 1732 | if (!nmk_gpio_chips[i]) { |
1733 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | 1733 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); |
1734 | devm_kfree(&pdev->dev, npct); | ||
1735 | return -EPROBE_DEFER; | 1734 | return -EPROBE_DEFER; |
1736 | } | 1735 | } |
1737 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; | 1736 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 2aae8a8978e9..7fca6ce5952b 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
@@ -1217,7 +1217,6 @@ out_no_rsc_remap: | |||
1217 | iounmap(spmx->gpio_virtbase); | 1217 | iounmap(spmx->gpio_virtbase); |
1218 | out_no_gpio_remap: | 1218 | out_no_gpio_remap: |
1219 | platform_set_drvdata(pdev, NULL); | 1219 | platform_set_drvdata(pdev, NULL); |
1220 | devm_kfree(&pdev->dev, spmx); | ||
1221 | return ret; | 1220 | return ret; |
1222 | } | 1221 | } |
1223 | 1222 | ||
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index a7ad8c112d91..309f5b9a70ec 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c | |||
@@ -1121,10 +1121,8 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
1121 | upmx->dev = &pdev->dev; | 1121 | upmx->dev = &pdev->dev; |
1122 | 1122 | ||
1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1124 | if (!res) { | 1124 | if (!res) |
1125 | ret = -ENOENT; | 1125 | return -ENOENT; |
1126 | goto out_no_resource; | ||
1127 | } | ||
1128 | upmx->phybase = res->start; | 1126 | upmx->phybase = res->start; |
1129 | upmx->physize = resource_size(res); | 1127 | upmx->physize = resource_size(res); |
1130 | 1128 | ||
@@ -1165,8 +1163,6 @@ out_no_remap: | |||
1165 | platform_set_drvdata(pdev, NULL); | 1163 | platform_set_drvdata(pdev, NULL); |
1166 | out_no_memregion: | 1164 | out_no_memregion: |
1167 | release_mem_region(upmx->phybase, upmx->physize); | 1165 | release_mem_region(upmx->phybase, upmx->physize); |
1168 | out_no_resource: | ||
1169 | devm_kfree(&pdev->dev, upmx); | ||
1170 | return ret; | 1166 | return ret; |
1171 | } | 1167 | } |
1172 | 1168 | ||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2a262f5c5c0c..c86bae828c28 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -289,6 +289,7 @@ config IDEAPAD_LAPTOP | |||
289 | tristate "Lenovo IdeaPad Laptop Extras" | 289 | tristate "Lenovo IdeaPad Laptop Extras" |
290 | depends on ACPI | 290 | depends on ACPI |
291 | depends on RFKILL && INPUT | 291 | depends on RFKILL && INPUT |
292 | depends on SERIO_I8042 | ||
292 | select INPUT_SPARSEKMAP | 293 | select INPUT_SPARSEKMAP |
293 | help | 294 | help |
294 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. | 295 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. |
@@ -758,8 +759,11 @@ config SAMSUNG_Q10 | |||
758 | 759 | ||
759 | config APPLE_GMUX | 760 | config APPLE_GMUX |
760 | tristate "Apple Gmux Driver" | 761 | tristate "Apple Gmux Driver" |
762 | depends on ACPI | ||
761 | depends on PNP | 763 | depends on PNP |
762 | select BACKLIGHT_CLASS_DEVICE | 764 | depends on BACKLIGHT_CLASS_DEVICE |
765 | depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE | ||
766 | depends on ACPI_VIDEO=n || ACPI_VIDEO | ||
763 | ---help--- | 767 | ---help--- |
764 | This driver provides support for the gmux device found on many | 768 | This driver provides support for the gmux device found on many |
765 | Apple laptops, which controls the display mux for the hybrid | 769 | Apple laptops, which controls the display mux for the hybrid |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 3782e1cd3697..934d861a3235 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -2196,10 +2196,8 @@ static int __init acer_wmi_init(void) | |||
2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
2197 | pr_info("Brightness must be controlled by acpi video driver\n"); | 2197 | pr_info("Brightness must be controlled by acpi video driver\n"); |
2198 | } else { | 2198 | } else { |
2199 | #ifdef CONFIG_ACPI_VIDEO | ||
2200 | pr_info("Disabling ACPI video driver\n"); | 2199 | pr_info("Disabling ACPI video driver\n"); |
2201 | acpi_video_unregister(); | 2200 | acpi_video_unregister(); |
2202 | #endif | ||
2203 | } | 2201 | } |
2204 | 2202 | ||
2205 | if (wmi_has_guid(WMID_GUID3)) { | 2203 | if (wmi_has_guid(WMID_GUID3)) { |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 905fa01ac8df..db8f63841b42 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Gmux driver for Apple laptops | 2 | * Gmux driver for Apple laptops |
3 | * | 3 | * |
4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> | 4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> |
5 | * Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -18,16 +19,30 @@ | |||
18 | #include <linux/pnp.h> | 19 | #include <linux/pnp.h> |
19 | #include <linux/apple_bl.h> | 20 | #include <linux/apple_bl.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/vga_switcheroo.h> | ||
21 | #include <acpi/video.h> | 25 | #include <acpi/video.h> |
22 | #include <asm/io.h> | 26 | #include <asm/io.h> |
23 | 27 | ||
24 | struct apple_gmux_data { | 28 | struct apple_gmux_data { |
25 | unsigned long iostart; | 29 | unsigned long iostart; |
26 | unsigned long iolen; | 30 | unsigned long iolen; |
31 | bool indexed; | ||
32 | struct mutex index_lock; | ||
27 | 33 | ||
28 | struct backlight_device *bdev; | 34 | struct backlight_device *bdev; |
35 | |||
36 | /* switcheroo data */ | ||
37 | acpi_handle dhandle; | ||
38 | int gpe; | ||
39 | enum vga_switcheroo_client_id resume_client_id; | ||
40 | enum vga_switcheroo_state power_state; | ||
41 | struct completion powerchange_done; | ||
29 | }; | 42 | }; |
30 | 43 | ||
44 | static struct apple_gmux_data *apple_gmux_data; | ||
45 | |||
31 | /* | 46 | /* |
32 | * gmux port offsets. Many of these are not yet used, but may be in the | 47 | * gmux port offsets. Many of these are not yet used, but may be in the |
33 | * future, and it's useful to have them documented here anyhow. | 48 | * future, and it's useful to have them documented here anyhow. |
@@ -45,6 +60,9 @@ struct apple_gmux_data { | |||
45 | #define GMUX_PORT_DISCRETE_POWER 0x50 | 60 | #define GMUX_PORT_DISCRETE_POWER 0x50 |
46 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 | 61 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 |
47 | #define GMUX_PORT_BRIGHTNESS 0x74 | 62 | #define GMUX_PORT_BRIGHTNESS 0x74 |
63 | #define GMUX_PORT_VALUE 0xc2 | ||
64 | #define GMUX_PORT_READ 0xd0 | ||
65 | #define GMUX_PORT_WRITE 0xd4 | ||
48 | 66 | ||
49 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) | 67 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) |
50 | 68 | ||
@@ -59,22 +77,174 @@ struct apple_gmux_data { | |||
59 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff | 77 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff |
60 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK | 78 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK |
61 | 79 | ||
62 | static inline u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | 80 | static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) |
63 | { | 81 | { |
64 | return inb(gmux_data->iostart + port); | 82 | return inb(gmux_data->iostart + port); |
65 | } | 83 | } |
66 | 84 | ||
67 | static inline void gmux_write8(struct apple_gmux_data *gmux_data, int port, | 85 | static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port, |
68 | u8 val) | 86 | u8 val) |
69 | { | 87 | { |
70 | outb(val, gmux_data->iostart + port); | 88 | outb(val, gmux_data->iostart + port); |
71 | } | 89 | } |
72 | 90 | ||
73 | static inline u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | 91 | static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port) |
74 | { | 92 | { |
75 | return inl(gmux_data->iostart + port); | 93 | return inl(gmux_data->iostart + port); |
76 | } | 94 | } |
77 | 95 | ||
96 | static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, | ||
97 | u32 val) | ||
98 | { | ||
99 | int i; | ||
100 | u8 tmpval; | ||
101 | |||
102 | for (i = 0; i < 4; i++) { | ||
103 | tmpval = (val >> (i * 8)) & 0xff; | ||
104 | outb(tmpval, gmux_data->iostart + port + i); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data) | ||
109 | { | ||
110 | int i = 200; | ||
111 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
112 | |||
113 | while (i && (gwr & 0x01)) { | ||
114 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
115 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
116 | udelay(100); | ||
117 | i--; | ||
118 | } | ||
119 | |||
120 | return !!i; | ||
121 | } | ||
122 | |||
123 | static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data) | ||
124 | { | ||
125 | int i = 200; | ||
126 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
127 | |||
128 | while (i && !(gwr & 0x01)) { | ||
129 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
130 | udelay(100); | ||
131 | i--; | ||
132 | } | ||
133 | |||
134 | if (gwr & 0x01) | ||
135 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
136 | |||
137 | return !!i; | ||
138 | } | ||
139 | |||
140 | static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) | ||
141 | { | ||
142 | u8 val; | ||
143 | |||
144 | mutex_lock(&gmux_data->index_lock); | ||
145 | gmux_index_wait_ready(gmux_data); | ||
146 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
147 | gmux_index_wait_complete(gmux_data); | ||
148 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); | ||
149 | mutex_unlock(&gmux_data->index_lock); | ||
150 | |||
151 | return val; | ||
152 | } | ||
153 | |||
154 | static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port, | ||
155 | u8 val) | ||
156 | { | ||
157 | mutex_lock(&gmux_data->index_lock); | ||
158 | outb(val, gmux_data->iostart + GMUX_PORT_VALUE); | ||
159 | gmux_index_wait_ready(gmux_data); | ||
160 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
161 | gmux_index_wait_complete(gmux_data); | ||
162 | mutex_unlock(&gmux_data->index_lock); | ||
163 | } | ||
164 | |||
165 | static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) | ||
166 | { | ||
167 | u32 val; | ||
168 | |||
169 | mutex_lock(&gmux_data->index_lock); | ||
170 | gmux_index_wait_ready(gmux_data); | ||
171 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
172 | gmux_index_wait_complete(gmux_data); | ||
173 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); | ||
174 | mutex_unlock(&gmux_data->index_lock); | ||
175 | |||
176 | return val; | ||
177 | } | ||
178 | |||
179 | static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port, | ||
180 | u32 val) | ||
181 | { | ||
182 | int i; | ||
183 | u8 tmpval; | ||
184 | |||
185 | mutex_lock(&gmux_data->index_lock); | ||
186 | |||
187 | for (i = 0; i < 4; i++) { | ||
188 | tmpval = (val >> (i * 8)) & 0xff; | ||
189 | outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i); | ||
190 | } | ||
191 | |||
192 | gmux_index_wait_ready(gmux_data); | ||
193 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
194 | gmux_index_wait_complete(gmux_data); | ||
195 | mutex_unlock(&gmux_data->index_lock); | ||
196 | } | ||
197 | |||
198 | static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | ||
199 | { | ||
200 | if (gmux_data->indexed) | ||
201 | return gmux_index_read8(gmux_data, port); | ||
202 | else | ||
203 | return gmux_pio_read8(gmux_data, port); | ||
204 | } | ||
205 | |||
206 | static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val) | ||
207 | { | ||
208 | if (gmux_data->indexed) | ||
209 | gmux_index_write8(gmux_data, port, val); | ||
210 | else | ||
211 | gmux_pio_write8(gmux_data, port, val); | ||
212 | } | ||
213 | |||
214 | static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | ||
215 | { | ||
216 | if (gmux_data->indexed) | ||
217 | return gmux_index_read32(gmux_data, port); | ||
218 | else | ||
219 | return gmux_pio_read32(gmux_data, port); | ||
220 | } | ||
221 | |||
222 | static void gmux_write32(struct apple_gmux_data *gmux_data, int port, | ||
223 | u32 val) | ||
224 | { | ||
225 | if (gmux_data->indexed) | ||
226 | gmux_index_write32(gmux_data, port, val); | ||
227 | else | ||
228 | gmux_pio_write32(gmux_data, port, val); | ||
229 | } | ||
230 | |||
231 | static bool gmux_is_indexed(struct apple_gmux_data *gmux_data) | ||
232 | { | ||
233 | u16 val; | ||
234 | |||
235 | outb(0xaa, gmux_data->iostart + 0xcc); | ||
236 | outb(0x55, gmux_data->iostart + 0xcd); | ||
237 | outb(0x00, gmux_data->iostart + 0xce); | ||
238 | |||
239 | val = inb(gmux_data->iostart + 0xcc) | | ||
240 | (inb(gmux_data->iostart + 0xcd) << 8); | ||
241 | |||
242 | if (val == 0x55aa) | ||
243 | return true; | ||
244 | |||
245 | return false; | ||
246 | } | ||
247 | |||
78 | static int gmux_get_brightness(struct backlight_device *bd) | 248 | static int gmux_get_brightness(struct backlight_device *bd) |
79 | { | 249 | { |
80 | struct apple_gmux_data *gmux_data = bl_get_data(bd); | 250 | struct apple_gmux_data *gmux_data = bl_get_data(bd); |
@@ -90,16 +260,7 @@ static int gmux_update_status(struct backlight_device *bd) | |||
90 | if (bd->props.state & BL_CORE_SUSPENDED) | 260 | if (bd->props.state & BL_CORE_SUSPENDED) |
91 | return 0; | 261 | return 0; |
92 | 262 | ||
93 | /* | 263 | gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); |
94 | * Older gmux versions require writing out lower bytes first then | ||
95 | * setting the upper byte to 0 to flush the values. Newer versions | ||
96 | * accept a single u32 write, but the old method also works, so we | ||
97 | * just use the old method for all gmux versions. | ||
98 | */ | ||
99 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); | ||
100 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 1, brightness >> 8); | ||
101 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 2, brightness >> 16); | ||
102 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 3, 0); | ||
103 | 264 | ||
104 | return 0; | 265 | return 0; |
105 | } | 266 | } |
@@ -110,6 +271,146 @@ static const struct backlight_ops gmux_bl_ops = { | |||
110 | .update_status = gmux_update_status, | 271 | .update_status = gmux_update_status, |
111 | }; | 272 | }; |
112 | 273 | ||
274 | static int gmux_switchto(enum vga_switcheroo_client_id id) | ||
275 | { | ||
276 | if (id == VGA_SWITCHEROO_IGD) { | ||
277 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); | ||
278 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); | ||
279 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); | ||
280 | } else { | ||
281 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); | ||
282 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); | ||
283 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); | ||
284 | } | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, | ||
290 | enum vga_switcheroo_state state) | ||
291 | { | ||
292 | INIT_COMPLETION(gmux_data->powerchange_done); | ||
293 | |||
294 | if (state == VGA_SWITCHEROO_ON) { | ||
295 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
296 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); | ||
297 | pr_debug("Discrete card powered up\n"); | ||
298 | } else { | ||
299 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
300 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); | ||
301 | pr_debug("Discrete card powered down\n"); | ||
302 | } | ||
303 | |||
304 | gmux_data->power_state = state; | ||
305 | |||
306 | if (gmux_data->gpe >= 0 && | ||
307 | !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done, | ||
308 | msecs_to_jiffies(200))) | ||
309 | pr_warn("Timeout waiting for gmux switch to complete\n"); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static int gmux_set_power_state(enum vga_switcheroo_client_id id, | ||
315 | enum vga_switcheroo_state state) | ||
316 | { | ||
317 | if (id == VGA_SWITCHEROO_IGD) | ||
318 | return 0; | ||
319 | |||
320 | return gmux_set_discrete_state(apple_gmux_data, state); | ||
321 | } | ||
322 | |||
323 | static int gmux_get_client_id(struct pci_dev *pdev) | ||
324 | { | ||
325 | /* | ||
326 | * Early Macbook Pros with switchable graphics use nvidia | ||
327 | * integrated graphics. Hardcode that the 9400M is integrated. | ||
328 | */ | ||
329 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) | ||
330 | return VGA_SWITCHEROO_IGD; | ||
331 | else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && | ||
332 | pdev->device == 0x0863) | ||
333 | return VGA_SWITCHEROO_IGD; | ||
334 | else | ||
335 | return VGA_SWITCHEROO_DIS; | ||
336 | } | ||
337 | |||
338 | static enum vga_switcheroo_client_id | ||
339 | gmux_active_client(struct apple_gmux_data *gmux_data) | ||
340 | { | ||
341 | if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) | ||
342 | return VGA_SWITCHEROO_IGD; | ||
343 | |||
344 | return VGA_SWITCHEROO_DIS; | ||
345 | } | ||
346 | |||
347 | static struct vga_switcheroo_handler gmux_handler = { | ||
348 | .switchto = gmux_switchto, | ||
349 | .power_state = gmux_set_power_state, | ||
350 | .get_client_id = gmux_get_client_id, | ||
351 | }; | ||
352 | |||
353 | static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) | ||
354 | { | ||
355 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
356 | GMUX_INTERRUPT_DISABLE); | ||
357 | } | ||
358 | |||
359 | static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data) | ||
360 | { | ||
361 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
362 | GMUX_INTERRUPT_ENABLE); | ||
363 | } | ||
364 | |||
365 | static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data) | ||
366 | { | ||
367 | return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS); | ||
368 | } | ||
369 | |||
370 | static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data) | ||
371 | { | ||
372 | u8 status; | ||
373 | |||
374 | /* to clear interrupts write back current status */ | ||
375 | status = gmux_interrupt_get_status(gmux_data); | ||
376 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status); | ||
377 | } | ||
378 | |||
379 | static void gmux_notify_handler(acpi_handle device, u32 value, void *context) | ||
380 | { | ||
381 | u8 status; | ||
382 | struct pnp_dev *pnp = (struct pnp_dev *)context; | ||
383 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
384 | |||
385 | status = gmux_interrupt_get_status(gmux_data); | ||
386 | gmux_disable_interrupts(gmux_data); | ||
387 | pr_debug("Notify handler called: status %d\n", status); | ||
388 | |||
389 | gmux_clear_interrupts(gmux_data); | ||
390 | gmux_enable_interrupts(gmux_data); | ||
391 | |||
392 | if (status & GMUX_INTERRUPT_STATUS_POWER) | ||
393 | complete(&gmux_data->powerchange_done); | ||
394 | } | ||
395 | |||
396 | static int gmux_suspend(struct pnp_dev *pnp, pm_message_t state) | ||
397 | { | ||
398 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
399 | gmux_data->resume_client_id = gmux_active_client(gmux_data); | ||
400 | gmux_disable_interrupts(gmux_data); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static int gmux_resume(struct pnp_dev *pnp) | ||
405 | { | ||
406 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
407 | gmux_enable_interrupts(gmux_data); | ||
408 | gmux_switchto(gmux_data->resume_client_id); | ||
409 | if (gmux_data->power_state == VGA_SWITCHEROO_OFF) | ||
410 | gmux_set_discrete_state(gmux_data, gmux_data->power_state); | ||
411 | return 0; | ||
412 | } | ||
413 | |||
113 | static int __devinit gmux_probe(struct pnp_dev *pnp, | 414 | static int __devinit gmux_probe(struct pnp_dev *pnp, |
114 | const struct pnp_device_id *id) | 415 | const struct pnp_device_id *id) |
115 | { | 416 | { |
@@ -119,6 +420,11 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
119 | struct backlight_device *bdev; | 420 | struct backlight_device *bdev; |
120 | u8 ver_major, ver_minor, ver_release; | 421 | u8 ver_major, ver_minor, ver_release; |
121 | int ret = -ENXIO; | 422 | int ret = -ENXIO; |
423 | acpi_status status; | ||
424 | unsigned long long gpe; | ||
425 | |||
426 | if (apple_gmux_data) | ||
427 | return -EBUSY; | ||
122 | 428 | ||
123 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); | 429 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); |
124 | if (!gmux_data) | 430 | if (!gmux_data) |
@@ -147,21 +453,32 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
147 | } | 453 | } |
148 | 454 | ||
149 | /* | 455 | /* |
150 | * On some machines the gmux is in ACPI even thought the machine | 456 | * Invalid version information may indicate either that the gmux |
151 | * doesn't really have a gmux. Check for invalid version information | 457 | * device isn't present or that it's a new one that uses indexed |
152 | * to detect this. | 458 | * io |
153 | */ | 459 | */ |
460 | |||
154 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); | 461 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); |
155 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); | 462 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); |
156 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); | 463 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); |
157 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { | 464 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { |
158 | pr_info("gmux device not present\n"); | 465 | if (gmux_is_indexed(gmux_data)) { |
159 | ret = -ENODEV; | 466 | u32 version; |
160 | goto err_release; | 467 | mutex_init(&gmux_data->index_lock); |
468 | gmux_data->indexed = true; | ||
469 | version = gmux_read32(gmux_data, | ||
470 | GMUX_PORT_VERSION_MAJOR); | ||
471 | ver_major = (version >> 24) & 0xff; | ||
472 | ver_minor = (version >> 16) & 0xff; | ||
473 | ver_release = (version >> 8) & 0xff; | ||
474 | } else { | ||
475 | pr_info("gmux device not present\n"); | ||
476 | ret = -ENODEV; | ||
477 | goto err_release; | ||
478 | } | ||
161 | } | 479 | } |
162 | 480 | pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, | |
163 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | 481 | ver_release, (gmux_data->indexed ? "indexed" : "classic")); |
164 | ver_release); | ||
165 | 482 | ||
166 | memset(&props, 0, sizeof(props)); | 483 | memset(&props, 0, sizeof(props)); |
167 | props.type = BACKLIGHT_PLATFORM; | 484 | props.type = BACKLIGHT_PLATFORM; |
@@ -194,13 +511,65 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
194 | * Disable the other backlight choices. | 511 | * Disable the other backlight choices. |
195 | */ | 512 | */ |
196 | acpi_video_dmi_promote_vendor(); | 513 | acpi_video_dmi_promote_vendor(); |
197 | #ifdef CONFIG_ACPI_VIDEO | ||
198 | acpi_video_unregister(); | 514 | acpi_video_unregister(); |
199 | #endif | ||
200 | apple_bl_unregister(); | 515 | apple_bl_unregister(); |
201 | 516 | ||
517 | gmux_data->power_state = VGA_SWITCHEROO_ON; | ||
518 | |||
519 | gmux_data->dhandle = DEVICE_ACPI_HANDLE(&pnp->dev); | ||
520 | if (!gmux_data->dhandle) { | ||
521 | pr_err("Cannot find acpi handle for pnp device %s\n", | ||
522 | dev_name(&pnp->dev)); | ||
523 | ret = -ENODEV; | ||
524 | goto err_notify; | ||
525 | } | ||
526 | |||
527 | status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe); | ||
528 | if (ACPI_SUCCESS(status)) { | ||
529 | gmux_data->gpe = (int)gpe; | ||
530 | |||
531 | status = acpi_install_notify_handler(gmux_data->dhandle, | ||
532 | ACPI_DEVICE_NOTIFY, | ||
533 | &gmux_notify_handler, pnp); | ||
534 | if (ACPI_FAILURE(status)) { | ||
535 | pr_err("Install notify handler failed: %s\n", | ||
536 | acpi_format_exception(status)); | ||
537 | ret = -ENODEV; | ||
538 | goto err_notify; | ||
539 | } | ||
540 | |||
541 | status = acpi_enable_gpe(NULL, gmux_data->gpe); | ||
542 | if (ACPI_FAILURE(status)) { | ||
543 | pr_err("Cannot enable gpe: %s\n", | ||
544 | acpi_format_exception(status)); | ||
545 | goto err_enable_gpe; | ||
546 | } | ||
547 | } else { | ||
548 | pr_warn("No GPE found for gmux\n"); | ||
549 | gmux_data->gpe = -1; | ||
550 | } | ||
551 | |||
552 | if (vga_switcheroo_register_handler(&gmux_handler)) { | ||
553 | ret = -ENODEV; | ||
554 | goto err_register_handler; | ||
555 | } | ||
556 | |||
557 | init_completion(&gmux_data->powerchange_done); | ||
558 | apple_gmux_data = gmux_data; | ||
559 | gmux_enable_interrupts(gmux_data); | ||
560 | |||
202 | return 0; | 561 | return 0; |
203 | 562 | ||
563 | err_register_handler: | ||
564 | if (gmux_data->gpe >= 0) | ||
565 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
566 | err_enable_gpe: | ||
567 | if (gmux_data->gpe >= 0) | ||
568 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
569 | ACPI_DEVICE_NOTIFY, | ||
570 | &gmux_notify_handler); | ||
571 | err_notify: | ||
572 | backlight_device_unregister(bdev); | ||
204 | err_release: | 573 | err_release: |
205 | release_region(gmux_data->iostart, gmux_data->iolen); | 574 | release_region(gmux_data->iostart, gmux_data->iolen); |
206 | err_free: | 575 | err_free: |
@@ -212,14 +581,23 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
212 | { | 581 | { |
213 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | 582 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); |
214 | 583 | ||
584 | vga_switcheroo_unregister_handler(); | ||
585 | gmux_disable_interrupts(gmux_data); | ||
586 | if (gmux_data->gpe >= 0) { | ||
587 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
588 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
589 | ACPI_DEVICE_NOTIFY, | ||
590 | &gmux_notify_handler); | ||
591 | } | ||
592 | |||
215 | backlight_device_unregister(gmux_data->bdev); | 593 | backlight_device_unregister(gmux_data->bdev); |
594 | |||
216 | release_region(gmux_data->iostart, gmux_data->iolen); | 595 | release_region(gmux_data->iostart, gmux_data->iolen); |
596 | apple_gmux_data = NULL; | ||
217 | kfree(gmux_data); | 597 | kfree(gmux_data); |
218 | 598 | ||
219 | acpi_video_dmi_demote_vendor(); | 599 | acpi_video_dmi_demote_vendor(); |
220 | #ifdef CONFIG_ACPI_VIDEO | ||
221 | acpi_video_register(); | 600 | acpi_video_register(); |
222 | #endif | ||
223 | apple_bl_register(); | 601 | apple_bl_register(); |
224 | } | 602 | } |
225 | 603 | ||
@@ -233,6 +611,8 @@ static struct pnp_driver gmux_pnp_driver = { | |||
233 | .probe = gmux_probe, | 611 | .probe = gmux_probe, |
234 | .remove = __devexit_p(gmux_remove), | 612 | .remove = __devexit_p(gmux_remove), |
235 | .id_table = gmux_device_ids, | 613 | .id_table = gmux_device_ids, |
614 | .suspend = gmux_suspend, | ||
615 | .resume = gmux_resume | ||
236 | }; | 616 | }; |
237 | 617 | ||
238 | static int __init apple_gmux_init(void) | 618 | static int __init apple_gmux_init(void) |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e38f91be0b10..4b568df56643 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -85,7 +85,7 @@ static char *wled_type = "unknown"; | |||
85 | static char *bled_type = "unknown"; | 85 | static char *bled_type = "unknown"; |
86 | 86 | ||
87 | module_param(wled_type, charp, 0444); | 87 | module_param(wled_type, charp, 0444); |
88 | MODULE_PARM_DESC(wlan_status, "Set the wled type on boot " | 88 | MODULE_PARM_DESC(wled_type, "Set the wled type on boot " |
89 | "(unknown, led or rfkill). " | 89 | "(unknown, led or rfkill). " |
90 | "default is unknown"); | 90 | "default is unknown"); |
91 | 91 | ||
@@ -863,9 +863,9 @@ static ssize_t show_infos(struct device *dev, | |||
863 | * The significance of others is yet to be found. | 863 | * The significance of others is yet to be found. |
864 | * If we don't find the method, we assume the device are present. | 864 | * If we don't find the method, we assume the device are present. |
865 | */ | 865 | */ |
866 | rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); | 866 | rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); |
867 | if (!ACPI_FAILURE(rv)) | 867 | if (!ACPI_FAILURE(rv)) |
868 | len += sprintf(page + len, "HRWS value : %#x\n", | 868 | len += sprintf(page + len, "HWRS value : %#x\n", |
869 | (uint) temp); | 869 | (uint) temp); |
870 | /* | 870 | /* |
871 | * Another value for userspace: the ASYM method returns 0x02 for | 871 | * Another value for userspace: the ASYM method returns 0x02 for |
@@ -1751,9 +1751,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1751 | * The significance of others is yet to be found. | 1751 | * The significance of others is yet to be found. |
1752 | */ | 1752 | */ |
1753 | status = | 1753 | status = |
1754 | acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); | 1754 | acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); |
1755 | if (!ACPI_FAILURE(status)) | 1755 | if (!ACPI_FAILURE(status)) |
1756 | pr_notice(" HRWS returned %x", (int)hwrs_result); | 1756 | pr_notice(" HWRS returned %x", (int)hwrs_result); |
1757 | 1757 | ||
1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) | 1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) |
1759 | asus->have_rsts = true; | 1759 | asus->have_rsts = true; |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index c7a36f6b0580..c0e9ff489b24 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -47,9 +47,7 @@ | |||
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
49 | #include <acpi/acpi_drivers.h> | 49 | #include <acpi/acpi_drivers.h> |
50 | #ifdef CONFIG_ACPI_VIDEO | ||
51 | #include <acpi/video.h> | 50 | #include <acpi/video.h> |
52 | #endif | ||
53 | 51 | ||
54 | #include "asus-wmi.h" | 52 | #include "asus-wmi.h" |
55 | 53 | ||
@@ -101,6 +99,7 @@ MODULE_LICENSE("GPL"); | |||
101 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 | 99 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 |
102 | #define ASUS_WMI_DEVID_CWAP 0x00010003 | 100 | #define ASUS_WMI_DEVID_CWAP 0x00010003 |
103 | #define ASUS_WMI_DEVID_WLAN 0x00010011 | 101 | #define ASUS_WMI_DEVID_WLAN 0x00010011 |
102 | #define ASUS_WMI_DEVID_WLAN_LED 0x00010012 | ||
104 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 | 103 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 |
105 | #define ASUS_WMI_DEVID_GPS 0x00010015 | 104 | #define ASUS_WMI_DEVID_GPS 0x00010015 |
106 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 | 105 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 |
@@ -731,8 +730,21 @@ static int asus_rfkill_set(void *data, bool blocked) | |||
731 | { | 730 | { |
732 | struct asus_rfkill *priv = data; | 731 | struct asus_rfkill *priv = data; |
733 | u32 ctrl_param = !blocked; | 732 | u32 ctrl_param = !blocked; |
733 | u32 dev_id = priv->dev_id; | ||
734 | 734 | ||
735 | return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL); | 735 | /* |
736 | * If the user bit is set, BIOS can't set and record the wlan status, | ||
737 | * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED | ||
738 | * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN). | ||
739 | * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED | ||
740 | * while setting the wlan status through WMI. | ||
741 | * This is also the behavior that windows app will do. | ||
742 | */ | ||
743 | if ((dev_id == ASUS_WMI_DEVID_WLAN) && | ||
744 | priv->asus->driver->wlan_ctrl_by_user) | ||
745 | dev_id = ASUS_WMI_DEVID_WLAN_LED; | ||
746 | |||
747 | return asus_wmi_set_devstate(dev_id, ctrl_param, NULL); | ||
736 | } | 748 | } |
737 | 749 | ||
738 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) | 750 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) |
@@ -1653,6 +1665,7 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1653 | struct asus_wmi *asus; | 1665 | struct asus_wmi *asus; |
1654 | acpi_status status; | 1666 | acpi_status status; |
1655 | int err; | 1667 | int err; |
1668 | u32 result; | ||
1656 | 1669 | ||
1657 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); | 1670 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); |
1658 | if (!asus) | 1671 | if (!asus) |
@@ -1689,10 +1702,8 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1689 | if (asus->driver->quirks->wmi_backlight_power) | 1702 | if (asus->driver->quirks->wmi_backlight_power) |
1690 | acpi_video_dmi_promote_vendor(); | 1703 | acpi_video_dmi_promote_vendor(); |
1691 | if (!acpi_video_backlight_support()) { | 1704 | if (!acpi_video_backlight_support()) { |
1692 | #ifdef CONFIG_ACPI_VIDEO | ||
1693 | pr_info("Disabling ACPI video driver\n"); | 1705 | pr_info("Disabling ACPI video driver\n"); |
1694 | acpi_video_unregister(); | 1706 | acpi_video_unregister(); |
1695 | #endif | ||
1696 | err = asus_wmi_backlight_init(asus); | 1707 | err = asus_wmi_backlight_init(asus); |
1697 | if (err && err != -ENODEV) | 1708 | if (err && err != -ENODEV) |
1698 | goto fail_backlight; | 1709 | goto fail_backlight; |
@@ -1711,6 +1722,10 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1711 | if (err) | 1722 | if (err) |
1712 | goto fail_debugfs; | 1723 | goto fail_debugfs; |
1713 | 1724 | ||
1725 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
1726 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
1727 | asus->driver->wlan_ctrl_by_user = 1; | ||
1728 | |||
1714 | return 0; | 1729 | return 0; |
1715 | 1730 | ||
1716 | fail_debugfs: | 1731 | fail_debugfs: |
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 9c1da8b81bea..4c9bd38bb0a2 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h | |||
@@ -46,6 +46,7 @@ struct quirk_entry { | |||
46 | struct asus_wmi_driver { | 46 | struct asus_wmi_driver { |
47 | int brightness; | 47 | int brightness; |
48 | int panel_power; | 48 | int panel_power; |
49 | int wlan_ctrl_by_user; | ||
49 | 50 | ||
50 | const char *name; | 51 | const char *name; |
51 | struct module *owner; | 52 | struct module *owner; |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 2ca7dd1ab3e4..c87ff16873f9 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -350,6 +350,7 @@ static void cmpc_accel_idev_init_v4(struct input_dev *inputdev) | |||
350 | inputdev->close = cmpc_accel_close_v4; | 350 | inputdev->close = cmpc_accel_close_v4; |
351 | } | 351 | } |
352 | 352 | ||
353 | #ifdef CONFIG_PM_SLEEP | ||
353 | static int cmpc_accel_suspend_v4(struct device *dev) | 354 | static int cmpc_accel_suspend_v4(struct device *dev) |
354 | { | 355 | { |
355 | struct input_dev *inputdev; | 356 | struct input_dev *inputdev; |
@@ -384,6 +385,7 @@ static int cmpc_accel_resume_v4(struct device *dev) | |||
384 | 385 | ||
385 | return 0; | 386 | return 0; |
386 | } | 387 | } |
388 | #endif | ||
387 | 389 | ||
388 | static int cmpc_accel_add_v4(struct acpi_device *acpi) | 390 | static int cmpc_accel_add_v4(struct acpi_device *acpi) |
389 | { | 391 | { |
@@ -723,8 +725,10 @@ static void cmpc_tablet_handler(struct acpi_device *dev, u32 event) | |||
723 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | 725 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); |
724 | 726 | ||
725 | if (event == 0x81) { | 727 | if (event == 0x81) { |
726 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) | 728 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) { |
727 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 729 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
730 | input_sync(inputdev); | ||
731 | } | ||
728 | } | 732 | } |
729 | } | 733 | } |
730 | 734 | ||
@@ -737,8 +741,10 @@ static void cmpc_tablet_idev_init(struct input_dev *inputdev) | |||
737 | set_bit(SW_TABLET_MODE, inputdev->swbit); | 741 | set_bit(SW_TABLET_MODE, inputdev->swbit); |
738 | 742 | ||
739 | acpi = to_acpi_device(inputdev->dev.parent); | 743 | acpi = to_acpi_device(inputdev->dev.parent); |
740 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) | 744 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) { |
741 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 745 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
746 | input_sync(inputdev); | ||
747 | } | ||
742 | } | 748 | } |
743 | 749 | ||
744 | static int cmpc_tablet_add(struct acpi_device *acpi) | 750 | static int cmpc_tablet_add(struct acpi_device *acpi) |
@@ -752,15 +758,19 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type) | |||
752 | return cmpc_remove_acpi_notify_device(acpi); | 758 | return cmpc_remove_acpi_notify_device(acpi); |
753 | } | 759 | } |
754 | 760 | ||
761 | #ifdef CONFIG_PM_SLEEP | ||
755 | static int cmpc_tablet_resume(struct device *dev) | 762 | static int cmpc_tablet_resume(struct device *dev) |
756 | { | 763 | { |
757 | struct input_dev *inputdev = dev_get_drvdata(dev); | 764 | struct input_dev *inputdev = dev_get_drvdata(dev); |
758 | 765 | ||
759 | unsigned long long val = 0; | 766 | unsigned long long val = 0; |
760 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) | 767 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) { |
761 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 768 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
769 | input_sync(inputdev); | ||
770 | } | ||
762 | return 0; | 771 | return 0; |
763 | } | 772 | } |
773 | #endif | ||
764 | 774 | ||
765 | static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); | 775 | static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); |
766 | 776 | ||
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 4e96e8c0b60f..927c33af67ec 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -211,7 +211,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
211 | .ident = "Dell Inspiron 5420", | 211 | .ident = "Dell Inspiron 5420", |
212 | .matches = { | 212 | .matches = { |
213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
214 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5420"), | 214 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"), |
215 | }, | 215 | }, |
216 | .driver_data = &quirk_dell_vostro_v130, | 216 | .driver_data = &quirk_dell_vostro_v130, |
217 | }, | 217 | }, |
@@ -220,7 +220,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
220 | .ident = "Dell Inspiron 5520", | 220 | .ident = "Dell Inspiron 5520", |
221 | .matches = { | 221 | .matches = { |
222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
223 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5520"), | 223 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"), |
224 | }, | 224 | }, |
225 | .driver_data = &quirk_dell_vostro_v130, | 225 | .driver_data = &quirk_dell_vostro_v130, |
226 | }, | 226 | }, |
@@ -229,7 +229,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
229 | .ident = "Dell Inspiron 5720", | 229 | .ident = "Dell Inspiron 5720", |
230 | .matches = { | 230 | .matches = { |
231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
232 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5720"), | 232 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"), |
233 | }, | 233 | }, |
234 | .driver_data = &quirk_dell_vostro_v130, | 234 | .driver_data = &quirk_dell_vostro_v130, |
235 | }, | 235 | }, |
@@ -238,7 +238,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
238 | .ident = "Dell Inspiron 7420", | 238 | .ident = "Dell Inspiron 7420", |
239 | .matches = { | 239 | .matches = { |
240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
241 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7420"), | 241 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"), |
242 | }, | 242 | }, |
243 | .driver_data = &quirk_dell_vostro_v130, | 243 | .driver_data = &quirk_dell_vostro_v130, |
244 | }, | 244 | }, |
@@ -247,7 +247,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
247 | .ident = "Dell Inspiron 7520", | 247 | .ident = "Dell Inspiron 7520", |
248 | .matches = { | 248 | .matches = { |
249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
250 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7520"), | 250 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), |
251 | }, | 251 | }, |
252 | .driver_data = &quirk_dell_vostro_v130, | 252 | .driver_data = &quirk_dell_vostro_v130, |
253 | }, | 253 | }, |
@@ -256,7 +256,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
256 | .ident = "Dell Inspiron 7720", | 256 | .ident = "Dell Inspiron 7720", |
257 | .matches = { | 257 | .matches = { |
258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
259 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7720"), | 259 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"), |
260 | }, | 260 | }, |
261 | .driver_data = &quirk_dell_vostro_v130, | 261 | .driver_data = &quirk_dell_vostro_v130, |
262 | }, | 262 | }, |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dab91b48d22c..5ca264179f4e 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -610,12 +610,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
610 | 610 | ||
611 | if (!bus) { | 611 | if (!bus) { |
612 | pr_warn("Unable to find PCI bus 1?\n"); | 612 | pr_warn("Unable to find PCI bus 1?\n"); |
613 | goto out_unlock; | 613 | goto out_put_dev; |
614 | } | 614 | } |
615 | 615 | ||
616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { | 616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { |
617 | pr_err("Unable to read PCI config space?\n"); | 617 | pr_err("Unable to read PCI config space?\n"); |
618 | goto out_unlock; | 618 | goto out_put_dev; |
619 | } | 619 | } |
620 | 620 | ||
621 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
@@ -627,7 +627,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
627 | absent ? "absent" : "present"); | 627 | absent ? "absent" : "present"); |
628 | pr_warn("skipped wireless hotplug as probably " | 628 | pr_warn("skipped wireless hotplug as probably " |
629 | "inappropriate for this model\n"); | 629 | "inappropriate for this model\n"); |
630 | goto out_unlock; | 630 | goto out_put_dev; |
631 | } | 631 | } |
632 | 632 | ||
633 | if (!blocked) { | 633 | if (!blocked) { |
@@ -635,7 +635,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
635 | if (dev) { | 635 | if (dev) { |
636 | /* Device already present */ | 636 | /* Device already present */ |
637 | pci_dev_put(dev); | 637 | pci_dev_put(dev); |
638 | goto out_unlock; | 638 | goto out_put_dev; |
639 | } | 639 | } |
640 | dev = pci_scan_single_device(bus, 0); | 640 | dev = pci_scan_single_device(bus, 0); |
641 | if (dev) { | 641 | if (dev) { |
@@ -650,6 +650,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
650 | pci_dev_put(dev); | 650 | pci_dev_put(dev); |
651 | } | 651 | } |
652 | } | 652 | } |
653 | out_put_dev: | ||
654 | pci_dev_put(port); | ||
653 | } | 655 | } |
654 | 656 | ||
655 | out_unlock: | 657 | out_unlock: |
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index d2e41735a47b..7acae3f85f3b 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -440,11 +440,13 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) | |||
440 | return 0; | 440 | return 0; |
441 | } | 441 | } |
442 | 442 | ||
443 | #ifdef CONFIG_PM_SLEEP | ||
443 | static int acpi_fujitsu_resume(struct device *dev) | 444 | static int acpi_fujitsu_resume(struct device *dev) |
444 | { | 445 | { |
445 | fujitsu_reset(); | 446 | fujitsu_reset(); |
446 | return 0; | 447 | return 0; |
447 | } | 448 | } |
449 | #endif | ||
448 | 450 | ||
449 | static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); | 451 | static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); |
450 | 452 | ||
diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index d9ab6f64dcec..777c7e3dda51 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c | |||
@@ -305,10 +305,12 @@ static int hdaps_probe(struct platform_device *dev) | |||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | #ifdef CONFIG_PM_SLEEP | ||
308 | static int hdaps_resume(struct device *dev) | 309 | static int hdaps_resume(struct device *dev) |
309 | { | 310 | { |
310 | return hdaps_device_init(); | 311 | return hdaps_device_init(); |
311 | } | 312 | } |
313 | #endif | ||
312 | 314 | ||
313 | static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); | 315 | static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); |
314 | 316 | ||
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index f4d91154ad67..6b9af989632b 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -352,7 +352,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
352 | } | 352 | } |
353 | 353 | ||
354 | 354 | ||
355 | #ifdef CONFIG_PM | 355 | #ifdef CONFIG_PM_SLEEP |
356 | static int lis3lv02d_suspend(struct device *dev) | 356 | static int lis3lv02d_suspend(struct device *dev) |
357 | { | 357 | { |
358 | /* make sure the device is off when we suspend */ | 358 | /* make sure the device is off when we suspend */ |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 17f6dfd8dbfb..dae7abe1d711 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/fb.h> | 36 | #include <linux/fb.h> |
37 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/i8042.h> | ||
39 | 40 | ||
40 | #define IDEAPAD_RFKILL_DEV_NUM (3) | 41 | #define IDEAPAD_RFKILL_DEV_NUM (3) |
41 | 42 | ||
@@ -63,8 +64,11 @@ enum { | |||
63 | VPCCMD_R_3G, | 64 | VPCCMD_R_3G, |
64 | VPCCMD_W_3G, | 65 | VPCCMD_W_3G, |
65 | VPCCMD_R_ODD, /* 0x21 */ | 66 | VPCCMD_R_ODD, /* 0x21 */ |
66 | VPCCMD_R_RF = 0x23, | 67 | VPCCMD_W_FAN, |
68 | VPCCMD_R_RF, | ||
67 | VPCCMD_W_RF, | 69 | VPCCMD_W_RF, |
70 | VPCCMD_R_FAN = 0x2B, | ||
71 | VPCCMD_R_SPECIAL_BUTTONS = 0x31, | ||
68 | VPCCMD_W_BL_POWER = 0x33, | 72 | VPCCMD_W_BL_POWER = 0x33, |
69 | }; | 73 | }; |
70 | 74 | ||
@@ -356,14 +360,46 @@ static ssize_t store_ideapad_cam(struct device *dev, | |||
356 | return -EINVAL; | 360 | return -EINVAL; |
357 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); | 361 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); |
358 | if (ret < 0) | 362 | if (ret < 0) |
359 | return ret; | 363 | return -EIO; |
360 | return count; | 364 | return count; |
361 | } | 365 | } |
362 | 366 | ||
363 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); | 367 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); |
364 | 368 | ||
369 | static ssize_t show_ideapad_fan(struct device *dev, | ||
370 | struct device_attribute *attr, | ||
371 | char *buf) | ||
372 | { | ||
373 | unsigned long result; | ||
374 | |||
375 | if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) | ||
376 | return sprintf(buf, "-1\n"); | ||
377 | return sprintf(buf, "%lu\n", result); | ||
378 | } | ||
379 | |||
380 | static ssize_t store_ideapad_fan(struct device *dev, | ||
381 | struct device_attribute *attr, | ||
382 | const char *buf, size_t count) | ||
383 | { | ||
384 | int ret, state; | ||
385 | |||
386 | if (!count) | ||
387 | return 0; | ||
388 | if (sscanf(buf, "%i", &state) != 1) | ||
389 | return -EINVAL; | ||
390 | if (state < 0 || state > 4 || state == 3) | ||
391 | return -EINVAL; | ||
392 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); | ||
393 | if (ret < 0) | ||
394 | return -EIO; | ||
395 | return count; | ||
396 | } | ||
397 | |||
398 | static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan); | ||
399 | |||
365 | static struct attribute *ideapad_attributes[] = { | 400 | static struct attribute *ideapad_attributes[] = { |
366 | &dev_attr_camera_power.attr, | 401 | &dev_attr_camera_power.attr, |
402 | &dev_attr_fan_mode.attr, | ||
367 | NULL | 403 | NULL |
368 | }; | 404 | }; |
369 | 405 | ||
@@ -377,7 +413,10 @@ static umode_t ideapad_is_visible(struct kobject *kobj, | |||
377 | 413 | ||
378 | if (attr == &dev_attr_camera_power.attr) | 414 | if (attr == &dev_attr_camera_power.attr) |
379 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); | 415 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); |
380 | else | 416 | else if (attr == &dev_attr_fan_mode.attr) { |
417 | unsigned long value; | ||
418 | supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); | ||
419 | } else | ||
381 | supported = true; | 420 | supported = true; |
382 | 421 | ||
383 | return supported ? attr->mode : 0; | 422 | return supported ? attr->mode : 0; |
@@ -518,9 +557,15 @@ static void ideapad_platform_exit(struct ideapad_private *priv) | |||
518 | */ | 557 | */ |
519 | static const struct key_entry ideapad_keymap[] = { | 558 | static const struct key_entry ideapad_keymap[] = { |
520 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, | 559 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, |
560 | { KE_KEY, 7, { KEY_CAMERA } }, | ||
561 | { KE_KEY, 11, { KEY_F16 } }, | ||
521 | { KE_KEY, 13, { KEY_WLAN } }, | 562 | { KE_KEY, 13, { KEY_WLAN } }, |
522 | { KE_KEY, 16, { KEY_PROG1 } }, | 563 | { KE_KEY, 16, { KEY_PROG1 } }, |
523 | { KE_KEY, 17, { KEY_PROG2 } }, | 564 | { KE_KEY, 17, { KEY_PROG2 } }, |
565 | { KE_KEY, 64, { KEY_PROG3 } }, | ||
566 | { KE_KEY, 65, { KEY_PROG4 } }, | ||
567 | { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, | ||
568 | { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, | ||
524 | { KE_END, 0 }, | 569 | { KE_END, 0 }, |
525 | }; | 570 | }; |
526 | 571 | ||
@@ -587,6 +632,28 @@ static void ideapad_input_novokey(struct ideapad_private *priv) | |||
587 | ideapad_input_report(priv, 16); | 632 | ideapad_input_report(priv, 16); |
588 | } | 633 | } |
589 | 634 | ||
635 | static void ideapad_check_special_buttons(struct ideapad_private *priv) | ||
636 | { | ||
637 | unsigned long bit, value; | ||
638 | |||
639 | read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); | ||
640 | |||
641 | for (bit = 0; bit < 16; bit++) { | ||
642 | if (test_bit(bit, &value)) { | ||
643 | switch (bit) { | ||
644 | case 6: | ||
645 | /* Thermal Management button */ | ||
646 | ideapad_input_report(priv, 65); | ||
647 | break; | ||
648 | case 1: | ||
649 | /* OneKey Theater button */ | ||
650 | ideapad_input_report(priv, 64); | ||
651 | break; | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | } | ||
656 | |||
590 | /* | 657 | /* |
591 | * backlight | 658 | * backlight |
592 | */ | 659 | */ |
@@ -691,6 +758,24 @@ static const struct acpi_device_id ideapad_device_ids[] = { | |||
691 | }; | 758 | }; |
692 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); | 759 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); |
693 | 760 | ||
761 | static void ideapad_sync_touchpad_state(struct acpi_device *adevice) | ||
762 | { | ||
763 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
764 | unsigned long value; | ||
765 | |||
766 | /* Without reading from EC touchpad LED doesn't switch state */ | ||
767 | if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { | ||
768 | /* Some IdeaPads don't really turn off touchpad - they only | ||
769 | * switch the LED state. We (de)activate KBC AUX port to turn | ||
770 | * touchpad off and on. We send KEY_TOUCHPAD_OFF and | ||
771 | * KEY_TOUCHPAD_ON to not to get out of sync with LED */ | ||
772 | unsigned char param; | ||
773 | i8042_command(¶m, value ? I8042_CMD_AUX_ENABLE : | ||
774 | I8042_CMD_AUX_DISABLE); | ||
775 | ideapad_input_report(priv, value ? 67 : 66); | ||
776 | } | ||
777 | } | ||
778 | |||
694 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | 779 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) |
695 | { | 780 | { |
696 | int ret, i; | 781 | int ret, i; |
@@ -727,6 +812,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | |||
727 | priv->rfk[i] = NULL; | 812 | priv->rfk[i] = NULL; |
728 | } | 813 | } |
729 | ideapad_sync_rfk_state(priv); | 814 | ideapad_sync_rfk_state(priv); |
815 | ideapad_sync_touchpad_state(adevice); | ||
730 | 816 | ||
731 | if (!acpi_video_backlight_support()) { | 817 | if (!acpi_video_backlight_support()) { |
732 | ret = ideapad_backlight_init(priv); | 818 | ret = ideapad_backlight_init(priv); |
@@ -785,9 +871,14 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
785 | ideapad_sync_rfk_state(priv); | 871 | ideapad_sync_rfk_state(priv); |
786 | break; | 872 | break; |
787 | case 13: | 873 | case 13: |
874 | case 11: | ||
875 | case 7: | ||
788 | case 6: | 876 | case 6: |
789 | ideapad_input_report(priv, vpc_bit); | 877 | ideapad_input_report(priv, vpc_bit); |
790 | break; | 878 | break; |
879 | case 5: | ||
880 | ideapad_sync_touchpad_state(adevice); | ||
881 | break; | ||
791 | case 4: | 882 | case 4: |
792 | ideapad_backlight_notify_brightness(priv); | 883 | ideapad_backlight_notify_brightness(priv); |
793 | break; | 884 | break; |
@@ -797,6 +888,9 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
797 | case 2: | 888 | case 2: |
798 | ideapad_backlight_notify_power(priv); | 889 | ideapad_backlight_notify_power(priv); |
799 | break; | 890 | break; |
891 | case 0: | ||
892 | ideapad_check_special_buttons(priv); | ||
893 | break; | ||
800 | default: | 894 | default: |
801 | pr_info("Unknown event: %lu\n", vpc_bit); | 895 | pr_info("Unknown event: %lu\n", vpc_bit); |
802 | } | 896 | } |
@@ -804,6 +898,15 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
804 | } | 898 | } |
805 | } | 899 | } |
806 | 900 | ||
901 | static int ideapad_acpi_resume(struct device *device) | ||
902 | { | ||
903 | ideapad_sync_rfk_state(ideapad_priv); | ||
904 | ideapad_sync_touchpad_state(to_acpi_device(device)); | ||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); | ||
909 | |||
807 | static struct acpi_driver ideapad_acpi_driver = { | 910 | static struct acpi_driver ideapad_acpi_driver = { |
808 | .name = "ideapad_acpi", | 911 | .name = "ideapad_acpi", |
809 | .class = "IdeaPad", | 912 | .class = "IdeaPad", |
@@ -811,6 +914,7 @@ static struct acpi_driver ideapad_acpi_driver = { | |||
811 | .ops.add = ideapad_acpi_add, | 914 | .ops.add = ideapad_acpi_add, |
812 | .ops.remove = ideapad_acpi_remove, | 915 | .ops.remove = ideapad_acpi_remove, |
813 | .ops.notify = ideapad_acpi_notify, | 916 | .ops.notify = ideapad_acpi_notify, |
917 | .drv.pm = &ideapad_pm, | ||
814 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
815 | }; | 919 | }; |
816 | 920 | ||
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index f64441844317..2111dbb7e1e3 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -85,7 +85,9 @@ | |||
85 | #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 | 85 | #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 |
86 | #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) | 86 | #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) |
87 | 87 | ||
88 | #ifdef CONFIG_PM_SLEEP | ||
88 | static int msi_laptop_resume(struct device *device); | 89 | static int msi_laptop_resume(struct device *device); |
90 | #endif | ||
89 | static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); | 91 | static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); |
90 | 92 | ||
91 | #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f | 93 | #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f |
@@ -753,6 +755,7 @@ err_bluetooth: | |||
753 | return retval; | 755 | return retval; |
754 | } | 756 | } |
755 | 757 | ||
758 | #ifdef CONFIG_PM_SLEEP | ||
756 | static int msi_laptop_resume(struct device *device) | 759 | static int msi_laptop_resume(struct device *device) |
757 | { | 760 | { |
758 | u8 data; | 761 | u8 data; |
@@ -773,6 +776,7 @@ static int msi_laptop_resume(struct device *device) | |||
773 | 776 | ||
774 | return 0; | 777 | return 0; |
775 | } | 778 | } |
779 | #endif | ||
776 | 780 | ||
777 | static int __init msi_laptop_input_setup(void) | 781 | static int __init msi_laptop_input_setup(void) |
778 | { | 782 | { |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 24480074bcf0..8e8caa767d6a 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -188,7 +188,9 @@ static const struct acpi_device_id pcc_device_ids[] = { | |||
188 | }; | 188 | }; |
189 | MODULE_DEVICE_TABLE(acpi, pcc_device_ids); | 189 | MODULE_DEVICE_TABLE(acpi, pcc_device_ids); |
190 | 190 | ||
191 | #ifdef CONFIG_PM_SLEEP | ||
191 | static int acpi_pcc_hotkey_resume(struct device *dev); | 192 | static int acpi_pcc_hotkey_resume(struct device *dev); |
193 | #endif | ||
192 | static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); | 194 | static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); |
193 | 195 | ||
194 | static struct acpi_driver acpi_pcc_driver = { | 196 | static struct acpi_driver acpi_pcc_driver = { |
@@ -540,6 +542,7 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) | |||
540 | 542 | ||
541 | /* kernel module interface */ | 543 | /* kernel module interface */ |
542 | 544 | ||
545 | #ifdef CONFIG_PM_SLEEP | ||
543 | static int acpi_pcc_hotkey_resume(struct device *dev) | 546 | static int acpi_pcc_hotkey_resume(struct device *dev) |
544 | { | 547 | { |
545 | struct pcc_acpi *pcc; | 548 | struct pcc_acpi *pcc; |
@@ -556,6 +559,7 @@ static int acpi_pcc_hotkey_resume(struct device *dev) | |||
556 | 559 | ||
557 | return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); | 560 | return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); |
558 | } | 561 | } |
562 | #endif | ||
559 | 563 | ||
560 | static int acpi_pcc_hotkey_add(struct acpi_device *device) | 564 | static int acpi_pcc_hotkey_add(struct acpi_device *device) |
561 | { | 565 | { |
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c1ca7bcebb66..dd90d15f5210 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
@@ -26,9 +26,7 @@ | |||
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #ifdef CONFIG_ACPI_VIDEO | ||
30 | #include <acpi/video.h> | 29 | #include <acpi/video.h> |
31 | #endif | ||
32 | 30 | ||
33 | /* | 31 | /* |
34 | * This driver is needed because a number of Samsung laptops do not hook | 32 | * This driver is needed because a number of Samsung laptops do not hook |
@@ -1558,9 +1556,7 @@ static int __init samsung_init(void) | |||
1558 | samsung->handle_backlight = false; | 1556 | samsung->handle_backlight = false; |
1559 | } else if (samsung->quirks->broken_acpi_video) { | 1557 | } else if (samsung->quirks->broken_acpi_video) { |
1560 | pr_info("Disabling ACPI video driver\n"); | 1558 | pr_info("Disabling ACPI video driver\n"); |
1561 | #ifdef CONFIG_ACPI_VIDEO | ||
1562 | acpi_video_unregister(); | 1559 | acpi_video_unregister(); |
1563 | #endif | ||
1564 | } | 1560 | } |
1565 | #endif | 1561 | #endif |
1566 | 1562 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 9363969ad07a..daaddec68def 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -140,7 +140,10 @@ MODULE_PARM_DESC(kbd_backlight_timeout, | |||
140 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " | 140 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " |
141 | "(default: 0)"); | 141 | "(default: 0)"); |
142 | 142 | ||
143 | #ifdef CONFIG_PM_SLEEP | ||
143 | static void sony_nc_kbd_backlight_resume(void); | 144 | static void sony_nc_kbd_backlight_resume(void); |
145 | static void sony_nc_thermal_resume(void); | ||
146 | #endif | ||
144 | static int sony_nc_kbd_backlight_setup(struct platform_device *pd, | 147 | static int sony_nc_kbd_backlight_setup(struct platform_device *pd, |
145 | unsigned int handle); | 148 | unsigned int handle); |
146 | static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); | 149 | static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); |
@@ -151,7 +154,6 @@ static void sony_nc_battery_care_cleanup(struct platform_device *pd); | |||
151 | 154 | ||
152 | static int sony_nc_thermal_setup(struct platform_device *pd); | 155 | static int sony_nc_thermal_setup(struct platform_device *pd); |
153 | static void sony_nc_thermal_cleanup(struct platform_device *pd); | 156 | static void sony_nc_thermal_cleanup(struct platform_device *pd); |
154 | static void sony_nc_thermal_resume(void); | ||
155 | 157 | ||
156 | static int sony_nc_lid_resume_setup(struct platform_device *pd); | 158 | static int sony_nc_lid_resume_setup(struct platform_device *pd); |
157 | static void sony_nc_lid_resume_cleanup(struct platform_device *pd); | 159 | static void sony_nc_lid_resume_cleanup(struct platform_device *pd); |
@@ -1431,6 +1433,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd) | |||
1431 | sony_nc_handles_cleanup(pd); | 1433 | sony_nc_handles_cleanup(pd); |
1432 | } | 1434 | } |
1433 | 1435 | ||
1436 | #ifdef CONFIG_PM_SLEEP | ||
1434 | static void sony_nc_function_resume(void) | 1437 | static void sony_nc_function_resume(void) |
1435 | { | 1438 | { |
1436 | unsigned int i, result, bitmask, arg; | 1439 | unsigned int i, result, bitmask, arg; |
@@ -1508,6 +1511,7 @@ static int sony_nc_resume(struct device *dev) | |||
1508 | 1511 | ||
1509 | return 0; | 1512 | return 0; |
1510 | } | 1513 | } |
1514 | #endif | ||
1511 | 1515 | ||
1512 | static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); | 1516 | static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); |
1513 | 1517 | ||
@@ -1872,6 +1876,7 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd) | |||
1872 | } | 1876 | } |
1873 | } | 1877 | } |
1874 | 1878 | ||
1879 | #ifdef CONFIG_PM_SLEEP | ||
1875 | static void sony_nc_kbd_backlight_resume(void) | 1880 | static void sony_nc_kbd_backlight_resume(void) |
1876 | { | 1881 | { |
1877 | int ignore = 0; | 1882 | int ignore = 0; |
@@ -1888,6 +1893,7 @@ static void sony_nc_kbd_backlight_resume(void) | |||
1888 | (kbdbl_ctl->base + 0x200) | | 1893 | (kbdbl_ctl->base + 0x200) | |
1889 | (kbdbl_ctl->timeout << 0x10), &ignore); | 1894 | (kbdbl_ctl->timeout << 0x10), &ignore); |
1890 | } | 1895 | } |
1896 | #endif | ||
1891 | 1897 | ||
1892 | struct battery_care_control { | 1898 | struct battery_care_control { |
1893 | struct device_attribute attrs[2]; | 1899 | struct device_attribute attrs[2]; |
@@ -2210,6 +2216,7 @@ static void sony_nc_thermal_cleanup(struct platform_device *pd) | |||
2210 | } | 2216 | } |
2211 | } | 2217 | } |
2212 | 2218 | ||
2219 | #ifdef CONFIG_PM_SLEEP | ||
2213 | static void sony_nc_thermal_resume(void) | 2220 | static void sony_nc_thermal_resume(void) |
2214 | { | 2221 | { |
2215 | unsigned int status = sony_nc_thermal_mode_get(); | 2222 | unsigned int status = sony_nc_thermal_mode_get(); |
@@ -2217,6 +2224,7 @@ static void sony_nc_thermal_resume(void) | |||
2217 | if (status != th_handle->mode) | 2224 | if (status != th_handle->mode) |
2218 | sony_nc_thermal_mode_set(th_handle->mode); | 2225 | sony_nc_thermal_mode_set(th_handle->mode); |
2219 | } | 2226 | } |
2227 | #endif | ||
2220 | 2228 | ||
2221 | /* resume on LID open */ | 2229 | /* resume on LID open */ |
2222 | struct snc_lid_resume_control { | 2230 | struct snc_lid_resume_control { |
@@ -4287,6 +4295,7 @@ err_free_resources: | |||
4287 | return result; | 4295 | return result; |
4288 | } | 4296 | } |
4289 | 4297 | ||
4298 | #ifdef CONFIG_PM_SLEEP | ||
4290 | static int sony_pic_suspend(struct device *dev) | 4299 | static int sony_pic_suspend(struct device *dev) |
4291 | { | 4300 | { |
4292 | if (sony_pic_disable(to_acpi_device(dev))) | 4301 | if (sony_pic_disable(to_acpi_device(dev))) |
@@ -4300,6 +4309,7 @@ static int sony_pic_resume(struct device *dev) | |||
4300 | spic_dev.cur_ioport, spic_dev.cur_irq); | 4309 | spic_dev.cur_ioport, spic_dev.cur_irq); |
4301 | return 0; | 4310 | return 0; |
4302 | } | 4311 | } |
4312 | #endif | ||
4303 | 4313 | ||
4304 | static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); | 4314 | static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); |
4305 | 4315 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e7f73287636c..52daaa816e53 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -545,7 +545,7 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ | |||
545 | */ | 545 | */ |
546 | 546 | ||
547 | static int acpi_evalf(acpi_handle handle, | 547 | static int acpi_evalf(acpi_handle handle, |
548 | void *res, char *method, char *fmt, ...) | 548 | int *res, char *method, char *fmt, ...) |
549 | { | 549 | { |
550 | char *fmt0 = fmt; | 550 | char *fmt0 = fmt; |
551 | struct acpi_object_list params; | 551 | struct acpi_object_list params; |
@@ -606,7 +606,7 @@ static int acpi_evalf(acpi_handle handle, | |||
606 | success = (status == AE_OK && | 606 | success = (status == AE_OK && |
607 | out_obj.type == ACPI_TYPE_INTEGER); | 607 | out_obj.type == ACPI_TYPE_INTEGER); |
608 | if (success && res) | 608 | if (success && res) |
609 | *(int *)res = out_obj.integer.value; | 609 | *res = out_obj.integer.value; |
610 | break; | 610 | break; |
611 | case 'v': /* void */ | 611 | case 'v': /* void */ |
612 | success = status == AE_OK; | 612 | success = status == AE_OK; |
@@ -922,6 +922,7 @@ static struct input_dev *tpacpi_inputdev; | |||
922 | static struct mutex tpacpi_inputdev_send_mutex; | 922 | static struct mutex tpacpi_inputdev_send_mutex; |
923 | static LIST_HEAD(tpacpi_all_drivers); | 923 | static LIST_HEAD(tpacpi_all_drivers); |
924 | 924 | ||
925 | #ifdef CONFIG_PM_SLEEP | ||
925 | static int tpacpi_suspend_handler(struct device *dev) | 926 | static int tpacpi_suspend_handler(struct device *dev) |
926 | { | 927 | { |
927 | struct ibm_struct *ibm, *itmp; | 928 | struct ibm_struct *ibm, *itmp; |
@@ -949,6 +950,7 @@ static int tpacpi_resume_handler(struct device *dev) | |||
949 | 950 | ||
950 | return 0; | 951 | return 0; |
951 | } | 952 | } |
953 | #endif | ||
952 | 954 | ||
953 | static SIMPLE_DEV_PM_OPS(tpacpi_pm, | 955 | static SIMPLE_DEV_PM_OPS(tpacpi_pm, |
954 | tpacpi_suspend_handler, tpacpi_resume_handler); | 956 | tpacpi_suspend_handler, tpacpi_resume_handler); |
@@ -7384,17 +7386,18 @@ static int fan_get_status(u8 *status) | |||
7384 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ | 7386 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ |
7385 | 7387 | ||
7386 | switch (fan_status_access_mode) { | 7388 | switch (fan_status_access_mode) { |
7387 | case TPACPI_FAN_RD_ACPI_GFAN: | 7389 | case TPACPI_FAN_RD_ACPI_GFAN: { |
7388 | /* 570, 600e/x, 770e, 770x */ | 7390 | /* 570, 600e/x, 770e, 770x */ |
7391 | int res; | ||
7389 | 7392 | ||
7390 | if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) | 7393 | if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d"))) |
7391 | return -EIO; | 7394 | return -EIO; |
7392 | 7395 | ||
7393 | if (likely(status)) | 7396 | if (likely(status)) |
7394 | *status = s & 0x07; | 7397 | *status = res & 0x07; |
7395 | 7398 | ||
7396 | break; | 7399 | break; |
7397 | 7400 | } | |
7398 | case TPACPI_FAN_RD_TPEC: | 7401 | case TPACPI_FAN_RD_TPEC: |
7399 | /* all except 570, 600e/x, 770e, 770x */ | 7402 | /* all except 570, 600e/x, 770e, 770x */ |
7400 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) | 7403 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) |
@@ -8662,6 +8665,13 @@ static int __must_check __init get_thinkpad_model_data( | |||
8662 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8665 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8663 | if (!tp->model_str) | 8666 | if (!tp->model_str) |
8664 | return -ENOMEM; | 8667 | return -ENOMEM; |
8668 | } else { | ||
8669 | s = dmi_get_system_info(DMI_BIOS_VENDOR); | ||
8670 | if (s && !(strnicmp(s, "Lenovo", 6))) { | ||
8671 | tp->model_str = kstrdup(s, GFP_KERNEL); | ||
8672 | if (!tp->model_str) | ||
8673 | return -ENOMEM; | ||
8674 | } | ||
8665 | } | 8675 | } |
8666 | 8676 | ||
8667 | s = dmi_get_system_info(DMI_PRODUCT_NAME); | 8677 | s = dmi_get_system_info(DMI_PRODUCT_NAME); |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c13ba5bac93f..5f1256d5e933 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -1296,6 +1296,7 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
1296 | } | 1296 | } |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | #ifdef CONFIG_PM_SLEEP | ||
1299 | static int toshiba_acpi_suspend(struct device *device) | 1300 | static int toshiba_acpi_suspend(struct device *device) |
1300 | { | 1301 | { |
1301 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); | 1302 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); |
@@ -1317,6 +1318,7 @@ static int toshiba_acpi_resume(struct device *device) | |||
1317 | 1318 | ||
1318 | return 0; | 1319 | return 0; |
1319 | } | 1320 | } |
1321 | #endif | ||
1320 | 1322 | ||
1321 | static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, | 1323 | static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, |
1322 | toshiba_acpi_suspend, toshiba_acpi_resume); | 1324 | toshiba_acpi_suspend, toshiba_acpi_resume); |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 715a43cb5e3c..5e5d6317d690 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -41,7 +41,9 @@ static const struct acpi_device_id bt_device_ids[] = { | |||
41 | }; | 41 | }; |
42 | MODULE_DEVICE_TABLE(acpi, bt_device_ids); | 42 | MODULE_DEVICE_TABLE(acpi, bt_device_ids); |
43 | 43 | ||
44 | #ifdef CONFIG_PM_SLEEP | ||
44 | static int toshiba_bt_resume(struct device *dev); | 45 | static int toshiba_bt_resume(struct device *dev); |
46 | #endif | ||
45 | static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); | 47 | static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); |
46 | 48 | ||
47 | static struct acpi_driver toshiba_bt_rfkill_driver = { | 49 | static struct acpi_driver toshiba_bt_rfkill_driver = { |
@@ -90,10 +92,12 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) | |||
90 | toshiba_bluetooth_enable(device->handle); | 92 | toshiba_bluetooth_enable(device->handle); |
91 | } | 93 | } |
92 | 94 | ||
95 | #ifdef CONFIG_PM_SLEEP | ||
93 | static int toshiba_bt_resume(struct device *dev) | 96 | static int toshiba_bt_resume(struct device *dev) |
94 | { | 97 | { |
95 | return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); | 98 | return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); |
96 | } | 99 | } |
100 | #endif | ||
97 | 101 | ||
98 | static int toshiba_bt_rfkill_add(struct acpi_device *device) | 102 | static int toshiba_bt_rfkill_add(struct acpi_device *device) |
99 | { | 103 | { |
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 849c07c13bf6..38ba39d7ca7d 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -77,10 +77,12 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event) | |||
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | #ifdef CONFIG_PM_SLEEP | ||
80 | static int ebook_switch_resume(struct device *dev) | 81 | static int ebook_switch_resume(struct device *dev) |
81 | { | 82 | { |
82 | return ebook_send_state(to_acpi_device(dev)); | 83 | return ebook_send_state(to_acpi_device(dev)); |
83 | } | 84 | } |
85 | #endif | ||
84 | 86 | ||
85 | static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); | 87 | static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); |
86 | 88 | ||
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 8fc3808d7a3e..90c5c7357a50 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig | |||
@@ -1,12 +1,31 @@ | |||
1 | menuconfig PWM | 1 | menuconfig PWM |
2 | bool "PWM Support" | 2 | bool "Pulse-Width Modulation (PWM) Support" |
3 | depends on !MACH_JZ4740 && !PUV3_PWM | 3 | depends on !MACH_JZ4740 && !PUV3_PWM |
4 | help | 4 | help |
5 | This enables PWM support through the generic PWM framework. | 5 | Generic Pulse-Width Modulation (PWM) support. |
6 | You only need to enable this, if you also want to enable | 6 | |
7 | one or more of the PWM drivers below. | 7 | In Pulse-Width Modulation, a variation of the width of pulses |
8 | 8 | in a rectangular pulse signal is used as a means to alter the | |
9 | If unsure, say N. | 9 | average power of the signal. Applications include efficient |
10 | power delivery and voltage regulation. In computer systems, | ||
11 | PWMs are commonly used to control fans or the brightness of | ||
12 | display backlights. | ||
13 | |||
14 | This framework provides a generic interface to PWM devices | ||
15 | within the Linux kernel. On the driver side it provides an API | ||
16 | to register and unregister a PWM chip, an abstraction of a PWM | ||
17 | controller, that supports one or more PWM devices. Client | ||
18 | drivers can request PWM devices and use the generic framework | ||
19 | to configure as well as enable and disable them. | ||
20 | |||
21 | This generic framework replaces the legacy PWM framework which | ||
22 | allows only a single driver implementing the required API. Not | ||
23 | all legacy implementations have been ported to the framework | ||
24 | yet. The framework provides an API that is backward compatible | ||
25 | with the legacy framework so that existing client drivers | ||
26 | continue to work as expected. | ||
27 | |||
28 | If unsure, say no. | ||
10 | 29 | ||
11 | if PWM | 30 | if PWM |
12 | 31 | ||
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index ecb76909e946..c6e05078d3ad 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c | |||
@@ -129,8 +129,8 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label) | |||
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc, | 132 | static struct pwm_device * |
133 | const struct of_phandle_args *args) | 133 | of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) |
134 | { | 134 | { |
135 | struct pwm_device *pwm; | 135 | struct pwm_device *pwm; |
136 | 136 | ||
@@ -149,7 +149,7 @@ static struct pwm_device *of_pwm_simple_xlate(struct pwm_chip *pc, | |||
149 | return pwm; | 149 | return pwm; |
150 | } | 150 | } |
151 | 151 | ||
152 | void of_pwmchip_add(struct pwm_chip *chip) | 152 | static void of_pwmchip_add(struct pwm_chip *chip) |
153 | { | 153 | { |
154 | if (!chip->dev || !chip->dev->of_node) | 154 | if (!chip->dev || !chip->dev->of_node) |
155 | return; | 155 | return; |
@@ -162,7 +162,7 @@ void of_pwmchip_add(struct pwm_chip *chip) | |||
162 | of_node_get(chip->dev->of_node); | 162 | of_node_get(chip->dev->of_node); |
163 | } | 163 | } |
164 | 164 | ||
165 | void of_pwmchip_remove(struct pwm_chip *chip) | 165 | static void of_pwmchip_remove(struct pwm_chip *chip) |
166 | { | 166 | { |
167 | if (chip->dev && chip->dev->of_node) | 167 | if (chip->dev && chip->dev->of_node) |
168 | of_node_put(chip->dev->of_node); | 168 | of_node_put(chip->dev->of_node); |
@@ -527,7 +527,7 @@ void __init pwm_add_table(struct pwm_lookup *table, size_t num) | |||
527 | struct pwm_device *pwm_get(struct device *dev, const char *con_id) | 527 | struct pwm_device *pwm_get(struct device *dev, const char *con_id) |
528 | { | 528 | { |
529 | struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER); | 529 | struct pwm_device *pwm = ERR_PTR(-EPROBE_DEFER); |
530 | const char *dev_id = dev ? dev_name(dev): NULL; | 530 | const char *dev_id = dev ? dev_name(dev) : NULL; |
531 | struct pwm_chip *chip = NULL; | 531 | struct pwm_chip *chip = NULL; |
532 | unsigned int index = 0; | 532 | unsigned int index = 0; |
533 | unsigned int best = 0; | 533 | unsigned int best = 0; |
@@ -609,7 +609,7 @@ void pwm_put(struct pwm_device *pwm) | |||
609 | mutex_lock(&pwm_lock); | 609 | mutex_lock(&pwm_lock); |
610 | 610 | ||
611 | if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) { | 611 | if (!test_and_clear_bit(PWMF_REQUESTED, &pwm->flags)) { |
612 | pr_warning("PWM device already freed\n"); | 612 | pr_warn("PWM device already freed\n"); |
613 | goto out; | 613 | goto out; |
614 | } | 614 | } |
615 | 615 | ||
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c index d10386528c9c..e5187c0ade9f 100644 --- a/drivers/pwm/pwm-samsung.c +++ b/drivers/pwm/pwm-samsung.c | |||
@@ -225,6 +225,7 @@ static int s3c_pwm_probe(struct platform_device *pdev) | |||
225 | 225 | ||
226 | /* calculate base of control bits in TCON */ | 226 | /* calculate base of control bits in TCON */ |
227 | s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4; | 227 | s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4; |
228 | s3c->chip.dev = &pdev->dev; | ||
228 | s3c->chip.ops = &s3c_pwm_ops; | 229 | s3c->chip.ops = &s3c_pwm_ops; |
229 | s3c->chip.base = -1; | 230 | s3c->chip.base = -1; |
230 | s3c->chip.npwm = 1; | 231 | s3c->chip.npwm = 1; |
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 02ce18d5e49a..057465e0553c 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c | |||
@@ -187,10 +187,8 @@ static int tegra_pwm_probe(struct platform_device *pdev) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | pwm->mmio_base = devm_request_and_ioremap(&pdev->dev, r); | 189 | pwm->mmio_base = devm_request_and_ioremap(&pdev->dev, r); |
190 | if (!pwm->mmio_base) { | 190 | if (!pwm->mmio_base) |
191 | dev_err(&pdev->dev, "failed to ioremap() region\n"); | ||
192 | return -EADDRNOTAVAIL; | 191 | return -EADDRNOTAVAIL; |
193 | } | ||
194 | 192 | ||
195 | platform_set_drvdata(pdev, pwm); | 193 | platform_set_drvdata(pdev, pwm); |
196 | 194 | ||
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 3c2ad284ee3e..4b6688909fee 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c | |||
@@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
100 | writel(period_cycles, pc->mmio_base + CAP3); | 100 | writel(period_cycles, pc->mmio_base + CAP3); |
101 | } | 101 | } |
102 | 102 | ||
103 | if (!test_bit(PWMF_ENABLED, &pwm->flags)) { | ||
104 | reg_val = readw(pc->mmio_base + ECCTL2); | ||
105 | /* Disable APWM mode to put APWM output Low */ | ||
106 | reg_val &= ~ECCTL2_APWM_MODE; | ||
107 | writew(reg_val, pc->mmio_base + ECCTL2); | ||
108 | } | ||
109 | |||
103 | pm_runtime_put_sync(pc->chip.dev); | 110 | pm_runtime_put_sync(pc->chip.dev); |
104 | return 0; | 111 | return 0; |
105 | } | 112 | } |
@@ -192,10 +199,8 @@ static int __devinit ecap_pwm_probe(struct platform_device *pdev) | |||
192 | } | 199 | } |
193 | 200 | ||
194 | pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); | 201 | pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); |
195 | if (!pc->mmio_base) { | 202 | if (!pc->mmio_base) |
196 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
197 | return -EADDRNOTAVAIL; | 203 | return -EADDRNOTAVAIL; |
198 | } | ||
199 | 204 | ||
200 | ret = pwmchip_add(&pc->chip); | 205 | ret = pwmchip_add(&pc->chip); |
201 | if (ret < 0) { | 206 | if (ret < 0) { |
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 010d232cb0c8..b1996bcd5b78 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
@@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip { | |||
104 | struct pwm_chip chip; | 104 | struct pwm_chip chip; |
105 | unsigned int clk_rate; | 105 | unsigned int clk_rate; |
106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
107 | unsigned long period_cycles[NUM_PWM_CHANNEL]; | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) | 110 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) |
@@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
210 | unsigned long long c; | 211 | unsigned long long c; |
211 | unsigned long period_cycles, duty_cycles; | 212 | unsigned long period_cycles, duty_cycles; |
212 | unsigned short ps_divval, tb_divval; | 213 | unsigned short ps_divval, tb_divval; |
214 | int i; | ||
213 | 215 | ||
214 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) | 216 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) |
215 | return -ERANGE; | 217 | return -ERANGE; |
@@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
229 | duty_cycles = (unsigned long)c; | 231 | duty_cycles = (unsigned long)c; |
230 | } | 232 | } |
231 | 233 | ||
234 | /* | ||
235 | * Period values should be same for multiple PWM channels as IP uses | ||
236 | * same period register for multiple channels. | ||
237 | */ | ||
238 | for (i = 0; i < NUM_PWM_CHANNEL; i++) { | ||
239 | if (pc->period_cycles[i] && | ||
240 | (pc->period_cycles[i] != period_cycles)) { | ||
241 | /* | ||
242 | * Allow channel to reconfigure period if no other | ||
243 | * channels being configured. | ||
244 | */ | ||
245 | if (i == pwm->hwpwm) | ||
246 | continue; | ||
247 | |||
248 | dev_err(chip->dev, "Period value conflicts with channel %d\n", | ||
249 | i); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | pc->period_cycles[pwm->hwpwm] = period_cycles; | ||
255 | |||
232 | /* Configure clock prescaler to support Low frequency PWM wave */ | 256 | /* Configure clock prescaler to support Low frequency PWM wave */ |
233 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, | 257 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, |
234 | &tb_divval)) { | 258 | &tb_divval)) { |
@@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
320 | 344 | ||
321 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | 345 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
322 | { | 346 | { |
347 | struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); | ||
348 | |||
323 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { | 349 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { |
324 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); | 350 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); |
325 | pm_runtime_put_sync(chip->dev); | 351 | pm_runtime_put_sync(chip->dev); |
326 | } | 352 | } |
353 | |||
354 | /* set period value to zero on free */ | ||
355 | pc->period_cycles[pwm->hwpwm] = 0; | ||
327 | } | 356 | } |
328 | 357 | ||
329 | static const struct pwm_ops ehrpwm_pwm_ops = { | 358 | static const struct pwm_ops ehrpwm_pwm_ops = { |
@@ -371,10 +400,8 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) | |||
371 | } | 400 | } |
372 | 401 | ||
373 | pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); | 402 | pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); |
374 | if (!pc->mmio_base) { | 403 | if (!pc->mmio_base) |
375 | dev_err(&pdev->dev, "failed to ioremap() registers\n"); | ||
376 | return -EADDRNOTAVAIL; | 404 | return -EADDRNOTAVAIL; |
377 | } | ||
378 | 405 | ||
379 | ret = pwmchip_add(&pc->chip); | 406 | ret = pwmchip_add(&pc->chip); |
380 | if (ret < 0) { | 407 | if (ret < 0) { |
diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c index 548021439f0c..ad14389b7144 100644 --- a/drivers/pwm/pwm-vt8500.c +++ b/drivers/pwm/pwm-vt8500.c | |||
@@ -41,7 +41,7 @@ static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask) | |||
41 | cpu_relax(); | 41 | cpu_relax(); |
42 | 42 | ||
43 | if (unlikely(!loops)) | 43 | if (unlikely(!loops)) |
44 | pr_warning("Waiting for status bits 0x%x to clear timed out\n", | 44 | pr_warn("Waiting for status bits 0x%x to clear timed out\n", |
45 | bitmask); | 45 | bitmask); |
46 | } | 46 | } |
47 | 47 | ||
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 722246cf20ab..5d44252b7342 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -435,6 +435,9 @@ static void tsi721_db_dpc(struct work_struct *work) | |||
435 | " info %4.4x\n", DBELL_SID(idb.bytes), | 435 | " info %4.4x\n", DBELL_SID(idb.bytes), |
436 | DBELL_TID(idb.bytes), DBELL_INF(idb.bytes)); | 436 | DBELL_TID(idb.bytes), DBELL_INF(idb.bytes)); |
437 | } | 437 | } |
438 | |||
439 | wr_ptr = ioread32(priv->regs + | ||
440 | TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; | ||
438 | } | 441 | } |
439 | 442 | ||
440 | iowrite32(rd_ptr & (IDB_QSIZE - 1), | 443 | iowrite32(rd_ptr & (IDB_QSIZE - 1), |
@@ -445,6 +448,10 @@ static void tsi721_db_dpc(struct work_struct *work) | |||
445 | regval |= TSI721_SR_CHINT_IDBQRCV; | 448 | regval |= TSI721_SR_CHINT_IDBQRCV; |
446 | iowrite32(regval, | 449 | iowrite32(regval, |
447 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); | 450 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); |
451 | |||
452 | wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; | ||
453 | if (wr_ptr != rd_ptr) | ||
454 | schedule_work(&priv->idb_work); | ||
448 | } | 455 | } |
449 | 456 | ||
450 | /** | 457 | /** |
@@ -2212,7 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2212 | const struct pci_device_id *id) | 2219 | const struct pci_device_id *id) |
2213 | { | 2220 | { |
2214 | struct tsi721_device *priv; | 2221 | struct tsi721_device *priv; |
2215 | int i, cap; | 2222 | int cap; |
2216 | int err; | 2223 | int err; |
2217 | u32 regval; | 2224 | u32 regval; |
2218 | 2225 | ||
@@ -2232,12 +2239,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2232 | priv->pdev = pdev; | 2239 | priv->pdev = pdev; |
2233 | 2240 | ||
2234 | #ifdef DEBUG | 2241 | #ifdef DEBUG |
2242 | { | ||
2243 | int i; | ||
2235 | for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { | 2244 | for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { |
2236 | dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n", | 2245 | dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n", |
2237 | i, (unsigned long long)pci_resource_start(pdev, i), | 2246 | i, (unsigned long long)pci_resource_start(pdev, i), |
2238 | (unsigned long)pci_resource_len(pdev, i), | 2247 | (unsigned long)pci_resource_len(pdev, i), |
2239 | pci_resource_flags(pdev, i)); | 2248 | pci_resource_flags(pdev, i)); |
2240 | } | 2249 | } |
2250 | } | ||
2241 | #endif | 2251 | #endif |
2242 | /* | 2252 | /* |
2243 | * Verify BAR configuration | 2253 | * Verify BAR configuration |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 182b553059c9..c151fd5d8c97 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -486,6 +486,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { | |||
486 | .id = AB3100_BUCK, | 486 | .id = AB3100_BUCK, |
487 | .ops = ®ulator_ops_variable_sleepable, | 487 | .ops = ®ulator_ops_variable_sleepable, |
488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), | 488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), |
489 | .volt_table = ldo_e_buck_typ_voltages, | ||
489 | .type = REGULATOR_VOLTAGE, | 490 | .type = REGULATOR_VOLTAGE, |
490 | .owner = THIS_MODULE, | 491 | .owner = THIS_MODULE, |
491 | .enable_time = 1000, | 492 | .enable_time = 1000, |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..ce0fe72a428e 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -64,14 +64,15 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) | |||
64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) | 64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) |
65 | { | 65 | { |
66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
67 | u32 val; | 67 | u32 val, mask; |
68 | 68 | ||
69 | if (!anatop_reg->control_reg) | 69 | if (!anatop_reg->control_reg) |
70 | return -ENOTSUPP; | 70 | return -ENOTSUPP; |
71 | 71 | ||
72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); | 72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); |
73 | val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> | 73 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << |
74 | anatop_reg->vol_bit_shift; | 74 | anatop_reg->vol_bit_shift; |
75 | val = (val & mask) >> anatop_reg->vol_bit_shift; | ||
75 | 76 | ||
76 | return val - anatop_reg->min_bit_val; | 77 | return val - anatop_reg->min_bit_val; |
77 | } | 78 | } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index f092588a078c..48385318175a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -3217,7 +3217,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3217 | 3217 | ||
3218 | dev_set_drvdata(&rdev->dev, rdev); | 3218 | dev_set_drvdata(&rdev->dev, rdev); |
3219 | 3219 | ||
3220 | if (config->ena_gpio) { | 3220 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { |
3221 | ret = gpio_request_one(config->ena_gpio, | 3221 | ret = gpio_request_one(config->ena_gpio, |
3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, | 3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, |
3223 | rdev_get_name(rdev)); | 3223 | rdev_get_name(rdev)); |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 34b67bee9323..8b5944f2d7d1 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) | |||
57 | return -EINVAL; | 57 | return -EINVAL; |
58 | } | 58 | } |
59 | 59 | ||
60 | static int gpio_regulator_set_value(struct regulator_dev *dev, | 60 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, |
61 | int min, int max, unsigned *selector) | 61 | int min_uV, int max_uV, |
62 | unsigned *selector) | ||
62 | { | 63 | { |
63 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | 64 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
64 | int ptr, target = 0, state, best_val = INT_MAX; | 65 | int ptr, target = 0, state, best_val = INT_MAX; |
65 | 66 | ||
66 | for (ptr = 0; ptr < data->nr_states; ptr++) | 67 | for (ptr = 0; ptr < data->nr_states; ptr++) |
67 | if (data->states[ptr].value < best_val && | 68 | if (data->states[ptr].value < best_val && |
68 | data->states[ptr].value >= min && | 69 | data->states[ptr].value >= min_uV && |
69 | data->states[ptr].value <= max) { | 70 | data->states[ptr].value <= max_uV) { |
70 | target = data->states[ptr].gpios; | 71 | target = data->states[ptr].gpios; |
71 | best_val = data->states[ptr].value; | 72 | best_val = data->states[ptr].value; |
72 | if (selector) | 73 | if (selector) |
@@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, | |||
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
87 | 88 | ||
88 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, | ||
89 | int min_uV, int max_uV, | ||
90 | unsigned *selector) | ||
91 | { | ||
92 | return gpio_regulator_set_value(dev, min_uV, max_uV, selector); | ||
93 | } | ||
94 | |||
95 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, | 89 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, |
96 | unsigned selector) | 90 | unsigned selector) |
97 | { | 91 | { |
@@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, | |||
106 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, | 100 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, |
107 | int min_uA, int max_uA) | 101 | int min_uA, int max_uA) |
108 | { | 102 | { |
109 | return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); | 103 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
104 | int ptr, target = 0, state, best_val = 0; | ||
105 | |||
106 | for (ptr = 0; ptr < data->nr_states; ptr++) | ||
107 | if (data->states[ptr].value > best_val && | ||
108 | data->states[ptr].value >= min_uA && | ||
109 | data->states[ptr].value <= max_uA) { | ||
110 | target = data->states[ptr].gpios; | ||
111 | best_val = data->states[ptr].value; | ||
112 | } | ||
113 | |||
114 | if (best_val == 0) | ||
115 | return -EINVAL; | ||
116 | |||
117 | for (ptr = 0; ptr < data->nr_gpios; ptr++) { | ||
118 | state = (target & (1 << ptr)) >> ptr; | ||
119 | gpio_set_value(data->gpios[ptr].gpio, state); | ||
120 | } | ||
121 | data->state = target; | ||
122 | |||
123 | return 0; | ||
110 | } | 124 | } |
111 | 125 | ||
112 | static struct regulator_ops gpio_regulator_voltage_ops = { | 126 | static struct regulator_ops gpio_regulator_voltage_ops = { |
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..46c7e88f8381 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -486,9 +486,12 @@ static int palmas_map_voltage_ldo(struct regulator_dev *rdev, | |||
486 | { | 486 | { |
487 | int ret, voltage; | 487 | int ret, voltage; |
488 | 488 | ||
489 | ret = ((min_uV - 900000) / 50000) + 1; | 489 | if (min_uV == 0) |
490 | if (ret < 0) | 490 | return 0; |
491 | return ret; | 491 | |
492 | if (min_uV < 900000) | ||
493 | min_uV = 900000; | ||
494 | ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; | ||
492 | 495 | ||
493 | /* Map back into a voltage to verify we're still in bounds */ | 496 | /* Map back into a voltage to verify we're still in bounds */ |
494 | voltage = palmas_list_voltage_ldo(rdev, ret); | 497 | voltage = palmas_list_voltage_ldo(rdev, ret); |
@@ -586,7 +589,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
586 | 589 | ||
587 | addr = palmas_regs_info[id].ctrl_addr; | 590 | addr = palmas_regs_info[id].ctrl_addr; |
588 | 591 | ||
589 | ret = palmas_smps_read(palmas, addr, ®); | 592 | ret = palmas_ldo_read(palmas, addr, ®); |
590 | if (ret) | 593 | if (ret) |
591 | return ret; | 594 | return ret; |
592 | 595 | ||
@@ -596,7 +599,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
596 | if (reg_init->mode_sleep) | 599 | if (reg_init->mode_sleep) |
597 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; | 600 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; |
598 | 601 | ||
599 | ret = palmas_smps_write(palmas, addr, reg); | 602 | ret = palmas_ldo_write(palmas, addr, reg); |
600 | if (ret) | 603 | if (ret) |
601 | return ret; | 604 | return ret; |
602 | 605 | ||
@@ -630,7 +633,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
630 | 633 | ||
631 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); | 634 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); |
632 | if (ret) | 635 | if (ret) |
633 | goto err_unregister_regulator; | 636 | return ret; |
634 | 637 | ||
635 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) | 638 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) |
636 | pmic->smps123 = 1; | 639 | pmic->smps123 = 1; |
@@ -676,7 +679,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
676 | case PALMAS_REG_SMPS10: | 679 | case PALMAS_REG_SMPS10: |
677 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; | 680 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; |
678 | pmic->desc[id].ops = &palmas_ops_smps10; | 681 | pmic->desc[id].ops = &palmas_ops_smps10; |
679 | pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; | 682 | pmic->desc[id].vsel_reg = |
683 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | ||
684 | PALMAS_SMPS10_CTRL); | ||
680 | pmic->desc[id].vsel_mask = SMPS10_VSEL; | 685 | pmic->desc[id].vsel_mask = SMPS10_VSEL; |
681 | pmic->desc[id].enable_reg = | 686 | pmic->desc[id].enable_reg = |
682 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | 687 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, |
@@ -778,8 +783,10 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
778 | reg_init = pdata->reg_init[id]; | 783 | reg_init = pdata->reg_init[id]; |
779 | if (reg_init) { | 784 | if (reg_init) { |
780 | ret = palmas_ldo_init(palmas, id, reg_init); | 785 | ret = palmas_ldo_init(palmas, id, reg_init); |
781 | if (ret) | 786 | if (ret) { |
787 | regulator_unregister(pmic->rdev[id]); | ||
782 | goto err_unregister_regulator; | 788 | goto err_unregister_regulator; |
789 | } | ||
783 | } | 790 | } |
784 | } | 791 | } |
785 | } | 792 | } |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77a..ab00cab905b7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/regulator/of_regulator.h> | ||
25 | #include <linux/regulator/driver.h> | 26 | #include <linux/regulator/driver.h> |
26 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
27 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
@@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = { | |||
281 | NULL), | 282 | NULL), |
282 | }; | 283 | }; |
283 | 284 | ||
285 | #ifdef CONFIG_OF | ||
286 | static struct of_regulator_match reg_matches[] = { | ||
287 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
288 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
289 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
290 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
291 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
292 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
293 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
294 | }; | ||
295 | |||
296 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
297 | { | ||
298 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
299 | struct device_node *node = tps->dev->of_node; | ||
300 | struct tps65217_board *pdata; | ||
301 | struct device_node *regs; | ||
302 | int i, count; | ||
303 | |||
304 | regs = of_find_node_by_name(node, "regulators"); | ||
305 | if (!regs) | ||
306 | return NULL; | ||
307 | |||
308 | count = of_regulator_match(pdev->dev.parent, regs, | ||
309 | reg_matches, TPS65217_NUM_REGULATOR); | ||
310 | of_node_put(regs); | ||
311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | ||
312 | return NULL; | ||
313 | |||
314 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
315 | if (!pdata) | ||
316 | return NULL; | ||
317 | |||
318 | for (i = 0; i < count; i++) { | ||
319 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
320 | continue; | ||
321 | |||
322 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
323 | pdata->of_node[i] = reg_matches[i].of_node; | ||
324 | } | ||
325 | |||
326 | return pdata; | ||
327 | } | ||
328 | #else | ||
329 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
330 | { | ||
331 | return NULL; | ||
332 | } | ||
333 | #endif | ||
334 | |||
284 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | 335 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) |
285 | { | 336 | { |
337 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
338 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | ||
339 | struct regulator_init_data *reg_data; | ||
286 | struct regulator_dev *rdev; | 340 | struct regulator_dev *rdev; |
287 | struct tps65217 *tps; | ||
288 | struct tps_info *info = &tps65217_pmic_regs[pdev->id]; | ||
289 | struct regulator_config config = { }; | 341 | struct regulator_config config = { }; |
342 | int i, ret; | ||
290 | 343 | ||
291 | /* Already set by core driver */ | 344 | if (tps->dev->of_node) |
292 | tps = dev_to_tps65217(pdev->dev.parent); | 345 | pdata = tps65217_parse_dt(pdev); |
293 | tps->info[pdev->id] = info; | ||
294 | 346 | ||
295 | config.dev = &pdev->dev; | 347 | if (!pdata) { |
296 | config.of_node = pdev->dev.of_node; | 348 | dev_err(&pdev->dev, "Platform data not found\n"); |
297 | config.init_data = pdev->dev.platform_data; | 349 | return -EINVAL; |
298 | config.driver_data = tps; | 350 | } |
299 | 351 | ||
300 | rdev = regulator_register(®ulators[pdev->id], &config); | 352 | if (tps65217_chip_id(tps) != TPS65217) { |
301 | if (IS_ERR(rdev)) | 353 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
302 | return PTR_ERR(rdev); | 354 | return -ENODEV; |
355 | } | ||
303 | 356 | ||
304 | platform_set_drvdata(pdev, rdev); | 357 | platform_set_drvdata(pdev, tps); |
305 | 358 | ||
359 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
360 | |||
361 | reg_data = pdata->tps65217_init_data[i]; | ||
362 | |||
363 | /* | ||
364 | * Regulator API handles empty constraints but not NULL | ||
365 | * constraints | ||
366 | */ | ||
367 | if (!reg_data) | ||
368 | continue; | ||
369 | |||
370 | /* Register the regulators */ | ||
371 | tps->info[i] = &tps65217_pmic_regs[i]; | ||
372 | |||
373 | config.dev = tps->dev; | ||
374 | config.init_data = reg_data; | ||
375 | config.driver_data = tps; | ||
376 | config.regmap = tps->regmap; | ||
377 | if (tps->dev->of_node) | ||
378 | config.of_node = pdata->of_node[i]; | ||
379 | |||
380 | rdev = regulator_register(®ulators[i], &config); | ||
381 | if (IS_ERR(rdev)) { | ||
382 | dev_err(tps->dev, "failed to register %s regulator\n", | ||
383 | pdev->name); | ||
384 | ret = PTR_ERR(rdev); | ||
385 | goto err_unregister_regulator; | ||
386 | } | ||
387 | |||
388 | /* Save regulator for cleanup */ | ||
389 | tps->rdev[i] = rdev; | ||
390 | } | ||
306 | return 0; | 391 | return 0; |
392 | |||
393 | err_unregister_regulator: | ||
394 | while (--i >= 0) | ||
395 | regulator_unregister(tps->rdev[i]); | ||
396 | |||
397 | return ret; | ||
307 | } | 398 | } |
308 | 399 | ||
309 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) | 400 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) |
310 | { | 401 | { |
311 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | 402 | struct tps65217 *tps = platform_get_drvdata(pdev); |
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | ||
406 | regulator_unregister(tps->rdev[i]); | ||
312 | 407 | ||
313 | platform_set_drvdata(pdev, NULL); | 408 | platform_set_drvdata(pdev, NULL); |
314 | regulator_unregister(rdev); | ||
315 | 409 | ||
316 | return 0; | 410 | return 0; |
317 | } | 411 | } |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index e6da90ab5153..19241fc30050 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -240,14 +240,16 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), | 241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
243 | TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), | 243 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
244 | 244 | ||
245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, | 245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, |
246 | ENB, 3, VCC2, 6), | 246 | ENB, 3, VCC2, 6), |
247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, | 247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, |
248 | END, 3, VCC1, 6), | 248 | END, 3, VCC1, 6), |
249 | TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), | 249 | TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1, |
250 | TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), | 250 | ENB, 1, VCC1, 2), |
251 | TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0, | ||
252 | ENB, 0, VCC1, 0), | ||
251 | }; | 253 | }; |
252 | 254 | ||
253 | /* | 255 | /* |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 242fe90dc565..77a71a5c17c3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -1037,7 +1037,7 @@ TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); | |||
1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); | 1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); | 1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | 1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); |
1040 | TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08); | 1040 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); |
1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); | 1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); | 1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); | 1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
@@ -1048,7 +1048,6 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); | |||
1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); | 1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); | 1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | 1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); |
1051 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0); | ||
1052 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); | 1051 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
1053 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); | 1052 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
1054 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); | 1053 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
@@ -1117,7 +1116,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { | |||
1117 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | 1116 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), |
1118 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | 1117 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), |
1119 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | 1118 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), |
1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | 1119 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), |
1121 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | 1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), |
1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | 1121 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), |
1123 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | 1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), |
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 590cfafc7c17..1859f71372e2 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -1008,8 +1008,8 @@ static int rpmsg_probe(struct virtio_device *vdev) | |||
1008 | return 0; | 1008 | return 0; |
1009 | 1009 | ||
1010 | free_coherent: | 1010 | free_coherent: |
1011 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, bufs_va, | 1011 | dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, |
1012 | vrp->bufs_dma); | 1012 | bufs_va, vrp->bufs_dma); |
1013 | vqs_del: | 1013 | vqs_del: |
1014 | vdev->config->del_vqs(vrp->vdev); | 1014 | vdev->config->del_vqs(vrp->vdev); |
1015 | free_vrp: | 1015 | free_vrp: |
@@ -1043,7 +1043,7 @@ static void __devexit rpmsg_remove(struct virtio_device *vdev) | |||
1043 | 1043 | ||
1044 | vdev->config->del_vqs(vrp->vdev); | 1044 | vdev->config->del_vqs(vrp->vdev); |
1045 | 1045 | ||
1046 | dma_free_coherent(vdev->dev.parent, RPMSG_TOTAL_BUF_SPACE, | 1046 | dma_free_coherent(vdev->dev.parent->parent, RPMSG_TOTAL_BUF_SPACE, |
1047 | vrp->rbufs, vrp->bufs_dma); | 1047 | vrp->rbufs, vrp->bufs_dma); |
1048 | 1048 | ||
1049 | kfree(vrp); | 1049 | kfree(vrp); |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index eb415bd76494..9592b936b71b 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -582,6 +582,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) | |||
582 | void rtc_update_irq(struct rtc_device *rtc, | 582 | void rtc_update_irq(struct rtc_device *rtc, |
583 | unsigned long num, unsigned long events) | 583 | unsigned long num, unsigned long events) |
584 | { | 584 | { |
585 | pm_stay_awake(rtc->dev.parent); | ||
585 | schedule_work(&rtc->irqwork); | 586 | schedule_work(&rtc->irqwork); |
586 | } | 587 | } |
587 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 588 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
@@ -844,6 +845,7 @@ void rtc_timer_do_work(struct work_struct *work) | |||
844 | 845 | ||
845 | mutex_lock(&rtc->ops_lock); | 846 | mutex_lock(&rtc->ops_lock); |
846 | again: | 847 | again: |
848 | pm_relax(rtc->dev.parent); | ||
847 | __rtc_read_time(rtc, &tm); | 849 | __rtc_read_time(rtc, &tm); |
848 | now = rtc_tm_to_ktime(tm); | 850 | now = rtc_tm_to_ktime(tm); |
849 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { | 851 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 831868904e02..1dd61f402b04 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -58,6 +58,7 @@ struct sam9_rtc { | |||
58 | struct rtc_device *rtcdev; | 58 | struct rtc_device *rtcdev; |
59 | u32 imr; | 59 | u32 imr; |
60 | void __iomem *gpbr; | 60 | void __iomem *gpbr; |
61 | int irq; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #define rtt_readl(rtc, field) \ | 64 | #define rtt_readl(rtc, field) \ |
@@ -292,7 +293,7 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
292 | { | 293 | { |
293 | struct resource *r, *r_gpbr; | 294 | struct resource *r, *r_gpbr; |
294 | struct sam9_rtc *rtc; | 295 | struct sam9_rtc *rtc; |
295 | int ret; | 296 | int ret, irq; |
296 | u32 mr; | 297 | u32 mr; |
297 | 298 | ||
298 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 299 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -302,10 +303,18 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
302 | return -ENODEV; | 303 | return -ENODEV; |
303 | } | 304 | } |
304 | 305 | ||
306 | irq = platform_get_irq(pdev, 0); | ||
307 | if (irq < 0) { | ||
308 | dev_err(&pdev->dev, "failed to get interrupt resource\n"); | ||
309 | return irq; | ||
310 | } | ||
311 | |||
305 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); | 312 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); |
306 | if (!rtc) | 313 | if (!rtc) |
307 | return -ENOMEM; | 314 | return -ENOMEM; |
308 | 315 | ||
316 | rtc->irq = irq; | ||
317 | |||
309 | /* platform setup code should have handled this; sigh */ | 318 | /* platform setup code should have handled this; sigh */ |
310 | if (!device_can_wakeup(&pdev->dev)) | 319 | if (!device_can_wakeup(&pdev->dev)) |
311 | device_init_wakeup(&pdev->dev, 1); | 320 | device_init_wakeup(&pdev->dev, 1); |
@@ -345,11 +354,10 @@ static int __devinit at91_rtc_probe(struct platform_device *pdev) | |||
345 | } | 354 | } |
346 | 355 | ||
347 | /* register irq handler after we know what name we'll use */ | 356 | /* register irq handler after we know what name we'll use */ |
348 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | 357 | ret = request_irq(rtc->irq, at91_rtc_interrupt, IRQF_SHARED, |
349 | IRQF_SHARED, | ||
350 | dev_name(&rtc->rtcdev->dev), rtc); | 358 | dev_name(&rtc->rtcdev->dev), rtc); |
351 | if (ret) { | 359 | if (ret) { |
352 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | 360 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", rtc->irq); |
353 | rtc_device_unregister(rtc->rtcdev); | 361 | rtc_device_unregister(rtc->rtcdev); |
354 | goto fail_register; | 362 | goto fail_register; |
355 | } | 363 | } |
@@ -386,7 +394,7 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev) | |||
386 | 394 | ||
387 | /* disable all interrupts */ | 395 | /* disable all interrupts */ |
388 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | 396 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); |
389 | free_irq(AT91_ID_SYS, rtc); | 397 | free_irq(rtc->irq, rtc); |
390 | 398 | ||
391 | rtc_device_unregister(rtc->rtcdev); | 399 | rtc_device_unregister(rtc->rtcdev); |
392 | 400 | ||
@@ -423,7 +431,7 @@ static int at91_rtc_suspend(struct platform_device *pdev, | |||
423 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | 431 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); |
424 | if (rtc->imr) { | 432 | if (rtc->imr) { |
425 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { | 433 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { |
426 | enable_irq_wake(AT91_ID_SYS); | 434 | enable_irq_wake(rtc->irq); |
427 | /* don't let RTTINC cause wakeups */ | 435 | /* don't let RTTINC cause wakeups */ |
428 | if (mr & AT91_RTT_RTTINCIEN) | 436 | if (mr & AT91_RTT_RTTINCIEN) |
429 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | 437 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); |
@@ -441,7 +449,7 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
441 | 449 | ||
442 | if (rtc->imr) { | 450 | if (rtc->imr) { |
443 | if (device_may_wakeup(&pdev->dev)) | 451 | if (device_may_wakeup(&pdev->dev)) |
444 | disable_irq_wake(AT91_ID_SYS); | 452 | disable_irq_wake(rtc->irq); |
445 | mr = rtt_readl(rtc, MR); | 453 | mr = rtt_readl(rtc, MR); |
446 | rtt_writel(rtc, MR, mr | rtc->imr); | 454 | rtt_writel(rtc, MR, mr | rtc->imr); |
447 | } | 455 | } |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 132333d75408..4267789ca995 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -568,7 +568,6 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
568 | hpet_mask_rtc_irq_bit(RTC_AIE); | 568 | hpet_mask_rtc_irq_bit(RTC_AIE); |
569 | 569 | ||
570 | CMOS_READ(RTC_INTR_FLAGS); | 570 | CMOS_READ(RTC_INTR_FLAGS); |
571 | pm_wakeup_event(cmos_rtc.dev, 0); | ||
572 | } | 571 | } |
573 | spin_unlock(&rtc_lock); | 572 | spin_unlock(&rtc_lock); |
574 | 573 | ||
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 836118795c0b..13e4df63974f 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/rtc.h> | 43 | #include <linux/rtc.h> |
44 | #include <linux/spi/spi.h> | 44 | #include <linux/spi/spi.h> |
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | #include <linux/sysfs.h> | ||
46 | 47 | ||
47 | #define DRV_VERSION "0.6" | 48 | #define DRV_VERSION "0.6" |
48 | 49 | ||
@@ -292,6 +293,7 @@ static int __devinit pcf2123_probe(struct spi_device *spi) | |||
292 | pdata->rtc = rtc; | 293 | pdata->rtc = rtc; |
293 | 294 | ||
294 | for (i = 0; i < 16; i++) { | 295 | for (i = 0; i < 16; i++) { |
296 | sysfs_attr_init(&pdata->regs[i].attr.attr); | ||
295 | sprintf(pdata->regs[i].name, "%1x", i); | 297 | sprintf(pdata->regs[i].name, "%1x", i); |
296 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; | 298 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; |
297 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; | 299 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; |
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 77074ccd2850..fd5c7af04ae5 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c | |||
@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
122 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); | 122 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); |
123 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); | 123 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); |
124 | if (!pdata->rtc_24h) { | 124 | if (!pdata->rtc_24h) { |
125 | tm->tm_hour %= 12; | 125 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { |
126 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) | 126 | tm->tm_hour -= 20; |
127 | tm->tm_hour %= 12; | ||
127 | tm->tm_hour += 12; | 128 | tm->tm_hour += 12; |
129 | } else | ||
130 | tm->tm_hour %= 12; | ||
128 | } | 131 | } |
129 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); | 132 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); |
130 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); | 133 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); |
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index c5d06fe83bba..9277d945bf48 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c | |||
@@ -495,6 +495,11 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) | |||
495 | if (ret < 0) | 495 | if (ret < 0) |
496 | goto out1; | 496 | goto out1; |
497 | 497 | ||
498 | /* ensure interrupts are disabled, bootloaders can be strange */ | ||
499 | ret = twl_rtc_write_u8(0, REG_RTC_INTERRUPTS_REG); | ||
500 | if (ret < 0) | ||
501 | dev_warn(&pdev->dev, "unable to disable interrupt\n"); | ||
502 | |||
498 | /* init cached IRQ enable bits */ | 503 | /* init cached IRQ enable bits */ |
499 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); | 504 | ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG); |
500 | if (ret < 0) | 505 | if (ret < 0) |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 15370a2c5ff0..0595c763dafd 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -534,11 +534,11 @@ static void dasd_change_state(struct dasd_device *device) | |||
534 | if (rc) | 534 | if (rc) |
535 | device->target = device->state; | 535 | device->target = device->state; |
536 | 536 | ||
537 | if (device->state == device->target) | ||
538 | wake_up(&dasd_init_waitq); | ||
539 | |||
540 | /* let user-space know that the device status changed */ | 537 | /* let user-space know that the device status changed */ |
541 | kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); | 538 | kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE); |
539 | |||
540 | if (device->state == device->target) | ||
541 | wake_up(&dasd_init_waitq); | ||
542 | } | 542 | } |
543 | 543 | ||
544 | /* | 544 | /* |
@@ -2157,6 +2157,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) | |||
2157 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && | 2157 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && |
2158 | (!dasd_eer_enabled(device))) { | 2158 | (!dasd_eer_enabled(device))) { |
2159 | cqr->status = DASD_CQR_FAILED; | 2159 | cqr->status = DASD_CQR_FAILED; |
2160 | cqr->intrc = -EAGAIN; | ||
2160 | continue; | 2161 | continue; |
2161 | } | 2162 | } |
2162 | /* Don't try to start requests if device is stopped */ | 2163 | /* Don't try to start requests if device is stopped */ |
@@ -3270,6 +3271,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) | |||
3270 | dasd_schedule_device_bh(device); | 3271 | dasd_schedule_device_bh(device); |
3271 | } | 3272 | } |
3272 | if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) { | 3273 | if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) { |
3274 | if (!(device->path_data.opm & eventlpm) && | ||
3275 | !(device->path_data.tbvpm & eventlpm)) { | ||
3276 | /* | ||
3277 | * we can not establish a pathgroup on an | ||
3278 | * unavailable path, so trigger a path | ||
3279 | * verification first | ||
3280 | */ | ||
3281 | device->path_data.tbvpm |= eventlpm; | ||
3282 | dasd_schedule_device_bh(device); | ||
3283 | } | ||
3273 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 3284 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", |
3274 | "Pathgroup re-established\n"); | 3285 | "Pathgroup re-established\n"); |
3275 | if (device->discipline->kick_validate) | 3286 | if (device->discipline->kick_validate) |
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index 157defe5e069..6b556995bb33 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
@@ -384,6 +384,29 @@ static void _remove_device_from_lcu(struct alias_lcu *lcu, | |||
384 | group->next = NULL; | 384 | group->next = NULL; |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static int | ||
388 | suborder_not_supported(struct dasd_ccw_req *cqr) | ||
389 | { | ||
390 | char *sense; | ||
391 | char reason; | ||
392 | char msg_format; | ||
393 | char msg_no; | ||
394 | |||
395 | sense = dasd_get_sense(&cqr->irb); | ||
396 | if (!sense) | ||
397 | return 0; | ||
398 | |||
399 | reason = sense[0]; | ||
400 | msg_format = (sense[7] & 0xF0); | ||
401 | msg_no = (sense[7] & 0x0F); | ||
402 | |||
403 | /* command reject, Format 0 MSG 4 - invalid parameter */ | ||
404 | if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04)) | ||
405 | return 1; | ||
406 | |||
407 | return 0; | ||
408 | } | ||
409 | |||
387 | static int read_unit_address_configuration(struct dasd_device *device, | 410 | static int read_unit_address_configuration(struct dasd_device *device, |
388 | struct alias_lcu *lcu) | 411 | struct alias_lcu *lcu) |
389 | { | 412 | { |
@@ -435,6 +458,8 @@ static int read_unit_address_configuration(struct dasd_device *device, | |||
435 | 458 | ||
436 | do { | 459 | do { |
437 | rc = dasd_sleep_on(cqr); | 460 | rc = dasd_sleep_on(cqr); |
461 | if (rc && suborder_not_supported(cqr)) | ||
462 | return -EOPNOTSUPP; | ||
438 | } while (rc && (cqr->retries > 0)); | 463 | } while (rc && (cqr->retries > 0)); |
439 | if (rc) { | 464 | if (rc) { |
440 | spin_lock_irqsave(&lcu->lock, flags); | 465 | spin_lock_irqsave(&lcu->lock, flags); |
@@ -521,7 +546,7 @@ static void lcu_update_work(struct work_struct *work) | |||
521 | * processing the data | 546 | * processing the data |
522 | */ | 547 | */ |
523 | spin_lock_irqsave(&lcu->lock, flags); | 548 | spin_lock_irqsave(&lcu->lock, flags); |
524 | if (rc || (lcu->flags & NEED_UAC_UPDATE)) { | 549 | if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) { |
525 | DBF_DEV_EVENT(DBF_WARNING, device, "could not update" | 550 | DBF_DEV_EVENT(DBF_WARNING, device, "could not update" |
526 | " alias data in lcu (rc = %d), retry later", rc); | 551 | " alias data in lcu (rc = %d), retry later", rc); |
527 | schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); | 552 | schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ); |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 40a826a7295f..c48c72abbefc 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1507,7 +1507,8 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device, | |||
1507 | * call might change behaviour of DASD devices. | 1507 | * call might change behaviour of DASD devices. |
1508 | */ | 1508 | */ |
1509 | static int | 1509 | static int |
1510 | dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav) | 1510 | dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav, |
1511 | unsigned long flags) | ||
1511 | { | 1512 | { |
1512 | struct dasd_ccw_req *cqr; | 1513 | struct dasd_ccw_req *cqr; |
1513 | int rc; | 1514 | int rc; |
@@ -1516,10 +1517,19 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav) | |||
1516 | if (IS_ERR(cqr)) | 1517 | if (IS_ERR(cqr)) |
1517 | return PTR_ERR(cqr); | 1518 | return PTR_ERR(cqr); |
1518 | 1519 | ||
1520 | /* | ||
1521 | * set flags e.g. turn on failfast, to prevent blocking | ||
1522 | * the calling function should handle failed requests | ||
1523 | */ | ||
1524 | cqr->flags |= flags; | ||
1525 | |||
1519 | rc = dasd_sleep_on(cqr); | 1526 | rc = dasd_sleep_on(cqr); |
1520 | if (!rc) | 1527 | if (!rc) |
1521 | /* trigger CIO to reprobe devices */ | 1528 | /* trigger CIO to reprobe devices */ |
1522 | css_schedule_reprobe(); | 1529 | css_schedule_reprobe(); |
1530 | else if (cqr->intrc == -EAGAIN) | ||
1531 | rc = -EAGAIN; | ||
1532 | |||
1523 | dasd_sfree_request(cqr, cqr->memdev); | 1533 | dasd_sfree_request(cqr, cqr->memdev); |
1524 | return rc; | 1534 | return rc; |
1525 | } | 1535 | } |
@@ -1527,7 +1537,8 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav) | |||
1527 | /* | 1537 | /* |
1528 | * Valide storage server of current device. | 1538 | * Valide storage server of current device. |
1529 | */ | 1539 | */ |
1530 | static void dasd_eckd_validate_server(struct dasd_device *device) | 1540 | static int dasd_eckd_validate_server(struct dasd_device *device, |
1541 | unsigned long flags) | ||
1531 | { | 1542 | { |
1532 | int rc; | 1543 | int rc; |
1533 | struct dasd_eckd_private *private; | 1544 | struct dasd_eckd_private *private; |
@@ -1536,17 +1547,18 @@ static void dasd_eckd_validate_server(struct dasd_device *device) | |||
1536 | private = (struct dasd_eckd_private *) device->private; | 1547 | private = (struct dasd_eckd_private *) device->private; |
1537 | if (private->uid.type == UA_BASE_PAV_ALIAS || | 1548 | if (private->uid.type == UA_BASE_PAV_ALIAS || |
1538 | private->uid.type == UA_HYPER_PAV_ALIAS) | 1549 | private->uid.type == UA_HYPER_PAV_ALIAS) |
1539 | return; | 1550 | return 0; |
1540 | if (dasd_nopav || MACHINE_IS_VM) | 1551 | if (dasd_nopav || MACHINE_IS_VM) |
1541 | enable_pav = 0; | 1552 | enable_pav = 0; |
1542 | else | 1553 | else |
1543 | enable_pav = 1; | 1554 | enable_pav = 1; |
1544 | rc = dasd_eckd_psf_ssc(device, enable_pav); | 1555 | rc = dasd_eckd_psf_ssc(device, enable_pav, flags); |
1545 | 1556 | ||
1546 | /* may be requested feature is not available on server, | 1557 | /* may be requested feature is not available on server, |
1547 | * therefore just report error and go ahead */ | 1558 | * therefore just report error and go ahead */ |
1548 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " | 1559 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " |
1549 | "returned rc=%d", private->uid.ssid, rc); | 1560 | "returned rc=%d", private->uid.ssid, rc); |
1561 | return rc; | ||
1550 | } | 1562 | } |
1551 | 1563 | ||
1552 | /* | 1564 | /* |
@@ -1556,7 +1568,13 @@ static void dasd_eckd_do_validate_server(struct work_struct *work) | |||
1556 | { | 1568 | { |
1557 | struct dasd_device *device = container_of(work, struct dasd_device, | 1569 | struct dasd_device *device = container_of(work, struct dasd_device, |
1558 | kick_validate); | 1570 | kick_validate); |
1559 | dasd_eckd_validate_server(device); | 1571 | if (dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST) |
1572 | == -EAGAIN) { | ||
1573 | /* schedule worker again if failed */ | ||
1574 | schedule_work(&device->kick_validate); | ||
1575 | return; | ||
1576 | } | ||
1577 | |||
1560 | dasd_put_device(device); | 1578 | dasd_put_device(device); |
1561 | } | 1579 | } |
1562 | 1580 | ||
@@ -1685,7 +1703,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1685 | if (rc) | 1703 | if (rc) |
1686 | goto out_err2; | 1704 | goto out_err2; |
1687 | 1705 | ||
1688 | dasd_eckd_validate_server(device); | 1706 | dasd_eckd_validate_server(device, 0); |
1689 | 1707 | ||
1690 | /* device may report different configuration data after LCU setup */ | 1708 | /* device may report different configuration data after LCU setup */ |
1691 | rc = dasd_eckd_read_conf(device); | 1709 | rc = dasd_eckd_read_conf(device); |
@@ -3804,7 +3822,7 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp) | |||
3804 | case BIODASDSYMMIO: | 3822 | case BIODASDSYMMIO: |
3805 | return dasd_symm_io(device, argp); | 3823 | return dasd_symm_io(device, argp); |
3806 | default: | 3824 | default: |
3807 | return -ENOIOCTLCMD; | 3825 | return -ENOTTY; |
3808 | } | 3826 | } |
3809 | } | 3827 | } |
3810 | 3828 | ||
@@ -4153,7 +4171,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device) | |||
4153 | rc = dasd_alias_make_device_known_to_lcu(device); | 4171 | rc = dasd_alias_make_device_known_to_lcu(device); |
4154 | if (rc) | 4172 | if (rc) |
4155 | return rc; | 4173 | return rc; |
4156 | dasd_eckd_validate_server(device); | 4174 | dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST); |
4157 | 4175 | ||
4158 | /* RE-Read Configuration Data */ | 4176 | /* RE-Read Configuration Data */ |
4159 | rc = dasd_eckd_read_conf(device); | 4177 | rc = dasd_eckd_read_conf(device); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index cceae70279f6..654c6921a6d4 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -498,12 +498,9 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, | |||
498 | break; | 498 | break; |
499 | default: | 499 | default: |
500 | /* if the discipline has an ioctl method try it. */ | 500 | /* if the discipline has an ioctl method try it. */ |
501 | if (base->discipline->ioctl) { | 501 | rc = -ENOTTY; |
502 | if (base->discipline->ioctl) | ||
502 | rc = base->discipline->ioctl(block, cmd, argp); | 503 | rc = base->discipline->ioctl(block, cmd, argp); |
503 | if (rc == -ENOIOCTLCMD) | ||
504 | rc = -EINVAL; | ||
505 | } else | ||
506 | rc = -EINVAL; | ||
507 | } | 504 | } |
508 | dasd_put_device(base); | 505 | dasd_put_device(base); |
509 | return rc; | 506 | return rc; |
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index 6a6f76bf6e3d..b1032931a1c4 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c | |||
@@ -242,11 +242,13 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) | |||
242 | switch (sdias_evbuf.event_status) { | 242 | switch (sdias_evbuf.event_status) { |
243 | case EVSTATE_ALL_STORED: | 243 | case EVSTATE_ALL_STORED: |
244 | TRACE("all stored\n"); | 244 | TRACE("all stored\n"); |
245 | break; | ||
245 | case EVSTATE_PART_STORED: | 246 | case EVSTATE_PART_STORED: |
246 | TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); | 247 | TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); |
247 | break; | 248 | break; |
248 | case EVSTATE_NO_DATA: | 249 | case EVSTATE_NO_DATA: |
249 | TRACE("no data\n"); | 250 | TRACE("no data\n"); |
251 | /* fall through */ | ||
250 | default: | 252 | default: |
251 | pr_err("Error from SCLP while copying hsa. " | 253 | pr_err("Error from SCLP while copying hsa. " |
252 | "Event status = %x\n", | 254 | "Event status = %x\n", |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index ed25c8740a9c..fc916f5d7314 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1426,6 +1426,8 @@ static enum io_sch_action sch_get_action(struct subchannel *sch) | |||
1426 | return IO_SCH_REPROBE; | 1426 | return IO_SCH_REPROBE; |
1427 | if (cdev->online) | 1427 | if (cdev->online) |
1428 | return IO_SCH_VERIFY; | 1428 | return IO_SCH_VERIFY; |
1429 | if (cdev->private->state == DEV_STATE_NOT_OPER) | ||
1430 | return IO_SCH_UNREG_ATTACH; | ||
1429 | return IO_SCH_NOP; | 1431 | return IO_SCH_NOP; |
1430 | } | 1432 | } |
1431 | 1433 | ||
@@ -1519,11 +1521,14 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process) | |||
1519 | goto out; | 1521 | goto out; |
1520 | break; | 1522 | break; |
1521 | case IO_SCH_UNREG_ATTACH: | 1523 | case IO_SCH_UNREG_ATTACH: |
1524 | spin_lock_irqsave(sch->lock, flags); | ||
1522 | if (cdev->private->flags.resuming) { | 1525 | if (cdev->private->flags.resuming) { |
1523 | /* Device will be handled later. */ | 1526 | /* Device will be handled later. */ |
1524 | rc = 0; | 1527 | rc = 0; |
1525 | goto out; | 1528 | goto out_unlock; |
1526 | } | 1529 | } |
1530 | sch_set_cdev(sch, NULL); | ||
1531 | spin_unlock_irqrestore(sch->lock, flags); | ||
1527 | /* Unregister ccw device. */ | 1532 | /* Unregister ccw device. */ |
1528 | ccw_device_unregister(cdev); | 1533 | ccw_device_unregister(cdev); |
1529 | break; | 1534 | break; |
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 33d6630529de..91eec60252ee 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -1264,6 +1264,9 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba) | |||
1264 | int rc = 0; | 1264 | int rc = 0; |
1265 | u64 mask64; | 1265 | u64 mask64; |
1266 | 1266 | ||
1267 | memset(&iscsi_init, 0x00, sizeof(struct iscsi_kwqe_init1)); | ||
1268 | memset(&iscsi_init2, 0x00, sizeof(struct iscsi_kwqe_init2)); | ||
1269 | |||
1267 | bnx2i_adjust_qp_size(hba); | 1270 | bnx2i_adjust_qp_size(hba); |
1268 | 1271 | ||
1269 | iscsi_init.flags = | 1272 | iscsi_init.flags = |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 796482badf13..2b4261cb7742 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -1315,8 +1315,9 @@ static void complete_scsi_command(struct CommandList *cp) | |||
1315 | } | 1315 | } |
1316 | break; | 1316 | break; |
1317 | case CMD_PROTOCOL_ERR: | 1317 | case CMD_PROTOCOL_ERR: |
1318 | cmd->result = DID_ERROR << 16; | ||
1318 | dev_warn(&h->pdev->dev, "cp %p has " | 1319 | dev_warn(&h->pdev->dev, "cp %p has " |
1319 | "protocol error \n", cp); | 1320 | "protocol error\n", cp); |
1320 | break; | 1321 | break; |
1321 | case CMD_HARDWARE_ERR: | 1322 | case CMD_HARDWARE_ERR: |
1322 | cmd->result = DID_ERROR << 16; | 1323 | cmd->result = DID_ERROR << 16; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e5..ed38454228c6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -4066,7 +4066,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4066 | spin_lock_init(&instance->cmd_pool_lock); | 4066 | spin_lock_init(&instance->cmd_pool_lock); |
4067 | spin_lock_init(&instance->hba_lock); | 4067 | spin_lock_init(&instance->hba_lock); |
4068 | spin_lock_init(&instance->completion_lock); | 4068 | spin_lock_init(&instance->completion_lock); |
4069 | spin_lock_init(&poll_aen_lock); | ||
4070 | 4069 | ||
4071 | mutex_init(&instance->aen_mutex); | 4070 | mutex_init(&instance->aen_mutex); |
4072 | mutex_init(&instance->reset_mutex); | 4071 | mutex_init(&instance->reset_mutex); |
@@ -5392,6 +5391,8 @@ static int __init megasas_init(void) | |||
5392 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, | 5391 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, |
5393 | MEGASAS_EXT_VERSION); | 5392 | MEGASAS_EXT_VERSION); |
5394 | 5393 | ||
5394 | spin_lock_init(&poll_aen_lock); | ||
5395 | |||
5395 | support_poll_for_event = 2; | 5396 | support_poll_for_event = 2; |
5396 | support_device_change = 1; | 5397 | support_device_change = 1; |
5397 | 5398 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe7755..9d5a56c4b332 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -1209,6 +1209,13 @@ _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc) | |||
1209 | u16 message_control; | 1209 | u16 message_control; |
1210 | 1210 | ||
1211 | 1211 | ||
1212 | /* Check whether controller SAS2008 B0 controller, | ||
1213 | if it is SAS2008 B0 controller use IO-APIC instead of MSIX */ | ||
1214 | if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 && | ||
1215 | ioc->pdev->revision == 0x01) { | ||
1216 | return -EINVAL; | ||
1217 | } | ||
1218 | |||
1212 | base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); | 1219 | base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX); |
1213 | if (!base) { | 1220 | if (!base) { |
1214 | dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not " | 1221 | dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not " |
@@ -2424,10 +2431,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2424 | } | 2431 | } |
2425 | 2432 | ||
2426 | /* command line tunables for max controller queue depth */ | 2433 | /* command line tunables for max controller queue depth */ |
2427 | if (max_queue_depth != -1) | 2434 | if (max_queue_depth != -1 && max_queue_depth != 0) { |
2428 | max_request_credit = (max_queue_depth < facts->RequestCredit) | 2435 | max_request_credit = min_t(u16, max_queue_depth + |
2429 | ? max_queue_depth : facts->RequestCredit; | 2436 | ioc->hi_priority_depth + ioc->internal_depth, |
2430 | else | 2437 | facts->RequestCredit); |
2438 | if (max_request_credit > MAX_HBA_QUEUE_DEPTH) | ||
2439 | max_request_credit = MAX_HBA_QUEUE_DEPTH; | ||
2440 | } else | ||
2431 | max_request_credit = min_t(u16, facts->RequestCredit, | 2441 | max_request_credit = min_t(u16, facts->RequestCredit, |
2432 | MAX_HBA_QUEUE_DEPTH); | 2442 | MAX_HBA_QUEUE_DEPTH); |
2433 | 2443 | ||
@@ -2502,7 +2512,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2502 | /* set the scsi host can_queue depth | 2512 | /* set the scsi host can_queue depth |
2503 | * with some internal commands that could be outstanding | 2513 | * with some internal commands that could be outstanding |
2504 | */ | 2514 | */ |
2505 | ioc->shost->can_queue = ioc->scsiio_depth - (2); | 2515 | ioc->shost->can_queue = ioc->scsiio_depth; |
2506 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " | 2516 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " |
2507 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); | 2517 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); |
2508 | 2518 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4a6381c87253..de2337f255a7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | #include <trace/events/scsi.h> | 43 | #include <trace/events/scsi.h> |
44 | 44 | ||
45 | static void scsi_eh_done(struct scsi_cmnd *scmd); | ||
46 | |||
45 | #define SENSE_TIMEOUT (10*HZ) | 47 | #define SENSE_TIMEOUT (10*HZ) |
46 | 48 | ||
47 | /* | 49 | /* |
@@ -241,6 +243,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
241 | if (! scsi_command_normalize_sense(scmd, &sshdr)) | 243 | if (! scsi_command_normalize_sense(scmd, &sshdr)) |
242 | return FAILED; /* no valid sense data */ | 244 | return FAILED; /* no valid sense data */ |
243 | 245 | ||
246 | if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) | ||
247 | /* | ||
248 | * nasty: for mid-layer issued TURs, we need to return the | ||
249 | * actual sense data without any recovery attempt. For eh | ||
250 | * issued ones, we need to try to recover and interpret | ||
251 | */ | ||
252 | return SUCCESS; | ||
253 | |||
244 | if (scsi_sense_is_deferred(&sshdr)) | 254 | if (scsi_sense_is_deferred(&sshdr)) |
245 | return NEEDS_RETRY; | 255 | return NEEDS_RETRY; |
246 | 256 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffd77739ae3e..faa790fba134 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -776,7 +776,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
776 | } | 776 | } |
777 | 777 | ||
778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ | 778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ |
779 | req->errors = result; | ||
780 | if (result) { | 779 | if (result) { |
781 | if (sense_valid && req->sense) { | 780 | if (sense_valid && req->sense) { |
782 | /* | 781 | /* |
@@ -792,6 +791,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
792 | if (!sense_deferred) | 791 | if (!sense_deferred) |
793 | error = __scsi_error_from_host_byte(cmd, result); | 792 | error = __scsi_error_from_host_byte(cmd, result); |
794 | } | 793 | } |
794 | /* | ||
795 | * __scsi_error_from_host_byte may have reset the host_byte | ||
796 | */ | ||
797 | req->errors = cmd->result; | ||
795 | 798 | ||
796 | req->resid_len = scsi_get_resid(cmd); | 799 | req->resid_len = scsi_get_resid(cmd); |
797 | 800 | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56a93794c470..d947ffc20ceb 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -764,6 +764,16 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
764 | sdev->model = (char *) (sdev->inquiry + 16); | 764 | sdev->model = (char *) (sdev->inquiry + 16); |
765 | sdev->rev = (char *) (sdev->inquiry + 32); | 765 | sdev->rev = (char *) (sdev->inquiry + 32); |
766 | 766 | ||
767 | if (strncmp(sdev->vendor, "ATA ", 8) == 0) { | ||
768 | /* | ||
769 | * sata emulation layer device. This is a hack to work around | ||
770 | * the SATL power management specifications which state that | ||
771 | * when the SATL detects the device has gone into standby | ||
772 | * mode, it shall respond with NOT READY. | ||
773 | */ | ||
774 | sdev->allow_restart = 1; | ||
775 | } | ||
776 | |||
767 | if (*bflags & BLIST_ISROM) { | 777 | if (*bflags & BLIST_ISROM) { |
768 | sdev->type = TYPE_ROM; | 778 | sdev->type = TYPE_ROM; |
769 | sdev->removable = 1; | 779 | sdev->removable = 1; |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index c7030fbee79c..3e79a2f00042 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -331,7 +331,7 @@ static void virtscsi_map_sgl(struct scatterlist *sg, unsigned int *p_idx, | |||
331 | int i; | 331 | int i; |
332 | 332 | ||
333 | for_each_sg(table->sgl, sg_elem, table->nents, i) | 333 | for_each_sg(table->sgl, sg_elem, table->nents, i) |
334 | sg_set_buf(&sg[idx++], sg_virt(sg_elem), sg_elem->length); | 334 | sg[idx++] = *sg_elem; |
335 | 335 | ||
336 | *p_idx = idx; | 336 | *p_idx = idx; |
337 | } | 337 | } |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 2374468615ed..8f32a1323a79 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -324,8 +324,16 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
324 | 324 | ||
325 | res = irq_create_identity_mapping(d->domain, irq); | 325 | res = irq_create_identity_mapping(d->domain, irq); |
326 | if (unlikely(res)) { | 326 | if (unlikely(res)) { |
327 | pr_err("can't get irq_desc for %d\n", irq); | 327 | if (res == -EEXIST) { |
328 | continue; | 328 | res = irq_domain_associate(d->domain, irq, irq); |
329 | if (unlikely(res)) { | ||
330 | pr_err("domain association failure\n"); | ||
331 | continue; | ||
332 | } | ||
333 | } else { | ||
334 | pr_err("can't identity map IRQ %d\n", irq); | ||
335 | continue; | ||
336 | } | ||
329 | } | 337 | } |
330 | 338 | ||
331 | intc_irq_xlate_set(irq, vect->enum_id, d); | 339 | intc_irq_xlate_set(irq, vect->enum_id, d); |
@@ -345,8 +353,19 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
345 | */ | 353 | */ |
346 | res = irq_create_identity_mapping(d->domain, irq2); | 354 | res = irq_create_identity_mapping(d->domain, irq2); |
347 | if (unlikely(res)) { | 355 | if (unlikely(res)) { |
348 | pr_err("can't get irq_desc for %d\n", irq2); | 356 | if (res == -EEXIST) { |
349 | continue; | 357 | res = irq_domain_associate(d->domain, |
358 | irq2, irq2); | ||
359 | if (unlikely(res)) { | ||
360 | pr_err("domain association " | ||
361 | "failure\n"); | ||
362 | continue; | ||
363 | } | ||
364 | } else { | ||
365 | pr_err("can't identity map IRQ %d\n", | ||
366 | irq); | ||
367 | continue; | ||
368 | } | ||
350 | } | 369 | } |
351 | 370 | ||
352 | vect2->enum_id = 0; | 371 | vect2->enum_id = 0; |
diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c index 2804eaae804e..0646bf6e7889 100644 --- a/drivers/sh/pfc/pinctrl.c +++ b/drivers/sh/pfc/pinctrl.c | |||
@@ -208,10 +208,13 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
208 | 208 | ||
209 | break; | 209 | break; |
210 | case PINMUX_TYPE_GPIO: | 210 | case PINMUX_TYPE_GPIO: |
211 | case PINMUX_TYPE_INPUT: | ||
212 | case PINMUX_TYPE_OUTPUT: | ||
211 | break; | 213 | break; |
212 | default: | 214 | default: |
213 | pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); | 215 | pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); |
214 | return -ENOTSUPP; | 216 | ret = -ENOTSUPP; |
217 | goto err; | ||
215 | } | 218 | } |
216 | 219 | ||
217 | ret = 0; | 220 | ret = 0; |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 6e25ef1bce91..a9f4049c6769 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -47,6 +47,8 @@ struct bcm63xx_spi { | |||
47 | /* Platform data */ | 47 | /* Platform data */ |
48 | u32 speed_hz; | 48 | u32 speed_hz; |
49 | unsigned fifo_size; | 49 | unsigned fifo_size; |
50 | unsigned int msg_type_shift; | ||
51 | unsigned int msg_ctl_width; | ||
50 | 52 | ||
51 | /* Data buffers */ | 53 | /* Data buffers */ |
52 | const unsigned char *tx_ptr; | 54 | const unsigned char *tx_ptr; |
@@ -221,13 +223,20 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, | |||
221 | msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); | 223 | msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); |
222 | 224 | ||
223 | if (t->rx_buf && t->tx_buf) | 225 | if (t->rx_buf && t->tx_buf) |
224 | msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); | 226 | msg_ctl |= (SPI_FD_RW << bs->msg_type_shift); |
225 | else if (t->rx_buf) | 227 | else if (t->rx_buf) |
226 | msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); | 228 | msg_ctl |= (SPI_HD_R << bs->msg_type_shift); |
227 | else if (t->tx_buf) | 229 | else if (t->tx_buf) |
228 | msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); | 230 | msg_ctl |= (SPI_HD_W << bs->msg_type_shift); |
229 | 231 | ||
230 | bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); | 232 | switch (bs->msg_ctl_width) { |
233 | case 8: | ||
234 | bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL); | ||
235 | break; | ||
236 | case 16: | ||
237 | bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); | ||
238 | break; | ||
239 | } | ||
231 | 240 | ||
232 | /* Issue the transfer */ | 241 | /* Issue the transfer */ |
233 | cmd = SPI_CMD_START_IMMEDIATE; | 242 | cmd = SPI_CMD_START_IMMEDIATE; |
@@ -406,9 +415,21 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) | |||
406 | master->transfer_one_message = bcm63xx_spi_transfer_one; | 415 | master->transfer_one_message = bcm63xx_spi_transfer_one; |
407 | master->mode_bits = MODEBITS; | 416 | master->mode_bits = MODEBITS; |
408 | bs->speed_hz = pdata->speed_hz; | 417 | bs->speed_hz = pdata->speed_hz; |
418 | bs->msg_type_shift = pdata->msg_type_shift; | ||
419 | bs->msg_ctl_width = pdata->msg_ctl_width; | ||
409 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); | 420 | bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); |
410 | bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); | 421 | bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); |
411 | 422 | ||
423 | switch (bs->msg_ctl_width) { | ||
424 | case 8: | ||
425 | case 16: | ||
426 | break; | ||
427 | default: | ||
428 | dev_err(dev, "unsupported MSG_CTL width: %d\n", | ||
429 | bs->msg_ctl_width); | ||
430 | goto out_clk_disable; | ||
431 | } | ||
432 | |||
412 | /* Initialize hardware */ | 433 | /* Initialize hardware */ |
413 | clk_enable(bs->clk); | 434 | clk_enable(bs->clk); |
414 | bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); | 435 | bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); |
@@ -438,7 +459,7 @@ out: | |||
438 | 459 | ||
439 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | 460 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) |
440 | { | 461 | { |
441 | struct spi_master *master = platform_get_drvdata(pdev); | 462 | struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); |
442 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); | 463 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); |
443 | 464 | ||
444 | spi_unregister_master(master); | 465 | spi_unregister_master(master); |
@@ -452,6 +473,8 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | |||
452 | 473 | ||
453 | platform_set_drvdata(pdev, 0); | 474 | platform_set_drvdata(pdev, 0); |
454 | 475 | ||
476 | spi_master_put(master); | ||
477 | |||
455 | return 0; | 478 | return 0; |
456 | } | 479 | } |
457 | 480 | ||
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index b2d4b9e4e010..764bfee75920 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
@@ -533,7 +533,6 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
533 | iounmap(mcfqspi->iobase); | 533 | iounmap(mcfqspi->iobase); |
534 | release_mem_region(res->start, resource_size(res)); | 534 | release_mem_region(res->start, resource_size(res)); |
535 | spi_unregister_master(master); | 535 | spi_unregister_master(master); |
536 | spi_master_put(master); | ||
537 | 536 | ||
538 | return 0; | 537 | return 0; |
539 | } | 538 | } |
@@ -541,7 +540,7 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
541 | #ifdef CONFIG_PM_SLEEP | 540 | #ifdef CONFIG_PM_SLEEP |
542 | static int mcfqspi_suspend(struct device *dev) | 541 | static int mcfqspi_suspend(struct device *dev) |
543 | { | 542 | { |
544 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 543 | struct spi_master *master = dev_get_drvdata(dev); |
545 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 544 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
546 | 545 | ||
547 | spi_master_suspend(master); | 546 | spi_master_suspend(master); |
@@ -553,7 +552,7 @@ static int mcfqspi_suspend(struct device *dev) | |||
553 | 552 | ||
554 | static int mcfqspi_resume(struct device *dev) | 553 | static int mcfqspi_resume(struct device *dev) |
555 | { | 554 | { |
556 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 555 | struct spi_master *master = dev_get_drvdata(dev); |
557 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 556 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
558 | 557 | ||
559 | spi_master_resume(master); | 558 | spi_master_resume(master); |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bc4778175e34..b2fb141da375 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -1228,18 +1228,16 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1228 | 1228 | ||
1229 | status = spi_register_master(master); | 1229 | status = spi_register_master(master); |
1230 | if (status < 0) | 1230 | if (status < 0) |
1231 | goto err_spi_register; | 1231 | goto disable_pm; |
1232 | 1232 | ||
1233 | return status; | 1233 | return status; |
1234 | 1234 | ||
1235 | err_spi_register: | ||
1236 | spi_master_put(master); | ||
1237 | disable_pm: | 1235 | disable_pm: |
1238 | pm_runtime_disable(&pdev->dev); | 1236 | pm_runtime_disable(&pdev->dev); |
1239 | dma_chnl_free: | 1237 | dma_chnl_free: |
1240 | kfree(mcspi->dma_channels); | 1238 | kfree(mcspi->dma_channels); |
1241 | free_master: | 1239 | free_master: |
1242 | kfree(master); | 1240 | spi_master_put(master); |
1243 | platform_set_drvdata(pdev, NULL); | 1241 | platform_set_drvdata(pdev, NULL); |
1244 | return status; | 1242 | return status; |
1245 | } | 1243 | } |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index aab518ec2bbc..6abbe23c39b4 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -2053,7 +2053,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2054 | adev->res.start, pl022->virtbase); | 2054 | adev->res.start, pl022->virtbase); |
2055 | 2055 | ||
2056 | pm_runtime_enable(dev); | ||
2057 | pm_runtime_resume(dev); | 2056 | pm_runtime_resume(dev); |
2058 | 2057 | ||
2059 | pl022->clk = clk_get(&adev->dev, NULL); | 2058 | pl022->clk = clk_get(&adev->dev, NULL); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 646a7657fe62..d1c8441f638c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -826,7 +826,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( | |||
826 | struct spi_device *spi) | 826 | struct spi_device *spi) |
827 | { | 827 | { |
828 | struct s3c64xx_spi_csinfo *cs; | 828 | struct s3c64xx_spi_csinfo *cs; |
829 | struct device_node *slave_np, *data_np; | 829 | struct device_node *slave_np, *data_np = NULL; |
830 | u32 fb_delay = 0; | 830 | u32 fb_delay = 0; |
831 | 831 | ||
832 | slave_np = spi->dev.of_node; | 832 | slave_np = spi->dev.of_node; |
@@ -1479,40 +1479,40 @@ static const struct dev_pm_ops s3c64xx_spi_pm = { | |||
1479 | s3c64xx_spi_runtime_resume, NULL) | 1479 | s3c64xx_spi_runtime_resume, NULL) |
1480 | }; | 1480 | }; |
1481 | 1481 | ||
1482 | struct s3c64xx_spi_port_config s3c2443_spi_port_config = { | 1482 | static struct s3c64xx_spi_port_config s3c2443_spi_port_config = { |
1483 | .fifo_lvl_mask = { 0x7f }, | 1483 | .fifo_lvl_mask = { 0x7f }, |
1484 | .rx_lvl_offset = 13, | 1484 | .rx_lvl_offset = 13, |
1485 | .tx_st_done = 21, | 1485 | .tx_st_done = 21, |
1486 | .high_speed = true, | 1486 | .high_speed = true, |
1487 | }; | 1487 | }; |
1488 | 1488 | ||
1489 | struct s3c64xx_spi_port_config s3c6410_spi_port_config = { | 1489 | static struct s3c64xx_spi_port_config s3c6410_spi_port_config = { |
1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
1491 | .rx_lvl_offset = 13, | 1491 | .rx_lvl_offset = 13, |
1492 | .tx_st_done = 21, | 1492 | .tx_st_done = 21, |
1493 | }; | 1493 | }; |
1494 | 1494 | ||
1495 | struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { | 1495 | static struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { |
1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
1497 | .rx_lvl_offset = 15, | 1497 | .rx_lvl_offset = 15, |
1498 | .tx_st_done = 25, | 1498 | .tx_st_done = 25, |
1499 | }; | 1499 | }; |
1500 | 1500 | ||
1501 | struct s3c64xx_spi_port_config s5pc100_spi_port_config = { | 1501 | static struct s3c64xx_spi_port_config s5pc100_spi_port_config = { |
1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
1503 | .rx_lvl_offset = 13, | 1503 | .rx_lvl_offset = 13, |
1504 | .tx_st_done = 21, | 1504 | .tx_st_done = 21, |
1505 | .high_speed = true, | 1505 | .high_speed = true, |
1506 | }; | 1506 | }; |
1507 | 1507 | ||
1508 | struct s3c64xx_spi_port_config s5pv210_spi_port_config = { | 1508 | static struct s3c64xx_spi_port_config s5pv210_spi_port_config = { |
1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
1510 | .rx_lvl_offset = 15, | 1510 | .rx_lvl_offset = 15, |
1511 | .tx_st_done = 25, | 1511 | .tx_st_done = 25, |
1512 | .high_speed = true, | 1512 | .high_speed = true, |
1513 | }; | 1513 | }; |
1514 | 1514 | ||
1515 | struct s3c64xx_spi_port_config exynos4_spi_port_config = { | 1515 | static struct s3c64xx_spi_port_config exynos4_spi_port_config = { |
1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, | 1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, |
1517 | .rx_lvl_offset = 15, | 1517 | .rx_lvl_offset = 15, |
1518 | .tx_st_done = 25, | 1518 | .tx_st_done = 25, |
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index d0cafd637199..f2ffd963f1c3 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
@@ -51,10 +51,12 @@ enum android_alarm_return_flags { | |||
51 | #define ANDROID_ALARM_WAIT _IO('a', 1) | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
52 | 52 | ||
53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
54 | #define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | ||
55 | |||
54 | /* Set alarm */ | 56 | /* Set alarm */ |
55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) | 57 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) | 58 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
57 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) | 59 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) |
58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) | 60 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) | 61 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) | 62 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c0fdb00783ed..2359151af7e1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c | |||
@@ -168,7 +168,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
168 | dev->board_ptr = comedi_recognize(driv, it->board_name); | 168 | dev->board_ptr = comedi_recognize(driv, it->board_name); |
169 | if (dev->board_ptr) | 169 | if (dev->board_ptr) |
170 | break; | 170 | break; |
171 | } else if (strcmp(driv->driver_name, it->board_name)) | 171 | } else if (strcmp(driv->driver_name, it->board_name) == 0) |
172 | break; | 172 | break; |
173 | module_put(driv->module); | 173 | module_put(driv->module); |
174 | } | 174 | } |
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 31986608eaf1..6b4d0d68e637 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c | |||
@@ -1349,9 +1349,6 @@ static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, | |||
1349 | } | 1349 | } |
1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
1351 | continue; | 1351 | continue; |
1352 | if (pci_is_enabled(pcidev)) | ||
1353 | continue; | ||
1354 | |||
1355 | if (strcmp(this_board->name, DRV_NAME) == 0) { | 1352 | if (strcmp(this_board->name, DRV_NAME) == 0) { |
1356 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1353 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
1357 | if (pcidev->device == boardtypes[i].device_id) { | 1354 | if (pcidev->device == boardtypes[i].device_id) { |
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index da5ee69d2c9d..dfde0f6328dd 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c | |||
@@ -301,8 +301,6 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, | |||
301 | } | 301 | } |
302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
303 | continue; | 303 | continue; |
304 | if (pci_is_enabled(pcidev)) | ||
305 | continue; | ||
306 | return pcidev; | 304 | return pcidev; |
307 | } | 305 | } |
308 | dev_err(dev->class_dev, | 306 | dev_err(dev->class_dev, |
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 97f06dc8e48d..2d4cb7f638b2 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c | |||
@@ -1064,8 +1064,6 @@ static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev, | |||
1064 | slot != PCI_SLOT(pcidev->devfn)) | 1064 | slot != PCI_SLOT(pcidev->devfn)) |
1065 | continue; | 1065 | continue; |
1066 | } | 1066 | } |
1067 | if (pci_is_enabled(pcidev)) | ||
1068 | continue; | ||
1069 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1067 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
1070 | if (boardtypes[i].vendor_id != pcidev->vendor) | 1068 | if (boardtypes[i].vendor_id != pcidev->vendor) |
1071 | continue; | 1069 | continue; |
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377262c..cc8931fde839 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c | |||
@@ -1412,6 +1412,13 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, | |||
1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
1413 | return -EINVAL; | 1413 | return -EINVAL; |
1414 | } | 1414 | } |
1415 | /* | ||
1416 | * Need to 'get' the PCI device to match the 'put' in dio200_detach(). | ||
1417 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1418 | * support for manual attachment of PCI devices via dio200_attach() | ||
1419 | * has been removed. | ||
1420 | */ | ||
1421 | pci_dev_get(pci_dev); | ||
1415 | return dio200_pci_common_attach(dev, pci_dev); | 1422 | return dio200_pci_common_attach(dev, pci_dev); |
1416 | } | 1423 | } |
1417 | 1424 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba9886b7d..f50287903038 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c | |||
@@ -565,6 +565,13 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, | |||
565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
566 | return -EINVAL; | 566 | return -EINVAL; |
567 | } | 567 | } |
568 | /* | ||
569 | * Need to 'get' the PCI device to match the 'put' in pc236_detach(). | ||
570 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
571 | * support for manual attachment of PCI devices via pc236_attach() | ||
572 | * has been removed. | ||
573 | */ | ||
574 | pci_dev_get(pci_dev); | ||
568 | return pc236_pci_common_attach(dev, pci_dev); | 575 | return pc236_pci_common_attach(dev, pci_dev); |
569 | } | 576 | } |
570 | 577 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ffebba6..8191c4e28e0a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c | |||
@@ -298,6 +298,13 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, | |||
298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | } | 300 | } |
301 | /* | ||
302 | * Need to 'get' the PCI device to match the 'put' in pc263_detach(). | ||
303 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
304 | * support for manual attachment of PCI devices via pc263_attach() | ||
305 | * has been removed. | ||
306 | */ | ||
307 | pci_dev_get(pci_dev); | ||
301 | return pc263_pci_common_attach(dev, pci_dev); | 308 | return pc263_pci_common_attach(dev, pci_dev); |
302 | } | 309 | } |
303 | 310 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e17f13e57f6..8bf109e7bb05 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c | |||
@@ -1503,6 +1503,13 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) | |||
1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); | 1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); |
1504 | return -EINVAL; | 1504 | return -EINVAL; |
1505 | } | 1505 | } |
1506 | /* | ||
1507 | * Need to 'get' the PCI device to match the 'put' in pci224_detach(). | ||
1508 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1509 | * support for manual attachment of PCI devices via pci224_attach() | ||
1510 | * has been removed. | ||
1511 | */ | ||
1512 | pci_dev_get(pci_dev); | ||
1506 | return pci224_attach_common(dev, pci_dev, NULL); | 1513 | return pci224_attach_common(dev, pci_dev, NULL); |
1507 | } | 1514 | } |
1508 | 1515 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1b67d0c61fa7..66e74bd12267 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c | |||
@@ -2925,6 +2925,13 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev, | |||
2925 | "amplc_pci230: BUG! cannot determine board type!\n"); | 2925 | "amplc_pci230: BUG! cannot determine board type!\n"); |
2926 | return -EINVAL; | 2926 | return -EINVAL; |
2927 | } | 2927 | } |
2928 | /* | ||
2929 | * Need to 'get' the PCI device to match the 'put' in pci230_detach(). | ||
2930 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
2931 | * support for manual attachment of PCI devices via pci230_attach() | ||
2932 | * has been removed. | ||
2933 | */ | ||
2934 | pci_dev_get(pci_dev); | ||
2928 | return pci230_attach_common(dev, pci_dev); | 2935 | return pci230_attach_common(dev, pci_dev); |
2929 | } | 2936 | } |
2930 | 2937 | ||
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index ef28385c1482..cad559a1a730 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c | |||
@@ -718,7 +718,8 @@ static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, | |||
718 | continue; | 718 | continue; |
719 | } | 719 | } |
720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || | 720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || |
721 | pcidev->device != 0x0409) | 721 | pcidev->device != 0x0409 || |
722 | pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) | ||
722 | continue; | 723 | continue; |
723 | 724 | ||
724 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { | 725 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { |
@@ -739,6 +740,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
739 | { | 740 | { |
740 | struct pci_dev *pcidev; | 741 | struct pci_dev *pcidev; |
741 | struct comedi_subdevice *s; | 742 | struct comedi_subdevice *s; |
743 | resource_size_t pci_base; | ||
742 | void *aux_data; | 744 | void *aux_data; |
743 | unsigned int aux_len; | 745 | unsigned int aux_len; |
744 | int result; | 746 | int result; |
@@ -758,11 +760,12 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
758 | "failed to enable PCI device and request regions\n"); | 760 | "failed to enable PCI device and request regions\n"); |
759 | return -EIO; | 761 | return -EIO; |
760 | } | 762 | } |
761 | dev->iobase = pci_resource_start(pcidev, 2); | 763 | dev->iobase = 1; /* the "detach" needs this */ |
762 | 764 | ||
763 | devpriv->plx = | 765 | pci_base = pci_resource_start(pcidev, 0); |
764 | ioremap(pci_resource_start(pcidev, 0), DAQBOARD2000_PLX_SIZE); | 766 | devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE); |
765 | devpriv->daq = ioremap(dev->iobase, DAQBOARD2000_DAQ_SIZE); | 767 | pci_base = pci_resource_start(pcidev, 2); |
768 | devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE); | ||
766 | if (!devpriv->plx || !devpriv->daq) | 769 | if (!devpriv->plx || !devpriv->daq) |
767 | return -ENOMEM; | 770 | return -ENOMEM; |
768 | 771 | ||
@@ -799,8 +802,6 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
799 | printk("Interrupt after is: %x\n", interrupt); | 802 | printk("Interrupt after is: %x\n", interrupt); |
800 | */ | 803 | */ |
801 | 804 | ||
802 | dev->iobase = (unsigned long)devpriv->daq; | ||
803 | |||
804 | dev->board_name = this_board->name; | 805 | dev->board_name = this_board->name; |
805 | 806 | ||
806 | s = dev->subdevices + 0; | 807 | s = dev->subdevices + 0; |
@@ -824,7 +825,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
824 | 825 | ||
825 | s = dev->subdevices + 2; | 826 | s = dev->subdevices + 2; |
826 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, | 827 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, |
827 | (unsigned long)(dev->iobase + 0x40)); | 828 | (unsigned long)(devpriv->daq + 0x40)); |
828 | 829 | ||
829 | out: | 830 | out: |
830 | return result; | 831 | return result; |
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 874e02e47668..67a914a10b55 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c | |||
@@ -378,7 +378,7 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
378 | int chan; | 378 | int chan; |
379 | 379 | ||
380 | lsb = data[0] & 0xff; | 380 | lsb = data[0] & 0xff; |
381 | msb = (data[0] >> 8) & 0xf; | 381 | msb = (data[0] >> 8) & 0xff; |
382 | 382 | ||
383 | chan = CR_CHAN(insn->chanspec); | 383 | chan = CR_CHAN(insn->chanspec); |
384 | 384 | ||
@@ -623,7 +623,7 @@ static const struct das08_board_struct das08_boards[] = { | |||
623 | .ai = das08_ai_rinsn, | 623 | .ai = das08_ai_rinsn, |
624 | .ai_nbits = 16, | 624 | .ai_nbits = 16, |
625 | .ai_pg = das08_pg_none, | 625 | .ai_pg = das08_pg_none, |
626 | .ai_encoding = das08_encode12, | 626 | .ai_encoding = das08_encode16, |
627 | .ao = das08jr_ao_winsn, | 627 | .ao = das08jr_ao_winsn, |
628 | .ao_nbits = 16, | 628 | .ao_nbits = 16, |
629 | .di = das08jr_di_rbits, | 629 | .di = das08jr_di_rbits, |
@@ -922,6 +922,13 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) | |||
922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | } | 924 | } |
925 | /* | ||
926 | * Need to 'get' the PCI device to match the 'put' in das08_detach(). | ||
927 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
928 | * support for manual attachment of PCI devices via das08_attach() | ||
929 | * has been removed. | ||
930 | */ | ||
931 | pci_dev_get(pdev); | ||
925 | return das08_pci_attach_common(dev, pdev); | 932 | return das08_pci_attach_common(dev, pdev); |
926 | } | 933 | } |
927 | 934 | ||
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index a6fe6c9be87e..3476cda0fff0 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c | |||
@@ -804,6 +804,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
804 | { | 804 | { |
805 | struct pci_dev *pcidev; | 805 | struct pci_dev *pcidev; |
806 | struct comedi_subdevice *s; | 806 | struct comedi_subdevice *s; |
807 | resource_size_t pci_base; | ||
807 | int ret = 0; | 808 | int ret = 0; |
808 | 809 | ||
809 | dev_dbg(dev->class_dev, "dt3000:\n"); | 810 | dev_dbg(dev->class_dev, "dt3000:\n"); |
@@ -820,9 +821,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
820 | ret = comedi_pci_enable(pcidev, "dt3000"); | 821 | ret = comedi_pci_enable(pcidev, "dt3000"); |
821 | if (ret < 0) | 822 | if (ret < 0) |
822 | return ret; | 823 | return ret; |
824 | dev->iobase = 1; /* the "detach" needs this */ | ||
823 | 825 | ||
824 | dev->iobase = pci_resource_start(pcidev, 0); | 826 | pci_base = pci_resource_start(pcidev, 0); |
825 | devpriv->io_addr = ioremap(dev->iobase, DT3000_SIZE); | 827 | devpriv->io_addr = ioremap(pci_base, DT3000_SIZE); |
826 | if (!devpriv->io_addr) | 828 | if (!devpriv->io_addr) |
827 | return -ENOMEM; | 829 | return -ENOMEM; |
828 | 830 | ||
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 112fdc3e9c69..5aa8be1e7b92 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c | |||
@@ -1619,9 +1619,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
1619 | struct rtdPrivate *devpriv; | 1619 | struct rtdPrivate *devpriv; |
1620 | struct pci_dev *pcidev; | 1620 | struct pci_dev *pcidev; |
1621 | struct comedi_subdevice *s; | 1621 | struct comedi_subdevice *s; |
1622 | resource_size_t pci_base; | ||
1622 | int ret; | 1623 | int ret; |
1623 | resource_size_t physLas1; /* data area */ | ||
1624 | resource_size_t physLcfg; /* PLX9080 */ | ||
1625 | #ifdef USE_DMA | 1624 | #ifdef USE_DMA |
1626 | int index; | 1625 | int index; |
1627 | #endif | 1626 | #endif |
@@ -1655,20 +1654,15 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
1655 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); | 1654 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); |
1656 | return ret; | 1655 | return ret; |
1657 | } | 1656 | } |
1658 | 1657 | dev->iobase = 1; /* the "detach" needs this */ | |
1659 | /* | 1658 | |
1660 | * Initialize base addresses | 1659 | /* Initialize the base addresses */ |
1661 | */ | 1660 | pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX); |
1662 | /* Get the physical address from PCI config */ | 1661 | devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE); |
1663 | dev->iobase = pci_resource_start(pcidev, LAS0_PCIINDEX); | 1662 | pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX); |
1664 | physLas1 = pci_resource_start(pcidev, LAS1_PCIINDEX); | 1663 | devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE); |
1665 | physLcfg = pci_resource_start(pcidev, LCFG_PCIINDEX); | 1664 | pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX); |
1666 | /* Now have the kernel map this into memory */ | 1665 | devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE); |
1667 | /* ASSUME page aligned */ | ||
1668 | devpriv->las0 = ioremap_nocache(dev->iobase, LAS0_PCISIZE); | ||
1669 | devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); | ||
1670 | devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); | ||
1671 | |||
1672 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) | 1666 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) |
1673 | return -ENOMEM; | 1667 | return -ENOMEM; |
1674 | 1668 | ||
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 848c7ec06976..11ee83681da7 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c | |||
@@ -102,6 +102,7 @@ sampling rate. If you sample two channels you get 4kHz and so on. | |||
102 | #define BULK_TIMEOUT 1000 | 102 | #define BULK_TIMEOUT 1000 |
103 | 103 | ||
104 | /* constants for "firmware" upload and download */ | 104 | /* constants for "firmware" upload and download */ |
105 | #define FIRMWARE "usbdux_firmware.bin" | ||
105 | #define USBDUXSUB_FIRMWARE 0xA0 | 106 | #define USBDUXSUB_FIRMWARE 0xA0 |
106 | #define VENDOR_DIR_IN 0xC0 | 107 | #define VENDOR_DIR_IN 0xC0 |
107 | #define VENDOR_DIR_OUT 0x40 | 108 | #define VENDOR_DIR_OUT 0x40 |
@@ -2791,7 +2792,7 @@ static int usbdux_usb_probe(struct usb_interface *uinterf, | |||
2791 | 2792 | ||
2792 | ret = request_firmware_nowait(THIS_MODULE, | 2793 | ret = request_firmware_nowait(THIS_MODULE, |
2793 | FW_ACTION_HOTPLUG, | 2794 | FW_ACTION_HOTPLUG, |
2794 | "usbdux_firmware.bin", | 2795 | FIRMWARE, |
2795 | &udev->dev, | 2796 | &udev->dev, |
2796 | GFP_KERNEL, | 2797 | GFP_KERNEL, |
2797 | usbduxsub + index, | 2798 | usbduxsub + index, |
@@ -2850,3 +2851,4 @@ module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); | |||
2850 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2851 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
2851 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); | 2852 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); |
2852 | MODULE_LICENSE("GPL"); | 2853 | MODULE_LICENSE("GPL"); |
2854 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index d9911588c10a..8eb41257c6ce 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c | |||
@@ -57,6 +57,7 @@ | |||
57 | /* | 57 | /* |
58 | * constants for "firmware" upload and download | 58 | * constants for "firmware" upload and download |
59 | */ | 59 | */ |
60 | #define FIRMWARE "usbduxfast_firmware.bin" | ||
60 | #define USBDUXFASTSUB_FIRMWARE 0xA0 | 61 | #define USBDUXFASTSUB_FIRMWARE 0xA0 |
61 | #define VENDOR_DIR_IN 0xC0 | 62 | #define VENDOR_DIR_IN 0xC0 |
62 | #define VENDOR_DIR_OUT 0x40 | 63 | #define VENDOR_DIR_OUT 0x40 |
@@ -1706,7 +1707,7 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, | |||
1706 | 1707 | ||
1707 | ret = request_firmware_nowait(THIS_MODULE, | 1708 | ret = request_firmware_nowait(THIS_MODULE, |
1708 | FW_ACTION_HOTPLUG, | 1709 | FW_ACTION_HOTPLUG, |
1709 | "usbduxfast_firmware.bin", | 1710 | FIRMWARE, |
1710 | &udev->dev, | 1711 | &udev->dev, |
1711 | GFP_KERNEL, | 1712 | GFP_KERNEL, |
1712 | usbduxfastsub + index, | 1713 | usbduxfastsub + index, |
@@ -1774,3 +1775,4 @@ module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver); | |||
1774 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 1775 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
1775 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); | 1776 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); |
1776 | MODULE_LICENSE("GPL"); | 1777 | MODULE_LICENSE("GPL"); |
1778 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 543e604791e2..f54ab8c2fcfd 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c | |||
@@ -63,6 +63,7 @@ Status: testing | |||
63 | #define BULK_TIMEOUT 1000 | 63 | #define BULK_TIMEOUT 1000 |
64 | 64 | ||
65 | /* constants for "firmware" upload and download */ | 65 | /* constants for "firmware" upload and download */ |
66 | #define FIRMWARE "usbduxsigma_firmware.bin" | ||
66 | #define USBDUXSUB_FIRMWARE 0xA0 | 67 | #define USBDUXSUB_FIRMWARE 0xA0 |
67 | #define VENDOR_DIR_IN 0xC0 | 68 | #define VENDOR_DIR_IN 0xC0 |
68 | #define VENDOR_DIR_OUT 0x40 | 69 | #define VENDOR_DIR_OUT 0x40 |
@@ -2780,7 +2781,7 @@ static int usbduxsigma_usb_probe(struct usb_interface *uinterf, | |||
2780 | 2781 | ||
2781 | ret = request_firmware_nowait(THIS_MODULE, | 2782 | ret = request_firmware_nowait(THIS_MODULE, |
2782 | FW_ACTION_HOTPLUG, | 2783 | FW_ACTION_HOTPLUG, |
2783 | "usbduxsigma_firmware.bin", | 2784 | FIRMWARE, |
2784 | &udev->dev, | 2785 | &udev->dev, |
2785 | GFP_KERNEL, | 2786 | GFP_KERNEL, |
2786 | usbduxsub + index, | 2787 | usbduxsub + index, |
@@ -2845,3 +2846,4 @@ module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); | |||
2845 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2846 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
2846 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); | 2847 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); |
2847 | MODULE_LICENSE("GPL"); | 2848 | MODULE_LICENSE("GPL"); |
2849 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig index cee8d48d2af9..ad2a1096e920 100644 --- a/drivers/staging/csr/Kconfig +++ b/drivers/staging/csr/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config CSR_WIFI | 1 | config CSR_WIFI |
2 | tristate "CSR wireless driver" | 2 | tristate "CSR wireless driver" |
3 | depends on MMC && CFG80211_WEXT | 3 | depends on MMC && CFG80211_WEXT && INET |
4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
5 | select WEXT_PRIV | 5 | select WEXT_PRIV |
6 | help | 6 | help |
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967a..f3da59063ed2 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c | |||
@@ -121,8 +121,10 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev, | |||
121 | if (rx_array == NULL) | 121 | if (rx_array == NULL) |
122 | return -ENOMEM; | 122 | return -ENOMEM; |
123 | ret = lis3l02dq_read_all(indio_dev, rx_array); | 123 | ret = lis3l02dq_read_all(indio_dev, rx_array); |
124 | if (ret < 0) | 124 | if (ret < 0) { |
125 | kfree(rx_array); | ||
125 | return ret; | 126 | return ret; |
127 | } | ||
126 | for (i = 0; i < scan_count; i++) | 128 | for (i = 0; i < scan_count; i++) |
127 | data[i] = combine_8_to_16(rx_array[i*4+1], | 129 | data[i] = combine_8_to_16(rx_array[i*4+1], |
128 | rx_array[i*4+3]); | 130 | rx_array[i*4+3]); |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 22c3923d55eb..19a064d649e3 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
@@ -647,6 +647,8 @@ static ssize_t ad7192_write_frequency(struct device *dev, | |||
647 | ret = strict_strtoul(buf, 10, &lval); | 647 | ret = strict_strtoul(buf, 10, &lval); |
648 | if (ret) | 648 | if (ret) |
649 | return ret; | 649 | return ret; |
650 | if (lval == 0) | ||
651 | return -EINVAL; | ||
650 | 652 | ||
651 | mutex_lock(&indio_dev->mlock); | 653 | mutex_lock(&indio_dev->mlock); |
652 | if (iio_buffer_enabled(indio_dev)) { | 654 | if (iio_buffer_enabled(indio_dev)) { |
@@ -754,7 +756,7 @@ static ssize_t ad7192_set(struct device *dev, | |||
754 | else | 756 | else |
755 | st->mode &= ~AD7192_MODE_ACX; | 757 | st->mode &= ~AD7192_MODE_ACX; |
756 | 758 | ||
757 | ad7192_write_reg(st, AD7192_REG_GPOCON, 3, st->mode); | 759 | ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); |
758 | break; | 760 | break; |
759 | default: | 761 | default: |
760 | ret = -EINVAL; | 762 | ret = -EINVAL; |
@@ -798,6 +800,11 @@ static const struct attribute_group ad7195_attribute_group = { | |||
798 | .attrs = ad7195_attributes, | 800 | .attrs = ad7195_attributes, |
799 | }; | 801 | }; |
800 | 802 | ||
803 | static unsigned int ad7192_get_temp_scale(bool unipolar) | ||
804 | { | ||
805 | return unipolar ? 2815 * 2 : 2815; | ||
806 | } | ||
807 | |||
801 | static int ad7192_read_raw(struct iio_dev *indio_dev, | 808 | static int ad7192_read_raw(struct iio_dev *indio_dev, |
802 | struct iio_chan_spec const *chan, | 809 | struct iio_chan_spec const *chan, |
803 | int *val, | 810 | int *val, |
@@ -824,19 +831,6 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
824 | *val = (smpl >> chan->scan_type.shift) & | 831 | *val = (smpl >> chan->scan_type.shift) & |
825 | ((1 << (chan->scan_type.realbits)) - 1); | 832 | ((1 << (chan->scan_type.realbits)) - 1); |
826 | 833 | ||
827 | switch (chan->type) { | ||
828 | case IIO_VOLTAGE: | ||
829 | if (!unipolar) | ||
830 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
831 | break; | ||
832 | case IIO_TEMP: | ||
833 | *val -= 0x800000; | ||
834 | *val /= 2815; /* temp Kelvin */ | ||
835 | *val -= 273; /* temp Celsius */ | ||
836 | break; | ||
837 | default: | ||
838 | return -EINVAL; | ||
839 | } | ||
840 | return IIO_VAL_INT; | 834 | return IIO_VAL_INT; |
841 | 835 | ||
842 | case IIO_CHAN_INFO_SCALE: | 836 | case IIO_CHAN_INFO_SCALE: |
@@ -848,11 +842,21 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
848 | mutex_unlock(&indio_dev->mlock); | 842 | mutex_unlock(&indio_dev->mlock); |
849 | return IIO_VAL_INT_PLUS_NANO; | 843 | return IIO_VAL_INT_PLUS_NANO; |
850 | case IIO_TEMP: | 844 | case IIO_TEMP: |
851 | *val = 1000; | 845 | *val = 0; |
852 | return IIO_VAL_INT; | 846 | *val2 = 1000000000 / ad7192_get_temp_scale(unipolar); |
847 | return IIO_VAL_INT_PLUS_NANO; | ||
853 | default: | 848 | default: |
854 | return -EINVAL; | 849 | return -EINVAL; |
855 | } | 850 | } |
851 | case IIO_CHAN_INFO_OFFSET: | ||
852 | if (!unipolar) | ||
853 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
854 | else | ||
855 | *val = 0; | ||
856 | /* Kelvin to Celsius */ | ||
857 | if (chan->type == IIO_TEMP) | ||
858 | *val -= 273 * ad7192_get_temp_scale(unipolar); | ||
859 | return IIO_VAL_INT; | ||
856 | } | 860 | } |
857 | 861 | ||
858 | return -EINVAL; | 862 | return -EINVAL; |
@@ -890,7 +894,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, | |||
890 | } | 894 | } |
891 | ret = 0; | 895 | ret = 0; |
892 | } | 896 | } |
893 | 897 | break; | |
894 | default: | 898 | default: |
895 | ret = -EINVAL; | 899 | ret = -EINVAL; |
896 | } | 900 | } |
@@ -942,20 +946,22 @@ static const struct iio_info ad7195_info = { | |||
942 | .channel = _chan, \ | 946 | .channel = _chan, \ |
943 | .channel2 = _chan2, \ | 947 | .channel2 = _chan2, \ |
944 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 948 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
945 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 949 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
950 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
946 | .address = _address, \ | 951 | .address = _address, \ |
947 | .scan_index = _si, \ | 952 | .scan_index = _si, \ |
948 | .scan_type = IIO_ST('s', 24, 32, 0)} | 953 | .scan_type = IIO_ST('u', 24, 32, 0)} |
949 | 954 | ||
950 | #define AD7192_CHAN(_chan, _address, _si) \ | 955 | #define AD7192_CHAN(_chan, _address, _si) \ |
951 | { .type = IIO_VOLTAGE, \ | 956 | { .type = IIO_VOLTAGE, \ |
952 | .indexed = 1, \ | 957 | .indexed = 1, \ |
953 | .channel = _chan, \ | 958 | .channel = _chan, \ |
954 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 959 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
955 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 960 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
961 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
956 | .address = _address, \ | 962 | .address = _address, \ |
957 | .scan_index = _si, \ | 963 | .scan_index = _si, \ |
958 | .scan_type = IIO_ST('s', 24, 32, 0)} | 964 | .scan_type = IIO_ST('u', 24, 32, 0)} |
959 | 965 | ||
960 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ | 966 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ |
961 | { .type = IIO_TEMP, \ | 967 | { .type = IIO_TEMP, \ |
@@ -965,7 +971,7 @@ static const struct iio_info ad7195_info = { | |||
965 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ | 971 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ |
966 | .address = _address, \ | 972 | .address = _address, \ |
967 | .scan_index = _si, \ | 973 | .scan_index = _si, \ |
968 | .scan_type = IIO_ST('s', 24, 32, 0)} | 974 | .scan_type = IIO_ST('u', 24, 32, 0)} |
969 | 975 | ||
970 | static struct iio_chan_spec ad7192_channels[] = { | 976 | static struct iio_chan_spec ad7192_channels[] = { |
971 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), | 977 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), |
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index fd1d855ff57a..506016f01593 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c | |||
@@ -76,7 +76,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) | |||
76 | struct iio_dev *indio_dev = pf->indio_dev; | 76 | struct iio_dev *indio_dev = pf->indio_dev; |
77 | struct ad7298_state *st = iio_priv(indio_dev); | 77 | struct ad7298_state *st = iio_priv(indio_dev); |
78 | struct iio_buffer *ring = indio_dev->buffer; | 78 | struct iio_buffer *ring = indio_dev->buffer; |
79 | s64 time_ns; | 79 | s64 time_ns = 0; |
80 | __u16 buf[16]; | 80 | __u16 buf[16]; |
81 | int b_sent, i; | 81 | int b_sent, i; |
82 | 82 | ||
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 1ece2ac8de56..19ee49c95de4 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c | |||
@@ -131,9 +131,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
131 | .indexed = 1, | 131 | .indexed = 1, |
132 | .channel = 0, | 132 | .channel = 0, |
133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
134 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 134 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
135 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
135 | .scan_type = { | 136 | .scan_type = { |
136 | .sign = 's', | 137 | .sign = 'u', |
137 | .realbits = 24, | 138 | .realbits = 24, |
138 | .storagebits = 32, | 139 | .storagebits = 32, |
139 | .shift = 8, | 140 | .shift = 8, |
@@ -146,9 +147,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
146 | .indexed = 1, | 147 | .indexed = 1, |
147 | .channel = 0, | 148 | .channel = 0, |
148 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 149 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
149 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 150 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
151 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
150 | .scan_type = { | 152 | .scan_type = { |
151 | .sign = 's', | 153 | .sign = 'u', |
152 | .realbits = 20, | 154 | .realbits = 20, |
153 | .storagebits = 32, | 155 | .storagebits = 32, |
154 | .shift = 12, | 156 | .shift = 12, |
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 76fdd7145fc5..112e2b7b5bc4 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c | |||
@@ -563,8 +563,9 @@ static ssize_t ad7793_show_scale_available(struct device *dev, | |||
563 | return len; | 563 | return len; |
564 | } | 564 | } |
565 | 565 | ||
566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, | 566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, |
567 | S_IRUGO, ad7793_show_scale_available, NULL, 0); | 567 | in_voltage-voltage_scale_available, S_IRUGO, |
568 | ad7793_show_scale_available, NULL, 0); | ||
568 | 569 | ||
569 | static struct attribute *ad7793_attributes[] = { | 570 | static struct attribute *ad7793_attributes[] = { |
570 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | 571 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
@@ -604,9 +605,6 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
604 | *val = (smpl >> chan->scan_type.shift) & | 605 | *val = (smpl >> chan->scan_type.shift) & |
605 | ((1 << (chan->scan_type.realbits)) - 1); | 606 | ((1 << (chan->scan_type.realbits)) - 1); |
606 | 607 | ||
607 | if (!unipolar) | ||
608 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
609 | |||
610 | return IIO_VAL_INT; | 608 | return IIO_VAL_INT; |
611 | 609 | ||
612 | case IIO_CHAN_INFO_SCALE: | 610 | case IIO_CHAN_INFO_SCALE: |
@@ -620,25 +618,38 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
620 | return IIO_VAL_INT_PLUS_NANO; | 618 | return IIO_VAL_INT_PLUS_NANO; |
621 | } else { | 619 | } else { |
622 | /* 1170mV / 2^23 * 6 */ | 620 | /* 1170mV / 2^23 * 6 */ |
623 | scale_uv = (1170ULL * 100000000ULL * 6ULL) | 621 | scale_uv = (1170ULL * 100000000ULL * 6ULL); |
624 | >> (chan->scan_type.realbits - | ||
625 | (unipolar ? 0 : 1)); | ||
626 | } | 622 | } |
627 | break; | 623 | break; |
628 | case IIO_TEMP: | 624 | case IIO_TEMP: |
629 | /* Always uses unity gain and internal ref */ | 625 | /* 1170mV / 0.81 mV/C / 2^23 */ |
630 | scale_uv = (2500ULL * 100000000ULL) | 626 | scale_uv = 1444444444444ULL; |
631 | >> (chan->scan_type.realbits - | ||
632 | (unipolar ? 0 : 1)); | ||
633 | break; | 627 | break; |
634 | default: | 628 | default: |
635 | return -EINVAL; | 629 | return -EINVAL; |
636 | } | 630 | } |
637 | 631 | ||
638 | *val2 = do_div(scale_uv, 100000000) * 10; | 632 | scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1)); |
639 | *val = scale_uv; | 633 | *val = 0; |
640 | 634 | *val2 = scale_uv; | |
641 | return IIO_VAL_INT_PLUS_NANO; | 635 | return IIO_VAL_INT_PLUS_NANO; |
636 | case IIO_CHAN_INFO_OFFSET: | ||
637 | if (!unipolar) | ||
638 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
639 | else | ||
640 | *val = 0; | ||
641 | |||
642 | /* Kelvin to Celsius */ | ||
643 | if (chan->type == IIO_TEMP) { | ||
644 | unsigned long long offset; | ||
645 | unsigned int shift; | ||
646 | |||
647 | shift = chan->scan_type.realbits - (unipolar ? 0 : 1); | ||
648 | offset = 273ULL << shift; | ||
649 | do_div(offset, 1444); | ||
650 | *val -= offset; | ||
651 | } | ||
652 | return IIO_VAL_INT; | ||
642 | } | 653 | } |
643 | return -EINVAL; | 654 | return -EINVAL; |
644 | } | 655 | } |
@@ -676,7 +687,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, | |||
676 | } | 687 | } |
677 | ret = 0; | 688 | ret = 0; |
678 | } | 689 | } |
679 | 690 | break; | |
680 | default: | 691 | default: |
681 | ret = -EINVAL; | 692 | ret = -EINVAL; |
682 | } | 693 | } |
@@ -720,9 +731,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
720 | .channel2 = 0, | 731 | .channel2 = 0, |
721 | .address = AD7793_CH_AIN1P_AIN1M, | 732 | .address = AD7793_CH_AIN1P_AIN1M, |
722 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 733 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
723 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 734 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
735 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
724 | .scan_index = 0, | 736 | .scan_index = 0, |
725 | .scan_type = IIO_ST('s', 24, 32, 0) | 737 | .scan_type = IIO_ST('u', 24, 32, 0) |
726 | }, | 738 | }, |
727 | .channel[1] = { | 739 | .channel[1] = { |
728 | .type = IIO_VOLTAGE, | 740 | .type = IIO_VOLTAGE, |
@@ -732,9 +744,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
732 | .channel2 = 1, | 744 | .channel2 = 1, |
733 | .address = AD7793_CH_AIN2P_AIN2M, | 745 | .address = AD7793_CH_AIN2P_AIN2M, |
734 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
735 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 747 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
748 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
736 | .scan_index = 1, | 749 | .scan_index = 1, |
737 | .scan_type = IIO_ST('s', 24, 32, 0) | 750 | .scan_type = IIO_ST('u', 24, 32, 0) |
738 | }, | 751 | }, |
739 | .channel[2] = { | 752 | .channel[2] = { |
740 | .type = IIO_VOLTAGE, | 753 | .type = IIO_VOLTAGE, |
@@ -744,9 +757,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
744 | .channel2 = 2, | 757 | .channel2 = 2, |
745 | .address = AD7793_CH_AIN3P_AIN3M, | 758 | .address = AD7793_CH_AIN3P_AIN3M, |
746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
747 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 760 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
761 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
748 | .scan_index = 2, | 762 | .scan_index = 2, |
749 | .scan_type = IIO_ST('s', 24, 32, 0) | 763 | .scan_type = IIO_ST('u', 24, 32, 0) |
750 | }, | 764 | }, |
751 | .channel[3] = { | 765 | .channel[3] = { |
752 | .type = IIO_VOLTAGE, | 766 | .type = IIO_VOLTAGE, |
@@ -757,9 +771,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
757 | .channel2 = 2, | 771 | .channel2 = 2, |
758 | .address = AD7793_CH_AIN1M_AIN1M, | 772 | .address = AD7793_CH_AIN1M_AIN1M, |
759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 773 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
760 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 774 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
775 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
761 | .scan_index = 3, | 776 | .scan_index = 3, |
762 | .scan_type = IIO_ST('s', 24, 32, 0) | 777 | .scan_type = IIO_ST('u', 24, 32, 0) |
763 | }, | 778 | }, |
764 | .channel[4] = { | 779 | .channel[4] = { |
765 | .type = IIO_TEMP, | 780 | .type = IIO_TEMP, |
@@ -769,7 +784,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
769 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 784 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
770 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 785 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
771 | .scan_index = 4, | 786 | .scan_index = 4, |
772 | .scan_type = IIO_ST('s', 24, 32, 0), | 787 | .scan_type = IIO_ST('u', 24, 32, 0), |
773 | }, | 788 | }, |
774 | .channel[5] = { | 789 | .channel[5] = { |
775 | .type = IIO_VOLTAGE, | 790 | .type = IIO_VOLTAGE, |
@@ -778,9 +793,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
778 | .channel = 4, | 793 | .channel = 4, |
779 | .address = AD7793_CH_AVDD_MONITOR, | 794 | .address = AD7793_CH_AVDD_MONITOR, |
780 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
781 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 796 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
797 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
782 | .scan_index = 5, | 798 | .scan_index = 5, |
783 | .scan_type = IIO_ST('s', 24, 32, 0), | 799 | .scan_type = IIO_ST('u', 24, 32, 0), |
784 | }, | 800 | }, |
785 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 801 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
786 | }, | 802 | }, |
@@ -793,9 +809,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
793 | .channel2 = 0, | 809 | .channel2 = 0, |
794 | .address = AD7793_CH_AIN1P_AIN1M, | 810 | .address = AD7793_CH_AIN1P_AIN1M, |
795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 811 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
796 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 812 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
813 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
797 | .scan_index = 0, | 814 | .scan_index = 0, |
798 | .scan_type = IIO_ST('s', 16, 32, 0) | 815 | .scan_type = IIO_ST('u', 16, 32, 0) |
799 | }, | 816 | }, |
800 | .channel[1] = { | 817 | .channel[1] = { |
801 | .type = IIO_VOLTAGE, | 818 | .type = IIO_VOLTAGE, |
@@ -805,9 +822,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
805 | .channel2 = 1, | 822 | .channel2 = 1, |
806 | .address = AD7793_CH_AIN2P_AIN2M, | 823 | .address = AD7793_CH_AIN2P_AIN2M, |
807 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 824 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
808 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 825 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
826 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
809 | .scan_index = 1, | 827 | .scan_index = 1, |
810 | .scan_type = IIO_ST('s', 16, 32, 0) | 828 | .scan_type = IIO_ST('u', 16, 32, 0) |
811 | }, | 829 | }, |
812 | .channel[2] = { | 830 | .channel[2] = { |
813 | .type = IIO_VOLTAGE, | 831 | .type = IIO_VOLTAGE, |
@@ -817,9 +835,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
817 | .channel2 = 2, | 835 | .channel2 = 2, |
818 | .address = AD7793_CH_AIN3P_AIN3M, | 836 | .address = AD7793_CH_AIN3P_AIN3M, |
819 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 837 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
820 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 838 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
839 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
821 | .scan_index = 2, | 840 | .scan_index = 2, |
822 | .scan_type = IIO_ST('s', 16, 32, 0) | 841 | .scan_type = IIO_ST('u', 16, 32, 0) |
823 | }, | 842 | }, |
824 | .channel[3] = { | 843 | .channel[3] = { |
825 | .type = IIO_VOLTAGE, | 844 | .type = IIO_VOLTAGE, |
@@ -830,9 +849,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
830 | .channel2 = 2, | 849 | .channel2 = 2, |
831 | .address = AD7793_CH_AIN1M_AIN1M, | 850 | .address = AD7793_CH_AIN1M_AIN1M, |
832 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 851 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
833 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 852 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
853 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
834 | .scan_index = 3, | 854 | .scan_index = 3, |
835 | .scan_type = IIO_ST('s', 16, 32, 0) | 855 | .scan_type = IIO_ST('u', 16, 32, 0) |
836 | }, | 856 | }, |
837 | .channel[4] = { | 857 | .channel[4] = { |
838 | .type = IIO_TEMP, | 858 | .type = IIO_TEMP, |
@@ -842,7 +862,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
842 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 862 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
843 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 863 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
844 | .scan_index = 4, | 864 | .scan_index = 4, |
845 | .scan_type = IIO_ST('s', 16, 32, 0), | 865 | .scan_type = IIO_ST('u', 16, 32, 0), |
846 | }, | 866 | }, |
847 | .channel[5] = { | 867 | .channel[5] = { |
848 | .type = IIO_VOLTAGE, | 868 | .type = IIO_VOLTAGE, |
@@ -851,9 +871,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
851 | .channel = 4, | 871 | .channel = 4, |
852 | .address = AD7793_CH_AVDD_MONITOR, | 872 | .address = AD7793_CH_AVDD_MONITOR, |
853 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 873 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
854 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 874 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
875 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
855 | .scan_index = 5, | 876 | .scan_index = 5, |
856 | .scan_type = IIO_ST('s', 16, 32, 0), | 877 | .scan_type = IIO_ST('u', 16, 32, 0), |
857 | }, | 878 | }, |
858 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 879 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
859 | }, | 880 | }, |
@@ -901,7 +922,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) | |||
901 | else if (voltage_uv) | 922 | else if (voltage_uv) |
902 | st->int_vref_mv = voltage_uv / 1000; | 923 | st->int_vref_mv = voltage_uv / 1000; |
903 | else | 924 | else |
904 | st->int_vref_mv = 2500; /* Build-in ref */ | 925 | st->int_vref_mv = 1170; /* Build-in ref */ |
905 | 926 | ||
906 | spi_set_drvdata(spi, indio_dev); | 927 | spi_set_drvdata(spi, indio_dev); |
907 | st->spi = spi; | 928 | st->spi = spi; |
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431287ac..eb8e9d69efd3 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c | |||
@@ -195,6 +195,8 @@ static ssize_t adis16260_write_frequency(struct device *dev, | |||
195 | ret = strict_strtol(buf, 10, &val); | 195 | ret = strict_strtol(buf, 10, &val); |
196 | if (ret) | 196 | if (ret) |
197 | return ret; | 197 | return ret; |
198 | if (val == 0) | ||
199 | return -EINVAL; | ||
198 | 200 | ||
199 | mutex_lock(&indio_dev->mlock); | 201 | mutex_lock(&indio_dev->mlock); |
200 | if (spi_get_device_id(st->us)) { | 202 | if (spi_get_device_id(st->us)) { |
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c17779b5a..a618327e06ed 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c | |||
@@ -234,6 +234,8 @@ static ssize_t adis16400_write_frequency(struct device *dev, | |||
234 | ret = strict_strtol(buf, 10, &val); | 234 | ret = strict_strtol(buf, 10, &val); |
235 | if (ret) | 235 | if (ret) |
236 | return ret; | 236 | return ret; |
237 | if (val == 0) | ||
238 | return -EINVAL; | ||
237 | 239 | ||
238 | mutex_lock(&indio_dev->mlock); | 240 | mutex_lock(&indio_dev->mlock); |
239 | 241 | ||
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2f..3ccff189f258 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c | |||
@@ -425,6 +425,8 @@ static ssize_t ade7753_write_frequency(struct device *dev, | |||
425 | ret = strict_strtol(buf, 10, &val); | 425 | ret = strict_strtol(buf, 10, &val); |
426 | if (ret) | 426 | if (ret) |
427 | return ret; | 427 | return ret; |
428 | if (val == 0) | ||
429 | return -EINVAL; | ||
428 | 430 | ||
429 | mutex_lock(&indio_dev->mlock); | 431 | mutex_lock(&indio_dev->mlock); |
430 | 432 | ||
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a5e877..abb1e9c8d094 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c | |||
@@ -445,6 +445,8 @@ static ssize_t ade7754_write_frequency(struct device *dev, | |||
445 | ret = strict_strtol(buf, 10, &val); | 445 | ret = strict_strtol(buf, 10, &val); |
446 | if (ret) | 446 | if (ret) |
447 | return ret; | 447 | return ret; |
448 | if (val == 0) | ||
449 | return -EINVAL; | ||
448 | 450 | ||
449 | mutex_lock(&indio_dev->mlock); | 451 | mutex_lock(&indio_dev->mlock); |
450 | 452 | ||
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa9612..eb0a2a98f388 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c | |||
@@ -385,6 +385,8 @@ static ssize_t ade7759_write_frequency(struct device *dev, | |||
385 | ret = strict_strtol(buf, 10, &val); | 385 | ret = strict_strtol(buf, 10, &val); |
386 | if (ret) | 386 | if (ret) |
387 | return ret; | 387 | return ret; |
388 | if (val == 0) | ||
389 | return -EINVAL; | ||
388 | 390 | ||
389 | mutex_lock(&indio_dev->mlock); | 391 | mutex_lock(&indio_dev->mlock); |
390 | 392 | ||
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35f75b0..d0a7e408efe9 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) | |||
837 | } | 837 | } |
838 | 838 | ||
839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, | 839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, |
840 | ARRAY_SIZE(nvec_devices), base, 0); | 840 | ARRAY_SIZE(nvec_devices), base, 0, NULL); |
841 | if (ret) | 841 | if (ret) |
842 | dev_err(nvec->dev, "error adding subdevices\n"); | 842 | dev_err(nvec->dev, "error adding subdevices\n"); |
843 | 843 | ||
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 5e2856c0e0bb..55e9c8655850 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c | |||
@@ -48,13 +48,20 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode, | |||
48 | mode->vsync_end = mode->vsync_start + timings->vsw; | 48 | mode->vsync_end = mode->vsync_start + timings->vsw; |
49 | mode->vtotal = mode->vsync_end + timings->vbp; | 49 | mode->vtotal = mode->vsync_end + timings->vbp; |
50 | 50 | ||
51 | /* note: whether or not it is interlaced, +/- h/vsync, etc, | 51 | mode->flags = 0; |
52 | * which should be set in the mode flags, is not exposed in | 52 | |
53 | * the omap_video_timings struct.. but hdmi driver tracks | 53 | if (timings->interlace) |
54 | * those separately so all we have to have to set the mode | 54 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
55 | * is the way to recover these timings values, and the | 55 | |
56 | * omap_dss_driver would do the rest. | 56 | if (timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) |
57 | */ | 57 | mode->flags |= DRM_MODE_FLAG_PHSYNC; |
58 | else | ||
59 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
60 | |||
61 | if (timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) | ||
62 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
63 | else | ||
64 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
58 | } | 65 | } |
59 | 66 | ||
60 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | 67 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, |
@@ -71,6 +78,22 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | |||
71 | timings->vfp = mode->vsync_start - mode->vdisplay; | 78 | timings->vfp = mode->vsync_start - mode->vdisplay; |
72 | timings->vsw = mode->vsync_end - mode->vsync_start; | 79 | timings->vsw = mode->vsync_end - mode->vsync_start; |
73 | timings->vbp = mode->vtotal - mode->vsync_end; | 80 | timings->vbp = mode->vtotal - mode->vsync_end; |
81 | |||
82 | timings->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); | ||
83 | |||
84 | if (mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
85 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
86 | else | ||
87 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
88 | |||
89 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
90 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
91 | else | ||
92 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
93 | |||
94 | timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
95 | timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
96 | timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
74 | } | 97 | } |
75 | 98 | ||
76 | static void omap_connector_dpms(struct drm_connector *connector, int mode) | 99 | static void omap_connector_dpms(struct drm_connector *connector, int mode) |
@@ -187,7 +210,7 @@ static int omap_connector_get_modes(struct drm_connector *connector) | |||
187 | } | 210 | } |
188 | } else { | 211 | } else { |
189 | struct drm_display_mode *mode = drm_mode_create(dev); | 212 | struct drm_display_mode *mode = drm_mode_create(dev); |
190 | struct omap_video_timings timings; | 213 | struct omap_video_timings timings = {0}; |
191 | 214 | ||
192 | dssdrv->get_timings(dssdev, &timings); | 215 | dssdrv->get_timings(dssdev, &timings); |
193 | 216 | ||
@@ -291,7 +314,7 @@ void omap_connector_mode_set(struct drm_connector *connector, | |||
291 | struct omap_connector *omap_connector = to_omap_connector(connector); | 314 | struct omap_connector *omap_connector = to_omap_connector(connector); |
292 | struct omap_dss_device *dssdev = omap_connector->dssdev; | 315 | struct omap_dss_device *dssdev = omap_connector->dssdev; |
293 | struct omap_dss_driver *dssdrv = dssdev->driver; | 316 | struct omap_dss_driver *dssdrv = dssdev->driver; |
294 | struct omap_video_timings timings; | 317 | struct omap_video_timings timings = {0}; |
295 | 318 | ||
296 | copy_timings_drm_to_omap(&timings, mode); | 319 | copy_timings_drm_to_omap(&timings, mode); |
297 | 320 | ||
diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index d98321945802..758ce0a8d82e 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/cdev.h> | 8 | #include <linux/cdev.h> |
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/etherdevice.h> | ||
11 | #include <linux/poll.h> | 12 | #include <linux/poll.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include "ozconfig.h" | 14 | #include "ozconfig.h" |
@@ -213,7 +214,7 @@ static int oz_set_active_pd(u8 *addr) | |||
213 | if (old_pd) | 214 | if (old_pd) |
214 | oz_pd_put(old_pd); | 215 | oz_pd_put(old_pd); |
215 | } else { | 216 | } else { |
216 | if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) { | 217 | if (is_zero_ether_addr(addr)) { |
217 | spin_lock_bh(&g_cdev.lock); | 218 | spin_lock_bh(&g_cdev.lock); |
218 | pd = g_cdev.active_pd; | 219 | pd = g_cdev.active_pd; |
219 | g_cdev.active_pd = 0; | 220 | g_cdev.active_pd = 0; |
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 0e26d5f6cf2d..495ee1205e02 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c | |||
@@ -117,13 +117,8 @@ void r8712_recv_indicatepkt(struct _adapter *padapter, | |||
117 | if (skb == NULL) | 117 | if (skb == NULL) |
118 | goto _recv_indicatepkt_drop; | 118 | goto _recv_indicatepkt_drop; |
119 | skb->data = precv_frame->u.hdr.rx_data; | 119 | skb->data = precv_frame->u.hdr.rx_data; |
120 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
121 | skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - | ||
122 | precv_frame->u.hdr.rx_head); | ||
123 | #else | ||
124 | skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; | ||
125 | #endif | ||
126 | skb->len = precv_frame->u.hdr.len; | 120 | skb->len = precv_frame->u.hdr.len; |
121 | skb_set_tail_pointer(skb, skb->len); | ||
127 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) | 122 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) |
128 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
129 | else | 124 | else |
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a2b582..3aa895ec6507 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c | |||
@@ -200,7 +200,7 @@ s_vProcessRxMACHeader ( | |||
200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { | 200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { |
201 | cbHeaderSize += 6; | 201 | cbHeaderSize += 6; |
202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
203 | if ((*pwType == cpu_to_le16(ETH_P_IPX)) || | 203 | if ((*pwType == cpu_to_be16(ETH_P_IPX)) || |
204 | (*pwType == cpu_to_le16(0xF380))) { | 204 | (*pwType == cpu_to_le16(0xF380))) { |
205 | cbHeaderSize -= 8; | 205 | cbHeaderSize -= 8; |
206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index b06fd5b723fa..d536756549e6 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c | |||
@@ -189,7 +189,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); | |||
189 | // Static vars definitions | 189 | // Static vars definitions |
190 | // | 190 | // |
191 | 191 | ||
192 | static struct usb_device_id vt6656_table[] __devinitdata = { | 192 | static struct usb_device_id vt6656_table[] = { |
193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, | 193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, |
194 | {} | 194 | {} |
195 | }; | 195 | }; |
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb464527fc1b..b6e04e7b629b 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c | |||
@@ -1699,7 +1699,7 @@ s_bPacketToWirelessUsb( | |||
1699 | // 802.1H | 1699 | // 802.1H |
1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { | 1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { |
1701 | if (pDevice->dwDiagRefCount == 0) { | 1701 | if (pDevice->dwDiagRefCount == 0) { |
1702 | if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || | 1702 | if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) || |
1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { | 1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { |
1704 | memcpy((PBYTE) (pbyPayloadHead), | 1704 | memcpy((PBYTE) (pbyPayloadHead), |
1705 | abySNAP_Bridgetunnel, 6); | 1705 | abySNAP_Bridgetunnel, 6); |
@@ -2838,10 +2838,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2838 | Packet_Type = skb->data[ETH_HLEN+1]; | 2838 | Packet_Type = skb->data[ETH_HLEN+1]; |
2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; | 2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; |
2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); | 2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); |
2841 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2841 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2842 | /* 802.1x OR eapol-key challenge frame transfer */ | 2842 | /* 802.1x OR eapol-key challenge frame transfer */ |
2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && | 2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && |
2844 | (Packet_Type == 3)) { | 2844 | (Packet_Type == 3)) { |
2845 | bTxeapol_key = TRUE; | 2845 | bTxeapol_key = TRUE; |
2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge | 2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge |
2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key | 2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key |
@@ -2987,19 +2987,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2987 | } | 2987 | } |
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2990 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2991 | if (pDevice->byBBType != BB_TYPE_11A) { | 2991 | if (pDevice->byBBType != BB_TYPE_11A) { |
2992 | pDevice->wCurrentRate = RATE_1M; | 2992 | pDevice->wCurrentRate = RATE_1M; |
2993 | pDevice->byACKRate = RATE_1M; | 2993 | pDevice->byACKRate = RATE_1M; |
2994 | pDevice->byTopCCKBasicRate = RATE_1M; | 2994 | pDevice->byTopCCKBasicRate = RATE_1M; |
2995 | pDevice->byTopOFDMBasicRate = RATE_6M; | 2995 | pDevice->byTopOFDMBasicRate = RATE_6M; |
2996 | } else { | 2996 | } else { |
2997 | pDevice->wCurrentRate = RATE_6M; | 2997 | pDevice->wCurrentRate = RATE_6M; |
2998 | pDevice->byACKRate = RATE_6M; | 2998 | pDevice->byACKRate = RATE_6M; |
2999 | pDevice->byTopCCKBasicRate = RATE_1M; | 2999 | pDevice->byTopCCKBasicRate = RATE_1M; |
3000 | pDevice->byTopOFDMBasicRate = RATE_6M; | 3000 | pDevice->byTopOFDMBasicRate = RATE_6M; |
3001 | } | 3001 | } |
3002 | } | 3002 | } |
3003 | 3003 | ||
3004 | DBG_PRT(MSG_LEVEL_DEBUG, | 3004 | DBG_PRT(MSG_LEVEL_DEBUG, |
3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", | 3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", |
@@ -3015,7 +3015,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
3015 | 3015 | ||
3016 | if (bNeedEncryption == TRUE) { | 3016 | if (bNeedEncryption == TRUE) { |
3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); | 3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); |
3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { | 3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) { |
3019 | bNeedEncryption = FALSE; | 3019 | bNeedEncryption = FALSE; |
3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); | 3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); |
3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { | 3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { |
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index ef360547ecec..0ca857ac473e 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c | |||
@@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); | |||
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | MODULE_VERSION("0.1"); | 26 | MODULE_VERSION("0.1"); |
27 | 27 | ||
28 | static const struct usb_device_id wb35_table[] __devinitconst = { | 28 | static const struct usb_device_id wb35_table[] = { |
29 | { USB_DEVICE(0x0416, 0x0035) }, | 29 | { USB_DEVICE(0x0416, 0x0035) }, |
30 | { USB_DEVICE(0x18E8, 0x6201) }, | 30 | { USB_DEVICE(0x18E8, 0x6201) }, |
31 | { USB_DEVICE(0x18E8, 0x6206) }, | 31 | { USB_DEVICE(0x18E8, 0x6206) }, |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index fabff4d650ef..0970127344e6 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -327,9 +327,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
327 | return result; | 327 | return result; |
328 | } | 328 | } |
329 | 329 | ||
330 | int prism2_scan(struct wiphy *wiphy, struct net_device *dev, | 330 | int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
331 | struct cfg80211_scan_request *request) | ||
332 | { | 331 | { |
332 | struct net_device *dev = request->wdev->netdev; | ||
333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); | 333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); |
334 | wlandevice_t *wlandev = dev->ml_priv; | 334 | wlandevice_t *wlandev = dev->ml_priv; |
335 | struct p80211msg_dot11req_scan msg1; | 335 | struct p80211msg_dot11req_scan msg1; |
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index c214977b4ab4..52b43b7b83d7 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c | |||
@@ -1251,13 +1251,12 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, | |||
1251 | void *pampd, struct tmem_pool *pool, | 1251 | void *pampd, struct tmem_pool *pool, |
1252 | struct tmem_oid *oid, uint32_t index) | 1252 | struct tmem_oid *oid, uint32_t index) |
1253 | { | 1253 | { |
1254 | int ret = 0; | ||
1255 | |||
1256 | BUG_ON(!is_ephemeral(pool)); | 1254 | BUG_ON(!is_ephemeral(pool)); |
1257 | zbud_decompress((struct page *)(data), pampd); | 1255 | if (zbud_decompress((struct page *)(data), pampd) < 0) |
1256 | return -EINVAL; | ||
1258 | zbud_free_and_delist((struct zbud_hdr *)pampd); | 1257 | zbud_free_and_delist((struct zbud_hdr *)pampd); |
1259 | atomic_dec(&zcache_curr_eph_pampd_count); | 1258 | atomic_dec(&zcache_curr_eph_pampd_count); |
1260 | return ret; | 1259 | return 0; |
1261 | } | 1260 | } |
1262 | 1261 | ||
1263 | /* | 1262 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce6..6aba4395e8d8 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1( | |||
221 | { | 221 | { |
222 | struct iscsi_session *sess = NULL; | 222 | struct iscsi_session *sess = NULL; |
223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; | 223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; |
224 | int ret; | ||
224 | 225 | ||
225 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); | 226 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); |
226 | if (!sess) { | 227 | if (!sess) { |
@@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1( | |||
257 | return -ENOMEM; | 258 | return -ENOMEM; |
258 | } | 259 | } |
259 | spin_lock(&sess_idr_lock); | 260 | spin_lock(&sess_idr_lock); |
260 | idr_get_new(&sess_idr, NULL, &sess->session_index); | 261 | ret = idr_get_new(&sess_idr, NULL, &sess->session_index); |
261 | spin_unlock(&sess_idr_lock); | 262 | spin_unlock(&sess_idr_lock); |
262 | 263 | ||
264 | if (ret < 0) { | ||
265 | pr_err("idr_get_new() for sess_idr failed\n"); | ||
266 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
267 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
268 | kfree(sess); | ||
269 | return -ENOMEM; | ||
270 | } | ||
271 | |||
263 | sess->creation_time = get_jiffies_64(); | 272 | sess->creation_time = get_jiffies_64(); |
264 | spin_lock_init(&sess->session_stats_lock); | 273 | spin_lock_init(&sess->session_stats_lock); |
265 | /* | 274 | /* |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081a..41641ba54828 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | } | 220 | } |
221 | if (cmd->data_length < 4) { | ||
222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | ||
223 | " small\n", cmd->data_length); | ||
224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
221 | buf = transport_kmap_data_sg(cmd); | 228 | buf = transport_kmap_data_sg(cmd); |
222 | 229 | ||
223 | /* | 230 | /* |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index cf2c66f3c116..9fc9a6006ca0 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd) | |||
669 | unsigned char *buf; | 669 | unsigned char *buf; |
670 | u32 lun_count = 0, offset = 8, i; | 670 | u32 lun_count = 0, offset = 8, i; |
671 | 671 | ||
672 | if (se_cmd->data_length < 16) { | ||
673 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
674 | se_cmd->data_length); | ||
675 | se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
672 | buf = transport_kmap_data_sg(se_cmd); | 679 | buf = transport_kmap_data_sg(se_cmd); |
673 | if (!buf) | 680 | if (!buf) |
674 | return -ENOMEM; | 681 | return -ENOMEM; |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836ed..9ba495477fd2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
325 | struct iblock_dev *ibd = dev->dev_ptr; | 325 | struct iblock_dev *ibd = dev->dev_ptr; |
326 | unsigned char *buf, *ptr = NULL; | 326 | unsigned char *buf, *ptr = NULL; |
327 | sector_t lba; | 327 | sector_t lba; |
328 | int size = cmd->data_length; | 328 | int size; |
329 | u32 range; | 329 | u32 range; |
330 | int ret = 0; | 330 | int ret = 0; |
331 | int dl, bd_dl; | 331 | int dl, bd_dl; |
332 | 332 | ||
333 | if (cmd->data_length < 8) { | ||
334 | pr_warn("UNMAP parameter list length %u too small\n", | ||
335 | cmd->data_length); | ||
336 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | |||
333 | buf = transport_kmap_data_sg(cmd); | 340 | buf = transport_kmap_data_sg(cmd); |
334 | 341 | ||
335 | dl = get_unaligned_be16(&buf[0]); | 342 | dl = get_unaligned_be16(&buf[0]); |
336 | bd_dl = get_unaligned_be16(&buf[2]); | 343 | bd_dl = get_unaligned_be16(&buf[2]); |
337 | 344 | ||
338 | size = min(size - 8, bd_dl); | 345 | size = cmd->data_length - 8; |
346 | if (bd_dl > size) | ||
347 | pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | ||
348 | cmd->data_length, bd_dl); | ||
349 | else | ||
350 | size = bd_dl; | ||
351 | |||
339 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 352 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
340 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 353 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
341 | ret = -EINVAL; | 354 | ret = -EINVAL; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c378..956c84c6b666 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port( | |||
1540 | tidh_new->dest_local_nexus = 1; | 1540 | tidh_new->dest_local_nexus = 1; |
1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
1542 | 1542 | ||
1543 | if (cmd->data_length < 28) { | ||
1544 | pr_warn("SPC-PR: Received PR OUT parameter list" | ||
1545 | " length too small: %u\n", cmd->data_length); | ||
1546 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
1547 | ret = -EINVAL; | ||
1548 | goto out; | ||
1549 | } | ||
1550 | |||
1543 | buf = transport_kmap_data_sg(cmd); | 1551 | buf = transport_kmap_data_sg(cmd); |
1544 | /* | 1552 | /* |
1545 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1553 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 6e32ff6f2fa0..9d7ce3daa262 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -667,24 +667,32 @@ static void pscsi_free_device(void *p) | |||
667 | kfree(pdv); | 667 | kfree(pdv); |
668 | } | 668 | } |
669 | 669 | ||
670 | static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | 670 | static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, |
671 | unsigned char *sense_buffer) | ||
671 | { | 672 | { |
672 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 673 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; |
673 | struct scsi_device *sd = pdv->pdv_sd; | 674 | struct scsi_device *sd = pdv->pdv_sd; |
674 | int result; | 675 | int result; |
675 | struct pscsi_plugin_task *pt = cmd->priv; | 676 | struct pscsi_plugin_task *pt = cmd->priv; |
676 | unsigned char *cdb = &pt->pscsi_cdb[0]; | 677 | unsigned char *cdb; |
678 | /* | ||
679 | * Special case for REPORT_LUNs handling where pscsi_plugin_task has | ||
680 | * not been allocated because TCM is handling the emulation directly. | ||
681 | */ | ||
682 | if (!pt) | ||
683 | return; | ||
677 | 684 | ||
685 | cdb = &pt->pscsi_cdb[0]; | ||
678 | result = pt->pscsi_result; | 686 | result = pt->pscsi_result; |
679 | /* | 687 | /* |
680 | * Hack to make sure that Write-Protect modepage is set if R/O mode is | 688 | * Hack to make sure that Write-Protect modepage is set if R/O mode is |
681 | * forced. | 689 | * forced. |
682 | */ | 690 | */ |
691 | if (!cmd->se_deve || !cmd->data_length) | ||
692 | goto after_mode_sense; | ||
693 | |||
683 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && | 694 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && |
684 | (status_byte(result) << 1) == SAM_STAT_GOOD) { | 695 | (status_byte(result) << 1) == SAM_STAT_GOOD) { |
685 | if (!cmd->se_deve) | ||
686 | goto after_mode_sense; | ||
687 | |||
688 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { | 696 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { |
689 | unsigned char *buf = transport_kmap_data_sg(cmd); | 697 | unsigned char *buf = transport_kmap_data_sg(cmd); |
690 | 698 | ||
@@ -701,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
701 | } | 709 | } |
702 | after_mode_sense: | 710 | after_mode_sense: |
703 | 711 | ||
704 | if (sd->type != TYPE_TAPE) | 712 | if (sd->type != TYPE_TAPE || !cmd->data_length) |
705 | goto after_mode_select; | 713 | goto after_mode_select; |
706 | 714 | ||
707 | /* | 715 | /* |
@@ -743,10 +751,10 @@ after_mode_sense: | |||
743 | } | 751 | } |
744 | after_mode_select: | 752 | after_mode_select: |
745 | 753 | ||
746 | if (status_byte(result) & CHECK_CONDITION) | 754 | if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) { |
747 | return 1; | 755 | memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER); |
748 | 756 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | |
749 | return 0; | 757 | } |
750 | } | 758 | } |
751 | 759 | ||
752 | enum { | 760 | enum { |
@@ -1177,13 +1185,6 @@ fail: | |||
1177 | return -ENOMEM; | 1185 | return -ENOMEM; |
1178 | } | 1186 | } |
1179 | 1187 | ||
1180 | static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) | ||
1181 | { | ||
1182 | struct pscsi_plugin_task *pt = cmd->priv; | ||
1183 | |||
1184 | return pt->pscsi_sense; | ||
1185 | } | ||
1186 | |||
1187 | /* pscsi_get_device_rev(): | 1188 | /* pscsi_get_device_rev(): |
1188 | * | 1189 | * |
1189 | * | 1190 | * |
@@ -1266,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = { | |||
1266 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, | 1267 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, |
1267 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, | 1268 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, |
1268 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, | 1269 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, |
1269 | .get_sense_buffer = pscsi_get_sense_buffer, | ||
1270 | .get_device_rev = pscsi_get_device_rev, | 1270 | .get_device_rev = pscsi_get_device_rev, |
1271 | .get_device_type = pscsi_get_device_type, | 1271 | .get_device_type = pscsi_get_device_type, |
1272 | .get_blocks = pscsi_get_blocks, | 1272 | .get_blocks = pscsi_get_blocks, |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 4c861de538c9..388a922c8f6d 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
877 | static int spc_emulate_request_sense(struct se_cmd *cmd) | 877 | static int spc_emulate_request_sense(struct se_cmd *cmd) |
878 | { | 878 | { |
879 | unsigned char *cdb = cmd->t_task_cdb; | 879 | unsigned char *cdb = cmd->t_task_cdb; |
880 | unsigned char *buf; | 880 | unsigned char *rbuf; |
881 | u8 ua_asc = 0, ua_ascq = 0; | 881 | u8 ua_asc = 0, ua_ascq = 0; |
882 | int err = 0; | 882 | unsigned char buf[SE_SENSE_BUF]; |
883 | |||
884 | memset(buf, 0, SE_SENSE_BUF); | ||
883 | 885 | ||
884 | if (cdb[1] & 0x01) { | 886 | if (cdb[1] & 0x01) { |
885 | pr_err("REQUEST_SENSE description emulation not" | 887 | pr_err("REQUEST_SENSE description emulation not" |
@@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
888 | return -ENOSYS; | 890 | return -ENOSYS; |
889 | } | 891 | } |
890 | 892 | ||
891 | buf = transport_kmap_data_sg(cmd); | 893 | rbuf = transport_kmap_data_sg(cmd); |
892 | 894 | if (cmd->scsi_sense_reason != 0) { | |
893 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | 895 | /* |
896 | * Out of memory. We will fail with CHECK CONDITION, so | ||
897 | * we must not clear the unit attention condition. | ||
898 | */ | ||
899 | target_complete_cmd(cmd, CHECK_CONDITION); | ||
900 | return 0; | ||
901 | } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | ||
894 | /* | 902 | /* |
895 | * CURRENT ERROR, UNIT ATTENTION | 903 | * CURRENT ERROR, UNIT ATTENTION |
896 | */ | 904 | */ |
897 | buf[0] = 0x70; | 905 | buf[0] = 0x70; |
898 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | 906 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; |
899 | 907 | ||
900 | if (cmd->data_length < 18) { | ||
901 | buf[7] = 0x00; | ||
902 | err = -EINVAL; | ||
903 | goto end; | ||
904 | } | ||
905 | /* | 908 | /* |
906 | * The Additional Sense Code (ASC) from the UNIT ATTENTION | 909 | * The Additional Sense Code (ASC) from the UNIT ATTENTION |
907 | */ | 910 | */ |
@@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
915 | buf[0] = 0x70; | 918 | buf[0] = 0x70; |
916 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; | 919 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; |
917 | 920 | ||
918 | if (cmd->data_length < 18) { | ||
919 | buf[7] = 0x00; | ||
920 | err = -EINVAL; | ||
921 | goto end; | ||
922 | } | ||
923 | /* | 921 | /* |
924 | * NO ADDITIONAL SENSE INFORMATION | 922 | * NO ADDITIONAL SENSE INFORMATION |
925 | */ | 923 | */ |
@@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
927 | buf[7] = 0x0A; | 925 | buf[7] = 0x0A; |
928 | } | 926 | } |
929 | 927 | ||
930 | end: | 928 | if (rbuf) { |
931 | transport_kunmap_data_sg(cmd); | 929 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
930 | transport_kunmap_data_sg(cmd); | ||
931 | } | ||
932 | |||
932 | target_complete_cmd(cmd, GOOD); | 933 | target_complete_cmd(cmd, GOOD); |
933 | return 0; | 934 | return 0; |
934 | } | 935 | } |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 0eaae23d12b5..269f54488397 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work) | |||
567 | transport_generic_request_failure(cmd); | 567 | transport_generic_request_failure(cmd); |
568 | } | 568 | } |
569 | 569 | ||
570 | /* | ||
571 | * Used when asking transport to copy Sense Data from the underlying | ||
572 | * Linux/SCSI struct scsi_cmnd | ||
573 | */ | ||
574 | static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) | ||
575 | { | ||
576 | unsigned char *buffer = cmd->sense_buffer; | ||
577 | struct se_device *dev = cmd->se_dev; | ||
578 | u32 offset = 0; | ||
579 | |||
580 | WARN_ON(!cmd->se_lun); | ||
581 | |||
582 | if (!dev) | ||
583 | return NULL; | ||
584 | |||
585 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) | ||
586 | return NULL; | ||
587 | |||
588 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
589 | |||
590 | /* Automatically padded */ | ||
591 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
592 | |||
593 | pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", | ||
594 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
595 | return &buffer[offset]; | ||
596 | } | ||
597 | |||
570 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | 598 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) |
571 | { | 599 | { |
572 | struct se_device *dev = cmd->se_dev; | 600 | struct se_device *dev = cmd->se_dev; |
@@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
580 | cmd->transport_state &= ~CMD_T_BUSY; | 608 | cmd->transport_state &= ~CMD_T_BUSY; |
581 | 609 | ||
582 | if (dev && dev->transport->transport_complete) { | 610 | if (dev && dev->transport->transport_complete) { |
583 | if (dev->transport->transport_complete(cmd, | 611 | dev->transport->transport_complete(cmd, |
584 | cmd->t_data_sg) != 0) { | 612 | cmd->t_data_sg, |
585 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | 613 | transport_get_sense_buffer(cmd)); |
614 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) | ||
586 | success = 1; | 615 | success = 1; |
587 | } | ||
588 | } | 616 | } |
589 | 617 | ||
590 | /* | 618 | /* |
@@ -1165,8 +1193,6 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1165 | " 0x%02x\n", cmd->se_tfo->get_fabric_name(), | 1193 | " 0x%02x\n", cmd->se_tfo->get_fabric_name(), |
1166 | cmd->data_length, size, cmd->t_task_cdb[0]); | 1194 | cmd->data_length, size, cmd->t_task_cdb[0]); |
1167 | 1195 | ||
1168 | cmd->cmd_spdtl = size; | ||
1169 | |||
1170 | if (cmd->data_direction == DMA_TO_DEVICE) { | 1196 | if (cmd->data_direction == DMA_TO_DEVICE) { |
1171 | pr_err("Rejecting underflow/overflow" | 1197 | pr_err("Rejecting underflow/overflow" |
1172 | " WRITE data\n"); | 1198 | " WRITE data\n"); |
@@ -1183,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1183 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ | 1209 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ |
1184 | goto out_invalid_cdb_field; | 1210 | goto out_invalid_cdb_field; |
1185 | } | 1211 | } |
1186 | 1212 | /* | |
1213 | * For the overflow case keep the existing fabric provided | ||
1214 | * ->data_length. Otherwise for the underflow case, reset | ||
1215 | * ->data_length to the smaller SCSI expected data transfer | ||
1216 | * length. | ||
1217 | */ | ||
1187 | if (size > cmd->data_length) { | 1218 | if (size > cmd->data_length) { |
1188 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; | 1219 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; |
1189 | cmd->residual_count = (size - cmd->data_length); | 1220 | cmd->residual_count = (size - cmd->data_length); |
1190 | } else { | 1221 | } else { |
1191 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | 1222 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; |
1192 | cmd->residual_count = (cmd->data_length - size); | 1223 | cmd->residual_count = (cmd->data_length - size); |
1224 | cmd->data_length = size; | ||
1193 | } | 1225 | } |
1194 | cmd->data_length = size; | ||
1195 | } | 1226 | } |
1196 | 1227 | ||
1197 | return 0; | 1228 | return 0; |
@@ -1818,61 +1849,6 @@ execute: | |||
1818 | EXPORT_SYMBOL(target_execute_cmd); | 1849 | EXPORT_SYMBOL(target_execute_cmd); |
1819 | 1850 | ||
1820 | /* | 1851 | /* |
1821 | * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd | ||
1822 | */ | ||
1823 | static int transport_get_sense_data(struct se_cmd *cmd) | ||
1824 | { | ||
1825 | unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; | ||
1826 | struct se_device *dev = cmd->se_dev; | ||
1827 | unsigned long flags; | ||
1828 | u32 offset = 0; | ||
1829 | |||
1830 | WARN_ON(!cmd->se_lun); | ||
1831 | |||
1832 | if (!dev) | ||
1833 | return 0; | ||
1834 | |||
1835 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1836 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | ||
1837 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1838 | return 0; | ||
1839 | } | ||
1840 | |||
1841 | if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) | ||
1842 | goto out; | ||
1843 | |||
1844 | if (!dev->transport->get_sense_buffer) { | ||
1845 | pr_err("dev->transport->get_sense_buffer is NULL\n"); | ||
1846 | goto out; | ||
1847 | } | ||
1848 | |||
1849 | sense_buffer = dev->transport->get_sense_buffer(cmd); | ||
1850 | if (!sense_buffer) { | ||
1851 | pr_err("ITT 0x%08x cmd %p: Unable to locate" | ||
1852 | " sense buffer for task with sense\n", | ||
1853 | cmd->se_tfo->get_task_tag(cmd), cmd); | ||
1854 | goto out; | ||
1855 | } | ||
1856 | |||
1857 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1858 | |||
1859 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
1860 | |||
1861 | memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); | ||
1862 | |||
1863 | /* Automatically padded */ | ||
1864 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
1865 | |||
1866 | pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", | ||
1867 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
1868 | return 0; | ||
1869 | |||
1870 | out: | ||
1871 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1872 | return -1; | ||
1873 | } | ||
1874 | |||
1875 | /* | ||
1876 | * Process all commands up to the last received ORDERED task attribute which | 1852 | * Process all commands up to the last received ORDERED task attribute which |
1877 | * requires another blocking boundary | 1853 | * requires another blocking boundary |
1878 | */ | 1854 | */ |
@@ -1987,7 +1963,7 @@ static void transport_handle_queue_full( | |||
1987 | static void target_complete_ok_work(struct work_struct *work) | 1963 | static void target_complete_ok_work(struct work_struct *work) |
1988 | { | 1964 | { |
1989 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 1965 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
1990 | int reason = 0, ret; | 1966 | int ret; |
1991 | 1967 | ||
1992 | /* | 1968 | /* |
1993 | * Check if we need to move delayed/dormant tasks from cmds on the | 1969 | * Check if we need to move delayed/dormant tasks from cmds on the |
@@ -2004,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work) | |||
2004 | schedule_work(&cmd->se_dev->qf_work_queue); | 1980 | schedule_work(&cmd->se_dev->qf_work_queue); |
2005 | 1981 | ||
2006 | /* | 1982 | /* |
2007 | * Check if we need to retrieve a sense buffer from | 1983 | * Check if we need to send a sense buffer from |
2008 | * the struct se_cmd in question. | 1984 | * the struct se_cmd in question. |
2009 | */ | 1985 | */ |
2010 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | 1986 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { |
2011 | if (transport_get_sense_data(cmd) < 0) | 1987 | WARN_ON(!cmd->scsi_status); |
2012 | reason = TCM_NON_EXISTENT_LUN; | 1988 | ret = transport_send_check_condition_and_sense( |
2013 | 1989 | cmd, 0, 1); | |
2014 | if (cmd->scsi_status) { | 1990 | if (ret == -EAGAIN || ret == -ENOMEM) |
2015 | ret = transport_send_check_condition_and_sense( | 1991 | goto queue_full; |
2016 | cmd, reason, 1); | ||
2017 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
2018 | goto queue_full; | ||
2019 | 1992 | ||
2020 | transport_lun_remove_cmd(cmd); | 1993 | transport_lun_remove_cmd(cmd); |
2021 | transport_cmd_check_stop_to_fabric(cmd); | 1994 | transport_cmd_check_stop_to_fabric(cmd); |
2022 | return; | 1995 | return; |
2023 | } | ||
2024 | } | 1996 | } |
2025 | /* | 1997 | /* |
2026 | * Check for a callback, used by amongst other things | 1998 | * Check for a callback, used by amongst other things |
@@ -2218,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2218 | struct page **pages; | 2190 | struct page **pages; |
2219 | int i; | 2191 | int i; |
2220 | 2192 | ||
2221 | BUG_ON(!sg); | ||
2222 | /* | 2193 | /* |
2223 | * We need to take into account a possible offset here for fabrics like | 2194 | * We need to take into account a possible offset here for fabrics like |
2224 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for | 2195 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for |
@@ -2226,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2226 | */ | 2197 | */ |
2227 | if (!cmd->t_data_nents) | 2198 | if (!cmd->t_data_nents) |
2228 | return NULL; | 2199 | return NULL; |
2229 | else if (cmd->t_data_nents == 1) | 2200 | |
2201 | BUG_ON(!sg); | ||
2202 | if (cmd->t_data_nents == 1) | ||
2230 | return kmap(sg_page(sg)) + sg->offset; | 2203 | return kmap(sg_page(sg)) + sg->offset; |
2231 | 2204 | ||
2232 | /* >1 page. use vmap */ | 2205 | /* >1 page. use vmap */ |
2233 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | 2206 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); |
2234 | if (!pages) | 2207 | if (!pages) { |
2208 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2235 | return NULL; | 2209 | return NULL; |
2210 | } | ||
2236 | 2211 | ||
2237 | /* convert sg[] to pages[] */ | 2212 | /* convert sg[] to pages[] */ |
2238 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | 2213 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { |
@@ -2241,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2241 | 2216 | ||
2242 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | 2217 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); |
2243 | kfree(pages); | 2218 | kfree(pages); |
2244 | if (!cmd->t_data_vmap) | 2219 | if (!cmd->t_data_vmap) { |
2220 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2245 | return NULL; | 2221 | return NULL; |
2222 | } | ||
2246 | 2223 | ||
2247 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | 2224 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; |
2248 | } | 2225 | } |
@@ -2294,9 +2271,9 @@ transport_generic_get_mem(struct se_cmd *cmd) | |||
2294 | return 0; | 2271 | return 0; |
2295 | 2272 | ||
2296 | out: | 2273 | out: |
2297 | while (i >= 0) { | 2274 | while (i > 0) { |
2298 | __free_page(sg_page(&cmd->t_data_sg[i])); | ||
2299 | i--; | 2275 | i--; |
2276 | __free_page(sg_page(&cmd->t_data_sg[i])); | ||
2300 | } | 2277 | } |
2301 | kfree(cmd->t_data_sg); | 2278 | kfree(cmd->t_data_sg); |
2302 | cmd->t_data_sg = NULL; | 2279 | cmd->t_data_sg = NULL; |
@@ -2323,21 +2300,19 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2323 | if (ret < 0) | 2300 | if (ret < 0) |
2324 | goto out_fail; | 2301 | goto out_fail; |
2325 | } | 2302 | } |
2326 | 2303 | /* | |
2327 | /* Workaround for handling zero-length control CDBs */ | 2304 | * If this command doesn't have any payload and we don't have to call |
2328 | if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && !cmd->data_length) { | 2305 | * into the fabric for data transfers, go ahead and complete it right |
2306 | * away. | ||
2307 | */ | ||
2308 | if (!cmd->data_length && | ||
2309 | cmd->t_task_cdb[0] != REQUEST_SENSE && | ||
2310 | cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
2329 | spin_lock_irq(&cmd->t_state_lock); | 2311 | spin_lock_irq(&cmd->t_state_lock); |
2330 | cmd->t_state = TRANSPORT_COMPLETE; | 2312 | cmd->t_state = TRANSPORT_COMPLETE; |
2331 | cmd->transport_state |= CMD_T_ACTIVE; | 2313 | cmd->transport_state |= CMD_T_ACTIVE; |
2332 | spin_unlock_irq(&cmd->t_state_lock); | 2314 | spin_unlock_irq(&cmd->t_state_lock); |
2333 | 2315 | ||
2334 | if (cmd->t_task_cdb[0] == REQUEST_SENSE) { | ||
2335 | u8 ua_asc = 0, ua_ascq = 0; | ||
2336 | |||
2337 | core_scsi3_ua_clear_for_request_sense(cmd, | ||
2338 | &ua_asc, &ua_ascq); | ||
2339 | } | ||
2340 | |||
2341 | INIT_WORK(&cmd->work, target_complete_ok_work); | 2316 | INIT_WORK(&cmd->work, target_complete_ok_work); |
2342 | queue_work(target_completion_wq, &cmd->work); | 2317 | queue_work(target_completion_wq, &cmd->work); |
2343 | return 0; | 2318 | return 0; |
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index c5eb3c33c3db..eea69358ced3 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h | |||
@@ -131,6 +131,7 @@ extern struct list_head ft_lport_list; | |||
131 | extern struct mutex ft_lport_lock; | 131 | extern struct mutex ft_lport_lock; |
132 | extern struct fc4_prov ft_prov; | 132 | extern struct fc4_prov ft_prov; |
133 | extern struct target_fabric_configfs *ft_configfs; | 133 | extern struct target_fabric_configfs *ft_configfs; |
134 | extern unsigned int ft_debug_logging; | ||
134 | 135 | ||
135 | /* | 136 | /* |
136 | * Fabric methods. | 137 | * Fabric methods. |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index b9cb5006177e..823e6922249d 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -48,7 +48,7 @@ | |||
48 | /* | 48 | /* |
49 | * Dump cmd state for debugging. | 49 | * Dump cmd state for debugging. |
50 | */ | 50 | */ |
51 | void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) | 51 | static void _ft_dump_cmd(struct ft_cmd *cmd, const char *caller) |
52 | { | 52 | { |
53 | struct fc_exch *ep; | 53 | struct fc_exch *ep; |
54 | struct fc_seq *sp; | 54 | struct fc_seq *sp; |
@@ -80,6 +80,12 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) | ||
84 | { | ||
85 | if (unlikely(ft_debug_logging)) | ||
86 | _ft_dump_cmd(cmd, caller); | ||
87 | } | ||
88 | |||
83 | static void ft_free_cmd(struct ft_cmd *cmd) | 89 | static void ft_free_cmd(struct ft_cmd *cmd) |
84 | { | 90 | { |
85 | struct fc_frame *fp; | 91 | struct fc_frame *fp; |
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 87901fa74dd7..3c9e5b57caab 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c | |||
@@ -456,7 +456,9 @@ static void ft_prlo(struct fc_rport_priv *rdata) | |||
456 | struct ft_tport *tport; | 456 | struct ft_tport *tport; |
457 | 457 | ||
458 | mutex_lock(&ft_lport_lock); | 458 | mutex_lock(&ft_lport_lock); |
459 | tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]); | 459 | tport = rcu_dereference_protected(rdata->local_port->prov[FC_TYPE_FCP], |
460 | lockdep_is_held(&ft_lport_lock)); | ||
461 | |||
460 | if (!tport) { | 462 | if (!tport) { |
461 | mutex_unlock(&ft_lport_lock); | 463 | mutex_unlock(&ft_lport_lock); |
462 | return; | 464 | return; |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 070b442c1f81..4720b4ba096a 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -160,10 +160,12 @@ config SERIAL_KS8695_CONSOLE | |||
160 | 160 | ||
161 | config SERIAL_CLPS711X | 161 | config SERIAL_CLPS711X |
162 | tristate "CLPS711X serial port support" | 162 | tristate "CLPS711X serial port support" |
163 | depends on ARM && ARCH_CLPS711X | 163 | depends on ARCH_CLPS711X |
164 | select SERIAL_CORE | 164 | select SERIAL_CORE |
165 | default y | ||
165 | help | 166 | help |
166 | ::: To be written ::: | 167 | This enables the driver for the on-chip UARTs of the Cirrus |
168 | Logic EP711x/EP721x/EP731x processors. | ||
167 | 169 | ||
168 | config SERIAL_CLPS711X_CONSOLE | 170 | config SERIAL_CLPS711X_CONSOLE |
169 | bool "Support for console on CLPS711X serial port" | 171 | bool "Support for console on CLPS711X serial port" |
@@ -173,9 +175,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
173 | Even if you say Y here, the currently visible virtual console | 175 | Even if you say Y here, the currently visible virtual console |
174 | (/dev/tty0) will still be used as the system console by default, but | 176 | (/dev/tty0) will still be used as the system console by default, but |
175 | you can alter that using a kernel command line option such as | 177 | you can alter that using a kernel command line option such as |
176 | "console=ttyCL1". (Try "man bootparam" or see the documentation of | 178 | "console=ttyCL1". |
177 | your boot loader (lilo or loadlin) about how to pass options to the | ||
178 | kernel at boot time.) | ||
179 | 179 | ||
180 | config SERIAL_SAMSUNG | 180 | config SERIAL_SAMSUNG |
181 | tristate "Samsung SoC serial support" | 181 | tristate "Samsung SoC serial support" |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 144cd3987d4c..3ad079ffd049 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -1331,7 +1331,7 @@ static const struct spi_device_id ifx_id_table[] = { | |||
1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); | 1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); |
1332 | 1332 | ||
1333 | /* spi operations */ | 1333 | /* spi operations */ |
1334 | static const struct spi_driver ifx_spi_driver = { | 1334 | static struct spi_driver ifx_spi_driver = { |
1335 | .driver = { | 1335 | .driver = { |
1336 | .name = DRVNAME, | 1336 | .name = DRVNAME, |
1337 | .pm = &ifx_spi_pm, | 1337 | .pm = &ifx_spi_pm, |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index d5c689d6217e..e309e8b0aaba 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -132,6 +132,7 @@ | |||
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | ||
135 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
136 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
137 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
@@ -667,22 +668,11 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
667 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | 668 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) |
668 | { | 669 | { |
669 | unsigned int val; | 670 | unsigned int val; |
670 | unsigned int ufcr_rfdiv; | ||
671 | |||
672 | /* set receiver / transmitter trigger level. | ||
673 | * RFDIV is set such way to satisfy requested uartclk value | ||
674 | */ | ||
675 | val = TXTL << 10 | RXTL; | ||
676 | ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2) | ||
677 | / sport->port.uartclk; | ||
678 | |||
679 | if(!ufcr_rfdiv) | ||
680 | ufcr_rfdiv = 1; | ||
681 | |||
682 | val |= UFCR_RFDIV_REG(ufcr_rfdiv); | ||
683 | 671 | ||
672 | /* set receiver / transmitter trigger level */ | ||
673 | val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); | ||
674 | val |= TXTL << UFCR_TXTL_SHF | RXTL; | ||
684 | writel(val, sport->port.membase + UFCR); | 675 | writel(val, sport->port.membase + UFCR); |
685 | |||
686 | return 0; | 676 | return 0; |
687 | } | 677 | } |
688 | 678 | ||
@@ -754,6 +744,7 @@ static int imx_startup(struct uart_port *port) | |||
754 | } | 744 | } |
755 | } | 745 | } |
756 | 746 | ||
747 | spin_lock_irqsave(&sport->port.lock, flags); | ||
757 | /* | 748 | /* |
758 | * Finally, clear and enable interrupts | 749 | * Finally, clear and enable interrupts |
759 | */ | 750 | */ |
@@ -807,7 +798,6 @@ static int imx_startup(struct uart_port *port) | |||
807 | /* | 798 | /* |
808 | * Enable modem status interrupts | 799 | * Enable modem status interrupts |
809 | */ | 800 | */ |
810 | spin_lock_irqsave(&sport->port.lock,flags); | ||
811 | imx_enable_ms(&sport->port); | 801 | imx_enable_ms(&sport->port); |
812 | spin_unlock_irqrestore(&sport->port.lock,flags); | 802 | spin_unlock_irqrestore(&sport->port.lock,flags); |
813 | 803 | ||
@@ -837,10 +827,13 @@ static void imx_shutdown(struct uart_port *port) | |||
837 | { | 827 | { |
838 | struct imx_port *sport = (struct imx_port *)port; | 828 | struct imx_port *sport = (struct imx_port *)port; |
839 | unsigned long temp; | 829 | unsigned long temp; |
830 | unsigned long flags; | ||
840 | 831 | ||
832 | spin_lock_irqsave(&sport->port.lock, flags); | ||
841 | temp = readl(sport->port.membase + UCR2); | 833 | temp = readl(sport->port.membase + UCR2); |
842 | temp &= ~(UCR2_TXEN); | 834 | temp &= ~(UCR2_TXEN); |
843 | writel(temp, sport->port.membase + UCR2); | 835 | writel(temp, sport->port.membase + UCR2); |
836 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
844 | 837 | ||
845 | if (USE_IRDA(sport)) { | 838 | if (USE_IRDA(sport)) { |
846 | struct imxuart_platform_data *pdata; | 839 | struct imxuart_platform_data *pdata; |
@@ -869,12 +862,14 @@ static void imx_shutdown(struct uart_port *port) | |||
869 | * Disable all interrupts, port and break condition. | 862 | * Disable all interrupts, port and break condition. |
870 | */ | 863 | */ |
871 | 864 | ||
865 | spin_lock_irqsave(&sport->port.lock, flags); | ||
872 | temp = readl(sport->port.membase + UCR1); | 866 | temp = readl(sport->port.membase + UCR1); |
873 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | 867 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
874 | if (USE_IRDA(sport)) | 868 | if (USE_IRDA(sport)) |
875 | temp &= ~(UCR1_IREN); | 869 | temp &= ~(UCR1_IREN); |
876 | 870 | ||
877 | writel(temp, sport->port.membase + UCR1); | 871 | writel(temp, sport->port.membase + UCR1); |
872 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
878 | } | 873 | } |
879 | 874 | ||
880 | static void | 875 | static void |
@@ -1217,6 +1212,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1217 | struct imx_port *sport = imx_ports[co->index]; | 1212 | struct imx_port *sport = imx_ports[co->index]; |
1218 | struct imx_port_ucrs old_ucr; | 1213 | struct imx_port_ucrs old_ucr; |
1219 | unsigned int ucr1; | 1214 | unsigned int ucr1; |
1215 | unsigned long flags; | ||
1216 | |||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1220 | 1218 | ||
1221 | /* | 1219 | /* |
1222 | * First, save UCR1/2/3 and then disable interrupts | 1220 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1242,6 +1240,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1242 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); | 1240 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); |
1243 | 1241 | ||
1244 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | |||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | /* | 1247 | /* |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 2e341b81ff89..3a667eed63d6 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #define AUART_CTRL0_CLKGATE (1 << 30) | 73 | #define AUART_CTRL0_CLKGATE (1 << 30) |
74 | 74 | ||
75 | #define AUART_CTRL2_CTSEN (1 << 15) | 75 | #define AUART_CTRL2_CTSEN (1 << 15) |
76 | #define AUART_CTRL2_RTSEN (1 << 14) | ||
76 | #define AUART_CTRL2_RTS (1 << 11) | 77 | #define AUART_CTRL2_RTS (1 << 11) |
77 | #define AUART_CTRL2_RXE (1 << 9) | 78 | #define AUART_CTRL2_RXE (1 << 9) |
78 | #define AUART_CTRL2_TXE (1 << 8) | 79 | #define AUART_CTRL2_TXE (1 << 8) |
@@ -259,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
259 | 260 | ||
260 | u32 ctrl = readl(u->membase + AUART_CTRL2); | 261 | u32 ctrl = readl(u->membase + AUART_CTRL2); |
261 | 262 | ||
262 | ctrl &= ~AUART_CTRL2_RTS; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
263 | if (mctrl & TIOCM_RTS) | 264 | if (mctrl & TIOCM_RTS) { |
264 | ctrl |= AUART_CTRL2_RTS; | 265 | if (u->state->port.flags & ASYNC_CTS_FLOW) |
266 | ctrl |= AUART_CTRL2_RTSEN; | ||
267 | } | ||
268 | |||
265 | s->ctrl = mctrl; | 269 | s->ctrl = mctrl; |
266 | writel(ctrl, u->membase + AUART_CTRL2); | 270 | writel(ctrl, u->membase + AUART_CTRL2); |
267 | } | 271 | } |
@@ -359,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
359 | 363 | ||
360 | /* figure out the hardware flow control settings */ | 364 | /* figure out the hardware flow control settings */ |
361 | if (cflag & CRTSCTS) | 365 | if (cflag & CRTSCTS) |
362 | ctrl2 |= AUART_CTRL2_CTSEN; | 366 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; |
363 | else | 367 | else |
364 | ctrl2 &= ~AUART_CTRL2_CTSEN; | 368 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); |
365 | 369 | ||
366 | /* set baud rate */ | 370 | /* set baud rate */ |
367 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); | 371 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 654755a990df..333c8d012b0e 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1348 | static int pmz_poll_get_char(struct uart_port *port) | 1348 | static int pmz_poll_get_char(struct uart_port *port) |
1349 | { | 1349 | { |
1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | 1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; |
1351 | int tries = 2; | ||
1351 | 1352 | ||
1352 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) | 1353 | while (tries) { |
1353 | udelay(5); | 1354 | if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0) |
1354 | return read_zsdata(uap); | 1355 | return read_zsdata(uap); |
1356 | if (tries--) | ||
1357 | udelay(5); | ||
1358 | } | ||
1359 | |||
1360 | return NO_POLL_CHAR; | ||
1355 | } | 1361 | } |
1356 | 1362 | ||
1357 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | 1363 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index a7773a3e02b1..7065df6036ca 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -13,7 +13,7 @@ config USB_ARCH_HAS_OHCI | |||
13 | default y if PXA3xx | 13 | default y if PXA3xx |
14 | default y if ARCH_EP93XX | 14 | default y if ARCH_EP93XX |
15 | default y if ARCH_AT91 | 15 | default y if ARCH_AT91 |
16 | default y if ARCH_PNX4008 && I2C | 16 | default y if ARCH_PNX4008 |
17 | default y if MFD_TC6393XB | 17 | default y if MFD_TC6393XB |
18 | default y if ARCH_W90X900 | 18 | default y if ARCH_W90X900 |
19 | default y if ARCH_DAVINCI_DA8XX | 19 | default y if ARCH_DAVINCI_DA8XX |
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 8337fb5d988d..47e499c9c0b6 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config USB_CHIPIDEA | 1 | config USB_CHIPIDEA |
2 | tristate "ChipIdea Highspeed Dual Role Controller" | 2 | tristate "ChipIdea Highspeed Dual Role Controller" |
3 | depends on USB | 3 | depends on USB || USB_GADGET |
4 | help | 4 | help |
5 | Say Y here if your system has a dual role high speed USB | 5 | Say Y here if your system has a dual role high speed USB |
6 | controller based on ChipIdea silicon IP. Currently, only the | 6 | controller based on ChipIdea silicon IP. Currently, only the |
7 | peripheral mode is supported. | 7 | peripheral mode is supported. |
8 | 8 | ||
9 | When compiled dynamically, the module will be called ci-hdrc.ko. | 9 | When compiled dynamically, the module will be called ci-hdrc.ko. |
@@ -12,7 +12,7 @@ if USB_CHIPIDEA | |||
12 | 12 | ||
13 | config USB_CHIPIDEA_UDC | 13 | config USB_CHIPIDEA_UDC |
14 | bool "ChipIdea device controller" | 14 | bool "ChipIdea device controller" |
15 | depends on USB_GADGET | 15 | depends on USB_GADGET=y || USB_GADGET=USB_CHIPIDEA |
16 | select USB_GADGET_DUALSPEED | 16 | select USB_GADGET_DUALSPEED |
17 | help | 17 | help |
18 | Say Y here to enable device controller functionality of the | 18 | Say Y here to enable device controller functionality of the |
@@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC | |||
20 | 20 | ||
21 | config USB_CHIPIDEA_HOST | 21 | config USB_CHIPIDEA_HOST |
22 | bool "ChipIdea host controller" | 22 | bool "ChipIdea host controller" |
23 | depends on USB=y || USB=USB_CHIPIDEA | ||
23 | select USB_EHCI_ROOT_HUB_TT | 24 | select USB_EHCI_ROOT_HUB_TT |
24 | help | 25 | help |
25 | Say Y here to enable host controller functionality of the | 26 | Say Y here to enable host controller functionality of the |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c7a032a4f0c5..d214448b677e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | 81 | * hw_device_state: enables/disables interrupts (execute without interruption) |
82 | * without interruption) | ||
83 | * @dma: 0 => disable, !0 => enable and set dma engine | 82 | * @dma: 0 => disable, !0 => enable and set dma engine |
84 | * | 83 | * |
85 | * This function returns an error code | 84 | * This function returns an error code |
@@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma) | |||
91 | /* interrupt, error, port change, reset, sleep/suspend */ | 90 | /* interrupt, error, port change, reset, sleep/suspend */ |
92 | hw_write(ci, OP_USBINTR, ~0, | 91 | hw_write(ci, OP_USBINTR, ~0, |
93 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | 92 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); |
94 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
95 | } else { | 93 | } else { |
96 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
97 | hw_write(ci, OP_USBINTR, ~0, 0); | 94 | hw_write(ci, OP_USBINTR, ~0, 0); |
98 | } | 95 | } |
99 | return 0; | 96 | return 0; |
@@ -774,10 +771,7 @@ __acquires(mEp->lock) | |||
774 | { | 771 | { |
775 | struct ci13xxx_req *mReq, *mReqTemp; | 772 | struct ci13xxx_req *mReq, *mReqTemp; |
776 | struct ci13xxx_ep *mEpTemp = mEp; | 773 | struct ci13xxx_ep *mEpTemp = mEp; |
777 | int uninitialized_var(retval); | 774 | int retval = 0; |
778 | |||
779 | if (list_empty(&mEp->qh.queue)) | ||
780 | return -EINVAL; | ||
781 | 775 | ||
782 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, | 776 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, |
783 | queue) { | 777 | queue) { |
@@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1420 | return -ENOTSUPP; | 1414 | return -ENOTSUPP; |
1421 | } | 1415 | } |
1422 | 1416 | ||
1417 | /* Change Data+ pullup status | ||
1418 | * this func is used by usb_gadget_connect/disconnet | ||
1419 | */ | ||
1420 | static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) | ||
1421 | { | ||
1422 | struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); | ||
1423 | |||
1424 | if (is_on) | ||
1425 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
1426 | else | ||
1427 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1423 | static int ci13xxx_start(struct usb_gadget *gadget, | 1432 | static int ci13xxx_start(struct usb_gadget *gadget, |
1424 | struct usb_gadget_driver *driver); | 1433 | struct usb_gadget_driver *driver); |
1425 | static int ci13xxx_stop(struct usb_gadget *gadget, | 1434 | static int ci13xxx_stop(struct usb_gadget *gadget, |
@@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget, | |||
1432 | static const struct usb_gadget_ops usb_gadget_ops = { | 1441 | static const struct usb_gadget_ops usb_gadget_ops = { |
1433 | .vbus_session = ci13xxx_vbus_session, | 1442 | .vbus_session = ci13xxx_vbus_session, |
1434 | .wakeup = ci13xxx_wakeup, | 1443 | .wakeup = ci13xxx_wakeup, |
1444 | .pullup = ci13xxx_pullup, | ||
1435 | .vbus_draw = ci13xxx_vbus_draw, | 1445 | .vbus_draw = ci13xxx_vbus_draw, |
1436 | .udc_start = ci13xxx_start, | 1446 | .udc_start = ci13xxx_start, |
1437 | .udc_stop = ci13xxx_stop, | 1447 | .udc_stop = ci13xxx_stop, |
@@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci) | |||
1455 | 1465 | ||
1456 | mEp->ep.name = mEp->name; | 1466 | mEp->ep.name = mEp->name; |
1457 | mEp->ep.ops = &usb_ep_ops; | 1467 | mEp->ep.ops = &usb_ep_ops; |
1458 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | 1468 | /* |
1469 | * for ep0: maxP defined in desc, for other | ||
1470 | * eps, maxP is set by epautoconfig() called | ||
1471 | * by gadget layer | ||
1472 | */ | ||
1473 | mEp->ep.maxpacket = (unsigned short)~0; | ||
1459 | 1474 | ||
1460 | INIT_LIST_HEAD(&mEp->qh.queue); | 1475 | INIT_LIST_HEAD(&mEp->qh.queue); |
1461 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, | 1476 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, |
@@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci) | |||
1475 | else | 1490 | else |
1476 | ci->ep0in = mEp; | 1491 | ci->ep0in = mEp; |
1477 | 1492 | ||
1493 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
1478 | continue; | 1494 | continue; |
1479 | } | 1495 | } |
1480 | 1496 | ||
@@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci) | |||
1484 | return retval; | 1500 | return retval; |
1485 | } | 1501 | } |
1486 | 1502 | ||
1503 | static void destroy_eps(struct ci13xxx *ci) | ||
1504 | { | ||
1505 | int i; | ||
1506 | |||
1507 | for (i = 0; i < ci->hw_ep_max; i++) { | ||
1508 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1509 | |||
1510 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1487 | /** | 1514 | /** |
1488 | * ci13xxx_start: register a gadget driver | 1515 | * ci13xxx_start: register a gadget driver |
1489 | * @gadget: our gadget | 1516 | * @gadget: our gadget |
@@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1691 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | 1718 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { |
1692 | if (ci->transceiver == NULL) { | 1719 | if (ci->transceiver == NULL) { |
1693 | retval = -ENODEV; | 1720 | retval = -ENODEV; |
1694 | goto free_pools; | 1721 | goto destroy_eps; |
1695 | } | 1722 | } |
1696 | } | 1723 | } |
1697 | 1724 | ||
@@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1729 | 1756 | ||
1730 | remove_trans: | 1757 | remove_trans: |
1731 | if (!IS_ERR_OR_NULL(ci->transceiver)) { | 1758 | if (!IS_ERR_OR_NULL(ci->transceiver)) { |
1732 | otg_set_peripheral(ci->transceiver->otg, &ci->gadget); | 1759 | otg_set_peripheral(ci->transceiver->otg, NULL); |
1733 | if (ci->global_phy) | 1760 | if (ci->global_phy) |
1734 | usb_put_phy(ci->transceiver); | 1761 | usb_put_phy(ci->transceiver); |
1735 | } | 1762 | } |
@@ -1742,6 +1769,8 @@ unreg_device: | |||
1742 | put_transceiver: | 1769 | put_transceiver: |
1743 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) | 1770 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) |
1744 | usb_put_phy(ci->transceiver); | 1771 | usb_put_phy(ci->transceiver); |
1772 | destroy_eps: | ||
1773 | destroy_eps(ci); | ||
1745 | free_pools: | 1774 | free_pools: |
1746 | dma_pool_destroy(ci->td_pool); | 1775 | dma_pool_destroy(ci->td_pool); |
1747 | free_qh_pool: | 1776 | free_qh_pool: |
@@ -1756,18 +1785,12 @@ free_qh_pool: | |||
1756 | */ | 1785 | */ |
1757 | static void udc_stop(struct ci13xxx *ci) | 1786 | static void udc_stop(struct ci13xxx *ci) |
1758 | { | 1787 | { |
1759 | int i; | ||
1760 | |||
1761 | if (ci == NULL) | 1788 | if (ci == NULL) |
1762 | return; | 1789 | return; |
1763 | 1790 | ||
1764 | usb_del_gadget_udc(&ci->gadget); | 1791 | usb_del_gadget_udc(&ci->gadget); |
1765 | 1792 | ||
1766 | for (i = 0; i < ci->hw_ep_max; i++) { | 1793 | destroy_eps(ci); |
1767 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1768 | |||
1769 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1770 | } | ||
1771 | 1794 | ||
1772 | dma_pool_destroy(ci->td_pool); | 1795 | dma_pool_destroy(ci->td_pool); |
1773 | dma_pool_destroy(ci->qh_pool); | 1796 | dma_pool_destroy(ci->qh_pool); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 56d6bf668488..f763ed7ba91e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1104,7 +1104,8 @@ skip_normal_probe: | |||
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | 1106 | ||
1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) | 1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || |
1108 | control_interface->cur_altsetting->desc.bNumEndpoints == 0) | ||
1108 | return -EINVAL; | 1109 | return -EINVAL; |
1109 | 1110 | ||
1110 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; | 1111 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 65a55abb791f..5f0cb417b736 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -109,12 +109,14 @@ static struct usb_driver wdm_driver; | |||
109 | /* return intfdata if we own the interface, else look up intf in the list */ | 109 | /* return intfdata if we own the interface, else look up intf in the list */ |
110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) | 110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) |
111 | { | 111 | { |
112 | struct wdm_device *desc = NULL; | 112 | struct wdm_device *desc; |
113 | 113 | ||
114 | spin_lock(&wdm_device_list_lock); | 114 | spin_lock(&wdm_device_list_lock); |
115 | list_for_each_entry(desc, &wdm_device_list, device_list) | 115 | list_for_each_entry(desc, &wdm_device_list, device_list) |
116 | if (desc->intf == intf) | 116 | if (desc->intf == intf) |
117 | break; | 117 | goto found; |
118 | desc = NULL; | ||
119 | found: | ||
118 | spin_unlock(&wdm_device_list_lock); | 120 | spin_unlock(&wdm_device_list_lock); |
119 | 121 | ||
120 | return desc; | 122 | return desc; |
@@ -122,12 +124,14 @@ static struct wdm_device *wdm_find_device(struct usb_interface *intf) | |||
122 | 124 | ||
123 | static struct wdm_device *wdm_find_device_by_minor(int minor) | 125 | static struct wdm_device *wdm_find_device_by_minor(int minor) |
124 | { | 126 | { |
125 | struct wdm_device *desc = NULL; | 127 | struct wdm_device *desc; |
126 | 128 | ||
127 | spin_lock(&wdm_device_list_lock); | 129 | spin_lock(&wdm_device_list_lock); |
128 | list_for_each_entry(desc, &wdm_device_list, device_list) | 130 | list_for_each_entry(desc, &wdm_device_list, device_list) |
129 | if (desc->intf->minor == minor) | 131 | if (desc->intf->minor == minor) |
130 | break; | 132 | goto found; |
133 | desc = NULL; | ||
134 | found: | ||
131 | spin_unlock(&wdm_device_list_lock); | 135 | spin_unlock(&wdm_device_list_lock); |
132 | 136 | ||
133 | return desc; | 137 | return desc; |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index d95696584762..3440812b4a84 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -624,7 +624,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf, | |||
624 | /* print devices for all busses */ | 624 | /* print devices for all busses */ |
625 | list_for_each_entry(bus, &usb_bus_list, bus_list) { | 625 | list_for_each_entry(bus, &usb_bus_list, bus_list) { |
626 | /* recurse through all children of the root hub */ | 626 | /* recurse through all children of the root hub */ |
627 | if (!bus->root_hub) | 627 | if (!bus_to_hcd(bus)->rh_registered) |
628 | continue; | 628 | continue; |
629 | usb_lock_device(bus->root_hub); | 629 | usb_lock_device(bus->root_hub); |
630 | ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, | 630 | ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index bc84106ac057..75ba2091f9b4 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1011,10 +1011,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
1011 | if (retval) { | 1011 | if (retval) { |
1012 | dev_err (parent_dev, "can't register root hub for %s, %d\n", | 1012 | dev_err (parent_dev, "can't register root hub for %s, %d\n", |
1013 | dev_name(&usb_dev->dev), retval); | 1013 | dev_name(&usb_dev->dev), retval); |
1014 | } | 1014 | } else { |
1015 | mutex_unlock(&usb_bus_list_lock); | ||
1016 | |||
1017 | if (retval == 0) { | ||
1018 | spin_lock_irq (&hcd_root_hub_lock); | 1015 | spin_lock_irq (&hcd_root_hub_lock); |
1019 | hcd->rh_registered = 1; | 1016 | hcd->rh_registered = 1; |
1020 | spin_unlock_irq (&hcd_root_hub_lock); | 1017 | spin_unlock_irq (&hcd_root_hub_lock); |
@@ -1023,6 +1020,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
1023 | if (HCD_DEAD(hcd)) | 1020 | if (HCD_DEAD(hcd)) |
1024 | usb_hc_died (hcd); /* This time clean up */ | 1021 | usb_hc_died (hcd); /* This time clean up */ |
1025 | } | 1022 | } |
1023 | mutex_unlock(&usb_bus_list_lock); | ||
1026 | 1024 | ||
1027 | return retval; | 1025 | return retval; |
1028 | } | 1026 | } |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f15501f4c585..e77a8e8eaa23 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = | 71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = |
72 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 72 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
73 | 73 | ||
74 | /* Microchip Joss Optical infrared touchboard device */ | ||
75 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = | ||
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
77 | |||
74 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ | 78 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ |
75 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = | 79 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = |
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 80 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c34452a7304f..a68ff53124dc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -436,16 +436,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev) | |||
436 | dev_err(dev, "missing IRQ\n"); | 436 | dev_err(dev, "missing IRQ\n"); |
437 | return -ENODEV; | 437 | return -ENODEV; |
438 | } | 438 | } |
439 | dwc->xhci_resources[1] = *res; | 439 | dwc->xhci_resources[1].start = res->start; |
440 | dwc->xhci_resources[1].end = res->end; | ||
441 | dwc->xhci_resources[1].flags = res->flags; | ||
442 | dwc->xhci_resources[1].name = res->name; | ||
440 | 443 | ||
441 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 444 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
442 | if (!res) { | 445 | if (!res) { |
443 | dev_err(dev, "missing memory resource\n"); | 446 | dev_err(dev, "missing memory resource\n"); |
444 | return -ENODEV; | 447 | return -ENODEV; |
445 | } | 448 | } |
446 | dwc->xhci_resources[0] = *res; | 449 | dwc->xhci_resources[0].start = res->start; |
447 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | 450 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + |
448 | DWC3_XHCI_REGS_END; | 451 | DWC3_XHCI_REGS_END; |
452 | dwc->xhci_resources[0].flags = res->flags; | ||
453 | dwc->xhci_resources[0].name = res->name; | ||
449 | 454 | ||
450 | /* | 455 | /* |
451 | * Request memory region but exclude xHCI regs, | 456 | * Request memory region but exclude xHCI regs, |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9b94886b66e5..e4d5ca86b9da 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -720,7 +720,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
720 | transferred = min_t(u32, ur->length, | 720 | transferred = min_t(u32, ur->length, |
721 | transfer_size - length); | 721 | transfer_size - length); |
722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | 722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); |
723 | dwc->ep0_bounced = false; | ||
724 | } else { | 723 | } else { |
725 | transferred = ur->length - length; | 724 | transferred = ur->length - length; |
726 | } | 725 | } |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 58fdfad96b4d..c2813c2b005a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
263 | if (req->request.status == -EINPROGRESS) | 263 | if (req->request.status == -EINPROGRESS) |
264 | req->request.status = status; | 264 | req->request.status = status; |
265 | 265 | ||
266 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 266 | if (dwc->ep0_bounced && dep->number == 0) |
267 | req->direction); | 267 | dwc->ep0_bounced = false; |
268 | else | ||
269 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | ||
270 | req->direction); | ||
268 | 271 | ||
269 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 272 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
270 | req, dep->name, req->request.actual, | 273 | req, dep->name, req->request.actual, |
@@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | |||
1026 | if (list_empty(&dep->request_list)) { | 1029 | if (list_empty(&dep->request_list)) { |
1027 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 1030 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", |
1028 | dep->name); | 1031 | dep->name); |
1032 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
1029 | return; | 1033 | return; |
1030 | } | 1034 | } |
1031 | 1035 | ||
@@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1089 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1093 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1090 | int ret; | 1094 | int ret; |
1091 | 1095 | ||
1096 | /* | ||
1097 | * If xfernotready is already elapsed and it is a case | ||
1098 | * of isoc transfer, then issue END TRANSFER, so that | ||
1099 | * you can receive xfernotready again and can have | ||
1100 | * notion of current microframe. | ||
1101 | */ | ||
1102 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1103 | dwc3_stop_active_transfer(dwc, dep->number); | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1092 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | 1107 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1093 | if (ret && ret != -EBUSY) { | 1108 | if (ret && ret != -EBUSY) { |
1094 | struct dwc3 *dwc = dep->dwc; | 1109 | struct dwc3 *dwc = dep->dwc; |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index ee0ebacf8227..89dcf155d57e 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) | |||
450 | writel(FLAG_CF, &ehci_regs->configured_flag); | 450 | writel(FLAG_CF, &ehci_regs->configured_flag); |
451 | 451 | ||
452 | /* Wait until the controller is no longer halted */ | 452 | /* Wait until the controller is no longer halted */ |
453 | loop = 10; | 453 | loop = 1000; |
454 | do { | 454 | do { |
455 | status = readl(&ehci_regs->status); | 455 | status = readl(&ehci_regs->status); |
456 | if (!(status & STS_HALT)) | 456 | if (!(status & STS_HALT)) |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index c9e66dfb02e6..1e35963bd4ed 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep, | |||
475 | unsigned long flags; | 475 | unsigned long flags; |
476 | 476 | ||
477 | if (!_ep || !ep | 477 | if (!_ep || !ep |
478 | || !desc || ep->ep.desc | 478 | || !desc || _ep->name == ep0name |
479 | || _ep->name == ep0name | ||
480 | || desc->bDescriptorType != USB_DT_ENDPOINT | 479 | || desc->bDescriptorType != USB_DT_ENDPOINT |
481 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 | 480 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 |
482 | || maxpacket > ep->maxpacket) { | 481 | || maxpacket > ep->maxpacket) { |
@@ -530,7 +529,6 @@ ok: | |||
530 | tmp |= AT91_UDP_EPEDS; | 529 | tmp |= AT91_UDP_EPEDS; |
531 | __raw_writel(tmp, ep->creg); | 530 | __raw_writel(tmp, ep->creg); |
532 | 531 | ||
533 | ep->ep.desc = desc; | ||
534 | ep->ep.maxpacket = maxpacket; | 532 | ep->ep.maxpacket = maxpacket; |
535 | 533 | ||
536 | /* | 534 | /* |
@@ -1635,7 +1633,6 @@ static int at91_start(struct usb_gadget *gadget, | |||
1635 | udc->driver = driver; | 1633 | udc->driver = driver; |
1636 | udc->gadget.dev.driver = &driver->driver; | 1634 | udc->gadget.dev.driver = &driver->driver; |
1637 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; | 1635 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; |
1638 | dev_set_drvdata(&udc->gadget.dev, &driver->driver); | ||
1639 | udc->enabled = 1; | 1636 | udc->enabled = 1; |
1640 | udc->selfpowered = 1; | 1637 | udc->selfpowered = 1; |
1641 | 1638 | ||
@@ -1656,7 +1653,6 @@ static int at91_stop(struct usb_gadget *gadget, | |||
1656 | spin_unlock_irqrestore(&udc->lock, flags); | 1653 | spin_unlock_irqrestore(&udc->lock, flags); |
1657 | 1654 | ||
1658 | udc->gadget.dev.driver = NULL; | 1655 | udc->gadget.dev.driver = NULL; |
1659 | dev_set_drvdata(&udc->gadget.dev, NULL); | ||
1660 | udc->driver = NULL; | 1656 | udc->driver = NULL; |
1661 | 1657 | ||
1662 | DBG("unbound from %s\n", driver->driver.name); | 1658 | DBG("unbound from %s\n", driver->driver.name); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027ad..afdbb1cbf5d9 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1916,6 +1916,27 @@ done: | |||
1916 | return retval; | 1916 | return retval; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | /* usb 3.0 root hub device descriptor */ | ||
1920 | struct { | ||
1921 | struct usb_bos_descriptor bos; | ||
1922 | struct usb_ss_cap_descriptor ss_cap; | ||
1923 | } __packed usb3_bos_desc = { | ||
1924 | |||
1925 | .bos = { | ||
1926 | .bLength = USB_DT_BOS_SIZE, | ||
1927 | .bDescriptorType = USB_DT_BOS, | ||
1928 | .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), | ||
1929 | .bNumDeviceCaps = 1, | ||
1930 | }, | ||
1931 | .ss_cap = { | ||
1932 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
1933 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
1934 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
1935 | .wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION), | ||
1936 | .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), | ||
1937 | }, | ||
1938 | }; | ||
1939 | |||
1919 | static inline void | 1940 | static inline void |
1920 | ss_hub_descriptor(struct usb_hub_descriptor *desc) | 1941 | ss_hub_descriptor(struct usb_hub_descriptor *desc) |
1921 | { | 1942 | { |
@@ -2006,6 +2027,18 @@ static int dummy_hub_control( | |||
2006 | else | 2027 | else |
2007 | hub_descriptor((struct usb_hub_descriptor *) buf); | 2028 | hub_descriptor((struct usb_hub_descriptor *) buf); |
2008 | break; | 2029 | break; |
2030 | |||
2031 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
2032 | if (hcd->speed != HCD_USB3) | ||
2033 | goto error; | ||
2034 | |||
2035 | if ((wValue >> 8) != USB_DT_BOS) | ||
2036 | goto error; | ||
2037 | |||
2038 | memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); | ||
2039 | retval = sizeof(usb3_bos_desc); | ||
2040 | break; | ||
2041 | |||
2009 | case GetHubStatus: | 2042 | case GetHubStatus: |
2010 | *(__le32 *) buf = cpu_to_le32(0); | 2043 | *(__le32 *) buf = cpu_to_le32(0); |
2011 | break; | 2044 | break; |
@@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2503 | hs_hcd->has_tt = 1; | 2536 | hs_hcd->has_tt = 1; |
2504 | 2537 | ||
2505 | retval = usb_add_hcd(hs_hcd, 0, 0); | 2538 | retval = usb_add_hcd(hs_hcd, 0, 0); |
2506 | if (retval != 0) { | 2539 | if (retval) |
2507 | usb_put_hcd(hs_hcd); | 2540 | goto put_usb2_hcd; |
2508 | return retval; | ||
2509 | } | ||
2510 | 2541 | ||
2511 | if (mod_data.is_super_speed) { | 2542 | if (mod_data.is_super_speed) { |
2512 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, | 2543 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, |
@@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2525 | put_usb3_hcd: | 2556 | put_usb3_hcd: |
2526 | usb_put_hcd(ss_hcd); | 2557 | usb_put_hcd(ss_hcd); |
2527 | dealloc_usb2_hcd: | 2558 | dealloc_usb2_hcd: |
2559 | usb_remove_hcd(hs_hcd); | ||
2560 | put_usb2_hcd: | ||
2528 | usb_put_hcd(hs_hcd); | 2561 | usb_put_hcd(hs_hcd); |
2529 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; | 2562 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; |
2530 | return retval; | 2563 | return retval; |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8adc79d1b402..829aba75a6df 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -34,11 +34,15 @@ | |||
34 | /* Debugging ****************************************************************/ | 34 | /* Debugging ****************************************************************/ |
35 | 35 | ||
36 | #ifdef VERBOSE_DEBUG | 36 | #ifdef VERBOSE_DEBUG |
37 | #ifndef pr_vdebug | ||
37 | # define pr_vdebug pr_debug | 38 | # define pr_vdebug pr_debug |
39 | #endif /* pr_vdebug */ | ||
38 | # define ffs_dump_mem(prefix, ptr, len) \ | 40 | # define ffs_dump_mem(prefix, ptr, len) \ |
39 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) | 41 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) |
40 | #else | 42 | #else |
43 | #ifndef pr_vdebug | ||
41 | # define pr_vdebug(...) do { } while (0) | 44 | # define pr_vdebug(...) do { } while (0) |
45 | #endif /* pr_vdebug */ | ||
42 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) | 46 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) |
43 | #endif /* VERBOSE_DEBUG */ | 47 | #endif /* VERBOSE_DEBUG */ |
44 | 48 | ||
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b13e0bb5f5b8..0bb617e1dda2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -3599,6 +3599,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3599 | 3599 | ||
3600 | if (hsotg->num_of_eps == 0) { | 3600 | if (hsotg->num_of_eps == 0) { |
3601 | dev_err(dev, "wrong number of EPs (zero)\n"); | 3601 | dev_err(dev, "wrong number of EPs (zero)\n"); |
3602 | ret = -EINVAL; | ||
3602 | goto err_supplies; | 3603 | goto err_supplies; |
3603 | } | 3604 | } |
3604 | 3605 | ||
@@ -3606,6 +3607,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3606 | GFP_KERNEL); | 3607 | GFP_KERNEL); |
3607 | if (!eps) { | 3608 | if (!eps) { |
3608 | dev_err(dev, "cannot get memory\n"); | 3609 | dev_err(dev, "cannot get memory\n"); |
3610 | ret = -ENOMEM; | ||
3609 | goto err_supplies; | 3611 | goto err_supplies; |
3610 | } | 3612 | } |
3611 | 3613 | ||
@@ -3622,6 +3624,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3622 | GFP_KERNEL); | 3624 | GFP_KERNEL); |
3623 | if (!hsotg->ctrl_req) { | 3625 | if (!hsotg->ctrl_req) { |
3624 | dev_err(dev, "failed to allocate ctrl req\n"); | 3626 | dev_err(dev, "failed to allocate ctrl req\n"); |
3627 | ret = -ENOMEM; | ||
3625 | goto err_ep_mem; | 3628 | goto err_ep_mem; |
3626 | } | 3629 | } |
3627 | 3630 | ||
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 90e82e288eb9..0e5230926154 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net) | |||
669 | spin_lock_irqsave(&dev->lock, flags); | 669 | spin_lock_irqsave(&dev->lock, flags); |
670 | if (dev->port_usb) { | 670 | if (dev->port_usb) { |
671 | struct gether *link = dev->port_usb; | 671 | struct gether *link = dev->port_usb; |
672 | const struct usb_endpoint_descriptor *in; | ||
673 | const struct usb_endpoint_descriptor *out; | ||
672 | 674 | ||
673 | if (link->close) | 675 | if (link->close) |
674 | link->close(link); | 676 | link->close(link); |
@@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net) | |||
682 | * their own pace; the network stack can handle old packets. | 684 | * their own pace; the network stack can handle old packets. |
683 | * For the moment we leave this here, since it works. | 685 | * For the moment we leave this here, since it works. |
684 | */ | 686 | */ |
687 | in = link->in_ep->desc; | ||
688 | out = link->out_ep->desc; | ||
685 | usb_ep_disable(link->in_ep); | 689 | usb_ep_disable(link->in_ep); |
686 | usb_ep_disable(link->out_ep); | 690 | usb_ep_disable(link->out_ep); |
687 | if (netif_carrier_ok(net)) { | 691 | if (netif_carrier_ok(net)) { |
688 | DBG(dev, "host still using in/out endpoints\n"); | 692 | DBG(dev, "host still using in/out endpoints\n"); |
693 | link->in_ep->desc = in; | ||
694 | link->out_ep->desc = out; | ||
689 | usb_ep_enable(link->in_ep); | 695 | usb_ep_enable(link->in_ep); |
690 | usb_ep_enable(link->out_ep); | 696 | usb_ep_enable(link->out_ep); |
691 | } | 697 | } |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 5b3f5fffea92..da6d479ff9a6 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -132,11 +132,15 @@ static unsigned n_ports; | |||
132 | 132 | ||
133 | 133 | ||
134 | #ifdef VERBOSE_DEBUG | 134 | #ifdef VERBOSE_DEBUG |
135 | #ifndef pr_vdebug | ||
135 | #define pr_vdebug(fmt, arg...) \ | 136 | #define pr_vdebug(fmt, arg...) \ |
136 | pr_debug(fmt, ##arg) | 137 | pr_debug(fmt, ##arg) |
138 | #endif /* pr_vdebug */ | ||
137 | #else | 139 | #else |
140 | #ifndef pr_vdebig | ||
138 | #define pr_vdebug(fmt, arg...) \ | 141 | #define pr_vdebug(fmt, arg...) \ |
139 | ({ if (0) pr_debug(fmt, ##arg); }) | 142 | ({ if (0) pr_debug(fmt, ##arg); }) |
143 | #endif /* pr_vdebug */ | ||
140 | #endif | 144 | #endif |
141 | 145 | ||
142 | /*-------------------------------------------------------------------------*/ | 146 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bb55eb4a7d48..d7fe287d0678 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -56,15 +56,6 @@ | |||
56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
58 | 58 | ||
59 | /* Errata i693 */ | ||
60 | static struct clk *utmi_p1_fck; | ||
61 | static struct clk *utmi_p2_fck; | ||
62 | static struct clk *xclk60mhsp1_ck; | ||
63 | static struct clk *xclk60mhsp2_ck; | ||
64 | static struct clk *usbhost_p1_fck; | ||
65 | static struct clk *usbhost_p2_fck; | ||
66 | static struct clk *init_60m_fclk; | ||
67 | |||
68 | /*-------------------------------------------------------------------------*/ | 59 | /*-------------------------------------------------------------------------*/ |
69 | 60 | ||
70 | static const struct hc_driver ehci_omap_hc_driver; | 61 | static const struct hc_driver ehci_omap_hc_driver; |
@@ -80,40 +71,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) | |||
80 | return __raw_readl(base + reg); | 71 | return __raw_readl(base + reg); |
81 | } | 72 | } |
82 | 73 | ||
83 | /* Erratum i693 workaround sequence */ | ||
84 | static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) | ||
85 | { | ||
86 | int ret = 0; | ||
87 | |||
88 | /* Switch to the internal 60 MHz clock */ | ||
89 | ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); | ||
90 | if (ret != 0) | ||
91 | ehci_err(ehci, "init_60m_fclk set parent" | ||
92 | "failed error:%d\n", ret); | ||
93 | |||
94 | ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); | ||
95 | if (ret != 0) | ||
96 | ehci_err(ehci, "init_60m_fclk set parent" | ||
97 | "failed error:%d\n", ret); | ||
98 | |||
99 | clk_enable(usbhost_p1_fck); | ||
100 | clk_enable(usbhost_p2_fck); | ||
101 | |||
102 | /* Wait 1ms and switch back to the external clock */ | ||
103 | mdelay(1); | ||
104 | ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); | ||
105 | if (ret != 0) | ||
106 | ehci_err(ehci, "xclk60mhsp1_ck set parent" | ||
107 | "failed error:%d\n", ret); | ||
108 | |||
109 | ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); | ||
110 | if (ret != 0) | ||
111 | ehci_err(ehci, "xclk60mhsp2_ck set parent" | ||
112 | "failed error:%d\n", ret); | ||
113 | |||
114 | clk_disable(usbhost_p1_fck); | ||
115 | clk_disable(usbhost_p2_fck); | ||
116 | } | ||
117 | 74 | ||
118 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) | 75 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) |
119 | { | 76 | { |
@@ -195,50 +152,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) | |||
195 | return rc; | 152 | return rc; |
196 | } | 153 | } |
197 | 154 | ||
198 | static int omap_ehci_hub_control( | ||
199 | struct usb_hcd *hcd, | ||
200 | u16 typeReq, | ||
201 | u16 wValue, | ||
202 | u16 wIndex, | ||
203 | char *buf, | ||
204 | u16 wLength | ||
205 | ) | ||
206 | { | ||
207 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
208 | u32 __iomem *status_reg = &ehci->regs->port_status[ | ||
209 | (wIndex & 0xff) - 1]; | ||
210 | u32 temp; | ||
211 | unsigned long flags; | ||
212 | int retval = 0; | ||
213 | |||
214 | spin_lock_irqsave(&ehci->lock, flags); | ||
215 | |||
216 | if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { | ||
217 | temp = ehci_readl(ehci, status_reg); | ||
218 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { | ||
219 | retval = -EPIPE; | ||
220 | goto done; | ||
221 | } | ||
222 | |||
223 | temp &= ~PORT_WKCONN_E; | ||
224 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
225 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
226 | |||
227 | omap_ehci_erratum_i693(ehci); | ||
228 | |||
229 | set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); | ||
230 | goto done; | ||
231 | } | ||
232 | |||
233 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
234 | |||
235 | /* Handle the hub control events here */ | ||
236 | return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
237 | done: | ||
238 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
239 | return retval; | ||
240 | } | ||
241 | |||
242 | static void disable_put_regulator( | 155 | static void disable_put_regulator( |
243 | struct ehci_hcd_omap_platform_data *pdata) | 156 | struct ehci_hcd_omap_platform_data *pdata) |
244 | { | 157 | { |
@@ -351,79 +264,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
351 | goto err_pm_runtime; | 264 | goto err_pm_runtime; |
352 | } | 265 | } |
353 | 266 | ||
354 | /* get clocks */ | ||
355 | utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | ||
356 | if (IS_ERR(utmi_p1_fck)) { | ||
357 | ret = PTR_ERR(utmi_p1_fck); | ||
358 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
359 | goto err_add_hcd; | ||
360 | } | ||
361 | |||
362 | xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | ||
363 | if (IS_ERR(xclk60mhsp1_ck)) { | ||
364 | ret = PTR_ERR(xclk60mhsp1_ck); | ||
365 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
366 | goto err_utmi_p1_fck; | ||
367 | } | ||
368 | |||
369 | utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); | ||
370 | if (IS_ERR(utmi_p2_fck)) { | ||
371 | ret = PTR_ERR(utmi_p2_fck); | ||
372 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
373 | goto err_xclk60mhsp1_ck; | ||
374 | } | ||
375 | |||
376 | xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | ||
377 | if (IS_ERR(xclk60mhsp2_ck)) { | ||
378 | ret = PTR_ERR(xclk60mhsp2_ck); | ||
379 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
380 | goto err_utmi_p2_fck; | ||
381 | } | ||
382 | |||
383 | usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); | ||
384 | if (IS_ERR(usbhost_p1_fck)) { | ||
385 | ret = PTR_ERR(usbhost_p1_fck); | ||
386 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
387 | goto err_xclk60mhsp2_ck; | ||
388 | } | ||
389 | |||
390 | usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); | ||
391 | if (IS_ERR(usbhost_p2_fck)) { | ||
392 | ret = PTR_ERR(usbhost_p2_fck); | ||
393 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
394 | goto err_usbhost_p1_fck; | ||
395 | } | ||
396 | |||
397 | init_60m_fclk = clk_get(dev, "init_60m_fclk"); | ||
398 | if (IS_ERR(init_60m_fclk)) { | ||
399 | ret = PTR_ERR(init_60m_fclk); | ||
400 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | ||
401 | goto err_usbhost_p2_fck; | ||
402 | } | ||
403 | 267 | ||
404 | return 0; | 268 | return 0; |
405 | 269 | ||
406 | err_usbhost_p2_fck: | ||
407 | clk_put(usbhost_p2_fck); | ||
408 | |||
409 | err_usbhost_p1_fck: | ||
410 | clk_put(usbhost_p1_fck); | ||
411 | |||
412 | err_xclk60mhsp2_ck: | ||
413 | clk_put(xclk60mhsp2_ck); | ||
414 | |||
415 | err_utmi_p2_fck: | ||
416 | clk_put(utmi_p2_fck); | ||
417 | |||
418 | err_xclk60mhsp1_ck: | ||
419 | clk_put(xclk60mhsp1_ck); | ||
420 | |||
421 | err_utmi_p1_fck: | ||
422 | clk_put(utmi_p1_fck); | ||
423 | |||
424 | err_add_hcd: | ||
425 | usb_remove_hcd(hcd); | ||
426 | |||
427 | err_pm_runtime: | 270 | err_pm_runtime: |
428 | disable_put_regulator(pdata); | 271 | disable_put_regulator(pdata); |
429 | pm_runtime_put_sync(dev); | 272 | pm_runtime_put_sync(dev); |
@@ -454,14 +297,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
454 | iounmap(hcd->regs); | 297 | iounmap(hcd->regs); |
455 | usb_put_hcd(hcd); | 298 | usb_put_hcd(hcd); |
456 | 299 | ||
457 | clk_put(utmi_p1_fck); | ||
458 | clk_put(utmi_p2_fck); | ||
459 | clk_put(xclk60mhsp1_ck); | ||
460 | clk_put(xclk60mhsp2_ck); | ||
461 | clk_put(usbhost_p1_fck); | ||
462 | clk_put(usbhost_p2_fck); | ||
463 | clk_put(init_60m_fclk); | ||
464 | |||
465 | pm_runtime_put_sync(dev); | 300 | pm_runtime_put_sync(dev); |
466 | pm_runtime_disable(dev); | 301 | pm_runtime_disable(dev); |
467 | 302 | ||
@@ -532,7 +367,7 @@ static const struct hc_driver ehci_omap_hc_driver = { | |||
532 | * root hub support | 367 | * root hub support |
533 | */ | 368 | */ |
534 | .hub_status_data = ehci_hub_status_data, | 369 | .hub_status_data = ehci_hub_status_data, |
535 | .hub_control = omap_ehci_hub_control, | 370 | .hub_control = ehci_hub_control, |
536 | .bus_suspend = ehci_bus_suspend, | 371 | .bus_suspend = ehci_bus_suspend, |
537 | .bus_resume = ehci_bus_resume, | 372 | .bus_resume = ehci_bus_resume, |
538 | 373 | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9bc39ca460c8..4b66374bdc8e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
128 | else { | 128 | else { |
129 | qtd = list_entry (qh->qtd_list.next, | 129 | qtd = list_entry (qh->qtd_list.next, |
130 | struct ehci_qtd, qtd_list); | 130 | struct ehci_qtd, qtd_list); |
131 | /* first qtd may already be partially processed */ | 131 | /* |
132 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) | 132 | * first qtd may already be partially processed. |
133 | * If we come here during unlink, the QH overlay region | ||
134 | * might have reference to the just unlinked qtd. The | ||
135 | * qtd is updated in qh_completions(). Update the QH | ||
136 | * overlay here. | ||
137 | */ | ||
138 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { | ||
139 | qh->hw->hw_qtd_next = qtd->hw_next; | ||
133 | qtd = NULL; | 140 | qtd = NULL; |
141 | } | ||
134 | } | 142 | } |
135 | 143 | ||
136 | if (qtd) | 144 | if (qtd) |
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 58c96bd50d22..0c9e43cfaff5 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c | |||
@@ -40,7 +40,7 @@ static int ehci_sead3_setup(struct usb_hcd *hcd) | |||
40 | ehci->need_io_watchdog = 0; | 40 | ehci->need_io_watchdog = 0; |
41 | 41 | ||
42 | /* Set burst length to 16 words. */ | 42 | /* Set burst length to 16 words. */ |
43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]); | 43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]); |
44 | 44 | ||
45 | return ret; | 45 | return ret; |
46 | } | 46 | } |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 950e95efa381..26dedb30ad0b 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -799,11 +799,12 @@ static int tegra_ehci_remove(struct platform_device *pdev) | |||
799 | #endif | 799 | #endif |
800 | 800 | ||
801 | usb_remove_hcd(hcd); | 801 | usb_remove_hcd(hcd); |
802 | usb_put_hcd(hcd); | ||
803 | 802 | ||
804 | tegra_usb_phy_close(tegra->phy); | 803 | tegra_usb_phy_close(tegra->phy); |
805 | iounmap(hcd->regs); | 804 | iounmap(hcd->regs); |
806 | 805 | ||
806 | usb_put_hcd(hcd); | ||
807 | |||
807 | clk_disable_unprepare(tegra->clk); | 808 | clk_disable_unprepare(tegra->clk); |
808 | clk_put(tegra->clk); | 809 | clk_put(tegra->clk); |
809 | 810 | ||
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 2ed112d3e159..256326322cfd 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -543,12 +543,12 @@ static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) | |||
543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, | 543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, |
544 | short_ok ? "" : "not_", | 544 | short_ok ? "" : "not_", |
545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); | 545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); |
546 | /* save the data underrun error code for later and | ||
547 | * proceed with the status stage | ||
548 | */ | ||
549 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
546 | if (usb_pipecontrol(urb->pipe)) { | 550 | if (usb_pipecontrol(urb->pipe)) { |
547 | ep->nextpid = USB_PID_ACK; | 551 | ep->nextpid = USB_PID_ACK; |
548 | /* save the data underrun error code for later and | ||
549 | * proceed with the status stage | ||
550 | */ | ||
551 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); | 552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); |
553 | 553 | ||
554 | if (urb->status == -EINPROGRESS) | 554 | if (urb->status == -EINPROGRESS) |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a665b3eaa746..0bf72f943b00 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -467,7 +467,8 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data) | |||
467 | /* From the GPIO notifying the over-current situation, find | 467 | /* From the GPIO notifying the over-current situation, find |
468 | * out the corresponding port */ | 468 | * out the corresponding port */ |
469 | at91_for_each_port(port) { | 469 | at91_for_each_port(port) { |
470 | if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { | 470 | if (gpio_is_valid(pdata->overcurrent_pin[port]) && |
471 | gpio_to_irq(pdata->overcurrent_pin[port]) == irq) { | ||
471 | gpio = pdata->overcurrent_pin[port]; | 472 | gpio = pdata->overcurrent_pin[port]; |
472 | break; | 473 | break; |
473 | } | 474 | } |
@@ -570,6 +571,16 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) | |||
570 | 571 | ||
571 | if (pdata) { | 572 | if (pdata) { |
572 | at91_for_each_port(i) { | 573 | at91_for_each_port(i) { |
574 | /* | ||
575 | * do not configure PIO if not in relation with | ||
576 | * real USB port on board | ||
577 | */ | ||
578 | if (i >= pdata->ports) { | ||
579 | pdata->vbus_pin[i] = -EINVAL; | ||
580 | pdata->overcurrent_pin[i] = -EINVAL; | ||
581 | break; | ||
582 | } | ||
583 | |||
573 | if (!gpio_is_valid(pdata->vbus_pin[i])) | 584 | if (!gpio_is_valid(pdata->vbus_pin[i])) |
574 | continue; | 585 | continue; |
575 | gpio = pdata->vbus_pin[i]; | 586 | gpio = pdata->vbus_pin[i]; |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index e7d75d295988..f8b2d91851f7 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -403,8 +403,6 @@ err0: | |||
403 | static inline void | 403 | static inline void |
404 | usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) | 404 | usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) |
405 | { | 405 | { |
406 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
407 | |||
408 | usb_remove_hcd(hcd); | 406 | usb_remove_hcd(hcd); |
409 | if (!IS_ERR_OR_NULL(hcd->phy)) { | 407 | if (!IS_ERR_OR_NULL(hcd->phy)) { |
410 | (void) otg_set_host(hcd->phy->otg, 0); | 408 | (void) otg_set_host(hcd->phy->otg, 0); |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index df0828cb2aa3..966d1484ee79 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -75,7 +75,9 @@ | |||
75 | #define NB_PIF0_PWRDOWN_1 0x01100013 | 75 | #define NB_PIF0_PWRDOWN_1 0x01100013 |
76 | 76 | ||
77 | #define USB_INTEL_XUSB2PR 0xD0 | 77 | #define USB_INTEL_XUSB2PR 0xD0 |
78 | #define USB_INTEL_USB2PRM 0xD4 | ||
78 | #define USB_INTEL_USB3_PSSEN 0xD8 | 79 | #define USB_INTEL_USB3_PSSEN 0xD8 |
80 | #define USB_INTEL_USB3PRM 0xDC | ||
79 | 81 | ||
80 | static struct amd_chipset_info { | 82 | static struct amd_chipset_info { |
81 | struct pci_dev *nb_dev; | 83 | struct pci_dev *nb_dev; |
@@ -772,10 +774,18 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
772 | return; | 774 | return; |
773 | } | 775 | } |
774 | 776 | ||
775 | ports_available = 0xffffffff; | 777 | /* Read USB3PRM, the USB 3.0 Port Routing Mask Register |
778 | * Indicate the ports that can be changed from OS. | ||
779 | */ | ||
780 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, | ||
781 | &ports_available); | ||
782 | |||
783 | dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", | ||
784 | ports_available); | ||
785 | |||
776 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | 786 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable |
777 | * Register, to turn on SuperSpeed terminations for all | 787 | * Register, to turn on SuperSpeed terminations for the |
778 | * available ports. | 788 | * switchable ports. |
779 | */ | 789 | */ |
780 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | 790 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, |
781 | cpu_to_le32(ports_available)); | 791 | cpu_to_le32(ports_available)); |
@@ -785,7 +795,16 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
785 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | 795 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " |
786 | "under xHCI: 0x%x\n", ports_available); | 796 | "under xHCI: 0x%x\n", ports_available); |
787 | 797 | ||
788 | ports_available = 0xffffffff; | 798 | /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register |
799 | * Indicate the USB 2.0 ports to be controlled by the xHCI host. | ||
800 | */ | ||
801 | |||
802 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, | ||
803 | &ports_available); | ||
804 | |||
805 | dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", | ||
806 | ports_available); | ||
807 | |||
789 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | 808 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to |
790 | * switch the USB 2.0 power and data lines over to the xHCI | 809 | * switch the USB 2.0 power and data lines over to the xHCI |
791 | * host. | 810 | * host. |
@@ -800,6 +819,13 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
800 | } | 819 | } |
801 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | 820 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); |
802 | 821 | ||
822 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) | ||
823 | { | ||
824 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0); | ||
825 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0); | ||
826 | } | ||
827 | EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); | ||
828 | |||
803 | /** | 829 | /** |
804 | * PCI Quirks for xHCI. | 830 | * PCI Quirks for xHCI. |
805 | * | 831 | * |
@@ -815,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
815 | void __iomem *op_reg_base; | 841 | void __iomem *op_reg_base; |
816 | u32 val; | 842 | u32 val; |
817 | int timeout; | 843 | int timeout; |
844 | int len = pci_resource_len(pdev, 0); | ||
818 | 845 | ||
819 | if (!mmio_resource_enabled(pdev, 0)) | 846 | if (!mmio_resource_enabled(pdev, 0)) |
820 | return; | 847 | return; |
821 | 848 | ||
822 | base = ioremap_nocache(pci_resource_start(pdev, 0), | 849 | base = ioremap_nocache(pci_resource_start(pdev, 0), len); |
823 | pci_resource_len(pdev, 0)); | ||
824 | if (base == NULL) | 850 | if (base == NULL) |
825 | return; | 851 | return; |
826 | 852 | ||
@@ -830,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
830 | */ | 856 | */ |
831 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); | 857 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); |
832 | do { | 858 | do { |
859 | if ((ext_cap_offset + sizeof(val)) > len) { | ||
860 | /* We're reading garbage from the controller */ | ||
861 | dev_warn(&pdev->dev, | ||
862 | "xHCI controller failing to respond"); | ||
863 | return; | ||
864 | } | ||
865 | |||
833 | if (!ext_cap_offset) | 866 | if (!ext_cap_offset) |
834 | /* We've reached the end of the extended capabilities */ | 867 | /* We've reached the end of the extended capabilities */ |
835 | goto hc_init; | 868 | goto hc_init; |
869 | |||
836 | val = readl(base + ext_cap_offset); | 870 | val = readl(base + ext_cap_offset); |
837 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) | 871 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) |
838 | break; | 872 | break; |
@@ -863,9 +897,10 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
863 | /* Disable any BIOS SMIs and clear all SMI events*/ | 897 | /* Disable any BIOS SMIs and clear all SMI events*/ |
864 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 898 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
865 | 899 | ||
900 | hc_init: | ||
866 | if (usb_is_intel_switchable_xhci(pdev)) | 901 | if (usb_is_intel_switchable_xhci(pdev)) |
867 | usb_enable_xhci_ports(pdev); | 902 | usb_enable_xhci_ports(pdev); |
868 | hc_init: | 903 | |
869 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 904 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
870 | 905 | ||
871 | /* Wait for the host controller to be ready before writing any | 906 | /* Wait for the host controller to be ready before writing any |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index b1002a8ef96f..7f69a39163ce 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -10,10 +10,12 @@ void usb_amd_quirk_pll_disable(void); | |||
10 | void usb_amd_quirk_pll_enable(void); | 10 | void usb_amd_quirk_pll_enable(void); |
11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); | 11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); |
12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); | 12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); |
13 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | ||
13 | #else | 14 | #else |
14 | static inline void usb_amd_quirk_pll_disable(void) {} | 15 | static inline void usb_amd_quirk_pll_disable(void) {} |
15 | static inline void usb_amd_quirk_pll_enable(void) {} | 16 | static inline void usb_amd_quirk_pll_enable(void) {} |
16 | static inline void usb_amd_dev_put(void) {} | 17 | static inline void usb_amd_dev_put(void) {} |
18 | static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} | ||
17 | #endif /* CONFIG_PCI */ | 19 | #endif /* CONFIG_PCI */ |
18 | 20 | ||
19 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ | 21 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 74bfc868b7ad..d5eb357aa5c4 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -493,11 +493,48 @@ static void xhci_hub_report_link_state(u32 *status, u32 status_reg) | |||
493 | * when this bit is set. | 493 | * when this bit is set. |
494 | */ | 494 | */ |
495 | pls |= USB_PORT_STAT_CONNECTION; | 495 | pls |= USB_PORT_STAT_CONNECTION; |
496 | } else { | ||
497 | /* | ||
498 | * If CAS bit isn't set but the Port is already at | ||
499 | * Compliance Mode, fake a connection so the USB core | ||
500 | * notices the Compliance state and resets the port. | ||
501 | * This resolves an issue generated by the SN65LVPE502CP | ||
502 | * in which sometimes the port enters compliance mode | ||
503 | * caused by a delay on the host-device negotiation. | ||
504 | */ | ||
505 | if (pls == USB_SS_PORT_LS_COMP_MOD) | ||
506 | pls |= USB_PORT_STAT_CONNECTION; | ||
496 | } | 507 | } |
508 | |||
497 | /* update status field */ | 509 | /* update status field */ |
498 | *status |= pls; | 510 | *status |= pls; |
499 | } | 511 | } |
500 | 512 | ||
513 | /* | ||
514 | * Function for Compliance Mode Quirk. | ||
515 | * | ||
516 | * This Function verifies if all xhc USB3 ports have entered U0, if so, | ||
517 | * the compliance mode timer is deleted. A port won't enter | ||
518 | * compliance mode if it has previously entered U0. | ||
519 | */ | ||
520 | void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) | ||
521 | { | ||
522 | u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1); | ||
523 | bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); | ||
524 | |||
525 | if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) | ||
526 | return; | ||
527 | |||
528 | if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { | ||
529 | xhci->port_status_u0 |= 1 << wIndex; | ||
530 | if (xhci->port_status_u0 == all_ports_seen_u0) { | ||
531 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
532 | xhci_dbg(xhci, "All USB3 ports have entered U0 already!\n"); | ||
533 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted.\n"); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | |||
501 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 538 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
502 | u16 wIndex, char *buf, u16 wLength) | 539 | u16 wIndex, char *buf, u16 wLength) |
503 | { | 540 | { |
@@ -651,6 +688,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
651 | /* Update Port Link State for super speed ports*/ | 688 | /* Update Port Link State for super speed ports*/ |
652 | if (hcd->speed == HCD_USB3) { | 689 | if (hcd->speed == HCD_USB3) { |
653 | xhci_hub_report_link_state(&status, temp); | 690 | xhci_hub_report_link_state(&status, temp); |
691 | /* | ||
692 | * Verify if all USB3 Ports Have entered U0 already. | ||
693 | * Delete Compliance Mode Timer if so. | ||
694 | */ | ||
695 | xhci_del_comp_mod_timer(xhci, temp, wIndex); | ||
654 | } | 696 | } |
655 | if (bus_state->port_c_suspend & (1 << wIndex)) | 697 | if (bus_state->port_c_suspend & (1 << wIndex)) |
656 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | 698 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 18b231b0c5d3..9bfd4ca1153c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -94,11 +94,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | 94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; |
95 | xhci->limit_active_eps = 64; | 95 | xhci->limit_active_eps = 64; |
96 | xhci->quirks |= XHCI_SW_BW_CHECKING; | 96 | xhci->quirks |= XHCI_SW_BW_CHECKING; |
97 | /* | ||
98 | * PPT desktop boards DH77EB and DH77DF will power back on after | ||
99 | * a few seconds of being shutdown. The fix for this is to | ||
100 | * switch the ports from xHCI to EHCI on shutdown. We can't use | ||
101 | * DMI information to find those particular boards (since each | ||
102 | * vendor will change the board name), so we have to key off all | ||
103 | * PPT chipsets. | ||
104 | */ | ||
105 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | ||
97 | } | 106 | } |
98 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 107 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
99 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 108 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { |
100 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 109 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
101 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); | 110 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); |
111 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
102 | } | 112 | } |
103 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 113 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
104 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 114 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 689bc18b051d..df90fe51b4aa 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -118,7 +118,7 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
118 | goto put_hcd; | 118 | goto put_hcd; |
119 | } | 119 | } |
120 | 120 | ||
121 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 121 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); |
122 | if (!hcd->regs) { | 122 | if (!hcd->regs) { |
123 | dev_dbg(&pdev->dev, "error mapping memory\n"); | 123 | dev_dbg(&pdev->dev, "error mapping memory\n"); |
124 | ret = -EFAULT; | 124 | ret = -EFAULT; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8275645889da..643c2f3f3e73 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -145,29 +145,37 @@ static void next_trb(struct xhci_hcd *xhci, | |||
145 | */ | 145 | */ |
146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) | 146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) |
147 | { | 147 | { |
148 | union xhci_trb *next; | ||
149 | unsigned long long addr; | 148 | unsigned long long addr; |
150 | 149 | ||
151 | ring->deq_updates++; | 150 | ring->deq_updates++; |
152 | 151 | ||
153 | /* If this is not event ring, there is one more usable TRB */ | 152 | /* |
153 | * If this is not event ring, and the dequeue pointer | ||
154 | * is not on a link TRB, there is one more usable TRB | ||
155 | */ | ||
154 | if (ring->type != TYPE_EVENT && | 156 | if (ring->type != TYPE_EVENT && |
155 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) | 157 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) |
156 | ring->num_trbs_free++; | 158 | ring->num_trbs_free++; |
157 | next = ++(ring->dequeue); | ||
158 | 159 | ||
159 | /* Update the dequeue pointer further if that was a link TRB or we're at | 160 | do { |
160 | * the end of an event ring segment (which doesn't have link TRBS) | 161 | /* |
161 | */ | 162 | * Update the dequeue pointer further if that was a link TRB or |
162 | while (last_trb(xhci, ring, ring->deq_seg, next)) { | 163 | * we're at the end of an event ring segment (which doesn't have |
163 | if (ring->type == TYPE_EVENT && last_trb_on_last_seg(xhci, | 164 | * link TRBS) |
164 | ring, ring->deq_seg, next)) { | 165 | */ |
165 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 166 | if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) { |
167 | if (ring->type == TYPE_EVENT && | ||
168 | last_trb_on_last_seg(xhci, ring, | ||
169 | ring->deq_seg, ring->dequeue)) { | ||
170 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | ||
171 | } | ||
172 | ring->deq_seg = ring->deq_seg->next; | ||
173 | ring->dequeue = ring->deq_seg->trbs; | ||
174 | } else { | ||
175 | ring->dequeue++; | ||
166 | } | 176 | } |
167 | ring->deq_seg = ring->deq_seg->next; | 177 | } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); |
168 | ring->dequeue = ring->deq_seg->trbs; | 178 | |
169 | next = ring->dequeue; | ||
170 | } | ||
171 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 179 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
172 | } | 180 | } |
173 | 181 | ||
@@ -2073,8 +2081,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2073 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) | 2081 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
2074 | trb_comp_code = COMP_SHORT_TX; | 2082 | trb_comp_code = COMP_SHORT_TX; |
2075 | else | 2083 | else |
2076 | xhci_warn(xhci, "WARN Successful completion on short TX: " | 2084 | xhci_warn_ratelimited(xhci, |
2077 | "needs XHCI_TRUST_TX_LENGTH quirk?\n"); | 2085 | "WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n"); |
2078 | case COMP_SHORT_TX: | 2086 | case COMP_SHORT_TX: |
2079 | break; | 2087 | break; |
2080 | case COMP_STOP: | 2088 | case COMP_STOP: |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7648b2d4b268..6ece0ed288d4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/dmi.h> | ||
29 | 30 | ||
30 | #include "xhci.h" | 31 | #include "xhci.h" |
31 | 32 | ||
@@ -166,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
166 | xhci_writel(xhci, command, &xhci->op_regs->command); | 167 | xhci_writel(xhci, command, &xhci->op_regs->command); |
167 | 168 | ||
168 | ret = handshake(xhci, &xhci->op_regs->command, | 169 | ret = handshake(xhci, &xhci->op_regs->command, |
169 | CMD_RESET, 0, 250 * 1000); | 170 | CMD_RESET, 0, 10 * 1000 * 1000); |
170 | if (ret) | 171 | if (ret) |
171 | return ret; | 172 | return ret; |
172 | 173 | ||
@@ -175,7 +176,8 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
175 | * xHCI cannot write to any doorbells or operational registers other | 176 | * xHCI cannot write to any doorbells or operational registers other |
176 | * than status until the "Controller Not Ready" flag is cleared. | 177 | * than status until the "Controller Not Ready" flag is cleared. |
177 | */ | 178 | */ |
178 | ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); | 179 | ret = handshake(xhci, &xhci->op_regs->status, |
180 | STS_CNR, 0, 10 * 1000 * 1000); | ||
179 | 181 | ||
180 | for (i = 0; i < 2; ++i) { | 182 | for (i = 0; i < 2; ++i) { |
181 | xhci->bus_state[i].port_c_suspend = 0; | 183 | xhci->bus_state[i].port_c_suspend = 0; |
@@ -397,6 +399,95 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) | |||
397 | 399 | ||
398 | #endif | 400 | #endif |
399 | 401 | ||
402 | static void compliance_mode_recovery(unsigned long arg) | ||
403 | { | ||
404 | struct xhci_hcd *xhci; | ||
405 | struct usb_hcd *hcd; | ||
406 | u32 temp; | ||
407 | int i; | ||
408 | |||
409 | xhci = (struct xhci_hcd *)arg; | ||
410 | |||
411 | for (i = 0; i < xhci->num_usb3_ports; i++) { | ||
412 | temp = xhci_readl(xhci, xhci->usb3_ports[i]); | ||
413 | if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { | ||
414 | /* | ||
415 | * Compliance Mode Detected. Letting USB Core | ||
416 | * handle the Warm Reset | ||
417 | */ | ||
418 | xhci_dbg(xhci, "Compliance Mode Detected->Port %d!\n", | ||
419 | i + 1); | ||
420 | xhci_dbg(xhci, "Attempting Recovery routine!\n"); | ||
421 | hcd = xhci->shared_hcd; | ||
422 | |||
423 | if (hcd->state == HC_STATE_SUSPENDED) | ||
424 | usb_hcd_resume_root_hub(hcd); | ||
425 | |||
426 | usb_hcd_poll_rh_status(hcd); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) | ||
431 | mod_timer(&xhci->comp_mode_recovery_timer, | ||
432 | jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * Quirk to work around issue generated by the SN65LVPE502CP USB3.0 re-driver | ||
437 | * that causes ports behind that hardware to enter compliance mode sometimes. | ||
438 | * The quirk creates a timer that polls every 2 seconds the link state of | ||
439 | * each host controller's port and recovers it by issuing a Warm reset | ||
440 | * if Compliance mode is detected, otherwise the port will become "dead" (no | ||
441 | * device connections or disconnections will be detected anymore). Becasue no | ||
442 | * status event is generated when entering compliance mode (per xhci spec), | ||
443 | * this quirk is needed on systems that have the failing hardware installed. | ||
444 | */ | ||
445 | static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) | ||
446 | { | ||
447 | xhci->port_status_u0 = 0; | ||
448 | init_timer(&xhci->comp_mode_recovery_timer); | ||
449 | |||
450 | xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; | ||
451 | xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; | ||
452 | xhci->comp_mode_recovery_timer.expires = jiffies + | ||
453 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); | ||
454 | |||
455 | set_timer_slack(&xhci->comp_mode_recovery_timer, | ||
456 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
457 | add_timer(&xhci->comp_mode_recovery_timer); | ||
458 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Initialized.\n"); | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * This function identifies the systems that have installed the SN65LVPE502CP | ||
463 | * USB3.0 re-driver and that need the Compliance Mode Quirk. | ||
464 | * Systems: | ||
465 | * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 | ||
466 | */ | ||
467 | static bool compliance_mode_recovery_timer_quirk_check(void) | ||
468 | { | ||
469 | const char *dmi_product_name, *dmi_sys_vendor; | ||
470 | |||
471 | dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
472 | dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); | ||
473 | |||
474 | if (!(strstr(dmi_sys_vendor, "Hewlett-Packard"))) | ||
475 | return false; | ||
476 | |||
477 | if (strstr(dmi_product_name, "Z420") || | ||
478 | strstr(dmi_product_name, "Z620") || | ||
479 | strstr(dmi_product_name, "Z820")) | ||
480 | return true; | ||
481 | |||
482 | return false; | ||
483 | } | ||
484 | |||
485 | static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci) | ||
486 | { | ||
487 | return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1)); | ||
488 | } | ||
489 | |||
490 | |||
400 | /* | 491 | /* |
401 | * Initialize memory for HCD and xHC (one-time init). | 492 | * Initialize memory for HCD and xHC (one-time init). |
402 | * | 493 | * |
@@ -420,6 +511,12 @@ int xhci_init(struct usb_hcd *hcd) | |||
420 | retval = xhci_mem_init(xhci, GFP_KERNEL); | 511 | retval = xhci_mem_init(xhci, GFP_KERNEL); |
421 | xhci_dbg(xhci, "Finished xhci_init\n"); | 512 | xhci_dbg(xhci, "Finished xhci_init\n"); |
422 | 513 | ||
514 | /* Initializing Compliance Mode Recovery Data If Needed */ | ||
515 | if (compliance_mode_recovery_timer_quirk_check()) { | ||
516 | xhci->quirks |= XHCI_COMP_MODE_QUIRK; | ||
517 | compliance_mode_recovery_timer_init(xhci); | ||
518 | } | ||
519 | |||
423 | return retval; | 520 | return retval; |
424 | } | 521 | } |
425 | 522 | ||
@@ -628,6 +725,11 @@ void xhci_stop(struct usb_hcd *hcd) | |||
628 | del_timer_sync(&xhci->event_ring_timer); | 725 | del_timer_sync(&xhci->event_ring_timer); |
629 | #endif | 726 | #endif |
630 | 727 | ||
728 | /* Deleting Compliance Mode Recovery Timer */ | ||
729 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
730 | (!(xhci_all_ports_seen_u0(xhci)))) | ||
731 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
732 | |||
631 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | 733 | if (xhci->quirks & XHCI_AMD_PLL_FIX) |
632 | usb_amd_dev_put(); | 734 | usb_amd_dev_put(); |
633 | 735 | ||
@@ -658,6 +760,9 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
658 | { | 760 | { |
659 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 761 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
660 | 762 | ||
763 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) | ||
764 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); | ||
765 | |||
661 | spin_lock_irq(&xhci->lock); | 766 | spin_lock_irq(&xhci->lock); |
662 | xhci_halt(xhci); | 767 | xhci_halt(xhci); |
663 | spin_unlock_irq(&xhci->lock); | 768 | spin_unlock_irq(&xhci->lock); |
@@ -802,6 +907,16 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
802 | } | 907 | } |
803 | spin_unlock_irq(&xhci->lock); | 908 | spin_unlock_irq(&xhci->lock); |
804 | 909 | ||
910 | /* | ||
911 | * Deleting Compliance Mode Recovery Timer because the xHCI Host | ||
912 | * is about to be suspended. | ||
913 | */ | ||
914 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
915 | (!(xhci_all_ports_seen_u0(xhci)))) { | ||
916 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
917 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted!\n"); | ||
918 | } | ||
919 | |||
805 | /* step 5: remove core well power */ | 920 | /* step 5: remove core well power */ |
806 | /* synchronize irq when using MSI-X */ | 921 | /* synchronize irq when using MSI-X */ |
807 | xhci_msix_sync_irqs(xhci); | 922 | xhci_msix_sync_irqs(xhci); |
@@ -934,6 +1049,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
934 | usb_hcd_resume_root_hub(hcd); | 1049 | usb_hcd_resume_root_hub(hcd); |
935 | usb_hcd_resume_root_hub(xhci->shared_hcd); | 1050 | usb_hcd_resume_root_hub(xhci->shared_hcd); |
936 | } | 1051 | } |
1052 | |||
1053 | /* | ||
1054 | * If system is subject to the Quirk, Compliance Mode Timer needs to | ||
1055 | * be re-initialized Always after a system resume. Ports are subject | ||
1056 | * to suffer the Compliance Mode issue again. It doesn't matter if | ||
1057 | * ports have entered previously to U0 before system's suspension. | ||
1058 | */ | ||
1059 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | ||
1060 | compliance_mode_recovery_timer_init(xhci); | ||
1061 | |||
937 | return retval; | 1062 | return retval; |
938 | } | 1063 | } |
939 | #endif /* CONFIG_PM */ | 1064 | #endif /* CONFIG_PM */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 55c0785810c9..1a05908c6673 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1494,6 +1494,8 @@ struct xhci_hcd { | |||
1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) | 1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) |
1495 | #define XHCI_LPM_SUPPORT (1 << 11) | 1495 | #define XHCI_LPM_SUPPORT (1 << 11) |
1496 | #define XHCI_INTEL_HOST (1 << 12) | 1496 | #define XHCI_INTEL_HOST (1 << 12) |
1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) | ||
1498 | #define XHCI_COMP_MODE_QUIRK (1 << 14) | ||
1497 | unsigned int num_active_eps; | 1499 | unsigned int num_active_eps; |
1498 | unsigned int limit_active_eps; | 1500 | unsigned int limit_active_eps; |
1499 | /* There are two roothubs to keep track of bus suspend info for */ | 1501 | /* There are two roothubs to keep track of bus suspend info for */ |
@@ -1510,6 +1512,11 @@ struct xhci_hcd { | |||
1510 | unsigned sw_lpm_support:1; | 1512 | unsigned sw_lpm_support:1; |
1511 | /* support xHCI 1.0 spec USB2 hardware LPM */ | 1513 | /* support xHCI 1.0 spec USB2 hardware LPM */ |
1512 | unsigned hw_lpm_support:1; | 1514 | unsigned hw_lpm_support:1; |
1515 | /* Compliance Mode Recovery Data */ | ||
1516 | struct timer_list comp_mode_recovery_timer; | ||
1517 | u32 port_status_u0; | ||
1518 | /* Compliance Mode Timer Triggered every 2 seconds */ | ||
1519 | #define COMP_MODE_RCVRY_MSECS 2000 | ||
1513 | }; | 1520 | }; |
1514 | 1521 | ||
1515 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 1522 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
@@ -1537,6 +1544,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
1537 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1544 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1538 | #define xhci_warn(xhci, fmt, args...) \ | 1545 | #define xhci_warn(xhci, fmt, args...) \ |
1539 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1546 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1547 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | ||
1548 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | ||
1540 | 1549 | ||
1541 | /* TODO: copied from ehci.h - can be refactored? */ | 1550 | /* TODO: copied from ehci.h - can be refactored? */ |
1542 | /* xHCI spec says all registers are little endian */ | 1551 | /* xHCI spec says all registers are little endian */ |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index ff08015b230c..ae794b90766b 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -232,7 +232,7 @@ wraperr: | |||
232 | return err; | 232 | return err; |
233 | } | 233 | } |
234 | 234 | ||
235 | static const struct usb_device_id id_table[] __devinitconst = { | 235 | static const struct usb_device_id id_table[] = { |
236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, | 236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, |
237 | { } /* Terminating entry */ | 237 | { } /* Terminating entry */ |
238 | }; | 238 | }; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ef0c3f9f0947..6259f0d99324 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -8,7 +8,7 @@ config USB_MUSB_HDRC | |||
8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
9 | depends on USB && USB_GADGET | 9 | depends on USB && USB_GADGET |
10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) | 10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) |
11 | select NOP_USB_XCEIV if (SOC_OMAPTI81XX || SOC_OMAPAM33XX) | 11 | select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) |
12 | select TWL4030_USB if MACH_OMAP_3430SDP | 12 | select TWL4030_USB if MACH_OMAP_3430SDP |
13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
14 | select USB_OTG_UTILS | 14 | select USB_OTG_UTILS |
@@ -57,7 +57,7 @@ config USB_MUSB_AM35X | |||
57 | 57 | ||
58 | config USB_MUSB_DSPS | 58 | config USB_MUSB_DSPS |
59 | tristate "TI DSPS platforms" | 59 | tristate "TI DSPS platforms" |
60 | depends on SOC_OMAPTI81XX || SOC_OMAPAM33XX | 60 | depends on SOC_TI81XX || SOC_AM33XX |
61 | 61 | ||
62 | config USB_MUSB_BLACKFIN | 62 | config USB_MUSB_BLACKFIN |
63 | tristate "Blackfin" | 63 | tristate "Blackfin" |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 217808d9fbe1..494772fc9e23 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -479,9 +479,9 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
479 | ret = -ENODEV; | 479 | ret = -ENODEV; |
480 | goto err0; | 480 | goto err0; |
481 | } | 481 | } |
482 | strcpy((u8 *)res->name, "mc"); | ||
483 | res->parent = NULL; | 482 | res->parent = NULL; |
484 | resources[1] = *res; | 483 | resources[1] = *res; |
484 | resources[1].name = "mc"; | ||
485 | 485 | ||
486 | /* allocate the child platform device */ | 486 | /* allocate the child platform device */ |
487 | musb = platform_device_alloc("musb-hdrc", -1); | 487 | musb = platform_device_alloc("musb-hdrc", -1); |
@@ -566,27 +566,28 @@ static int __devinit dsps_probe(struct platform_device *pdev) | |||
566 | } | 566 | } |
567 | platform_set_drvdata(pdev, glue); | 567 | platform_set_drvdata(pdev, glue); |
568 | 568 | ||
569 | /* create the child platform device for first instances of musb */ | ||
570 | ret = dsps_create_musb_pdev(glue, 0); | ||
571 | if (ret != 0) { | ||
572 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
573 | goto err2; | ||
574 | } | ||
575 | |||
576 | /* enable the usbss clocks */ | 569 | /* enable the usbss clocks */ |
577 | pm_runtime_enable(&pdev->dev); | 570 | pm_runtime_enable(&pdev->dev); |
578 | 571 | ||
579 | ret = pm_runtime_get_sync(&pdev->dev); | 572 | ret = pm_runtime_get_sync(&pdev->dev); |
580 | if (ret < 0) { | 573 | if (ret < 0) { |
581 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); | 574 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); |
575 | goto err2; | ||
576 | } | ||
577 | |||
578 | /* create the child platform device for first instances of musb */ | ||
579 | ret = dsps_create_musb_pdev(glue, 0); | ||
580 | if (ret != 0) { | ||
581 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
582 | goto err3; | 582 | goto err3; |
583 | } | 583 | } |
584 | 584 | ||
585 | return 0; | 585 | return 0; |
586 | 586 | ||
587 | err3: | 587 | err3: |
588 | pm_runtime_disable(&pdev->dev); | 588 | pm_runtime_put(&pdev->dev); |
589 | err2: | 589 | err2: |
590 | pm_runtime_disable(&pdev->dev); | ||
590 | kfree(glue->wrp); | 591 | kfree(glue->wrp); |
591 | err1: | 592 | err1: |
592 | kfree(glue); | 593 | kfree(glue); |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4bb717d0bd41..1ae378d5fc6f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -2049,7 +2049,7 @@ static int musb_urb_enqueue( | |||
2049 | * we only have work to do in the former case. | 2049 | * we only have work to do in the former case. |
2050 | */ | 2050 | */ |
2051 | spin_lock_irqsave(&musb->lock, flags); | 2051 | spin_lock_irqsave(&musb->lock, flags); |
2052 | if (hep->hcpriv) { | 2052 | if (hep->hcpriv || !next_urb(qh)) { |
2053 | /* some concurrent activity submitted another urb to hep... | 2053 | /* some concurrent activity submitted another urb to hep... |
2054 | * odd, rare, error prone, but legal. | 2054 | * odd, rare, error prone, but legal. |
2055 | */ | 2055 | */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 57a608584e16..c1be687e00ec 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -388,7 +388,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
388 | struct platform_device *pdev = to_platform_device(dev); | 388 | struct platform_device *pdev = to_platform_device(dev); |
389 | int irq = platform_get_irq_byname(pdev, "dma"); | 389 | int irq = platform_get_irq_byname(pdev, "dma"); |
390 | 390 | ||
391 | if (irq == 0) { | 391 | if (irq <= 0) { |
392 | dev_err(dev, "No DMA interrupt line!\n"); | 392 | dev_err(dev, "No DMA interrupt line!\n"); |
393 | return NULL; | 393 | return NULL; |
394 | } | 394 | } |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1a1bd9cf40c5..341625442377 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1215,7 +1215,7 @@ static int __devinit tusb_probe(struct platform_device *pdev) | |||
1215 | ret = platform_device_add(musb); | 1215 | ret = platform_device_add(musb); |
1216 | if (ret) { | 1216 | if (ret) { |
1217 | dev_err(&pdev->dev, "failed to register musb device\n"); | 1217 | dev_err(&pdev->dev, "failed to register musb device\n"); |
1218 | goto err1; | 1218 | goto err2; |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | return 0; | 1221 | return 0; |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 8c9bb1ad3069..681da06170c2 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -603,12 +603,12 @@ static int usbhsc_resume(struct device *dev) | |||
603 | struct usbhs_priv *priv = dev_get_drvdata(dev); | 603 | struct usbhs_priv *priv = dev_get_drvdata(dev); |
604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | 604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
605 | 605 | ||
606 | usbhs_platform_call(priv, phy_reset, pdev); | ||
607 | |||
608 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) | 606 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) |
609 | usbhsc_power_ctrl(priv, 1); | 607 | usbhsc_power_ctrl(priv, 1); |
610 | 608 | ||
611 | usbhsc_hotplug(priv); | 609 | usbhs_platform_call(priv, phy_reset, pdev); |
610 | |||
611 | usbhsc_drvcllbck_notify_hotplug(pdev); | ||
612 | 612 | ||
613 | return 0; | 613 | return 0; |
614 | } | 614 | } |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ecd173032fd4..143c4e9e1be4 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -818,7 +818,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
818 | usbhs_pipe_is_dcp(pipe)) | 818 | usbhs_pipe_is_dcp(pipe)) |
819 | goto usbhsf_pio_prepare_push; | 819 | goto usbhsf_pio_prepare_push; |
820 | 820 | ||
821 | if (len % 4) /* 32bit alignment */ | 821 | if (len & 0x7) /* 8byte alignment */ |
822 | goto usbhsf_pio_prepare_push; | 822 | goto usbhsf_pio_prepare_push; |
823 | 823 | ||
824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
@@ -905,7 +905,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
905 | /* use PIO if packet is less than pio_dma_border */ | 905 | /* use PIO if packet is less than pio_dma_border */ |
906 | len = usbhsf_fifo_rcv_len(priv, fifo); | 906 | len = usbhsf_fifo_rcv_len(priv, fifo); |
907 | len = min(pkt->length - pkt->actual, len); | 907 | len = min(pkt->length - pkt->actual, len); |
908 | if (len % 4) /* 32bit alignment */ | 908 | if (len & 0x7) /* 8byte alignment */ |
909 | goto usbhsf_pio_prepare_pop_unselect; | 909 | goto usbhsf_pio_prepare_pop_unselect; |
910 | 910 | ||
911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) | 911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 1834cf50888c..9b69a1323294 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -1266,6 +1266,12 @@ static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
1266 | return ret; | 1266 | return ret; |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | static int usbhsh_bus_nop(struct usb_hcd *hcd) | ||
1270 | { | ||
1271 | /* nothing to do */ | ||
1272 | return 0; | ||
1273 | } | ||
1274 | |||
1269 | static struct hc_driver usbhsh_driver = { | 1275 | static struct hc_driver usbhsh_driver = { |
1270 | .description = usbhsh_hcd_name, | 1276 | .description = usbhsh_hcd_name, |
1271 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), | 1277 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), |
@@ -1290,6 +1296,8 @@ static struct hc_driver usbhsh_driver = { | |||
1290 | */ | 1296 | */ |
1291 | .hub_status_data = usbhsh_hub_status_data, | 1297 | .hub_status_data = usbhsh_hub_status_data, |
1292 | .hub_control = usbhsh_hub_control, | 1298 | .hub_control = usbhsh_hub_control, |
1299 | .bus_suspend = usbhsh_bus_nop, | ||
1300 | .bus_resume = usbhsh_bus_nop, | ||
1293 | }; | 1301 | }; |
1294 | 1302 | ||
1295 | /* | 1303 | /* |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index f398d1e34474..c15f2e7cefc7 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -61,18 +61,23 @@ static int usb_serial_device_probe(struct device *dev) | |||
61 | goto exit; | 61 | goto exit; |
62 | } | 62 | } |
63 | 63 | ||
64 | /* make sure suspend/resume doesn't race against port_probe */ | ||
65 | retval = usb_autopm_get_interface(port->serial->interface); | ||
66 | if (retval) | ||
67 | goto exit; | ||
68 | |||
64 | driver = port->serial->type; | 69 | driver = port->serial->type; |
65 | if (driver->port_probe) { | 70 | if (driver->port_probe) { |
66 | retval = driver->port_probe(port); | 71 | retval = driver->port_probe(port); |
67 | if (retval) | 72 | if (retval) |
68 | goto exit; | 73 | goto exit_with_autopm; |
69 | } | 74 | } |
70 | 75 | ||
71 | retval = device_create_file(dev, &dev_attr_port_number); | 76 | retval = device_create_file(dev, &dev_attr_port_number); |
72 | if (retval) { | 77 | if (retval) { |
73 | if (driver->port_remove) | 78 | if (driver->port_remove) |
74 | retval = driver->port_remove(port); | 79 | retval = driver->port_remove(port); |
75 | goto exit; | 80 | goto exit_with_autopm; |
76 | } | 81 | } |
77 | 82 | ||
78 | minor = port->number; | 83 | minor = port->number; |
@@ -81,6 +86,8 @@ static int usb_serial_device_probe(struct device *dev) | |||
81 | "%s converter now attached to ttyUSB%d\n", | 86 | "%s converter now attached to ttyUSB%d\n", |
82 | driver->description, minor); | 87 | driver->description, minor); |
83 | 88 | ||
89 | exit_with_autopm: | ||
90 | usb_autopm_put_interface(port->serial->interface); | ||
84 | exit: | 91 | exit: |
85 | return retval; | 92 | return retval; |
86 | } | 93 | } |
@@ -96,6 +103,9 @@ static int usb_serial_device_remove(struct device *dev) | |||
96 | if (!port) | 103 | if (!port) |
97 | return -ENODEV; | 104 | return -ENODEV; |
98 | 105 | ||
106 | /* make sure suspend/resume doesn't race against port_remove */ | ||
107 | usb_autopm_get_interface(port->serial->interface); | ||
108 | |||
99 | device_remove_file(&port->dev, &dev_attr_port_number); | 109 | device_remove_file(&port->dev, &dev_attr_port_number); |
100 | 110 | ||
101 | driver = port->serial->type; | 111 | driver = port->serial->type; |
@@ -107,6 +117,7 @@ static int usb_serial_device_remove(struct device *dev) | |||
107 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", | 117 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", |
108 | driver->description, minor); | 118 | driver->description, minor); |
109 | 119 | ||
120 | usb_autopm_put_interface(port->serial->interface); | ||
110 | return retval; | 121 | return retval; |
111 | } | 122 | } |
112 | 123 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bc912e5a3beb..f906b3aec217 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -704,6 +704,7 @@ static struct usb_device_id id_table_combined [] = { | |||
704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, | 704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, |
705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, | 705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, |
706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, | 706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, |
707 | { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) }, | ||
707 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, | 708 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, |
708 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, | 709 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, |
709 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, | 710 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, |
@@ -804,13 +805,33 @@ static struct usb_device_id id_table_combined [] = { | |||
804 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 805 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
805 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), | 806 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), |
806 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 807 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
807 | { USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, | 808 | { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, |
809 | USB_CLASS_VENDOR_SPEC, | ||
810 | USB_SUBCLASS_VENDOR_SPEC, 0x00) }, | ||
808 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 811 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
809 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 812 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
810 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 813 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 814 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | 815 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, |
816 | { USB_DEVICE(FTDI_VID, PI_C865_PID) }, | ||
817 | { USB_DEVICE(FTDI_VID, PI_C857_PID) }, | ||
818 | { USB_DEVICE(PI_VID, PI_C866_PID) }, | ||
819 | { USB_DEVICE(PI_VID, PI_C663_PID) }, | ||
820 | { USB_DEVICE(PI_VID, PI_C725_PID) }, | ||
821 | { USB_DEVICE(PI_VID, PI_E517_PID) }, | ||
822 | { USB_DEVICE(PI_VID, PI_C863_PID) }, | ||
813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, | 823 | { USB_DEVICE(PI_VID, PI_E861_PID) }, |
824 | { USB_DEVICE(PI_VID, PI_C867_PID) }, | ||
825 | { USB_DEVICE(PI_VID, PI_E609_PID) }, | ||
826 | { USB_DEVICE(PI_VID, PI_E709_PID) }, | ||
827 | { USB_DEVICE(PI_VID, PI_100F_PID) }, | ||
828 | { USB_DEVICE(PI_VID, PI_1011_PID) }, | ||
829 | { USB_DEVICE(PI_VID, PI_1012_PID) }, | ||
830 | { USB_DEVICE(PI_VID, PI_1013_PID) }, | ||
831 | { USB_DEVICE(PI_VID, PI_1014_PID) }, | ||
832 | { USB_DEVICE(PI_VID, PI_1015_PID) }, | ||
833 | { USB_DEVICE(PI_VID, PI_1016_PID) }, | ||
834 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, | ||
814 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 835 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
815 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 836 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
816 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 837 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5661c7e2d415..41fe5826100c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -75,6 +75,9 @@ | |||
75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | 75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB |
76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC | 76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC |
77 | 77 | ||
78 | /* NZR SEM 16+ USB (http://www.nzr.de) */ | ||
79 | #define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ | ||
80 | |||
78 | /* | 81 | /* |
79 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) | 82 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) |
80 | */ | 83 | */ |
@@ -539,7 +542,10 @@ | |||
539 | /* | 542 | /* |
540 | * Microchip Technology, Inc. | 543 | * Microchip Technology, Inc. |
541 | * | 544 | * |
542 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: | 545 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are |
546 | * used by single function CDC ACM class based firmware demo | ||
547 | * applications. The VID/PID has also been used in firmware | ||
548 | * emulating FTDI serial chips by: | ||
543 | * Hornby Elite - Digital Command Control Console | 549 | * Hornby Elite - Digital Command Control Console |
544 | * http://www.hornby.com/hornby-dcc/controllers/ | 550 | * http://www.hornby.com/hornby-dcc/controllers/ |
545 | */ | 551 | */ |
@@ -791,8 +797,34 @@ | |||
791 | * Physik Instrumente | 797 | * Physik Instrumente |
792 | * http://www.physikinstrumente.com/en/products/ | 798 | * http://www.physikinstrumente.com/en/products/ |
793 | */ | 799 | */ |
800 | /* These two devices use the VID of FTDI */ | ||
801 | #define PI_C865_PID 0xe0a0 /* PI C-865 Piezomotor Controller */ | ||
802 | #define PI_C857_PID 0xe0a1 /* PI Encoder Trigger Box */ | ||
803 | |||
794 | #define PI_VID 0x1a72 /* Vendor ID */ | 804 | #define PI_VID 0x1a72 /* Vendor ID */ |
795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ | 805 | #define PI_C866_PID 0x1000 /* PI C-866 Piezomotor Controller */ |
806 | #define PI_C663_PID 0x1001 /* PI C-663 Mercury-Step */ | ||
807 | #define PI_C725_PID 0x1002 /* PI C-725 Piezomotor Controller */ | ||
808 | #define PI_E517_PID 0x1005 /* PI E-517 Digital Piezo Controller Operation Module */ | ||
809 | #define PI_C863_PID 0x1007 /* PI C-863 */ | ||
810 | #define PI_E861_PID 0x1008 /* PI E-861 Piezomotor Controller */ | ||
811 | #define PI_C867_PID 0x1009 /* PI C-867 Piezomotor Controller */ | ||
812 | #define PI_E609_PID 0x100D /* PI E-609 Digital Piezo Controller */ | ||
813 | #define PI_E709_PID 0x100E /* PI E-709 Digital Piezo Controller */ | ||
814 | #define PI_100F_PID 0x100F /* PI Digital Piezo Controller */ | ||
815 | #define PI_1011_PID 0x1011 /* PI Digital Piezo Controller */ | ||
816 | #define PI_1012_PID 0x1012 /* PI Motion Controller */ | ||
817 | #define PI_1013_PID 0x1013 /* PI Motion Controller */ | ||
818 | #define PI_1014_PID 0x1014 /* PI Device */ | ||
819 | #define PI_1015_PID 0x1015 /* PI Device */ | ||
820 | #define PI_1016_PID 0x1016 /* PI Digital Servo Module */ | ||
821 | |||
822 | /* | ||
823 | * Kondo Kagaku Co.Ltd. | ||
824 | * http://www.kondo-robot.com/EN | ||
825 | */ | ||
826 | #define KONDO_VID 0x165c | ||
827 | #define KONDO_USB_SERIAL_PID 0x0002 | ||
796 | 828 | ||
797 | /* | 829 | /* |
798 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. | 830 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 5811d34b6c6b..2cb30c535839 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -227,7 +227,6 @@ static void ipw_release(struct usb_serial *serial) | |||
227 | { | 227 | { |
228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); | 228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); |
229 | 229 | ||
230 | usb_wwan_release(serial); | ||
231 | usb_set_serial_data(serial, NULL); | 230 | usb_set_serial_data(serial, NULL); |
232 | kfree(data); | 231 | kfree(data); |
233 | } | 232 | } |
@@ -309,12 +308,12 @@ static struct usb_serial_driver ipw_device = { | |||
309 | .description = "IPWireless converter", | 308 | .description = "IPWireless converter", |
310 | .id_table = id_table, | 309 | .id_table = id_table, |
311 | .num_ports = 1, | 310 | .num_ports = 1, |
312 | .disconnect = usb_wwan_disconnect, | ||
313 | .open = ipw_open, | 311 | .open = ipw_open, |
314 | .close = ipw_close, | 312 | .close = ipw_close, |
315 | .probe = ipw_probe, | 313 | .probe = ipw_probe, |
316 | .attach = usb_wwan_startup, | 314 | .attach = usb_wwan_startup, |
317 | .release = ipw_release, | 315 | .release = ipw_release, |
316 | .port_remove = usb_wwan_port_remove, | ||
318 | .dtr_rts = ipw_dtr_rts, | 317 | .dtr_rts = ipw_dtr_rts, |
319 | .write = usb_wwan_write, | 318 | .write = usb_wwan_write, |
320 | }; | 319 | }; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 57eca2448424..2f6da1e89bfa 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -82,8 +82,7 @@ | |||
82 | * Defines used for sending commands to port | 82 | * Defines used for sending commands to port |
83 | */ | 83 | */ |
84 | 84 | ||
85 | #define WAIT_FOR_EVER (HZ * 0) /* timeout urb is wait for ever */ | 85 | #define MOS_WDR_TIMEOUT 5000 /* default urb timeout */ |
86 | #define MOS_WDR_TIMEOUT (HZ * 5) /* default urb timeout */ | ||
87 | 86 | ||
88 | #define MOS_PORT1 0x0200 | 87 | #define MOS_PORT1 0x0200 |
89 | #define MOS_PORT2 0x0300 | 88 | #define MOS_PORT2 0x0300 |
@@ -1232,9 +1231,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | |||
1232 | return 0; | 1231 | return 0; |
1233 | 1232 | ||
1234 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | 1233 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); |
1235 | for (i = 0; i < NUM_URBS; ++i) | 1234 | for (i = 0; i < NUM_URBS; ++i) { |
1236 | if (mos7840_port->busy[i]) | 1235 | if (mos7840_port->busy[i]) { |
1237 | chars += URB_TRANSFER_BUFFER_SIZE; | 1236 | struct urb *urb = mos7840_port->write_urb_pool[i]; |
1237 | chars += urb->transfer_buffer_length; | ||
1238 | } | ||
1239 | } | ||
1238 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | 1240 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); |
1239 | dbg("%s - returns %d", __func__, chars); | 1241 | dbg("%s - returns %d", __func__, chars); |
1240 | return chars; | 1242 | return chars; |
@@ -1344,7 +1346,7 @@ static void mos7840_close(struct usb_serial_port *port) | |||
1344 | static void mos7840_block_until_chase_response(struct tty_struct *tty, | 1346 | static void mos7840_block_until_chase_response(struct tty_struct *tty, |
1345 | struct moschip_port *mos7840_port) | 1347 | struct moschip_port *mos7840_port) |
1346 | { | 1348 | { |
1347 | int timeout = 1 * HZ; | 1349 | int timeout = msecs_to_jiffies(1000); |
1348 | int wait = 10; | 1350 | int wait = 10; |
1349 | int count; | 1351 | int count; |
1350 | 1352 | ||
@@ -2672,7 +2674,7 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2672 | 2674 | ||
2673 | /* setting configuration feature to one */ | 2675 | /* setting configuration feature to one */ |
2674 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2676 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
2675 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); | 2677 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); |
2676 | return 0; | 2678 | return 0; |
2677 | error: | 2679 | error: |
2678 | for (/* nothing */; i >= 0; i--) { | 2680 | for (/* nothing */; i >= 0; i--) { |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 08ff9b862049..5ce88d1bc6f1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -80,85 +80,9 @@ static void option_instat_callback(struct urb *urb); | |||
80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 | 80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 |
81 | 81 | ||
82 | #define HUAWEI_VENDOR_ID 0x12D1 | 82 | #define HUAWEI_VENDOR_ID 0x12D1 |
83 | #define HUAWEI_PRODUCT_E600 0x1001 | ||
84 | #define HUAWEI_PRODUCT_E220 0x1003 | ||
85 | #define HUAWEI_PRODUCT_E220BIS 0x1004 | ||
86 | #define HUAWEI_PRODUCT_E1401 0x1401 | ||
87 | #define HUAWEI_PRODUCT_E1402 0x1402 | ||
88 | #define HUAWEI_PRODUCT_E1403 0x1403 | ||
89 | #define HUAWEI_PRODUCT_E1404 0x1404 | ||
90 | #define HUAWEI_PRODUCT_E1405 0x1405 | ||
91 | #define HUAWEI_PRODUCT_E1406 0x1406 | ||
92 | #define HUAWEI_PRODUCT_E1407 0x1407 | ||
93 | #define HUAWEI_PRODUCT_E1408 0x1408 | ||
94 | #define HUAWEI_PRODUCT_E1409 0x1409 | ||
95 | #define HUAWEI_PRODUCT_E140A 0x140A | ||
96 | #define HUAWEI_PRODUCT_E140B 0x140B | ||
97 | #define HUAWEI_PRODUCT_E140C 0x140C | ||
98 | #define HUAWEI_PRODUCT_E140D 0x140D | ||
99 | #define HUAWEI_PRODUCT_E140E 0x140E | ||
100 | #define HUAWEI_PRODUCT_E140F 0x140F | ||
101 | #define HUAWEI_PRODUCT_E1410 0x1410 | ||
102 | #define HUAWEI_PRODUCT_E1411 0x1411 | ||
103 | #define HUAWEI_PRODUCT_E1412 0x1412 | ||
104 | #define HUAWEI_PRODUCT_E1413 0x1413 | ||
105 | #define HUAWEI_PRODUCT_E1414 0x1414 | ||
106 | #define HUAWEI_PRODUCT_E1415 0x1415 | ||
107 | #define HUAWEI_PRODUCT_E1416 0x1416 | ||
108 | #define HUAWEI_PRODUCT_E1417 0x1417 | ||
109 | #define HUAWEI_PRODUCT_E1418 0x1418 | ||
110 | #define HUAWEI_PRODUCT_E1419 0x1419 | ||
111 | #define HUAWEI_PRODUCT_E141A 0x141A | ||
112 | #define HUAWEI_PRODUCT_E141B 0x141B | ||
113 | #define HUAWEI_PRODUCT_E141C 0x141C | ||
114 | #define HUAWEI_PRODUCT_E141D 0x141D | ||
115 | #define HUAWEI_PRODUCT_E141E 0x141E | ||
116 | #define HUAWEI_PRODUCT_E141F 0x141F | ||
117 | #define HUAWEI_PRODUCT_E1420 0x1420 | ||
118 | #define HUAWEI_PRODUCT_E1421 0x1421 | ||
119 | #define HUAWEI_PRODUCT_E1422 0x1422 | ||
120 | #define HUAWEI_PRODUCT_E1423 0x1423 | ||
121 | #define HUAWEI_PRODUCT_E1424 0x1424 | ||
122 | #define HUAWEI_PRODUCT_E1425 0x1425 | ||
123 | #define HUAWEI_PRODUCT_E1426 0x1426 | ||
124 | #define HUAWEI_PRODUCT_E1427 0x1427 | ||
125 | #define HUAWEI_PRODUCT_E1428 0x1428 | ||
126 | #define HUAWEI_PRODUCT_E1429 0x1429 | ||
127 | #define HUAWEI_PRODUCT_E142A 0x142A | ||
128 | #define HUAWEI_PRODUCT_E142B 0x142B | ||
129 | #define HUAWEI_PRODUCT_E142C 0x142C | ||
130 | #define HUAWEI_PRODUCT_E142D 0x142D | ||
131 | #define HUAWEI_PRODUCT_E142E 0x142E | ||
132 | #define HUAWEI_PRODUCT_E142F 0x142F | ||
133 | #define HUAWEI_PRODUCT_E1430 0x1430 | ||
134 | #define HUAWEI_PRODUCT_E1431 0x1431 | ||
135 | #define HUAWEI_PRODUCT_E1432 0x1432 | ||
136 | #define HUAWEI_PRODUCT_E1433 0x1433 | ||
137 | #define HUAWEI_PRODUCT_E1434 0x1434 | ||
138 | #define HUAWEI_PRODUCT_E1435 0x1435 | ||
139 | #define HUAWEI_PRODUCT_E1436 0x1436 | ||
140 | #define HUAWEI_PRODUCT_E1437 0x1437 | ||
141 | #define HUAWEI_PRODUCT_E1438 0x1438 | ||
142 | #define HUAWEI_PRODUCT_E1439 0x1439 | ||
143 | #define HUAWEI_PRODUCT_E143A 0x143A | ||
144 | #define HUAWEI_PRODUCT_E143B 0x143B | ||
145 | #define HUAWEI_PRODUCT_E143C 0x143C | ||
146 | #define HUAWEI_PRODUCT_E143D 0x143D | ||
147 | #define HUAWEI_PRODUCT_E143E 0x143E | ||
148 | #define HUAWEI_PRODUCT_E143F 0x143F | ||
149 | #define HUAWEI_PRODUCT_K4505 0x1464 | 83 | #define HUAWEI_PRODUCT_K4505 0x1464 |
150 | #define HUAWEI_PRODUCT_K3765 0x1465 | 84 | #define HUAWEI_PRODUCT_K3765 0x1465 |
151 | #define HUAWEI_PRODUCT_E14AC 0x14AC | ||
152 | #define HUAWEI_PRODUCT_K3806 0x14AE | ||
153 | #define HUAWEI_PRODUCT_K4605 0x14C6 | 85 | #define HUAWEI_PRODUCT_K4605 0x14C6 |
154 | #define HUAWEI_PRODUCT_K5005 0x14C8 | ||
155 | #define HUAWEI_PRODUCT_K3770 0x14C9 | ||
156 | #define HUAWEI_PRODUCT_K3771 0x14CA | ||
157 | #define HUAWEI_PRODUCT_K4510 0x14CB | ||
158 | #define HUAWEI_PRODUCT_K4511 0x14CC | ||
159 | #define HUAWEI_PRODUCT_ETS1220 0x1803 | ||
160 | #define HUAWEI_PRODUCT_E353 0x1506 | ||
161 | #define HUAWEI_PRODUCT_E173S 0x1C05 | ||
162 | 86 | ||
163 | #define QUANTA_VENDOR_ID 0x0408 | 87 | #define QUANTA_VENDOR_ID 0x0408 |
164 | #define QUANTA_PRODUCT_Q101 0xEA02 | 88 | #define QUANTA_PRODUCT_Q101 0xEA02 |
@@ -615,104 +539,123 @@ static const struct usb_device_id option_ids[] = { | |||
615 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, | 539 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, |
616 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, | 540 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, |
617 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, | 541 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, |
618 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, | ||
619 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | ||
620 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | ||
621 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, | ||
622 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, | ||
623 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, | ||
624 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, | ||
625 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, | ||
626 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, | ||
627 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, | ||
628 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, | ||
629 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, | ||
630 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, | ||
631 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, | ||
632 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, | ||
633 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, | ||
634 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, | ||
635 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, | ||
636 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, | ||
637 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, | ||
638 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, | ||
639 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, | ||
640 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, | ||
641 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, | ||
642 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, | ||
643 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, | ||
644 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, | ||
645 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, | ||
646 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, | ||
647 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, | ||
648 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, | ||
649 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, | ||
650 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, | ||
651 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, | ||
652 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, | ||
653 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, | ||
654 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, | ||
655 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, | ||
656 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, | ||
657 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, | ||
658 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, | ||
659 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, | ||
660 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, | ||
661 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, | ||
662 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, | ||
663 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, | ||
664 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, | ||
665 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, | ||
666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, | ||
667 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, | ||
668 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, | ||
669 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, | ||
671 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, | ||
672 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, | ||
673 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, | ||
674 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, | ||
675 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, | ||
676 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, | ||
677 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, | ||
678 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, | ||
679 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, | ||
680 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, | ||
681 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, | ||
682 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, | ||
683 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, | ||
684 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, | ||
685 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 542 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
686 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 543 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
687 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), | 544 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), |
688 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 545 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
689 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, | ||
690 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, | ||
691 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, | ||
692 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), | 546 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), |
693 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 547 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
694 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, | 548 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, |
695 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, | 549 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, |
696 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, | 550 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, |
697 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, | 551 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) }, |
698 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, | 552 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) }, |
699 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, | 553 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) }, |
700 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, | 554 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) }, |
701 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, | 555 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) }, |
702 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, | 556 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) }, |
703 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, | 557 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) }, |
704 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, | 558 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) }, |
705 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, | 559 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) }, |
706 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, | 560 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) }, |
707 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, | 561 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) }, |
708 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, | 562 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) }, |
709 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, | 563 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) }, |
710 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, | 564 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) }, |
711 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, | 565 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) }, |
712 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, | 566 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) }, |
713 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ | 567 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) }, |
714 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ | 568 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) }, |
715 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ | 569 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) }, |
570 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) }, | ||
571 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) }, | ||
572 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) }, | ||
573 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) }, | ||
574 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) }, | ||
575 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) }, | ||
576 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) }, | ||
577 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) }, | ||
578 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) }, | ||
579 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) }, | ||
580 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) }, | ||
581 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) }, | ||
582 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) }, | ||
583 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) }, | ||
584 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) }, | ||
585 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) }, | ||
586 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) }, | ||
587 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) }, | ||
588 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) }, | ||
589 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) }, | ||
590 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) }, | ||
591 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) }, | ||
592 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) }, | ||
593 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) }, | ||
594 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) }, | ||
595 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, | ||
596 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, | ||
597 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, | ||
598 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, | ||
599 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, | ||
600 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, | ||
601 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) }, | ||
602 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) }, | ||
603 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
604 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) }, | ||
605 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) }, | ||
606 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) }, | ||
607 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
608 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) }, | ||
609 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) }, | ||
610 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) }, | ||
611 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) }, | ||
612 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) }, | ||
613 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) }, | ||
614 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) }, | ||
615 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) }, | ||
616 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) }, | ||
617 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) }, | ||
618 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) }, | ||
619 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) }, | ||
620 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) }, | ||
621 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) }, | ||
622 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) }, | ||
623 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) }, | ||
624 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) }, | ||
625 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) }, | ||
626 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) }, | ||
627 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) }, | ||
628 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) }, | ||
629 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) }, | ||
630 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) }, | ||
631 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) }, | ||
632 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) }, | ||
633 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) }, | ||
634 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) }, | ||
635 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) }, | ||
636 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) }, | ||
637 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) }, | ||
638 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) }, | ||
639 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) }, | ||
640 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) }, | ||
641 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) }, | ||
642 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) }, | ||
643 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) }, | ||
644 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) }, | ||
645 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) }, | ||
646 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) }, | ||
647 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) }, | ||
648 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) }, | ||
649 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, | ||
650 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, | ||
651 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, | ||
652 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, | ||
653 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, | ||
654 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, | ||
655 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, | ||
656 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, | ||
657 | |||
658 | |||
716 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, | 659 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
717 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, | 660 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
718 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, | 661 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
@@ -1147,6 +1090,10 @@ static const struct usb_device_id option_ids[] = { | |||
1147 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | 1090 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, |
1148 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | 1091 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), |
1149 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | 1092 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, |
1093 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
1094 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
1095 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, | ||
1096 | |||
1150 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1097 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
1151 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1098 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
1152 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 1099 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
@@ -1297,8 +1244,8 @@ static struct usb_serial_driver option_1port_device = { | |||
1297 | .tiocmset = usb_wwan_tiocmset, | 1244 | .tiocmset = usb_wwan_tiocmset, |
1298 | .ioctl = usb_wwan_ioctl, | 1245 | .ioctl = usb_wwan_ioctl, |
1299 | .attach = usb_wwan_startup, | 1246 | .attach = usb_wwan_startup, |
1300 | .disconnect = usb_wwan_disconnect, | ||
1301 | .release = option_release, | 1247 | .release = option_release, |
1248 | .port_remove = usb_wwan_port_remove, | ||
1302 | .read_int_callback = option_instat_callback, | 1249 | .read_int_callback = option_instat_callback, |
1303 | #ifdef CONFIG_PM | 1250 | #ifdef CONFIG_PM |
1304 | .suspend = usb_wwan_suspend, | 1251 | .suspend = usb_wwan_suspend, |
@@ -1414,8 +1361,6 @@ static void option_release(struct usb_serial *serial) | |||
1414 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); | 1361 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); |
1415 | struct option_private *priv = intfdata->private; | 1362 | struct option_private *priv = intfdata->private; |
1416 | 1363 | ||
1417 | usb_wwan_release(serial); | ||
1418 | |||
1419 | kfree(priv); | 1364 | kfree(priv); |
1420 | kfree(intfdata); | 1365 | kfree(intfdata); |
1421 | } | 1366 | } |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 8d103019d6aa..bfd50779f0c9 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -199,43 +199,49 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
199 | 199 | ||
200 | /* default to enabling interface */ | 200 | /* default to enabling interface */ |
201 | altsetting = 0; | 201 | altsetting = 0; |
202 | switch (ifnum) { | ||
203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
204 | * gets handled by other drivers. | ||
205 | */ | ||
206 | 202 | ||
203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
204 | * gets handled by other drivers. | ||
205 | */ | ||
206 | |||
207 | if (is_gobi1k) { | ||
207 | /* Gobi 1K USB layout: | 208 | /* Gobi 1K USB layout: |
208 | * 0: serial port (doesn't respond) | 209 | * 0: serial port (doesn't respond) |
209 | * 1: serial port (doesn't respond) | 210 | * 1: serial port (doesn't respond) |
210 | * 2: AT-capable modem port | 211 | * 2: AT-capable modem port |
211 | * 3: QMI/net | 212 | * 3: QMI/net |
212 | * | 213 | */ |
213 | * Gobi 2K+ USB layout: | 214 | if (ifnum == 2) |
215 | dev_dbg(dev, "Modem port found\n"); | ||
216 | else | ||
217 | altsetting = -1; | ||
218 | } else { | ||
219 | /* Gobi 2K+ USB layout: | ||
214 | * 0: QMI/net | 220 | * 0: QMI/net |
215 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) | 221 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) |
216 | * 2: AT-capable modem port | 222 | * 2: AT-capable modem port |
217 | * 3: NMEA | 223 | * 3: NMEA |
218 | */ | 224 | */ |
219 | 225 | switch (ifnum) { | |
220 | case 1: | 226 | case 0: |
221 | if (is_gobi1k) | 227 | /* Don't claim the QMI/net interface */ |
222 | altsetting = -1; | 228 | altsetting = -1; |
223 | else | 229 | break; |
230 | case 1: | ||
224 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); | 231 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); |
225 | break; | 232 | break; |
226 | case 2: | 233 | case 2: |
227 | dev_dbg(dev, "Modem port found\n"); | 234 | dev_dbg(dev, "Modem port found\n"); |
228 | break; | 235 | break; |
229 | case 3: | 236 | case 3: |
230 | if (is_gobi1k) | ||
231 | altsetting = -1; | ||
232 | else | ||
233 | /* | 237 | /* |
234 | * NMEA (serial line 9600 8N1) | 238 | * NMEA (serial line 9600 8N1) |
235 | * # echo "\$GPS_START" > /dev/ttyUSBx | 239 | * # echo "\$GPS_START" > /dev/ttyUSBx |
236 | * # echo "\$GPS_STOP" > /dev/ttyUSBx | 240 | * # echo "\$GPS_STOP" > /dev/ttyUSBx |
237 | */ | 241 | */ |
238 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); | 242 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); |
243 | break; | ||
244 | } | ||
239 | } | 245 | } |
240 | 246 | ||
241 | done: | 247 | done: |
@@ -262,8 +268,7 @@ static void qc_release(struct usb_serial *serial) | |||
262 | { | 268 | { |
263 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | 269 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); |
264 | 270 | ||
265 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | 271 | /* Free the private data allocated in qcprobe */ |
266 | usb_wwan_release(serial); | ||
267 | usb_set_serial_data(serial, NULL); | 272 | usb_set_serial_data(serial, NULL); |
268 | kfree(priv); | 273 | kfree(priv); |
269 | } | 274 | } |
@@ -283,8 +288,8 @@ static struct usb_serial_driver qcdevice = { | |||
283 | .write_room = usb_wwan_write_room, | 288 | .write_room = usb_wwan_write_room, |
284 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 289 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
285 | .attach = usb_wwan_startup, | 290 | .attach = usb_wwan_startup, |
286 | .disconnect = usb_wwan_disconnect, | ||
287 | .release = qc_release, | 291 | .release = qc_release, |
292 | .port_remove = usb_wwan_port_remove, | ||
288 | #ifdef CONFIG_PM | 293 | #ifdef CONFIG_PM |
289 | .suspend = usb_wwan_suspend, | 294 | .suspend = usb_wwan_suspend, |
290 | .resume = usb_wwan_resume, | 295 | .resume = usb_wwan_resume, |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index c47b6ec03063..1f034d2397c6 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
@@ -9,8 +9,7 @@ extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | |||
9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); |
10 | extern void usb_wwan_close(struct usb_serial_port *port); | 10 | extern void usb_wwan_close(struct usb_serial_port *port); |
11 | extern int usb_wwan_startup(struct usb_serial *serial); | 11 | extern int usb_wwan_startup(struct usb_serial *serial); |
12 | extern void usb_wwan_disconnect(struct usb_serial *serial); | 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); |
13 | extern void usb_wwan_release(struct usb_serial *serial); | ||
14 | extern int usb_wwan_write_room(struct tty_struct *tty); | 13 | extern int usb_wwan_write_room(struct tty_struct *tty); |
15 | extern void usb_wwan_set_termios(struct tty_struct *tty, | 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, |
16 | struct usb_serial_port *port, | 15 | struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index f35971dff4a5..6855d5ed0331 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -565,62 +565,52 @@ bail_out_error: | |||
565 | } | 565 | } |
566 | EXPORT_SYMBOL(usb_wwan_startup); | 566 | EXPORT_SYMBOL(usb_wwan_startup); |
567 | 567 | ||
568 | static void stop_read_write_urbs(struct usb_serial *serial) | 568 | int usb_wwan_port_remove(struct usb_serial_port *port) |
569 | { | 569 | { |
570 | int i, j; | 570 | int i; |
571 | struct usb_serial_port *port; | ||
572 | struct usb_wwan_port_private *portdata; | 571 | struct usb_wwan_port_private *portdata; |
573 | 572 | ||
574 | /* Stop reading/writing urbs */ | 573 | portdata = usb_get_serial_port_data(port); |
575 | for (i = 0; i < serial->num_ports; ++i) { | 574 | usb_set_serial_port_data(port, NULL); |
576 | port = serial->port[i]; | 575 | |
577 | portdata = usb_get_serial_port_data(port); | 576 | /* Stop reading/writing urbs and free them */ |
578 | for (j = 0; j < N_IN_URB; j++) | 577 | for (i = 0; i < N_IN_URB; i++) { |
579 | usb_kill_urb(portdata->in_urbs[j]); | 578 | usb_kill_urb(portdata->in_urbs[i]); |
580 | for (j = 0; j < N_OUT_URB; j++) | 579 | usb_free_urb(portdata->in_urbs[i]); |
581 | usb_kill_urb(portdata->out_urbs[j]); | 580 | free_page((unsigned long)portdata->in_buffer[i]); |
581 | } | ||
582 | for (i = 0; i < N_OUT_URB; i++) { | ||
583 | usb_kill_urb(portdata->out_urbs[i]); | ||
584 | usb_free_urb(portdata->out_urbs[i]); | ||
585 | kfree(portdata->out_buffer[i]); | ||
582 | } | 586 | } |
583 | } | ||
584 | 587 | ||
585 | void usb_wwan_disconnect(struct usb_serial *serial) | 588 | /* Now free port private data */ |
586 | { | 589 | kfree(portdata); |
587 | stop_read_write_urbs(serial); | 590 | return 0; |
588 | } | 591 | } |
589 | EXPORT_SYMBOL(usb_wwan_disconnect); | 592 | EXPORT_SYMBOL(usb_wwan_port_remove); |
590 | 593 | ||
591 | void usb_wwan_release(struct usb_serial *serial) | 594 | #ifdef CONFIG_PM |
595 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
592 | { | 596 | { |
593 | int i, j; | 597 | int i, j; |
594 | struct usb_serial_port *port; | 598 | struct usb_serial_port *port; |
595 | struct usb_wwan_port_private *portdata; | 599 | struct usb_wwan_port_private *portdata; |
596 | 600 | ||
597 | /* Now free them */ | 601 | /* Stop reading/writing urbs */ |
598 | for (i = 0; i < serial->num_ports; ++i) { | 602 | for (i = 0; i < serial->num_ports; ++i) { |
599 | port = serial->port[i]; | 603 | port = serial->port[i]; |
600 | portdata = usb_get_serial_port_data(port); | 604 | portdata = usb_get_serial_port_data(port); |
601 | 605 | if (!portdata) | |
602 | for (j = 0; j < N_IN_URB; j++) { | 606 | continue; |
603 | usb_free_urb(portdata->in_urbs[j]); | 607 | for (j = 0; j < N_IN_URB; j++) |
604 | free_page((unsigned long) | 608 | usb_kill_urb(portdata->in_urbs[j]); |
605 | portdata->in_buffer[j]); | 609 | for (j = 0; j < N_OUT_URB; j++) |
606 | portdata->in_urbs[j] = NULL; | 610 | usb_kill_urb(portdata->out_urbs[j]); |
607 | } | ||
608 | for (j = 0; j < N_OUT_URB; j++) { | ||
609 | usb_free_urb(portdata->out_urbs[j]); | ||
610 | kfree(portdata->out_buffer[j]); | ||
611 | portdata->out_urbs[j] = NULL; | ||
612 | } | ||
613 | } | ||
614 | |||
615 | /* Now free per port private data */ | ||
616 | for (i = 0; i < serial->num_ports; i++) { | ||
617 | port = serial->port[i]; | ||
618 | kfree(usb_get_serial_port_data(port)); | ||
619 | } | 611 | } |
620 | } | 612 | } |
621 | EXPORT_SYMBOL(usb_wwan_release); | ||
622 | 613 | ||
623 | #ifdef CONFIG_PM | ||
624 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) | 614 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) |
625 | { | 615 | { |
626 | struct usb_wwan_intf_private *intfdata = serial->private; | 616 | struct usb_wwan_intf_private *intfdata = serial->private; |
@@ -712,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial) | |||
712 | 702 | ||
713 | /* skip closed ports */ | 703 | /* skip closed ports */ |
714 | spin_lock_irq(&intfdata->susp_lock); | 704 | spin_lock_irq(&intfdata->susp_lock); |
715 | if (!portdata->opened) { | 705 | if (!portdata || !portdata->opened) { |
716 | spin_unlock_irq(&intfdata->susp_lock); | 706 | spin_unlock_irq(&intfdata->susp_lock); |
717 | continue; | 707 | continue; |
718 | } | 708 | } |
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 211a4920b88a..d8dedc7d3910 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c | |||
@@ -76,9 +76,24 @@ static int virqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) | |||
76 | schedule_work(&virqfd->inject); | 76 | schedule_work(&virqfd->inject); |
77 | } | 77 | } |
78 | 78 | ||
79 | if (flags & POLLHUP) | 79 | if (flags & POLLHUP) { |
80 | /* The eventfd is closing, detach from VFIO */ | 80 | unsigned long flags; |
81 | virqfd_deactivate(virqfd); | 81 | spin_lock_irqsave(&virqfd->vdev->irqlock, flags); |
82 | |||
83 | /* | ||
84 | * The eventfd is closing, if the virqfd has not yet been | ||
85 | * queued for release, as determined by testing whether the | ||
86 | * vdev pointer to it is still valid, queue it now. As | ||
87 | * with kvm irqfds, we know we won't race against the virqfd | ||
88 | * going away because we hold wqh->lock to get here. | ||
89 | */ | ||
90 | if (*(virqfd->pvirqfd) == virqfd) { | ||
91 | *(virqfd->pvirqfd) = NULL; | ||
92 | virqfd_deactivate(virqfd); | ||
93 | } | ||
94 | |||
95 | spin_unlock_irqrestore(&virqfd->vdev->irqlock, flags); | ||
96 | } | ||
82 | 97 | ||
83 | return 0; | 98 | return 0; |
84 | } | 99 | } |
@@ -93,7 +108,6 @@ static void virqfd_ptable_queue_proc(struct file *file, | |||
93 | static void virqfd_shutdown(struct work_struct *work) | 108 | static void virqfd_shutdown(struct work_struct *work) |
94 | { | 109 | { |
95 | struct virqfd *virqfd = container_of(work, struct virqfd, shutdown); | 110 | struct virqfd *virqfd = container_of(work, struct virqfd, shutdown); |
96 | struct virqfd **pvirqfd = virqfd->pvirqfd; | ||
97 | u64 cnt; | 111 | u64 cnt; |
98 | 112 | ||
99 | eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt); | 113 | eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt); |
@@ -101,7 +115,6 @@ static void virqfd_shutdown(struct work_struct *work) | |||
101 | eventfd_ctx_put(virqfd->eventfd); | 115 | eventfd_ctx_put(virqfd->eventfd); |
102 | 116 | ||
103 | kfree(virqfd); | 117 | kfree(virqfd); |
104 | *pvirqfd = NULL; | ||
105 | } | 118 | } |
106 | 119 | ||
107 | static void virqfd_inject(struct work_struct *work) | 120 | static void virqfd_inject(struct work_struct *work) |
@@ -122,15 +135,11 @@ static int virqfd_enable(struct vfio_pci_device *vdev, | |||
122 | int ret = 0; | 135 | int ret = 0; |
123 | unsigned int events; | 136 | unsigned int events; |
124 | 137 | ||
125 | if (*pvirqfd) | ||
126 | return -EBUSY; | ||
127 | |||
128 | virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL); | 138 | virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL); |
129 | if (!virqfd) | 139 | if (!virqfd) |
130 | return -ENOMEM; | 140 | return -ENOMEM; |
131 | 141 | ||
132 | virqfd->pvirqfd = pvirqfd; | 142 | virqfd->pvirqfd = pvirqfd; |
133 | *pvirqfd = virqfd; | ||
134 | virqfd->vdev = vdev; | 143 | virqfd->vdev = vdev; |
135 | virqfd->handler = handler; | 144 | virqfd->handler = handler; |
136 | virqfd->thread = thread; | 145 | virqfd->thread = thread; |
@@ -154,6 +163,23 @@ static int virqfd_enable(struct vfio_pci_device *vdev, | |||
154 | virqfd->eventfd = ctx; | 163 | virqfd->eventfd = ctx; |
155 | 164 | ||
156 | /* | 165 | /* |
166 | * virqfds can be released by closing the eventfd or directly | ||
167 | * through ioctl. These are both done through a workqueue, so | ||
168 | * we update the pointer to the virqfd under lock to avoid | ||
169 | * pushing multiple jobs to release the same virqfd. | ||
170 | */ | ||
171 | spin_lock_irq(&vdev->irqlock); | ||
172 | |||
173 | if (*pvirqfd) { | ||
174 | spin_unlock_irq(&vdev->irqlock); | ||
175 | ret = -EBUSY; | ||
176 | goto fail; | ||
177 | } | ||
178 | *pvirqfd = virqfd; | ||
179 | |||
180 | spin_unlock_irq(&vdev->irqlock); | ||
181 | |||
182 | /* | ||
157 | * Install our own custom wake-up handling so we are notified via | 183 | * Install our own custom wake-up handling so we are notified via |
158 | * a callback whenever someone signals the underlying eventfd. | 184 | * a callback whenever someone signals the underlying eventfd. |
159 | */ | 185 | */ |
@@ -187,19 +213,29 @@ fail: | |||
187 | fput(file); | 213 | fput(file); |
188 | 214 | ||
189 | kfree(virqfd); | 215 | kfree(virqfd); |
190 | *pvirqfd = NULL; | ||
191 | 216 | ||
192 | return ret; | 217 | return ret; |
193 | } | 218 | } |
194 | 219 | ||
195 | static void virqfd_disable(struct virqfd *virqfd) | 220 | static void virqfd_disable(struct vfio_pci_device *vdev, |
221 | struct virqfd **pvirqfd) | ||
196 | { | 222 | { |
197 | if (!virqfd) | 223 | unsigned long flags; |
198 | return; | 224 | |
225 | spin_lock_irqsave(&vdev->irqlock, flags); | ||
226 | |||
227 | if (*pvirqfd) { | ||
228 | virqfd_deactivate(*pvirqfd); | ||
229 | *pvirqfd = NULL; | ||
230 | } | ||
199 | 231 | ||
200 | virqfd_deactivate(virqfd); | 232 | spin_unlock_irqrestore(&vdev->irqlock, flags); |
201 | 233 | ||
202 | /* Block until we know all outstanding shutdown jobs have completed. */ | 234 | /* |
235 | * Block until we know all outstanding shutdown jobs have completed. | ||
236 | * Even if we don't queue the job, flush the wq to be sure it's | ||
237 | * been released. | ||
238 | */ | ||
203 | flush_workqueue(vfio_irqfd_cleanup_wq); | 239 | flush_workqueue(vfio_irqfd_cleanup_wq); |
204 | } | 240 | } |
205 | 241 | ||
@@ -392,8 +428,8 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd) | |||
392 | static void vfio_intx_disable(struct vfio_pci_device *vdev) | 428 | static void vfio_intx_disable(struct vfio_pci_device *vdev) |
393 | { | 429 | { |
394 | vfio_intx_set_signal(vdev, -1); | 430 | vfio_intx_set_signal(vdev, -1); |
395 | virqfd_disable(vdev->ctx[0].unmask); | 431 | virqfd_disable(vdev, &vdev->ctx[0].unmask); |
396 | virqfd_disable(vdev->ctx[0].mask); | 432 | virqfd_disable(vdev, &vdev->ctx[0].mask); |
397 | vdev->irq_type = VFIO_PCI_NUM_IRQS; | 433 | vdev->irq_type = VFIO_PCI_NUM_IRQS; |
398 | vdev->num_ctx = 0; | 434 | vdev->num_ctx = 0; |
399 | kfree(vdev->ctx); | 435 | kfree(vdev->ctx); |
@@ -539,8 +575,8 @@ static void vfio_msi_disable(struct vfio_pci_device *vdev, bool msix) | |||
539 | vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix); | 575 | vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix); |
540 | 576 | ||
541 | for (i = 0; i < vdev->num_ctx; i++) { | 577 | for (i = 0; i < vdev->num_ctx; i++) { |
542 | virqfd_disable(vdev->ctx[i].unmask); | 578 | virqfd_disable(vdev, &vdev->ctx[i].unmask); |
543 | virqfd_disable(vdev->ctx[i].mask); | 579 | virqfd_disable(vdev, &vdev->ctx[i].mask); |
544 | } | 580 | } |
545 | 581 | ||
546 | if (msix) { | 582 | if (msix) { |
@@ -577,7 +613,7 @@ static int vfio_pci_set_intx_unmask(struct vfio_pci_device *vdev, | |||
577 | vfio_send_intx_eventfd, NULL, | 613 | vfio_send_intx_eventfd, NULL, |
578 | &vdev->ctx[0].unmask, fd); | 614 | &vdev->ctx[0].unmask, fd); |
579 | 615 | ||
580 | virqfd_disable(vdev->ctx[0].unmask); | 616 | virqfd_disable(vdev, &vdev->ctx[0].unmask); |
581 | } | 617 | } |
582 | 618 | ||
583 | return 0; | 619 | return 0; |
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 9591e2b509d7..17830c9c7cc6 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c | |||
@@ -264,6 +264,7 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group) | |||
264 | return group; | 264 | return group; |
265 | } | 265 | } |
266 | 266 | ||
267 | /* called with vfio.group_lock held */ | ||
267 | static void vfio_group_release(struct kref *kref) | 268 | static void vfio_group_release(struct kref *kref) |
268 | { | 269 | { |
269 | struct vfio_group *group = container_of(kref, struct vfio_group, kref); | 270 | struct vfio_group *group = container_of(kref, struct vfio_group, kref); |
@@ -287,13 +288,7 @@ static void vfio_group_release(struct kref *kref) | |||
287 | 288 | ||
288 | static void vfio_group_put(struct vfio_group *group) | 289 | static void vfio_group_put(struct vfio_group *group) |
289 | { | 290 | { |
290 | mutex_lock(&vfio.group_lock); | 291 | kref_put_mutex(&group->kref, vfio_group_release, &vfio.group_lock); |
291 | /* | ||
292 | * Release needs to unlock to unregister the notifier, so only | ||
293 | * unlock if not released. | ||
294 | */ | ||
295 | if (!kref_put(&group->kref, vfio_group_release)) | ||
296 | mutex_unlock(&vfio.group_lock); | ||
297 | } | 292 | } |
298 | 293 | ||
299 | /* Assume group_lock or group reference is held */ | 294 | /* Assume group_lock or group reference is held */ |
@@ -401,7 +396,6 @@ static void vfio_device_release(struct kref *kref) | |||
401 | struct vfio_device, kref); | 396 | struct vfio_device, kref); |
402 | struct vfio_group *group = device->group; | 397 | struct vfio_group *group = device->group; |
403 | 398 | ||
404 | mutex_lock(&group->device_lock); | ||
405 | list_del(&device->group_next); | 399 | list_del(&device->group_next); |
406 | mutex_unlock(&group->device_lock); | 400 | mutex_unlock(&group->device_lock); |
407 | 401 | ||
@@ -416,8 +410,9 @@ static void vfio_device_release(struct kref *kref) | |||
416 | /* Device reference always implies a group reference */ | 410 | /* Device reference always implies a group reference */ |
417 | static void vfio_device_put(struct vfio_device *device) | 411 | static void vfio_device_put(struct vfio_device *device) |
418 | { | 412 | { |
419 | kref_put(&device->kref, vfio_device_release); | 413 | struct vfio_group *group = device->group; |
420 | vfio_group_put(device->group); | 414 | kref_put_mutex(&device->kref, vfio_device_release, &group->device_lock); |
415 | vfio_group_put(group); | ||
421 | } | 416 | } |
422 | 417 | ||
423 | static void vfio_device_get(struct vfio_device *device) | 418 | static void vfio_device_get(struct vfio_device *device) |
@@ -1116,10 +1111,10 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf) | |||
1116 | */ | 1111 | */ |
1117 | filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); | 1112 | filep->f_mode |= (FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); |
1118 | 1113 | ||
1119 | fd_install(ret, filep); | ||
1120 | |||
1121 | vfio_device_get(device); | 1114 | vfio_device_get(device); |
1122 | atomic_inc(&group->container_users); | 1115 | atomic_inc(&group->container_users); |
1116 | |||
1117 | fd_install(ret, filep); | ||
1123 | break; | 1118 | break; |
1124 | } | 1119 | } |
1125 | mutex_unlock(&group->device_lock); | 1120 | mutex_unlock(&group->device_lock); |
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index e4e2fd1b5107..202bba6c997c 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig | |||
@@ -9,3 +9,6 @@ config VHOST_NET | |||
9 | To compile this driver as a module, choose M here: the module will | 9 | To compile this driver as a module, choose M here: the module will |
10 | be called vhost_net. | 10 | be called vhost_net. |
11 | 11 | ||
12 | if STAGING | ||
13 | source "drivers/vhost/Kconfig.tcm" | ||
14 | endif | ||
diff --git a/drivers/vhost/Kconfig.tcm b/drivers/vhost/Kconfig.tcm new file mode 100644 index 000000000000..a9c6f76e3208 --- /dev/null +++ b/drivers/vhost/Kconfig.tcm | |||
@@ -0,0 +1,6 @@ | |||
1 | config TCM_VHOST | ||
2 | tristate "TCM_VHOST fabric module (EXPERIMENTAL)" | ||
3 | depends on TARGET_CORE && EVENTFD && EXPERIMENTAL && m | ||
4 | default n | ||
5 | ---help--- | ||
6 | Say M here to enable the TCM_VHOST fabric module for use with virtio-scsi guests | ||
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile index 72dd02050bb9..a27b053bc9ab 100644 --- a/drivers/vhost/Makefile +++ b/drivers/vhost/Makefile | |||
@@ -1,2 +1,4 @@ | |||
1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o | 1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o |
2 | vhost_net-y := vhost.o net.o | 2 | vhost_net-y := vhost.o net.o |
3 | |||
4 | obj-$(CONFIG_TCM_VHOST) += tcm_vhost.o | ||
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c new file mode 100644 index 000000000000..ed8e2e6c8df2 --- /dev/null +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -0,0 +1,1649 @@ | |||
1 | /******************************************************************************* | ||
2 | * Vhost kernel TCM fabric driver for virtio SCSI initiators | ||
3 | * | ||
4 | * (C) Copyright 2010-2012 RisingTide Systems LLC. | ||
5 | * (C) Copyright 2010-2012 IBM Corp. | ||
6 | * | ||
7 | * Licensed to the Linux Foundation under the General Public License (GPL) version 2. | ||
8 | * | ||
9 | * Authors: Nicholas A. Bellinger <nab@risingtidesystems.com> | ||
10 | * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <generated/utsrelease.h> | ||
27 | #include <linux/utsname.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/kthread.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/configfs.h> | ||
34 | #include <linux/ctype.h> | ||
35 | #include <linux/compat.h> | ||
36 | #include <linux/eventfd.h> | ||
37 | #include <linux/vhost.h> | ||
38 | #include <linux/fs.h> | ||
39 | #include <linux/miscdevice.h> | ||
40 | #include <asm/unaligned.h> | ||
41 | #include <scsi/scsi.h> | ||
42 | #include <scsi/scsi_tcq.h> | ||
43 | #include <target/target_core_base.h> | ||
44 | #include <target/target_core_fabric.h> | ||
45 | #include <target/target_core_fabric_configfs.h> | ||
46 | #include <target/target_core_configfs.h> | ||
47 | #include <target/configfs_macros.h> | ||
48 | #include <linux/vhost.h> | ||
49 | #include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */ | ||
50 | #include <linux/virtio_scsi.h> | ||
51 | |||
52 | #include "vhost.c" | ||
53 | #include "vhost.h" | ||
54 | #include "tcm_vhost.h" | ||
55 | |||
56 | enum { | ||
57 | VHOST_SCSI_VQ_CTL = 0, | ||
58 | VHOST_SCSI_VQ_EVT = 1, | ||
59 | VHOST_SCSI_VQ_IO = 2, | ||
60 | }; | ||
61 | |||
62 | struct vhost_scsi { | ||
63 | struct tcm_vhost_tpg *vs_tpg; /* Protected by vhost_scsi->dev.mutex */ | ||
64 | struct vhost_dev dev; | ||
65 | struct vhost_virtqueue vqs[3]; | ||
66 | |||
67 | struct vhost_work vs_completion_work; /* cmd completion work item */ | ||
68 | struct list_head vs_completion_list; /* cmd completion queue */ | ||
69 | spinlock_t vs_completion_lock; /* protects s_completion_list */ | ||
70 | }; | ||
71 | |||
72 | /* Local pointer to allocated TCM configfs fabric module */ | ||
73 | static struct target_fabric_configfs *tcm_vhost_fabric_configfs; | ||
74 | |||
75 | static struct workqueue_struct *tcm_vhost_workqueue; | ||
76 | |||
77 | /* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */ | ||
78 | static DEFINE_MUTEX(tcm_vhost_mutex); | ||
79 | static LIST_HEAD(tcm_vhost_list); | ||
80 | |||
81 | static int tcm_vhost_check_true(struct se_portal_group *se_tpg) | ||
82 | { | ||
83 | return 1; | ||
84 | } | ||
85 | |||
86 | static int tcm_vhost_check_false(struct se_portal_group *se_tpg) | ||
87 | { | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static char *tcm_vhost_get_fabric_name(void) | ||
92 | { | ||
93 | return "vhost"; | ||
94 | } | ||
95 | |||
96 | static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg) | ||
97 | { | ||
98 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
99 | struct tcm_vhost_tpg, se_tpg); | ||
100 | struct tcm_vhost_tport *tport = tpg->tport; | ||
101 | |||
102 | switch (tport->tport_proto_id) { | ||
103 | case SCSI_PROTOCOL_SAS: | ||
104 | return sas_get_fabric_proto_ident(se_tpg); | ||
105 | case SCSI_PROTOCOL_FCP: | ||
106 | return fc_get_fabric_proto_ident(se_tpg); | ||
107 | case SCSI_PROTOCOL_ISCSI: | ||
108 | return iscsi_get_fabric_proto_ident(se_tpg); | ||
109 | default: | ||
110 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
111 | " SAS emulation\n", tport->tport_proto_id); | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | return sas_get_fabric_proto_ident(se_tpg); | ||
116 | } | ||
117 | |||
118 | static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg) | ||
119 | { | ||
120 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
121 | struct tcm_vhost_tpg, se_tpg); | ||
122 | struct tcm_vhost_tport *tport = tpg->tport; | ||
123 | |||
124 | return &tport->tport_name[0]; | ||
125 | } | ||
126 | |||
127 | static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg) | ||
128 | { | ||
129 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
130 | struct tcm_vhost_tpg, se_tpg); | ||
131 | return tpg->tport_tpgt; | ||
132 | } | ||
133 | |||
134 | static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg) | ||
135 | { | ||
136 | return 1; | ||
137 | } | ||
138 | |||
139 | static u32 tcm_vhost_get_pr_transport_id(struct se_portal_group *se_tpg, | ||
140 | struct se_node_acl *se_nacl, | ||
141 | struct t10_pr_registration *pr_reg, | ||
142 | int *format_code, | ||
143 | unsigned char *buf) | ||
144 | { | ||
145 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
146 | struct tcm_vhost_tpg, se_tpg); | ||
147 | struct tcm_vhost_tport *tport = tpg->tport; | ||
148 | |||
149 | switch (tport->tport_proto_id) { | ||
150 | case SCSI_PROTOCOL_SAS: | ||
151 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
152 | format_code, buf); | ||
153 | case SCSI_PROTOCOL_FCP: | ||
154 | return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
155 | format_code, buf); | ||
156 | case SCSI_PROTOCOL_ISCSI: | ||
157 | return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
158 | format_code, buf); | ||
159 | default: | ||
160 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
161 | " SAS emulation\n", tport->tport_proto_id); | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
166 | format_code, buf); | ||
167 | } | ||
168 | |||
169 | static u32 tcm_vhost_get_pr_transport_id_len(struct se_portal_group *se_tpg, | ||
170 | struct se_node_acl *se_nacl, | ||
171 | struct t10_pr_registration *pr_reg, | ||
172 | int *format_code) | ||
173 | { | ||
174 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
175 | struct tcm_vhost_tpg, se_tpg); | ||
176 | struct tcm_vhost_tport *tport = tpg->tport; | ||
177 | |||
178 | switch (tport->tport_proto_id) { | ||
179 | case SCSI_PROTOCOL_SAS: | ||
180 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
181 | format_code); | ||
182 | case SCSI_PROTOCOL_FCP: | ||
183 | return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
184 | format_code); | ||
185 | case SCSI_PROTOCOL_ISCSI: | ||
186 | return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
187 | format_code); | ||
188 | default: | ||
189 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
190 | " SAS emulation\n", tport->tport_proto_id); | ||
191 | break; | ||
192 | } | ||
193 | |||
194 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
195 | format_code); | ||
196 | } | ||
197 | |||
198 | static char *tcm_vhost_parse_pr_out_transport_id(struct se_portal_group *se_tpg, | ||
199 | const char *buf, | ||
200 | u32 *out_tid_len, | ||
201 | char **port_nexus_ptr) | ||
202 | { | ||
203 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
204 | struct tcm_vhost_tpg, se_tpg); | ||
205 | struct tcm_vhost_tport *tport = tpg->tport; | ||
206 | |||
207 | switch (tport->tport_proto_id) { | ||
208 | case SCSI_PROTOCOL_SAS: | ||
209 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
210 | port_nexus_ptr); | ||
211 | case SCSI_PROTOCOL_FCP: | ||
212 | return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
213 | port_nexus_ptr); | ||
214 | case SCSI_PROTOCOL_ISCSI: | ||
215 | return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
216 | port_nexus_ptr); | ||
217 | default: | ||
218 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
219 | " SAS emulation\n", tport->tport_proto_id); | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
224 | port_nexus_ptr); | ||
225 | } | ||
226 | |||
227 | static struct se_node_acl *tcm_vhost_alloc_fabric_acl( | ||
228 | struct se_portal_group *se_tpg) | ||
229 | { | ||
230 | struct tcm_vhost_nacl *nacl; | ||
231 | |||
232 | nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL); | ||
233 | if (!nacl) { | ||
234 | pr_err("Unable to alocate struct tcm_vhost_nacl\n"); | ||
235 | return NULL; | ||
236 | } | ||
237 | |||
238 | return &nacl->se_node_acl; | ||
239 | } | ||
240 | |||
241 | static void tcm_vhost_release_fabric_acl(struct se_portal_group *se_tpg, | ||
242 | struct se_node_acl *se_nacl) | ||
243 | { | ||
244 | struct tcm_vhost_nacl *nacl = container_of(se_nacl, | ||
245 | struct tcm_vhost_nacl, se_node_acl); | ||
246 | kfree(nacl); | ||
247 | } | ||
248 | |||
249 | static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg) | ||
250 | { | ||
251 | return 1; | ||
252 | } | ||
253 | |||
254 | static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) | ||
255 | { | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | static int tcm_vhost_shutdown_session(struct se_session *se_sess) | ||
260 | { | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static void tcm_vhost_close_session(struct se_session *se_sess) | ||
265 | { | ||
266 | return; | ||
267 | } | ||
268 | |||
269 | static u32 tcm_vhost_sess_get_index(struct se_session *se_sess) | ||
270 | { | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int tcm_vhost_write_pending(struct se_cmd *se_cmd) | ||
275 | { | ||
276 | /* Go ahead and process the write immediately */ | ||
277 | target_execute_cmd(se_cmd); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd) | ||
282 | { | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl) | ||
287 | { | ||
288 | return; | ||
289 | } | ||
290 | |||
291 | static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd) | ||
297 | { | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) | ||
302 | { | ||
303 | struct vhost_scsi *vs = tv_cmd->tvc_vhost; | ||
304 | |||
305 | spin_lock_bh(&vs->vs_completion_lock); | ||
306 | list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); | ||
307 | spin_unlock_bh(&vs->vs_completion_lock); | ||
308 | |||
309 | vhost_work_queue(&vs->dev, &vs->vs_completion_work); | ||
310 | } | ||
311 | |||
312 | static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) | ||
313 | { | ||
314 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | ||
315 | struct tcm_vhost_cmd, tvc_se_cmd); | ||
316 | vhost_scsi_complete_cmd(tv_cmd); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int tcm_vhost_queue_status(struct se_cmd *se_cmd) | ||
321 | { | ||
322 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | ||
323 | struct tcm_vhost_cmd, tvc_se_cmd); | ||
324 | vhost_scsi_complete_cmd(tv_cmd); | ||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) | ||
329 | { | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, | ||
334 | u32 sense_length) | ||
335 | { | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | static u16 tcm_vhost_get_fabric_sense_len(void) | ||
340 | { | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) | ||
345 | { | ||
346 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
347 | |||
348 | /* TODO locking against target/backend threads? */ | ||
349 | transport_generic_free_cmd(se_cmd, 1); | ||
350 | |||
351 | if (tv_cmd->tvc_sgl_count) { | ||
352 | u32 i; | ||
353 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | ||
354 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | ||
355 | |||
356 | kfree(tv_cmd->tvc_sgl); | ||
357 | } | ||
358 | |||
359 | kfree(tv_cmd); | ||
360 | } | ||
361 | |||
362 | /* Dequeue a command from the completion list */ | ||
363 | static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion( | ||
364 | struct vhost_scsi *vs) | ||
365 | { | ||
366 | struct tcm_vhost_cmd *tv_cmd = NULL; | ||
367 | |||
368 | spin_lock_bh(&vs->vs_completion_lock); | ||
369 | if (list_empty(&vs->vs_completion_list)) { | ||
370 | spin_unlock_bh(&vs->vs_completion_lock); | ||
371 | return NULL; | ||
372 | } | ||
373 | |||
374 | list_for_each_entry(tv_cmd, &vs->vs_completion_list, | ||
375 | tvc_completion_list) { | ||
376 | list_del(&tv_cmd->tvc_completion_list); | ||
377 | break; | ||
378 | } | ||
379 | spin_unlock_bh(&vs->vs_completion_lock); | ||
380 | return tv_cmd; | ||
381 | } | ||
382 | |||
383 | /* Fill in status and signal that we are done processing this command | ||
384 | * | ||
385 | * This is scheduled in the vhost work queue so we are called with the owner | ||
386 | * process mm and can access the vring. | ||
387 | */ | ||
388 | static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | ||
389 | { | ||
390 | struct vhost_scsi *vs = container_of(work, struct vhost_scsi, | ||
391 | vs_completion_work); | ||
392 | struct tcm_vhost_cmd *tv_cmd; | ||
393 | |||
394 | while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs))) { | ||
395 | struct virtio_scsi_cmd_resp v_rsp; | ||
396 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
397 | int ret; | ||
398 | |||
399 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, | ||
400 | tv_cmd, se_cmd->residual_count, se_cmd->scsi_status); | ||
401 | |||
402 | memset(&v_rsp, 0, sizeof(v_rsp)); | ||
403 | v_rsp.resid = se_cmd->residual_count; | ||
404 | /* TODO is status_qualifier field needed? */ | ||
405 | v_rsp.status = se_cmd->scsi_status; | ||
406 | v_rsp.sense_len = se_cmd->scsi_sense_length; | ||
407 | memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf, | ||
408 | v_rsp.sense_len); | ||
409 | ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); | ||
410 | if (likely(ret == 0)) | ||
411 | vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0); | ||
412 | else | ||
413 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); | ||
414 | |||
415 | vhost_scsi_free_cmd(tv_cmd); | ||
416 | } | ||
417 | |||
418 | vhost_signal(&vs->dev, &vs->vqs[2]); | ||
419 | } | ||
420 | |||
421 | static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | ||
422 | struct tcm_vhost_tpg *tv_tpg, | ||
423 | struct virtio_scsi_cmd_req *v_req, | ||
424 | u32 exp_data_len, | ||
425 | int data_direction) | ||
426 | { | ||
427 | struct tcm_vhost_cmd *tv_cmd; | ||
428 | struct tcm_vhost_nexus *tv_nexus; | ||
429 | struct se_portal_group *se_tpg = &tv_tpg->se_tpg; | ||
430 | struct se_session *se_sess; | ||
431 | struct se_cmd *se_cmd; | ||
432 | int sam_task_attr; | ||
433 | |||
434 | tv_nexus = tv_tpg->tpg_nexus; | ||
435 | if (!tv_nexus) { | ||
436 | pr_err("Unable to locate active struct tcm_vhost_nexus\n"); | ||
437 | return ERR_PTR(-EIO); | ||
438 | } | ||
439 | se_sess = tv_nexus->tvn_se_sess; | ||
440 | |||
441 | tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); | ||
442 | if (!tv_cmd) { | ||
443 | pr_err("Unable to allocate struct tcm_vhost_cmd\n"); | ||
444 | return ERR_PTR(-ENOMEM); | ||
445 | } | ||
446 | INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); | ||
447 | tv_cmd->tvc_tag = v_req->tag; | ||
448 | |||
449 | se_cmd = &tv_cmd->tvc_se_cmd; | ||
450 | /* | ||
451 | * Locate the SAM Task Attr from virtio_scsi_cmd_req | ||
452 | */ | ||
453 | sam_task_attr = v_req->task_attr; | ||
454 | /* | ||
455 | * Initialize struct se_cmd descriptor from TCM infrastructure | ||
456 | */ | ||
457 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, | ||
458 | data_direction, sam_task_attr, | ||
459 | &tv_cmd->tvc_sense_buf[0]); | ||
460 | |||
461 | #if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ | ||
462 | if (bidi) | ||
463 | se_cmd->se_cmd_flags |= SCF_BIDI; | ||
464 | #endif | ||
465 | return tv_cmd; | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * Map a user memory range into a scatterlist | ||
470 | * | ||
471 | * Returns the number of scatterlist entries used or -errno on error. | ||
472 | */ | ||
473 | static int vhost_scsi_map_to_sgl(struct scatterlist *sgl, | ||
474 | unsigned int sgl_count, void __user *ptr, size_t len, int write) | ||
475 | { | ||
476 | struct scatterlist *sg = sgl; | ||
477 | unsigned int npages = 0; | ||
478 | int ret; | ||
479 | |||
480 | while (len > 0) { | ||
481 | struct page *page; | ||
482 | unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK; | ||
483 | unsigned int nbytes = min_t(unsigned int, | ||
484 | PAGE_SIZE - offset, len); | ||
485 | |||
486 | if (npages == sgl_count) { | ||
487 | ret = -ENOBUFS; | ||
488 | goto err; | ||
489 | } | ||
490 | |||
491 | ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page); | ||
492 | BUG_ON(ret == 0); /* we should either get our page or fail */ | ||
493 | if (ret < 0) | ||
494 | goto err; | ||
495 | |||
496 | sg_set_page(sg, page, nbytes, offset); | ||
497 | ptr += nbytes; | ||
498 | len -= nbytes; | ||
499 | sg++; | ||
500 | npages++; | ||
501 | } | ||
502 | return npages; | ||
503 | |||
504 | err: | ||
505 | /* Put pages that we hold */ | ||
506 | for (sg = sgl; sg != &sgl[npages]; sg++) | ||
507 | put_page(sg_page(sg)); | ||
508 | return ret; | ||
509 | } | ||
510 | |||
511 | static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, | ||
512 | struct iovec *iov, unsigned int niov, int write) | ||
513 | { | ||
514 | int ret; | ||
515 | unsigned int i; | ||
516 | u32 sgl_count; | ||
517 | struct scatterlist *sg; | ||
518 | |||
519 | /* | ||
520 | * Find out how long sglist needs to be | ||
521 | */ | ||
522 | sgl_count = 0; | ||
523 | for (i = 0; i < niov; i++) { | ||
524 | sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len + | ||
525 | PAGE_SIZE - 1) >> PAGE_SHIFT) - | ||
526 | ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT); | ||
527 | } | ||
528 | /* TODO overflow checking */ | ||
529 | |||
530 | sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); | ||
531 | if (!sg) | ||
532 | return -ENOMEM; | ||
533 | pr_debug("%s sg %p sgl_count %u is_err %d\n", __func__, | ||
534 | sg, sgl_count, !sg); | ||
535 | sg_init_table(sg, sgl_count); | ||
536 | |||
537 | tv_cmd->tvc_sgl = sg; | ||
538 | tv_cmd->tvc_sgl_count = sgl_count; | ||
539 | |||
540 | pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); | ||
541 | for (i = 0; i < niov; i++) { | ||
542 | ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base, | ||
543 | iov[i].iov_len, write); | ||
544 | if (ret < 0) { | ||
545 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | ||
546 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | ||
547 | kfree(tv_cmd->tvc_sgl); | ||
548 | tv_cmd->tvc_sgl = NULL; | ||
549 | tv_cmd->tvc_sgl_count = 0; | ||
550 | return ret; | ||
551 | } | ||
552 | |||
553 | sg += ret; | ||
554 | sgl_count -= ret; | ||
555 | } | ||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | static void tcm_vhost_submission_work(struct work_struct *work) | ||
560 | { | ||
561 | struct tcm_vhost_cmd *tv_cmd = | ||
562 | container_of(work, struct tcm_vhost_cmd, work); | ||
563 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
564 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; | ||
565 | int rc, sg_no_bidi = 0; | ||
566 | /* | ||
567 | * Locate the struct se_lun pointer based on v_req->lun, and | ||
568 | * attach it to struct se_cmd | ||
569 | */ | ||
570 | rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); | ||
571 | if (rc < 0) { | ||
572 | pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); | ||
573 | transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, | ||
574 | tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); | ||
575 | transport_generic_free_cmd(se_cmd, 0); | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); | ||
580 | if (rc == -ENOMEM) { | ||
581 | transport_send_check_condition_and_sense(se_cmd, | ||
582 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | ||
583 | transport_generic_free_cmd(se_cmd, 0); | ||
584 | return; | ||
585 | } else if (rc < 0) { | ||
586 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
587 | tcm_vhost_queue_status(se_cmd); | ||
588 | else | ||
589 | transport_send_check_condition_and_sense(se_cmd, | ||
590 | se_cmd->scsi_sense_reason, 0); | ||
591 | transport_generic_free_cmd(se_cmd, 0); | ||
592 | return; | ||
593 | } | ||
594 | |||
595 | if (tv_cmd->tvc_sgl_count) { | ||
596 | sg_ptr = tv_cmd->tvc_sgl; | ||
597 | /* | ||
598 | * For BIDI commands, pass in the extra READ buffer | ||
599 | * to transport_generic_map_mem_to_cmd() below.. | ||
600 | */ | ||
601 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ | ||
602 | #if 0 | ||
603 | if (se_cmd->se_cmd_flags & SCF_BIDI) { | ||
604 | sg_bidi_ptr = NULL; | ||
605 | sg_no_bidi = 0; | ||
606 | } | ||
607 | #endif | ||
608 | } else { | ||
609 | sg_ptr = NULL; | ||
610 | } | ||
611 | |||
612 | rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, | ||
613 | tv_cmd->tvc_sgl_count, sg_bidi_ptr, | ||
614 | sg_no_bidi); | ||
615 | if (rc < 0) { | ||
616 | transport_send_check_condition_and_sense(se_cmd, | ||
617 | se_cmd->scsi_sense_reason, 0); | ||
618 | transport_generic_free_cmd(se_cmd, 0); | ||
619 | return; | ||
620 | } | ||
621 | transport_handle_cdb_direct(se_cmd); | ||
622 | } | ||
623 | |||
624 | static void vhost_scsi_handle_vq(struct vhost_scsi *vs) | ||
625 | { | ||
626 | struct vhost_virtqueue *vq = &vs->vqs[2]; | ||
627 | struct virtio_scsi_cmd_req v_req; | ||
628 | struct tcm_vhost_tpg *tv_tpg; | ||
629 | struct tcm_vhost_cmd *tv_cmd; | ||
630 | u32 exp_data_len, data_first, data_num, data_direction; | ||
631 | unsigned out, in, i; | ||
632 | int head, ret; | ||
633 | |||
634 | /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ | ||
635 | tv_tpg = vs->vs_tpg; | ||
636 | if (unlikely(!tv_tpg)) { | ||
637 | pr_err("%s endpoint not set\n", __func__); | ||
638 | return; | ||
639 | } | ||
640 | |||
641 | mutex_lock(&vq->mutex); | ||
642 | vhost_disable_notify(&vs->dev, vq); | ||
643 | |||
644 | for (;;) { | ||
645 | head = vhost_get_vq_desc(&vs->dev, vq, vq->iov, | ||
646 | ARRAY_SIZE(vq->iov), &out, &in, | ||
647 | NULL, NULL); | ||
648 | pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n", | ||
649 | head, out, in); | ||
650 | /* On error, stop handling until the next kick. */ | ||
651 | if (unlikely(head < 0)) | ||
652 | break; | ||
653 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | ||
654 | if (head == vq->num) { | ||
655 | if (unlikely(vhost_enable_notify(&vs->dev, vq))) { | ||
656 | vhost_disable_notify(&vs->dev, vq); | ||
657 | continue; | ||
658 | } | ||
659 | break; | ||
660 | } | ||
661 | |||
662 | /* FIXME: BIDI operation */ | ||
663 | if (out == 1 && in == 1) { | ||
664 | data_direction = DMA_NONE; | ||
665 | data_first = 0; | ||
666 | data_num = 0; | ||
667 | } else if (out == 1 && in > 1) { | ||
668 | data_direction = DMA_FROM_DEVICE; | ||
669 | data_first = out + 1; | ||
670 | data_num = in - 1; | ||
671 | } else if (out > 1 && in == 1) { | ||
672 | data_direction = DMA_TO_DEVICE; | ||
673 | data_first = 1; | ||
674 | data_num = out - 1; | ||
675 | } else { | ||
676 | vq_err(vq, "Invalid buffer layout out: %u in: %u\n", | ||
677 | out, in); | ||
678 | break; | ||
679 | } | ||
680 | |||
681 | /* | ||
682 | * Check for a sane resp buffer so we can report errors to | ||
683 | * the guest. | ||
684 | */ | ||
685 | if (unlikely(vq->iov[out].iov_len != | ||
686 | sizeof(struct virtio_scsi_cmd_resp))) { | ||
687 | vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" | ||
688 | " bytes\n", vq->iov[out].iov_len); | ||
689 | break; | ||
690 | } | ||
691 | |||
692 | if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) { | ||
693 | vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu" | ||
694 | " bytes\n", vq->iov[0].iov_len); | ||
695 | break; | ||
696 | } | ||
697 | pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p," | ||
698 | " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req)); | ||
699 | ret = __copy_from_user(&v_req, vq->iov[0].iov_base, | ||
700 | sizeof(v_req)); | ||
701 | if (unlikely(ret)) { | ||
702 | vq_err(vq, "Faulted on virtio_scsi_cmd_req\n"); | ||
703 | break; | ||
704 | } | ||
705 | |||
706 | exp_data_len = 0; | ||
707 | for (i = 0; i < data_num; i++) | ||
708 | exp_data_len += vq->iov[data_first + i].iov_len; | ||
709 | |||
710 | tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req, | ||
711 | exp_data_len, data_direction); | ||
712 | if (IS_ERR(tv_cmd)) { | ||
713 | vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", | ||
714 | PTR_ERR(tv_cmd)); | ||
715 | break; | ||
716 | } | ||
717 | pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" | ||
718 | ": %d\n", tv_cmd, exp_data_len, data_direction); | ||
719 | |||
720 | tv_cmd->tvc_vhost = vs; | ||
721 | |||
722 | if (unlikely(vq->iov[out].iov_len != | ||
723 | sizeof(struct virtio_scsi_cmd_resp))) { | ||
724 | vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" | ||
725 | " bytes, out: %d, in: %d\n", | ||
726 | vq->iov[out].iov_len, out, in); | ||
727 | break; | ||
728 | } | ||
729 | |||
730 | tv_cmd->tvc_resp = vq->iov[out].iov_base; | ||
731 | |||
732 | /* | ||
733 | * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb | ||
734 | * that will be used by tcm_vhost_new_cmd_map() and down into | ||
735 | * target_setup_cmd_from_cdb() | ||
736 | */ | ||
737 | memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE); | ||
738 | /* | ||
739 | * Check that the recieved CDB size does not exceeded our | ||
740 | * hardcoded max for tcm_vhost | ||
741 | */ | ||
742 | /* TODO what if cdb was too small for varlen cdb header? */ | ||
743 | if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) > | ||
744 | TCM_VHOST_MAX_CDB_SIZE)) { | ||
745 | vq_err(vq, "Received SCSI CDB with command_size: %d that" | ||
746 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | ||
747 | scsi_command_size(tv_cmd->tvc_cdb), | ||
748 | TCM_VHOST_MAX_CDB_SIZE); | ||
749 | break; /* TODO */ | ||
750 | } | ||
751 | tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; | ||
752 | |||
753 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", | ||
754 | tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun); | ||
755 | |||
756 | if (data_direction != DMA_NONE) { | ||
757 | ret = vhost_scsi_map_iov_to_sgl(tv_cmd, | ||
758 | &vq->iov[data_first], data_num, | ||
759 | data_direction == DMA_TO_DEVICE); | ||
760 | if (unlikely(ret)) { | ||
761 | vq_err(vq, "Failed to map iov to sgl\n"); | ||
762 | break; /* TODO */ | ||
763 | } | ||
764 | } | ||
765 | |||
766 | /* | ||
767 | * Save the descriptor from vhost_get_vq_desc() to be used to | ||
768 | * complete the virtio-scsi request in TCM callback context via | ||
769 | * tcm_vhost_queue_data_in() and tcm_vhost_queue_status() | ||
770 | */ | ||
771 | tv_cmd->tvc_vq_desc = head; | ||
772 | /* | ||
773 | * Dispatch tv_cmd descriptor for cmwq execution in process | ||
774 | * context provided by tcm_vhost_workqueue. This also ensures | ||
775 | * tv_cmd is executed on the same kworker CPU as this vhost | ||
776 | * thread to gain positive L2 cache locality effects.. | ||
777 | */ | ||
778 | INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work); | ||
779 | queue_work(tcm_vhost_workqueue, &tv_cmd->work); | ||
780 | } | ||
781 | |||
782 | mutex_unlock(&vq->mutex); | ||
783 | } | ||
784 | |||
785 | static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) | ||
786 | { | ||
787 | pr_debug("%s: The handling func for control queue.\n", __func__); | ||
788 | } | ||
789 | |||
790 | static void vhost_scsi_evt_handle_kick(struct vhost_work *work) | ||
791 | { | ||
792 | pr_debug("%s: The handling func for event queue.\n", __func__); | ||
793 | } | ||
794 | |||
795 | static void vhost_scsi_handle_kick(struct vhost_work *work) | ||
796 | { | ||
797 | struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, | ||
798 | poll.work); | ||
799 | struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev); | ||
800 | |||
801 | vhost_scsi_handle_vq(vs); | ||
802 | } | ||
803 | |||
804 | /* | ||
805 | * Called from vhost_scsi_ioctl() context to walk the list of available | ||
806 | * tcm_vhost_tpg with an active struct tcm_vhost_nexus | ||
807 | */ | ||
808 | static int vhost_scsi_set_endpoint( | ||
809 | struct vhost_scsi *vs, | ||
810 | struct vhost_scsi_target *t) | ||
811 | { | ||
812 | struct tcm_vhost_tport *tv_tport; | ||
813 | struct tcm_vhost_tpg *tv_tpg; | ||
814 | int index; | ||
815 | |||
816 | mutex_lock(&vs->dev.mutex); | ||
817 | /* Verify that ring has been setup correctly. */ | ||
818 | for (index = 0; index < vs->dev.nvqs; ++index) { | ||
819 | /* Verify that ring has been setup correctly. */ | ||
820 | if (!vhost_vq_access_ok(&vs->vqs[index])) { | ||
821 | mutex_unlock(&vs->dev.mutex); | ||
822 | return -EFAULT; | ||
823 | } | ||
824 | } | ||
825 | mutex_unlock(&vs->dev.mutex); | ||
826 | |||
827 | mutex_lock(&tcm_vhost_mutex); | ||
828 | list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { | ||
829 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
830 | if (!tv_tpg->tpg_nexus) { | ||
831 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
832 | continue; | ||
833 | } | ||
834 | if (tv_tpg->tv_tpg_vhost_count != 0) { | ||
835 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
836 | continue; | ||
837 | } | ||
838 | tv_tport = tv_tpg->tport; | ||
839 | |||
840 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) && | ||
841 | (tv_tpg->tport_tpgt == t->vhost_tpgt)) { | ||
842 | tv_tpg->tv_tpg_vhost_count++; | ||
843 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
844 | mutex_unlock(&tcm_vhost_mutex); | ||
845 | |||
846 | mutex_lock(&vs->dev.mutex); | ||
847 | if (vs->vs_tpg) { | ||
848 | mutex_unlock(&vs->dev.mutex); | ||
849 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
850 | tv_tpg->tv_tpg_vhost_count--; | ||
851 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
852 | return -EEXIST; | ||
853 | } | ||
854 | |||
855 | vs->vs_tpg = tv_tpg; | ||
856 | smp_mb__after_atomic_inc(); | ||
857 | mutex_unlock(&vs->dev.mutex); | ||
858 | return 0; | ||
859 | } | ||
860 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
861 | } | ||
862 | mutex_unlock(&tcm_vhost_mutex); | ||
863 | return -EINVAL; | ||
864 | } | ||
865 | |||
866 | static int vhost_scsi_clear_endpoint( | ||
867 | struct vhost_scsi *vs, | ||
868 | struct vhost_scsi_target *t) | ||
869 | { | ||
870 | struct tcm_vhost_tport *tv_tport; | ||
871 | struct tcm_vhost_tpg *tv_tpg; | ||
872 | int index, ret; | ||
873 | |||
874 | mutex_lock(&vs->dev.mutex); | ||
875 | /* Verify that ring has been setup correctly. */ | ||
876 | for (index = 0; index < vs->dev.nvqs; ++index) { | ||
877 | if (!vhost_vq_access_ok(&vs->vqs[index])) { | ||
878 | ret = -EFAULT; | ||
879 | goto err; | ||
880 | } | ||
881 | } | ||
882 | |||
883 | if (!vs->vs_tpg) { | ||
884 | ret = -ENODEV; | ||
885 | goto err; | ||
886 | } | ||
887 | tv_tpg = vs->vs_tpg; | ||
888 | tv_tport = tv_tpg->tport; | ||
889 | |||
890 | if (strcmp(tv_tport->tport_name, t->vhost_wwpn) || | ||
891 | (tv_tpg->tport_tpgt != t->vhost_tpgt)) { | ||
892 | pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" | ||
893 | " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", | ||
894 | tv_tport->tport_name, tv_tpg->tport_tpgt, | ||
895 | t->vhost_wwpn, t->vhost_tpgt); | ||
896 | ret = -EINVAL; | ||
897 | goto err; | ||
898 | } | ||
899 | tv_tpg->tv_tpg_vhost_count--; | ||
900 | vs->vs_tpg = NULL; | ||
901 | mutex_unlock(&vs->dev.mutex); | ||
902 | |||
903 | return 0; | ||
904 | |||
905 | err: | ||
906 | mutex_unlock(&vs->dev.mutex); | ||
907 | return ret; | ||
908 | } | ||
909 | |||
910 | static int vhost_scsi_open(struct inode *inode, struct file *f) | ||
911 | { | ||
912 | struct vhost_scsi *s; | ||
913 | int r; | ||
914 | |||
915 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
916 | if (!s) | ||
917 | return -ENOMEM; | ||
918 | |||
919 | vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work); | ||
920 | INIT_LIST_HEAD(&s->vs_completion_list); | ||
921 | spin_lock_init(&s->vs_completion_lock); | ||
922 | |||
923 | s->vqs[VHOST_SCSI_VQ_CTL].handle_kick = vhost_scsi_ctl_handle_kick; | ||
924 | s->vqs[VHOST_SCSI_VQ_EVT].handle_kick = vhost_scsi_evt_handle_kick; | ||
925 | s->vqs[VHOST_SCSI_VQ_IO].handle_kick = vhost_scsi_handle_kick; | ||
926 | r = vhost_dev_init(&s->dev, s->vqs, 3); | ||
927 | if (r < 0) { | ||
928 | kfree(s); | ||
929 | return r; | ||
930 | } | ||
931 | |||
932 | f->private_data = s; | ||
933 | return 0; | ||
934 | } | ||
935 | |||
936 | static int vhost_scsi_release(struct inode *inode, struct file *f) | ||
937 | { | ||
938 | struct vhost_scsi *s = f->private_data; | ||
939 | |||
940 | if (s->vs_tpg && s->vs_tpg->tport) { | ||
941 | struct vhost_scsi_target backend; | ||
942 | |||
943 | memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name, | ||
944 | sizeof(backend.vhost_wwpn)); | ||
945 | backend.vhost_tpgt = s->vs_tpg->tport_tpgt; | ||
946 | vhost_scsi_clear_endpoint(s, &backend); | ||
947 | } | ||
948 | |||
949 | vhost_dev_cleanup(&s->dev, false); | ||
950 | kfree(s); | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | static void vhost_scsi_flush_vq(struct vhost_scsi *vs, int index) | ||
955 | { | ||
956 | vhost_poll_flush(&vs->dev.vqs[index].poll); | ||
957 | } | ||
958 | |||
959 | static void vhost_scsi_flush(struct vhost_scsi *vs) | ||
960 | { | ||
961 | vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_CTL); | ||
962 | vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_EVT); | ||
963 | vhost_scsi_flush_vq(vs, VHOST_SCSI_VQ_IO); | ||
964 | } | ||
965 | |||
966 | static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) | ||
967 | { | ||
968 | if (features & ~VHOST_FEATURES) | ||
969 | return -EOPNOTSUPP; | ||
970 | |||
971 | mutex_lock(&vs->dev.mutex); | ||
972 | if ((features & (1 << VHOST_F_LOG_ALL)) && | ||
973 | !vhost_log_access_ok(&vs->dev)) { | ||
974 | mutex_unlock(&vs->dev.mutex); | ||
975 | return -EFAULT; | ||
976 | } | ||
977 | vs->dev.acked_features = features; | ||
978 | smp_wmb(); | ||
979 | vhost_scsi_flush(vs); | ||
980 | mutex_unlock(&vs->dev.mutex); | ||
981 | return 0; | ||
982 | } | ||
983 | |||
984 | static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, | ||
985 | unsigned long arg) | ||
986 | { | ||
987 | struct vhost_scsi *vs = f->private_data; | ||
988 | struct vhost_scsi_target backend; | ||
989 | void __user *argp = (void __user *)arg; | ||
990 | u64 __user *featurep = argp; | ||
991 | u64 features; | ||
992 | int r, abi_version = VHOST_SCSI_ABI_VERSION; | ||
993 | |||
994 | switch (ioctl) { | ||
995 | case VHOST_SCSI_SET_ENDPOINT: | ||
996 | if (copy_from_user(&backend, argp, sizeof backend)) | ||
997 | return -EFAULT; | ||
998 | if (backend.reserved != 0) | ||
999 | return -EOPNOTSUPP; | ||
1000 | |||
1001 | return vhost_scsi_set_endpoint(vs, &backend); | ||
1002 | case VHOST_SCSI_CLEAR_ENDPOINT: | ||
1003 | if (copy_from_user(&backend, argp, sizeof backend)) | ||
1004 | return -EFAULT; | ||
1005 | if (backend.reserved != 0) | ||
1006 | return -EOPNOTSUPP; | ||
1007 | |||
1008 | return vhost_scsi_clear_endpoint(vs, &backend); | ||
1009 | case VHOST_SCSI_GET_ABI_VERSION: | ||
1010 | if (copy_to_user(argp, &abi_version, sizeof abi_version)) | ||
1011 | return -EFAULT; | ||
1012 | return 0; | ||
1013 | case VHOST_GET_FEATURES: | ||
1014 | features = VHOST_FEATURES; | ||
1015 | if (copy_to_user(featurep, &features, sizeof features)) | ||
1016 | return -EFAULT; | ||
1017 | return 0; | ||
1018 | case VHOST_SET_FEATURES: | ||
1019 | if (copy_from_user(&features, featurep, sizeof features)) | ||
1020 | return -EFAULT; | ||
1021 | return vhost_scsi_set_features(vs, features); | ||
1022 | default: | ||
1023 | mutex_lock(&vs->dev.mutex); | ||
1024 | r = vhost_dev_ioctl(&vs->dev, ioctl, arg); | ||
1025 | mutex_unlock(&vs->dev.mutex); | ||
1026 | return r; | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1030 | #ifdef CONFIG_COMPAT | ||
1031 | static long vhost_scsi_compat_ioctl(struct file *f, unsigned int ioctl, | ||
1032 | unsigned long arg) | ||
1033 | { | ||
1034 | return vhost_scsi_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); | ||
1035 | } | ||
1036 | #endif | ||
1037 | |||
1038 | static const struct file_operations vhost_scsi_fops = { | ||
1039 | .owner = THIS_MODULE, | ||
1040 | .release = vhost_scsi_release, | ||
1041 | .unlocked_ioctl = vhost_scsi_ioctl, | ||
1042 | #ifdef CONFIG_COMPAT | ||
1043 | .compat_ioctl = vhost_scsi_compat_ioctl, | ||
1044 | #endif | ||
1045 | .open = vhost_scsi_open, | ||
1046 | .llseek = noop_llseek, | ||
1047 | }; | ||
1048 | |||
1049 | static struct miscdevice vhost_scsi_misc = { | ||
1050 | MISC_DYNAMIC_MINOR, | ||
1051 | "vhost-scsi", | ||
1052 | &vhost_scsi_fops, | ||
1053 | }; | ||
1054 | |||
1055 | static int __init vhost_scsi_register(void) | ||
1056 | { | ||
1057 | return misc_register(&vhost_scsi_misc); | ||
1058 | } | ||
1059 | |||
1060 | static int vhost_scsi_deregister(void) | ||
1061 | { | ||
1062 | return misc_deregister(&vhost_scsi_misc); | ||
1063 | } | ||
1064 | |||
1065 | static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport) | ||
1066 | { | ||
1067 | switch (tport->tport_proto_id) { | ||
1068 | case SCSI_PROTOCOL_SAS: | ||
1069 | return "SAS"; | ||
1070 | case SCSI_PROTOCOL_FCP: | ||
1071 | return "FCP"; | ||
1072 | case SCSI_PROTOCOL_ISCSI: | ||
1073 | return "iSCSI"; | ||
1074 | default: | ||
1075 | break; | ||
1076 | } | ||
1077 | |||
1078 | return "Unknown"; | ||
1079 | } | ||
1080 | |||
1081 | static int tcm_vhost_port_link(struct se_portal_group *se_tpg, | ||
1082 | struct se_lun *lun) | ||
1083 | { | ||
1084 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1085 | struct tcm_vhost_tpg, se_tpg); | ||
1086 | |||
1087 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1088 | tv_tpg->tv_tpg_port_count++; | ||
1089 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1090 | |||
1091 | return 0; | ||
1092 | } | ||
1093 | |||
1094 | static void tcm_vhost_port_unlink(struct se_portal_group *se_tpg, | ||
1095 | struct se_lun *se_lun) | ||
1096 | { | ||
1097 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1098 | struct tcm_vhost_tpg, se_tpg); | ||
1099 | |||
1100 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1101 | tv_tpg->tv_tpg_port_count--; | ||
1102 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1103 | } | ||
1104 | |||
1105 | static struct se_node_acl *tcm_vhost_make_nodeacl( | ||
1106 | struct se_portal_group *se_tpg, | ||
1107 | struct config_group *group, | ||
1108 | const char *name) | ||
1109 | { | ||
1110 | struct se_node_acl *se_nacl, *se_nacl_new; | ||
1111 | struct tcm_vhost_nacl *nacl; | ||
1112 | u64 wwpn = 0; | ||
1113 | u32 nexus_depth; | ||
1114 | |||
1115 | /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) | ||
1116 | return ERR_PTR(-EINVAL); */ | ||
1117 | se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg); | ||
1118 | if (!se_nacl_new) | ||
1119 | return ERR_PTR(-ENOMEM); | ||
1120 | |||
1121 | nexus_depth = 1; | ||
1122 | /* | ||
1123 | * se_nacl_new may be released by core_tpg_add_initiator_node_acl() | ||
1124 | * when converting a NodeACL from demo mode -> explict | ||
1125 | */ | ||
1126 | se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, | ||
1127 | name, nexus_depth); | ||
1128 | if (IS_ERR(se_nacl)) { | ||
1129 | tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new); | ||
1130 | return se_nacl; | ||
1131 | } | ||
1132 | /* | ||
1133 | * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN | ||
1134 | */ | ||
1135 | nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl); | ||
1136 | nacl->iport_wwpn = wwpn; | ||
1137 | |||
1138 | return se_nacl; | ||
1139 | } | ||
1140 | |||
1141 | static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl) | ||
1142 | { | ||
1143 | struct tcm_vhost_nacl *nacl = container_of(se_acl, | ||
1144 | struct tcm_vhost_nacl, se_node_acl); | ||
1145 | core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); | ||
1146 | kfree(nacl); | ||
1147 | } | ||
1148 | |||
1149 | static int tcm_vhost_make_nexus(struct tcm_vhost_tpg *tv_tpg, | ||
1150 | const char *name) | ||
1151 | { | ||
1152 | struct se_portal_group *se_tpg; | ||
1153 | struct tcm_vhost_nexus *tv_nexus; | ||
1154 | |||
1155 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1156 | if (tv_tpg->tpg_nexus) { | ||
1157 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1158 | pr_debug("tv_tpg->tpg_nexus already exists\n"); | ||
1159 | return -EEXIST; | ||
1160 | } | ||
1161 | se_tpg = &tv_tpg->se_tpg; | ||
1162 | |||
1163 | tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL); | ||
1164 | if (!tv_nexus) { | ||
1165 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1166 | pr_err("Unable to allocate struct tcm_vhost_nexus\n"); | ||
1167 | return -ENOMEM; | ||
1168 | } | ||
1169 | /* | ||
1170 | * Initialize the struct se_session pointer | ||
1171 | */ | ||
1172 | tv_nexus->tvn_se_sess = transport_init_session(); | ||
1173 | if (IS_ERR(tv_nexus->tvn_se_sess)) { | ||
1174 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1175 | kfree(tv_nexus); | ||
1176 | return -ENOMEM; | ||
1177 | } | ||
1178 | /* | ||
1179 | * Since we are running in 'demo mode' this call with generate a | ||
1180 | * struct se_node_acl for the tcm_vhost struct se_portal_group with | ||
1181 | * the SCSI Initiator port name of the passed configfs group 'name'. | ||
1182 | */ | ||
1183 | tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( | ||
1184 | se_tpg, (unsigned char *)name); | ||
1185 | if (!tv_nexus->tvn_se_sess->se_node_acl) { | ||
1186 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1187 | pr_debug("core_tpg_check_initiator_node_acl() failed" | ||
1188 | " for %s\n", name); | ||
1189 | transport_free_session(tv_nexus->tvn_se_sess); | ||
1190 | kfree(tv_nexus); | ||
1191 | return -ENOMEM; | ||
1192 | } | ||
1193 | /* | ||
1194 | * Now register the TCM vhost virtual I_T Nexus as active with the | ||
1195 | * call to __transport_register_session() | ||
1196 | */ | ||
1197 | __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | ||
1198 | tv_nexus->tvn_se_sess, tv_nexus); | ||
1199 | tv_tpg->tpg_nexus = tv_nexus; | ||
1200 | |||
1201 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | static int tcm_vhost_drop_nexus(struct tcm_vhost_tpg *tpg) | ||
1206 | { | ||
1207 | struct se_session *se_sess; | ||
1208 | struct tcm_vhost_nexus *tv_nexus; | ||
1209 | |||
1210 | mutex_lock(&tpg->tv_tpg_mutex); | ||
1211 | tv_nexus = tpg->tpg_nexus; | ||
1212 | if (!tv_nexus) { | ||
1213 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1214 | return -ENODEV; | ||
1215 | } | ||
1216 | |||
1217 | se_sess = tv_nexus->tvn_se_sess; | ||
1218 | if (!se_sess) { | ||
1219 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1220 | return -ENODEV; | ||
1221 | } | ||
1222 | |||
1223 | if (tpg->tv_tpg_port_count != 0) { | ||
1224 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1225 | pr_err("Unable to remove TCM_vhost I_T Nexus with" | ||
1226 | " active TPG port count: %d\n", | ||
1227 | tpg->tv_tpg_port_count); | ||
1228 | return -EBUSY; | ||
1229 | } | ||
1230 | |||
1231 | if (tpg->tv_tpg_vhost_count != 0) { | ||
1232 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1233 | pr_err("Unable to remove TCM_vhost I_T Nexus with" | ||
1234 | " active TPG vhost count: %d\n", | ||
1235 | tpg->tv_tpg_vhost_count); | ||
1236 | return -EBUSY; | ||
1237 | } | ||
1238 | |||
1239 | pr_debug("TCM_vhost_ConfigFS: Removing I_T Nexus to emulated" | ||
1240 | " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport), | ||
1241 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); | ||
1242 | /* | ||
1243 | * Release the SCSI I_T Nexus to the emulated vhost Target Port | ||
1244 | */ | ||
1245 | transport_deregister_session(tv_nexus->tvn_se_sess); | ||
1246 | tpg->tpg_nexus = NULL; | ||
1247 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1248 | |||
1249 | kfree(tv_nexus); | ||
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | static ssize_t tcm_vhost_tpg_show_nexus(struct se_portal_group *se_tpg, | ||
1254 | char *page) | ||
1255 | { | ||
1256 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1257 | struct tcm_vhost_tpg, se_tpg); | ||
1258 | struct tcm_vhost_nexus *tv_nexus; | ||
1259 | ssize_t ret; | ||
1260 | |||
1261 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1262 | tv_nexus = tv_tpg->tpg_nexus; | ||
1263 | if (!tv_nexus) { | ||
1264 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1265 | return -ENODEV; | ||
1266 | } | ||
1267 | ret = snprintf(page, PAGE_SIZE, "%s\n", | ||
1268 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); | ||
1269 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1270 | |||
1271 | return ret; | ||
1272 | } | ||
1273 | |||
1274 | static ssize_t tcm_vhost_tpg_store_nexus(struct se_portal_group *se_tpg, | ||
1275 | const char *page, | ||
1276 | size_t count) | ||
1277 | { | ||
1278 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1279 | struct tcm_vhost_tpg, se_tpg); | ||
1280 | struct tcm_vhost_tport *tport_wwn = tv_tpg->tport; | ||
1281 | unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr; | ||
1282 | int ret; | ||
1283 | /* | ||
1284 | * Shutdown the active I_T nexus if 'NULL' is passed.. | ||
1285 | */ | ||
1286 | if (!strncmp(page, "NULL", 4)) { | ||
1287 | ret = tcm_vhost_drop_nexus(tv_tpg); | ||
1288 | return (!ret) ? count : ret; | ||
1289 | } | ||
1290 | /* | ||
1291 | * Otherwise make sure the passed virtual Initiator port WWN matches | ||
1292 | * the fabric protocol_id set in tcm_vhost_make_tport(), and call | ||
1293 | * tcm_vhost_make_nexus(). | ||
1294 | */ | ||
1295 | if (strlen(page) >= TCM_VHOST_NAMELEN) { | ||
1296 | pr_err("Emulated NAA Sas Address: %s, exceeds" | ||
1297 | " max: %d\n", page, TCM_VHOST_NAMELEN); | ||
1298 | return -EINVAL; | ||
1299 | } | ||
1300 | snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page); | ||
1301 | |||
1302 | ptr = strstr(i_port, "naa."); | ||
1303 | if (ptr) { | ||
1304 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) { | ||
1305 | pr_err("Passed SAS Initiator Port %s does not" | ||
1306 | " match target port protoid: %s\n", i_port, | ||
1307 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1308 | return -EINVAL; | ||
1309 | } | ||
1310 | port_ptr = &i_port[0]; | ||
1311 | goto check_newline; | ||
1312 | } | ||
1313 | ptr = strstr(i_port, "fc."); | ||
1314 | if (ptr) { | ||
1315 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) { | ||
1316 | pr_err("Passed FCP Initiator Port %s does not" | ||
1317 | " match target port protoid: %s\n", i_port, | ||
1318 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1319 | return -EINVAL; | ||
1320 | } | ||
1321 | port_ptr = &i_port[3]; /* Skip over "fc." */ | ||
1322 | goto check_newline; | ||
1323 | } | ||
1324 | ptr = strstr(i_port, "iqn."); | ||
1325 | if (ptr) { | ||
1326 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) { | ||
1327 | pr_err("Passed iSCSI Initiator Port %s does not" | ||
1328 | " match target port protoid: %s\n", i_port, | ||
1329 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1330 | return -EINVAL; | ||
1331 | } | ||
1332 | port_ptr = &i_port[0]; | ||
1333 | goto check_newline; | ||
1334 | } | ||
1335 | pr_err("Unable to locate prefix for emulated Initiator Port:" | ||
1336 | " %s\n", i_port); | ||
1337 | return -EINVAL; | ||
1338 | /* | ||
1339 | * Clear any trailing newline for the NAA WWN | ||
1340 | */ | ||
1341 | check_newline: | ||
1342 | if (i_port[strlen(i_port)-1] == '\n') | ||
1343 | i_port[strlen(i_port)-1] = '\0'; | ||
1344 | |||
1345 | ret = tcm_vhost_make_nexus(tv_tpg, port_ptr); | ||
1346 | if (ret < 0) | ||
1347 | return ret; | ||
1348 | |||
1349 | return count; | ||
1350 | } | ||
1351 | |||
1352 | TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR); | ||
1353 | |||
1354 | static struct configfs_attribute *tcm_vhost_tpg_attrs[] = { | ||
1355 | &tcm_vhost_tpg_nexus.attr, | ||
1356 | NULL, | ||
1357 | }; | ||
1358 | |||
1359 | static struct se_portal_group *tcm_vhost_make_tpg(struct se_wwn *wwn, | ||
1360 | struct config_group *group, | ||
1361 | const char *name) | ||
1362 | { | ||
1363 | struct tcm_vhost_tport *tport = container_of(wwn, | ||
1364 | struct tcm_vhost_tport, tport_wwn); | ||
1365 | |||
1366 | struct tcm_vhost_tpg *tpg; | ||
1367 | unsigned long tpgt; | ||
1368 | int ret; | ||
1369 | |||
1370 | if (strstr(name, "tpgt_") != name) | ||
1371 | return ERR_PTR(-EINVAL); | ||
1372 | if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX) | ||
1373 | return ERR_PTR(-EINVAL); | ||
1374 | |||
1375 | tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL); | ||
1376 | if (!tpg) { | ||
1377 | pr_err("Unable to allocate struct tcm_vhost_tpg"); | ||
1378 | return ERR_PTR(-ENOMEM); | ||
1379 | } | ||
1380 | mutex_init(&tpg->tv_tpg_mutex); | ||
1381 | INIT_LIST_HEAD(&tpg->tv_tpg_list); | ||
1382 | tpg->tport = tport; | ||
1383 | tpg->tport_tpgt = tpgt; | ||
1384 | |||
1385 | ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn, | ||
1386 | &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||
1387 | if (ret < 0) { | ||
1388 | kfree(tpg); | ||
1389 | return NULL; | ||
1390 | } | ||
1391 | mutex_lock(&tcm_vhost_mutex); | ||
1392 | list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list); | ||
1393 | mutex_unlock(&tcm_vhost_mutex); | ||
1394 | |||
1395 | return &tpg->se_tpg; | ||
1396 | } | ||
1397 | |||
1398 | static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) | ||
1399 | { | ||
1400 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
1401 | struct tcm_vhost_tpg, se_tpg); | ||
1402 | |||
1403 | mutex_lock(&tcm_vhost_mutex); | ||
1404 | list_del(&tpg->tv_tpg_list); | ||
1405 | mutex_unlock(&tcm_vhost_mutex); | ||
1406 | /* | ||
1407 | * Release the virtual I_T Nexus for this vhost TPG | ||
1408 | */ | ||
1409 | tcm_vhost_drop_nexus(tpg); | ||
1410 | /* | ||
1411 | * Deregister the se_tpg from TCM.. | ||
1412 | */ | ||
1413 | core_tpg_deregister(se_tpg); | ||
1414 | kfree(tpg); | ||
1415 | } | ||
1416 | |||
1417 | static struct se_wwn *tcm_vhost_make_tport(struct target_fabric_configfs *tf, | ||
1418 | struct config_group *group, | ||
1419 | const char *name) | ||
1420 | { | ||
1421 | struct tcm_vhost_tport *tport; | ||
1422 | char *ptr; | ||
1423 | u64 wwpn = 0; | ||
1424 | int off = 0; | ||
1425 | |||
1426 | /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) | ||
1427 | return ERR_PTR(-EINVAL); */ | ||
1428 | |||
1429 | tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL); | ||
1430 | if (!tport) { | ||
1431 | pr_err("Unable to allocate struct tcm_vhost_tport"); | ||
1432 | return ERR_PTR(-ENOMEM); | ||
1433 | } | ||
1434 | tport->tport_wwpn = wwpn; | ||
1435 | /* | ||
1436 | * Determine the emulated Protocol Identifier and Target Port Name | ||
1437 | * based on the incoming configfs directory name. | ||
1438 | */ | ||
1439 | ptr = strstr(name, "naa."); | ||
1440 | if (ptr) { | ||
1441 | tport->tport_proto_id = SCSI_PROTOCOL_SAS; | ||
1442 | goto check_len; | ||
1443 | } | ||
1444 | ptr = strstr(name, "fc."); | ||
1445 | if (ptr) { | ||
1446 | tport->tport_proto_id = SCSI_PROTOCOL_FCP; | ||
1447 | off = 3; /* Skip over "fc." */ | ||
1448 | goto check_len; | ||
1449 | } | ||
1450 | ptr = strstr(name, "iqn."); | ||
1451 | if (ptr) { | ||
1452 | tport->tport_proto_id = SCSI_PROTOCOL_ISCSI; | ||
1453 | goto check_len; | ||
1454 | } | ||
1455 | |||
1456 | pr_err("Unable to locate prefix for emulated Target Port:" | ||
1457 | " %s\n", name); | ||
1458 | kfree(tport); | ||
1459 | return ERR_PTR(-EINVAL); | ||
1460 | |||
1461 | check_len: | ||
1462 | if (strlen(name) >= TCM_VHOST_NAMELEN) { | ||
1463 | pr_err("Emulated %s Address: %s, exceeds" | ||
1464 | " max: %d\n", name, tcm_vhost_dump_proto_id(tport), | ||
1465 | TCM_VHOST_NAMELEN); | ||
1466 | kfree(tport); | ||
1467 | return ERR_PTR(-EINVAL); | ||
1468 | } | ||
1469 | snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]); | ||
1470 | |||
1471 | pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target" | ||
1472 | " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name); | ||
1473 | |||
1474 | return &tport->tport_wwn; | ||
1475 | } | ||
1476 | |||
1477 | static void tcm_vhost_drop_tport(struct se_wwn *wwn) | ||
1478 | { | ||
1479 | struct tcm_vhost_tport *tport = container_of(wwn, | ||
1480 | struct tcm_vhost_tport, tport_wwn); | ||
1481 | |||
1482 | pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target" | ||
1483 | " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), | ||
1484 | tport->tport_name); | ||
1485 | |||
1486 | kfree(tport); | ||
1487 | } | ||
1488 | |||
1489 | static ssize_t tcm_vhost_wwn_show_attr_version( | ||
1490 | struct target_fabric_configfs *tf, | ||
1491 | char *page) | ||
1492 | { | ||
1493 | return sprintf(page, "TCM_VHOST fabric module %s on %s/%s" | ||
1494 | "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, | ||
1495 | utsname()->machine); | ||
1496 | } | ||
1497 | |||
1498 | TF_WWN_ATTR_RO(tcm_vhost, version); | ||
1499 | |||
1500 | static struct configfs_attribute *tcm_vhost_wwn_attrs[] = { | ||
1501 | &tcm_vhost_wwn_version.attr, | ||
1502 | NULL, | ||
1503 | }; | ||
1504 | |||
1505 | static struct target_core_fabric_ops tcm_vhost_ops = { | ||
1506 | .get_fabric_name = tcm_vhost_get_fabric_name, | ||
1507 | .get_fabric_proto_ident = tcm_vhost_get_fabric_proto_ident, | ||
1508 | .tpg_get_wwn = tcm_vhost_get_fabric_wwn, | ||
1509 | .tpg_get_tag = tcm_vhost_get_tag, | ||
1510 | .tpg_get_default_depth = tcm_vhost_get_default_depth, | ||
1511 | .tpg_get_pr_transport_id = tcm_vhost_get_pr_transport_id, | ||
1512 | .tpg_get_pr_transport_id_len = tcm_vhost_get_pr_transport_id_len, | ||
1513 | .tpg_parse_pr_out_transport_id = tcm_vhost_parse_pr_out_transport_id, | ||
1514 | .tpg_check_demo_mode = tcm_vhost_check_true, | ||
1515 | .tpg_check_demo_mode_cache = tcm_vhost_check_true, | ||
1516 | .tpg_check_demo_mode_write_protect = tcm_vhost_check_false, | ||
1517 | .tpg_check_prod_mode_write_protect = tcm_vhost_check_false, | ||
1518 | .tpg_alloc_fabric_acl = tcm_vhost_alloc_fabric_acl, | ||
1519 | .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, | ||
1520 | .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, | ||
1521 | .release_cmd = tcm_vhost_release_cmd, | ||
1522 | .shutdown_session = tcm_vhost_shutdown_session, | ||
1523 | .close_session = tcm_vhost_close_session, | ||
1524 | .sess_get_index = tcm_vhost_sess_get_index, | ||
1525 | .sess_get_initiator_sid = NULL, | ||
1526 | .write_pending = tcm_vhost_write_pending, | ||
1527 | .write_pending_status = tcm_vhost_write_pending_status, | ||
1528 | .set_default_node_attributes = tcm_vhost_set_default_node_attrs, | ||
1529 | .get_task_tag = tcm_vhost_get_task_tag, | ||
1530 | .get_cmd_state = tcm_vhost_get_cmd_state, | ||
1531 | .queue_data_in = tcm_vhost_queue_data_in, | ||
1532 | .queue_status = tcm_vhost_queue_status, | ||
1533 | .queue_tm_rsp = tcm_vhost_queue_tm_rsp, | ||
1534 | .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len, | ||
1535 | .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, | ||
1536 | /* | ||
1537 | * Setup callers for generic logic in target_core_fabric_configfs.c | ||
1538 | */ | ||
1539 | .fabric_make_wwn = tcm_vhost_make_tport, | ||
1540 | .fabric_drop_wwn = tcm_vhost_drop_tport, | ||
1541 | .fabric_make_tpg = tcm_vhost_make_tpg, | ||
1542 | .fabric_drop_tpg = tcm_vhost_drop_tpg, | ||
1543 | .fabric_post_link = tcm_vhost_port_link, | ||
1544 | .fabric_pre_unlink = tcm_vhost_port_unlink, | ||
1545 | .fabric_make_np = NULL, | ||
1546 | .fabric_drop_np = NULL, | ||
1547 | .fabric_make_nodeacl = tcm_vhost_make_nodeacl, | ||
1548 | .fabric_drop_nodeacl = tcm_vhost_drop_nodeacl, | ||
1549 | }; | ||
1550 | |||
1551 | static int tcm_vhost_register_configfs(void) | ||
1552 | { | ||
1553 | struct target_fabric_configfs *fabric; | ||
1554 | int ret; | ||
1555 | |||
1556 | pr_debug("TCM_VHOST fabric module %s on %s/%s" | ||
1557 | " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, | ||
1558 | utsname()->machine); | ||
1559 | /* | ||
1560 | * Register the top level struct config_item_type with TCM core | ||
1561 | */ | ||
1562 | fabric = target_fabric_configfs_init(THIS_MODULE, "vhost"); | ||
1563 | if (IS_ERR(fabric)) { | ||
1564 | pr_err("target_fabric_configfs_init() failed\n"); | ||
1565 | return PTR_ERR(fabric); | ||
1566 | } | ||
1567 | /* | ||
1568 | * Setup fabric->tf_ops from our local tcm_vhost_ops | ||
1569 | */ | ||
1570 | fabric->tf_ops = tcm_vhost_ops; | ||
1571 | /* | ||
1572 | * Setup default attribute lists for various fabric->tf_cit_tmpl | ||
1573 | */ | ||
1574 | TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs; | ||
1575 | TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs; | ||
1576 | TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; | ||
1577 | TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; | ||
1578 | TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; | ||
1579 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||
1580 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||
1581 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||
1582 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||
1583 | /* | ||
1584 | * Register the fabric for use within TCM | ||
1585 | */ | ||
1586 | ret = target_fabric_configfs_register(fabric); | ||
1587 | if (ret < 0) { | ||
1588 | pr_err("target_fabric_configfs_register() failed" | ||
1589 | " for TCM_VHOST\n"); | ||
1590 | return ret; | ||
1591 | } | ||
1592 | /* | ||
1593 | * Setup our local pointer to *fabric | ||
1594 | */ | ||
1595 | tcm_vhost_fabric_configfs = fabric; | ||
1596 | pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n"); | ||
1597 | return 0; | ||
1598 | }; | ||
1599 | |||
1600 | static void tcm_vhost_deregister_configfs(void) | ||
1601 | { | ||
1602 | if (!tcm_vhost_fabric_configfs) | ||
1603 | return; | ||
1604 | |||
1605 | target_fabric_configfs_deregister(tcm_vhost_fabric_configfs); | ||
1606 | tcm_vhost_fabric_configfs = NULL; | ||
1607 | pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n"); | ||
1608 | }; | ||
1609 | |||
1610 | static int __init tcm_vhost_init(void) | ||
1611 | { | ||
1612 | int ret = -ENOMEM; | ||
1613 | /* | ||
1614 | * Use our own dedicated workqueue for submitting I/O into | ||
1615 | * target core to avoid contention within system_wq. | ||
1616 | */ | ||
1617 | tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0); | ||
1618 | if (!tcm_vhost_workqueue) | ||
1619 | goto out; | ||
1620 | |||
1621 | ret = vhost_scsi_register(); | ||
1622 | if (ret < 0) | ||
1623 | goto out_destroy_workqueue; | ||
1624 | |||
1625 | ret = tcm_vhost_register_configfs(); | ||
1626 | if (ret < 0) | ||
1627 | goto out_vhost_scsi_deregister; | ||
1628 | |||
1629 | return 0; | ||
1630 | |||
1631 | out_vhost_scsi_deregister: | ||
1632 | vhost_scsi_deregister(); | ||
1633 | out_destroy_workqueue: | ||
1634 | destroy_workqueue(tcm_vhost_workqueue); | ||
1635 | out: | ||
1636 | return ret; | ||
1637 | }; | ||
1638 | |||
1639 | static void tcm_vhost_exit(void) | ||
1640 | { | ||
1641 | tcm_vhost_deregister_configfs(); | ||
1642 | vhost_scsi_deregister(); | ||
1643 | destroy_workqueue(tcm_vhost_workqueue); | ||
1644 | }; | ||
1645 | |||
1646 | MODULE_DESCRIPTION("TCM_VHOST series fabric driver"); | ||
1647 | MODULE_LICENSE("GPL"); | ||
1648 | module_init(tcm_vhost_init); | ||
1649 | module_exit(tcm_vhost_exit); | ||
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h new file mode 100644 index 000000000000..d9e93557d669 --- /dev/null +++ b/drivers/vhost/tcm_vhost.h | |||
@@ -0,0 +1,103 @@ | |||
1 | #define TCM_VHOST_VERSION "v0.1" | ||
2 | #define TCM_VHOST_NAMELEN 256 | ||
3 | #define TCM_VHOST_MAX_CDB_SIZE 32 | ||
4 | |||
5 | struct tcm_vhost_cmd { | ||
6 | /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ | ||
7 | int tvc_vq_desc; | ||
8 | /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ | ||
9 | u64 tvc_tag; | ||
10 | /* The number of scatterlists associated with this cmd */ | ||
11 | u32 tvc_sgl_count; | ||
12 | /* Saved unpacked SCSI LUN for tcm_vhost_submission_work() */ | ||
13 | u32 tvc_lun; | ||
14 | /* Pointer to the SGL formatted memory from virtio-scsi */ | ||
15 | struct scatterlist *tvc_sgl; | ||
16 | /* Pointer to response */ | ||
17 | struct virtio_scsi_cmd_resp __user *tvc_resp; | ||
18 | /* Pointer to vhost_scsi for our device */ | ||
19 | struct vhost_scsi *tvc_vhost; | ||
20 | /* The TCM I/O descriptor that is accessed via container_of() */ | ||
21 | struct se_cmd tvc_se_cmd; | ||
22 | /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ | ||
23 | struct work_struct work; | ||
24 | /* Copy of the incoming SCSI command descriptor block (CDB) */ | ||
25 | unsigned char tvc_cdb[TCM_VHOST_MAX_CDB_SIZE]; | ||
26 | /* Sense buffer that will be mapped into outgoing status */ | ||
27 | unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER]; | ||
28 | /* Completed commands list, serviced from vhost worker thread */ | ||
29 | struct list_head tvc_completion_list; | ||
30 | }; | ||
31 | |||
32 | struct tcm_vhost_nexus { | ||
33 | /* Pointer to TCM session for I_T Nexus */ | ||
34 | struct se_session *tvn_se_sess; | ||
35 | }; | ||
36 | |||
37 | struct tcm_vhost_nacl { | ||
38 | /* Binary World Wide unique Port Name for Vhost Initiator port */ | ||
39 | u64 iport_wwpn; | ||
40 | /* ASCII formatted WWPN for Sas Initiator port */ | ||
41 | char iport_name[TCM_VHOST_NAMELEN]; | ||
42 | /* Returned by tcm_vhost_make_nodeacl() */ | ||
43 | struct se_node_acl se_node_acl; | ||
44 | }; | ||
45 | |||
46 | struct tcm_vhost_tpg { | ||
47 | /* Vhost port target portal group tag for TCM */ | ||
48 | u16 tport_tpgt; | ||
49 | /* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus shutdown */ | ||
50 | int tv_tpg_port_count; | ||
51 | /* Used for vhost_scsi device reference to tpg_nexus, protected by tv_tpg_mutex */ | ||
52 | int tv_tpg_vhost_count; | ||
53 | /* list for tcm_vhost_list */ | ||
54 | struct list_head tv_tpg_list; | ||
55 | /* Used to protect access for tpg_nexus */ | ||
56 | struct mutex tv_tpg_mutex; | ||
57 | /* Pointer to the TCM VHost I_T Nexus for this TPG endpoint */ | ||
58 | struct tcm_vhost_nexus *tpg_nexus; | ||
59 | /* Pointer back to tcm_vhost_tport */ | ||
60 | struct tcm_vhost_tport *tport; | ||
61 | /* Returned by tcm_vhost_make_tpg() */ | ||
62 | struct se_portal_group se_tpg; | ||
63 | }; | ||
64 | |||
65 | struct tcm_vhost_tport { | ||
66 | /* SCSI protocol the tport is providing */ | ||
67 | u8 tport_proto_id; | ||
68 | /* Binary World Wide unique Port Name for Vhost Target port */ | ||
69 | u64 tport_wwpn; | ||
70 | /* ASCII formatted WWPN for Vhost Target port */ | ||
71 | char tport_name[TCM_VHOST_NAMELEN]; | ||
72 | /* Returned by tcm_vhost_make_tport() */ | ||
73 | struct se_wwn tport_wwn; | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * As per request from MST, keep TCM_VHOST related ioctl defines out of | ||
78 | * linux/vhost.h (user-space) for now.. | ||
79 | */ | ||
80 | |||
81 | #include <linux/vhost.h> | ||
82 | |||
83 | /* | ||
84 | * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. | ||
85 | * | ||
86 | * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + | ||
87 | * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage | ||
88 | */ | ||
89 | |||
90 | #define VHOST_SCSI_ABI_VERSION 0 | ||
91 | |||
92 | struct vhost_scsi_target { | ||
93 | int abi_version; | ||
94 | char vhost_wwpn[TRANSPORT_IQN_LEN]; | ||
95 | unsigned short vhost_tpgt; | ||
96 | unsigned short reserved; | ||
97 | }; | ||
98 | |||
99 | /* VHOST_SCSI specific defines */ | ||
100 | #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) | ||
101 | #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) | ||
102 | /* Changing this breaks userspace. */ | ||
103 | #define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int) | ||
diff --git a/drivers/video/auo_k190x.c b/drivers/video/auo_k190x.c index 77da6a2f43dc..c03ecdd31e4c 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/auo_k190x.c | |||
@@ -987,7 +987,6 @@ err_regfb: | |||
987 | fb_dealloc_cmap(&info->cmap); | 987 | fb_dealloc_cmap(&info->cmap); |
988 | err_cmap: | 988 | err_cmap: |
989 | fb_deferred_io_cleanup(info); | 989 | fb_deferred_io_cleanup(info); |
990 | kfree(info->fbdefio); | ||
991 | err_defio: | 990 | err_defio: |
992 | vfree((void *)info->screen_base); | 991 | vfree((void *)info->screen_base); |
993 | err_irq: | 992 | err_irq: |
@@ -1022,7 +1021,6 @@ int __devexit auok190x_common_remove(struct platform_device *pdev) | |||
1022 | fb_dealloc_cmap(&info->cmap); | 1021 | fb_dealloc_cmap(&info->cmap); |
1023 | 1022 | ||
1024 | fb_deferred_io_cleanup(info); | 1023 | fb_deferred_io_cleanup(info); |
1025 | kfree(info->fbdefio); | ||
1026 | 1024 | ||
1027 | vfree((void *)info->screen_base); | 1025 | vfree((void *)info->screen_base); |
1028 | 1026 | ||
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 28b1a834906b..61b182bf32a2 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c | |||
@@ -162,7 +162,7 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, | |||
162 | image.depth = 1; | 162 | image.depth = 1; |
163 | 163 | ||
164 | if (attribute) { | 164 | if (attribute) { |
165 | buf = kmalloc(cellsize, GFP_KERNEL); | 165 | buf = kmalloc(cellsize, GFP_ATOMIC); |
166 | if (!buf) | 166 | if (!buf) |
167 | return; | 167 | return; |
168 | } | 168 | } |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 2e471c22abf5..fdefa8fd72c4 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -372,8 +372,15 @@ static void fb_flashcursor(struct work_struct *work) | |||
372 | struct vc_data *vc = NULL; | 372 | struct vc_data *vc = NULL; |
373 | int c; | 373 | int c; |
374 | int mode; | 374 | int mode; |
375 | int ret; | ||
376 | |||
377 | /* FIXME: we should sort out the unbind locking instead */ | ||
378 | /* instead we just fail to flash the cursor if we can't get | ||
379 | * the lock instead of blocking fbcon deinit */ | ||
380 | ret = console_trylock(); | ||
381 | if (ret == 0) | ||
382 | return; | ||
375 | 383 | ||
376 | console_lock(); | ||
377 | if (ops && ops->currcon != -1) | 384 | if (ops && ops->currcon != -1) |
378 | vc = vc_cons[ops->currcon].d; | 385 | vc = vc_cons[ops->currcon].d; |
379 | 386 | ||
@@ -442,7 +449,7 @@ static int __init fb_console_setup(char *this_opt) | |||
442 | 449 | ||
443 | while ((options = strsep(&this_opt, ",")) != NULL) { | 450 | while ((options = strsep(&this_opt, ",")) != NULL) { |
444 | if (!strncmp(options, "font:", 5)) | 451 | if (!strncmp(options, "font:", 5)) |
445 | strcpy(fontname, options + 5); | 452 | strlcpy(fontname, options + 5, sizeof(fontname)); |
446 | 453 | ||
447 | if (!strncmp(options, "scrollback:", 11)) { | 454 | if (!strncmp(options, "scrollback:", 11)) { |
448 | options += 11; | 455 | options += 11; |
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c index 00ce1f34b496..57d940be5f3d 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/mb862xx/mb862xxfbdrv.c | |||
@@ -328,6 +328,8 @@ static int mb862xxfb_ioctl(struct fb_info *fbi, unsigned int cmd, | |||
328 | case MB862XX_L1_SET_CFG: | 328 | case MB862XX_L1_SET_CFG: |
329 | if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg))) | 329 | if (copy_from_user(l1_cfg, argp, sizeof(*l1_cfg))) |
330 | return -EFAULT; | 330 | return -EFAULT; |
331 | if (l1_cfg->dh == 0 || l1_cfg->dw == 0) | ||
332 | return -EINVAL; | ||
331 | if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) { | 333 | if ((l1_cfg->sw >= l1_cfg->dw) && (l1_cfg->sh >= l1_cfg->dh)) { |
332 | /* downscaling */ | 334 | /* downscaling */ |
333 | outreg(cap, GC_CAP_CSC, | 335 | outreg(cap, GC_CAP_CSC, |
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 5d31699fbd3c..f43bfe17b3b6 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c | |||
@@ -105,6 +105,20 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) | |||
105 | 105 | ||
106 | sdi_config_lcd_manager(dssdev); | 106 | sdi_config_lcd_manager(dssdev); |
107 | 107 | ||
108 | /* | ||
109 | * LCLK and PCLK divisors are located in shadow registers, and we | ||
110 | * normally write them to DISPC registers when enabling the output. | ||
111 | * However, SDI uses pck-free as source clock for its PLL, and pck-free | ||
112 | * is affected by the divisors. And as we need the PLL before enabling | ||
113 | * the output, we need to write the divisors early. | ||
114 | * | ||
115 | * It seems just writing to the DISPC register is enough, and we don't | ||
116 | * need to care about the shadow register mechanism for pck-free. The | ||
117 | * exact reason for this is unknown. | ||
118 | */ | ||
119 | dispc_mgr_set_clock_div(dssdev->manager->id, | ||
120 | &sdi.mgr_config.clock_info); | ||
121 | |||
108 | dss_sdi_init(dssdev->phy.sdi.datapairs); | 122 | dss_sdi_init(dssdev->phy.sdi.datapairs); |
109 | r = dss_sdi_enable(); | 123 | r = dss_sdi_enable(); |
110 | if (r) | 124 | if (r) |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 08ec1a7103f2..fc671d3d8004 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -1192,7 +1192,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green, | |||
1192 | break; | 1192 | break; |
1193 | 1193 | ||
1194 | if (regno < 16) { | 1194 | if (regno < 16) { |
1195 | u16 pal; | 1195 | u32 pal; |
1196 | pal = ((red >> (16 - var->red.length)) << | 1196 | pal = ((red >> (16 - var->red.length)) << |
1197 | var->red.offset) | | 1197 | var->red.offset) | |
1198 | ((green >> (16 - var->green.length)) << | 1198 | ((green >> (16 - var->green.length)) << |
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index d90062b211f8..92d08e7fcba2 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -91,6 +91,11 @@ static struct w1_family w1_therm_family_DS28EA00 = { | |||
91 | .fops = &w1_therm_fops, | 91 | .fops = &w1_therm_fops, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static struct w1_family w1_therm_family_DS1825 = { | ||
95 | .fid = W1_THERM_DS1825, | ||
96 | .fops = &w1_therm_fops, | ||
97 | }; | ||
98 | |||
94 | struct w1_therm_family_converter | 99 | struct w1_therm_family_converter |
95 | { | 100 | { |
96 | u8 broken; | 101 | u8 broken; |
@@ -120,6 +125,10 @@ static struct w1_therm_family_converter w1_therm_families[] = { | |||
120 | .f = &w1_therm_family_DS28EA00, | 125 | .f = &w1_therm_family_DS28EA00, |
121 | .convert = w1_DS18B20_convert_temp | 126 | .convert = w1_DS18B20_convert_temp |
122 | }, | 127 | }, |
128 | { | ||
129 | .f = &w1_therm_family_DS1825, | ||
130 | .convert = w1_DS18B20_convert_temp | ||
131 | } | ||
123 | }; | 132 | }; |
124 | 133 | ||
125 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) | 134 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index b00ada44a89b..a1f0ce151d53 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define W1_EEPROM_DS2431 0x2D | 39 | #define W1_EEPROM_DS2431 0x2D |
40 | #define W1_FAMILY_DS2760 0x30 | 40 | #define W1_FAMILY_DS2760 0x30 |
41 | #define W1_FAMILY_DS2780 0x32 | 41 | #define W1_FAMILY_DS2780 0x32 |
42 | #define W1_THERM_DS1825 0x3B | ||
42 | #define W1_FAMILY_DS2781 0x3D | 43 | #define W1_FAMILY_DS2781 0x3D |
43 | #define W1_THERM_DS28EA00 0x42 | 44 | #define W1_THERM_DS28EA00 0x42 |
44 | 45 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 3fe82d0e8caa..5b06d31ab6a9 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -166,18 +166,17 @@ static long booke_wdt_ioctl(struct file *file, | |||
166 | 166 | ||
167 | switch (cmd) { | 167 | switch (cmd) { |
168 | case WDIOC_GETSUPPORT: | 168 | case WDIOC_GETSUPPORT: |
169 | if (copy_to_user((void *)arg, &ident, sizeof(ident))) | 169 | return copy_to_user(p, &ident, sizeof(ident)) ? -EFAULT : 0; |
170 | return -EFAULT; | ||
171 | case WDIOC_GETSTATUS: | 170 | case WDIOC_GETSTATUS: |
172 | return put_user(0, p); | 171 | return put_user(0, p); |
173 | case WDIOC_GETBOOTSTATUS: | 172 | case WDIOC_GETBOOTSTATUS: |
174 | /* XXX: something is clearing TSR */ | 173 | /* XXX: something is clearing TSR */ |
175 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); | 174 | tmp = mfspr(SPRN_TSR) & TSR_WRS(3); |
176 | /* returns CARDRESET if last reset was caused by the WDT */ | 175 | /* returns CARDRESET if last reset was caused by the WDT */ |
177 | return (tmp ? WDIOF_CARDRESET : 0); | 176 | return put_user((tmp ? WDIOF_CARDRESET : 0), p); |
178 | case WDIOC_SETOPTIONS: | 177 | case WDIOC_SETOPTIONS: |
179 | if (get_user(tmp, p)) | 178 | if (get_user(tmp, p)) |
180 | return -EINVAL; | 179 | return -EFAULT; |
181 | if (tmp == WDIOS_ENABLECARD) { | 180 | if (tmp == WDIOS_ENABLECARD) { |
182 | booke_wdt_ping(); | 181 | booke_wdt_ping(); |
183 | break; | 182 | break; |
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index 3f75129eb0a9..f7abbaeebcaf 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
24 | #include <linux/delay.h> | ||
25 | 24 | ||
26 | #include <linux/mfd/da9052/reg.h> | 25 | #include <linux/mfd/da9052/reg.h> |
27 | #include <linux/mfd/da9052/da9052.h> | 26 | #include <linux/mfd/da9052/da9052.h> |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 1eff743ec497..ae60406ea8a1 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -814,6 +814,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev, | |||
814 | hpwdt_timer_reg = pci_mem_addr + 0x70; | 814 | hpwdt_timer_reg = pci_mem_addr + 0x70; |
815 | hpwdt_timer_con = pci_mem_addr + 0x72; | 815 | hpwdt_timer_con = pci_mem_addr + 0x72; |
816 | 816 | ||
817 | /* Make sure that timer is disabled until /dev/watchdog is opened */ | ||
818 | hpwdt_stop(); | ||
819 | |||
817 | /* Make sure that we have a valid soft_margin */ | 820 | /* Make sure that we have a valid soft_margin */ |
818 | if (hpwdt_change_timer(soft_margin)) | 821 | if (hpwdt_change_timer(soft_margin)) |
819 | hpwdt_change_timer(DEFAULT_MARGIN); | 822 | hpwdt_change_timer(DEFAULT_MARGIN); |
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 6aa46a90ff02..3796434991fa 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c | |||
@@ -128,11 +128,12 @@ EXPORT_SYMBOL_GPL(watchdog_register_device); | |||
128 | void watchdog_unregister_device(struct watchdog_device *wdd) | 128 | void watchdog_unregister_device(struct watchdog_device *wdd) |
129 | { | 129 | { |
130 | int ret; | 130 | int ret; |
131 | int devno = wdd->cdev.dev; | 131 | int devno; |
132 | 132 | ||
133 | if (wdd == NULL) | 133 | if (wdd == NULL) |
134 | return; | 134 | return; |
135 | 135 | ||
136 | devno = wdd->cdev.dev; | ||
136 | ret = watchdog_dev_unregister(wdd); | 137 | ret = watchdog_dev_unregister(wdd); |
137 | if (ret) | 138 | if (ret) |
138 | pr_err("error unregistering /dev/watchdog (err=%d)\n", ret); | 139 | pr_err("error unregistering /dev/watchdog (err=%d)\n", ret); |
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 1ffd03bf8e10..7f1241608489 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c | |||
@@ -314,8 +314,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages) | |||
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
317 | err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages + offset, | 317 | err = gnttab_unmap_refs(map->unmap_ops + offset, |
318 | pages, true); | 318 | use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, |
319 | pages); | ||
319 | if (err) | 320 | if (err) |
320 | return err; | 321 | return err; |
321 | 322 | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 0bfc1ef11259..006726688baf 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -870,7 +870,8 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, | |||
870 | EXPORT_SYMBOL_GPL(gnttab_map_refs); | 870 | EXPORT_SYMBOL_GPL(gnttab_map_refs); |
871 | 871 | ||
872 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | 872 | int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, |
873 | struct page **pages, unsigned int count, bool clear_pte) | 873 | struct gnttab_map_grant_ref *kmap_ops, |
874 | struct page **pages, unsigned int count) | ||
874 | { | 875 | { |
875 | int i, ret; | 876 | int i, ret; |
876 | bool lazy = false; | 877 | bool lazy = false; |
@@ -888,7 +889,8 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, | |||
888 | } | 889 | } |
889 | 890 | ||
890 | for (i = 0; i < count; i++) { | 891 | for (i = 0; i < count; i++) { |
891 | ret = m2p_remove_override(pages[i], clear_pte); | 892 | ret = m2p_remove_override(pages[i], kmap_ops ? |
893 | &kmap_ops[i] : NULL); | ||
892 | if (ret) | 894 | if (ret) |
893 | return ret; | 895 | return ret; |
894 | } | 896 | } |
diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c index d4c50d63acbc..97ca359ae2bd 100644 --- a/drivers/xen/platform-pci.c +++ b/drivers/xen/platform-pci.c | |||
@@ -101,19 +101,6 @@ static int platform_pci_resume(struct pci_dev *pdev) | |||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void __devinit prepare_shared_info(void) | ||
105 | { | ||
106 | #ifdef CONFIG_KEXEC | ||
107 | unsigned long addr; | ||
108 | struct shared_info *hvm_shared_info; | ||
109 | |||
110 | addr = alloc_xen_mmio(PAGE_SIZE); | ||
111 | hvm_shared_info = ioremap(addr, PAGE_SIZE); | ||
112 | memset(hvm_shared_info, 0, PAGE_SIZE); | ||
113 | xen_hvm_prepare_kexec(hvm_shared_info, addr >> PAGE_SHIFT); | ||
114 | #endif | ||
115 | } | ||
116 | |||
117 | static int __devinit platform_pci_init(struct pci_dev *pdev, | 104 | static int __devinit platform_pci_init(struct pci_dev *pdev, |
118 | const struct pci_device_id *ent) | 105 | const struct pci_device_id *ent) |
119 | { | 106 | { |
@@ -151,8 +138,6 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, | |||
151 | platform_mmio = mmio_addr; | 138 | platform_mmio = mmio_addr; |
152 | platform_mmiolen = mmio_len; | 139 | platform_mmiolen = mmio_len; |
153 | 140 | ||
154 | prepare_shared_info(); | ||
155 | |||
156 | if (!xen_have_vector_callback) { | 141 | if (!xen_have_vector_callback) { |
157 | ret = xen_allocate_irq(pdev); | 142 | ret = xen_allocate_irq(pdev); |
158 | if (ret) { | 143 | if (ret) { |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 1afb4fba11b4..4d519488d304 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
@@ -232,7 +232,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
232 | return ret; | 232 | return ret; |
233 | 233 | ||
234 | if (hwdev && hwdev->coherent_dma_mask) | 234 | if (hwdev && hwdev->coherent_dma_mask) |
235 | dma_mask = hwdev->coherent_dma_mask; | 235 | dma_mask = dma_alloc_coherent_mask(hwdev, flags); |
236 | 236 | ||
237 | phys = virt_to_phys(ret); | 237 | phys = virt_to_phys(ret); |
238 | dev_addr = xen_phys_to_bus(phys); | 238 | dev_addr = xen_phys_to_bus(phys); |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 097e536e8672..03342728bf23 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -353,16 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) | |||
353 | if (err) | 353 | if (err) |
354 | goto config_release; | 354 | goto config_release; |
355 | 355 | ||
356 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | ||
357 | __pci_reset_function_locked(dev); | ||
358 | |||
359 | /* We need the device active to save the state. */ | 356 | /* We need the device active to save the state. */ |
360 | dev_dbg(&dev->dev, "save state of device\n"); | 357 | dev_dbg(&dev->dev, "save state of device\n"); |
361 | pci_save_state(dev); | 358 | pci_save_state(dev); |
362 | dev_data->pci_saved_state = pci_store_saved_state(dev); | 359 | dev_data->pci_saved_state = pci_store_saved_state(dev); |
363 | if (!dev_data->pci_saved_state) | 360 | if (!dev_data->pci_saved_state) |
364 | dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); | 361 | dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); |
365 | 362 | else { | |
363 | dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); | ||
364 | __pci_reset_function_locked(dev); | ||
365 | } | ||
366 | /* Now disable the device (this also ensures some private device | 366 | /* Now disable the device (this also ensures some private device |
367 | * data is setup before we export) | 367 | * data is setup before we export) |
368 | */ | 368 | */ |
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 181fa8158a8b..858c9714b2f3 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c | |||
@@ -37,7 +37,6 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | struct zorro_bus { | 39 | struct zorro_bus { |
40 | struct list_head devices; /* list of devices on this bus */ | ||
41 | struct device dev; | 40 | struct device dev; |
42 | }; | 41 | }; |
43 | 42 | ||
@@ -136,7 +135,6 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) | |||
136 | if (!bus) | 135 | if (!bus) |
137 | return -ENOMEM; | 136 | return -ENOMEM; |
138 | 137 | ||
139 | INIT_LIST_HEAD(&bus->devices); | ||
140 | bus->dev.parent = &pdev->dev; | 138 | bus->dev.parent = &pdev->dev; |
141 | dev_set_name(&bus->dev, "zorro"); | 139 | dev_set_name(&bus->dev, "zorro"); |
142 | error = device_register(&bus->dev); | 140 | error = device_register(&bus->dev); |